<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>小维 · 博客园</title>
  
  
  <link href="https://luckynwa.top/atom.xml" rel="self"/>
  
  <link href="https://luckynwa.top/"/>
  <updated>2026-07-07T16:20:55.856Z</updated>
  <id>https://luckynwa.top/</id>
  
  <author>
    <name>Lucky小维</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>MaxKB 私有化部署：快速搭建本地知识库问答系统</title>
    <link href="https://luckynwa.top/posts/58234/"/>
    <id>https://luckynwa.top/posts/58234/</id>
    <published>2026-07-04T02:00:00.000Z</published>
    <updated>2026-07-07T16:20:55.856Z</updated>
    
    <content type="html"><![CDATA[<h1 id="maxkb-部署"><a class="markdownIt-Anchor" href="#maxkb-部署"></a> MaxKB 部署</h1><h2 id="环境准备"><a class="markdownIt-Anchor" href="#环境准备"></a> 环境准备</h2><p>打开桌面版的 Docker，直接 cmd 运行即可。MaxKBv1.3.0 的 logo 是吸附的，推荐使用该版本。</p><h2 id="镜像拉取"><a class="markdownIt-Anchor" href="#镜像拉取"></a> 镜像拉取</h2><figure class="highlight shell"><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">docker pull registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/maxkb</span><br><span class="line">docker pull registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/maxkb:v1.3.0</span><br></pre></td></tr></table></figure><h2 id="容器运行"><a class="markdownIt-Anchor" href="#容器运行"></a> 容器运行</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d --restart=always --name=maxkb -p 18080:8080 -v ~/.maxkb:/var/lib/postgresql/data registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/maxkb:v1.3.0</span><br></pre></td></tr></table></figure><h2 id="访问地址"><a class="markdownIt-Anchor" href="#访问地址"></a> 访问地址</h2><ul><li>本地访问：<code>http://localhost:18080</code></li></ul><h2 id="默认账号"><a class="markdownIt-Anchor" href="#默认账号"></a> 默认账号</h2><figure class="highlight plaintext"><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">admin</span><br><span class="line">MaxKB@123..</span><br></pre></td></tr></table></figure><h1 id="模型配置"><a class="markdownIt-Anchor" href="#模型配置"></a> 模型配置</h1><h2 id="添加模型"><a class="markdownIt-Anchor" href="#添加模型"></a> 添加模型</h2><p>登录—&gt;系统设置—&gt; 模型设置 —&gt; 添加 Ollama：</p><ul><li>名称：qwen0.5b</li><li>类型：大语言模型</li><li>模型：<code>qwen0.5b</code>，如果没有则通过 <code>ollama list</code> 把 name 复制出来即可</li></ul><h2 id="api-域名"><a class="markdownIt-Anchor" href="#api-域名"></a> API 域名</h2><p>需要先内网穿透出来或者解除 IP 限制才能访问到宿主机，可以去看下我ollama那篇文章</p><table><thead><tr><th>环境</th><th>地址</th></tr></thead><tbody><tr><td>Docker 桌面版</td><td><code>http://host.docker.internal:11434/</code></td></tr><tr><td>宿主机查看</td><td><code>http://localhost:11434</code></td></tr><tr><td>内网穿透外网 Ollama</td><td><code>http://ip:11434</code></td></tr></tbody></table><p>API Key 随便填</p><h1 id="创建应用"><a class="markdownIt-Anchor" href="#创建应用"></a> 创建应用</h1><p>应用 -&gt; 创建应用</p><p>应用名称：lucky-gpt</p><p>应用描述：基于N100小主机，部署的无显卡qwen:0.5小模型</p><p>应用类型：简单配置（新手）</p><p><strong>提示词</strong></p><p>我弄了一个mysql的知识库，所以提示词可以下面这样写</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">角色</span></span><br><span class="line">你是后端开发领域的专家，精通mysql数据库相关知识。</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">回答要求</span></span><br><span class="line">- 请严格根据下面[已知信息]来回答用户的[问题]</span><br><span class="line">- 禁止使用任何你自己的知识</span><br><span class="line">- 请使用能让小白听懂的语言回答</span><br><span class="line">- 如果[已知信息]中没有答案，请回复：&quot;抱歉，关于您的问题，我暂时没有找到相关信息，建议联系人工客服。&quot;</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">已知信息</span></span><br><span class="line">&#123;data&#125;</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">用户问题</span></span><br><span class="line">&#123;question&#125;</span><br></pre></td></tr></table></figure><p>（1）勾选多轮对话</p><p>（2）选择前面配置的AI模型</p><p>（3）问题优化也勾选（后续搭建知识库的话）</p><p><strong>开场白</strong></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></pre></td><td class="code"><pre><span class="line">您好！我是小维的 MySQL 数据库专家。精通数据库架构设计和理论知识。</span><br><span class="line"></span><br><span class="line">我可以为您提供以下帮助：</span><br><span class="line">- 请解释什么是回表？</span><br><span class="line">- 主从复制的原理？</span><br><span class="line">- ACID特性是什么？</span><br></pre></td></tr></table></figure><p>然后右边直接输入问题，即可调用自己部署的本地大模型</p><h1 id="第三方调用"><a class="markdownIt-Anchor" href="#第三方调用"></a> 第三方调用</h1><p>点概览，可以查看演示，访问限制等</p><p>支持嵌入到第三方应用中，很好用，直接复制到对应项目的前端页面中即可</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704202116882_20260704202117A007.png" alt="image-20260704202116882" /></p><h1 id="创建知识库"><a class="markdownIt-Anchor" href="#创建知识库"></a> 创建知识库</h1><p>导航那点击知识库----&gt;创建----&gt;输入名称----&gt;描述----&gt;通用型----&gt;上传文件最好是md格式的</p><p>看到列表里的文件状态是成功即可，…的设置里可以改这个</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704204230785_20260704204231A008.png" alt="image-20260704204230785" /></p><p>再去给自己的大模型关联上知识库：</p><p>配置参考如下：</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704204338734_20260704204339A009.png" alt="image-20260704204338734" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704201542011_20260704201542A006.png" alt="image-20260704201542011" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704204422203_20260704204422A010.png" alt="image-20260704204422203" /></p>]]></content>
    
    
    <summary type="html">长风破浪会有时，直挂云帆济沧海</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Ops" scheme="https://luckynwa.top/tags/Ops/"/>
    
  </entry>
  
  <entry>
    <title>RAG 学习笔记</title>
    <link href="https://luckynwa.top/posts/rag732/"/>
    <id>https://luckynwa.top/posts/rag732/</id>
    <published>2026-04-06T06:30:00.000Z</published>
    <updated>2026-07-07T16:19:34.042Z</updated>
    
    <content type="html"><![CDATA[<h2 id="什么是-rag"><a class="markdownIt-Anchor" href="#什么是-rag"></a> 什么是 RAG？</h2><p>RAG = Retrieval-Augmented Generation<br />中文：<strong>检索增强生成</strong></p><p>一句话理解：</p><blockquote><p>先从资料中&quot;查答案&quot;，再让大模型&quot;根据资料作答&quot;。</p></blockquote><h2 id="为什么需要-rag"><a class="markdownIt-Anchor" href="#为什么需要-rag"></a> 为什么需要 RAG？</h2><p>企业内部的资料，大模型不一定有，所以会出现乱说</p><p>还有不可能把几百页的说明书给大模型的，这样开销很大</p><p>大模型有两个问题：</p><ol><li>会胡编（幻觉 hallucination）</li><li>不知道私有数据</li></ol><p>RAG 解决方式：</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></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><br><span class="line"> ↓</span><br><span class="line">大模型根据资料回答</span><br></pre></td></tr></table></figure><h2 id="rag-整体流程"><a class="markdownIt-Anchor" href="#rag-整体流程"></a> RAG 整体流程</h2><p><strong>离线阶段：</strong> 文档解析 → Chunk 切分 → Embedding 向量化 → 向量入库</p><p><strong>在线阶段：</strong> 用户问题 Embedding → 语义缓存匹配 → Milvus 向量检索 + BM25 混合召回 → Reranker 精排 → Prompt 拼接 → 大模型生成答案</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><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><br><span class="line">│                                                                      │</span><br><span class="line">│  PDF 文档解析                                                         │</span><br><span class="line">│       ↓                                                              │</span><br><span class="line">│  文本分片（Chunking）  按段落/章节字数等，LLM有上下文长度限制              │</span><br><span class="line">│       ↓                                                              │</span><br><span class="line">│  Embedding  将文字翻译为高维度向量，语义相近则空间距离就近                 │</span><br><span class="line">│       ↓                                                              │</span><br><span class="line">│  向量数据库（Milvus）  存储 向量 + 原始文本的对照表                      │</span><br><span class="line">└──────────────────────────────────────────────────────────────────────┘</span><br><span class="line"></span><br><span class="line">┌──────────────────────────────────────────────────────────────────────┐</span><br><span class="line">│                          在 线 阶 段                                  │</span><br><span class="line">│                                                                      │</span><br><span class="line">│  用户提问                                                             │</span><br><span class="line">│       ↓                                                              │</span><br><span class="line">│  Embedding 向量化                                                     │</span><br><span class="line">│       ↓                                                              │</span><br><span class="line">│  语义缓存匹配  ──命中──→  直接返回缓存答案                              │</span><br><span class="line">│       ↓ 未命中                                                        │</span><br><span class="line">│  双路检索召回                                                          │</span><br><span class="line">│  ┌──────────────────────────┐  ┌──────────────────────────┐           │</span><br><span class="line">│  │    BM25 稀疏检索          │  │    BGE 稠密检索           │           │</span><br><span class="line">│  │                          │  │                          │           │</span><br><span class="line">│  │  用户查询                 │  │  用户查询                 │           │</span><br><span class="line">│  │    ↓                     │  │    ↓                     │           │</span><br><span class="line">│  │  分词 → 词频统计（TF）     │  │  BGE 模型 Embedding       │           │</span><br><span class="line">│  │    ↓                     │  │    ↓                     │           │</span><br><span class="line">│  │  逆文档频率（IDF）计算     │  │  生成查询向量 Q            │           │</span><br><span class="line">│  │    ↓                     │  │    ↓                     │           │</span><br><span class="line">│  │  TF × IDF 得分            │  │  ANN 索引检索（HNSW/IVF） │           │</span><br><span class="line">│  │    ↓                     │  │  余弦相似度计算 cos(Q,D)   │           │</span><br><span class="line">│  │  按关键词匹配度排序        │  │    ↓                     │           │</span><br><span class="line">│  │    ↓                     │  │  按语义相似度排序          │           │</span><br><span class="line">│  │  返回 Top-K 候选文档      │  │  返回 Top-K 候选文档      │           │</span><br><span class="line">│  └──────────┬───────────────┘  └──────────┬───────────────┘           │</span><br><span class="line">│             └──────────┬──────────────────┘                           │</span><br><span class="line">│                  ↓                                                    │</span><br><span class="line">│          RRF 融合算法（Reciprocal Rank Fusion）                        │</span><br><span class="line">│                  ↓                                                    │</span><br><span class="line">│          Reranker 精排（bge-reranker-base）                            │</span><br><span class="line">│                  ↓                                                    │</span><br><span class="line">│          构造 Prompt（角色设定 + 规则 + 检索资料 + 问题）                 │</span><br><span class="line">│                  ↓                                                    │</span><br><span class="line">│          调用大模型（GLM）                                              │</span><br><span class="line">│                  ↓                                                    │</span><br><span class="line">│          生成答案                                                      │</span><br><span class="line">└──────────────────────────────────────────────────────────────────────┘</span><br></pre></td></tr></table></figure><h2 id="常见问题与解决方案"><a class="markdownIt-Anchor" href="#常见问题与解决方案"></a> 常见问题与解决方案</h2><ol><li>文档解析出现乱码，表格行错位 → OCR + 人工复核</li><li>颗粒度问题 → 切太大噪音太多，太小语义丢失</li><li>检索准确率 → 加入混合检索 + rerank</li><li>用户提问模糊性 → 比如问&quot;货没了去补&quot;，需要查询重写（Query Rewrite）后再去搜索</li></ol><p>大模型选型和评估标准：</p><ol><li>推理能力</li><li>指令遵循能力</li><li>防幻觉能力</li></ol><p>进阶方案：GraphRAG 和 Agentic RAG</p><h2 id="分块策略"><a class="markdownIt-Anchor" href="#分块策略"></a> 分块策略</h2><p><code>chunk_size</code>：256 / 512 / 1024（token 或字节）</p><p><code>chunk_overlap</code>：10%~20% 相邻块重叠部分，防止语意断裂</p><p><strong>策略：</strong></p><p><strong>基础分块：</strong> 固定长度、递归字符（首选，按优先级分隔符递归切分 <code>\n\n</code> → <code>\n</code> → <code>&quot; &quot;</code>，能保留句子完整性）、按句切分</p><p><strong>结构感知：</strong> HTML、Markdown、对话格式</p><p><strong>语义/主题：</strong> 向量相似度</p><p><strong>高级策略：</strong> 小-大分块、代理分块（让模型切分，成本很高）</p><p><strong>复杂文档最佳实践：</strong> 采用混合分块，可以先按结构粗切，再语义/递归细切，做命中率测试</p><p><strong>建议：</strong></p><table><thead><tr><th>场景</th><th>推荐方式</th></tr></thead><tbody><tr><td>通用文本</td><td>递归字符分块（RecursiveCharacterTextSplitter）</td></tr><tr><td>Markdown 文档</td><td>MarkdownHeaderTextSplitter</td></tr><tr><td>HTML 页面</td><td>HTMLHeaderTextSplitter</td></tr><tr><td>追求最高精度</td><td>SemanticChunker（成本高）</td></tr><tr><td>代码文件</td><td>按函数/类切分，保留完整结构</td></tr></tbody></table><h3 id="langchain-分块伪代码"><a class="markdownIt-Anchor" href="#langchain-分块伪代码"></a> LangChain 分块伪代码</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> langchain.text_splitter <span class="keyword">import</span> (</span><br><span class="line">    RecursiveCharacterTextSplitter,</span><br><span class="line">    CharacterTextSplitter,</span><br><span class="line">    MarkdownHeaderTextSplitter,</span><br><span class="line">    HTMLHeaderTextSplitter,</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 1. 递归字符分块（首选）</span></span><br><span class="line">splitter = RecursiveCharacterTextSplitter(</span><br><span class="line">    chunk_size=<span class="number">512</span>,       <span class="comment"># 每块最大长度</span></span><br><span class="line">    chunk_overlap=<span class="number">50</span>,     <span class="comment"># 相邻块重叠</span></span><br><span class="line">    separators=[<span class="string">&quot;\n\n&quot;</span>, <span class="string">&quot;\n&quot;</span>, <span class="string">&quot;。&quot;</span>, <span class="string">&quot;！&quot;</span>, <span class="string">&quot;？&quot;</span>, <span class="string">&quot; &quot;</span>],  <span class="comment"># 按优先级递归切分</span></span><br><span class="line">    length_function=<span class="built_in">len</span>,  <span class="comment"># 按字符数计算</span></span><br><span class="line">)</span><br><span class="line">chunks = splitter.split_text(document)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 固定长度分块</span></span><br><span class="line">splitter = CharacterTextSplitter(</span><br><span class="line">    chunk_size=<span class="number">256</span>,</span><br><span class="line">    chunk_overlap=<span class="number">20</span>,</span><br><span class="line">    separator=<span class="string">&quot;\n&quot;</span>,       <span class="comment"># 尽量在换行处切</span></span><br><span class="line">)</span><br><span class="line">chunks = splitter.split_text(document)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. Markdown 结构感知分块</span></span><br><span class="line">headers_to_split = [</span><br><span class="line">    (<span class="string">&quot;#&quot;</span>, <span class="string">&quot;h1&quot;</span>),</span><br><span class="line">    (<span class="string">&quot;##&quot;</span>, <span class="string">&quot;h2&quot;</span>),</span><br><span class="line">    (<span class="string">&quot;###&quot;</span>, <span class="string">&quot;h3&quot;</span>),</span><br><span class="line">]</span><br><span class="line">splitter = MarkdownHeaderTextSplitter(headers_to_split=headers_to_split)</span><br><span class="line"><span class="comment"># 按标题层级拆分，每个 chunk 自带标题元数据</span></span><br><span class="line">docs = splitter.split_text(markdown_text)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. HTML 结构感知分块</span></span><br><span class="line">headers_to_split = [(<span class="string">&quot;h1&quot;</span>, <span class="string">&quot;Header 1&quot;</span>), (<span class="string">&quot;h2&quot;</span>, <span class="string">&quot;Header 2&quot;</span>)]</span><br><span class="line">splitter = HTMLHeaderTextSplitter(headers_to_split=headers_to_split)</span><br><span class="line">docs = splitter.split_text(html_text)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. 语义分块（需要 embedding 模型）</span></span><br><span class="line"><span class="keyword">from</span> langchain_experimental.text_splitter <span class="keyword">import</span> SemanticChunker</span><br><span class="line"><span class="keyword">from</span> langchain_openai <span class="keyword">import</span> OpenAIEmbeddings</span><br><span class="line"></span><br><span class="line">splitter = SemanticChunker(</span><br><span class="line">    OpenAIEmbeddings(),</span><br><span class="line">    breakpoint_threshold_type=<span class="string">&quot;percentile&quot;</span>,  <span class="comment"># 按相似度百分位切</span></span><br><span class="line">)</span><br><span class="line">docs = splitter.split_text(document)</span><br></pre></td></tr></table></figure><h2 id="检索策略"><a class="markdownIt-Anchor" href="#检索策略"></a> 检索策略</h2><ol><li><strong>假想性文档嵌入：</strong> 让 LLM 生成理想答案，再去向量化检索</li><li><strong>混合搜索：</strong> 先通过向量相似度找到相近的，再 BM25 稀疏检索锁定匹配结构，加权融合结果合并，向量 0.6，关键词 0.4</li><li><strong>多子问题检索：</strong> 让大语言模型生成多个语义等价的子问题，再去查，然后用 RAG-Fusion 的 RRF 算法对多个查询结果进行打分重排，强调共识文档——就是多个评委都打分了就是它了</li><li><strong>抽象+具体双路：</strong> 用户问的过具体，可以让 LLM 抽象问题，将 2 个都拿去检索，既抓细节，又抓背景</li></ol>]]></content>
    
    
    <summary type="html">路漫漫其修远兮，吾将上下而求索</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Python" scheme="https://luckynwa.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>AI数学预备知识</title>
    <link href="https://luckynwa.top/posts/math001/"/>
    <id>https://luckynwa.top/posts/math001/</id>
    <published>2026-03-27T02:30:00.000Z</published>
    <updated>2026-07-07T16:19:33.838Z</updated>
    
    <content type="html"><![CDATA[<h2 id="标量scalar"><a class="markdownIt-Anchor" href="#标量scalar"></a> 标量（Scalar）</h2><p>标量就是一个单独的数。<br />例如：1、3.14、-5</p><h2 id="向量vector"><a class="markdownIt-Anchor" href="#向量vector"></a> 向量（Vector）</h2><p>向量是一维数组，通常表示为列向量：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>x</mi><mn>1</mn></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>x</mi><mn>2</mn></msub></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi><mi mathvariant="normal">⋮</mi><mpadded height="+0em" voffset="0em"><mspace mathbackground="black" width="0em" height="1.5em"></mspace></mpadded></mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><msub><mi>x</mi><mi>n</mi></msub></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><annotation encoding="application/x-tex">\begin{bmatrix}x_1 \\x_2 \\\vdots \\x_n\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:5.459999999999999em;vertical-align:-2.4799999999999995em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.9799999999999995em;"><span style="top:-5.8275em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-4.6275em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span><span style="top:-2.7674999999999996em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord">⋮</span><span class="mord rule" style="border-right-width:0em;border-top-width:1.5em;bottom:0em;"></span></span></span></span><span style="top:-1.5675000000000006em;"><span class="pstrut" style="height:3.6875em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4799999999999995em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.953995em;"><span style="top:-1.3499850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.4999850000000006em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.0959850000000007em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.6919850000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-3.712975em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.953995em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:2.4500349999999997em;"><span></span></span></span></span></span></span></span></span></span></span></span></p><p>向量可理解为空间中的点，每个元素对应不同坐标轴的坐标。</p><p>向量中有多少个元素，就叫几维向量。</p><p>例如：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[1,2,3,4]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">]</span></span></span></span></span></p><h3 id="向量加法"><a class="markdownIt-Anchor" href="#向量加法"></a> 向量加法</h3><p>要求两个向量维度相同。</p><p>交换律：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>+</mo><mi>B</mi><mo>=</mo><mi>B</mi><mo>+</mo><mi>A</mi></mrow><annotation encoding="application/x-tex">A + B = B + A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span></span></span></span></span></p><p>示例：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">]</mo><mo>+</mo><mo stretchy="false">[</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">]</mo><mo>=</mo><mo stretchy="false">[</mo><mn>4</mn><mo separator="true">,</mo><mn>6</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">[1,2] + [3,4] = [4,6]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">6</span><span class="mclose">]</span></span></span></span></span></p><h3 id="向量内积点积"><a class="markdownIt-Anchor" href="#向量内积点积"></a> 向量内积（点积）</h3><p>要求两个向量维度相同。</p><p>定义：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>⋅</mo><mi>B</mi><mo>=</mo><msub><mi>x</mi><mn>1</mn></msub><msub><mi>y</mi><mn>1</mn></msub><mo>+</mo><msub><mi>x</mi><mn>2</mn></msub><msub><mi>y</mi><mn>2</mn></msub><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>x</mi><mi>n</mi></msub><msub><mi>y</mi><mi>n</mi></msub></mrow><annotation encoding="application/x-tex">A \cdot B = x_1 y_1 + x_2 y_2 + \cdots + x_n y_n</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.7777700000000001em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.7777700000000001em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.66666em;vertical-align:-0.08333em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.151392em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span></p><p>交换律：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>⋅</mo><mi>B</mi><mo>=</mo><mi>B</mi><mo>⋅</mo><mi>A</mi></mrow><annotation encoding="application/x-tex">A \cdot B = B \cdot A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span></span></span></span></span></p><p>示例：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo stretchy="false">]</mo><mo>⋅</mo><mo stretchy="false">[</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">]</mo><mo>=</mo><mn>1</mn><mo>⋅</mo><mn>3</mn><mo>+</mo><mn>2</mn><mo>⋅</mo><mn>4</mn><mo>=</mo><mn>11</mn></mrow><annotation encoding="application/x-tex">[1,2] \cdot [3,4] = 1 \cdot 3 + 2 \cdot 4 = 11</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord">1</span></span></span></span></span></p><h3 id="向量的模长度"><a class="markdownIt-Anchor" href="#向量的模长度"></a> 向量的模（长度）</h3><p>定义：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi mathvariant="normal">∥</mi><mi>A</mi><mi mathvariant="normal">∥</mi><mo>=</mo><msqrt><mrow><msubsup><mi>x</mi><mn>1</mn><mn>2</mn></msubsup><mo>+</mo><msubsup><mi>x</mi><mn>2</mn><mn>2</mn></msubsup><mo>+</mo><mo>⋯</mo><mo>+</mo><msubsup><mi>x</mi><mi>n</mi><mn>2</mn></msubsup></mrow></msqrt></mrow><annotation encoding="application/x-tex">\|A\| = \sqrt{x_1^2 + x_2^2 + \cdots + x_n^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">∥</span><span class="mord mathnormal">A</span><span class="mord">∥</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.84em;vertical-align:-0.5413249999999998em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.2986750000000002em;"><span class="svg-align" style="top:-3.8em;"><span class="pstrut" style="height:3.8em;"></span><span class="mord" style="padding-left:1em;"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7959080000000001em;"><span style="top:-2.433692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span><span style="top:-3.0448000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26630799999999993em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.7959080000000001em;"><span style="top:-2.433692em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span><span style="top:-3.0448000000000004em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.26630799999999993em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="minner">⋯</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.4530000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.247em;"><span></span></span></span></span></span></span></span></span><span style="top:-3.258675em;"><span class="pstrut" style="height:3.8em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.8800000000000001em;"><svg width='400em' height='1.8800000000000001em' viewBox='0 0 400000 1944' preserveAspectRatio='xMinYMin slice'><path d='M983 90l0 -0c4,-6.7,10,-10,18,-10 H400000v40H1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7s-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744c-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30c26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722c56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5c53.7,-170.3,84.5,-266.8,92.5,-289.5zM1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.5413249999999998em;"><span></span></span></span></span></span></span></span></span></span></p><h3 id="向量夹角的余弦值"><a class="markdownIt-Anchor" href="#向量夹角的余弦值"></a> 向量夹角的余弦值</h3><p>要求两个向量维度相同。</p><p>定义：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>cos</mi><mo>⁡</mo><mi>θ</mi><mo>=</mo><mfrac><mrow><mi>A</mi><mo>⋅</mo><mi>B</mi></mrow><mrow><mi mathvariant="normal">∥</mi><mi>A</mi><mi mathvariant="normal">∥</mi><mo>⋅</mo><mi mathvariant="normal">∥</mi><mi>B</mi><mi mathvariant="normal">∥</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\cos \theta = \frac{A \cdot B}{\|A\| \cdot \|B\|}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mop">cos</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.02778em;">θ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.29633em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.36033em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">∥</span><span class="mord mathnormal">A</span><span class="mord">∥</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">∥</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord">∥</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><h2 id="矩阵matrix"><a class="markdownIt-Anchor" href="#矩阵matrix"></a> 矩阵（Matrix）</h2><p>矩阵是一个二维数组，每个元素为标量，可通过行号和列号索引。</p><h3 id="矩阵加法"><a class="markdownIt-Anchor" href="#矩阵加法"></a> 矩阵加法</h3><p>要求两个矩阵维度相同。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>+</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>5</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>6</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>5</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{bmatrix}1 &amp; 2\\3 &amp; 4\end{bmatrix}+\begin{bmatrix}4 &amp; 2\\3 &amp; 1\end{bmatrix}=\begin{bmatrix}5 &amp; 4\\6 &amp; 5\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">5</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span></span></span></span></span></p><h3 id="矩阵乘法点积矩阵乘法"><a class="markdownIt-Anchor" href="#矩阵乘法点积矩阵乘法"></a> 矩阵乘法（点积矩阵乘法）</h3><p><strong>前提</strong></p><p>左矩阵 A 的列数等于右矩阵 B 的行数</p><p>设：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>a</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>b</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>c</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>d</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo separator="true">,</mo><mspace width="1em"/><mi>B</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>e</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>f</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>g</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>h</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">A=\begin{pmatrix}a &amp; b \\c &amp; d\end{pmatrix},\quadB=\begin{pmatrix}e &amp; f \\g &amp; h\end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">c</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">b</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">e</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">h</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span></p><p>则：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>×</mo><mi>B</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>a</mi><mi>e</mi><mo>+</mo><mi>b</mi><mi>g</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>a</mi><mi>f</mi><mo>+</mo><mi>b</mi><mi>h</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>c</mi><mi>e</mi><mo>+</mo><mi>d</mi><mi>g</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>c</mi><mi>f</mi><mo>+</mo><mi>d</mi><mi>h</mi></mrow></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">A \times B =\begin{pmatrix}ae+bg &amp; af+bh \\ce+dg &amp; cf+dh\end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">c</span><span class="mord mathnormal">e</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">h</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">d</span><span class="mord mathnormal">h</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span></span></span></span></span></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>a</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>b</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>c</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>d</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>e</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>f</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>g</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>h</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>i</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow><mo separator="true">,</mo><mspace width="1em"/><mi>B</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>j</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>k</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>l</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>m</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>n</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>o</mi></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>p</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>q</mi></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mi>r</mi></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">A=\begin{pmatrix}a&amp;b&amp;c\\d&amp;e&amp;f\\g&amp;h&amp;i\end{pmatrix},\quadB=\begin{pmatrix}j&amp;k&amp;l\\m&amp;n&amp;o\\p&amp;q&amp;r\end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎝</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M291 0 H417 V300 H291 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎛</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">b</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">e</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">h</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">c</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">i</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎠</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M457 0 H583 V300 H457 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎞</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎝</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M291 0 H417 V300 H291 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎛</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.05724em;">j</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">m</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03148em;">k</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">n</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">o</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎠</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M457 0 H583 V300 H457 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎞</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span></span></span></span></span></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mi>B</mi><mo>=</mo><mrow><mo fence="true">(</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>a</mi><mi>j</mi><mo>+</mo><mi>b</mi><mi>m</mi><mo>+</mo><mi>c</mi><mi>p</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>a</mi><mi>k</mi><mo>+</mo><mi>b</mi><mi>n</mi><mo>+</mo><mi>c</mi><mi>q</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>a</mi><mi>l</mi><mo>+</mo><mi>b</mi><mi>o</mi><mo>+</mo><mi>c</mi><mi>r</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>d</mi><mi>j</mi><mo>+</mo><mi>e</mi><mi>m</mi><mo>+</mo><mi>f</mi><mi>p</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>d</mi><mi>k</mi><mo>+</mo><mi>e</mi><mi>n</mi><mo>+</mo><mi>f</mi><mi>q</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>d</mi><mi>l</mi><mo>+</mo><mi>e</mi><mi>o</mi><mo>+</mo><mi>f</mi><mi>r</mi></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>g</mi><mi>j</mi><mo>+</mo><mi>h</mi><mi>m</mi><mo>+</mo><mi>i</mi><mi>p</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>g</mi><mi>k</mi><mo>+</mo><mi>h</mi><mi>n</mi><mo>+</mo><mi>i</mi><mi>q</mi></mrow></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mi>g</mi><mi>l</mi><mo>+</mo><mi>h</mi><mi>o</mi><mo>+</mo><mi>i</mi><mi>r</mi></mrow></mstyle></mtd></mtr></mtable><mo fence="true">)</mo></mrow></mrow><annotation encoding="application/x-tex">AB =\begin{pmatrix}aj+bm+cp &amp; ak+bn+cq &amp; al+bo+cr \\dj+em+fp &amp; dk+en+fq &amp; dl+eo+fr \\gj+hm+ip &amp; gk+hn+iq &amp; gl+ho+ir\end{pmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.60004em;vertical-align:-1.55002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎝</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M291 0 H417 V300 H291 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎛</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal">p</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal">p</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">m</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal">p</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.03148em;">k</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.03588em;">q</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">a</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">b</span><span class="mord mathnormal">o</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">c</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">e</span><span class="mord mathnormal">o</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">h</span><span class="mord mathnormal">o</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05002em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎠</span></span></span><span style="top:-3.2550000000000003em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="overlay" style="height:0.3em;width:0.875em;"><svg width='0.875em' height='0.3em' style='width:0.875em' viewBox='0 0 875 300' preserveAspectRatio='xMinYMin'><path d='M457 0 H583 V300 H457 z'/></svg></span></span><span style="top:-4.05002em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎞</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span></span></span></span></span></p><p>矩阵 A 是 2 行 3 列 2×3</p><figure class="highlight plaintext"><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">| 1  2  3 |</span><br><span class="line">| 4  5  6 |</span><br></pre></td></tr></table></figure><p>矩阵 B 是 3 行 2 列 3×2</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">| 1  2 |</span><br><span class="line">| 3  4 |</span><br><span class="line">| 5  6 |</span><br></pre></td></tr></table></figure><p>结果 C= A × B = 2×2</p><p>计算过程：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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">第 1 行 × 第 1 列：     1*1 + 2*3 + 3*5 = 1 + 6 + 15 = 22</span><br><span class="line">第 1 行 × 第 2 列：     1*2 + 2*4 + 3*6 = 2 + 8 + 18 = 28</span><br><span class="line">第 2 行 × 第 1 列：     4*1 + 5*3 + 6*5 = 4 + 15 + 30 = 49</span><br><span class="line">第 2 行 × 第 2 列：     4*2 + 5*4 + 6*6 = 8 + 20 + 36 = 64</span><br><span class="line">最终结果：</span><br><span class="line">| 22  28 |</span><br><span class="line">| 49  64 |</span><br></pre></td></tr></table></figure><p><strong>性质</strong></p><p>不满足交换律：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo>⋅</mo><mi>B</mi><mo mathvariant="normal">≠</mo><mi>B</mi><mo>⋅</mo><mi>A</mi></mrow><annotation encoding="application/x-tex">A \cdot B \ne B \cdot A</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel"><span class="mrel"><span class="mord vbox"><span class="thinbox"><span class="rlap"><span class="strut" style="height:0.8888799999999999em;vertical-align:-0.19444em;"></span><span class="inner"><span class="mrel"></span></span><span class="fix"></span></span></span></span></span><span class="mrel">=</span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span></span></span></span></span></p><p>满足分配律：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo stretchy="false">(</mo><mi>B</mi><mo>+</mo><mi>C</mi><mo stretchy="false">)</mo><mo>=</mo><mi>A</mi><mi>B</mi><mo>+</mo><mi>A</mi><mi>C</mi></mrow><annotation encoding="application/x-tex">A(B + C) = AB + AC</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">A</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span></span></span></span></span></p><p>满足结合律：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>A</mi><mo stretchy="false">(</mo><mi>B</mi><mi>C</mi><mo stretchy="false">)</mo><mo>=</mo><mo stretchy="false">(</mo><mi>A</mi><mi>B</mi><mo stretchy="false">)</mo><mi>C</mi></mrow><annotation encoding="application/x-tex">A(BC) = (AB)C</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">A</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">A</span><span class="mord mathnormal" style="margin-right:0.05017em;">B</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.07153em;">C</span></span></span></span></span></p><h3 id="hadamard-乘法逐元素乘"><a class="markdownIt-Anchor" href="#hadamard-乘法逐元素乘"></a> Hadamard 乘法（逐元素乘）</h3><p>要求两个矩阵形状一致。</p><p>示例：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>∘</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mo>−</mo><mn>1</mn></mrow></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>0</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mrow><mo>−</mo><mn>4</mn></mrow></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{bmatrix}1 &amp; 2 \\3 &amp; 4\end{bmatrix}\circ\begin{bmatrix}1 &amp; 2 \\0 &amp; -1\end{bmatrix}=\begin{bmatrix}1 &amp; 4 \\0 &amp; -4\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∘</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">−</span><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">−</span><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span></span></span></span></span></p><h3 id="矩阵转置transpose"><a class="markdownIt-Anchor" href="#矩阵转置transpose"></a> 矩阵转置（Transpose）</h3><p>行列互换。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mi>T</mi></msup><mo>=</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">\begin{bmatrix}1 &amp; 2 \\3 &amp; 4\end{bmatrix}^T=\begin{bmatrix}1 &amp; 3 \\2 &amp; 4\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.631261em;vertical-align:-0.95003em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.681231em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style="margin-right:0.13889em;">T</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span></span></span></span></span></p><p>例如：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>3</mn><mo>×</mo><mn>2</mn><mo>→</mo><mn>2</mn><mo>×</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">3 \times 2 \rightarrow 2 \times 3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span></span></p><h3 id="向量与矩阵转换"><a class="markdownIt-Anchor" href="#向量与矩阵转换"></a> 向量与矩阵转换</h3><p><strong>reshape</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo stretchy="false">]</mo><mo>→</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">[1,2,3,4]\rightarrow\begin{bmatrix}1 &amp; 2\\3 &amp; 4\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.40003em;vertical-align:-0.95003em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">[</span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.45em;"><span style="top:-3.61em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-2.4099999999999997em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.9500000000000004em;"><span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">]</span></span></span></span></span></span></span></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo separator="true">,</mo><mn>5</mn><mo separator="true">,</mo><mn>6</mn><mo stretchy="false">]</mo><mo>→</mo><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>5</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>6</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow></mrow><annotation encoding="application/x-tex">[1,2,3,4,5,6]\rightarrow\begin{bmatrix}1 &amp; 2\\3 &amp; 4\\5 &amp; 6\end{bmatrix}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">6</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:3.6010299999999997em;vertical-align:-1.55002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span></span></span></span></span></p><p><strong>flatten</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mrow><mo fence="true">[</mo><mtable rowspacing="0.15999999999999992em" columnspacing="1em"><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>1</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>2</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>3</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>4</mn></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>5</mn></mstyle></mtd><mtd><mstyle scriptlevel="0" displaystyle="false"><mn>6</mn></mstyle></mtd></mtr></mtable><mo fence="true">]</mo></mrow><mo>→</mo><mo stretchy="false">[</mo><mn>1</mn><mo separator="true">,</mo><mn>2</mn><mo separator="true">,</mo><mn>3</mn><mo separator="true">,</mo><mn>4</mn><mo separator="true">,</mo><mn>5</mn><mo separator="true">,</mo><mn>6</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">\begin{bmatrix}1 &amp; 2\\3 &amp; 4\\5 &amp; 6\end{bmatrix}\rightarrow[1,2,3,4,5,6]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:3.6010299999999997em;vertical-align:-1.55002em;"></span><span class="minner"><span class="mopen"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎣</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎢</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎡</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span><span class="mord"><span class="mtable"><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">3</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">5</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span><span class="arraycolsep" style="width:0.5em;"></span><span class="arraycolsep" style="width:0.5em;"></span><span class="col-align-c"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.05em;"><span style="top:-4.21em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">2</span></span></span><span style="top:-3.0099999999999993em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">4</span></span></span><span style="top:-1.8099999999999994em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">6</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.5500000000000007em;"><span></span></span></span></span></span></span></span><span class="mclose"><span class="delimsizing mult"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:2.0510099999999998em;"><span style="top:-2.2500000000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎦</span></span></span><span style="top:-2.8099900000000004em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎥</span></span></span><span style="top:-4.05101em;"><span class="pstrut" style="height:3.1550000000000002em;"></span><span class="delimsizinginner delim-size4"><span>⎤</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:1.55002em;"><span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">[</span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">2</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">3</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">5</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">6</span><span class="mclose">]</span></span></span></span></span></p><h2 id="张量tensor"><a class="markdownIt-Anchor" href="#张量tensor"></a> 张量（Tensor）</h2><p>矩阵是二维，张量是多维数据结构。</p><p>示例：</p><p>3 个 2×2 矩阵：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>3</mn><mo>×</mo><mn>2</mn><mo>×</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">3\times2\times2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span></span></p><p>4 个 3×2×2 张量：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mn>4</mn><mo>×</mo><mn>3</mn><mo>×</mo><mn>2</mn><mo>×</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">4\times3\times2\times2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">×</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span></span></span></span></span></p><p>在深度学习中，输入、输出、中间结果几乎都是张量。</p><h2 id="导数derivative"><a class="markdownIt-Anchor" href="#导数derivative"></a> 导数（Derivative）</h2><ul><li><p>如果函数是位置，导数就是速度</p></li><li><p>如果函数是距离变化，导数就是变化速度</p></li><li><p>函数曲线上某点的导数 = 该点切线斜率</p></li><li><p>变化方向（正增长还是负增长）</p></li><li><p>变化快慢（增长多快）</p></li><li><p>曲线斜率（图像有多陡）</p></li></ul><p>如果没有导数，你看不出未来趋势。<br />有了导数，你能预测变化、做优化、画切线、做智能算法。</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><munder><mo><mi>lim</mi><mo>⁡</mo></mo><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo>+</mo><mi mathvariant="normal">Δ</mi><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">f&#x27;(x_0) = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.171331em;vertical-align:-0.744331em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-2.355669em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">Δ</span><span class="mord mathnormal mtight">x</span><span class="mrel mtight">→</span><span class="mord mtight">0</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">lim</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.744331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">Δ</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><blockquote><p>函数在某个点x下标0的导数，就是函数值变化量与自变量变化量的比值，当变化量趋于无穷小</p></blockquote><p><strong>导数的直观理解（速度类比）</strong></p><p>想象你站在某条路上的一个位置：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msub><mi>x</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">x_0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.58056em;vertical-align:-0.15em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span></span></span></span></span></p><p>你想知道此刻你的 <strong>瞬时速度</strong>（也就是导数）。</p><p>你不能直接问&quot;现在速度是多少&quot;，<br />因为你只知道 <strong>位置</strong>，不是 <strong>速度</strong></p><p><strong>1. 走一点点距离</strong></p><p>向前走一小段距离：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi></mrow><annotation encoding="application/x-tex">\Delta x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span></span></span></span></span></p><p><strong>2. 看位置变化多少</strong></p><p>计算位置的变化：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo>+</mo><mi mathvariant="normal">Δ</mi><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">f(x_0 + \Delta x) - f(x_0)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span></span></p><p><strong>3. 求平均速度</strong></p><p>平均速度 = 路程变化 / 时间变化：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo>+</mo><mi mathvariant="normal">Δ</mi><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">\frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.113em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">Δ</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><p><strong>4. 但我们要的是&quot;瞬时速度&quot;！</strong></p><p>平均速度不够，我们想知道 <strong>这一瞬间的速度</strong>！</p><p>怎么办？</p><p>让这段&quot;时间&quot;越来越短：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi><mo>→</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">\Delta x \to 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">→</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></span></p><p><strong>5. 当时间趋近 0，平均速度变成瞬时速度</strong></p><p>于是得到：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><munder><mo><mi>lim</mi><mo>⁡</mo></mo><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo>+</mo><mi mathvariant="normal">Δ</mi><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">f&#x27;(x_0) = \lim_{\Delta x \to 0}\frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.171331em;vertical-align:-0.744331em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-2.355669em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">Δ</span><span class="mord mathnormal mtight">x</span><span class="mrel mtight">→</span><span class="mord mtight">0</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">lim</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.744331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">Δ</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><h3 id="幂函数求导"><a class="markdownIt-Anchor" href="#幂函数求导"></a> 幂函数求导</h3><p>公式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><msup><mi>x</mi><mi>n</mi></msup><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>n</mi><msup><mi>x</mi><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">(x^n)&#x27; = n x^{n-1}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.664392em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">n</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord mathnormal">n</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span></span></span></span></span></span></span></span></p><p>案例：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(x) = x^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span> 求导<br />解：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>2</mn><mi>x</mi></mrow><annotation encoding="application/x-tex">f&#x27;(x)=2x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal">x</span></span></span></span></p><h3 id="常数求导"><a class="markdownIt-Anchor" href="#常数求导"></a> 常数求导</h3><p>公式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>c</mi><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">(c)&#x27; = 0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">c</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></p><p>案例：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">f(x)=5</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">5</span></span></span></span><br />不管怎么移动 x，y 都不变，没变化 → 变化速度=0<br />解：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">f&#x27;(x)=0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">0</span></span></span></span></p><h3 id="线性函数求导"><a class="markdownIt-Anchor" href="#线性函数求导"></a> 线性函数求导</h3><p>公式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>a</mi><mi>x</mi><mo>+</mo><mi>b</mi><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mi>a</mi></mrow><annotation encoding="application/x-tex">(ax+b)&#x27; = a</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">a</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">a</span></span></span></span></p><p>案例：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>3</mn><mi>x</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">f(x)=3x+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span><br />线性函数求导=斜率<br />解：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">f&#x27;(x)=3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span></p><h3 id="乘积法则"><a class="markdownIt-Anchor" href="#乘积法则"></a> 乘积法则</h3><p>公式：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>+</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(f(x)g(x))&#x27;=f&#x27;(x)g(x)+f(x)g&#x27;(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></p><p>案例：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>x</mi><mo separator="true">,</mo><mtext>  </mtext><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">f(x)=x,\; g(x)=x^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><br />前导后不导 + 前不导后导<br />解：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>⋅</mo><msup><mi>x</mi><mn>2</mn></msup><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">(x \cdot x^2)&#x27;</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span><br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>⋅</mo><msup><mi>x</mi><mn>2</mn></msup><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>1</mn><mo>⋅</mo><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mi>x</mi><mo>⋅</mo><mn>2</mn><mi>x</mi></mrow><annotation encoding="application/x-tex">(x \cdot x^2)&#x27; = 1 \cdot x^2 + x \cdot 2x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.44445em;vertical-align:0em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal">x</span></span></span></span><br />化简：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>x</mi><mo>⋅</mo><msup><mi>x</mi><mn>2</mn></msup><msup><mo stretchy="false">)</mo><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><msup><mi>x</mi><mn>2</mn></msup><mo>=</mo><mn>3</mn><msup><mi>x</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">(x \cdot x^2)&#x27; = x^2 + 2x^2 = 3x^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.897438em;vertical-align:-0.08333em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord">3</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></p><h3 id="商法则"><a class="markdownIt-Anchor" href="#商法则"></a> 商法则</h3><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>公式：</mtext><msup><mrow><mo fence="true">(</mo><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow></mfrac><mo fence="true">)</mo></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mo stretchy="false">[</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><msup><mo stretchy="false">]</mo><mn>2</mn></msup></mrow></mfrac></mrow><annotation encoding="application/x-tex">\text{公式：}\left(\frac{f(x)}{g(x)}\right)&#x27; = \frac{f&#x27;(x)g(x)-f(x)g&#x27;(x)}{[g(x)]^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:2.5418220000000002em;vertical-align:-0.95003em;"></span><span class="mord text"><span class="mord cjk_fallback">公式：</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size3">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size3">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.591792em;"><span style="top:-3.9029000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.364892em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.428892em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><p>求导：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mrow><mo fence="true">(</mo><mfrac><mi>x</mi><msup><mi>x</mi><mn>2</mn></msup></mfrac><mo fence="true">)</mo></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup></mrow><annotation encoding="application/x-tex">\left(\frac{x}{x^2}\right)&#x27;</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.341802em;vertical-align:-0.35001em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.695392em;"><span style="top:-2.6550000000000002em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7463142857142857em;"><span style="top:-2.786em;margin-right:0.07142857142857144em;"><span class="pstrut" style="height:2.5em;"></span><span class="sizing reset-size3 size1 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.394em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">x</span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.345em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.991792em;"><span style="top:-3.3029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span></span></span></span></p><p><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>x</mi><mo separator="true">,</mo><mtext>  </mtext><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup><mo separator="true">,</mo><mspace width="1em"/><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo separator="true">,</mo><mtext>  </mtext><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>2</mn><mi>x</mi></mrow><annotation encoding="application/x-tex">f(x)=x,\; g(x)=x^2,\quad f&#x27;(x)=1,\; g&#x27;(x)=2x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">2</span><span class="mord mathnormal">x</span></span></span></span></p><p>代入商法则：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mrow><mo fence="true">(</mo><mfrac><mi>x</mi><msup><mi>x</mi><mn>2</mn></msup></mfrac><mo fence="true">)</mo></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mfrac><mrow><mn>1</mn><mo>⋅</mo><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><mi>x</mi><mo>⋅</mo><mn>2</mn><mi>x</mi></mrow><mrow><mo stretchy="false">(</mo><msup><mi>x</mi><mn>2</mn></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mfrac><mo>=</mo><mfrac><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>−</mo><mn>2</mn><msup><mi>x</mi><mn>2</mn></msup></mrow><msup><mi>x</mi><mn>4</mn></msup></mfrac><mo>=</mo><mfrac><mrow><mo>−</mo><msup><mi>x</mi><mn>2</mn></msup></mrow><msup><mi>x</mi><mn>4</mn></msup></mfrac><mo>=</mo><mo>−</mo><mfrac><mn>1</mn><msup><mi>x</mi><mn>2</mn></msup></mfrac></mrow><annotation encoding="application/x-tex">\left(\frac{x}{x^2}\right)&#x27; = \frac{1 \cdot x^2 - x \cdot 2x}{(x^2)^2} = \frac{x^2 - 2x^2}{x^4} = \frac{-x^2}{x^4} = -\frac{1}{x^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.977792em;vertical-align:-0.686em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size2">(</span></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.10756em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">x</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size2">)</span></span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:1.291792em;"><span style="top:-3.6029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.427108em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.491108em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">2</span><span class="mord mathnormal">x</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.177108em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.491108em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">2</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.177108em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.491108em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">−</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.00744em;vertical-align:-0.686em;"></span><span class="mord">−</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><h3 id="链式法则"><a class="markdownIt-Anchor" href="#链式法则"></a> 链式法则</h3><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>公式：</mtext><msup><mrow><mo fence="true">(</mo><mi>f</mi><mo stretchy="false">(</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo fence="true">)</mo></mrow><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\text{公式：}\left(f(g(x))\right)&#x27; = f&#x27;(g(x)) \cdot g&#x27;(x)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.1417920000000001em;vertical-align:-0.25em;"></span><span class="mord text"><span class="mord cjk_fallback">公式：</span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="minner"><span class="minner"><span class="mopen delimcenter" style="top:0em;">(</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span><span class="mclose delimcenter" style="top:0em;">)</span></span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.891792em;"><span style="top:-3.2029em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span></span></p><p>案例：<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>y</mi><mo>=</mo><mo stretchy="false">(</mo><mn>3</mn><mi>x</mi><mo>+</mo><mn>1</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">y = (3x+1)^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.064108em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></p><p>外层 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>u</mi><mn>2</mn></msup><mo separator="true">,</mo><mspace width="1em"/></mrow><annotation encoding="application/x-tex">f(u)=u^2,\quad</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.008548em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span></span></span></span> 内层 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>u</mi><mo>=</mo><mn>3</mn><mi>x</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">u=3x+1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">u</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span></span></span></span><br />外层先导，把 u 是内层带进去，再乘内层导数<br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">)</mo><mo>=</mo><mn>2</mn><mi>u</mi><mo separator="true">,</mo><mspace width="1em"/><msup><mi>u</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">f&#x27;(u)=2u,\quad u&#x27;=3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.001892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord">2</span><span class="mord mathnormal">u</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span><br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>2</mn><mo stretchy="false">(</mo><mn>3</mn><mi>x</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>⋅</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">y&#x27; = 2(3x+1) \cdot 3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">2</span><span class="mopen">(</span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">3</span></span></span></span><br /><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>6</mn><mo stretchy="false">(</mo><mn>3</mn><mi>x</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">y&#x27; = 6(3x+1)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">6</span><span class="mopen">(</span><span class="mord">3</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mclose">)</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>18</mn><mi>x</mi><mo>+</mo><mn>6</mn></mrow><annotation encoding="application/x-tex">y&#x27; = 18x+6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">8</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">6</span></span></span></span>，<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>y</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo>=</mo><mn>18</mn><mi>x</mi><mo>+</mo><mn>6</mn></mrow><annotation encoding="application/x-tex">y&#x27; = 18x+6</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.946332em;vertical-align:-0.19444em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mord">8</span><span class="mord mathnormal">x</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">6</span></span></span></span></p><h2 id="标准差"><a class="markdownIt-Anchor" href="#标准差"></a> 标准差</h2><p>数据：[2, 4, 6]</p><p><strong>1. 平均值：</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>μ</mi><mo>=</mo><mo stretchy="false">(</mo><mn>2</mn><mo>+</mo><mn>4</mn><mo>+</mo><mn>6</mn><mo stretchy="false">)</mo><mi mathvariant="normal">/</mi><mn>3</mn><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">\mu = (2 + 4 + 6) / 3 = 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.625em;vertical-align:-0.19444em;"></span><span class="mord mathnormal">μ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">6</span><span class="mclose">)</span><span class="mord">/</span><span class="mord">3</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span></span></p><p><strong>2. 差值平方：</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mo stretchy="false">(</mo><mn>2</mn><mo>−</mo><mn>4</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>4</mn><mo separator="true">,</mo><mspace width="1em"/><mo stretchy="false">(</mo><mn>4</mn><mo>−</mo><mn>4</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>0</mn><mo separator="true">,</mo><mspace width="1em"/><mo stretchy="false">(</mo><mn>6</mn><mo>−</mo><mn>4</mn><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>=</mo><mn>4</mn></mrow><annotation encoding="application/x-tex">(2-4)^2 = 4,\quad (4-4)^2 = 0,\quad (6-4)^2 = 4</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">2</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">0</span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord">6</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.1141079999999999em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">4</span></span></span></span></span></p><p><strong>3. 方差：</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>σ</mi><mn>2</mn></msup><mo>=</mo><mo stretchy="false">(</mo><mn>4</mn><mo>+</mo><mn>0</mn><mo>+</mo><mn>4</mn><mo stretchy="false">)</mo><mi mathvariant="normal">/</mi><mn>3</mn><mo>=</mo><mn>8</mn><mi mathvariant="normal">/</mi><mn>3</mn></mrow><annotation encoding="application/x-tex">\sigma^2 = (4 + 0 + 4) / 3 = 8/3</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8641079999999999em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8641079999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">4</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">4</span><span class="mclose">)</span><span class="mord">/</span><span class="mord">3</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord">8</span><span class="mord">/</span><span class="mord">3</span></span></span></span></span></p><p><strong>4. 标准差：</strong></p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>σ</mi><mo>=</mo><msqrt><mrow><mn>8</mn><mi mathvariant="normal">/</mi><mn>3</mn></mrow></msqrt><mo>≈</mo><mn>1.63</mn></mrow><annotation encoding="application/x-tex">\sigma = \sqrt{8/3} \approx 1.63</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.24em;vertical-align:-0.25612499999999994em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.983875em;"><span class="svg-align" style="top:-3.2em;"><span class="pstrut" style="height:3.2em;"></span><span class="mord" style="padding-left:1em;"><span class="mord">8</span><span class="mord">/</span><span class="mord">3</span></span></span><span style="top:-2.9438750000000002em;"><span class="pstrut" style="height:3.2em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.28em;"><svg width='400em' height='1.28em' viewBox='0 0 400000 1296' preserveAspectRatio='xMinYMin slice'><path d='M263,681c0.7,0,18,39.7,52,119c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120c340,-704.7,510.7,-1060.3,512,-1067l0 -0c4.7,-7.3,11,-11,19,-11H40000v40H1012.3s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60zM1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.25612499999999994em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≈</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.64444em;vertical-align:0em;"></span><span class="mord">1</span><span class="mord">.</span><span class="mord">6</span><span class="mord">3</span></span></span></span></span></p>]]></content>
    
    
    <summary type="html">路漫漫其修远兮，吾将上下而求索</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Python" scheme="https://luckynwa.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>Claude Code &amp; CodeX 配置手册</title>
    <link href="https://luckynwa.top/posts/ai1/"/>
    <id>https://luckynwa.top/posts/ai1/</id>
    <published>2026-02-28T21:44:01.000Z</published>
    <updated>2026-07-07T16:19:34.164Z</updated>
    
    <content type="html"><![CDATA[<h2 id="claude-code"><a class="markdownIt-Anchor" href="#claude-code"></a> Claude Code</h2><p>Claude Code是Anthropic打造的<strong>终端原生AI编程工具</strong></p><h3 id="环境要求"><a class="markdownIt-Anchor" href="#环境要求"></a> 环境要求</h3><p>NodeJS 18.0+，推荐使用 v24.13.0</p><h3 id="安装配置"><a class="markdownIt-Anchor" href="#安装配置"></a> 安装配置</h3><p>推荐使用 <a href="https://github.com/farion1231/cc-switch/releases/tag/v3.12.2">cc-switch</a> 统一管理配置</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></pre></td><td class="code"><pre><span class="line">npm config <span class="built_in">set</span> registry https://registry.npmmirror.com/    <span class="comment">#设置国内镜像源</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 全局安装最新稳定版</span></span><br><span class="line">npm install -g @anthropic-ai/claude-code</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证安装成功（显示版本号即生效）</span></span><br><span class="line">claude --version</span><br></pre></td></tr></table></figure><h3 id="token-plan-配置"><a class="markdownIt-Anchor" href="#token-plan-配置"></a> Token Plan 配置</h3><p>直接去 <code>C:\Users\Administrator\.claude</code> 下编辑 <code>settings.json</code>，配置小米AI的token plan即可</p><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;env&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_AUTH_TOKEN&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tp-c7p5iymh5lh28eg4e4f1hn2iyw1y????&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_BASE_URL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;https://token-plan-cn.xiaomimimo.com/anthropic&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;mimo-v2.5-pro&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;mimo-v2.5-pro&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;mimo-v2.5-pro&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;mimo-v2.5-pro&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_EFFORT_LEVEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;max&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;skipWebFetchPreflight&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="启动验证"><a class="markdownIt-Anchor" href="#启动验证"></a> 启动验证</h3><p>终端输入 <code>claude</code> 后确定，能看到以下信息说明配置成功：</p><figure class="highlight plaintext"><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">│   mimo-v2.5-pro ·API Usage Billing   │ Auto mode is now available for Max subscribers when using Opus 4.7</span><br><span class="line">│        C:\Users\Administrator</span><br></pre></td></tr></table></figure><h3 id="vscode-集成"><a class="markdownIt-Anchor" href="#vscode-集成"></a> VSCode 集成</h3><p>去VSCode插件市场搜索 <strong>Claude Code</strong> 集成，就能直接在VSCode上开发</p><h3 id="常用命令"><a class="markdownIt-Anchor" href="#常用命令"></a> 常用命令</h3><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">/context    <span class="comment"># 查看上下文用量，如果携带太多可以采用压缩</span></span><br><span class="line">/compact    <span class="comment"># 压缩上下文</span></span><br></pre></td></tr></table></figure><blockquote><p><strong>记忆与上下文的区别：</strong> 记忆可以跨越对话，上下文不行</p></blockquote><h3 id="技能配置"><a class="markdownIt-Anchor" href="#技能配置"></a> 技能配置</h3><p>这是全局的技能配置路径：<code>C:\Users\Administrator\.claude\skills</code> 下创建技能文件夹和它对应的 <code>SKILL.md</code></p><p>项目级技能配置：<code>.claude/skills/技能文件夹名/SKILL.md</code></p><p>创建子agents：<code>.claude/agents/tester.md</code>（测试专家）</p><h2 id="codex"><a class="markdownIt-Anchor" href="#codex"></a> CodeX</h2><h3 id="环境要求-2"><a class="markdownIt-Anchor" href="#环境要求-2"></a> 环境要求</h3><p>用 NodeJS v24.13.0</p><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</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></pre></td><td class="code"><pre><span class="line">npm install -g @openai/codex</span><br><span class="line"></span><br><span class="line">codex --version</span><br></pre></td></tr></table></figure><blockquote><p><strong>注意：</strong> 以前要是装过有缓存，可能请求超时，直接删除 <code>C:\Users\Administrator\.codex</code> 文件夹即可</p></blockquote><h3 id="使用步骤"><a class="markdownIt-Anchor" href="#使用步骤"></a> 使用步骤</h3><ol><li><p>创建一个空的文件夹项目，用来给codex表演，cmd进入这个文件夹</p></li><li><p>输入 <code>/</code> 去修改默认配置，model选最新的 <code>gpt-5.2-codex</code>，effort 选 <code>xhigh</code></p></li><li><p>继续输入 <code>/</code>，permissions 选 <code>full access</code>，给它全部权限</p></li><li><p>输入 <code>/init</code> 就能生成一个md文档</p></li></ol><h3 id="示例任务"><a class="markdownIt-Anchor" href="#示例任务"></a> 示例任务</h3><p>以下是一个完整的项目开发示例：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">我打算做一个新的电影评分软件，基本实现电影评分和评论功能，你需要完成整个项目的完整开发，并且部署上线，你需要抓取豆瓣上正在上线的电影，自动更新，这是一个完整的项目，你负责全部流程，最终交付给我部署后的网址，你可以利用相关部署的skills来帮助你，如果没有你自己搜索并下载使用，再交付前，你肉眼检查，没啥问题再给我</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">千淘万漉虽辛苦，吹尽狂沙始到金</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Ops" scheme="https://luckynwa.top/tags/Ops/"/>
    
  </entry>
  
  <entry>
    <title>从零搭建Python深度学习环境</title>
    <link href="https://luckynwa.top/posts/ai6/"/>
    <id>https://luckynwa.top/posts/ai6/</id>
    <published>2026-02-06T01:30:03.000Z</published>
    <updated>2026-07-07T16:19:33.930Z</updated>
    
    <content type="html"><![CDATA[<h2 id="conda-常用命令"><a class="markdownIt-Anchor" href="#conda-常用命令"></a> conda 常用命令</h2><p><strong>环境说明：</strong></p><ul><li><code>env_name</code>：创建的环境名称（如 <code>py312</code>）</li><li><code>package_name</code>：需要安装的包名（如 <code>numpy</code>）</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看所有环境</span></span><br><span class="line">conda env list</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进入某个py环境</span></span><br><span class="line">conda activate env_name</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">退出当前py环境</span></span><br><span class="line">conda deactivate</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">删除指定的py环境</span></span><br><span class="line">conda remove -n env_name --all</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">删除Anaconda镜像源并恢复默认</span></span><br><span class="line">conda config --remove-key channels</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看当前环境下是否安装了指定的包</span></span><br><span class="line">conda list | findstr 指定的包名       # win</span><br><span class="line">conda list | grep 指定的包名          # Mac</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看指定环境下是否安装了指定的包</span></span><br><span class="line">conda list -n env_name | findstr 指定的包名     # win</span><br><span class="line">conda list -n env_name | grep 指定的包名        # Mac</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装需要的第三方包（库）【进入到py虚拟环境下】</span></span><br><span class="line">conda install package_name          # 安装最新版</span><br><span class="line">conda install package_name==版本号   # 安装指定版本</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">conda安装不成功时，尝试pip命令</span></span><br><span class="line">pip install package_name==版本号 -i 源链接</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">卸载指定的包（库）【进入到py虚拟环境下】</span></span><br><span class="line">conda uninstall package_name</span><br><span class="line">pip uninstall package_name         # 通过pip安装的包卸载</span><br></pre></td></tr></table></figure><p><strong>常用镜像源：</strong></p><ul><li>清华源：<code>https://pypi.tuna.tsinghua.edu.cn/simple</code></li><li>阿里源：<code>https://mirrors.aliyun.com/pypi/simple</code></li></ul><h2 id="创建-py-环境"><a class="markdownIt-Anchor" href="#创建-py-环境"></a> 创建 py 环境</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">打开cmd创建python版本号为3.12的虚拟环境</span></span><br><span class="line">conda create -n py312 python=3.12         # 输入：y，回车</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">激活环境</span></span><br><span class="line">conda activate py312</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">退出当前环境</span></span><br><span class="line">conda deactivate</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">删除指定的py环境</span></span><br><span class="line">conda remove -n py312 --all</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装Jupyter相关包</span></span><br><span class="line">pip install jupyterlab</span><br><span class="line">pip install notebook</span><br><span class="line">python -m notebook                        # 浏览器中打开Jupyter Notebook</span><br></pre></td></tr></table></figure><h2 id="软件安装"><a class="markdownIt-Anchor" href="#软件安装"></a> 软件安装</h2><h3 id="miniconda"><a class="markdownIt-Anchor" href="#miniconda"></a> Miniconda</h3><p><strong>安装步骤：</strong></p><ol><li>新建文件夹 D:\soft\miniconda3</li><li>安装 <code>Miniconda3-py312_24.9.2-0-Windows-x86_64.exe</code>，默认下一步即可</li></ol><p>WIN+R 输入 cmd</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">conda init</span><br><span class="line">conda info</span><br><span class="line">先配置下面，记得创建文件夹cdataenv\pkgs 和 envs</span><br><span class="line">conda config --add pkgs_dirs D:\soft2\cdataenv\pkgs</span><br><span class="line">conda config --add envs_dirs D:\soft2\cdataenv\envs</span><br><span class="line"></span><br><span class="line">pip config set global.cache-dir D:\soft2\cdataenv\pip_cache</span><br><span class="line">setx PIP_CACHE_DIR D:\soft2\cdataenv\pip_cache</span><br><span class="line">set PIP_CACHE_DIR=D:\soft2\cdataenv\pip_cache</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">conda create -n py312 python=3.12         输入：y，回车</span><br><span class="line">conda create -n py310 python=3.10</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">conda activate py312</span><br><span class="line">(py312) C:\Users\Administrator&gt;where python</span><br><span class="line">C:\Users\Administrator\.conda\envs\py312\python.exe</span><br><span class="line"></span><br><span class="line">如果上面配置好了还是在c盘就问ai</span><br><span class="line">解决D:\soft\miniconda3我安装在这，为什么c盘里.conda占用12.6，我希望放这下D:\soft2\cdataenv</span><br></pre></td></tr></table></figure><h3 id="pycharm"><a class="markdownIt-Anchor" href="#pycharm"></a> Pycharm</h3><p><strong>作用：</strong> 用于编写 python 代码，运行课程中的代码</p><ul><li><a href="https://download.jetbrains.com/python/pycharm-professional-2024.1.3.exe">Win版下载（专业版）</a></li><li><a href="https://download.jetbrains.com/python/pycharm-community-2024.1.3-aarch64.dmg">Mac M4版下载</a></li></ul><p>激活码参考：pycharm 激活码</p><h2 id="深度学习环境配置"><a class="markdownIt-Anchor" href="#深度学习环境配置"></a> 深度学习环境配置</h2><blockquote><p>打开 cmd，进入需要的 py 环境：<code>conda activate py312</code></p></blockquote><h3 id="numpy"><a class="markdownIt-Anchor" href="#numpy"></a> Numpy</h3><p><strong>作用：</strong> 用于科学计算，提供了高性能的多维数组对象和丰富的数学函数</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install numpy==1.26.4 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><blockquote><p>当清华源下载失败时，可尝试更换为阿里源、别开代理</p></blockquote><h3 id="pandas"><a class="markdownIt-Anchor" href="#pandas"></a> Pandas</h3><p><strong>作用：</strong> 用于数据分析，提供了灵活的数据结构（如 DataFrame），使数据清洗和分析变得简单高效</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pandas==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="mineru"><a class="markdownIt-Anchor" href="#mineru"></a> Mineru</h3><p><strong>作用：</strong> 开源的，用于复杂PDF 文档解析和转换 的工具。它的核心目标是将 PDF 文档高效、准确地转换为易于编辑和阅读的Markdown 格式</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">pip install --upgrade pip -i https://mirrors.aliyun.com/pypi/simple</span><br><span class="line">pip install uv -i https://mirrors.aliyun.com/pypi/simple</span><br><span class="line">uv pip install -U &quot;mineru[core]&quot; -i https://mirrors.aliyun.com/pypi/simple</span><br></pre></td></tr></table></figure><p><strong>使用方法</strong></p><ul><li>命令行使用 （离线使用）</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mineru -p &lt;input_path&gt; -o &lt;output_path&gt;</span><br></pre></td></tr></table></figure><ul><li>fastapi 部署 （部署为服务，在线使用）</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mineru-api --host 0.0.0.0 --port 8000 --allow-public-http-client</span><br></pre></td></tr></table></figure><h3 id="jieba"><a class="markdownIt-Anchor" href="#jieba"></a> Jieba</h3><p><strong>作用：</strong> jieba 是一个专门用于中文文本分词的 Python 库，可以将连续的中文字符切分为有意义的词语</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install jieba -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="matplotlib"><a class="markdownIt-Anchor" href="#matplotlib"></a> Matplotlib</h3><p><strong>作用：</strong> 用于数据可视化，能够创建静态、动态和交互式图表</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install matplotlib==3.9.2 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="scikit-learn"><a class="markdownIt-Anchor" href="#scikit-learn"></a> Scikit-learn</h3><p><strong>作用：</strong> 提供了简单高效的数据挖掘和数据分析工具，支持多种机器学习算法</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install Scikit-learn==1.5.1 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="peft"><a class="markdownIt-Anchor" href="#peft"></a> Peft</h3><p><strong>作用：</strong> 模型微调</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install peft==0.15.0 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="transformers"><a class="markdownIt-Anchor" href="#transformers"></a> Transformers</h3><p><strong>作用：</strong> 通过自注意力机制和位置编码，实现对序列数据的高效处理</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install transformers==4.56.2 -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="fastapi"><a class="markdownIt-Anchor" href="#fastapi"></a> FastAPI</h3><p><strong>作用：</strong> 现代、快速（高性能）的 Python Web 框架，用于构建 API</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Win命令</span></span><br><span class="line">pip install fastapi[standard] -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">Mac命令</span></span><br><span class="line">pip install fastapi -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="mypy"><a class="markdownIt-Anchor" href="#mypy"></a> Mypy</h3><p><strong>作用：</strong> 静态类型检查工具，它使用 Python 的类型提示（Type Hints）来检查代码中的类型错误</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install mypy -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br></pre></td></tr></table></figure><h3 id="pytorch"><a class="markdownIt-Anchor" href="#pytorch"></a> Pytorch</h3><p><strong>作用：</strong> 深度学习领域的顶级框架，提供了构建和训练神经网络的工具</p><p><strong>CPU 版本安装：</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进入虚拟环境</span></span><br><span class="line">conda activate py312</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装CPU版本torch</span></span><br><span class="line">python -m pip install torch==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">测试是否安装成功</span></span><br><span class="line">python</span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; import torch</span></span><br><span class="line"><span class="meta prompt_">&gt;</span><span class="language-bash">&gt;&gt; <span class="built_in">print</span>(torch.__version__)</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">返回：2.6.0+cpu 代表安装成功</span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">安装GPU版本torch</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进入py312环境</span></span><br><span class="line">pip uninstall torch torchvision torchaudio -y</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">cmd执行</span></span><br><span class="line">nvidia-smi    # 发现cuda版本12.7    3060笔记本电脑和4060ti主机</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">3060-4080的GPU版本 个人的2台电脑，控制驱动版本</span></span><br><span class="line">pip install torch==2.6.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">5070ti的GPU版本</span></span><br><span class="line">pip install torch==2.11.0 torchvision torchaudio --index-url https://download.pytorch.org/whl/cu128</span><br><span class="line"></span><br><span class="line">import torch</span><br><span class="line">print(torch.cuda.is_available())</span><br><span class="line">print(torch.cuda.get_device_name(0))</span><br><span class="line">print(torch.cuda.current_device())</span><br><span class="line">print(torch.cuda.get_device_capability())</span><br></pre></td></tr></table></figure><h3 id="gensim"><a class="markdownIt-Anchor" href="#gensim"></a> Gensim</h3><p><strong>作用：</strong> 用于主题建模和文本相似性计算</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 class="meta prompt_"># </span><span class="language-bash">在线安装（推荐）</span></span><br><span class="line">conda activate py312</span><br><span class="line">pip install gensim -i https://pypi.tuna.tsinghua.edu.cn/simple</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">离线安装</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">1. 访问 https://pypi.org/project/gensim/</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">2. 点击 Release <span class="built_in">history</span> → 选择版本 → Download files</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">3. 下载对应的 .whl 文件（如 gensim-4.2.0-cp38-cp38-win_amd64.whl）</span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">4. 进入 whl 文件所在目录，执行：</span></span><br><span class="line">pip install gensim-4.2.0-cp38-cp38-win_amd64.whl</span><br></pre></td></tr></table></figure><h2 id="anaconda-与-miniconda-对比"><a class="markdownIt-Anchor" href="#anaconda-与-miniconda-对比"></a> Anaconda 与 Miniconda 对比</h2><h3 id="anaconda"><a class="markdownIt-Anchor" href="#anaconda"></a> Anaconda</h3><p>Anaconda 是一个开源的 Python 和 R 编程语言发行版，专为科学计算和数据科学设计。它简化了包管理和部署，自身包含了 python 解释器，不需要额外安装 Python SDK。</p><p><strong>主要特点：</strong></p><ul><li>包含了 Conda 包管理器，可以轻松安装、更新、管理和卸载 Python 包和依赖项</li><li>多版本支持：可以在同一系统上管理和切换不同版本的 Python 和包</li><li>默认安装了大量常用的包，适合需要快速搭建数据科学和机器学习环境的用户</li><li>提供了 Anaconda Navigator 图形界面，用户可以轻松管理包和环境</li></ul><p><strong>缺点：</strong></p><ul><li>安装包较大（几百兆到几个 GB），占用较多的磁盘空间</li><li>更新和维护所有包的版本不如手动安装的方式灵活</li></ul><h3 id="miniconda-2"><a class="markdownIt-Anchor" href="#miniconda-2"></a> Miniconda</h3><p>Miniconda 是 Anaconda 的一个精简版本，它仅包含 Conda 包管理器及其依赖项，用户可以根据需要安装其他包。</p><p><strong>优点：</strong></p><ul><li>轻量级：安装包小，安装速度快，占用磁盘空间少</li><li>灵活性：用户可以根据自己的需求安装需要的包</li></ul><p><strong>缺点：</strong></p><ul><li>初始安装后需要手动安装所需的包，适合有一定经验的用户</li><li>不包含 Anaconda Navigator 图形界面，所有操作需要通过命令行完成</li></ul><p><strong>总结：</strong> Miniconda 提供了与 Anaconda 同样的功能，但以更轻量和灵活的方式实现，所以安装 Anaconda 和 Miniconda 都是可以的。</p><h2 id="pycharm-配置-conda-环境"><a class="markdownIt-Anchor" href="#pycharm-配置-conda-环境"></a> Pycharm 配置 conda 环境</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">文件 → 设置 → 项目 → python 解释器 → 添加解释器 → Conda 环境 → 使用现有环境 → 选文件路径 D:\soft\miniconda3\Scripts\conda.exe → 加载环境 → 下拉选择需要的虚拟环境确定即可</span><br></pre></td></tr></table></figure><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">PyCharm →File → Settings → Tools → Terminal → Shell path 查看终端，默认进入这个环境</span><br><span class="line"></span><br><span class="line">cmd.exe /K &quot;D:\soft\miniconda3\condabin\conda.bat activate py312&quot;</span><br></pre></td></tr></table></figure><h3 id="激活码"><a class="markdownIt-Anchor" href="#激活码"></a> 激活码</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">EUWT4EE9X2-eyJsaWNlbnNlSWQiOiJFVVdUNEVFOVgyIiwibGljZW5zZWVOYW1lIjoic2lnbnVwIHNjb290ZXIiLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJQU0kiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjpmYWxzZX0seyJjb2RlIjoiUFBDIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQV1MiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBDV01QIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfV0sIm1ldGFkYXRhIjoiMDEyMDIyMDkwMlBTQU4wMDAwMDUiLCJoYXNoIjoiVFJJQUw6MzUzOTQ0NTE3IiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-FT9l1nyyF9EyNmlelrLP9rGtugZ6sEs3CkYIKqGgSi608LIamge623nLLjI8f6O4EdbCfjJcPXLxklUe1O/5ASO3JnbPFUBYUEebCWZPgPfIdjw7hfA1PsGUdw1SBvh4BEWCMVVJWVtc9ktE+gQ8ldugYjXs0s34xaWjjfolJn2V4f4lnnCv0pikF7Ig/Bsyd/8bsySBJ54Uy9dkEsBUFJzqYSfR7Z/xsrACGFgq96ZsifnAnnOvfGbRX8Q8IIu0zDbNh7smxOwrz2odmL72UaU51A5YaOcPSXRM9uyqCnSp/ENLzkQa/B9RNO+VA7kCsj3MlJWJp5Sotn5spyV+gA==-MIIETDCCAjSgAwIBAgIBDTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTIwMTAxOTA5MDU1M1oXDTIyMTAyMTA5MDU1M1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyMDEwMTkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUlaUFc1wf+CfY9wzFWEL2euKQ5nswqb57V8QZG7d7RoR6rwYUIXseTOAFq210oMEe++LCjzKDuqwDfsyhgDNTgZBPAaC4vUU2oy+XR+Fq8nBixWIsH668HeOnRK6RRhsr0rJzRB95aZ3EAPzBuQ2qPaNGm17pAX0Rd6MPRgjp75IWwI9eA6aMEdPQEVN7uyOtM5zSsjoj79Lbu1fjShOnQZuJcsV8tqnayeFkNzv2LTOlofU/Tbx502Ro073gGjoeRzNvrynAP03pL486P3KCAyiNPhDs2z8/COMrxRlZW5mfzo0xsK0dQGNH3UoG/9RVwHG4eS8LFpMTR9oetHZBAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUJNoRIpb1hUHAk0foMSNM9MCEAv8wSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBABqRoNGxAQct9dQUFK8xqhiZaYPd30TlmCmSAaGJ0eBpvkVeqA2jGYhAQRqFiAlFC63JKvWvRZO1iRuWCEfUMkdqQ9VQPXziE/BlsOIgrL6RlJfuFcEZ8TK3syIfIGQZNCxYhLLUuet2HE6LJYPQ5c0jH4kDooRpcVZ4rBxNwddpctUO2te9UU5/FjhioZQsPvd92qOTsV+8Cyl2fvNhNKD1Uu9ff5AkVIQn4JU23ozdB/R5oUlebwaTE6WZNBs+TA/qPj+5/we9NH71WRB0hqUoLI2AKKyiPw++FtN4Su1vsdDlrAzDj9ILjpjJKA1ImuVcG329/WTYIKysZ1CWK3zATg9BeCUPAV1pQy8ToXOq+RSYen6winZ2OO93eyHv2Iw5kbn1dqfBw1BuTE29V2FJKicJSu8iEOpfoafwJISXmz1wnnWL3V/0NxTulfWsXugOoLfv0ZIBP1xH9kmf22jjQ2JiHhQZP7ZDsreRrOeIQ/c4yR8IQvMLfC0WKQqrHu5ZzXTH4NO3CwGWSlTY74kE91zXB5mwWAx1jig+UXYc2w4RkVhy0//lOmVya/PEepuuTTI4+UJwC7qbVlh5zfhj8oTNUXgN0AOc+Q0/WFPl1aw5VV/VrO8FCoB15lFVlpKaQ1Yh+DVU8ke+rt9Th0BCHXe0uZOEmH0nOnH/0onD</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">读书不觉已春深，一寸光阴一寸金</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Python" scheme="https://luckynwa.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>llama.cpp、Ollama、LM Studio新手避坑指南</title>
    <link href="https://luckynwa.top/posts/ai7/"/>
    <id>https://luckynwa.top/posts/ai7/</id>
    <published>2025-12-12T16:51:15.000Z</published>
    <updated>2026-07-07T16:19:34.121Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h1><p>llama.cpp 是&quot;底层推理引擎&quot;，Ollama 和 LM Studio 均是基于它封装的上层应用，Ollama 是&quot;命令行版&quot;，LM Studio 是&quot;图形界面版&quot;，三者本质都是让你在自己电脑上跑大模型，只是封装层级不同。</p><h1 id="ollama"><a class="markdownIt-Anchor" href="#ollama"></a> Ollama</h1><p>Ollama是一个开源的大型语言模型服务工具，它帮助用户快速在本地运行大模型。</p><p><strong>除了要搭建服务给别人调用，否则不推荐使用！</strong></p><p>官网下载安装包：<a href="https://ollama.com/">https://ollama.com/</a></p><p>1、默认是安装到C盘的，改N盘，N:\AI\Ollama新建它<br />2、将OLLAMA的安装包放在N:\AI\Ollama下<br />3、路径CMD回车<br /><code>OllamaSetup.exe /DIR=N:\AI\OLLAMA</code></p><p>设置它，创建N:\AI\Ollama\models放模型</p><p>首先看显卡性能、6g显存–&gt;qwen:4b 无显存–&gt;qwen:0.5b</p><p>ollama <a href="https://github.com/ollama/ollama">https://github.com/ollama/ollama</a></p><p>个人登录 <a href="https://ollama.com/luckyNwa%EF%BC%8C%E8%83%BD%E9%A2%86%E5%8F%96%E5%85%8D%E8%B4%B9%E7%9A%84cloud%E6%A8%A1%E5%9E%8B%E4%BD%BF%E7%94%A8">https://ollama.com/luckyNwa，能领取免费的cloud模型使用</a></p><p>查看模型库qwen2</p><p><a href="https://ollama.com/library/qwen2">https://ollama.com/library/qwen2</a></p><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></pre></td><td class="code"><pre><span class="line">ollama list</span><br><span class="line"></span><br><span class="line">N100 无显卡</span><br><span class="line">ollama run qwen:0.5b</span><br><span class="line">ollama run qwen3.5:cloud    云端有免费额度</span><br><span class="line">ollama run qwen3.5:397b-cloud</span><br><span class="line"></span><br><span class="line">ollama run gemma-4-26b-local</span><br><span class="line">ollama <span class="built_in">rm</span> gemma-4-26b-local     移除模型</span><br></pre></td></tr></table></figure><h2 id="api"><a class="markdownIt-Anchor" href="#api"></a> API</h2><p>访问地址：<code>http://ip:11434/api/generate</code></p><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;model&quot;</span><span class="punctuation">:</span> <span class="string">&quot;qwen:0.5b&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;prompt&quot;</span><span class="punctuation">:</span> <span class="string">&quot;你是谁?&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>返回 JSON 对象流。</p><p>更多 API 查看：<a href="https://github.com/ollama/ollama/blob/main/docs/api.md">Ollama API 文档</a></p><h2 id="环境变量配置"><a class="markdownIt-Anchor" href="#环境变量配置"></a> 环境变量配置</h2><p>如果想将本地运行的模型外网或局域网访问，则需要去配置 <strong>环境变量</strong></p><p>修改 IP 访问：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">OLLAMA_HOST=0.0.0.0:11434</span><br></pre></td></tr></table></figure><p>修改跨域访问：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">OLLAMA_ORIGINS=*</span><br></pre></td></tr></table></figure><blockquote><p>否则访问会出现 403，再关闭 Ollama 重启即可，笔记本防火墙需要关闭。</p></blockquote><p>修改 GPU 释放：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">OLLAMA_KEEP_ALIVE=2m</span><br></pre></td></tr></table></figure><blockquote><p>默认是 5m，降低 GPU 占用。</p></blockquote><p>修改模型位置：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">OLLAMA_MODELS=D:\lucky\OllamaModels</span><br></pre></td></tr></table></figure><p>改完关闭进程，再 cmd 启动：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ollama run qwen:0.5b</span><br></pre></td></tr></table></figure><h2 id="使用docker安装"><a class="markdownIt-Anchor" href="#使用docker安装"></a> 使用docker安装</h2><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></pre></td><td class="code"><pre><span class="line">docker pull registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/ollama</span><br><span class="line"></span><br><span class="line">docker run -d -v /nwa/ollama:/root/.ollama -p 11434:11434 --privileged=true --name ollama registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/ollama</span><br><span class="line"></span><br><span class="line">docker exec -it ollama ollama run qwen:0.5b</span><br></pre></td></tr></table></figure><h3 id="进入容器操作"><a class="markdownIt-Anchor" href="#进入容器操作"></a> 进入容器操作</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">docker exec -it ollama bash</span><br><span class="line">ollama run qwen:0.5b</span><br><span class="line">export OLLAMA_HOST=0.0.0.0:11434</span><br></pre></td></tr></table></figure><blockquote><p>搞半天没啥软用，端口忘记穿透了</p></blockquote><h3 id="网络配置"><a class="markdownIt-Anchor" href="#网络配置"></a> 网络配置</h3><p>发现在 1Panel 中的 IP 地址是 <code>172.17.0.5</code>，每次重启容器会变，需要注意。分析之后发现都存于 <code>172.17.0.1</code> 这个网关下，填这个就行了。而且 MaxKB（看另一篇文章） 也是这个地址，可以直接输入它在 MaxKB 中：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://172.17.0.5:11434</span><br></pre></td></tr></table></figure><h1 id="llamacpp"><a class="markdownIt-Anchor" href="#llamacpp"></a> llama.cpp</h1><p>llama.cpp的Github地址：<a href="https://github.com/ggml-org/llama.cpp/releases">Releases · ggml-org/llama.cpp</a></p><p>N:\AI\llama.cpp下安装2个llama.cpp，一个12版本一个13版本的 , 13需要比较新的驱动和显卡</p><p>复制C:\Program Files\NVIDIA GPU Computing Toolkit\ 到文件夹地址上并查看当前cuda工具包的版本====CUDA\v12.2的</p><p>发现是12的，下载12的<a href="https://github.com/ggml-org/llama.cpp/releases/tag/b8828?utm_source=chatgpt.com">Release b8828 · ggml-org/llama.cpp</a> 8828版本稳定点</p><p>下载13的去<a href="https://developer.nvidia.com/cuda-downloads?target_os=Windows&amp;target_arch=x86_64&amp;target_version=10&amp;target_type=exe_local">https://developer.nvidia.com/cuda-downloads?target_os=Windows&amp;target_arch=x86_64&amp;target_version=10&amp;target_type=exe_local</a></p><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">nvcc --version   当前使用版本</span><br><span class="line">nvidia-smi</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><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cmd 路径 N:\AI\llama.cpp\cuda12</span><br><span class="line"></span><br><span class="line">.\llama-cli.exe -m ..\models\ZL-Qwen3.6-35B-MOE-FP4.gguf -ngl 100 --color auto --reasoning off</span><br></pre></td></tr></table></figure><p>异常 回答速度 [ Prompt: 43.8 t/s | Generation: 10.9 t/s ]</p><p>正常速度 [ Prompt: 133.5 t/s | Generation: 21.4 t/s ] 4080 16g显存，这个混合专家模型18.4GB</p><p>去N:\AI\llama.cpp\cuda12下cmd运行</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">.\llama-bench.exe --list-devices    输入这个查看cuda有没有用上</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><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">N:\AI\llama.cpp\cuda12&gt;.\llama-bench.exe --list-devices</span><br><span class="line">ggml_cuda_init: found 1 CUDA devices (Total VRAM: 16375 MiB):</span><br><span class="line">  Device 0: NVIDIA GeForce RTX 4080, compute capability 8.9, VMM: yes, VRAM: 16375 MiB</span><br><span class="line">load_backend: loaded CUDA backend from N:\AI\llama.cpp\cuda12\ggml-cuda.dll</span><br><span class="line">load_backend: loaded RPC backend from N:\AI\llama.cpp\cuda12\ggml-rpc.dll</span><br><span class="line">load_backend: loaded CPU backend from N:\AI\llama.cpp\cuda12\ggml-cpu-alderlake.dll</span><br><span class="line">Available devices:</span><br><span class="line">  CUDA0: NVIDIA GeForce RTX 4080 (16375 MiB, 15048 MiB free)</span><br></pre></td></tr></table></figure><p>测试拉满这个12g模型，显卡对应token速度</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">.\llama-bench.exe -m ..\models\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL.gguf -ngl 100</span><br></pre></td></tr></table></figure><p>cuda版本没对上用cpu运行结果如下：</p><figure class="highlight text"><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">N:\AI\llama.cpp\cuda12&gt;.\llama-bench.exe -m ..\models\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL.gguf -ngl 100</span><br><span class="line"></span><br><span class="line">load_backend: loaded RPC backend from N:\AI\llama\llama-b8827-bin-win-cuda-13.1-x64\ggml-rpc.dll</span><br><span class="line">load_backend: loaded CPU backend from N:\AI\llama\llama-b8827-bin-win-cuda-13.1-x64\ggml-cpu-alderlake.dll</span><br><span class="line">| model                          |       size |     params | backend    | threads |            test |                  t/s |</span><br><span class="line">| ------------------------------ | ---------: | ---------: | ---------- | ------: | --------------: | -------------------: |</span><br><span class="line">| gemma4 ?B IQ4_NL - 4.5 bpw     |  12.48 GiB |    25.23 B | CPU        |      16 |           pp512 |         52.06 ± 0.09 |</span><br><span class="line">| gemma4 ?B IQ4_NL - 4.5 bpw     |  12.48 GiB |    25.23 B | CPU        |      16 |           tg128 |         10.69 ± 0.10 |</span><br><span class="line"></span><br><span class="line">build: fcc750875 (8828)</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><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">N:\AI\llama.cpp\cuda12&gt;.\llama-bench.exe -m ..\models\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL.gguf -ngl 100</span><br><span class="line">ggml_cuda_init: found 1 CUDA devices (Total VRAM: 16375 MiB):</span><br><span class="line">  Device 0: NVIDIA GeForce RTX 4080, compute capability 8.9, VMM: yes, VRAM: 16375 MiB</span><br><span class="line">load_backend: loaded CUDA backend from N:\AI\llama.cpp\cuda12\ggml-cuda.dll</span><br><span class="line">load_backend: loaded RPC backend from N:\AI\llama.cpp\cuda12\ggml-rpc.dll</span><br><span class="line">load_backend: loaded CPU backend from N:\AI\llama.cpp\cuda12\ggml-cpu-alderlake.dll</span><br><span class="line">| model                          |       size |     params | backend    | ngl |            test |                  t/s |</span><br><span class="line">| ------------------------------ | ---------: | ---------: | ---------- | --: | --------------: | -------------------: |</span><br><span class="line">| gemma4 26B.A4B IQ4_NL - 4.5 bpw |  12.48 GiB |    25.23 B | CUDA       | 100 |           pp512 |     5417.02 ± 110.14 |</span><br><span class="line">| gemma4 26B.A4B IQ4_NL - 4.5 bpw |  12.48 GiB |    25.23 B | CUDA       | 100 |           tg128 |        131.50 ± 0.50 |</span><br><span class="line"></span><br><span class="line">build: fcc750875 (8828)</span><br></pre></td></tr></table></figure><p>4080 16G显存结果：</p><figure class="highlight text"><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">N:\AI\llama.cpp\cuda12&gt;.\llama-bench.exe -m ..\models\Qwen3-14B-Q4_K_M.gguf -ngl 100</span><br><span class="line">ggml_cuda_init: found 1 CUDA devices (Total VRAM: 16375 MiB):</span><br><span class="line">  Device 0: NVIDIA GeForce RTX 4080, compute capability 8.9, VMM: yes, VRAM: 16375 MiB</span><br><span class="line">load_backend: loaded CUDA backend from N:\AI\llama.cpp\cuda12\ggml-cuda.dll</span><br><span class="line">load_backend: loaded RPC backend from N:\AI\llama.cpp\cuda12\ggml-rpc.dll</span><br><span class="line">load_backend: loaded CPU backend from N:\AI\llama.cpp\cuda12\ggml-cpu-alderlake.dll</span><br><span class="line">| model                          |       size |     params | backend    | ngl |            test |                  t/s |</span><br><span class="line">| ------------------------------ | ---------: | ---------: | ---------- | --: | --------------: | -------------------: |</span><br><span class="line">| qwen3 14B Q4_K - Medium        |   8.38 GiB |    14.77 B | CUDA       | 100 |           pp512 |     3866.13 ± 125.80 |</span><br><span class="line">| qwen3 14B Q4_K - Medium        |   8.38 GiB |    14.77 B | CUDA       | 100 |           tg128 |         66.49 ± 0.03 |</span><br><span class="line"></span><br><span class="line">build: fcc750875 (8828)</span><br></pre></td></tr></table></figure><p>3080 10Gx显存结果：</p><figure class="highlight text"><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">D:\AI\llama.cpp\cuda12&gt;.\llama-bench.exe -m ..\models\Qwen3-14B-Q4_K_M.gguf -ngl 100</span><br><span class="line">ggml_cuda_init: found 1 CUDA devices (Total VRAM: 10239 MiB):</span><br><span class="line">  Device 0: NVIDIA GeForce RTX 3080, compute capability 8.6, VMM: yes, VRAM: 10239 MiB</span><br><span class="line">load_backend: loaded CUDA backend from D:\AI\llama.cpp\cuda12\ggml-cuda.dll</span><br><span class="line">load_backend: loaded RPC backend from D:\AI\llama.cpp\cuda12\ggml-rpc.dll</span><br><span class="line">load_backend: loaded CPU backend from D:\AI\llama.cpp\cuda12\ggml-cpu-zen4.dll</span><br><span class="line">| model                          |       size |     params | backend    | ngl |            test |                  t/s |</span><br><span class="line">| ------------------------------ | ---------: | ---------: | ---------- | --: | --------------: | -------------------: |</span><br><span class="line">| qwen3 14B Q4_K - Medium        |   8.38 GiB |    14.77 B | CUDA       | 100 |           pp512 |      2341.71 ± 48.03 |</span><br><span class="line">| qwen3 14B Q4_K - Medium        |   8.38 GiB |    14.77 B | CUDA       | 100 |           tg128 |         65.09 ± 0.76 |</span><br><span class="line"></span><br><span class="line">build: fcc750875 (8828)</span><br></pre></td></tr></table></figure><p>16G显存跑下面</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></pre></td><td class="code"><pre><span class="line">.\llama-server.exe -m N:\AI\llama.cpp\models\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL.gguf -ngl 100 -c 16384 -ctk q8_0 -ctv q8_0</span><br><span class="line"></span><br><span class="line">.\llama-server.exe -m <span class="string">&quot;N:\AI\llama.cpp\models\Qwen3-Coder-30B-A3B-Instruct-Q3_K_M\Qwen3-Coder-30B-A3B-Instruct-Q3_K_M\Qwen3-Coder-30B-A3B-Instruct-Q3_K_M.gguf&quot;</span> -ngl 100 -c 16384 -ctk q8_0 -ctv q8_0</span><br></pre></td></tr></table></figure><p>10G显存跑</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></pre></td><td class="code"><pre><span class="line">.\llama-server.exe -m <span class="string">&quot;..\models\Qwen3-14B-Q4_K_M.gguf&quot;</span> -ngl 999 -c 4096 -ctk q4_0 -ctv q4_0 -fa on --host 0.0.0.0 --port 8080</span><br><span class="line"></span><br><span class="line">3080、4080跑这个模型都 59 t/s</span><br></pre></td></tr></table></figure><p><a href="http://127.0.0.1:8080">http://127.0.0.1:8080</a></p><h1 id="lm-studio"><a class="markdownIt-Anchor" href="#lm-studio"></a> LM Studio</h1><p>它就是一个&quot;本地版 ChatGPT&quot;——你可以把各种开源大模型下载到电脑上，断网也能用，而且所有数据都不上传云端，完全隐私安全</p><p><a href="https://lmstudio.ai">https://lmstudio.ai</a></p><p>安装进入自动llama.cpp-win-x86_64-nvidia-cuda12-avx2 (2.13.0)这个比较慢，开科学虚拟卡模式</p><h1 id="模型下载"><a class="markdownIt-Anchor" href="#模型下载"></a> 模型下载</h1><p><a href="https://www.modelscope.cn/models">国内模型库（ModelScope）</a></p><p><a href="https://www.modelscope.cn/models/unsloth/gemma-4-26B-A4B-it-GGUF?utm_source=copilot.com">gemma-4-26B-A4B-it-GGUF · 模型库</a></p><p>页面的右边有4bit的，Q4量化的，可以在4080显卡16g显存下跑，下载放到N:\AI\llama.cpp\models\gemma-4-26B-A4B-it-UD-IQ4_NL\gemma-4-26B-A4B-it-UD-IQ4_NL下</p><p><strong>别装了，ollama太拉了，就是llamcpp套一层壳的，速度还比llamcpp慢，用lm studio和llamcpp折腾玩耍大模型</strong></p><p>新建Modelfile</p><figure class="highlight text"><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">FROM ./gemma-4-26B-A4B-it-UD-IQ4_NL.gguf</span><br><span class="line">TEMPLATE &quot;&quot;&quot;&#123;&#123; .Prompt &#125;&#125;&quot;&quot;&quot;</span><br></pre></td></tr></table></figure><p>cmd 进入这个路径</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">ollama create gemma-4-26b-local -f Modelfile</span><br></pre></td></tr></table></figure><p>出现success 即可</p><p>需要科学上网：<a href="https://huggingface.co/models">国外模型库（huggingface）</a></p><h1 id="ai-大模型客户端"><a class="markdownIt-Anchor" href="#ai-大模型客户端"></a> AI 大模型客户端</h1><p>连接用户与大模型之间的&quot;桥梁&quot;或&quot;遥控器&quot;，自身不包含大模型，需要搭配后端服务使用</p><h2 id="lobe-chat"><a class="markdownIt-Anchor" href="#lobe-chat"></a> Lobe Chat</h2><p>Lobe Chat是一个可以本地部署的、支持多模型的 AI 聊天客户端，类似于一个&quot;万能 AI 遥控器&quot;，把各种大模型整合到一个界面里统一管理</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 3210:3210 -e OLLAMA_PROXY_URL=http://host.docker.internal:11434 lobehub/lobe-chat</span><br></pre></td></tr></table></figure><p>去设置那语言模型，只勾选 Ollama，模型列表只留下 <code>deepseek-r1:7b</code>，再检查默认助手（模型就选 <code>deepseek-r1:7b</code>）只能使用。</p><h2 id="cherry-studio使用中"><a class="markdownIt-Anchor" href="#cherry-studio使用中"></a> Cherry Studio（使用中）</h2><p>Cherry Studio 是一款全能型 AI 助手桌面客户端,能把各种大模型统一接入的&quot;AI 工作台</p><p>直接去官网下载win版本，配置一下，开箱即用</p><p><a href="https://cherry-ai.com">https://cherry-ai.com</a></p><h2 id="其他"><a class="markdownIt-Anchor" href="#其他"></a> 其他</h2><table><thead><tr><th>层级</th><th>工具</th></tr></thead><tbody><tr><td>纯聊天界面</td><td>Chatbox、NextChat</td></tr><tr><td>聊天 + 多模型管理</td><td>LobeChat、Cherry Studio</td></tr><tr><td>聊天 + 知识库 + 插件</td><td>Open WebUI、AnythingLLM</td></tr><tr><td>本地模型运行器</td><td>Ollama、LM Studio、llama.cpp</td></tr></tbody></table>]]></content>
    
    
    <summary type="html">黑发不知勤学早，白首方悔读书迟</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>Vercel一键部署AI聊天助手</title>
    <link href="https://luckynwa.top/posts/website_construction2/"/>
    <id>https://luckynwa.top/posts/website_construction2/</id>
    <published>2025-11-07T20:42:42.000Z</published>
    <updated>2026-07-07T16:16:50.376Z</updated>
    
    <content type="html"><![CDATA[<h1 id="项目简介"><a class="markdownIt-Anchor" href="#项目简介"></a> 项目简介</h1><blockquote><p>基于开源项目 <a href="https://github.com/Yidadaa/ChatGPT-Next-Web">ChatGPT-Next-Web</a> 搭建的私人 ChatGPT 聊天应用，支持自定义域名访问。</p></blockquote><h1 id="搭建步骤"><a class="markdownIt-Anchor" href="#搭建步骤"></a> 搭建步骤</h1><h2 id="1获取源码并部署"><a class="markdownIt-Anchor" href="#1获取源码并部署"></a> （1）获取源码并部署</h2><p>访问开源项目仓库：<a href="https://github.com/Yidadaa/ChatGPT-Next-Web">https://github.com/Yidadaa/ChatGPT-Next-Web</a></p><p>在页面下方找到 <strong>Deploy</strong> 按钮，点击进入 Vercel 平台进行部署：</p><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa/lucky-pic-bed@main/img/image-20240709102430639.png" alt="image-20240709102430639" /></p><h2 id="2配置环境变量"><a class="markdownIt-Anchor" href="#2配置环境变量"></a> （2）配置环境变量</h2><ul><li><strong>项目名称</strong>：可自定义，如 <code>lucky-next-chat</code></li><li><strong>OPENAI_API_KEY</strong>：ChatGPT 的 API 密钥（可通过淘宝购买）</li><li><strong>CODE</strong>：网站访问密码</li></ul><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa/lucky-pic-bed@main/img/image-20240709104449387.png" alt="image-20240709104449387" /></p><h2 id="3完成部署"><a class="markdownIt-Anchor" href="#3完成部署"></a> （3）完成部署</h2><p>点击 <strong>Deploy</strong> 后，等待片刻直到显示 <code>Congratulations!</code>，然后点击继续。</p><blockquote><p>Vercel 管理地址：<a href="https://vercel.com/luckynwa6/chat-gpt-next-web">https://vercel.com/luckynwa6/chat-gpt-next-web</a></p></blockquote><h2 id="4配置自定义域名"><a class="markdownIt-Anchor" href="#4配置自定义域名"></a> （4）配置自定义域名</h2><p><strong>Vercel 添加域名：</strong></p><p>进入 <strong>Settings → Domains → Add</strong>，输入你的二级域名（如 <code>chat.luckynwa.top</code>）</p><p><strong>DNS 解析配置：</strong></p><p>前往你的域名服务商（如 DNSPod），添加域名解析记录：</p><blockquote><p>DNSPod 管理地址：<a href="https://console.dnspod.cn/dns/luckynwa.top/record">https://console.dnspod.cn/dns/luckynwa.top/record</a></p></blockquote><h2 id="5更新密钥"><a class="markdownIt-Anchor" href="#5更新密钥"></a> （5）更新密钥</h2><p>如果需要更换 API Key 或密码，进入 Vercel 项目的 <strong>Settings → Environment Variables</strong> 进行修改。</p><blockquote><p>修改后需要重新部署才能生效</p></blockquote><h1 id="最终访问"><a class="markdownIt-Anchor" href="#最终访问"></a> 最终访问</h1><p>配置完成后，通过你的域名即可访问：</p><p><a href="https://chat.luckynwa.top/#/">https://chat.luckynwa.top/#/</a></p>]]></content>
    
    
    <summary type="html">粉骨碎身浑不怕，要留清白在人间</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>NumPy 矩阵运算速查手册</title>
    <link href="https://luckynwa.top/posts/ai3222/"/>
    <id>https://luckynwa.top/posts/ai3222/</id>
    <published>2025-11-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:19:34.192Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h1><p>numpy一般用来定义矩阵并调用里面的方法</p><figure class="highlight py"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">arr1 = np.arange(<span class="number">15</span>).reshape(<span class="number">3</span>, <span class="number">5</span>)  <span class="comment"># 创建ndarray对象</span></span><br><span class="line"><span class="built_in">print</span>(arr1)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的轴：<span class="subst">&#123;arr1.ndim&#125;</span>&#x27;</span>)  <span class="comment"># 2</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的维度：<span class="subst">&#123;arr1.shape&#125;</span>&#x27;</span>)  <span class="comment"># 3行5列</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的元素类型：<span class="subst">&#123;arr1.dtype&#125;</span>&#x27;</span>)  <span class="comment"># int32</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的元素个数：<span class="subst">&#123;arr1.size&#125;</span>&#x27;</span>)  <span class="comment"># 15</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的元素字节数：<span class="subst">&#123;arr1.itemsize&#125;</span>&#x27;</span>)  <span class="comment"># 4   32除8</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;np的元素类型：<span class="subst">&#123;<span class="built_in">type</span>(arr1)&#125;</span>&#x27;</span>)  <span class="comment"># &lt;class &#x27;numpy.ndarray&#x27;&gt;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 矩阵运算</span></span><br><span class="line"></span><br><span class="line">arr2 = np.array([<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">40</span>])</span><br><span class="line">arr3 = np.arange(<span class="number">4</span>)  <span class="comment"># 都是一行四列</span></span><br><span class="line"><span class="built_in">print</span>(arr2)</span><br><span class="line"><span class="built_in">print</span>(arr3)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(arr2 + arr3)</span><br><span class="line"><span class="built_in">print</span>(arr2 - arr3)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line"><span class="comment"># 矩阵的乘法，行列数一致</span></span><br><span class="line">arr4 = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line">arr5 = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line"><span class="built_in">print</span>(arr4 * arr5)</span><br><span class="line"><span class="built_in">print</span>(np.multiply(arr4, arr5))  <span class="comment"># 这2个结果一样都是相乘</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line"><span class="comment"># 矩阵乘，行列数不一致，需要a的列和b的行一致</span></span><br><span class="line">arr4 = np.array([[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>], [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]])</span><br><span class="line">arr5 = np.array([[<span class="number">9</span>, <span class="number">8</span>], [<span class="number">6</span>, <span class="number">5</span>], [<span class="number">3</span>, <span class="number">2</span>]])</span><br><span class="line"><span class="built_in">print</span>(np.dot(arr4, arr5))</span><br><span class="line"><span class="built_in">print</span>(arr4.dot(arr5))</span><br><span class="line"><span class="built_in">print</span>(arr4 @ arr5)  <span class="comment"># 这3效果一致</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="常见的创建方式"><a class="markdownIt-Anchor" href="#常见的创建方式"></a> 常见的创建方式</h1><p>把py列表转ndarray类型</p><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 把py列表转ndarray对象</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">my_list = [<span class="number">11</span>, <span class="number">22</span>, <span class="number">33</span>, <span class="number">55</span>, <span class="number">67</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(my_list))</span><br><span class="line"></span><br><span class="line">arr2 = np.array(my_list)</span><br><span class="line"><span class="built_in">print</span>(arr2)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(arr2))</span><br></pre></td></tr></table></figure><p>arange(起始,结束,步长,dtype=类型)函数创建ndarray类型 类似py的range()函数</p><figure class="highlight py"><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">arr3 = np.arange(<span class="number">0</span>, <span class="number">10</span>, <span class="number">2</span>, dtype=np.float32) <span class="comment">#指定np的类型，有int32 int64等</span></span><br><span class="line"><span class="built_in">print</span>(arr3)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(arr3))</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;元素的类型：<span class="subst">&#123;arr3.dtype&#125;</span>&#x27;</span>)</span><br><span class="line"><span class="comment"># [0. 2. 4. 6. 8.]</span></span><br><span class="line"><span class="comment"># &lt;class &#x27;numpy.ndarray&#x27;&gt;</span></span><br><span class="line"><span class="comment"># 元素的类型：float32</span></span><br></pre></td></tr></table></figure><p>random.rand() 生成 包左不包右 随机小数矩阵</p><p>randint(起始，结束，size=（行，列）)</p><figure class="highlight py"><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 class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line">arr4 = np.random.rand(<span class="number">3</span>, <span class="number">5</span>)</span><br><span class="line"><span class="built_in">print</span>(arr4)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line">arr5 = np.random.randint(<span class="number">3</span>, <span class="number">5</span>, size=(<span class="number">2</span>, <span class="number">6</span>)) <span class="comment">#2行3列   范围3-4，包左不包右，随机整数</span></span><br><span class="line"><span class="built_in">print</span>(arr5)</span><br></pre></td></tr></table></figure><p>等比/等差数列</p><p>开始和结束点都是10的幂,base指定2为底数</p><figure class="highlight py"><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">arr3 = np.logspace(<span class="number">0</span>, <span class="number">0</span>, <span class="number">10</span>)</span><br><span class="line"><span class="built_in">print</span>(arr3)</span><br><span class="line"></span><br><span class="line">arr4 = np.logspace(<span class="number">0</span>, <span class="number">1</span>, <span class="number">10</span>, base=<span class="number">2</span>)  <span class="comment"># 等比数列</span></span><br><span class="line"><span class="built_in">print</span>(arr4)</span><br><span class="line"></span><br><span class="line">arr5 = np.linspace(<span class="number">1</span>, <span class="number">10</span>, <span class="number">10</span>) <span class="comment"># 等差数列浮点型   ,endpoint= False 不包含结束值, dtype=np.int32指定类型</span></span><br><span class="line"><span class="built_in">print</span>(arr5)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="排序函数"><a class="markdownIt-Anchor" href="#排序函数"></a> 排序函数</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">arr1 = np.array([<span class="number">12</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">14</span>, <span class="number">5</span>])</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(arr1)</span><br><span class="line"></span><br><span class="line">arr2 = np.sort(arr1)  <span class="comment"># 这样不修改原来数组</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;*&quot;</span> * <span class="number">20</span>)</span><br><span class="line"><span class="built_in">print</span>(arr1)</span><br><span class="line"><span class="built_in">print</span>(arr2)</span><br><span class="line"></span><br><span class="line">arr1.sort()  <span class="comment"># 这样直接修改原来数组</span></span><br><span class="line"><span class="built_in">print</span>(arr1)</span><br></pre></td></tr></table></figure><h1 id="类型转换"><a class="markdownIt-Anchor" href="#类型转换"></a> 类型转换</h1><figure class="highlight py"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"></span><br><span class="line">arr1 = np.arange(<span class="number">0</span>, <span class="number">10</span>, <span class="number">2</span>, dtype=np.int64)</span><br><span class="line"><span class="built_in">print</span>(arr1)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(arr1))</span><br><span class="line"></span><br><span class="line">arr2 = arr1.astype(np.float64)</span><br><span class="line"><span class="built_in">print</span>(arr2)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(arr2))</span><br></pre></td></tr></table></figure><h1 id="常用方法速查"><a class="markdownIt-Anchor" href="#常用方法速查"></a> 常用方法速查</h1><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.array()</td><td>np.array([1,2,3])</td><td>从 Python 列表创建</td></tr><tr><td>np.zeros()</td><td>np.zeros((2,3))</td><td>创建全 0 矩阵</td></tr><tr><td>np.ones()</td><td>np.ones((3,3))</td><td>创建全 1 矩阵</td></tr><tr><td>np.eye()</td><td>np.eye(3)</td><td>单位矩阵</td></tr><tr><td>np.full()</td><td>np.full((2,2),7)</td><td>指定值填充</td></tr><tr><td>np.arange()</td><td>np.arange(0,10,2)</td><td>生成等差序列</td></tr><tr><td>np.linspace()</td><td>np.linspace(0,1,5)</td><td>生成等间隔序列</td></tr><tr><td>np.random.rand()</td><td>np.random.rand(2,3)</td><td>0~1均匀分布随机数</td></tr><tr><td>np.random.randn()</td><td>np.random.randn(2,3)</td><td>标准正态分布</td></tr><tr><td>np.random.randint()</td><td>np.random.randint(0,10,(2,2))</td><td>随机整数矩阵</td></tr></tbody></table><h4 id="矩阵运算"><a class="markdownIt-Anchor" href="#矩阵运算"></a> 矩阵运算</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>加法</td><td>A + B</td><td>按元素</td></tr><tr><td>减法</td><td>A - B</td><td>按元素</td></tr><tr><td>乘法（逐元素）</td><td>A * B</td><td>向量化操作</td></tr><tr><td>点乘（矩阵乘法）</td><td>A.dot(B)</td><td>或 np.dot(A,B)</td></tr><tr><td>点乘（运算符）</td><td>A @ B</td><td>同矩阵乘法</td></tr><tr><td>幂</td><td>A ** 2</td><td>每个元素平方</td></tr><tr><td>取反</td><td>-A</td><td>每个元素取负</td></tr></tbody></table><p>示例：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">A = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]])</span><br><span class="line">B = np.array([[<span class="number">5</span>,<span class="number">6</span>],[<span class="number">7</span>,<span class="number">8</span>]])</span><br><span class="line">C = A @ B</span><br></pre></td></tr></table></figure><h4 id="常用数学函数"><a class="markdownIt-Anchor" href="#常用数学函数"></a> 常用数学函数</h4><table><thead><tr><th>函数</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.sum()</td><td>np.sum(A)</td><td>求和</td></tr><tr><td>np.mean()</td><td>np.mean(A)</td><td>均值</td></tr><tr><td>np.max()</td><td>np.max(A)</td><td>最大值</td></tr><tr><td>np.min()</td><td>np.min(A)</td><td>最小值</td></tr><tr><td>np.std()</td><td>np.std(A)</td><td>标准差</td></tr><tr><td>np.sqrt()</td><td>np.sqrt(A)</td><td>开根号</td></tr><tr><td>np.exp()</td><td>np.exp(A)</td><td>e^x</td></tr><tr><td>np.log()</td><td>np.log(A)</td><td>ln(x)</td></tr><tr><td>np.sin()</td><td>np.sin(A)</td><td>正弦</td></tr><tr><td>np.cos()</td><td>np.cos(A)</td><td>余弦</td></tr><tr><td>np.abs()</td><td>np.abs(A)</td><td>绝对值</td></tr><tr><td>np.round()</td><td>np.round(A,2)</td><td>保留小数</td></tr></tbody></table><h4 id="矩阵属性"><a class="markdownIt-Anchor" href="#矩阵属性"></a> 矩阵属性</h4><table><thead><tr><th>表达式</th><th>说明</th></tr></thead><tbody><tr><td>A.shape</td><td>形状</td></tr><tr><td>A.ndim</td><td>维度</td></tr><tr><td>A.size</td><td>元素总数</td></tr><tr><td>A.dtype</td><td>数据类型</td></tr><tr><td>A.T</td><td>转置</td></tr><tr><td>A.real</td><td>实部</td></tr><tr><td>A.imag</td><td>虚部</td></tr></tbody></table><h4 id="形状操作reshape-flatten"><a class="markdownIt-Anchor" href="#形状操作reshape-flatten"></a> 形状操作（Reshape / Flatten）</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>reshape()</td><td>A.reshape(3,2)</td><td>改形状</td></tr><tr><td>flatten()</td><td>A.flatten()</td><td>展平为 1D</td></tr><tr><td>ravel()</td><td>A.ravel()</td><td>展平（更快）</td></tr><tr><td>resize()</td><td>A.resize(2,3)</td><td>直接修改原数组</td></tr><tr><td>transpose()</td><td>A.transpose()</td><td>转置</td></tr></tbody></table><p>示例：</p><figure class="highlight python"><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">A = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>],[<span class="number">5</span>,<span class="number">6</span>]])</span><br><span class="line">A.reshape(<span class="number">2</span>,<span class="number">3</span>)</span><br></pre></td></tr></table></figure><h4 id="索引操作"><a class="markdownIt-Anchor" href="#索引操作"></a> 索引操作</h4><p>普通索引</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">A[<span class="number">0</span>,<span class="number">1</span>]     <span class="comment"># 第一行第二列</span></span><br><span class="line">A[:,<span class="number">1</span>]     <span class="comment"># 所有行，第2列</span></span><br><span class="line">A[<span class="number">1</span>,:]     <span class="comment"># 第2行，所有列</span></span><br><span class="line">A[<span class="number">0</span>:<span class="number">2</span>, :]  <span class="comment"># 前两行</span></span><br></pre></td></tr></table></figure><p>布尔索引</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A[A &gt; <span class="number">0</span>]</span><br></pre></td></tr></table></figure><h4 id="拼接操作concatenate-stack"><a class="markdownIt-Anchor" href="#拼接操作concatenate-stack"></a> 拼接操作（Concatenate / Stack）</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.concatenate()</td><td>np.concatenate([A,B], axis=0)</td><td>合并数组</td></tr><tr><td>np.hstack()</td><td>np.hstack([A,B])</td><td>水平拼接</td></tr><tr><td>np.vstack()</td><td>np.vstack([A,B])</td><td>垂直拼接</td></tr><tr><td>np.stack()</td><td>np.stack([A,B], axis=0)</td><td>新增维度堆叠</td></tr></tbody></table><h4 id="线性代数"><a class="markdownIt-Anchor" href="#线性代数"></a> 线性代数</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.linalg.inv()</td><td>np.linalg.inv(A)</td><td>逆矩阵</td></tr><tr><td>np.linalg.det()</td><td>np.linalg.det(A)</td><td>行列式</td></tr><tr><td>np.linalg.eig()</td><td>np.linalg.eig(A)</td><td>特征值、特征向量</td></tr><tr><td>np.linalg.norm()</td><td>np.linalg.norm(A)</td><td>范数</td></tr><tr><td>np.linalg.solve()</td><td>np.linalg.solve(A,b)</td><td>解方程：Ax=b</td></tr></tbody></table><p>示例：</p><figure class="highlight python"><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">A = np.array([[<span class="number">1</span>,<span class="number">2</span>],[<span class="number">3</span>,<span class="number">4</span>]])</span><br><span class="line">inv = np.linalg.inv(A)</span><br></pre></td></tr></table></figure><h4 id="随机模块"><a class="markdownIt-Anchor" href="#随机模块"></a> 随机模块</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.random.seed()</td><td>np.random.seed(0)</td><td>设置随机种子</td></tr><tr><td>np.random.rand()</td><td>np.random.rand(2,3)</td><td>均匀分布</td></tr><tr><td>np.random.randn()</td><td>np.random.randn(2,3)</td><td>正态分布</td></tr><tr><td>np.random.randint()</td><td>np.random.randint(0,10,(2,2))</td><td>随机整数</td></tr><tr><td>np.random.shuffle()</td><td>np.random.shuffle(A)</td><td>原地洗牌</td></tr></tbody></table><h4 id="类型转换-2"><a class="markdownIt-Anchor" href="#类型转换-2"></a> 类型转换</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>astype()</td><td>A.astype(np.float32)</td><td>转换数据类型</td></tr></tbody></table><h4 id="读写文件"><a class="markdownIt-Anchor" href="#读写文件"></a> 读写文件</h4><table><thead><tr><th>方法</th><th>示例</th><th>说明</th></tr></thead><tbody><tr><td>np.save()</td><td>np.save(‘a.npy’,A)</td><td>保存二进制</td></tr><tr><td>np.load()</td><td>np.load(‘a.npy’)</td><td>读取二进制</td></tr><tr><td>np.savetxt()</td><td>np.savetxt(‘a.txt’,A)</td><td>保存文本</td></tr><tr><td>np.loadtxt()</td><td>np.loadtxt(‘a.txt’)</td><td>读取文本</td></tr></tbody></table><h4 id="常见小技巧"><a class="markdownIt-Anchor" href="#常见小技巧"></a> 常见小技巧</h4><ol><li>快速生成单位矩阵</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">np.eye(<span class="number">4</span>)</span><br></pre></td></tr></table></figure><ol start="2"><li>生成一个 10x10 的随机矩阵</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">np.random.randn(<span class="number">10</span>,<span class="number">10</span>)</span><br></pre></td></tr></table></figure><ol start="3"><li>快速查看数据统计信息</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">A.<span class="built_in">min</span>(), A.<span class="built_in">max</span>(), A.mean(), A.std()</span><br></pre></td></tr></table></figure><ol start="4"><li>比较两个矩阵是否相等</li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">np.allclose(A, B)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">欲穷千里目，更上一层楼</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Doc" scheme="https://luckynwa.top/tags/Doc/"/>
    
  </entry>
  
  <entry>
    <title>Twikoo 评论系统搭建：Docker 与 Vercel+MongoDB 两种方案</title>
    <link href="https://luckynwa.top/posts/tool839/"/>
    <id>https://luckynwa.top/posts/tool839/</id>
    <published>2025-11-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:20:55.633Z</updated>
    
    <content type="html"><![CDATA[<h1 id="docker部署"><a class="markdownIt-Anchor" href="#docker部署"></a> Docker部署</h1><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></pre></td><td class="code"><pre><span class="line">docker run --name twikoo \</span><br><span class="line">  -e TWIKOO_THROTTLE=1000 \</span><br><span class="line">  -p 3737:8080 \</span><br><span class="line">  -v $&#123;PWD&#125;/data:/app/data \</span><br><span class="line">  -d registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/twikoo</span><br></pre></td></tr></table></figure><p>博客主题配置中修改如下：</p><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></pre></td><td class="code"><pre><span class="line"><span class="attr">twikoo:</span></span><br><span class="line">  <span class="attr">envId:</span> <span class="string">http://xxxxxx:3737/</span></span><br><span class="line">  <span class="attr">region:</span></span><br><span class="line">  <span class="attr">visitor:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">option:</span></span><br></pre></td></tr></table></figure><p><code>use</code> 也选它，上面连接去浏览器输入有东西出来就配置好了。</p><h2 id="nginx-反向代理"><a class="markdownIt-Anchor" href="#nginx-反向代理"></a> Nginx 反向代理</h2><p>必须申请一个二级域名，不然会出现跨域情况。</p><p><code>twikoo.luckynwa.top</code> 的 Nginx 配置如下（必须带上 IP，不然 tw 设置无法查看访问者具体位置）：</p><figure class="highlight nginx"><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="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span>  <span class="number">443</span> ssl;</span><br><span class="line">    <span class="attribute">server_name</span>  twikoo.luckynwa.top;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_certificate</span> /etc/nginx/cert/twikoo.luckynwa.top.cer;</span><br><span class="line">    <span class="attribute">ssl_certificate_key</span> /etc/nginx/cert/twikoo.luckynwa.top.key;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_session_timeout</span>  <span class="number">5m</span>;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">ssl_protocols</span> SSLv3 TLSv1 TLSv1.<span class="number">1</span> TLSv1.<span class="number">2</span>;</span><br><span class="line">    <span class="attribute">ssl_ciphers</span>  HIGH:!ADH:!EXPORT56:RC4+RSA:+MEDIUM;</span><br><span class="line">    <span class="attribute">ssl_prefer_server_ciphers</span>  <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">    <span class="section">location</span> / &#123;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://xxxxxx:3737;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="vercelmongodb部署使用中"><a class="markdownIt-Anchor" href="#vercelmongodb部署使用中"></a> Vercel+MongoDB部署（使用中）</h1><p>打开<a href="https://cloud.mongodb.com/%E6%B3%A8%E5%86%8C%E5%B9%B6%E7%99%BB%E5%BD%95">https://cloud.mongodb.com/注册并登录</a></p><p>使用n165… gmail的谷歌账号登录</p><ol><li>点左侧 <strong>Database Access</strong>，添加一个数据库用户（设好用户名和密码）</li><li>点左侧 <strong>Network Access</strong>，添加 IP 为 <code>0.0.0.0/0</code>（允许所有 IP 访问）</li><li>回到 <strong>Database</strong> 页面，点击你的集群 -&gt; <strong>Connect</strong> -&gt; <strong>Connect your application</strong></li><li>复制下面，替换密码</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mongodb+srv://n1656213092:第二步设的密码@cluster0.5x5rf.mongodb.net/?retryWrites=true&amp;w=majority&amp;appName=Cluster0</span><br></pre></td></tr></table></figure><p>打开我的GitHub的这个仓库，<a href="https://github.com/luckyNwa6/twikoo%EF%BC%8CFork%E8%BF%99%E4%BB%93%E5%BA%93">https://github.com/luckyNwa6/twikoo，Fork这仓库</a></p><p>点击以下链接将Twikoo一键部署到Vercel：</p><p><a href="https://vercel.com/import/project?template=https://github.com/imaegoo/twikoo/tree/main/src/server/vercel-min">https://vercel.com/import/project?template=https://github.com/imaegoo/twikoo/tree/main/src/server/vercel-min</a></p><p>进入<code>Settings - Environment Variables</code>页面。<br />新建一个NAME为<code>MONGODB_URI</code>;VALUE为<code>复制里的信息</code></p><p>进入<code>Deployments</code>界面，点击右边的竖三点，点击<code>Redeploy</code></p><p>提示 100 运行正常就可以了，得配置域名国内才能访问</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705200259539_20260705200301A036.png" alt="image-20260705200259539" /></p><h1 id="邮箱通知"><a class="markdownIt-Anchor" href="#邮箱通知"></a> 邮箱通知</h1><p>控制面板在项目中的留言区，可以设置各种功能，比如留言时 QQ 邮箱通知提醒</p><p>默认在–昵称–输入admin 展示这个设置 现在昵称这个LuckyNwa 展示设置，密7…</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705191529997_20260705191531A035.png" alt="image-20260705191529997" /></p><p>QQ 邮箱开启 SMTP 服务，授权码记得保存，配置到控制面板中即可。</p><p>默认twikoo数据文件会在/root/data中 db0.json是评论信息 其他是系统配置的json</p>]]></content>
    
    
    <summary type="html">独学而无友，则孤陋而寡闻</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Docker" scheme="https://luckynwa.top/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>WSL2 + vLLM 搭建本地 AI 推理服务</title>
    <link href="https://luckynwa.top/posts/ai5/"/>
    <id>https://luckynwa.top/posts/ai5/</id>
    <published>2025-09-28T19:38:44.000Z</published>
    <updated>2026-07-07T16:19:34.035Z</updated>
    
    <content type="html"><![CDATA[<h1 id="wsl2-和-vllm-部署指南"><a class="markdownIt-Anchor" href="#wsl2-和-vllm-部署指南"></a> WSL2 和 vLLM 部署指南</h1><p>用 <strong>管理员 PowerShell</strong></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">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:Microsoft<span class="literal">-Windows-Subsystem-Linux</span> /all /norestart</span><br><span class="line">dism.exe /online /<span class="built_in">enable-feature</span> /featurename:VirtualMachinePlatform /all /norestart</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><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">wsl <span class="literal">--set-default-version</span> <span class="number">2</span></span><br><span class="line">wsl <span class="literal">--update</span></span><br><span class="line">wsl <span class="literal">--status</span></span><br></pre></td></tr></table></figure><p>安装 Ubuntu（不开科学也挺快）</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">wsl <span class="literal">--install</span> <span class="literal">-d</span> Ubuntu</span><br></pre></td></tr></table></figure><p>过后创建号：<code>lucky</code> / <code>221...</code></p><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">sudo apt update</span><br><span class="line">sudo apt upgrade -y</span><br></pre></td></tr></table></figure><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">sudo -i</span><br></pre></td></tr></table></figure><h2 id="安装-miniconda"><a class="markdownIt-Anchor" href="#安装-miniconda"></a> 安装 Miniconda</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">wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh</span><br><span class="line">bash Miniconda3-latest-Linux-x86_64.sh     <span class="comment"># 一直回车 或 yes</span></span><br></pre></td></tr></table></figure><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 class="built_in">source</span> ~/.bashrc</span><br></pre></td></tr></table></figure><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">conda --version</span><br></pre></td></tr></table></figure><h2 id="配置-ssh"><a class="markdownIt-Anchor" href="#配置-ssh"></a> 配置 SSH</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></pre></td><td class="code"><pre><span class="line">sudo apt install openssh-server -y</span><br><span class="line">sudo service ssh start</span><br><span class="line">service ssh status</span><br><span class="line">passwd        <span class="comment"># 221...</span></span><br></pre></td></tr></table></figure><p>端口转发到 2222（管理员 PowerShell）</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">netsh interface portproxy add v4tov4 listenport=<span class="number">2222</span> listenaddress=<span class="number">0.0</span>.<span class="number">0.0</span> connectport=<span class="number">22</span> connectaddress=<span class="number">172.24</span>.<span class="number">212.8</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">netsh advfirewall firewall add rule name=<span class="string">&quot;WSL SSH&quot;</span> <span class="built_in">dir</span>=<span class="keyword">in</span> action=allow protocol=TCP localport=<span class="number">2222</span></span><br></pre></td></tr></table></figure><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">ssh lucky@127.0.0.1 -p 2222</span><br></pre></td></tr></table></figure><h2 id="配置-root-ssh-登录"><a class="markdownIt-Anchor" href="#配置-root-ssh-登录"></a> 配置 root SSH 登录</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></pre></td><td class="code"><pre><span class="line">sudo -i</span><br><span class="line">passwd root     <span class="comment"># 也改成 221..</span></span><br><span class="line">nano /etc/ssh/sshd_config</span><br></pre></td></tr></table></figure><p>#不去找注释了，直接新增下面2行</p><figure class="highlight plaintext"><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">PermitRootLogin yes</span><br><span class="line">PasswordAuthentication yes</span><br></pre></td></tr></table></figure><p>#保存退出 重启</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Ctrl + O</span><br><span class="line">Enter</span><br><span class="line">Ctrl + X</span><br></pre></td></tr></table></figure><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">service ssh restart</span><br></pre></td></tr></table></figure><h2 id="修复终端提示符过长"><a class="markdownIt-Anchor" href="#修复终端提示符过长"></a> 修复终端提示符过长</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 class="built_in">unset</span> PROMPT_COMMAND</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;unset PROMPT_COMMAND&#x27;</span> &gt;&gt; ~/.bashrc</span><br></pre></td></tr></table></figure><h2 id="安装-python-310-环境"><a class="markdownIt-Anchor" href="#安装-python-310-环境"></a> 安装 Python 3.10 环境</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></pre></td><td class="code"><pre><span class="line">conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main</span><br><span class="line">conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r</span><br><span class="line">conda remove -n vllm --all -y         <span class="comment"># 移除环境</span></span><br><span class="line">conda create -n vllm python=3.10 -y   <span class="comment"># 安装环境</span></span><br><span class="line">conda activate vllm</span><br><span class="line">pip install -U pip</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">apt-get update</span><br><span class="line">apt-get install -y gcc</span><br></pre></td></tr></table></figure><h2 id="安装-vllm-依赖"><a class="markdownIt-Anchor" href="#安装-vllm-依赖"></a> 安装 vLLM 依赖</h2><p>指定版本，因为我的显卡3080的驱动不支持太新的pytorch版本，安装vllm自动安装pytorch</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></pre></td><td class="code"><pre><span class="line">pip install vllm==0.8.5</span><br><span class="line">pip show vllm</span><br><span class="line">pip install transformers==4.51.1 --force-reinstall</span><br><span class="line">pip install numpy==2.0.2 --force-reinstall</span><br><span class="line">pip install --force-reinstall \</span><br><span class="line">  fastapi==0.110.0 \</span><br><span class="line">  starlette==0.36.3 \</span><br><span class="line">  prometheus-fastapi-instrumentator==7.0.0</span><br></pre></td></tr></table></figure><h2 id="配置模型下载路径"><a class="markdownIt-Anchor" href="#配置模型下载路径"></a> 配置模型下载路径</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></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p /nwa/hf_models</span><br><span class="line"><span class="built_in">chmod</span> -R 777 /nwa/hf_models</span><br><span class="line"><span class="built_in">export</span> HF_HOME=/nwa/hf_models</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&#x27;export HF_HOME=/nwa/hf_models&#x27;</span> &gt;&gt; ~/.bashrc</span><br><span class="line"><span class="built_in">source</span> ~/.bashrc</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$HF_HOME</span></span><br><span class="line"><span class="comment"># 设置国内镜像就不用科学下载了</span></span><br><span class="line"><span class="built_in">export</span> HF_ENDPOINT=https://hf-mirror.com</span><br></pre></td></tr></table></figure><h2 id="检查-gpu-环境"><a class="markdownIt-Anchor" href="#检查-gpu-环境"></a> 检查 GPU 环境</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></pre></td><td class="code"><pre><span class="line">apt install -y nvidia-utils-560</span><br><span class="line">nvidia-smi</span><br><span class="line">python -c <span class="string">&quot;import torch; print(torch.version.cuda)&quot;</span></span><br><span class="line">python -c <span class="string">&quot;import torch; print(torch.backends.cuda.is_built())&quot;</span></span><br></pre></td></tr></table></figure><h2 id="下载模型"><a class="markdownIt-Anchor" href="#下载模型"></a> 下载模型</h2><h3 id="方法一huggingface-官方源"><a class="markdownIt-Anchor" href="#方法一huggingface-官方源"></a> 方法一：HuggingFace 官方源</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></pre></td><td class="code"><pre><span class="line">pip install -U huggingface_hub</span><br><span class="line">huggingface-cli download Qwen/Qwen3-4B-Instruct-2507 \</span><br><span class="line">  --local-dir /nwa/hf_models/Qwen3-4B-Instruct-2507 \</span><br><span class="line">  --resume-download \</span><br><span class="line">  --local-dir-use-symlinks False</span><br></pre></td></tr></table></figure><h3 id="方法二modelscope-国内源"><a class="markdownIt-Anchor" href="#方法二modelscope-国内源"></a> 方法二：ModelScope 国内源</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></pre></td><td class="code"><pre><span class="line">pip install modelscope -U</span><br><span class="line">modelscope download --model Qwen/Qwen3-4B-Instruct-2507 \</span><br><span class="line">  --local_dir /nwa/hf_models/Qwen3-4B-Instruct-2507</span><br></pre></td></tr></table></figure><h2 id="部署-vllm-推理服务"><a class="markdownIt-Anchor" href="#部署-vllm-推理服务"></a> 部署 vLLM 推理服务</h2><h3 id="直接从线上下载部署"><a class="markdownIt-Anchor" href="#直接从线上下载部署"></a> 直接从线上下载部署</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></pre></td><td class="code"><pre><span class="line">vllm serve Qwen/Qwen2.5-7B-Instruct \</span><br><span class="line">  --host 0.0.0.0 \</span><br><span class="line">  --port 9089</span><br></pre></td></tr></table></figure><h3 id="用已下载的模型部署推荐"><a class="markdownIt-Anchor" href="#用已下载的模型部署推荐"></a> 用已下载的模型部署（推荐）</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><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">vllm serve /nwa/hf_models/Qwen3-4B-Instruct-2507 \</span><br><span class="line">  --host 0.0.0.0 \</span><br><span class="line">  --port 9089 \</span><br><span class="line">  --dtype half \</span><br><span class="line">  --kv-cache-dtype fp8 \</span><br><span class="line">  --max-model-len 1024 \</span><br><span class="line">  --gpu-memory-utilization 0.99 \</span><br><span class="line">  --enforce-eager \</span><br><span class="line">  --trust-remote-code</span><br></pre></td></tr></table></figure><p>切换到 root 并激活环境</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">su - root</span><br><span class="line">conda activate vllm</span><br></pre></td></tr></table></figure><h2 id="映射-vllm-端口到宿主机"><a class="markdownIt-Anchor" href="#映射-vllm-端口到宿主机"></a> 映射 vLLM 端口到宿主机</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">netsh interface portproxy add v4tov4 listenport=<span class="number">9089</span> listenaddress=<span class="number">0.0</span>.<span class="number">0.0</span> connectport=<span class="number">9089</span> connectaddress=<span class="number">172.24</span>.<span class="number">212.8</span></span><br><span class="line">netsh advfirewall firewall add rule name=<span class="string">&quot;vllm-9089&quot;</span> <span class="built_in">dir</span>=<span class="keyword">in</span> action=allow protocol=TCP localport=<span class="number">9089</span></span><br></pre></td></tr></table></figure><h1 id="embedding-和-reranker-部署"><a class="markdownIt-Anchor" href="#embedding-和-reranker-部署"></a> Embedding 和 Reranker 部署</h1><h2 id="创建环境并安装依赖"><a class="markdownIt-Anchor" href="#创建环境并安装依赖"></a> 创建环境并安装依赖</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></pre></td><td class="code"><pre><span class="line">conda create -n embedding python=3.10 -y</span><br><span class="line"></span><br><span class="line">conda activate embedding</span><br><span class="line">pip config <span class="built_in">set</span> global.index-url https://mirrors.aliyun.com/pypi/simple   <span class="comment"># 配置pip默认阿里云镜像</span></span><br><span class="line"><span class="built_in">export</span> VLLM_USE_MODELSCOPE=True</span><br><span class="line">pip install modelscope</span><br><span class="line">pip install vllm==0.8.5</span><br><span class="line">pip show vllm</span><br><span class="line">pip install transformers==4.51.1 --force-reinstall</span><br><span class="line">pip install numpy==2.0.2 --force-reinstall</span><br><span class="line">pip install --force-reinstall \</span><br><span class="line">  fastapi==0.110.0 \</span><br><span class="line">  starlette==0.36.3 \</span><br><span class="line">  prometheus-fastapi-instrumentator==7.0.0</span><br></pre></td></tr></table></figure><h2 id="下载-embedding-模型"><a class="markdownIt-Anchor" href="#下载-embedding-模型"></a> 下载 Embedding 模型</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">modelscope download --model Qwen/Qwen3-Embedding-0.6B \</span><br><span class="line">  --local_dir /nwa/hf_models/Qwen3-Embedding-0.6B</span><br></pre></td></tr></table></figure><h2 id="启动-embedding-服务"><a class="markdownIt-Anchor" href="#启动-embedding-服务"></a> 启动 Embedding 服务</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">conda activate embedding</span><br><span class="line">vllm serve --task embed /nwa/hf_models/Qwen3-Embedding-0.6B --host 0.0.0.0 --port 8000</span><br></pre></td></tr></table></figure><p>验证：<code>localhost:8000/v1/models</code></p><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">netsh interface portproxy add v4tov4 listenport=<span class="number">8000</span> listenaddress=<span class="number">0.0</span>.<span class="number">0.0</span> connectport=<span class="number">8000</span> connectaddress=<span class="number">172.24</span>.<span class="number">212.8</span></span><br><span class="line">netsh advfirewall firewall add rule name=<span class="string">&quot;embedding-8000&quot;</span> <span class="built_in">dir</span>=<span class="keyword">in</span> action=allow protocol=TCP localport=<span class="number">8000</span></span><br></pre></td></tr></table></figure><h2 id="下载-reranker-模型"><a class="markdownIt-Anchor" href="#下载-reranker-模型"></a> 下载 Reranker 模型</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">modelscope download --model BAAI/bge-reranker-base \</span><br><span class="line">  --local_dir /nwa/hf_models/BAAI/bge-reranker-base</span><br></pre></td></tr></table></figure><h2 id="启动-reranker-服务"><a class="markdownIt-Anchor" href="#启动-reranker-服务"></a> 启动 Reranker 服务</h2><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">vllm serve /nwa/hf_models/BAAI/bge-reranker-base --task score --host 0.0.0.0 --port 7999</span><br></pre></td></tr></table></figure><p>验证：<code>localhost:7999/v1/models</code></p><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">netsh interface portproxy add v4tov4 listenport=<span class="number">7999</span> listenaddress=<span class="number">0.0</span>.<span class="number">0.0</span> connectport=<span class="number">7999</span> connectaddress=<span class="number">172.24</span>.<span class="number">212.8</span></span><br><span class="line">netsh advfirewall firewall add rule name=<span class="string">&quot;embedding-7999&quot;</span> <span class="built_in">dir</span>=<span class="keyword">in</span> action=allow protocol=TCP localport=<span class="number">7999</span></span><br></pre></td></tr></table></figure><h2 id="改造为-systemd-自动启动服务"><a class="markdownIt-Anchor" href="#改造为-systemd-自动启动服务"></a> 改造为 systemd 自动启动服务</h2><h3 id="服务一embedding"><a class="markdownIt-Anchor" href="#服务一embedding"></a> 服务一：Embedding</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">sudo nano /etc/systemd/system/vllm-embedding.service</span><br></pre></td></tr></table></figure><figure class="highlight ini"><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 class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=vLLM Embedding Server</span><br><span class="line"><span class="attr">After</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"><span class="attr">Wants</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=simple</span><br><span class="line"><span class="attr">User</span>=root</span><br><span class="line"><span class="attr">WorkingDirectory</span>=/root</span><br><span class="line"></span><br><span class="line"><span class="attr">ExecStart</span>=/root/miniconda3/envs/embedding/bin/vllm serve \</span><br><span class="line">    /nwa/hf_models/Qwen3-Embedding-0.6B \</span><br><span class="line">    --task embed \</span><br><span class="line">    --host 0.0.0.0 \</span><br><span class="line">    --port 8000</span><br><span class="line"></span><br><span class="line"><span class="attr">Restart</span>=always</span><br><span class="line"><span class="attr">RestartSec</span>=<span class="number">5</span></span><br><span class="line"></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;PATH=/root/miniconda3/envs/embedding/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&quot;</span></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;PYTHONUNBUFFERED=1&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=multi-user.target</span><br></pre></td></tr></table></figure><h3 id="服务二reranker"><a class="markdownIt-Anchor" href="#服务二reranker"></a> 服务二：Reranker</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">sudo nano /etc/systemd/system/vllm-reranker.service</span><br></pre></td></tr></table></figure><figure class="highlight ini"><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 class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=vLLM Reranker Server</span><br><span class="line"><span class="attr">After</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"><span class="attr">Wants</span>=network-<span class="literal">on</span>line.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=simple</span><br><span class="line"><span class="attr">User</span>=root</span><br><span class="line"><span class="attr">WorkingDirectory</span>=/root</span><br><span class="line"></span><br><span class="line"><span class="attr">ExecStart</span>=/root/miniconda3/envs/embedding/bin/vllm serve \</span><br><span class="line">    /nwa/hf_models/BAAI/bge-reranker-base \</span><br><span class="line">    --task score \</span><br><span class="line">    --host 0.0.0.0 \</span><br><span class="line">    --port 7999</span><br><span class="line"></span><br><span class="line"><span class="attr">Restart</span>=always</span><br><span class="line"><span class="attr">RestartSec</span>=<span class="number">5</span></span><br><span class="line"></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;PATH=/root/miniconda3/envs/embedding/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&quot;</span></span><br><span class="line"><span class="attr">Environment</span>=<span class="string">&quot;PYTHONUNBUFFERED=1&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=multi-user.target</span><br></pre></td></tr></table></figure><h3 id="启用并启动服务"><a class="markdownIt-Anchor" href="#启用并启动服务"></a> 启用并启动服务</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><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">sudo systemctl daemon-reload</span><br><span class="line"></span><br><span class="line">sudo systemctl <span class="built_in">enable</span> vllm-embedding</span><br><span class="line">sudo systemctl <span class="built_in">enable</span> vllm-reranker</span><br><span class="line"></span><br><span class="line">sudo systemctl start vllm-embedding</span><br><span class="line">sudo systemctl start vllm-reranker</span><br></pre></td></tr></table></figure><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">systemctl status vllm-embedding</span><br><span class="line">systemctl status vllm-reranker</span><br></pre></td></tr></table></figure><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">journalctl -u vllm-embedding -f</span><br><span class="line">journalctl -u vllm-reranker -f</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">粗缯大布裹生涯，腹有诗书气自华</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Ops" scheme="https://luckynwa.top/tags/Ops/"/>
    
  </entry>
  
  <entry>
    <title>JDK8 Lambda与Stream实战指南</title>
    <link href="https://luckynwa.top/posts/java2/"/>
    <id>https://luckynwa.top/posts/java2/</id>
    <published>2025-08-08T01:17:06.000Z</published>
    <updated>2026-07-07T16:16:50.359Z</updated>
    
    <content type="html"><![CDATA[<h2 id="常用遍历"><a class="markdownIt-Anchor" href="#常用遍历"></a> 常用遍历</h2><figure class="highlight java"><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">products.stream().forEach(System.out::println);          <span class="comment">// 遍历打印对象，products是列表</span></span><br><span class="line">Arrays.stream(strArray).forEach(System.out::println);    <span class="comment">// 数组遍历打印每一项</span></span><br></pre></td></tr></table></figure><h2 id="lambda-表达式"><a class="markdownIt-Anchor" href="#lambda-表达式"></a> Lambda 表达式</h2><p>Lambda 表达式是 JDK8 引入的函数式编程特性，使用时必须满足：</p><ol><li>必须有且仅有一个抽象方法的接口（函数式接口）</li><li>Lambda 体中调用方法的参数列表与返回值类型，要与函数式接口中抽象方法的参数列表和返回值类型保持一致</li><li>若 Lambda 参数列表中的第一个参数是实例方法的调用者，而第二个参数是实例方法的参数时，可以使用 <code>ClassName::method</code> 形式</li><li>JDK 里的 Runnable、Comparator、Consumer、BiConsumer 接口满足条件，自定义接口只要满足也可以使用</li></ol><p><strong>Lambda 表达式语法：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(参数列表) -&gt; &#123;重写方法的代码&#125;;</span><br></pre></td></tr></table></figure><ul><li><code>()</code> 里面需要参数就写上，没有则不写，多个参数用逗号隔开</li><li><code>-&gt;</code>：传参符号</li><li><code>&#123;&#125;</code>：重写接口的抽象方法的方法体</li></ul><h3 id="案例-1runnable-线程创建"><a class="markdownIt-Anchor" href="#案例-1runnable-线程创建"></a> 案例 1：Runnable 线程创建</h3><p>Runnable 是一个接口，传统方式需要重写 run 方法，使用 Lambda 可以简化代码：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Lambda</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">// 匿名内部类方式</span></span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">Thread</span>(<span class="keyword">new</span> <span class="title class_">Runnable</span>() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">                System.out.println(Thread.currentThread().getName() + <span class="string">&quot;线程的实现方法2&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;).start();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Lambda 方式（单行代码可省略大括号）</span></span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">Thread</span>(() -&gt; System.out.println(Thread.currentThread().getName() + <span class="string">&quot;牛逼的Lambda&quot;</span>)).start();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="案例-2comparator-集合排序"><a class="markdownIt-Anchor" href="#案例-2comparator-集合排序"></a> 案例 2：Comparator 集合排序</h3><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><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.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Entity</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> age;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Entity</span><span class="params">()</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Entity</span><span class="params">(String name, <span class="type">int</span> age)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">        <span class="built_in">this</span>.age = age;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getName</span><span class="params">()</span> &#123; <span class="keyword">return</span> name; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123; <span class="built_in">this</span>.name = name; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getAge</span><span class="params">()</span> &#123; <span class="keyword">return</span> age; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setAge</span><span class="params">(<span class="type">int</span> age)</span> &#123; <span class="built_in">this</span>.age = age; &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Entity&#123;name=&#x27;&quot;</span> + name + <span class="string">&quot;&#x27;, age=&quot;</span> + age + <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果在实体类中实现 <code>Comparable&lt;Entity&gt;</code> 接口，可以直接调用 <code>Collections.sort(entities)</code> 进行排序：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">implements</span> <span class="title class_">Comparable</span>&lt;Entity&gt;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compareTo</span><span class="params">(Entity other)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> Integer.compare(<span class="built_in">this</span>.age, other.age);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用</span></span><br><span class="line">Collections.sort(entities);  <span class="comment">// 从小到大排序</span></span><br></pre></td></tr></table></figure><p><strong>排序方式对比：</strong></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.Collections;</span><br><span class="line"><span class="keyword">import</span> java.util.Comparator;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Lambda2</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        ArrayList&lt;Entity&gt; entities = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        entities.add(<span class="keyword">new</span> <span class="title class_">Entity</span>(<span class="string">&quot;小A&quot;</span>, <span class="number">19</span>));</span><br><span class="line">        entities.add(<span class="keyword">new</span> <span class="title class_">Entity</span>(<span class="string">&quot;小B&quot;</span>, <span class="number">29</span>));</span><br><span class="line">        entities.add(<span class="keyword">new</span> <span class="title class_">Entity</span>(<span class="string">&quot;小C&quot;</span>, <span class="number">22</span>));</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 方式1：匿名内部类</span></span><br><span class="line">        Collections.sort(entities, <span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;Entity&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(Entity entity1, Entity entity2)</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> entity1.getAge() - entity2.getAge();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 方式2：Lambda表达式</span></span><br><span class="line">        Collections.sort(entities, (entity1, entity2) -&gt; entity1.getAge() - entity2.getAge());</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 方式3：方法引用（最简洁）</span></span><br><span class="line">        Collections.sort(entities, Comparator.comparingInt(Entity::getAge));</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (Entity entity : entities) &#123;</span><br><span class="line">            System.out.println(entity);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>Comparator.comparingInt(Entity::getAge)</code> 说明：</p><ul><li><code>Comparator.comparingInt</code>：静态方法，用于创建一个比较器对象</li><li><code>Entity::getAge</code>：方法引用，使用实体对象的 <code>getAge()</code> 方法来提取整数值进行比较</li></ul><h3 id="案例-3consumer-消费处理"><a class="markdownIt-Anchor" href="#案例-3consumer-消费处理"></a> 案例 3：Consumer 消费处理</h3><p>Consumer 是一个函数式接口，定义了 <code>accept</code> 方法接受输入参数，不返回结果：</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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 打印字符串</span></span><br><span class="line">Consumer&lt;String&gt; printConsumer = (str) -&gt; System.out.println(str);</span><br><span class="line">printConsumer.accept(<span class="string">&quot;Hello, World!&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 计算平方</span></span><br><span class="line">Consumer&lt;Integer&gt; squareConsumer = (num) -&gt; &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">square</span> <span class="operator">=</span> num * num;</span><br><span class="line">    System.out.println(square);</span><br><span class="line">&#125;;</span><br><span class="line">squareConsumer.accept(<span class="number">5</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 遍历集合</span></span><br><span class="line">List&lt;String&gt; names = Arrays.asList(<span class="string">&quot;Alice&quot;</span>, <span class="string">&quot;Bob&quot;</span>, <span class="string">&quot;Charlie&quot;</span>);</span><br><span class="line">names.forEach(name -&gt; System.out.println(<span class="string">&quot;Hello, &quot;</span> + name));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法引用方式</span></span><br><span class="line">Consumer&lt;String&gt; greetingConsumer = System.out::println;</span><br><span class="line">names.forEach(greetingConsumer);</span><br></pre></td></tr></table></figure><h3 id="案例-4biconsumer-双参处理"><a class="markdownIt-Anchor" href="#案例-4biconsumer-双参处理"></a> 案例 4：BiConsumer 双参处理</h3><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="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.function.BiConsumer;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Example</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">greet</span><span class="params">(String name, String greeting)</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;, &quot;</span> + greeting + <span class="string">&quot;!&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> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Example</span> <span class="variable">example</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Example</span>();</span><br><span class="line">        BiConsumer&lt;String, String&gt; greeter = example::greet;</span><br><span class="line">        greeter.accept(<span class="string">&quot;Hello&quot;</span>, <span class="string">&quot;lucky&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>其他函数式接口示例：</strong></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></pre></td><td class="code"><pre><span class="line"><span class="comment">// BiFunction 比较</span></span><br><span class="line">BiFunction&lt;Integer, Integer, Integer&gt; biFun = Integer::compare;</span><br><span class="line">System.out.println(biFun.apply(<span class="number">300</span>, <span class="number">200</span>));  <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 方法引用 - 类名::实例方法名</span></span><br><span class="line">BiFunction&lt;String, String, Boolean&gt; fun2 = String::equals;</span><br><span class="line">System.out.println(fun2.apply(<span class="string">&quot;hello&quot;</span>, <span class="string">&quot;world&quot;</span>));  <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 数组引用</span></span><br><span class="line">Function&lt;Integer, String[]&gt; fun3 = String[]::<span class="keyword">new</span>;</span><br><span class="line">String[] strArray = fun3.apply(<span class="number">2</span>);</span><br><span class="line">Arrays.fill(strArray, <span class="string">&quot;Hello&quot;</span>);</span><br><span class="line">Arrays.stream(strArray).forEach(System.out::println);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Supplier 延迟获取对象</span></span><br><span class="line">Supplier&lt;Entity&gt; sup = () -&gt; <span class="keyword">new</span> <span class="title class_">Entity</span>();</span><br><span class="line">System.out.println(sup.get());</span><br></pre></td></tr></table></figure><h3 id="案例-5自定义函数式接口"><a class="markdownIt-Anchor" href="#案例-5自定义函数式接口"></a> 案例 5：自定义函数式接口</h3><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Counter</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="title function_">sum</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Lambda3</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        Cal(<span class="number">1</span>, <span class="number">2</span>, (a, b) -&gt; a + b);</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> <span class="keyword">void</span> <span class="title function_">Cal</span><span class="params">(<span class="type">int</span> a, <span class="type">int</span> b, Counter c)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> c.sum(a, b);</span><br><span class="line">        System.out.println(sum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="案例-6lambda-优化代码"><a class="markdownIt-Anchor" href="#案例-6lambda-优化代码"></a> 案例 6：Lambda 优化代码</h3><p>商城筛选商品（价格小于 6666）：</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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 传统方式 - 每次需求变更都要新增方法</span></span><br><span class="line"><span class="keyword">public</span> List&lt;Product&gt; <span class="title function_">filterProductByPrice</span><span class="params">(List&lt;Product&gt; list)</span> &#123;</span><br><span class="line">    List&lt;Product&gt; prods = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span> (Product product : list) &#123;</span><br><span class="line">        <span class="keyword">if</span> (product.getPrice() &lt; <span class="number">6666</span>) &#123;</span><br><span class="line">            prods.add(product);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> prods;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>使用自定义接口优化：</strong></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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义接口</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">MyPredicate</span>&lt;T&gt; &#123;</span><br><span class="line">    <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(T t)</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        ArrayList&lt;Product&gt; products = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        products.add(<span class="keyword">new</span> <span class="title class_">Product</span>(<span class="number">1555</span>));</span><br><span class="line">        products.add(<span class="keyword">new</span> <span class="title class_">Product</span>(<span class="number">8555</span>));</span><br><span class="line">        products.add(<span class="keyword">new</span> <span class="title class_">Product</span>(<span class="number">10555</span>));</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 匿名内部类方式</span></span><br><span class="line">        List&lt;Product&gt; filter = Demo.filter(products, <span class="keyword">new</span> <span class="title class_">MyPredicate</span>&lt;Product&gt;() &#123;</span><br><span class="line">            <span class="meta">@Override</span></span><br><span class="line">            <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(Product product)</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> product.getPrice() &lt; <span class="number">6666</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Lambda方式</span></span><br><span class="line">        List&lt;Product&gt; filter2 = Demo.filter(products, product -&gt; product.getPrice() &lt; <span class="number">6666</span>);</span><br><span class="line">        filter2.stream().forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// Stream流方式（一步到位）</span></span><br><span class="line">        products.stream()</span><br><span class="line">                .filter(p -&gt; p.getPrice() &lt; <span class="number">6666</span>)</span><br><span class="line">                .limit(<span class="number">2</span>)</span><br><span class="line">                .forEach(System.out::println);</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> List&lt;Product&gt; <span class="title function_">filter</span><span class="params">(List&lt;Product&gt; list, MyPredicate&lt;Product&gt; mp)</span> &#123;</span><br><span class="line">        List&lt;Product&gt; prods = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        <span class="keyword">for</span> (Product prod : list) &#123;</span><br><span class="line">            <span class="keyword">if</span> (mp.test(prod)) &#123;</span><br><span class="line">                prods.add(prod);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> prods;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="stream-流"><a class="markdownIt-Anchor" href="#stream-流"></a> Stream 流</h2><p><code>Stream</code> 将要处理的元素集合看作一种流，在流的过程中借助 <code>Stream API</code> 对流中的元素进行操作，如筛选、排序、聚合等。</p><p><strong>stream 和 parallelStream 的区别：</strong></p><ul><li><code>stream</code>：顺序流，由主线程按顺序对流执行操作</li><li><code>parallelStream</code>：并行流，多线程处理后合并成顺序流，效率更高</li></ul><p><strong>Optional 类</strong>：可以为 null 的容器对象，<code>isPresent()</code> 判断值是否存在，<code>get()</code> 获取对象。</p><h3 id="案例-1流的创建"><a class="markdownIt-Anchor" href="#案例-1流的创建"></a> 案例 1：流的创建</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.IntStream;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Stream;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Stream1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建顺序流和并行流</span></span><br><span class="line">        Stream&lt;String&gt; stream = list.stream();</span><br><span class="line">        Stream&lt;String&gt; parallelStream = list.parallelStream();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 从数组创建</span></span><br><span class="line">        <span class="type">int</span>[] array = &#123;<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">8</span>&#125;;</span><br><span class="line">        <span class="type">IntStream</span> <span class="variable">stream3</span> <span class="operator">=</span> Arrays.stream(array);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 无限流 - iterate（初始值0，每次+3，取前4个）</span></span><br><span class="line">        Stream&lt;Integer&gt; stream2 = Stream.iterate(<span class="number">0</span>, x -&gt; x + <span class="number">3</span>).limit(<span class="number">4</span>);</span><br><span class="line">        stream2.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 无限流 - generate（随机数，取前3个）</span></span><br><span class="line">        Stream&lt;Double&gt; stream4 = Stream.generate(Math::random).limit(<span class="number">3</span>);</span><br><span class="line">        stream4.forEach(System.out::println);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 顺序流转并行流</span></span><br><span class="line">        List&lt;Integer&gt; list2 = Arrays.asList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">11</span>);</span><br><span class="line">        Optional&lt;Integer&gt; findFirst = list2.stream().parallel().filter(x -&gt; x &gt; <span class="number">6</span>).findFirst();</span><br><span class="line">        System.out.println(<span class="string">&quot;第一个大于6的是：&quot;</span> + findFirst);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="案例-2stream-常用操作"><a class="markdownIt-Anchor" href="#案例-2stream-常用操作"></a> 案例 2：Stream 常用操作</h3><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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.*;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Collectors;</span><br><span class="line"><span class="keyword">import</span> java.util.stream.Stream;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Stream2</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        List&lt;Person&gt; personList = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Tom&quot;</span>, <span class="number">8900</span>, <span class="number">23</span>, <span class="string">&quot;male&quot;</span>, <span class="string">&quot;New York&quot;</span>));</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Jack&quot;</span>, <span class="number">7000</span>, <span class="number">25</span>, <span class="string">&quot;male&quot;</span>, <span class="string">&quot;Washington&quot;</span>));</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Lily&quot;</span>, <span class="number">7800</span>, <span class="number">21</span>, <span class="string">&quot;female&quot;</span>, <span class="string">&quot;Washington&quot;</span>));</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Anni&quot;</span>, <span class="number">8200</span>, <span class="number">24</span>, <span class="string">&quot;female&quot;</span>, <span class="string">&quot;New York&quot;</span>));</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Owen&quot;</span>, <span class="number">9500</span>, <span class="number">25</span>, <span class="string">&quot;male&quot;</span>, <span class="string">&quot;New York&quot;</span>));</span><br><span class="line">        personList.add(<span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&quot;Alisa&quot;</span>, <span class="number">7900</span>, <span class="number">26</span>, <span class="string">&quot;female&quot;</span>, <span class="string">&quot;New York&quot;</span>));</span><br><span class="line"></span><br><span class="line">        fun1();</span><br><span class="line">        fun2();</span><br><span class="line">        fun3();</span><br><span class="line">        fun4(personList);</span><br><span class="line">        fun5(personList);</span><br><span class="line">        fun6();</span><br><span class="line">        fun7(personList);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 遍历/匹配</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; list = Arrays.asList(<span class="number">7</span>, <span class="number">6</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">8</span>, <span class="number">2</span>, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">        list.stream().filter(x -&gt; x &gt; <span class="number">6</span>).forEach(System.out::println);</span><br><span class="line">        Optional&lt;Integer&gt; findFirst = list.stream().filter(x -&gt; x &gt; <span class="number">6</span>).findFirst();</span><br><span class="line">        Optional&lt;Integer&gt; findAny = list.parallelStream().filter(x -&gt; x &gt; <span class="number">6</span>).findAny();</span><br><span class="line">        <span class="type">boolean</span> <span class="variable">anyMatch</span> <span class="operator">=</span> list.stream().anyMatch(x -&gt; x &gt; <span class="number">6</span>);</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;匹配第一个值：&quot;</span> + findFirst.get());</span><br><span class="line">        System.out.println(<span class="string">&quot;匹配任意一个值：&quot;</span> + findAny.get());</span><br><span class="line">        System.out.println(<span class="string">&quot;是否存在大于6的值：&quot;</span> + anyMatch);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 聚合 max/min</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun2</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;adnm&quot;</span>, <span class="string">&quot;admmt&quot;</span>, <span class="string">&quot;pot&quot;</span>, <span class="string">&quot;xbangd&quot;</span>, <span class="string">&quot;weoujgsd&quot;</span>);</span><br><span class="line">        Optional&lt;String&gt; max = list.stream().max(Comparator.comparing(String::length));</span><br><span class="line">        System.out.println(<span class="string">&quot;最长的字符串：&quot;</span> + max.get());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 排序</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun3</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;Integer&gt; list = Arrays.asList(<span class="number">7</span>, <span class="number">6</span>, <span class="number">9</span>, <span class="number">4</span>, <span class="number">11</span>, <span class="number">6</span>);</span><br><span class="line">        Optional&lt;Integer&gt; max = list.stream().max(Integer::compareTo);</span><br><span class="line">        Optional&lt;Integer&gt; min = list.stream().max((o1, o2) -&gt; o2 - o1);</span><br><span class="line">        System.out.println(<span class="string">&quot;自然排序的最大值：&quot;</span> + max.get());</span><br><span class="line">        System.out.println(<span class="string">&quot;自定义排序的最小值：&quot;</span> + min.get());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 统计</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun4</span><span class="params">(List&lt;Person&gt; personList)</span> &#123;</span><br><span class="line">        Optional&lt;Person&gt; max = personList.stream().max(Comparator.comparingInt(Person::getSalary));</span><br><span class="line">        System.out.println(<span class="string">&quot;员工薪资最大值：&quot;</span> + max.get().getSalary());</span><br><span class="line"></span><br><span class="line">        List&lt;Integer&gt; list = Arrays.asList(<span class="number">7</span>, <span class="number">6</span>, <span class="number">4</span>, <span class="number">8</span>, <span class="number">2</span>, <span class="number">11</span>, <span class="number">9</span>);</span><br><span class="line">        <span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> list.stream().filter(x -&gt; x &gt; <span class="number">6</span>).count();</span><br><span class="line">        System.out.println(<span class="string">&quot;list中大于6的元素个数：&quot;</span> + count);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 映射 map/flatMap</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun5</span><span class="params">(List&lt;Person&gt; personList)</span> &#123;</span><br><span class="line">        <span class="comment">// 英文字符串转大写，整数+3</span></span><br><span class="line">        String[] strArr = &#123;<span class="string">&quot;abcd&quot;</span>, <span class="string">&quot;bcdd&quot;</span>, <span class="string">&quot;defde&quot;</span>, <span class="string">&quot;fTr&quot;</span>&#125;;</span><br><span class="line">        List&lt;String&gt; strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());</span><br><span class="line">        List&lt;Integer&gt; intList = Arrays.asList(<span class="number">1</span>, <span class="number">3</span>, <span class="number">5</span>, <span class="number">7</span>, <span class="number">9</span>, <span class="number">11</span>);</span><br><span class="line">        List&lt;Integer&gt; intListNew = intList.stream().map(x -&gt; x + <span class="number">3</span>).collect(Collectors.toList());</span><br><span class="line">        System.out.println(<span class="string">&quot;每个元素大写：&quot;</span> + strList);</span><br><span class="line">        System.out.println(<span class="string">&quot;每个元素+3：&quot;</span> + intListNew);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 不改变原集合的方式（new 新对象）</span></span><br><span class="line">        List&lt;Person&gt; personListNew = personList.stream().map(person -&gt; &#123;</span><br><span class="line">            <span class="type">Person</span> <span class="variable">personNew</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Person</span>(person.getName(), <span class="number">0</span>, <span class="number">0</span>, <span class="literal">null</span>, <span class="literal">null</span>);</span><br><span class="line">            personNew.setSalary(person.getSalary() + <span class="number">10000</span>);</span><br><span class="line">            <span class="keyword">return</span> personNew;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line">        System.out.println(<span class="string">&quot;改动前：&quot;</span> + personList.get(<span class="number">0</span>).getSalary());</span><br><span class="line">        System.out.println(<span class="string">&quot;改动后：&quot;</span> + personListNew.get(<span class="number">0</span>).getSalary());</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 改变原集合的方式（直接操作原对象）</span></span><br><span class="line">        List&lt;Person&gt; personListNew2 = personList.stream().map(person -&gt; &#123;</span><br><span class="line">            person.setSalary(person.getSalary() + <span class="number">10000</span>);</span><br><span class="line">            <span class="keyword">return</span> person;</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// flatMap 扁平化</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun6</span><span class="params">()</span> &#123;</span><br><span class="line">        List&lt;String&gt; list = Arrays.asList(<span class="string">&quot;m-k-l-a&quot;</span>, <span class="string">&quot;1,3,5,7&quot;</span>);</span><br><span class="line">        List&lt;String&gt; listNew = list.stream().flatMap(s -&gt; &#123;</span><br><span class="line">            String[] split = s.split(<span class="string">&quot;-&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> Arrays.stream(split);</span><br><span class="line">        &#125;).collect(Collectors.toList());</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;处理前：&quot;</span> + list);</span><br><span class="line">        System.out.println(<span class="string">&quot;处理后：&quot;</span> + listNew);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// reduce 聚合</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">fun7</span><span class="params">(List&lt;Person&gt; personList)</span> &#123;</span><br><span class="line">        <span class="comment">// 求工资之和</span></span><br><span class="line">        Optional&lt;Integer&gt; sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);</span><br><span class="line">        <span class="type">Integer</span> <span class="variable">sumSalary2</span> <span class="operator">=</span> personList.stream().reduce(<span class="number">0</span>, (sum, p) -&gt; sum += p.getSalary(), Integer::sum);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 求最高工资</span></span><br><span class="line">        <span class="type">Integer</span> <span class="variable">maxSalary</span> <span class="operator">=</span> personList.stream().reduce(<span class="number">0</span>, (max, p) -&gt; max &gt; p.getSalary() ? max : p.getSalary(), Integer::max);</span><br><span class="line">        <span class="type">Integer</span> <span class="variable">maxSalary2</span> <span class="operator">=</span> personList.stream().map(Person::getSalary).reduce(Integer::max).get();</span><br><span class="line"></span><br><span class="line">        System.out.println(<span class="string">&quot;工资之和：&quot;</span> + sumSalary.get() + <span class="string">&quot;,&quot;</span> + sumSalary2);</span><br><span class="line">        System.out.println(<span class="string">&quot;最高工资：&quot;</span> + maxSalary + <span class="string">&quot;,&quot;</span> + maxSalary2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>Person 类：</strong></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> salary;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> age;</span><br><span class="line">    <span class="keyword">private</span> String sex;</span><br><span class="line">    <span class="keyword">private</span> String area;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Person</span><span class="params">()</span> &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Person</span><span class="params">(String name, <span class="type">int</span> salary, <span class="type">int</span> age, String sex, String area)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">        <span class="built_in">this</span>.salary = salary;</span><br><span class="line">        <span class="built_in">this</span>.age = age;</span><br><span class="line">        <span class="built_in">this</span>.sex = sex;</span><br><span class="line">        <span class="built_in">this</span>.area = area;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Person</span><span class="params">(String name, <span class="type">int</span> salary, String sex, String area)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">        <span class="built_in">this</span>.salary = salary;</span><br><span class="line">        <span class="built_in">this</span>.sex = sex;</span><br><span class="line">        <span class="built_in">this</span>.area = area;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getName</span><span class="params">()</span> &#123; <span class="keyword">return</span> name; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123; <span class="built_in">this</span>.name = name; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getSalary</span><span class="params">()</span> &#123; <span class="keyword">return</span> salary; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setSalary</span><span class="params">(<span class="type">int</span> salary)</span> &#123; <span class="built_in">this</span>.salary = salary; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getAge</span><span class="params">()</span> &#123; <span class="keyword">return</span> age; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setAge</span><span class="params">(<span class="type">int</span> age)</span> &#123; <span class="built_in">this</span>.age = age; &#125;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getSex</span><span class="params">()</span> &#123; <span class="keyword">return</span> sex; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setSex</span><span class="params">(String sex)</span> &#123; <span class="built_in">this</span>.sex = sex; &#125;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getArea</span><span class="params">()</span> &#123; <span class="keyword">return</span> area; &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setArea</span><span class="params">(String area)</span> &#123; <span class="built_in">this</span>.area = area; &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Person&#123;name=&#x27;&quot;</span> + name + <span class="string">&quot;&#x27;, salary=&quot;</span> + salary + <span class="string">&quot;, age=&quot;</span> + age + <span class="string">&quot;, sex=&#x27;&quot;</span> + sex + <span class="string">&quot;&#x27;, area=&#x27;&quot;</span> + area + <span class="string">&quot;&#x27;&#125;&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">吾生也有涯，而知也无涯</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Linux命令速查手册</title>
    <link href="https://luckynwa.top/posts/tool5/"/>
    <id>https://luckynwa.top/posts/tool5/</id>
    <published>2025-07-28T19:33:09.000Z</published>
    <updated>2026-07-07T16:19:34.149Z</updated>
    
    <content type="html"><![CDATA[<h2 id="查看路径下的文件和文件夹名称"><a class="markdownIt-Anchor" href="#查看路径下的文件和文件夹名称"></a> 查看路径下的文件和文件夹名称</h2><ul><li><code>-a</code> 显示隐藏文件</li><li><code>-l</code> 列表展示</li><li><code>-h</code> 显示文件大小</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ls -lah</span><br></pre></td></tr></table></figure><h2 id="切换工作目录"><a class="markdownIt-Anchor" href="#切换工作目录"></a> 切换工作目录</h2><p><code>cd /</code> 根目录，<code>..</code> 上一级，<code>-</code> 回退，<code>~</code> 也是根目录</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd 路径</span><br></pre></td></tr></table></figure><h2 id="查看当前工作目录"><a class="markdownIt-Anchor" href="#查看当前工作目录"></a> 查看当前工作目录</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pwd</span><br></pre></td></tr></table></figure><h2 id="相对路径和绝对路径"><a class="markdownIt-Anchor" href="#相对路径和绝对路径"></a> 相对路径和绝对路径</h2><p>绝对路径：从 <code>/</code> 根目录开始</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd /nwa/joplin</span><br></pre></td></tr></table></figure><p>相对路径：在当前目录下直接写</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd joplin</span><br></pre></td></tr></table></figure><h2 id="创建目录"><a class="markdownIt-Anchor" href="#创建目录"></a> 创建目录</h2><p><code>-p</code> 递归创建整条路径</p><figure class="highlight shell"><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">mkdir luckytextdir</span><br><span class="line">mkdir -p luckyt/hha/text/zzz</span><br></pre></td></tr></table></figure><h2 id="创建文件"><a class="markdownIt-Anchor" href="#创建文件"></a> 创建文件</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">touch 1.txt</span><br></pre></td></tr></table></figure><h2 id="查看文件内容"><a class="markdownIt-Anchor" href="#查看文件内容"></a> 查看文件内容</h2><p><code>cat</code> 一次性全部展示文件内容</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat docker-compose.yml</span><br></pre></td></tr></table></figure><p><code>more</code> 可以分页查看，空格向下翻页，回车换行，q退出，b往前翻</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">more docker-compose.yml</span><br></pre></td></tr></table></figure><h2 id="复制文件"><a class="markdownIt-Anchor" href="#复制文件"></a> 复制文件</h2><p><code>-r</code> 复制文件夹时使用，表示递归</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cp 1.txt 2.txt</span><br><span class="line">cp 1.txt /nwa/luckytextdir</span><br><span class="line">cp -a /nwa/frp .              # 复制目录至当前目录</span><br></pre></td></tr></table></figure><h2 id="移动文件或文件夹"><a class="markdownIt-Anchor" href="#移动文件或文件夹"></a> 移动文件或文件夹</h2><p>直接移动到当前路径有改名的效果</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mv 1.txt 11.txt</span><br><span class="line">mv 1.txt /nwa/luckytextdir/22.txt</span><br><span class="line">mv old_dir new_dir            # 重命名/移动目录</span><br></pre></td></tr></table></figure><h2 id="删除"><a class="markdownIt-Anchor" href="#删除"></a> 删除</h2><p><code>-r</code> 删除文件夹，<code>-f</code> 强制删除不提示确认</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">rm 1.txt</span><br><span class="line">rm -r -f luckyt</span><br><span class="line">rm *.txt</span><br><span class="line">rm -rf *                      # 当前目录全删</span><br><span class="line">rm -rf /*                     # 根目录全删（禁用）</span><br></pre></td></tr></table></figure><h2 id="内置命令查找"><a class="markdownIt-Anchor" href="#内置命令查找"></a> 内置命令查找</h2><p>查找命令的本体位置</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">which mkdir</span><br></pre></td></tr></table></figure><h2 id="查找文件"><a class="markdownIt-Anchor" href="#查找文件"></a> 查找文件</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">find / -name &quot;python&quot;         # 根目录查找</span><br><span class="line">find ./ -name &#x27;*.yml&#x27;         # 当前路径通配符查找</span><br><span class="line">find / -size +10M             # 查找大于10M的文件</span><br></pre></td></tr></table></figure><h2 id="切换root用户"><a class="markdownIt-Anchor" href="#切换root用户"></a> 切换root用户</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo su -</span><br></pre></td></tr></table></figure><h2 id="读取文件并过滤内容"><a class="markdownIt-Anchor" href="#读取文件并过滤内容"></a> 读取文件并过滤内容</h2><figure class="highlight shell"><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">grep &#x27;nginx&#x27; docker-compose.yml           # 过滤包含nginx的行</span><br><span class="line">grep ^A pwd.txt                           # 查找以A开头的内容</span><br></pre></td></tr></table></figure><h2 id="内容输入到文件"><a class="markdownIt-Anchor" href="#内容输入到文件"></a> 内容输入到文件</h2><p><code>&gt;</code> 覆盖写入，<code>&gt;&gt;</code> 追加写入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">echo &quot;abcdd&quot; &gt; 1.txt</span><br><span class="line">ls -l /usr/bin &gt; 2.txt                    # 输出转存到文件</span><br><span class="line">echo &quot;我当前的工作目录：`pwd`&quot;</span><br></pre></td></tr></table></figure><h2 id="查看文件尾部内容"><a class="markdownIt-Anchor" href="#查看文件尾部内容"></a> 查看文件尾部内容</h2><p><code>-f</code> 持续跟踪，<code>-10</code> 显示行数（默认10行）</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tail -f 1.txt</span><br></pre></td></tr></table></figure><h2 id="数量统计"><a class="markdownIt-Anchor" href="#数量统计"></a> 数量统计</h2><ul><li><code>-c</code> 统计bytes数量</li><li><code>-m</code> 统计字符数量</li><li><code>-l</code> 统计行数</li><li><code>-w</code> 统计单词数量</li></ul><p>1个英文对应一个字节，1个字节8个比特，1个utf8中文3个字节</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wc -c 1.txt</span><br></pre></td></tr></table></figure><h2 id="管道符"><a class="markdownIt-Anchor" href="#管道符"></a> 管道符</h2><p><code>|</code> 将左边命令的结果作为右边命令的输入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cat 1.txt | grep &#x27;好&#x27;</span><br><span class="line">cat 1.txt | grep &#x27;好&#x27; | wc -l           # 统计包含&quot;好&quot;的行数</span><br><span class="line">ls /usr/bin | wc -w</span><br></pre></td></tr></table></figure><h2 id="联网安装软件"><a class="markdownIt-Anchor" href="#联网安装软件"></a> 联网安装软件</h2><p>Debian/Ubuntu 用 <code>apt</code>，CentOS 用 <code>yum</code>，<code>-y</code> 不提示确认</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">apt install vim</span><br><span class="line">apt remove vim -y</span><br><span class="line">yum install -y vim</span><br></pre></td></tr></table></figure><h2 id="文本编辑"><a class="markdownIt-Anchor" href="#文本编辑"></a> 文本编辑</h2><p>vi 旧版，vim 新版，vim兼容vi全部功能</p><p><strong>三种模式</strong>：</p><ul><li>命令模式：按 <code>i</code> 进入输入模式</li><li>输入模式：按 <code>esc</code> 回退命令模式</li><li>底线命令模式：<code>:wq</code> 保存退出，<code>:q!</code> 不保存退出，<code>:w</code> 只保存</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim hello.txt</span><br></pre></td></tr></table></figure><p><strong>命令模式快捷键</strong>：</p><ul><li><code>/搜索内容</code> 进入搜索模式，n向下搜，N向上搜</li><li><code>p</code> 粘贴，<code>yy</code> 复制当前行，<code>u</code> 撤销，<code>gg</code> 跳首行，<code>G</code> 跳尾行</li><li><code>i</code> 当前位置进入输入，<code>a</code> 光标后进入输入</li></ul><h2 id="压缩"><a class="markdownIt-Anchor" href="#压缩"></a> 压缩</h2><ul><li><code>-c</code> 创建压缩包</li><li><code>-x</code> 解压</li><li><code>-v</code> 显示过程</li><li><code>-f</code> 指定文件名</li><li><code>-z</code> 使用gzip算法（针对.tar.gz文件）</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">tar -zcvf lucky.tar.gz *.txt</span><br><span class="line">tar -zxvf lucky.tar.gz</span><br><span class="line">tar -cvf lucky.tar *.txt</span><br><span class="line">tar -xvf lucky.tar</span><br></pre></td></tr></table></figure><h2 id="运维常用命令"><a class="markdownIt-Anchor" href="#运维常用命令"></a> 运维常用命令</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">服务管理</span></span><br><span class="line">sudo systemctl restart network          # 重启网络</span><br><span class="line">docker compose up -d                    # 启动服务</span><br><span class="line">docker-compose down                     # 停止服务</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">内存查看</span></span><br><span class="line">free -m</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">权限修改</span></span><br><span class="line">chmod 777 文件名                         # 最高权限</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进程管理</span></span><br><span class="line">ps -aux | grep java | grep -v grep      # 排除grep查看java进程</span><br><span class="line">kill -9 pid                             # 强制关闭进程</span><br></pre></td></tr></table></figure><h2 id="日志查看"><a class="markdownIt-Anchor" href="#日志查看"></a> 日志查看</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查找异常并显示后50行</span></span><br><span class="line">grep -A 50 &quot;java.lang.NullPointerException&quot; xxx.log</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">显示前后行数（A=After, B=Before, C=上下行）</span></span><br><span class="line">grep -A 50 &quot;java.lang.NullPointerException&quot; xxx.log | less</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">实时监控日志</span></span><br><span class="line">tail -f a.log | grep -A 50 &quot;java.lang.NullPointerException&quot;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">忽略大小写</span></span><br><span class="line">grep -i &quot;Exception&quot; a.log</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查找所有.<span class="built_in">log</span>文件中的内容（显示文件名）</span></span><br><span class="line">grep -H -A 50 &quot;java.lang.NullPointerException&quot; *.log</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">处理.gz压缩日志</span></span><br><span class="line">zgrep -H -A 50 &quot;java.lang.NullPointerException&quot; *.gz</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">统计异常出现次数</span></span><br><span class="line">grep -c &quot;java.lang.NullPointerException&quot; a.log</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">递归查找包含内容的文件</span></span><br><span class="line">grep -rl &quot;要查的内容&quot; *</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进入文件查看前后100行</span></span><br><span class="line">grep -n -C 100 &quot;要查内容&quot; xxx.log</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">less分页查看</span></span><br><span class="line">less xx.log</span><br><span class="line">/关键字     # 搜索</span><br><span class="line">n下一个     # N上一个</span><br><span class="line">q退出</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">博学之，审问之，慎思之，明辨之，笃行之</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Doc" scheme="https://luckynwa.top/tags/Doc/"/>
    
  </entry>
  
  <entry>
    <title>机器学习入门指南</title>
    <link href="https://luckynwa.top/posts/ai8/"/>
    <id>https://luckynwa.top/posts/ai8/</id>
    <published>2025-07-19T16:31:15.000Z</published>
    <updated>2026-07-07T16:20:55.837Z</updated>
    
    <content type="html"><![CDATA[<h2 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h2><p><strong>AI（Artificial Intelligence 人工智能）</strong>：用计算机模拟人脑，让计算机像人一样的思考和行动</p><p><strong>ML（Machine Learning 机器学习）</strong>：训练机器从数据中自动学习规律和模式</p><p><strong>DL（Deep Learning 深度学习）</strong>：也叫深度神经网络，大脑仿生，设计一层一层神经元模拟万事万物</p><blockquote><p>机器学习是实现人工智能的一种途径，深度学习是机器学习的一种方法（机器学习包含深度学习）</p></blockquote><p><strong>AI发展三要素</strong>：数据（决定模型效果上限）、算法、算力</p><h2 id="常用术语"><a class="markdownIt-Anchor" href="#常用术语"></a> 常用术语</h2><table><thead><tr><th>术语</th><th>英文</th><th>定义</th></tr></thead><tbody><tr><td>样本</td><td>sample</td><td>一行数据就是一个样本</td></tr><tr><td>数据集</td><td>dataset</td><td>多个样本组成数据集</td></tr><tr><td>特征</td><td>feature</td><td>一列数据一个特征，也叫属性</td></tr><tr><td>标签/目标</td><td>label/target</td><td>模型要预测的那一列数据</td></tr></tbody></table><p><strong>数据集划分</strong>：训练集用来训练模型、测试集用来测试评估模型，一般比例 7:3 或 8:2</p><p><strong>拟合</strong>：模型在训练集和测试集上的表现情况</p><ul><li><strong>欠拟合（under-fitting）</strong>：模型在训练集和测试集表现都不好 → 模型太简单</li><li><strong>过拟合（over-fitting）</strong>：训练集表现好，测试集表现不好 → 模型过复杂、数据不纯、训练数据太少</li></ul><p><strong>泛化（Generalization）</strong>：模型在新数据集（非训练数据）上表现好坏的能力</p><h2 id="ml算法分类"><a class="markdownIt-Anchor" href="#ml算法分类"></a> ML算法分类</h2><p><strong>有监督学习</strong>：有特征、有标签</p><ul><li>标签连续 → 回归问题（房屋信息–&gt;价格预测）</li><li>标签不连续 → 分类问题（猫/狗图片–&gt;猫|狗）</li></ul><p><strong>无监督学习</strong>：有特征、没有标签，基于样本间相似性（如：聚类）</p><p><strong>半监督学习</strong>：专家标注少量数据训练模型，用模型预测未标记数据，再由专家校验审核</p><p><strong>强化学习</strong>：寻找最优解以获取更多奖励</p><ul><li>四要素：Agent（智能体）、环境（environment）、行动（action）、奖励（reward）</li><li>示例：下象棋，每一步追求最优解</li></ul><h2 id="有监督分类问题"><a class="markdownIt-Anchor" href="#有监督分类问题"></a> 有监督分类问题</h2><p><strong>Classification</strong>：标签/目标不连续</p><ul><li>分类种类：二分类、多分类</li><li>示例：猫狗分类</li></ul><h2 id="有监督回归问题"><a class="markdownIt-Anchor" href="#有监督回归问题"></a> 有监督回归问题</h2><p><strong>Regression</strong>：目标是连续的，y=wx+b 线性回归</p><ul><li>示例：房价预测</li></ul><h2 id="无监督聚类问题"><a class="markdownIt-Anchor" href="#无监督聚类问题"></a> 无监督聚类问题</h2><p><strong>Clustering</strong>：有特征、没有标签</p><h2 id="ml建模流程"><a class="markdownIt-Anchor" href="#ml建模流程"></a> ML建模流程</h2><ol><li><strong>加载数据</strong>：图像数据、文本数据等</li><li><strong>数据预处理</strong>：处理缺失值、异常值等</li><li><strong>特征工程</strong>：<ul><li>特征提取（提取和任务相关特征）</li><li>特征预处理（归一化、<strong>标准化</strong>）</li><li>特征降维、特征选择、特征组合</li></ul></li><li><strong>模型训练</strong>：线性回归、决策树等</li><li><strong>评估</strong>：回归评测指标、分类评测指标等</li><li><strong>模型预测</strong>：图像数据、文本数据等</li></ol><h2 id="交叉验证"><a class="markdownIt-Anchor" href="#交叉验证"></a> 交叉验证</h2><p>数据集的分割方法，将训练集分n份，拿一份做验证集（测试集）、其他n-1份做训练集</p><p>是划分数据集的一种方法，目的为了得到更加准确可信的模型评分</p><p>解决：模型数据输入问题（数据集划分）</p><h2 id="网格搜索"><a class="markdownIt-Anchor" href="#网格搜索"></a> 网格搜索</h2><p>是模型调参的有力工具，只需将若干参数传给网格搜索对象，它自动帮我们完成不同超参数的组合、模型训练、模型评估，最终返回一组最优的超参数</p><blockquote><p>KNN的K就是超参</p></blockquote><p>解决：超参数的组合</p><p>一般都是<strong>网格搜索 + 交叉验证</strong>组合（模型选择和调优）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sklearn.model_selection.GridSearchCV(estimator, param_grid=<span class="literal">None</span>, cv=<span class="literal">None</span>)</span><br></pre></td></tr></table></figure><p>对估计器的指定参数值进行详尽搜索</p><ul><li><strong>estimator</strong>：估计器对象也就是模型</li><li><strong>param_grid</strong>：估计器参数 (dict) <code>&#123;&quot;n_neighbors&quot;: [1, 3, 5]&#125;</code></li><li><strong>cv</strong>：指定几折交叉验证</li><li><strong>fit</strong>：输入训练数据</li><li><strong>score</strong>：准确率</li></ul><p><strong>结果分析</strong>：</p><ul><li><strong>best_score</strong>：在交叉验证中验证的最好结果</li><li><strong>best_estimator</strong>：最好的参数模型</li><li><strong>cv_results</strong>：每次交叉验证后的验证集准确率结果和训练集准确率结果</li></ul><h2 id="knn算法"><a class="markdownIt-Anchor" href="#knn算法"></a> KNN算法</h2><p>K-近邻算法（K Nearest Neighbor）简称KNN，根据你的邻居来推断你的类型</p><p><strong>思想</strong>：一个样本在特征空间中的k个最相似的样本中，大多数属于某个类别，则该样本也属于这个类别</p><p><strong>距离度量</strong>：</p><ul><li><strong>欧式距离</strong>：对应维度差值平方和，开平方根<ul><li><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>d</mi><mo>=</mo><msqrt><mrow><mo stretchy="false">(</mo><msub><mi>x</mi><mn>1</mn></msub><mo>−</mo><msub><mi>x</mi><mn>2</mn></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup><mo>+</mo><mo stretchy="false">(</mo><msub><mi>y</mi><mn>1</mn></msub><mo>−</mo><msub><mi>y</mi><mn>2</mn></msub><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></msqrt></mrow><annotation encoding="application/x-tex">d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.69444em;vertical-align:0em;"></span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.24em;vertical-align:-0.30499999999999994em;"></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.935em;"><span class="svg-align" style="top:-3.2em;"><span class="pstrut" style="height:3.2em;"></span><span class="mord" style="padding-left:1em;"><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">y</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:-0.03588em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-2.8950000000000005em;"><span class="pstrut" style="height:3.2em;"></span><span class="hide-tail" style="min-width:1.02em;height:1.28em;"><svg width='400em' height='1.28em' viewBox='0 0 400000 1296' preserveAspectRatio='xMinYMin slice'><path d='M263,681c0.7,0,18,39.7,52,119c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120c340,-704.7,510.7,-1060.3,512,-1067l0 -0c4.7,-7.3,11,-11,19,-11H40000v40H1012.3s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60zM1001 80h400000v40h-400000z'/></svg></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.30499999999999994em;"><span></span></span></span></span></span></span></span></span></li></ul></li><li><strong>曼哈顿距离</strong>：对应维度差值的绝对值求和<ul><li>示例：坐标(0,0)到(6,6) → |0-6|+|0-6|=12步</li></ul></li></ul><p><strong>K值选择</strong>：</p><ul><li>K过大会欠投合 → 模型变得简单</li><li>K过小则过拟合 → 过度分析样本</li></ul><p><strong>算法步骤</strong>：</p><ol><li>计算未知样本到每一个训练样本的距离</li><li>将训练样本根据距离大小升序排序</li><li>取出距离最近的K个训练样本</li><li><strong>分类</strong>：进行多数表决，统计K个样本中哪个类别的样本个数最多</li><li><strong>回归</strong>：把K个样本的目标值计算其平均值</li></ol><h3 id="代码示例"><a class="markdownIt-Anchor" href="#代码示例"></a> 代码示例</h3><p><strong>分类问题</strong>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.neighbors <span class="keyword">import</span> KNeighborsClassifier</span><br><span class="line"></span><br><span class="line">x_train = [[<span class="number">1</span>], [<span class="number">2</span>], [<span class="number">3</span>], [<span class="number">4</span>]]  <span class="comment"># 训练集特征</span></span><br><span class="line">y_train = [<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>]  <span class="comment"># 训练集标签</span></span><br><span class="line">x_test = [[<span class="number">5</span>]]  <span class="comment"># 测试集特征</span></span><br><span class="line">model = KNeighborsClassifier(n_neighbors=<span class="number">2</span>)</span><br><span class="line">model.fit(x_train, y_train)</span><br><span class="line"></span><br><span class="line">y_test = model.predict(x_test)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;模型预测结果为：<span class="subst">&#123;y_test&#125;</span>&#x27;</span>)</span><br></pre></td></tr></table></figure><p><strong>回归问题</strong>：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.neighbors <span class="keyword">import</span> KNeighborsRegressor</span><br><span class="line"></span><br><span class="line">x_train = [[<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>], [<span class="number">1</span>, <span class="number">1</span>, <span class="number">0</span>], [<span class="number">3</span>, <span class="number">10</span>, <span class="number">10</span>], [<span class="number">4</span>, <span class="number">11</span>, <span class="number">12</span>]]</span><br><span class="line">y_train = [<span class="number">0.1</span>, <span class="number">0.2</span>, <span class="number">0.3</span>, <span class="number">0.4</span>]  <span class="comment"># 标签连续，一维数组</span></span><br><span class="line">x_test = [[<span class="number">3</span>, <span class="number">11</span>, <span class="number">10</span>]]</span><br><span class="line">model = KNeighborsRegressor(n_neighbors=<span class="number">3</span>)</span><br><span class="line">model.fit(x_train, y_train)</span><br><span class="line"></span><br><span class="line">y_test = model.predict(x_test)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;模型预测结果为：<span class="subst">&#123;y_test&#125;</span>&#x27;</span>)</span><br></pre></td></tr></table></figure><h2 id="归一化"><a class="markdownIt-Anchor" href="#归一化"></a> 归一化</h2><p>通过对原始数据进行变化，把数据映射到0到1之间，都包括左右</p><p><strong>适用场景</strong>：适合小数据集操作</p><p><strong>公式</strong>：（当前值-最小值）/（最大值-最小值）</p><table><thead><tr><th>样本</th><th>特征1 (原始)</th><th>特征2 (原始)</th><th>特征3 (原始)</th><th>特征4 (原始)</th></tr></thead><tbody><tr><td>A</td><td>90</td><td>2</td><td>10</td><td>40</td></tr><tr><td>B</td><td>60</td><td>4</td><td>15</td><td>45</td></tr><tr><td>C</td><td>75</td><td>3</td><td>13</td><td>46</td></tr></tbody></table><p><strong>示例</strong>：90 → (90-60)/(90-60)=1.0，60 → (60-60)/(90-60)=0</p><p><strong>映射到其他范围</strong>：结果 *（最大值-最小值）+ 最小值</p><table><thead><tr><th>样本</th><th>特征1</th><th>特征2</th><th>特征3</th><th>特征4</th></tr></thead><tbody><tr><td>A</td><td>1.0</td><td>0.0</td><td>0.0</td><td>0.0</td></tr><tr><td>B</td><td>0.0</td><td>1.0</td><td>1.0</td><td>0.83</td></tr><tr><td>C</td><td>0.5</td><td>0.5</td><td>0.6</td><td>1.0</td></tr></tbody></table><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.preprocessing <span class="keyword">import</span> MinMaxScaler</span><br><span class="line"></span><br><span class="line">x_train = [[<span class="number">90</span>, <span class="number">2</span>, <span class="number">10</span>, <span class="number">40</span>], [<span class="number">60</span>, <span class="number">4</span>, <span class="number">15</span>, <span class="number">45</span>], [<span class="number">75</span>, <span class="number">3</span>, <span class="number">13</span>, <span class="number">46</span>]]</span><br><span class="line">transfer = MinMaxScaler(feature_range=(<span class="number">0</span>, <span class="number">1</span>))</span><br><span class="line">x_train_new = transfer.fit_transform(x_train)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(x_train_new)</span><br></pre></td></tr></table></figure><h2 id="标准化"><a class="markdownIt-Anchor" href="#标准化"></a> 标准化</h2><p>数据标准化：通过对原始数据进行标准化，各列的值映射到<strong>均值为0、标准差为1</strong>的标准正态分布序列</p><p><strong>正态分布</strong>：也叫高斯分布，记作 N(μ, σ)</p><ul><li>μ决定其位置</li><li>标准差σ决定了分布的幅度</li></ul><p><strong>适用场景</strong>：大数据处理，样本大时异常值影响可忽略不计</p><p><strong>目的</strong>：解决量纲（单位）问题导致的模型评估较低等问题</p><p><strong>公式</strong>：x =（当前值-该列平均值）/ 该列的标准差σ</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> sklearn.preprocessing <span class="keyword">import</span> StandardScaler</span><br><span class="line"></span><br><span class="line">x_train = [[<span class="number">90</span>, <span class="number">2</span>, <span class="number">10</span>, <span class="number">40</span>],</span><br><span class="line">           [<span class="number">60</span>, <span class="number">4</span>, <span class="number">15</span>, <span class="number">45</span>],</span><br><span class="line">           [<span class="number">75</span>, <span class="number">3</span>, <span class="number">13</span>, <span class="number">46</span>]]</span><br><span class="line"></span><br><span class="line">transfer = StandardScaler()</span><br><span class="line">x_train_new = transfer.fit_transform(x_train)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;标准化后的数据为：\n<span class="subst">&#123;x_train_new&#125;</span>&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;数据集的均值为：<span class="subst">&#123;transfer.mean_&#125;</span>&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;数据集的方差为：<span class="subst">&#123;transfer.var_&#125;</span>&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;数据集的标准差为：<span class="subst">&#123;transfer.scale_&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出结果：</span></span><br><span class="line"><span class="comment"># [[ 1.22474487 -1.22474487 -1.29777137 -1.3970014 ]</span></span><br><span class="line"><span class="comment">#  [-1.22474487  1.22474487  1.13554995  0.50800051]</span></span><br><span class="line"><span class="comment">#  [ 0.          0.          0.16222142  0.88900089]]</span></span><br></pre></td></tr></table></figure><p><strong>计算示例</strong>（第一列）：</p><ul><li>均值：(90+60+75)/3 = 75</li><li>方差：((90-75)²+(60-75)²+(75-75)²)/3 = 150</li><li>标准差：√150 = 12.24744871</li><li>90标准化后：(90-75)/12.247 = 1.22474487</li></ul><p><strong>公式说明</strong>：</p><ul><li>方差 = 该列每个值与均值的差的平方和的平均值</li><li>标准差 = √方差</li></ul><h2 id="线性回归"><a class="markdownIt-Anchor" href="#线性回归"></a> 线性回归</h2><p><strong>定义</strong>：用一条线表示2个变量之间的关系</p><p><strong>公式</strong>：</p><ul><li>一元线性回归：y=kx+b（k斜率，b截距）</li><li>多元线性回归：y=w₁x₁+w₂x₂+…+b = wᵀx + b</li><li>其中：w（weight）权重，b（bias）偏置</li></ul><p><strong>应用场景</strong>：有了身高体重数据，根据身高去预测体重</p><p><strong>损失函数（loss function）</strong>：用来计算模型的预测值和真实值之间的误差，也叫代价函数、目标函数 = 各个样本的误差和，越小越好</p><p><strong>让损失函数最小的方法</strong>：</p><ul><li><strong>梯度下降法</strong>：更加普遍</li><li><strong>正规方程</strong>（求导、偏导）：适合数据量小</li></ul><h3 id="回归模型评估指标"><a class="markdownIt-Anchor" href="#回归模型评估指标"></a> 回归模型评估指标</h3><table><thead><tr><th>指标</th><th>全称</th><th>计算公式</th><th>说明</th></tr></thead><tbody><tr><td>MAE</td><td>平均绝对误差（Mean Absolute Error）</td><td>Σ|预测值−真实值| / 样本总数</td><td>反映预测值与真实值的平均误差，对异常值不敏感</td></tr><tr><td>MSE</td><td>均方误差（Mean Squared Error）</td><td>Σ(预测值−真实值)² / 样本总数</td><td>平方放大误差，对异常值敏感，最小二乘法常用</td></tr><tr><td>RMSE</td><td>均方根误差（Root Mean Squared Error）</td><td>√MSE</td><td>与原始数据单位一致，对较大误差更加敏感</td></tr></tbody></table><h3 id="sklearn-api"><a class="markdownIt-Anchor" href="#sklearn-api"></a> sklearn API</h3><p><strong>LinearRegression</strong>（正规方程优化）：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sklearn.linear_model.LinearRegression(fit_intercept=<span class="literal">True</span>)</span><br></pre></td></tr></table></figure><ul><li><strong>参数</strong>：fit_intercept 是否计算偏置</li><li><strong>属性</strong>：coef*（回归系数），intercept*（偏置）</li></ul><p><strong>SGDRegressor</strong>（随机梯度下降）：</p><figure class="highlight python"><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">sklearn.linear_model.SGDRegressor(loss=”squared_loss”, fit_intercept=<span class="literal">True</span>,</span><br><span class="line">                                   learning_rate=<span class="string">&#x27;constant&#x27;</span>, eta0=<span class="number">0.01</span>)</span><br></pre></td></tr></table></figure><ul><li><strong>参数</strong>：<ul><li>loss：损失函数类型</li><li>fit_intercept：是否计算偏置</li><li>learning_rate：学习率策略</li><li>eta0：学习率的值</li></ul></li><li><strong>属性</strong>：coef*（回归系数），intercept*（偏置）</li></ul><h2 id="梯度"><a class="markdownIt-Anchor" href="#梯度"></a> 梯度</h2><p><strong>概念</strong>：梯度的方向就是上升最快的方向，单变量函数就是导数，多变量函数就是偏导数</p><p><strong>梯度下降法公式</strong>：下一个点 = 当前点 - 学习率 × 损失函数</p><p><strong>学习率</strong>：范围一般 0.001~0.01</p><ul><li>太小：学的很慢</li><li>太大：抖动、震荡、错过最优解</li></ul><h3 id="梯度下降算法分类"><a class="markdownIt-Anchor" href="#梯度下降算法分类"></a> 梯度下降算法分类</h3><table><thead><tr><th>算法</th><th>全称</th><th>说明</th></tr></thead><tbody><tr><td>FGD</td><td>全梯度下降</td><td>使用全部样本的梯度值</td></tr><tr><td>SGD</td><td>随机梯度下降</td><td>随机选择一个样本的梯度值更新权重</td></tr><tr><td>Mini-batch</td><td>小批量梯度下降</td><td>随机选择小部分样本的梯度值更新权重（使用最多）</td></tr><tr><td>SAG</td><td>随机平均梯度下降</td><td>使用以前产生的梯度值来指导当前的梯度计算</td></tr></tbody></table><h2 id="逻辑回归"><a class="markdownIt-Anchor" href="#逻辑回归"></a> 逻辑回归</h2><p>一种分类模型，把线性回归的输出，作为逻辑回归的输入，输出（0,1）之间的值</p><p><strong>基本思想</strong>：</p><ol><li>利用线性模型 f(x)=wᵀx+b 根据特征的重要性计算出一个值</li><li>再使用 sigmoid 激活函数将 f(x) 的输出值映射为概率值<ul><li>设置阈值(eg: 0.5)，输出概率值大于 0.5 → 1类</li><li>否则 → 0类</li></ul></li></ol><p><strong>假设函数</strong>：h(x)=sigmoid(wᵀx+b)</p><blockquote><p>一般用于二分类</p></blockquote><p><strong>损失函数</strong>：- 极大似然估计函数</p><h3 id="分类问题评估"><a class="markdownIt-Anchor" href="#分类问题评估"></a> 分类问题评估</h3><p>混淆矩阵、精确率、召回率、F1-score</p><p><strong>示例</strong>：共10个样本，其中6个为恶性（正例），4个为良性（假例），模型A预测对了3个恶性肿瘤样本，4个良性肿瘤样本</p><table><thead><tr><th></th><th>预测：正例</th><th>预测：假例</th></tr></thead><tbody><tr><td>真实：正例 (6)</td><td>TP = 3</td><td>FN = 3</td></tr><tr><td>真实：假例 (4)</td><td>FP = 0</td><td>TN = 4</td></tr></tbody></table><table><thead><tr><th>指标</th><th>计算公式</th><th>含义</th></tr></thead><tbody><tr><td>精确率 (Precision)</td><td>TP/(TP+FP)</td><td>预测为正例的样本中，有多少是真的正例</td></tr><tr><td>召回率 (Recall)</td><td>TP/(TP+FN)</td><td>所有真实的正例样本中，有多少被成功预测出来</td></tr><tr><td>F1-Score</td><td>2×精确率×召回率/(精确率+召回率)</td><td>精确率和召回率的调和平均数</td></tr></tbody></table><h2 id="决策树"><a class="markdownIt-Anchor" href="#决策树"></a> 决策树</h2><p>树中每个内部节点表示一个特征上的判断，每个分支代表一个判断结果的输出，每个叶子节点代表一种分类结果</p><p><strong>核心概念</strong>：</p><ul><li><strong>信息熵</strong>：数据的混乱程度，数据越混乱，熵越大<ul><li>H = -Σ(Pᵢ × log₂Pᵢ)</li></ul></li><li><strong>条件熵</strong>：特征列中A分类占比 × 条件A的熵 + …</li><li><strong>信息增益</strong>：熵 - 条件熵</li><li><strong>信息增益率</strong>：信息增益 / 特征熵（C4.5树）</li></ul><h3 id="id3-决策树构建流程"><a class="markdownIt-Anchor" href="#id3-决策树构建流程"></a> ID3 决策树构建流程</h3><ol><li>计算每个特征的信息增益</li><li>使用信息增益最大的特征将数据集拆分为子集</li><li>使用该特征作为决策树的一个节点</li><li>使用剩余特征对子集重复上述过程</li></ol><h3 id="cart决策树classification-and-regression-tree"><a class="markdownIt-Anchor" href="#cart决策树classification-and-regression-tree"></a> CART决策树（Classification and Regression Tree）</h3><p>Cart模型是一种决策树模型，必须是二叉树，既可以用于分类，也可以用于回归</p><table><thead><tr><th>类型</th><th>策略</th></tr></thead><tbody><tr><td>Cart回归树</td><td>平方误差最小化</td></tr><tr><td>Cart分类树</td><td>基尼指数最小化</td></tr></tbody></table><p><strong>基尼值</strong>：从数据集中随机抽取两个样本，其类别标记不一致的概率 = 1 - ΣPᵢ²（越小越好，纯度越高）</p><p><strong>基尼系数</strong>：分类占比 × 基尼值 累加和</p><h3 id="剪枝"><a class="markdownIt-Anchor" href="#剪枝"></a> 剪枝</h3><p>把叶子节点、子节点删掉，用更大的叶子节点（子树）替换叶子节点</p><table><thead><tr><th>类型</th><th>说明</th></tr></thead><tbody><tr><td>预剪枝</td><td>在决策树生成过程中，对每个节点在划分前先进行估计，若当前节点的划分不能带来决策树泛化性能提升，则停止划分并将当前节点标记为叶节点</td></tr><tr><td>后剪枝</td><td>先从训练集生成一棵完整的决策树，然后自底向上地对非叶节点进行考察，若将该节点对应的子树替换为叶节点能带来决策树泛化性能提升，则将该子树替换为叶节点</td></tr></tbody></table><h2 id="集成学习"><a class="markdownIt-Anchor" href="#集成学习"></a> 集成学习</h2><p><strong>定义</strong>：构建并结合多个”弱学习器”（表现一般的模型），组合成一个”强学习器”</p><p><strong>目的</strong>：通过集体智慧，解决单一模型预测不准的问题，从而获得比单个模型更好的性能</p><h3 id="bagging思想代表算法随机森林"><a class="markdownIt-Anchor" href="#bagging思想代表算法随机森林"></a> Bagging思想（代表算法：随机森林）</h3><p>采用决策树模型作为每一个弱学习器</p><table><thead><tr><th>特点</th><th>说明</th></tr></thead><tbody><tr><td>有放回抽样</td><td>Bootstrap Sampling，允许重复抽取，每个子模型看到的数据略有不同</td></tr><tr><td>并行训练</td><td>所有的子模型同时训练，互不干扰，效率很高</td></tr><tr><td>平权投票</td><td>分类任务采用”多数表决”，回归任务采用”平均法”</td></tr></tbody></table><h3 id="boosting思想代表算法adaboost-gbdt-xgboost"><a class="markdownIt-Anchor" href="#boosting思想代表算法adaboost-gbdt-xgboost"></a> Boosting思想（代表算法：AdaBoost, GBDT, XGBoost）</h3><p>Boosting的核心在于**”串行”<strong>与</strong>”纠错”**</p><table><thead><tr><th>特点</th><th>说明</th></tr></thead><tbody><tr><td>关注不足</td><td>每一个新模型都是为了解决前一个模型的错误而生</td></tr><tr><td>串行训练</td><td>模型必须一个接一个地训练，后一个模型依赖于前一个模型的结果</td></tr><tr><td>加权投票</td><td>表现好的模型话语权更大（权重高），表现差的模型话语权小</td></tr></tbody></table><h2 id="聚类算法"><a class="markdownIt-Anchor" href="#聚类算法"></a> 聚类算法</h2><p>无监督学习，根据样本之间的相似度进行划分，一般用相似度计算方法，如欧式距离</p><p><strong>聚类分类</strong>：Kmeans算法、层次聚类、DBSCAN聚类、谱聚类</p><h3 id="sklearn实现"><a class="markdownIt-Anchor" href="#sklearn实现"></a> sklearn实现</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sklearn.cluster.KMeans(n_clusters=<span class="number">8</span>)</span><br></pre></td></tr></table></figure><p><strong>核心参数</strong>：</p><ul><li><code>n_clusters</code>：聚类中心数量（默认值8）</li><li>含义：指定生成的聚类数，即最终要产生的质心数量</li></ul><p><strong>常用方法</strong>：</p><ul><li><code>estimator.fit(x)</code>：训练模型，确定聚类中心的位置</li><li><code>estimator.predict(x)</code>：根据已确定的聚类中心，判断每个样本属于哪个类别</li><li><code>estimator.fit_predict(x)</code>：一步到位，同时完成”计算聚类中心”和”预测样本类别”</li></ul><h2 id="基础数学"><a class="markdownIt-Anchor" href="#基础数学"></a> 基础数学</h2><p><strong>为什么要学习标量、向量、矩阵、张量？</strong></p><p>宗旨：用到就学什么，不要盲目的展开、大篇幅学数学</p><table><thead><tr><th>概念</th><th>说明</th></tr></thead><tbody><tr><td>标量 scalar</td><td>一个独立存在的数，只有大小没有方向</td></tr><tr><td>向量 vector</td><td>一列顺序排列的元素，默认是列向量，有大小和方向</td></tr><tr><td>矩阵 matrix</td><td>二维数组，Pandas中的DataFrame</td></tr><tr><td>张量 tensor</td><td>基于向量和矩阵的推广，reshape(2,3,4) 表示2个3行4列的矩阵</td></tr></tbody></table><p><strong>导数</strong>：函数值变化量与自变量变化量的比值，当变化量趋于无穷小</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo><mo>=</mo><munder><mo><mi>lim</mi><mo>⁡</mo></mo><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo>+</mo><mi mathvariant="normal">Δ</mi><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><msub><mi>x</mi><mn>0</mn></msub><mo stretchy="false">)</mo></mrow><mrow><mi mathvariant="normal">Δ</mi><mi>x</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex">f&#x27;(x_0) = \lim_{\Delta x \to 0} \frac{f(x_0 + \Delta x) - f(x_0)}{\Delta x}</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.171331em;vertical-align:-0.744331em;"></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.69444em;"><span style="top:-2.355669em;margin-left:0em;"><span class="pstrut" style="height:3em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">Δ</span><span class="mord mathnormal mtight">x</span><span class="mrel mtight">→</span><span class="mord mtight">0</span></span></span></span><span style="top:-3em;"><span class="pstrut" style="height:3em;"></span><span><span class="mop">lim</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.744331em;"><span></span></span></span></span></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.427em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">Δ</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">Δ</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord"><span class="mord mathnormal">x</span><span class="msupsub"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:0.30110799999999993em;"><span style="top:-2.5500000000000003em;margin-left:0em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.15em;"><span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></span></span></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/03/image-20260610210148590_20260703192927A003.png" alt="image-20260610210148590" /></p><p><strong>导数四则运算</strong>：</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/03/image-20260610210420560_20260703193000A004.png" alt="image-20260610210420560" /></p><h2 id="鸢尾花"><a class="markdownIt-Anchor" href="#鸢尾花"></a> 鸢尾花</h2><h3 id="花特征"><a class="markdownIt-Anchor" href="#花特征"></a> 花特征</h3><table><thead><tr><th>特征</th><th>最小值</th><th>最大值</th><th>均值</th><th>标准差</th><th>类别相关性</th></tr></thead><tbody><tr><td>sepal length</td><td>4.3</td><td>7.9</td><td>5.84</td><td>0.83</td><td>0.7826</td></tr><tr><td>sepal width</td><td>2.0</td><td>4.4</td><td>3.05</td><td>0.43</td><td>-0.4194</td></tr><tr><td>petal length</td><td>1.0</td><td>6.9</td><td>3.76</td><td>1.76</td><td>0.9490 (high!)</td></tr><tr><td>petal width</td><td>0.1</td><td>2.5</td><td>1.20</td><td>0.76</td><td>0.9565 (high!)</td></tr></tbody></table><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line">有监督学习（Supervised Learning）</span><br><span class="line">│</span><br><span class="line">├── 分类（Classification）</span><br><span class="line">│      │</span><br><span class="line">│      ├── 二分类（Binary Classification）</span><br><span class="line">│      │      ├── 垃圾邮件识别</span><br><span class="line">│      │      ├── 猫/狗分类</span><br><span class="line">│      │      └── 是否违约</span><br><span class="line">│      │</span><br><span class="line">│      └── 多分类（Multi-class Classification）</span><br><span class="line">│             ├── 手写数字识别（0~9）</span><br><span class="line">│             ├── 动物分类</span><br><span class="line">│             └── 新闻分类</span><br><span class="line">│</span><br><span class="line">│      常用评估指标：</span><br><span class="line">│      ├── Accuracy（准确率）</span><br><span class="line">│      │      ├── 越大越好</span><br><span class="line">│      │      ├── 含义：预测正确样本占总样本比例</span><br><span class="line">│      │      └── 场景：类别均衡（如猫狗分类）</span><br><span class="line">│      │</span><br><span class="line">│      ├── Precision（精确率）</span><br><span class="line">│      │      ├── 越大越好，误报越少</span><br><span class="line">│      │      ├── 含义：预测为正的样本中，有多少是真的正样本（减少误报 FP）</span><br><span class="line">│      │      └── 场景：垃圾邮件、推荐系统、人脸识别（不能误报）</span><br><span class="line">│      │</span><br><span class="line">│      ├── Recall（召回率）</span><br><span class="line">│      │      ├── 越大越好，漏报越少</span><br><span class="line">│      │      ├── 含义：真实正样本中，有多少被找出来（减少漏报 FN）</span><br><span class="line">│      │      └── 场景：癌症检测、欺诈检测、安全风控（不能漏报）</span><br><span class="line">│      │</span><br><span class="line">│      ├── F1 Score</span><br><span class="line">│      │      ├── 越大越好</span><br><span class="line">│      │      ├── 含义：精确和召回的综合指标</span><br><span class="line">│      │      └── 场景：类别不平衡，需要兼顾误报和漏报</span><br><span class="line">│      │</span><br><span class="line">│      └── AUC-ROC</span><br><span class="line">│             ├── 越大越好（0.5≈随机，1.0最好）</span><br><span class="line">│             ├── 含义：模型区分正负样本的整体能力</span><br><span class="line">│             └── 场景：二分类模型比较、类别不平衡、评价整体性能</span><br><span class="line">│</span><br><span class="line">└── 回归（Regression）</span><br><span class="line">       │</span><br><span class="line">       ├── 房价预测</span><br><span class="line">       ├── 温度预测</span><br><span class="line">       ├── 销售额预测</span><br><span class="line">       └── 股票价格预测</span><br><span class="line"></span><br><span class="line">       常用评估指标：</span><br><span class="line">       ├── MAE（平均绝对误差）</span><br><span class="line">       │      ├── 越小越好</span><br><span class="line">       │      ├── 含义：平均预测误差</span><br><span class="line">       │      └── 场景：关注平均误差，对异常值不敏感</span><br><span class="line">       │</span><br><span class="line">       ├── MSE（均方误差）</span><br><span class="line">       │      ├── 越小越好</span><br><span class="line">       │      ├── 含义：平方后的平均误差，会放大大误差</span><br><span class="line">       │      └── 场景：希望重点惩罚大误差（训练损失常用）</span><br><span class="line">       │</span><br><span class="line">       ├── RMSE（均方根误差）</span><br><span class="line">       │      ├── 越小越好</span><br><span class="line">       │      ├── 含义：MSE 开平方，与原始数据单位一致</span><br><span class="line">       │      └── 场景：最常用的回归评估指标，易解释</span><br><span class="line">       │</span><br><span class="line">       ├── R²（决定系数）</span><br><span class="line">       │      ├── 越接近1越好</span><br><span class="line">       │      ├── 含义：模型对数据变化的解释能力</span><br><span class="line">       │      └── 场景：比较不同回归模型拟合效果</span><br><span class="line">       │</span><br><span class="line">       └── MAPE（平均绝对百分比误差）</span><br><span class="line">              ├── 越小越好</span><br><span class="line">              ├── 含义：预测误差占真实值的百分比</span><br><span class="line">              └── 场景：销售预测、流量预测、业务指标预测（便于业务理解）</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">纸上得来终觉浅，绝知此事要躬行</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Python" scheme="https://luckynwa.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>Stable Diffusion 环境搭建与使用指南</title>
    <link href="https://luckynwa.top/posts/ai4/"/>
    <id>https://luckynwa.top/posts/ai4/</id>
    <published>2025-06-21T22:34:51.000Z</published>
    <updated>2026-07-07T16:19:34.163Z</updated>
    
    <content type="html"><![CDATA[<h1 id="环境"><a class="markdownIt-Anchor" href="#环境"></a> 环境</h1><p>python-3.10.6-amd64.exe 安装记得全局 path 勾选，其他默认即可</p><p>cmd python -V 查看版本</p><p>cmd 输入 nvidia-smi 查看 cuda 的版本 12.1</p><p><a href="https://developer.nvidia.com/cuda-toolkit-archive">https://developer.nvidia.com/cuda-toolkit-archive</a> cuda 官网</p><p>选 local 安装</p><p><a href="https://space.bilibili.com/12566101/video">https://space.bilibili.com/12566101/video</a></p><p>下载 stable diffusion 整合包</p><p>训练模型的位置 D:\bgsoft\sd-webui-aki\sd-webui-aki-v4\models\Stable-diffusion</p><p>后缀 safetensors| ckpt 大模型</p><p>还需要去网页那点击刷新按钮，</p><p>旁边还有一个VAE（变分自解码器调色滤镜）D:\bgsoft\sd-webui-aki\sd-webui-aki-v4\models\VAE</p><h1 id="使用"><a class="markdownIt-Anchor" href="#使用"></a> 使用</h1><h2 id="通用提示词"><a class="markdownIt-Anchor" href="#通用提示词"></a> 通用提示词</h2><p>*正面提示词后</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(masterpiece:1,2), best quality, masterpiece, highres, original, extremely detailed wallpaper, perfect lighting,(extremely detailed CG:1.2), drawing, paintbrush,</span><br></pre></td></tr></table></figure><p>插画风</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">illustration,painting,paintbrush</span><br></pre></td></tr></table></figure><p>二次风</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">anime,comic,gane CG</span><br></pre></td></tr></table></figure><p>写实</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">photorealistic,realistic,photograph</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></pre></td><td class="code"><pre><span class="line">NSFW, (worst quality:2), (low quality:2), (normal quality:2), lowres, normal quality, ((monochrome)), ((grayscale)), skin spots, acnes, skin blemishes, age spot, (ugly:1.331), (duplicate:1.331), (morbid:1.21), (mutilated:1.21), (tranny:1.331), mutated hands, (poorly drawn hands:1.5), blurry, (bad anatomy:1.21), (bad proportions:1.331), extra limbs, (disfigured:1.331), (missing arms:1.331), (extra legs:1.331), (fused fingers:1.61051), (too many fingers:1.61051), (unclear eyes:1.331), lowers, bad hands, missing fingers, extra digit,bad hands, missing fingers, (((extra arms and legs))),</span><br></pre></td></tr></table></figure><p>:后面是权重</p><h2 id="文生图"><a class="markdownIt-Anchor" href="#文生图"></a> 文生图</h2><h3 id="二次元风格"><a class="markdownIt-Anchor" href="#二次元风格"></a> 二次元风格</h3><p>默认20算力高步数30-40 | 采样方法推荐带+，DPM+ | 勾面部修复 | 宽800高450</p><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa6/lucky-pic-bed@main/img/image-20240805205031133.png" alt="image-20240805205031133" /></p><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa6/lucky-pic-bed@main/img/image-20240805211042457.png" alt="image-20240805211042457" /></p><h2 id="图生图"><a class="markdownIt-Anchor" href="#图生图"></a> 图生图</h2><p>重绘幅度是和原图有多像，其他和文生图差不多</p><p>随机种子 -1就是每次都是新的，可以看到生成的图中有Seed: 3010602137这个可以保持风格基本一致，换背景</p><p>勾选高清修复</p><p>会先生低分辨率—&gt;再生高分辨率的</p><p>R-E… |二次元 选 …+Anime6B 0 0.7</p><p>2 0 0</p><p>一般都是低分辨率下炼丹，再借助固定随机种子，来进行高分辨率修复，放大安全区0.3-0.5.高了就让ai现象了</p><p>3、结合 chatGPT</p><p>将我给你说的一段话转换为 AI 绘画关键字。请转化下面这段话并且中英文双语回答我：这个美女在一间安静的图书馆里，她坐在一张舒适的椅子上，身穿清新简洁的白色衬衫，秀发轻轻地梳了一下，留在肩膀上，散发着淡淡的香气。她深深地沉浸在一本书中，眉头微皱，似乎在思考着书中所阐述的概念，不时翻动书页，倾听着心中的声音。周围的环境十分安静，只有书页翻动的声音以及微弱的呼吸声，显得更加静谧而优雅。整个场景充满了一种优雅、安静、充满知识氛围的感觉，让人心生向往。</p><p>ai:英文关键词：Quiet Library, Comfortable Chair, White Shirt, Gentle Scent, Immersed in Book, Concept, Quietness, Elegance, Knowledge Atmosphere, Wistfulness.</p><p>中文关键词：安静的图书馆，舒适的椅子，白色衬衫，淡淡的香气，沉浸在书中，概念，宁静，优雅，知识氛围，向往之感。</p><p>如何写提示词？</p><p>内容提示词：人物及主题特征 穿衣颜色 发色 面部 五官 肢体动作 室内、外 小细节 白天黑夜 特定时段 光环境 天空 距离 人物比例 观察视角 镜头类型</p><p>标准化提示词：通用高画质、特定分辨率、插画风、二次元、写实系</p><p>给提示词加()、{}来提高权重 削弱[]</p><p>补充：painting,illustration,anime,game cg</p><p>通用高画质：best quality,ultra detailed,masterpiece,8k</p><p>特定超高分辨率类型 ：unreal engine rendered,extremely detailed CG unity 8k wallpaper,</p><p>下面是反面</p><p>NSFW, (worst quality2), low quality2),(normal quality,2) lowres, normal quality,([grayscale)l,skin spots, acnes, skin blemishes, age spot,(ugly.1.331),(duplicate1.331) (morbid:1.21),(mutlated:1.21),(tranny,1.331), mutated hands,(poorly drawn hands:1.5), blurry,(bad anatomy.1.21),(bad proportions:1.331, extra limbs,(disigured1.331,(missing arms:1.331),(extra legs:1.31,(fused fingers;1.61051),(too many fingers:1.61051),(unclear eyes:1.331), lowers, bad hands, missing fingers, extra digit,bad hands, missing fingers,(lextra arms and legs)</p><p>案例 1</p><p>Realistic Beauty Girl: A realistic depiction of a beautiful young girl, with long blonde hair, a smallgolden hairband, blue eyes, a royal sister-like look, a cold face, and a white shirt. Her portrait isdetailed and intricate, with 8K wallpapers, gorgeous girls, and a stunning upper body. She has acold expression and is looking at the viewer, wearing school uniform, sailor suit, and crazy whitehair. She has red eyes, detailed double eyes with a black crosshair, handsome, glowing, andtheatrical angle.Her 8K wallpaper is detailed, with a girl with red eyes, white hair, a ponytail, longhair, light pink inner hair, white windbreaker, inner blue clothes, studio photography, masterpiece,movie highlight hair, and exquisite hands. Her exterior features include nipples, small chest, flatchest, highest quality, very detailed, masterpiece,ultra-details, illustration, extremely delicate andbeautiful loli, very detailed eyes and face, detailed eye details, masterpiece, best illustration, aquablue eyes, bright eyes, movie lights, extremely delicate and beautiful loli, gradient eyes, white hair,red eyes, and twelve-year-old loli,(best quality},,{highres} ,original,extremely detailed wallpaper,1girl,{an extremely delicate and beautifull}</p><p>Lowres, bad anatomy, bad hands, text, error,missing fingers, extra digit,fewerdigits, cropped, worst quality,low quality,normal quality,jpeg artifacts,signature, watermark, username, blurry,missing arms,long neck, Humpbacked</p><p>使用二次元风格模型：illustration,painting, sketch, drawing, painting, comic, anime, catoon</p><p>真实：photography, photo, realistic, photorealistic,RAW photo</p><p>2.5d:3D, render,chibi, digital art, concept art, {realistic}</p><h2 id="模型总结"><a class="markdownIt-Anchor" href="#模型总结"></a> 模型总结</h2><p>二次元：</p><p>1.最受欢迎的二次元模型：Anything</p><p>2精致度满满，室内外场景优秀：counterfeit</p><p>3.魔幻感十足：dreamlike diffusion</p><p>真实：</p><p>1.真实朴素：Realistic vision</p><p>2.照片级：Lofi</p><p>3.精细的写实风格：deliberate</p><p>2.5D</p><p>1.动漫角色的二次创作，即真实又二次元：never ending dream</p><p>2.超现实的画面：Protogen x3.4 (Photorealism)</p><p>3.国风、小人书、水墨风：guofeng</p><p>3 拓展： 富有现代感的建筑（dvArch - Multi-Prompt Archittecture Tuned Model)</p><p>富有魔幻感的场景(Cheese Daddy’s Landscapes mix)</p><p>富有高级感的平面设计(Graphic design_2.0)</p><h1 id="comfyui"><a class="markdownIt-Anchor" href="#comfyui"></a> ComfyUI</h1><p>翻译插件 <a href="https://github.com/a63976659/ComfyUI-Chinese-Translation">https://github.com/a63976659/ComfyUI-Chinese-Translation</a></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">cd</span> ComfyUI/custom_nodes</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/a63976659/ComfyUI-Chinese-Translation.git</span><br></pre></td></tr></table></figure><p>TODO</p>]]></content>
    
    
    <summary type="html">会当凌绝顶，一览众山小</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>Dify 私有化部署指南</title>
    <link href="https://luckynwa.top/posts/ai2/"/>
    <id>https://luckynwa.top/posts/ai2/</id>
    <published>2025-06-08T03:48:45.000Z</published>
    <updated>2026-07-07T16:19:34.169Z</updated>
    
    <content type="html"><![CDATA[<h2 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h2><p>Dify 是一个开源的 LLM 应用开发平台，提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理、可观测性等能力，帮助开发者快速搭建和部署生产级的 AI 应用。本文将介绍如何使用 Docker Compose 进行本地部署。</p><h2 id="环境准备"><a class="markdownIt-Anchor" href="#环境准备"></a> 环境准备</h2><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">apt install -y jq</span><br></pre></td></tr></table></figure><h2 id="获取项目代码"><a class="markdownIt-Anchor" href="#获取项目代码"></a> 获取项目代码</h2><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> --branch <span class="string">&quot;<span class="subst">$(curl -s https://api.github.com/repos/langgenius/dify/releases/latest | jq -r .tag_name)</span>&quot;</span> https://github.com/langgenius/dify.git</span><br></pre></td></tr></table></figure><h2 id="初始化配置"><a class="markdownIt-Anchor" href="#初始化配置"></a> 初始化配置</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 class="built_in">cd</span> dify/docker</span><br><span class="line"><span class="built_in">cp</span> .env.example .<span class="built_in">env</span></span><br></pre></td></tr></table></figure><h2 id="拉取-docker-镜像"><a class="markdownIt-Anchor" href="#拉取-docker-镜像"></a> 拉取 Docker 镜像</h2><blockquote><p>⚠️ 服务器需要配置代理才能访问 Docker Hub，建议先完成代理配置。</p></blockquote><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">docker pull redis:6-alpine</span><br><span class="line">docker pull postgres:15-alpine</span><br><span class="line">docker pull langgenius/dify-api:1.13.2</span><br><span class="line">docker pull langgenius/dify-web:1.13.2</span><br><span class="line">docker pull semitechnologies/weaviate:1.27.0</span><br><span class="line">docker pull ubuntu/squid:latest</span><br><span class="line">docker pull nginx:latest</span><br><span class="line">docker pull busybox:latest</span><br><span class="line">docker pull langgenius/dify-plugin-daemon:0.5.4-<span class="built_in">local</span></span><br><span class="line">docker pull langgenius/dify-sandbox:0.2.12</span><br></pre></td></tr></table></figure><h2 id="启动服务"><a class="markdownIt-Anchor" href="#启动服务"></a> 启动服务</h2><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><h2 id="访问服务"><a class="markdownIt-Anchor" href="#访问服务"></a> 访问服务</h2><p>服务默认使用 80 端口，以下为映射后的访问地址：</p><ul><li>本地访问：<a href="http://localhost/install">http://localhost/install</a></li><li>内网访问：<a href="http://127.0.0.1:20080/install">http://127.0.0.1:20080/install</a></li><li>外网访问：<a href="http://ip:20080">http://ip:20080</a></li></ul><p>内外穿透到外网，首次访问需要设置管理员账号。1656… luckyNwa Nwa…</p><h2 id="注意事项"><a class="markdownIt-Anchor" href="#注意事项"></a> 注意事项</h2><ul><li>下载模型插件时需要开启代理</li><li>确保服务器防火墙已开放对应端口</li></ul>]]></content>
    
    
    <summary type="html">宝剑锋从磨砺出，梅花香自苦寒来</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Ops" scheme="https://luckynwa.top/tags/Ops/"/>
    
  </entry>
  
  <entry>
    <title>Typora 常用语法</title>
    <link href="https://luckynwa.top/posts/tool14/"/>
    <id>https://luckynwa.top/posts/tool14/</id>
    <published>2025-04-29T19:32:52.000Z</published>
    <updated>2026-07-07T16:20:55.639Z</updated>
    
    <content type="html"><![CDATA[<h2 id="文字样式"><a class="markdownIt-Anchor" href="#文字样式"></a> 文字样式</h2><table><thead><tr><th style="text-align:center">样式</th><th style="text-align:center">语法</th><th style="text-align:center">快捷键</th></tr></thead><tbody><tr><td style="text-align:center"><strong>加粗</strong></td><td style="text-align:center"><code>**文字**</code></td><td style="text-align:center"><code>Ctrl+B</code></td></tr><tr><td style="text-align:center"><em>倾斜</em></td><td style="text-align:center"><code>*文字*</code></td><td style="text-align:center"><code>Ctrl+I</code></td></tr><tr><td style="text-align:center"><strong><em>加粗斜体</em></strong></td><td style="text-align:center"><code>***文字***</code></td><td style="text-align:center">—</td></tr><tr><td style="text-align:center"><s>删除线</s></td><td style="text-align:center"><code>~~文字~~</code></td><td style="text-align:center">—</td></tr><tr><td style="text-align:center"><code>行内代码</code></td><td style="text-align:center"><code>`文字`</code></td><td style="text-align:center">—</td></tr></tbody></table><blockquote><p>💡 选中文字后按快捷键可快速设置样式，效果和手动输入语法一致。</p></blockquote><h2 id="图片与链接"><a class="markdownIt-Anchor" href="#图片与链接"></a> 图片与链接</h2><h3 id="插入图片"><a class="markdownIt-Anchor" href="#插入图片"></a> 插入图片</h3><p>支持直接拖入图片，也可手动输入语法：</p><figure class="highlight plaintext"><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">![示例](/img/demo.jpg &#x27;悬停提示文字&#x27;)</span><br></pre></td></tr></table></figure><p>效果如下：</p><p><img src="https://cloud.luckynwa.top/profile/blog/loading.gif" alt="" /></p><h3 id="超链接跳转"><a class="markdownIt-Anchor" href="#超链接跳转"></a> 超链接跳转</h3><p><code>Ctrl + 点击</code> 可跳转到链接地址：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[百度](https://www.baidu.com/ &quot;悬停提示文字&quot;)</span><br></pre></td></tr></table></figure><p>示例：<a href="https://www.baidu.com/" title="www.baidu.com">百度</a></p><h3 id="图片链接"><a class="markdownIt-Anchor" href="#图片链接"></a> 图片链接</h3><p>点击图片跳转到指定地址：</p><figure class="highlight plaintext"><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="代码块"><a class="markdownIt-Anchor" href="#代码块"></a> 代码块</h2><h3 id="行内代码"><a class="markdownIt-Anchor" href="#行内代码"></a> 行内代码</h3><p>使用单个反引号包裹：<code>`code`</code></p><h3 id="代码块-2"><a class="markdownIt-Anchor" href="#代码块-2"></a> 代码块</h3><p>使用三个反引号包裹，后面指定语言可实现语法高亮：</p><figure class="highlight javascript"><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="string">``</span><span class="string">`javascript</span></span><br><span class="line"><span class="string">const a = &#x27;luckyNwa&#x27;</span></span><br><span class="line"><span class="string">`</span><span class="string">``</span></span><br></pre></td></tr></table></figure><h2 id="列表"><a class="markdownIt-Anchor" href="#列表"></a> 列表</h2><h3 id="无序列表"><a class="markdownIt-Anchor" href="#无序列表"></a> 无序列表</h3><p>使用 <code>+</code>、<code>-</code> 或 <code>*</code> 后加空格创建：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">- 第一项</span><br><span class="line">- 第二项</span><br><span class="line">  - 嵌套项</span><br><span class="line">+ 第三项</span><br></pre></td></tr></table></figure><h3 id="有序列表"><a class="markdownIt-Anchor" href="#有序列表"></a> 有序列表</h3><p>使用数字加 <code>.</code> 后加空格创建：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. 第一步</span><br><span class="line">2. 第二步</span><br><span class="line">3. 第三步</span><br></pre></td></tr></table></figure><h3 id="任务列表"><a class="markdownIt-Anchor" href="#任务列表"></a> 任务列表</h3><p>使用 <code>- [ ]</code> 创建待办项，<code>- [x]</code> 表示已完成：</p><figure class="highlight plaintext"><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">- [x] 已完成的任务</span><br><span class="line">- [ ] 未完成的任务</span><br></pre></td></tr></table></figure><ul><li>[x] 已完成的任务</li><li>[ ] 未完成的任务</li></ul><h2 id="引用"><a class="markdownIt-Anchor" href="#引用"></a> 引用</h2><p>使用 <code>&gt;</code> 后加空格创建引用块，支持多层嵌套：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&gt; 这是一级引用</span><br><span class="line">&gt;&gt; 这是二级引用</span><br><span class="line">&gt;&gt;&gt; 这是三级引用</span><br></pre></td></tr></table></figure><blockquote><p>一级引用内容</p><blockquote><p>二级引用内容</p><blockquote><p>三级引用内容</p></blockquote></blockquote></blockquote><h2 id="表格"><a class="markdownIt-Anchor" href="#表格"></a> 表格</h2><p>使用 <code>|</code> 和 <code>-</code> 绘制表格，<code>:</code> 可控制对齐方式：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">| 左对齐 | 居中对齐 | 右对齐 |</span><br><span class="line">| :----- | :------: | -----: |</span><br><span class="line">| 内容1  |  内容2   |  内容3 |</span><br></pre></td></tr></table></figure><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></tbody></table><h2 id="分割线"><a class="markdownIt-Anchor" href="#分割线"></a> 分割线</h2><p>使用三个及以上的 <code>-</code> 或 <code>*</code> 创建分割线：</p><figure class="highlight plaintext"><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">***</span><br></pre></td></tr></table></figure><hr /><h2 id="数学公式"><a class="markdownIt-Anchor" href="#数学公式"></a> 数学公式</h2><p>Typora 支持 LaTeX 数学公式：</p><ul><li><p><strong>行内公式</strong>：用 <code>$</code> 包裹，如 <code>$E=mc^2$</code> → <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>E</mi><mo>=</mo><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">E=mc^2</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord mathnormal" style="margin-right:0.05764em;">E</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8141079999999999em;vertical-align:0em;"></span><span class="mord mathnormal">m</span><span class="mord"><span class="mord mathnormal">c</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span></span></p></li><li><p><strong>块级公式</strong>：用 <code>$$</code> 包裹：</p><p class='katex-block'><span class="katex-display"><span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac><mspace linebreak="newline"></mspace><mspace linebreak="newline"></mspace><mtext>上（分子）：</mtext><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo separator="true">;</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>0</mn><mo separator="true">;</mo><mspace linebreak="newline"></mspace><mtext>下（分母）：</mtext><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mtext>就是对</mtext><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mtext>采用链式法则求导</mtext><mspace linebreak="newline"></mspace><mspace linebreak="newline"></mspace><mtext>外层函数：</mtext><mi>f</mi><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>e</mi><mi>u</mi></msup><mo separator="true">,</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">)</mo><mo>=</mo><msup><mi>e</mi><mi>u</mi></msup><mo separator="true">;</mo><mtext>内层函数：</mtext><mi>u</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mi>x</mi><mo separator="true">,</mo><msup><mi>u</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><mn>1</mn><mspace linebreak="newline"></mspace><mtext>链式法则公式：</mtext><mfrac><mi>d</mi><mrow><mi>d</mi><mi>x</mi></mrow></mfrac><mi>f</mi><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo>=</mo><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>u</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>u</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mspace linebreak="newline"></mspace><mfrac><mi>d</mi><mrow><mi>d</mi><mi>x</mi></mrow></mfrac><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mtext>求导过程【外层先导，把</mtext><mi>u</mi><mtext>是</mtext><mo>−</mo><mi>x</mi><mtext>带入，再乘内层导数】结果：</mtext><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mo>⋅</mo><mo stretchy="false">(</mo><mo>−</mo><mn>1</mn><mo stretchy="false">)</mo><mspace linebreak="newline"></mspace><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mi>d</mi><mrow><mi>d</mi><mi>x</mi></mrow></mfrac><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mo stretchy="false">)</mo><mo>=</mo><mo>−</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mspace linebreak="newline"></mspace><mtext>然后使用商法则来求导</mtext><mo separator="true">,</mo><mo stretchy="false">(</mo><mtext>上导</mtext><mo>∗</mo><mtext>下−上</mtext><mo>∗</mo><mtext>下导</mtext><mo stretchy="false">)</mo><mi mathvariant="normal">/</mi><mtext>下²</mtext><mo separator="true">,</mo><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><msup><mi>f</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>⋅</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>−</mo><mi>f</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>⋅</mo><msup><mi>g</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo></mrow><mrow><mo stretchy="false">[</mo><mi>g</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><msup><mo stretchy="false">]</mo><mn>2</mn></msup></mrow></mfrac><mspace linebreak="newline"></mspace><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mn>0</mn><mo>⋅</mo><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mo stretchy="false">)</mo><mo>−</mo><mn>1</mn><mo>⋅</mo><mo stretchy="false">(</mo><mo>−</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mo stretchy="false">)</mo></mrow><mrow><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mfrac><mspace linebreak="newline"></mspace><mtext>化简：</mtext><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mrow><mo stretchy="false">(</mo><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><msup><mo stretchy="false">)</mo><mn>2</mn></msup></mrow></mfrac><mspace linebreak="newline"></mspace><mtext>与原函数联系</mtext><mo separator="true">,</mo><mtext>两边都</mtext><mn>1</mn><mtext>减：</mtext><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac><mspace linebreak="newline"></mspace><mn>1</mn><mo>−</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac><mo>−</mo><mfrac><mn>1</mn><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac><mo separator="true">,</mo><mspace width="1em"/><mn>1</mn><mo>−</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mfrac><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup><mrow><mn>1</mn><mo>+</mo><msup><mi>e</mi><mrow><mo>−</mo><mi>x</mi></mrow></msup></mrow></mfrac><mspace linebreak="newline"></mspace><msup><mi>σ</mi><mo mathvariant="normal" lspace="0em" rspace="0em">′</mo></msup><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>=</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo>⋅</mo><mo stretchy="false">(</mo><mn>1</mn><mo>−</mo><mi>σ</mi><mo stretchy="false">(</mo><mi>x</mi><mo stretchy="false">)</mo><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">\sigma(x) = \frac{1}{1 + e^{-x}} \\\\上（分子）：f(x) = 1; f&#x27;(x) = 0;\\下（分母）：g(x) = 1 + e^{-x}就是对e^{-x}采用链式法则求导 \\\\外层函数：f(u) = e^u ,f&#x27;(u) = e^u ;  内层函数：u(x) = -x ,u&#x27;(x) = -1\\链式法则公式：\frac{d}{dx} f(u(x)) = f&#x27;(u(x)) \cdot u&#x27;(x)\\\frac{d}{dx} e^{-x}求导过程【外层先导，把u是-x带入，再乘内层导数】结果：  e^{-x} \cdot (-1)\\g&#x27;(x) = \frac{d}{dx}(1 + e^{-x}) = -e^{-x}\\然后使用商法则来求导,(上导*下 − 上*下导) / 下²,\sigma&#x27;(x) = \frac{f&#x27;(x)\cdot g(x) - f(x)\cdot g&#x27;(x)}{[g(x)]^2}\\\sigma&#x27;(x) = \frac{0 \cdot (1+e^{-x}) - 1 \cdot (-e^{-x})}{(1+e^{-x})^2}\\化简：\sigma&#x27;(x) = \frac{e^{-x}}{(1 + e^{-x})^2}\\与原函数联系,两边都1减：\sigma(x) = \frac{1}{1+e^{-x}}\\1 - \sigma(x) = \frac{1+e^{-x}}{1+e^{-x}} - \frac{1}{1+e^{-x}}, \quad 1-\sigma(x) = \frac{e^{-x}}{1+e^{-x}}\\\sigma&#x27;(x) = \sigma(x) \cdot (1 - \sigma(x))</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.09077em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">上</span><span class="mord cjk_fallback">（</span><span class="mord cjk_fallback">分</span><span class="mord cjk_fallback">子</span><span class="mord cjk_fallback">）</span><span class="mord cjk_fallback">：</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord">1</span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.8388800000000001em;vertical-align:-0.19444em;"></span><span class="mord">0</span><span class="mpunct">;</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">下</span><span class="mord cjk_fallback">（</span><span class="mord cjk_fallback">分</span><span class="mord cjk_fallback">母</span><span class="mord cjk_fallback">）</span><span class="mord cjk_fallback">：</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.821331em;vertical-align:0em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mord cjk_fallback">就</span><span class="mord cjk_fallback">是</span><span class="mord cjk_fallback">对</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mord cjk_fallback">采</span><span class="mord cjk_fallback">用</span><span class="mord cjk_fallback">链</span><span class="mord cjk_fallback">式</span><span class="mord cjk_fallback">法</span><span class="mord cjk_fallback">则</span><span class="mord cjk_fallback">求</span><span class="mord cjk_fallback">导</span></span><span class="mspace newline"></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">外</span><span class="mord cjk_fallback">层</span><span class="mord cjk_fallback">函</span><span class="mord cjk_fallback">数</span><span class="mord cjk_fallback">：</span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7143919999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">u</span></span></span></span></span></span></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.7143919999999999em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">u</span></span></span></span></span></span></span></span><span class="mpunct">;</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord cjk_fallback">内</span><span class="mord cjk_fallback">层</span><span class="mord cjk_fallback">函</span><span class="mord cjk_fallback">数</span><span class="mord cjk_fallback">：</span><span class="mord mathnormal">u</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord">−</span><span class="mord mathnormal">x</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord">1</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:2.05744em;vertical-align:-0.686em;"></span><span class="mord cjk_fallback">链</span><span class="mord cjk_fallback">式</span><span class="mord cjk_fallback">法</span><span class="mord cjk_fallback">则</span><span class="mord cjk_fallback">公</span><span class="mord cjk_fallback">式</span><span class="mord cjk_fallback">：</span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">u</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">u</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:2.05744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mord cjk_fallback">求</span><span class="mord cjk_fallback">导</span><span class="mord cjk_fallback">过</span><span class="mord cjk_fallback">程</span><span class="mord cjk_fallback">【</span><span class="mord cjk_fallback">外</span><span class="mord cjk_fallback">层</span><span class="mord cjk_fallback">先</span><span class="mord cjk_fallback">导</span><span class="mord cjk_fallback">，</span><span class="mord cjk_fallback">把</span><span class="mord mathnormal">u</span><span class="mord cjk_fallback">是</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.821331em;vertical-align:0em;"></span><span class="mord mathnormal">x</span><span class="mord cjk_fallback">带</span><span class="mord cjk_fallback">入</span><span class="mord cjk_fallback">，</span><span class="mord cjk_fallback">再</span><span class="mord cjk_fallback">乘</span><span class="mord cjk_fallback">内</span><span class="mord cjk_fallback">层</span><span class="mord cjk_fallback">导</span><span class="mord cjk_fallback">数</span><span class="mord cjk_fallback">】</span><span class="mord cjk_fallback">结</span><span class="mord cjk_fallback">果</span><span class="mord cjk_fallback">：</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord">1</span><span class="mclose">)</span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.05744em;vertical-align:-0.686em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.37144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span><span class="mord mathnormal">x</span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord mathnormal">d</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.686em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.071331em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:0.904661em;vertical-align:-0.08333em;"></span><span class="mord">−</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.821331em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">然</span><span class="mord cjk_fallback">后</span><span class="mord cjk_fallback">使</span><span class="mord cjk_fallback">用</span><span class="mord cjk_fallback">商</span><span class="mord cjk_fallback">法</span><span class="mord cjk_fallback">则</span><span class="mord cjk_fallback">来</span><span class="mord cjk_fallback">求</span><span class="mord cjk_fallback">导</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mopen">(</span><span class="mord cjk_fallback">上</span><span class="mord cjk_fallback">导</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.76666em;vertical-align:-0.08333em;"></span><span class="mord cjk_fallback">下</span><span class="mord">−</span><span class="mord cjk_fallback">上</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">∗</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">下</span><span class="mord cjk_fallback">导</span><span class="mclose">)</span><span class="mord">/</span><span class="mord cjk_fallback">下</span><span class="mord">²</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.364892em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.428892em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose"><span class="mclose">]</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.751892em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.384331em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.448331em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">0</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mopen">(</span><span class="mord">−</span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose">)</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">化</span><span class="mord cjk_fallback">简</span><span class="mord cjk_fallback">：</span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.384331em;vertical-align:-0.936em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.448331em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span><span class="mclose"><span class="mclose">)</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.740108em;"><span style="top:-2.9890000000000003em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.936em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord cjk_fallback">与</span><span class="mord cjk_fallback">原</span><span class="mord cjk_fallback">函</span><span class="mord cjk_fallback">数</span><span class="mord cjk_fallback">联</span><span class="mord cjk_fallback">系</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord cjk_fallback">两</span><span class="mord cjk_fallback">边</span><span class="mord cjk_fallback">都</span><span class="mord">1</span><span class="mord cjk_fallback">减</span><span class="mord cjk_fallback">：</span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.09077em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:0.72777em;vertical-align:-0.08333em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.217661em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.448331em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:2.09077em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.32144em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span><span class="mpunct">,</span><span class="mspace" style="margin-right:1em;"></span><span class="mspace" style="margin-right:0.16666666666666666em;"></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:2.217661em;vertical-align:-0.7693300000000001em;"></span><span class="mord"><span class="mopen nulldelimiter"></span><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height:1.448331em;"><span style="top:-2.314em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.697331em;"><span style="top:-2.989em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span><span style="top:-3.23em;"><span class="pstrut" style="height:3em;"></span><span class="frac-line" style="border-bottom-width:0.04em;"></span></span><span style="top:-3.677em;"><span class="pstrut" style="height:3em;"></span><span class="mord"><span class="mord"><span class="mord mathnormal">e</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.771331em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">−</span><span class="mord mathnormal mtight">x</span></span></span></span></span></span></span></span></span></span></span></span><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist" style="height:0.7693300000000001em;"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mspace newline"></span><span class="base"><span class="strut" style="height:1.051892em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.801892em;"><span style="top:-3.113em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">′</span></span></span></span></span></span></span></span></span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">⋅</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord">1</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">σ</span><span class="mopen">(</span><span class="mord mathnormal">x</span><span class="mclose">)</span><span class="mclose">)</span></span></span></span></span></p></li></ul><h2 id="其他技巧"><a class="markdownIt-Anchor" href="#其他技巧"></a> 其他技巧</h2><h3 id="表情符号"><a class="markdownIt-Anchor" href="#表情符号"></a> 表情符号</h3><p>使用 <code>:表情关键词:</code> 插入表情：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:smile:  :rocket:  :heart:</span><br></pre></td></tr></table></figure><p>😄 🚀 ❤️</p><h3 id="生成目录"><a class="markdownIt-Anchor" href="#生成目录"></a> 生成目录</h3><p>在文档任意位置输入 <code>[TOC]</code>，Typora 会自动生成标题目录：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[TOC]</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">人生自古谁无死，留取丹心照汗青</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Doc" scheme="https://luckynwa.top/tags/Doc/"/>
    
  </entry>
  
  <entry>
    <title>ECharts在Vue项目中的配置与实践</title>
    <link href="https://luckynwa.top/posts/front2/"/>
    <id>https://luckynwa.top/posts/front2/</id>
    <published>2025-04-07T22:59:18.000Z</published>
    <updated>2026-07-07T16:19:33.920Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>本章节将记录 echarts 在项目中的常见配置，以便提高开发速度。</p><p>echarts 4.x（以下简称 <code>v4</code>）升级到 echarts 5.x（以下简称 <code>v5</code>），<code>v5</code> 仍然带来了一些非兼容改动，需要特别关注，<code>v5</code> 不再支持 IE8 浏览器，过渡动画的增强。</p><p><a href="https://echarts.apache.org/zh/option.html#xAxis.id'">官网配置项点我跳转</a></p><h2 id="创建一个-vue-应用"><a class="markdownIt-Anchor" href="#创建一个-vue-应用"></a> 创建一个 Vue 应用</h2><p>在 HTML 中定义一个 <code>&lt;div&gt;</code> 节点，并且通过 CSS 使得该节点具有宽度和高度。初始化图表的时候，传入该节点，图表的大小默认即为该节点的大小。</p><p>环境：Node16 和 Node18 (nvm 来管理)</p><p>开发工具: VSCode</p><p>代码: 直接从本人的 Github 上拉取<br />Vue3 模板</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone -b test https://github.com/luckyNwa6/luckyVue3Template.git</span><br></pre></td></tr></table></figure><p>Vue2 模板</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone -b test https://github.com/luckyNwa6/luckyVue2Template.git</span><br></pre></td></tr></table></figure><h2 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h2><p>vue2模板</p><figure class="highlight shell"><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">yarn   安装全部依赖</span><br><span class="line">yarn remove  echarts</span><br></pre></td></tr></table></figure><p>vue3模板</p><figure class="highlight shell"><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">pnpm i</span><br><span class="line">pnpm uninstall echarts</span><br></pre></td></tr></table></figure><p>可选版本</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm install echarts --save</span><br><span class="line">yarn add echarts</span><br><span class="line">pnpm install echarts@4.9.0 --save</span><br></pre></td></tr></table></figure><h2 id="引用-echarts"><a class="markdownIt-Anchor" href="#引用-echarts"></a> 引用 ECharts</h2><p>如果使用者在 <code>v4</code> 中这样引用了 echarts：</p><figure class="highlight js"><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="keyword">import</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts&#x27;</span></span><br><span class="line"><span class="comment">// 或者按需引入</span></span><br><span class="line"><span class="keyword">import</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts/lib/echarts&#x27;</span></span><br></pre></td></tr></table></figure><p>这两种方式，<code>v5</code> 中不再支持了。</p><p>使用者需要如下更改代码解决这个问题</p><figure class="highlight js"><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="keyword">import</span> * <span class="keyword">as</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts&#x27;</span></span><br><span class="line"><span class="comment">// 按需引入</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts/lib/echarts&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="简单图表案例"><a class="markdownIt-Anchor" href="#简单图表案例"></a> 简单图表案例</h2><p>本章节将实现一个简单的图表案例，并解析其中的具体配置</p><h3 id="demo"><a class="markdownIt-Anchor" href="#demo"></a> Demo</h3><p>选项式</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</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">id</span>=<span class="string">&quot;lucky&quot;</span> <span class="attr">style</span>=<span class="string">&quot;width: 600px; height: 600px&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">myChart</span>: <span class="literal">null</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">dataX</span>: [<span class="string">&#x27;衬衫&#x27;</span>, <span class="string">&#x27;羊毛衫&#x27;</span>, <span class="string">&#x27;雪纺衫&#x27;</span>, <span class="string">&#x27;裤子&#x27;</span>, <span class="string">&#x27;高跟鞋&#x27;</span>, <span class="string">&#x27;袜子&#x27;</span>], <span class="comment">//x轴的数据</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">seriesValue</span>: [<span class="number">5</span>, <span class="number">20</span>, <span class="number">36</span>, <span class="number">10</span>, <span class="number">10</span>, <span class="number">20</span>], <span class="comment">//X轴对应的数据</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">mounted</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">this</span>.<span class="title function_">initChart</span>()</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">initChart</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">myChart</span> = echarts.<span class="title function_">init</span>(<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;lucky&#x27;</span>)) <span class="comment">// 基于准备好的dom要有宽度，初始化echarts实例</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">// 指定图表的配置项和数据，不管折线图、柱状图、饼图等都需要配置，后续抽离封装</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">var</span> option = &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">title</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="attr">text</span>: <span class="string">&#x27;ECharts 入门示例&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">tooltip</span>: &#123;&#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">legend</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="attr">data</span>: [<span class="string">&#x27;销量&#x27;</span>],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">xAxis</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="attr">data</span>: <span class="variable language_">this</span>.<span class="property">dataX</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">yAxis</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">series</span>: [</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="attr">name</span>: <span class="string">&#x27;销量&#x27;</span>, <span class="comment">//数据中对应的名称</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>, <span class="comment">//柱状图</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="attr">data</span>: <span class="variable language_">this</span>.<span class="property">seriesValue</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        ],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">// 使用刚指定的配置项和数据显示图表，后续有点击事件</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">myChart</span>.<span class="title function_">setOption</span>(option)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure><p>组合式</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> chart = <span class="title function_">ref</span>(<span class="literal">null</span>)</span><br><span class="line"><span class="keyword">const</span> chartId = <span class="string">&#x27;productType&#x27;</span> + <span class="title class_">Math</span>.<span class="title function_">round</span>(<span class="title class_">Math</span>.<span class="title function_">random</span>() * <span class="number">10000</span>)</span><br><span class="line"></span><br><span class="line">chart.<span class="property">value</span> = echarts.<span class="title function_">init</span>(<span class="variable language_">document</span>.<span class="title function_">getElementById</span>(chartId))</span><br><span class="line"></span><br><span class="line">chart.<span class="property">value</span>.<span class="title function_">setOption</span>(option, <span class="literal">true</span>)</span><br></pre></td></tr></table></figure><h2 id="组件封装"><a class="markdownIt-Anchor" href="#组件封装"></a> 组件封装</h2><p>封装可以考虑多种的情况，是否是全局都有、还是一个模块下面有，可以封装一个vue组件、传入配置项来显示需要的图表，或者抽离配置项单独去定制。</p><h3 id="简单封装"><a class="markdownIt-Anchor" href="#简单封装"></a> 简单封装</h3><p>场景是某个模块下需要 液位/流量、水质等配置图表，参数如下：</p><ul><li>悬浮框 --&gt; 定制里面的属性展示（如果不抽离需要传更多的值）</li><li>图表缩放 --&gt; 可以不用，直接在这写死，默认图表都是需要这个的</li><li>水平数据 --&gt; X轴的label展示</li><li>纵轴数据 --&gt; X轴值对应的Y轴数据</li><li>图表实例</li><li>另个垂直数据</li></ul><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 液位/流量的配置项--------------------------------------------------------------------------------</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">liquidFlowOpt</span> = (<span class="params">tooltip, dataZoom, curveHorizontal, liquidVerticalData, echarts, flowVerticalData</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">grid</span>: &#123;</span><br><span class="line">      <span class="attr">left</span>: <span class="string">&#x27;7%&#x27;</span>, <span class="comment">//图表距离左边</span></span><br><span class="line">      <span class="attr">right</span>: <span class="string">&#x27;6%&#x27;</span>,</span><br><span class="line">      <span class="attr">containLabel</span>: <span class="literal">true</span>, <span class="comment">//grid 区域是否包含坐标轴的刻度标签</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">legend</span>: [</span><br><span class="line">      <span class="comment">//图例组件展现了不同系列的标记(symbol)，颜色和名字。可以通过点击图例控制哪些系列不显示。</span></span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">data</span>: [</span><br><span class="line">          &#123;</span><br><span class="line">            <span class="attr">name</span>: <span class="string">&#x27;液位&#x27;</span>,</span><br><span class="line">            <span class="attr">icon</span>: <span class="string">&#x27;rect&#x27;</span>, <span class="comment">//长方形的</span></span><br><span class="line">          &#125;,</span><br><span class="line">        ],</span><br><span class="line">        <span class="attr">itemWidth</span>: <span class="number">11</span>, <span class="comment">//宽</span></span><br><span class="line">        <span class="attr">itemHeight</span>: <span class="number">2</span>, <span class="comment">//高</span></span><br><span class="line">        <span class="attr">top</span>: <span class="string">&#x27;4%&#x27;</span>, <span class="comment">//距离上方</span></span><br><span class="line">        <span class="attr">left</span>: <span class="string">&#x27;45%&#x27;</span>, <span class="comment">//距离左</span></span><br><span class="line">        <span class="attr">textStyle</span>: &#123;</span><br><span class="line">          <span class="comment">//文字样式</span></span><br><span class="line">          <span class="attr">color</span>: <span class="string">&#x27;#2C3542 &#x27;</span>,</span><br><span class="line">          <span class="comment">// fontWeight: &quot;normal&quot;,</span></span><br><span class="line">          <span class="attr">fontSize</span>: <span class="number">12</span>,</span><br><span class="line">          <span class="attr">fontFamily</span>: <span class="string">&#x27;PingFang SC Arial, Helvetica, sans-serif&#x27;</span>, <span class="comment">// 设置字体类型为 Arial、Helvetica 或 sans-serif 中的一种</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">data</span>: [</span><br><span class="line">          &#123;</span><br><span class="line">            <span class="attr">name</span>: <span class="string">&#x27;流量&#x27;</span>,</span><br><span class="line">            <span class="attr">icon</span>: <span class="string">&#x27;rect&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        ],</span><br><span class="line">        <span class="attr">itemWidth</span>: <span class="number">11</span>,</span><br><span class="line">        <span class="attr">itemHeight</span>: <span class="number">2</span>,</span><br><span class="line">        <span class="attr">top</span>: <span class="string">&#x27;4%&#x27;</span>,</span><br><span class="line">        <span class="attr">left</span>: <span class="string">&#x27;55%&#x27;</span>,</span><br><span class="line">        <span class="attr">textStyle</span>: &#123;</span><br><span class="line">          <span class="attr">color</span>: <span class="string">&#x27;#2C3542 &#x27;</span>,</span><br><span class="line">          <span class="comment">// fontWeight: &quot;normal&quot;,</span></span><br><span class="line">          <span class="attr">fontSize</span>: <span class="number">12</span>,</span><br><span class="line">          <span class="attr">fontFamily</span>: <span class="string">&#x27;PingFang SC Arial, Helvetica, sans-serif&#x27;</span>, <span class="comment">// 设置字体类型为 Arial、Helvetica 或 sans-serif 中的一种</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">    <span class="attr">tooltip</span>: tooltip, <span class="comment">//悬浮提示</span></span><br><span class="line">    <span class="attr">dataZoom</span>: dataZoom, <span class="comment">//缩放</span></span><br><span class="line">    <span class="comment">//x轴</span></span><br><span class="line">    <span class="attr">xAxis</span>: &#123;</span><br><span class="line">      <span class="attr">data</span>: curveHorizontal,</span><br><span class="line">      <span class="attr">boundaryGap</span>: <span class="literal">false</span>,</span><br><span class="line">      <span class="attr">axisLine</span>: &#123;</span><br><span class="line">        <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">          <span class="comment">// 设置x轴颜色</span></span><br><span class="line">          <span class="attr">color</span>: <span class="string">&#x27;#FFFFFF&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisLabel</span>: &#123;</span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#999999 &#x27;</span>, <span class="comment">//坐标轴的文本颜色</span></span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">//y轴没有显式设置，根据值自动生成y轴</span></span><br><span class="line">    <span class="attr">yAxis</span>: [</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;指标：液位(m)&#x27;</span>,</span><br><span class="line">        <span class="attr">nameGap</span>: <span class="number">25</span>, <span class="comment">// 设置纵轴名称距离轴线的距离为 25 像素</span></span><br><span class="line">        <span class="attr">min</span>: <span class="keyword">function</span> (<span class="params">v</span>) &#123;</span><br><span class="line">          <span class="comment">//如果没数据时候默认展示的纵轴</span></span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(v)</span><br><span class="line">          <span class="keyword">if</span> (v.<span class="property">min</span> == <span class="title class_">Infinity</span>) &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">22222</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">return</span> v.<span class="property">min</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="comment">// offset: -30,</span></span><br><span class="line">        <span class="attr">max</span>: <span class="keyword">function</span> (<span class="params">v</span>) &#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(v)</span><br><span class="line">          <span class="keyword">if</span> (v.<span class="property">max</span> == -<span class="title class_">Infinity</span>) &#123;</span><br><span class="line">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="number">1111</span>)</span><br><span class="line">            <span class="keyword">return</span> <span class="number">1.5</span></span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">return</span> v.<span class="property">max</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span>,</span><br><span class="line">        <span class="attr">position</span>: <span class="string">&#x27;left&#x27;</span>,</span><br><span class="line">        <span class="attr">axisTick</span>: &#123;</span><br><span class="line">          <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">//坐标轴刻度|隐藏</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="comment">// alignTicks: true,  //开启该配置项自动对齐刻度,刻度都隐藏了就没有必要了</span></span><br><span class="line">        <span class="attr">axisLine</span>: &#123;</span><br><span class="line">          <span class="comment">//纵轴文字,就是0 3 6 9 12 14</span></span><br><span class="line">          <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">          <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">            <span class="attr">color</span>: <span class="string">&#x27;#999999&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">splitLine</span>: &#123;</span><br><span class="line">          <span class="attr">show</span>: <span class="literal">true</span>, <span class="comment">//隐藏纵轴的横线</span></span><br><span class="line">          <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">            <span class="attr">color</span>: <span class="string">&#x27;#DCDFE6 &#x27;</span>,</span><br><span class="line">            <span class="attr">type</span>: <span class="string">&#x27;dashed&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">axisLabel</span>: &#123;</span><br><span class="line">          <span class="attr">formatter</span>: <span class="string">&#x27;&#123;value&#125; &#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;指标：流量(m³/s)&#x27;</span>,</span><br><span class="line">        <span class="attr">nameGap</span>: <span class="number">25</span>, <span class="comment">// 设置纵轴名称距离轴线的距离为 25 像素</span></span><br><span class="line">        <span class="attr">min</span>: <span class="keyword">function</span> (<span class="params">v</span>) &#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(v)</span><br><span class="line">          <span class="keyword">if</span> (v.<span class="property">min</span> == <span class="title class_">Infinity</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">return</span> v.<span class="property">min</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">max</span>: <span class="keyword">function</span> (<span class="params">v</span>) &#123;</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(v)</span><br><span class="line">          <span class="keyword">if</span> (v.<span class="property">max</span> == -<span class="title class_">Infinity</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">100</span></span><br><span class="line">          &#125;</span><br><span class="line">          <span class="keyword">return</span> v.<span class="property">max</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="comment">// interval: 3,</span></span><br><span class="line">        <span class="attr">axisTick</span>: &#123;</span><br><span class="line">          <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 设置 axisTick 的 show 属性为 false</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span>,</span><br><span class="line">        <span class="attr">position</span>: <span class="string">&#x27;right&#x27;</span>,</span><br><span class="line">        <span class="comment">// alignTicks: true,</span></span><br><span class="line">        <span class="attr">splitLine</span>: &#123;</span><br><span class="line">          <span class="attr">show</span>: <span class="literal">true</span>, <span class="comment">//隐藏纵轴的横线</span></span><br><span class="line">          <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">            <span class="attr">color</span>: <span class="string">&#x27;#DCDFE6&#x27;</span>,</span><br><span class="line">            <span class="attr">type</span>: <span class="string">&#x27;dashed&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">axisLine</span>: &#123;</span><br><span class="line">          <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">          <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">            <span class="attr">color</span>: <span class="string">&#x27;#999999&#x27;</span>,</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">axisLabel</span>: &#123;</span><br><span class="line">          <span class="attr">formatter</span>: <span class="string">&#x27;&#123;value&#125; &#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line"></span><br><span class="line">    <span class="comment">//数据-data是最终要显示的数据</span></span><br><span class="line">    <span class="attr">series</span>: [</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;液位&#x27;</span>,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>,</span><br><span class="line">        <span class="attr">symbol</span>: <span class="string">&#x27;circle&#x27;</span>, <span class="comment">// 默认是空心圆（中间是白色的），改成实心圆</span></span><br><span class="line">        <span class="attr">smooth</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#1d72f1&#x27;</span>,</span><br><span class="line">        <span class="attr">areaStyle</span>: &#123;</span><br><span class="line">          <span class="attr">normal</span>: &#123;</span><br><span class="line">            <span class="comment">//线性渐变，前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是&#x27;true&#x27;，则该四个值是绝对像素位置。</span></span><br><span class="line">            <span class="attr">color</span>: <span class="keyword">new</span> echarts.<span class="property">graphic</span>.<span class="title class_">LinearGradient</span>(</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">1</span>,</span><br><span class="line">              [</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">0</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#e5f5fe&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">0.6</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#e0f4fe&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">1</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#dcf3fe&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">              ],</span><br><span class="line">              <span class="literal">false</span>,</span><br><span class="line">            ),</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">data</span>: liquidVerticalData,</span><br><span class="line">        <span class="attr">showSymbol</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">symbolSize</span>: <span class="number">6</span>,</span><br><span class="line">        <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">          <span class="attr">width</span>: <span class="number">3</span>, <span class="comment">// 设置线的粗细，这里设置为 3</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">name</span>: <span class="string">&#x27;流量&#x27;</span>,</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>,</span><br><span class="line">        <span class="attr">symbol</span>: <span class="string">&#x27;circle&#x27;</span>, <span class="comment">// 默认是空心圆（中间是白色的），改成实心圆</span></span><br><span class="line">        <span class="attr">smooth</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">yAxisIndex</span>: <span class="number">1</span>,</span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#00dbd5&#x27;</span>,</span><br><span class="line">        <span class="attr">areaStyle</span>: &#123;</span><br><span class="line">          <span class="attr">normal</span>: &#123;</span><br><span class="line">            <span class="comment">//线性渐变，前4个参数分别是x0,y0,x2,y2(范围0~1);相当于图形包围盒中的百分比。如果最后一个参数是&#x27;true&#x27;，则该四个值是绝对像素位置。</span></span><br><span class="line">            <span class="attr">color</span>: <span class="keyword">new</span> echarts.<span class="property">graphic</span>.<span class="title class_">LinearGradient</span>(</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">0</span>,</span><br><span class="line">              <span class="number">1</span>,</span><br><span class="line">              [</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">0</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#fcfefe&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">0.6</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#d6f4fa&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">                &#123;</span><br><span class="line">                  <span class="attr">offset</span>: <span class="number">1</span>,</span><br><span class="line">                  <span class="attr">color</span>: <span class="string">&#x27;#ccf7f6&#x27;</span>,</span><br><span class="line">                &#125;,</span><br><span class="line">              ],</span><br><span class="line">              <span class="literal">false</span>,</span><br><span class="line">            ),</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">data</span>: flowVerticalData,</span><br><span class="line">        <span class="comment">// showSymbol: flowVerticalData.length == 1 ? true : false,</span></span><br><span class="line">        <span class="attr">showSymbol</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">symbolSize</span>: <span class="number">6</span>,</span><br><span class="line">        <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">          <span class="attr">width</span>: <span class="number">3</span>, <span class="comment">// 设置线的粗细，这里设置为 3</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>调用</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> that = <span class="variable language_">this</span></span><br><span class="line"><span class="keyword">let</span> dataZoom = <span class="title function_">deepClone</span>(<span class="variable language_">this</span>.<span class="property">echartOptions</span>.<span class="property">dataZoom</span>)</span><br><span class="line"><span class="comment">//Todo 液位/流量图表的Tooltip 有时间可以再封装</span></span><br><span class="line"><span class="keyword">let</span> liquidFlowTooltip = &#123;</span><br><span class="line">  <span class="attr">trigger</span>: <span class="string">&#x27;axis&#x27;</span>,</span><br><span class="line">  <span class="attr">backgroundColor</span>: <span class="string">&#x27;rgba(0, 0, 0, 0.75)&#x27;</span>,</span><br><span class="line">  <span class="attr">confine</span>: <span class="literal">true</span>,</span><br><span class="line">  <span class="attr">formatter</span>: <span class="keyword">function</span> (<span class="params">params</span>) &#123;</span><br><span class="line">    <span class="comment">// console.log(params);</span></span><br><span class="line">    <span class="keyword">var</span> relVal = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">var</span> time = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">let</span> qId = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>, l = params.<span class="property">length</span>; i &lt; l; i++) &#123;</span><br><span class="line">      <span class="keyword">if</span> (i === <span class="number">0</span>) &#123;</span><br><span class="line">        relVal +=</span><br><span class="line">          <span class="string">&#x27;&lt;span style=&quot;display:inline-block;margin-right:5px;width:1px;&quot;&gt;&lt;/span&gt;&#x27;</span> + that.<span class="property">chartShowTime</span>[params[i].<span class="property">dataIndex</span>] + <span class="string">&#x27;&lt;br/&gt;&#x27;</span></span><br><span class="line">        time = that.<span class="property">curveDateTime</span>[params[i].<span class="property">dataIndex</span>]</span><br><span class="line">        qId = that.<span class="property">curveIdList</span>[params[i].<span class="property">dataIndex</span>]</span><br><span class="line">      &#125;</span><br><span class="line">      relVal +=</span><br><span class="line">        <span class="string">&#x27;&lt;span style=&quot;display:inline-block;padding-bottom:20px;width:1px;&quot;&gt;&lt;/span&gt; &lt;span style=&quot;display:inline-block;margin-right:5px;margin-bottom:4px;border-radius:10px;width:13px;height:3px;background-color:&#x27;</span> +</span><br><span class="line">        params[i].<span class="property">color</span> +</span><br><span class="line">        <span class="string">&#x27;&quot;&gt;&lt;/span&gt;&#x27;</span> +</span><br><span class="line">        params[i].<span class="property">seriesName</span> +</span><br><span class="line">        <span class="string">&#x27;：&#x27;</span> +</span><br><span class="line">        (params[i].<span class="property">value</span> || <span class="string">&#x27;-&#x27;</span>) +</span><br><span class="line">        <span class="title function_">getUnit</span>(params[i].<span class="property">seriesName</span>, params[i].<span class="property">value</span>) +</span><br><span class="line">        <span class="string">&#x27;&lt;br/&gt;&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">    that.<span class="property">queryTime</span> = time</span><br><span class="line">    that.<span class="property">queryID</span> = qId</span><br><span class="line">    <span class="keyword">return</span> relVal</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// 添加以下样式</span></span><br><span class="line">  <span class="attr">textStyle</span>: &#123;</span><br><span class="line">    <span class="attr">fontSize</span>: <span class="number">14</span>,</span><br><span class="line">    <span class="attr">color</span>: <span class="string">&#x27;#FFFFFF &#x27;</span>,</span><br><span class="line">    <span class="attr">margin</span>: <span class="number">20</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">extraCssText</span>: <span class="string">&#x27;max-width: 300px; padding: 12px;&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> option1 = <span class="title function_">liquidFlowOpt</span>(</span><br><span class="line">  liquidFlowTooltip,</span><br><span class="line">  dataZoom,</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">curveHorizontal</span>,</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">liquidVerticalData</span>,</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">$echarts</span>,</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">flowVerticalData</span>,</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">//初始化ehcharts实例</span></span><br><span class="line"><span class="keyword">let</span> charts = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;line_charts&#x27;</span>)</span><br><span class="line"><span class="variable language_">this</span>.<span class="property">myChart</span> = <span class="variable language_">this</span>.<span class="property">$echarts</span>.<span class="title function_">init</span>(charts) <span class="comment">//这是全局注册了</span></span><br><span class="line"><span class="variable language_">this</span>.<span class="property">myChart</span>.<span class="title function_">setOption</span>(option1)</span><br></pre></td></tr></table></figure><h3 id="组件抽离"><a class="markdownIt-Anchor" href="#组件抽离"></a> 组件抽离</h3><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><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></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;div ref=&quot;chart&quot; /&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script&gt;</span><br><span class="line">export default &#123;</span><br><span class="line">  name: &#x27;EChartsChart&#x27;,</span><br><span class="line">  props: &#123;</span><br><span class="line">    option: &#123;</span><br><span class="line">      type: Object,</span><br><span class="line">      required: true,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  mounted() &#123;</span><br><span class="line">    this.initChart()</span><br><span class="line">  &#125;,</span><br><span class="line">  beforeDestroy() &#123;</span><br><span class="line">    // 在组件销毁前销毁图表实例，释放资源</span><br><span class="line">    if (this.chart) &#123;</span><br><span class="line">      this.chart.dispose()</span><br><span class="line">      this.chart = null</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  methods: &#123;</span><br><span class="line">    initChart() &#123;</span><br><span class="line">      // 在mounted钩子函数中初始化图表</span><br><span class="line">      this.chart = this.$echarts.init(this.$refs.chart)</span><br><span class="line">      this.chart.setOption(this.option)</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure><p>配置项抽离，应该要类似简单封装那配置项用方法导出，更智能</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> option7 = &#123;</span><br><span class="line">  <span class="attr">color</span>: [</span><br><span class="line">    <span class="string">&#x27;#ff2600&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#ffc000&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#00ad4e&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#0073c2&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#165868&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#e76f00&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#316194&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#723761&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#00b2f1&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#4d6022&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#4b83bf&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#f9c813&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;#0176c0&#x27;</span>,</span><br><span class="line">  ], <span class="comment">// 柱状图颜色列表</span></span><br><span class="line">  <span class="attr">tooltip</span>: &#123;</span><br><span class="line">    <span class="comment">// 鼠标悬浮时的提示框配置</span></span><br><span class="line">    <span class="attr">trigger</span>: <span class="string">&#x27;axis&#x27;</span>, <span class="comment">// 触发类型为坐标轴</span></span><br><span class="line">    <span class="attr">transitionDuration</span>: <span class="number">0</span>, <span class="comment">// 提示框动画过渡时间</span></span><br><span class="line">    <span class="attr">formatter</span>: <span class="keyword">function</span> (<span class="params">params, ticket, callback</span>) &#123;</span><br><span class="line">      <span class="comment">// 提示框内容格式化函数</span></span><br><span class="line">      <span class="keyword">var</span> res = <span class="string">&#x27;&#x27;</span></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>, l = params.<span class="property">length</span>; i &lt; l; i++) &#123;</span><br><span class="line">        res += <span class="string">&#x27;&#x27;</span> + params[i].<span class="property">seriesName</span> + <span class="string">&#x27; : &#x27;</span> + params[i].<span class="property">value</span> + <span class="string">&#x27;&lt;br&gt;&#x27;</span> <span class="comment">// 拼接系列名称和对应的数值</span></span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> res</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">axisPointer</span>: &#123;</span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>,</span><br><span class="line">      <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="string">&#x27;dashed&#x27;</span>,</span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#ffff00&#x27;</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">toolbox</span>: &#123;</span><br><span class="line">    <span class="attr">show</span>: <span class="literal">true</span>, <span class="comment">// 显示工具栏</span></span><br><span class="line">    <span class="attr">feature</span>: &#123;</span><br><span class="line">      <span class="attr">mark</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">true</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">grid</span>: &#123;</span><br><span class="line">    <span class="attr">borderWidth</span>: <span class="number">0</span>, <span class="comment">// 网格边框宽度</span></span><br><span class="line">    <span class="attr">top</span>: <span class="string">&#x27;40&#x27;</span>, <span class="comment">// 上边距</span></span><br><span class="line">    <span class="attr">left</span>: <span class="string">&#x27;30&#x27;</span>, <span class="comment">// 左边距</span></span><br><span class="line">    <span class="attr">right</span>: <span class="string">&#x27;10&#x27;</span>, <span class="comment">// 右边距</span></span><br><span class="line">    <span class="attr">bottom</span>: <span class="string">&#x27;40&#x27;</span>, <span class="comment">// 下边距</span></span><br><span class="line"></span><br><span class="line">    <span class="attr">color</span>: <span class="string">&#x27;#fff&#x27;</span>, <span class="comment">// 文字颜色</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">xAxis</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;category&#x27;</span>, <span class="comment">// 类目轴</span></span><br><span class="line">      <span class="attr">axisTick</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 不显示刻度线</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisLine</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 不显示轴线</span></span><br><span class="line">        <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">          <span class="attr">color</span>: <span class="string">&#x27;#868c96&#x27;</span>, <span class="comment">// 轴线颜色</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisLabel</span>: &#123;</span><br><span class="line">        <span class="attr">interval</span>: <span class="number">0</span>, <span class="comment">// 强制显示所有类目</span></span><br><span class="line">        <span class="attr">fontSize</span>: <span class="number">14</span>, <span class="comment">// 字体大小</span></span><br><span class="line">        <span class="attr">formatter</span>: <span class="keyword">function</span> (<span class="params">value</span>) &#123;</span><br><span class="line">          <span class="keyword">var</span> ret = <span class="string">&#x27;&#x27;</span> <span class="comment">// 拼接加\n返回的类目项</span></span><br><span class="line">          <span class="keyword">var</span> maxLength = <span class="number">2</span> <span class="comment">// 每项显示文字个数</span></span><br><span class="line">          <span class="keyword">var</span> valLength = value.<span class="property">length</span> <span class="comment">// X轴类目项的文字个数</span></span><br><span class="line">          <span class="keyword">var</span> rowN = <span class="title class_">Math</span>.<span class="title function_">ceil</span>(valLength / maxLength) <span class="comment">// 类目项需要换行的行数</span></span><br><span class="line">          <span class="keyword">if</span> (rowN &gt; <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="comment">// 如果类目项的文字大于3,</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; rowN; i++) &#123;</span><br><span class="line">              <span class="keyword">var</span> temp = <span class="string">&#x27;&#x27;</span> <span class="comment">// 每次截取的字符串</span></span><br><span class="line">              <span class="keyword">var</span> start = i * maxLength <span class="comment">// 开始截取的位置</span></span><br><span class="line">              <span class="keyword">var</span> end = start + maxLength <span class="comment">// 结束截取的位置</span></span><br><span class="line">              <span class="comment">// 这里也可以加一个是否是最后一行的判断，但是不加也没有影响，那就不加吧</span></span><br><span class="line">              temp = value.<span class="title function_">substring</span>(start, end) + <span class="string">&#x27;\n&#x27;</span></span><br><span class="line">              ret += temp <span class="comment">// 凭借最终的字符串</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">return</span> ret</span><br><span class="line">          &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">splitArea</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">data</span>: [<span class="string">&#x27;电力部门&#x27;</span>, <span class="string">&#x27;水利部门&#x27;</span>, <span class="string">&#x27;海外部门&#x27;</span>, <span class="string">&#x27;物联网&#x27;</span>, <span class="string">&#x27;消防部门&#x27;</span>, <span class="string">&#x27;平台研发&#x27;</span>, <span class="string">&#x27;其他&#x27;</span>], <span class="comment">// X轴数据</span></span><br><span class="line">      <span class="attr">splitLine</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">  <span class="attr">yAxis</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;value&#x27;</span>, <span class="comment">// 数值轴</span></span><br><span class="line">      <span class="attr">offset</span>: -<span class="number">14</span>, <span class="comment">// 偏移量</span></span><br><span class="line">      <span class="attr">splitLine</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 不显示分隔线</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisLine</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 不显示轴线</span></span><br><span class="line">        <span class="attr">lineStyle</span>: &#123;</span><br><span class="line">          <span class="attr">color</span>: <span class="string">&#x27;#868c96&#x27;</span>, <span class="comment">// 轴线颜色</span></span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisTick</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>, <span class="comment">// 不显示刻度线</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">axisLabel</span>: &#123;</span><br><span class="line">        <span class="attr">interval</span>: <span class="number">0</span>, <span class="comment">// 强制显示所有标签</span></span><br><span class="line">        <span class="attr">fontSize</span>: <span class="number">14</span>, <span class="comment">// 字体大小</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">splitArea</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">false</span>,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">  <span class="attr">series</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">name</span>: <span class="string">&#x27;共享次数&#x27;</span>, <span class="comment">// 系列名称</span></span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;bar&#x27;</span>, <span class="comment">// 柱状图</span></span><br><span class="line">      <span class="attr">data</span>: [<span class="number">2912</span>, <span class="number">3991</span>, <span class="number">4621</span>, <span class="number">3941</span>, <span class="number">3313</span>, <span class="number">6631</span>, <span class="number">5543</span>, <span class="number">4463</span>, <span class="number">6541</span>, <span class="number">3381</span>], <span class="comment">// 数据</span></span><br><span class="line">      <span class="attr">itemStyle</span>: &#123;</span><br><span class="line">        <span class="attr">color</span>: <span class="keyword">function</span> (<span class="params">params</span>) &#123;</span><br><span class="line">          <span class="comment">// 柱状图颜色</span></span><br><span class="line">          <span class="keyword">var</span> colorList = [</span><br><span class="line">            <span class="string">&#x27;#ff2600&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#ffc000&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#00ad4e&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#0073c2&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#165868&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#e76f00&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#316194&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#723761&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#00b2f1&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#4d6022&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#4b83bf&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#f9c813&#x27;</span>,</span><br><span class="line">            <span class="string">&#x27;#0176c0&#x27;</span>,</span><br><span class="line">          ]</span><br><span class="line">          <span class="keyword">return</span> colorList[params.<span class="property">dataIndex</span>]</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">barWidth</span>: <span class="number">14</span>, <span class="comment">// 柱状图宽度</span></span><br><span class="line">      <span class="attr">label</span>: &#123;</span><br><span class="line">        <span class="attr">show</span>: <span class="literal">true</span>, <span class="comment">// 显示标签</span></span><br><span class="line">        <span class="attr">position</span>: <span class="string">&#x27;top&#x27;</span>, <span class="comment">// 标签位置</span></span><br><span class="line"></span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#ffc72b&#x27;</span>, <span class="comment">// 标签文字颜色</span></span><br><span class="line">        <span class="attr">fontSize</span>: <span class="number">10</span>, <span class="comment">// 标签文字大小</span></span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">name</span>: <span class="string">&#x27;折线&#x27;</span>, <span class="comment">// 系列名称</span></span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;line&#x27;</span>, <span class="comment">// 折线图</span></span><br><span class="line">      <span class="attr">itemStyle</span>: &#123;</span><br><span class="line">        <span class="attr">color</span>: <span class="string">&#x27;#d3d5fd&#x27;</span>, <span class="comment">// 折线颜色</span></span><br><span class="line">      &#125;,</span><br><span class="line">      <span class="attr">data</span>: [<span class="number">2912</span>, <span class="number">3991</span>, <span class="number">4621</span>, <span class="number">3941</span>, <span class="number">3313</span>, <span class="number">6631</span>, <span class="number">5543</span>, <span class="number">4463</span>, <span class="number">6541</span>, <span class="number">3381</span>], <span class="comment">// 数据</span></span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>调用</p><figure class="highlight js"><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">&lt;<span class="title class_">EChartsChart</span> :option=<span class="string">&quot;option7&quot;</span> style=<span class="string">&quot;width: 100%; height: 300px&quot;</span> /&gt;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> &#123; option7 &#125; <span class="keyword">from</span> <span class="string">&#x27;@/components/echarts/option7.js&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">EChartsChart</span> <span class="keyword">from</span> <span class="string">&#x27;@/components/echarts/EChartsChart.vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">components</span>: &#123;<span class="title class_">EChartsChart</span> &#125;,<span class="comment">//data同级</span></span><br><span class="line"><span class="title function_">created</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="variable language_">this</span>.<span class="property">option7</span> = option7</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="图表自适应"><a class="markdownIt-Anchor" href="#图表自适应"></a> 图表自适应</h2><p>很多时候我们后台管理系统可以收缩，然后就导致了图表变形的情况，这个时候我们就需要给图表加入自适应功能。</p><h3 id="vue2自适应"><a class="markdownIt-Anchor" href="#vue2自适应"></a> Vue2自适应</h3><p>引入第三方库</p><figure class="highlight shell"><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">npm i resize-detector@0.3.0</span><br><span class="line">npm i lodash@4.17.21</span><br></pre></td></tr></table></figure><p>新增mixins-resize.js</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; addListener, removeListener &#125; <span class="keyword">from</span> <span class="string">&#x27;resize-detector&#x27;</span></span><br><span class="line"><span class="keyword">import</span> _ <span class="keyword">from</span> <span class="string">&#x27;lodash&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">  <span class="title function_">mounted</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; onResize &#125; = <span class="variable language_">this</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">__resizeHandler</span> = _.<span class="title function_">debounce</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> onResize === <span class="string">&#x27;function&#x27;</span>) <span class="title function_">onResize</span>()</span><br><span class="line">    &#125;, <span class="number">100</span>)</span><br><span class="line"></span><br><span class="line">    <span class="variable language_">this</span>.$nextTick(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">addListener</span>(<span class="variable language_">this</span>.<span class="property">$el</span>, <span class="variable language_">this</span>.<span class="property">__resizeHandler</span>)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="title function_">beforeDestroy</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="title function_">removeListener</span>(<span class="variable language_">this</span>.<span class="property">$el</span>, <span class="variable language_">this</span>.<span class="property">__resizeHandler</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在图表vue中使用</p><figure class="highlight js"><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">import</span> <span class="title class_">ResizeMixins</span> <span class="keyword">from</span> <span class="string">&#x27;@/views/common/mixins-resize.js&#x27;</span></span><br><span class="line"><span class="keyword">import</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts&#x27;</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">mixins</span>: [<span class="title class_">ResizeMixins</span>],<span class="comment">//混入和data同级</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="comment">//自适应分辨率</span></span><br><span class="line">    <span class="title function_">onResize</span>(<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">myChart</span> &amp;&amp; <span class="variable language_">this</span>.<span class="property">myChart</span>.<span class="title function_">resize</span>()   <span class="comment">//myChart图表实例，就是渲染dom-id</span></span><br><span class="line">      <span class="comment">// this.$refs.swiper1 &amp;&amp; this.$refs.swiper1.resize();</span></span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>详细可以查看Vue模板中的具体实现结果。</p><h3 id="vue3自适应"><a class="markdownIt-Anchor" href="#vue3自适应"></a> Vue3自适应</h3><p>组合式写法</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> echarts <span class="keyword">from</span> <span class="string">&#x27;echarts&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; useDebounceFn &#125; <span class="keyword">from</span> <span class="string">&#x27;@vueuse/core&#x27;</span> <span class="comment">//vue配置文件做了自动按需导入,这句可有可无</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 窗口自适应并开启过渡动画</span></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">resize</span> = (<span class="params"></span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">if</span> (chart.<span class="property">value</span>) &#123;</span><br><span class="line">    chart.<span class="property">value</span>.<span class="title function_">resize</span>(&#123; <span class="attr">animation</span>: &#123; <span class="attr">duration</span>: <span class="number">300</span> &#125; &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 自适应防抖优化</span></span><br><span class="line"><span class="keyword">const</span> debouncedResize = <span class="title function_">useDebounceFn</span>(resize, <span class="number">500</span>, &#123; <span class="attr">maxWait</span>: <span class="number">800</span> &#125;)</span><br><span class="line"></span><br><span class="line"><span class="title function_">onMounted</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="title function_">initData</span>()</span><br><span class="line">  <span class="title function_">nextTick</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">window</span>.<span class="title function_">addEventListener</span>(<span class="string">&#x27;resize&#x27;</span>, debouncedResize)</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="title function_">onBeforeUnmount</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">if</span> (chart.<span class="property">value</span>) &#123;</span><br><span class="line">    chart.<span class="property">value</span>.<span class="title function_">dispose</span>()</span><br><span class="line">    chart.<span class="property">value</span> = <span class="literal">null</span></span><br><span class="line">    <span class="variable language_">window</span>.<span class="title function_">removeEventListener</span>(<span class="string">&#x27;resize&#x27;</span>, debouncedResize)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">博观而约取，厚积而薄发</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="ECharts" scheme="https://luckynwa.top/tags/ECharts/"/>
    
  </entry>
  
  <entry>
    <title>Flex弹性布局详解</title>
    <link href="https://luckynwa.top/posts/front5/"/>
    <id>https://luckynwa.top/posts/front5/</id>
    <published>2025-03-29T02:36:04.000Z</published>
    <updated>2026-07-07T16:20:55.864Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>Flex 是 Flexible Box 的缩写，即弹性布局。</p><h2 id="基础概念"><a class="markdownIt-Anchor" href="#基础概念"></a> 基础概念</h2><ul><li><strong>flex 容器</strong>（flex container）：开启 Flex 布局的父元素</li><li><strong>flex 项目</strong>（flex item）：容器的子元素</li><li><strong>主轴</strong>（main axis）：默认水平方向</li><li><strong>交叉轴</strong>（cross axis）：默认垂直方向</li><li><strong>占用主轴空间</strong>（main size）</li><li><strong>占用交叉轴空间</strong>（cross size）</li></ul><p>Flex 布局发生在父和子容器之间，父一旦被声明为 Flex 布局（flex 容器），它的所有子元素自动成为容器成员（flex 项目）。</p><p>项目（flex 项目）默认是沿主轴 X 方向排列的，单个项目占据主轴的空间称之为 main size，占据交叉 Y 轴的空间称之为 cross size。</p><h2 id="容器属性"><a class="markdownIt-Anchor" href="#容器属性"></a> 容器属性</h2><p><img src="https://cloud.luckynwa.top/profile/mdS/flex1.png" alt="flex容器属性" /></p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.box</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: flex;</span><br><span class="line">  <span class="attribute">justify-content</span>: flex-start | flex-end | center | space-between | space-around;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>垂直换行：</strong> <code>flex-direction: column</code> 加 <code>flex-wrap: wrap</code>，如果有 2 列，就从 1 列开始从上到下，多了就第二列</p><p><img src="https://cloud.luckynwa.top/profile/mdS/flex2.png" alt="flex布局示例1" /></p><p><img src="https://cloud.luckynwa.top/profile/mdS/flex3.png" alt="flex布局示例2" /></p><p><strong>justify-content 属性说明：</strong></p><ul><li><code>space-between</code>：项目两端对齐，项目之间的间距相同</li><li><code>space-around</code>：项目间距相同，两端也会有间距</li></ul><h2 id="项目属性"><a class="markdownIt-Anchor" href="#项目属性"></a> 项目属性</h2><p><img src="https://cloud.luckynwa.top/profile/mdS/flex4.png" alt="flex项目属性" /></p><h3 id="flex-grow"><a class="markdownIt-Anchor" href="#flex-grow"></a> flex-grow</h3><p>定义项目的放大比例，默认为 0，即如果存在剩余空间，也不放大。</p><h3 id="flex-shrink"><a class="markdownIt-Anchor" href="#flex-shrink"></a> flex-shrink</h3><p>定义项目的缩小比例，默认为 1，即如果空间不足，该项目将缩小。负值对该属性无效。如果 <code>flex-shrink</code> 值为 0，表示该项目不收缩。</p><h3 id="flex-basis"><a class="markdownIt-Anchor" href="#flex-basis"></a> flex-basis</h3><p>定义在分配多余空间之前，项目占据的<strong>主轴空间</strong>（main size）。浏览器根据这个属性，计算主轴是否有多余空间。默认值为 <code>auto</code>，即项目的本来大小。</p><h3 id="flex-简写属性"><a class="markdownIt-Anchor" href="#flex-简写属性"></a> flex 简写属性</h3><p><code>flex</code> 是 <code>flex-grow</code>、<code>flex-shrink</code> 和 <code>flex-basis</code> 的简写，默认值为 <code>0 1 auto</code>。</p><figure class="highlight css"><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="attribute">flex</span>: auto    <span class="comment">/* 相当于 flex: 1 1 auto */</span></span><br><span class="line">flex: none    <span class="comment">/* 相当于 flex: 0 0 auto */</span></span><br></pre></td></tr></table></figure><p><strong>等分布局示例：</strong></p><p>给 3 个子 div 设置不同的 flex 值：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 均分宽度，B 占一半 */</span></span><br><span class="line"><span class="selector-tag">A</span>: flex: <span class="number">1</span></span><br><span class="line">B: flex: <span class="number">2</span></span><br><span class="line">C: flex: <span class="number">1</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">立志欲坚不欲锐，成功在久不在速</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Css" scheme="https://luckynwa.top/tags/Css/"/>
    
  </entry>
  
  <entry>
    <title>ElasticSearch7快速入门</title>
    <link href="https://luckynwa.top/posts/java1/"/>
    <id>https://luckynwa.top/posts/java1/</id>
    <published>2025-02-28T21:12:59.000Z</published>
    <updated>2026-07-07T16:20:55.693Z</updated>
    
    <content type="html"><![CDATA[<h1 id="入门"><a class="markdownIt-Anchor" href="#入门"></a> 入门</h1><p><a href="https://blog.csdn.net/Y_hanxiong/article/details/127261296">Elasticsearch 硬核入门教程（2022 最全）</a></p><p>版本 elasticsearch-7.0.0 太高会不支持 JDK8</p><ul><li><p>运行软件目录下的 bin 文件夹下的 elasticsearch.bat</p></li><li><p><code>9300</code> 端口为 Elasticsearch 集群间组件的通信端口</p></li><li><p><code>9200</code> 端口为浏览器访问的 HTTP 协议 RESTful 端口</p></li><li><p>浏览器运行 <a href="http://localhost:9200/">localhost:9200</a></p></li><li><p>出现 “tagline”: “You Know, for Search” 就成功</p></li></ul><p>概念类比：</p><p><img src="http://120.26.80.35:3737/mdS/es.png" alt="图片1" /></p><p>Elasticsearch 7.X 中，Type 的概念已经被删除了</p><h2 id="索引操作"><a class="markdownIt-Anchor" href="#索引操作"></a> 索引操作</h2><h3 id="创建索引"><a class="markdownIt-Anchor" href="#创建索引"></a> 创建索引</h3><p>用 Postman 软件进行下面操作</p><p>PUT 请求下面链接即可无参</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start</span><br></pre></td></tr></table></figure><p>返回</p><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;acknowledged&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;shards_acknowledged&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="string">&quot;start&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>解析：</p><ul><li><code>acknowledged</code>【响应结果】: true，操作成功</li><li><code>shards_acknowledged</code>【分片结果】: true，分片操作成功</li><li><code>index</code>【索引名称】: start</li><li>注意：创建索引库的分片数默认 1 片，在 7.0.0 之前的 Elasticsearch 版本中，默认 5 片</li></ul><h3 id="查看索引"><a class="markdownIt-Anchor" href="#查看索引"></a> 查看索引</h3><p>向 ES 服务器发 GET 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/_cat/indices?v</span><br></pre></td></tr></table></figure><p>这里请求路径中的 <code>_cat</code> 表示查看的意思，<code>indices</code> 表示索引，所以整体含义就是查看当前 ES 服务器中的所有索引，就好像 MySQL 中的 <code>show tables</code></p><p>返回</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size</span><br><span class="line">yellow open   start 9cGmSfZ_TxyUiI1Gl9BiAw   1   1          0            0       230b           230b</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/Snipaste_2023-07-20_10-01-23.png" alt="Snipaste_2023-07-20_10-01-23" /></p><h3 id="查看单个索引"><a class="markdownIt-Anchor" href="#查看单个索引"></a> 查看单个索引</h3><p>GET 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start</span><br></pre></td></tr></table></figure><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;start&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;aliases&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;creation_date&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1689818229673&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;number_of_shards&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;number_of_replicas&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;uuid&quot;</span><span class="punctuation">:</span> <span class="string">&quot;9cGmSfZ_TxyUiI1Gl9BiAw&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;created&quot;</span><span class="punctuation">:</span> <span class="string">&quot;7000099&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;provided_name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;start&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>解析：</p><ul><li><code>start</code>【索引名】<ul><li><code>aliases</code>【别名】: {}</li><li><code>mappings</code>【映射】: {}</li><li><code>settings</code>【设置】<ul><li><code>number_of_shards</code>【主分片数量】: 1</li><li><code>number_of_replicas</code>【副分片数量】: 1</li><li><code>uuid</code>【唯一标识】</li><li><code>version</code>【版本】</li></ul></li></ul></li></ul><h3 id="删除索引"><a class="markdownIt-Anchor" href="#删除索引"></a> 删除索引</h3><p>发 DELETE 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start</span><br></pre></td></tr></table></figure><h2 id="文档操作"><a class="markdownIt-Anchor" href="#文档操作"></a> 文档操作</h2><h3 id="创建文档"><a class="markdownIt-Anchor" href="#创建文档"></a> 创建文档</h3><p>文档可以类比为关系型数据库中的表数据，添加的数据格式为 JSON 格式</p><p>在 Postman 中，向 ES 服务器发 POST 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/doc</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></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/doc/1</span><br></pre></td></tr></table></figure><p>需要 Body -&gt; Row -&gt; JSON</p><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;title&quot;</span><span class="punctuation">:</span> <span class="string">&quot;小米手机&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;category&quot;</span><span class="punctuation">:</span> <span class="string">&quot;小米&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;images&quot;</span><span class="punctuation">:</span> <span class="string">&quot;www.xiaobear.cn&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;price&quot;</span><span class="punctuation">:</span> <span class="number">36666.0</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>返回结果</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;_index&quot;</span><span class="punctuation">:</span> <span class="string">&quot;start&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;doc&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;LopVcYkBQUfrnphKjG1q&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_version&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;result&quot;</span><span class="punctuation">:</span> <span class="string">&quot;created&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_shards&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;total&quot;</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;successful&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;failed&quot;</span><span class="punctuation">:</span> <span class="number">0</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_seq_no&quot;</span><span class="punctuation">:</span> <span class="number">0</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;_primary_term&quot;</span><span class="punctuation">:</span> <span class="number">2</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>解析：</p><ul><li><code>_index</code>【索引】: start</li><li><code>_type</code>【类型-文档】: doc</li><li><code>_id</code>【唯一标识】: 可以类比为 MySQL 中的主键，随机生成</li><li><code>_version</code>【版本号】: 1</li><li><code>result</code>【结果】: created，表示创建成功</li><li><code>_shards</code>【分片】<ul><li><code>total</code>【分片-总数】: 2</li><li><code>successful</code>【分片-成功】: 1</li><li><code>failed</code>【分片-失败】: 0</li></ul></li></ul><h3 id="修改文档"><a class="markdownIt-Anchor" href="#修改文档"></a> 修改文档</h3><p>POST 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/_doc/1</span><br></pre></td></tr></table></figure><p>如果请求体变化，会将原有的数据内容覆盖，在 Postman 中，并且版本会变化</p><h3 id="修改字段"><a class="markdownIt-Anchor" href="#修改字段"></a> 修改字段</h3><p>POST 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/_update/1</span><br></pre></td></tr></table></figure><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;doc&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;price&quot;</span><span class="punctuation">:</span> <span class="number">5000.0</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h3 id="查看文档"><a class="markdownIt-Anchor" href="#查看文档"></a> 查看文档</h3><p>根据唯一性标识，查询文档数据，文档数据已经更新</p><p>GET 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/_doc/1</span><br></pre></td></tr></table></figure><h3 id="删除文档"><a class="markdownIt-Anchor" href="#删除文档"></a> 删除文档</h3><p>ES 服务器发 DELETE 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/_doc/1</span><br></pre></td></tr></table></figure><p>一般删除数据都是根据文档的唯一性标识进行删除，实际操作时，也可以根据条件对多条数据进行删除</p><p>POST 请求（按条件删除）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/start/_delete_by_query</span><br></pre></td></tr></table></figure><figure class="highlight json"><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 class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;query&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;match&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;price&quot;</span><span class="punctuation">:</span> <span class="number">3999.0</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="映射操作"><a class="markdownIt-Anchor" href="#映射操作"></a> 映射操作</h2><p>有了索引库，等于有了数据库中的 database。</p><p>接下来就需要建索引库(index)中的映射了，类似于数据库(database)中的表结构(table)。创建数据库表需要设置字段名称，类型，长度，约束等；索引库也一样，需要知道这个类型下有哪些字段，每个字段有哪些约束信息，这就叫做映射(mapping)。</p><h3 id="创建映射"><a class="markdownIt-Anchor" href="#创建映射"></a> 创建映射</h3><p>先创建索引才能映射，PUT 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://localhost:9200/user</span><br></pre></td></tr></table></figure><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;number_of_shards&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;number_of_replicas&quot;</span><span class="punctuation">:</span> <span class="number">1</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;age&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;integer&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>PUT 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/user/_mapping</span><br></pre></td></tr></table></figure><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;sex&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;phone&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>映射数据说明</p><ul><li><p><strong>字段名</strong>：任意填写，下面指定许多属性，例如：title、subtitle、images、price</p></li><li><p><strong>type</strong>：类型，Elasticsearch 中支持的数据类型非常丰富</p><ul><li>基本数据类型：long、integer、short、byte、double、float、half_float</li><li>浮点数的高精度类型：scaled_float</li><li>text：可分词</li><li>keyword：不可分词，数据会作为完整字段进行匹配</li><li>String 类型，又分两种</li><li>Numerical：数值类型，分两类</li><li>Date：日期类型</li><li>Array：数组类型</li><li>Object：对象</li></ul></li><li><p><strong>index</strong>：是否索引，默认为 true，也就是说你不进行任何配置，所有字段都会被索引</p><ul><li>true：字段会被索引，则可以用来进行搜索</li><li>false：字段不会被索引，不能用来搜索</li></ul></li><li><p><strong>store</strong>：是否将数据进行独立存储，默认为 false</p><p>原始的文本会存储在 <code>_source</code> 里面，默认情况下其他提取出来的字段都不是独立存储的，是从 <code>_source</code> 里面提取出来的。当然你也可以独立的存储某个字段，只要设置 <code>&quot;store&quot;: true</code> 即可，获取独立存储的字段要比从 <code>_source</code> 中解析快得多，但是也会占用更多的空间，所以要根据实际业务需求来设置。</p></li><li><p><strong>analyzer</strong>：分词器，这里的 ik_max_word 即使用 ik 分词器</p></li></ul><h3 id="查看映射"><a class="markdownIt-Anchor" href="#查看映射"></a> 查看映射</h3><p>在 Postman 中，向 ES 服务器发 GET 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/user/_mapping</span><br></pre></td></tr></table></figure><h3 id="索引映射关联"><a class="markdownIt-Anchor" href="#索引映射关联"></a> 索引映射关联</h3><p>PUT 请求</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://127.0.0.1:9200/user1</span><br></pre></td></tr></table></figure><h2 id="idea-操作"><a class="markdownIt-Anchor" href="#idea-操作"></a> Idea 操作</h2><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></pre></td><td class="code"><pre><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.elasticsearch.client<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>elasticsearch-rest-high-level-client<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>6.6.2<span class="tag">&lt;/<span class="name">version</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">exclusions</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">exclusion</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.elasticsearch<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>elasticsearch<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">exclusion</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">exclusions</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><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.elasticsearch<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>elasticsearch<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>6.6.2<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></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ElasticSearch</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">// 9200 端口为 Elasticsearch 的 Web 通信端口 localhost 为启动 ES 服务的主机名</span></span><br><span class="line">        <span class="type">RestHighLevelClient</span> <span class="variable">client</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RestHighLevelClient</span>(</span><br><span class="line">                RestClient.builder(<span class="keyword">new</span> <span class="title class_">HttpHost</span>(<span class="string">&quot;localhost&quot;</span>, <span class="number">9200</span>)));</span><br><span class="line">        client.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>没有任何输出或报错信息即是成功</p><h3 id="创建索引-2"><a class="markdownIt-Anchor" href="#创建索引-2"></a> 创建索引</h3><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 9200 端口为 Elasticsearch 的 Web 通信端口 localhost 为启动 ES 服务的主机名</span></span><br><span class="line"><span class="type">RestHighLevelClient</span> <span class="variable">client</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RestHighLevelClient</span>(</span><br><span class="line">        RestClient.builder(<span class="keyword">new</span> <span class="title class_">HttpHost</span>(<span class="string">&quot;localhost&quot;</span>, <span class="number">9200</span>)));</span><br><span class="line"><span class="comment">// 创建索引</span></span><br><span class="line"><span class="type">CreateIndexRequest</span> <span class="variable">request</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">CreateIndexRequest</span>(<span class="string">&quot;pic&quot;</span>);</span><br><span class="line"><span class="type">CreateIndexResponse</span> <span class="variable">response</span> <span class="operator">=</span> client.indices().create(request, RequestOptions.DEFAULT);</span><br><span class="line"><span class="comment">// 创建索引的响应状态</span></span><br><span class="line"><span class="type">boolean</span> <span class="variable">acknowledged</span> <span class="operator">=</span> response.isAcknowledged();</span><br><span class="line">System.out.println(<span class="string">&quot;响应状态为：&quot;</span> + acknowledged);</span><br><span class="line">client.close();</span><br></pre></td></tr></table></figure><h3 id="查询"><a class="markdownIt-Anchor" href="#查询"></a> 查询</h3><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 查询索引</span></span><br><span class="line"><span class="type">GetIndexRequest</span> <span class="variable">request</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">GetIndexRequest</span>().indices(<span class="string">&quot;pic&quot;</span>);</span><br><span class="line"><span class="type">GetIndexResponse</span> <span class="variable">response</span> <span class="operator">=</span> client.indices().get(request, RequestOptions.DEFAULT);</span><br><span class="line"><span class="comment">// 查询索引的响应状态</span></span><br><span class="line">System.out.println(response);</span><br><span class="line">System.out.println(response.getSettings());</span><br><span class="line">System.out.println(response.getAliases());</span><br><span class="line">System.out.println(response.getMappings());</span><br><span class="line">client.close();</span><br></pre></td></tr></table></figure><h1 id="项目"><a class="markdownIt-Anchor" href="#项目"></a> 项目</h1><h2 id="创建索引-3"><a class="markdownIt-Anchor" href="#创建索引-3"></a> 创建索引</h2><p>在 Kibana 的可视化下的开发工具里运行</p><p>进入 <a href="http://192.168.56.10:5601/app/management/kibana/spaces">http://192.168.56.10:5601/app/management/kibana/spaces</a></p><p>点击 D -&gt; 看到索引管理</p><figure class="highlight json"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line">PUT /course-publish</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;number_of_shards&quot;</span><span class="punctuation">:</span> <span class="number">1</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;number_of_replicas&quot;</span><span class="punctuation">:</span> <span class="number">0</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;properties&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;companyId&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;companyName&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_max_word&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;search_analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_smart&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_max_word&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;search_analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_smart&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;users&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;tags&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_max_word&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;search_analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_smart&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;mt&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;mtName&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;st&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;stName&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;grade&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;teachmode&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;pic&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_max_word&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;search_analyzer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ik_smart&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;createDate&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;format&quot;</span><span class="punctuation">:</span> <span class="string">&quot;yyyy-MM-dd HH:mm:ss&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;date&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;remark&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;index&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;text&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;charge&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;keyword&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;price&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;scaled_float&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;scaling_factor&quot;</span><span class="punctuation">:</span> <span class="number">100</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;originalPrice&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;scaled_float&quot;</span><span class="punctuation">,</span></span><br><span class="line">                <span class="attr">&quot;scaling_factor&quot;</span><span class="punctuation">:</span> <span class="number">100</span></span><br><span class="line">            <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;validDays&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;integer&quot;</span></span><br><span class="line">            <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="删除索引-2"><a class="markdownIt-Anchor" href="#删除索引-2"></a> 删除索引</h2><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DELETE /course-publish</span><br></pre></td></tr></table></figure><h2 id="查询索引"><a class="markdownIt-Anchor" href="#查询索引"></a> 查询索引</h2><figure class="highlight json"><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">GET /_cat/indices?v</span><br><span class="line">GET /course-publish/_mapping</span><br><span class="line">GET course-publish</span><br></pre></td></tr></table></figure><h2 id="创建文档-2"><a class="markdownIt-Anchor" href="#创建文档-2"></a> 创建文档</h2><figure class="highlight json"><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">POST /course-publish/_doc/<span class="number">103</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;charge&quot;</span><span class="punctuation">:</span> <span class="string">&quot;201001&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;companyId&quot;</span><span class="punctuation">:</span> <span class="number">100000</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;companyName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;北京黑马程序&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;createDate&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2022-09-25 09:36:11&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;HTML/CSS&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;grade&quot;</span><span class="punctuation">:</span> <span class="string">&quot;204001&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="number">102</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;mt&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1-1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;mtName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;前端开发&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Html参考大全&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;originalPrice&quot;</span><span class="punctuation">:</span> <span class="number">200.0</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;pic&quot;</span><span class="punctuation">:</span> <span class="string">&quot;/mediafiles/2022/09/20/e726b71ba99c70e8c9d2850c2a7019d7.jpg&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;price&quot;</span><span class="punctuation">:</span> <span class="number">100.0</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;remark&quot;</span><span class="punctuation">:</span> <span class="string">&quot;没有备注&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;st&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1-1-1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;stName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;HTML/CSS&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;status&quot;</span><span class="punctuation">:</span> <span class="string">&quot;203002&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;tags&quot;</span><span class="punctuation">:</span> <span class="string">&quot;没有标签&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;teachmode&quot;</span><span class="punctuation">:</span> <span class="string">&quot;200002&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;validDays&quot;</span><span class="punctuation">:</span> <span class="number">222</span></span><br><span class="line"><span class="punctuation">&#125;</span></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></pre></td><td class="code"><pre><span class="line">GET /course-publish/_doc/103</span><br></pre></td></tr></table></figure><h2 id="更新文档"><a class="markdownIt-Anchor" href="#更新文档"></a> 更新文档</h2><p>更新文档分为全量更新和局部更新。</p><p>全量更新是指先删除再更新，语法如下：</p><figure class="highlight json"><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">PUT /course-publish/_doc/<span class="number">103</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;字段1&quot;</span><span class="punctuation">:</span> <span class="string">&quot;值1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;字段2&quot;</span><span class="punctuation">:</span> <span class="string">&quot;值2&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;...&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>局部更新语法如下：</p><figure class="highlight json"><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">POST /<span class="punctuation">&#123;</span>索引库名<span class="punctuation">&#125;</span>/_update/文档id</span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;doc&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;字段名&quot;</span><span class="punctuation">:</span> <span class="string">&quot;新的值&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="删除文档-2"><a class="markdownIt-Anchor" href="#删除文档-2"></a> 删除文档</h2><p>删除文档将从索引中删除文档的记录。</p><p>语法如下：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DELETE /<span class="punctuation">&#123;</span>索引库名<span class="punctuation">&#125;</span>/_doc/id值</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">三人行，必有我师焉</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="ElasticSearch" scheme="https://luckynwa.top/tags/ElasticSearch/"/>
    
  </entry>
  
  <entry>
    <title>情侣网站搭建教程 - Typecho主题配置与部署</title>
    <link href="https://luckynwa.top/posts/love182/"/>
    <id>https://luckynwa.top/posts/love182/</id>
    <published>2025-02-24T02:30:00.000Z</published>
    <updated>2026-07-07T16:20:55.582Z</updated>
    
    <content type="html"><![CDATA[<h1 id="情侣网站搭建教程"><a class="markdownIt-Anchor" href="#情侣网站搭建教程"></a> 情侣网站搭建教程</h1><h2 id="方式1"><a class="markdownIt-Anchor" href="#方式1"></a> 方式1</h2><p>使用 docker 安装，先去创建 <code>/nwa/typecho</code> 文件夹，再在里面创建 <code>docker-compose.yml</code>，我外部有 mysql8 直接配置外部的。</p><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></pre></td><td class="code"><pre><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="comment">#   image: mysql:8.0</span></span><br><span class="line">  <span class="comment">#   container_name: typecho-mysql</span></span><br><span class="line">  <span class="comment">#   restart: always</span></span><br><span class="line">  <span class="comment">#   environment:</span></span><br><span class="line">  <span class="comment">#     MYSQL_ROOT_PASSWORD: root123</span></span><br><span class="line">  <span class="comment">#     MYSQL_DATABASE: typecho</span></span><br><span class="line">  <span class="comment">#     MYSQL_USER: typecho</span></span><br><span class="line">  <span class="comment">#     MYSQL_PASSWORD: typecho123</span></span><br><span class="line">  <span class="comment">#   volumes:</span></span><br><span class="line">  <span class="comment">#     - ./mysql:/var/lib/mysql</span></span><br><span class="line">  <span class="comment">#   command: --default-authentication-plugin=mysql_native_password</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># typecho:</span></span><br><span class="line">  <span class="comment">#   image: joyqi/typecho:nightly-php8.2-apache</span></span><br><span class="line">  <span class="comment">#   container_name: typecho</span></span><br><span class="line">  <span class="comment">#   restart: always</span></span><br><span class="line">  <span class="comment">#   depends_on:</span></span><br><span class="line">  <span class="comment">#     - mysql</span></span><br><span class="line">  <span class="comment">#   ports:</span></span><br><span class="line">  <span class="comment">#     - &quot;8080:80&quot;</span></span><br><span class="line">  <span class="comment">#   volumes:</span></span><br><span class="line">  <span class="comment">#     - ./typecho:/app/usr</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">typecho:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">joyqi/typecho:nightly-php8.2-apache</span></span><br><span class="line">    <span class="attr">container_name:</span> <span class="string">typecho</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&#x27;17575:80&#x27;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">/nwa/typecho/usr:/app/usr</span></span><br></pre></td></tr></table></figure><p>建表：</p><figure class="highlight sql"><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="keyword">CREATE</span> DATABASE typecho</span><br><span class="line"><span class="type">CHARACTER</span> <span class="keyword">SET</span> utf8mb4</span><br><span class="line"><span class="keyword">COLLATE</span> utf8mb4_unicode_ci;</span><br></pre></td></tr></table></figure><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">docker compose up -d</span><br></pre></td></tr></table></figure><p>记得端口映射，前缀那个默认不改动。访问 <a href="http://localhost:17575/">http://localhost:17575/</a></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705122225409_20260705122226A011.png" alt="image-20260705122225409" /></p><p>luckyNwa，22…，1656213092@qq.com</p><p>主题下载地址：<a href="https://github.com/zwying0814/Brave">zwying0814/Brave: Typecho情侣主题Brave</a><br /><a href="https://github.com/luckyNwa6/Brave">修复了它的cdn问题，推荐下载这个</a></p><p>本地打开 <a href="http://localhost:17575/admin/themes.php%EF%BC%8C%E7%9C%8B%E5%88%B0">http://localhost:17575/admin/themes.php，看到</a> Brave 主题，点击启动，再设置外观。</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><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">https://cloud.luckynwa.top/profile/love/bg.jpg</span><br><span class="line">2024/12/28</span><br><span class="line">https://cloud.luckynwa.top/profile/love/boy.jpg</span><br><span class="line">https://cloud.luckynwa.top/profile/love/girl.jpg</span><br><span class="line">boy</span><br><span class="line">girl</span><br><span class="line"></span><br><span class="line">https://cloud.luckynwa.top/profile/love/bg2.jpg</span><br><span class="line">http://localhost:8080/index.php/5.html  #注意创建下的值</span><br><span class="line"></span><br><span class="line">https://cloud.luckynwa.top/profile/love/bg3.jpg</span><br><span class="line">http://localhost:8080/index.php/3.html</span><br><span class="line"></span><br><span class="line">https://cloud.luckynwa.top/profile/love/bg4.jpg</span><br></pre></td></tr></table></figure><p>创建 <strong>三个页面</strong>，记得勾选自定义模板：</p><ul><li>首页：自定义模板不选择，对应 3.html</li><li>祝福板：自定义模板祝福板，对应 4.html</li><li>Love List：自定义模板 Love List，对应 localhost:17575/index.php/Love-List.html</li></ul><h3 id="首页配置"><a class="markdownIt-Anchor" href="#首页配置"></a> 首页配置</h3><p><img src="https://cloud.luckynwa.top/profile/love/jc1.png" alt="首页配置" /></p><h2 id="修改版权"><a class="markdownIt-Anchor" href="#修改版权"></a> 修改版权</h2><p>修改文件：<code>/wwwroot/usr/themes/Brave/base/</code> 下的 <code>foot.php</code></p><p><strong>原代码</strong>：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;p <span class="class"><span class="keyword">class</span>=&quot;<span class="title">h6</span>&quot;&gt; <span class="title">Powered</span> <span class="title">by</span> &lt;<span class="title">a</span> <span class="title">href</span>=&quot;<span class="title">http</span>://<span class="title">typecho</span>.<span class="title">org</span>&quot; <span class="title">target</span>=&quot;<span class="title">_blank</span>&quot;&gt;<span class="title">Typecho</span>&lt;/<span class="title">a</span>&gt; ※ <span class="title">Theme</span> <span class="title">is</span> &lt;<span class="title">a</span> <span class="title">href</span>=&quot;<span class="title">https</span>://<span class="title">blog</span>.<span class="title">zwying</span>.<span class="title">com</span>&quot; <span class="title">target</span>=&quot;<span class="title">_blank</span>&quot;&gt;<span class="title">Brave</span>&lt;/<span class="title">a</span>&gt;&lt;/<span class="title">p</span>&gt;</span></span><br></pre></td></tr></table></figure><p><strong>改为</strong>：</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;p <span class="class"><span class="keyword">class</span>=&quot;<span class="title">h6</span>&quot;&gt; <span class="title">Powered</span> <span class="title">by</span> &lt;<span class="title">a</span> <span class="title">href</span>=&quot;<span class="title">https</span>://<span class="title">luckynwa</span>.<span class="title">top</span>&quot; <span class="title">target</span>=&quot;<span class="title">_blank</span>&quot;&gt;<span class="title">luckyNwa</span>&lt;/<span class="title">a</span>&gt;&lt;/<span class="title">p</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="方式2"><a class="markdownIt-Anchor" href="#方式2"></a> 方式2</h2><h3 id="服务器选择"><a class="markdownIt-Anchor" href="#服务器选择"></a> 服务器选择</h3><p>推荐使用 <strong>星辰云</strong> 轻量云主机，性价比超高</p><ul><li>官网：<a href="https://starxn.com/">https://starxn.com/</a></li><li>价格：<strong>2块钱一个月</strong></li><li>管理面板：<a href="https://aspanel.starzv.com/vhost/#/home/">https://aspanel.starzv.com/vhost/#/home/</a></li></ul><h3 id="域名配置"><a class="markdownIt-Anchor" href="#域名配置"></a> 域名配置</h3><p>需要域名（二级域名即可），要做域名解析</p><ol><li>先腾讯云域名解析：<a href="https://console.cloud.tencent.com/cns">https://console.cloud.tencent.com/cns</a></li><li>然后绑定在自己的轻量云主机上面</li></ol><h3 id="环境要求"><a class="markdownIt-Anchor" href="#环境要求"></a> 环境要求</h3><table><thead><tr><th>组件</th><th>版本</th></tr></thead><tbody><tr><td>宝塔面板</td><td>最新版</td></tr><tr><td>Nginx</td><td>1.22.1（端口改为80）</td></tr><tr><td>MySQL</td><td>5.6</td></tr><tr><td>PHP</td><td>7.2.33</td></tr></tbody></table><p>然后访问 <code>http://域名/</code> 进入 nginx 页面，加上 index.html 即可正常访问。</p><h3 id="宝塔操作流程"><a class="markdownIt-Anchor" href="#宝塔操作流程"></a> 宝塔操作流程</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">宝塔 → 网站 → 添加站点 → 域名（ftp和数据库也要勾选）→ 双击根目录 → typecho 压缩包上传并解压</span><br></pre></td></tr></table></figure><p><strong>上传目录无法写入？</strong></p><p>手动将安装目录下的 <code>/usr/uploads</code> 目录权限设置为可写：</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></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> /www</span><br><span class="line">chattr -ia wwwroot</span><br><span class="line"><span class="built_in">chmod</span> -R 777 wwwroot</span><br></pre></td></tr></table></figure><p>用的星辰云，数据库账号：<code>aiwwazbbi</code>，密码同下。</p><p>管理地址：<a href="http://love.luckynwa.top/admin/welcome.php">http://love.luckynwa.top/admin/welcome.php</a> （这是下面配置网站 luckyNwa 22…）</p><h2 id="主题配置"><a class="markdownIt-Anchor" href="#主题配置"></a> 主题配置</h2><p>将主题压缩包完整上传到服务器上 Typecho 的 <code>/usr/themes/</code> 文件夹内，解压，然后到 <strong>Typecho 后台 → 控制台 → 外观 → 启用主题</strong></p><p>后面的配置和方式 1 一样。</p>]]></content>
    
    
    <summary type="html">愿得一心人，白首不相离</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Docker" scheme="https://luckynwa.top/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>Vite项目框架搭建</title>
    <link href="https://luckynwa.top/posts/front11/"/>
    <id>https://luckynwa.top/posts/front11/</id>
    <published>2025-02-10T01:59:36.000Z</published>
    <updated>2026-07-07T16:19:34.009Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1-搭建后台管理系统模板"><a class="markdownIt-Anchor" href="#1-搭建后台管理系统模板"></a> 1、搭建后台管理系统模板</h2><h3 id="环境准备"><a class="markdownIt-Anchor" href="#环境准备"></a> 环境准备</h3><ul><li>node v16.20.1</li><li>pnpm 8.10.2</li></ul><h3 id="初始化项目"><a class="markdownIt-Anchor" href="#初始化项目"></a> 初始化项目</h3><p>本项目使用vite进行构建，vite官方中文文档参考：<a href="https://cn.vitejs.dev/guide/">cn.vitejs.dev/guide/</a></p><p><strong>pnpm:performant npm，意味&quot;高性能的npm&quot;。pnpm由npm/yarn衍生而来，解决了npm/yarn内部潜在的bug，极大的优化了性能，扩展了使用场景。被誉为&quot;最先进的包管理工具&quot;</strong></p><p>pnpm安装指令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i -g pnpm</span><br></pre></td></tr></table></figure><p>项目初始化命令:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><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">pnpm create vite</span><br><span class="line">选</span><br><span class="line">y  回车</span><br><span class="line">vue 回车  ts  回车</span><br><span class="line">cd luckyWeb</span><br><span class="line">pnpm i</span><br><span class="line">npm run dev</span><br></pre></td></tr></table></figure><p>运行完毕项目跑在<a href="http://127.0.0.1:5173">http://127.0.0.1:5173</a></p><h3 id="项目配置"><a class="markdownIt-Anchor" href="#项目配置"></a> 项目配置</h3><h4 id="eslint配置"><a class="markdownIt-Anchor" href="#eslint配置"></a> eslint配置</h4><p><strong>eslint中文官网:<a href="http://eslint.cn/">http://eslint.cn/</a></strong></p><p>ESLint最初是由<a href="http://nczonline.net/">Nicholas C. Zakas</a>于2013年6月创建的开源项目。它的目标是提供一个插件化的<strong>javascript代码检测工具</strong></p><p>首先安装eslint</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm i eslint@8.57.0 -D</span><br></pre></td></tr></table></figure><p>生成配置文件.eslint.cjs</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx eslint --init</span><br></pre></td></tr></table></figure><p><strong>.eslint.cjs配置如下</strong></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="comment">//运行环境</span></span><br><span class="line">  <span class="attr">env</span>: &#123;</span><br><span class="line">    <span class="attr">browser</span>: <span class="literal">true</span>, <span class="comment">//浏览器端</span></span><br><span class="line">    <span class="attr">es2021</span>: <span class="literal">true</span>, <span class="comment">//es2021</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">//规则继承</span></span><br><span class="line">  <span class="attr">extends</span>: [</span><br><span class="line">    <span class="comment">//全部规则默认是关闭的,这个配置项开启推荐规则,推荐规则参照文档</span></span><br><span class="line">    <span class="comment">//比如:函数不能重名、对象不能出现重复key</span></span><br><span class="line">    <span class="string">&#x27;eslint:recommended&#x27;</span>,</span><br><span class="line">    <span class="comment">//vue3语法规则</span></span><br><span class="line">    <span class="string">&#x27;plugin:vue/vue3-essential&#x27;</span>,</span><br><span class="line">    <span class="comment">//ts语法规则</span></span><br><span class="line">    <span class="string">&#x27;plugin:@typescript-eslint/recommended&#x27;</span>,</span><br><span class="line">  ],</span><br><span class="line">  <span class="comment">//要为特定类型的文件指定处理器</span></span><br><span class="line">  <span class="attr">overrides</span>: [],</span><br><span class="line">  <span class="comment">//指定解析器:解析器</span></span><br><span class="line">  <span class="comment">//Esprima 默认解析器</span></span><br><span class="line">  <span class="comment">//Babel-ESLint babel解析器</span></span><br><span class="line">  <span class="comment">//@typescript-eslint/parser ts解析器</span></span><br><span class="line">  <span class="attr">parser</span>: <span class="string">&#x27;@typescript-eslint/parser&#x27;</span>,</span><br><span class="line">  <span class="comment">//指定解析器选项</span></span><br><span class="line">  <span class="attr">parserOptions</span>: &#123;</span><br><span class="line">    <span class="attr">ecmaVersion</span>: <span class="string">&#x27;latest&#x27;</span>, <span class="comment">//校验ECMA最新版本</span></span><br><span class="line">    <span class="attr">sourceType</span>: <span class="string">&#x27;module&#x27;</span>, <span class="comment">//设置为&quot;script&quot;（默认），或者&quot;module&quot;代码在ECMAScript模块中</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">//ESLint支持使用第三方插件。在使用插件之前，您必须使用npm安装它</span></span><br><span class="line">  <span class="comment">//该eslint-plugin-前缀可以从插件名称被省略</span></span><br><span class="line">  <span class="attr">plugins</span>: [<span class="string">&#x27;vue&#x27;</span>, <span class="string">&#x27;@typescript-eslint&#x27;</span>],</span><br><span class="line">  <span class="comment">//eslint规则</span></span><br><span class="line">  <span class="attr">rules</span>: &#123;&#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>vue3环境代码校验插件</strong></p><p>安装指令</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm install -D eslint-plugin-import@2.29.1 eslint-plugin-vue@9.22.0 eslint-plugin-node@11.1.0 eslint-plugin-prettier@5.1.3 eslint-config-prettier@9.1.0 eslint-plugin-node@11.1.0 @babel/eslint-parser@7.23.10</span><br></pre></td></tr></table></figure><p>修改.eslintrc.cjs配置文件</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// @see https://eslint.bootcss.com/docs/rules/</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">env</span>: &#123;</span><br><span class="line">    <span class="attr">browser</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">es2021</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">node</span>: <span class="literal">true</span>,</span><br><span class="line">    <span class="attr">jest</span>: <span class="literal">true</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">/* 指定如何解析语法 */</span></span><br><span class="line">  <span class="attr">parser</span>: <span class="string">&#x27;vue-eslint-parser&#x27;</span>,</span><br><span class="line">  <span class="comment">/** 优先级低于 parse 的语法解析配置 */</span></span><br><span class="line">  <span class="attr">parserOptions</span>: &#123;</span><br><span class="line">    <span class="attr">ecmaVersion</span>: <span class="string">&#x27;latest&#x27;</span>,</span><br><span class="line">    <span class="attr">sourceType</span>: <span class="string">&#x27;module&#x27;</span>,</span><br><span class="line">    <span class="attr">parser</span>: <span class="string">&#x27;@typescript-eslint/parser&#x27;</span>,</span><br><span class="line">    <span class="attr">jsxPragma</span>: <span class="string">&#x27;React&#x27;</span>,</span><br><span class="line">    <span class="attr">ecmaFeatures</span>: &#123;</span><br><span class="line">      <span class="attr">jsx</span>: <span class="literal">true</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">/* 继承已有的规则 */</span></span><br><span class="line">  <span class="attr">extends</span>: [<span class="string">&#x27;eslint:recommended&#x27;</span>, <span class="string">&#x27;plugin:vue/vue3-essential&#x27;</span>, <span class="string">&#x27;plugin:@typescript-eslint/recommended&#x27;</span>, <span class="string">&#x27;plugin:prettier/recommended&#x27;</span>],</span><br><span class="line">  <span class="attr">plugins</span>: [<span class="string">&#x27;vue&#x27;</span>, <span class="string">&#x27;@typescript-eslint&#x27;</span>],</span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * &quot;off&quot; 或 0    ==&gt;  关闭规则</span></span><br><span class="line"><span class="comment">   * &quot;warn&quot; 或 1   ==&gt;  打开的规则作为警告（不影响代码执行）</span></span><br><span class="line"><span class="comment">   * &quot;error&quot; 或 2  ==&gt;  规则作为一个错误（代码不能执行，界面报错）</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  <span class="attr">rules</span>: &#123;</span><br><span class="line">    <span class="comment">// eslint（https://eslint.bootcss.com/docs/rules/）</span></span><br><span class="line">    <span class="string">&#x27;no-var&#x27;</span>: <span class="string">&#x27;error&#x27;</span>, <span class="comment">// 要求使用 let 或 const 而不是 var</span></span><br><span class="line">    <span class="string">&#x27;no-multiple-empty-lines&#x27;</span>: [<span class="string">&#x27;warn&#x27;</span>, &#123; <span class="attr">max</span>: <span class="number">1</span> &#125;], <span class="comment">// 不允许多个空行</span></span><br><span class="line">    <span class="string">&#x27;no-console&#x27;</span>: process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">&#x27;production&#x27;</span> ? <span class="string">&#x27;error&#x27;</span> : <span class="string">&#x27;off&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;no-debugger&#x27;</span>: process.<span class="property">env</span>.<span class="property">NODE_ENV</span> === <span class="string">&#x27;production&#x27;</span> ? <span class="string">&#x27;error&#x27;</span> : <span class="string">&#x27;off&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;no-unexpected-multiline&#x27;</span>: <span class="string">&#x27;error&#x27;</span>, <span class="comment">// 禁止空余的多行</span></span><br><span class="line">    <span class="string">&#x27;no-useless-escape&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 禁止不必要的转义字符</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// typeScript (https://typescript-eslint.io/rules)</span></span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/no-unused-vars&#x27;</span>: <span class="string">&#x27;error&#x27;</span>, <span class="comment">// 禁止定义未使用的变量</span></span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/prefer-ts-expect-error&#x27;</span>: <span class="string">&#x27;error&#x27;</span>, <span class="comment">// 禁止使用 @ts-ignore</span></span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/no-explicit-any&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 禁止使用 any 类型</span></span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/no-non-null-assertion&#x27;</span>: <span class="string">&#x27;off&#x27;</span>,</span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/no-namespace&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 禁止使用自定义 TypeScript 模块和命名空间。</span></span><br><span class="line">    <span class="string">&#x27;@typescript-eslint/semi&#x27;</span>: <span class="string">&#x27;off&#x27;</span>,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// eslint-plugin-vue (https://eslint.vuejs.org/rules/)</span></span><br><span class="line">    <span class="string">&#x27;vue/multi-word-component-names&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 要求组件名称始终为 &quot;-&quot; 链接的单词</span></span><br><span class="line">    <span class="string">&#x27;vue/script-setup-uses-vars&#x27;</span>: <span class="string">&#x27;error&#x27;</span>, <span class="comment">// 防止&lt;script setup&gt;使用的变量&lt;template&gt;被标记为未使用</span></span><br><span class="line">    <span class="string">&#x27;vue/no-mutating-props&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 不允许组件 prop的改变</span></span><br><span class="line">    <span class="string">&#x27;vue/attribute-hyphenation&#x27;</span>: <span class="string">&#x27;off&#x27;</span>, <span class="comment">// 对模板中的自定义组件强制执行属性命名样式</span></span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>.eslintignore文件</strong></p><figure class="highlight plaintext"><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">dist</span><br><span class="line">node_modules</span><br></pre></td></tr></table></figure><p><strong>运行脚本</strong></p><p>package.json新增两个运行脚本</p><figure class="highlight json"><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="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;lint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint src&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;fix&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint src --fix&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h4 id="prettier配置"><a class="markdownIt-Anchor" href="#prettier配置"></a> prettier配置</h4><p>有了eslint，为什么还要有prettier？eslint针对的是javascript，他是一个检测工具，包含js语法以及少部分格式问题，在eslint看来，语法对了就能保证代码正常运行，格式问题属于其次；</p><p>而prettier属于格式化工具，它看不惯格式不统一，所以它就把eslint没干好的事接着干，另外，prettier支持包含js在内的多种语言。</p><p>总结起来，<strong>eslint和prettier这俩兄弟一个保证js代码质量，一个保证代码美观。</strong></p><p>新增.prettierrc.cjs</p><figure class="highlight js"><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="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">singleQuote</span>: <span class="literal">true</span>, <span class="comment">// 使用单引号</span></span><br><span class="line">  <span class="attr">tabWidth</span>: <span class="number">2</span>, <span class="comment">// 缩进字节数</span></span><br><span class="line">  <span class="attr">printWidth</span>: <span class="number">140</span>, <span class="comment">// 超过最大值换行</span></span><br><span class="line">  <span class="attr">htmlWhitespaceSensitivity</span>: <span class="string">&#x27;ignore&#x27;</span>, <span class="comment">//处理 HTML 文件时忽略空格敏感度,闭合标签&gt;新行问题</span></span><br><span class="line">  <span class="attr">semi</span>: <span class="literal">false</span>, <span class="comment">// 结尾不用分号</span></span><br><span class="line">  <span class="attr">useTabs</span>: <span class="literal">false</span>, <span class="comment">// 启用tab取代空格符缩进，默认为false</span></span><br><span class="line">  <span class="attr">bracketSpacing</span>: <span class="literal">true</span>, <span class="comment">// 对象大括号直接是否有空格，默认为true，效果：&#123; foo: bar &#125;</span></span><br><span class="line">  <span class="attr">trailingComma</span>: <span class="string">&#x27;es5&#x27;</span>, <span class="comment">// 每个键值对后面是否一定有尾随逗号，默认es5，保持默认即可</span></span><br><span class="line">  <span class="attr">quoteProps</span>: <span class="string">&#x27;as-needed&#x27;</span>, <span class="comment">// 给对象里的属性名是否要加上引号，默认为as-needed，即根据需要决定，如果不加引号会报错则加，否则不加</span></span><br><span class="line">  <span class="attr">arrowParens</span>: <span class="string">&#x27;avoid&#x27;</span>, <span class="comment">//箭头函数只有一个参数的时候可以忽略括号</span></span><br><span class="line">  <span class="attr">endOfLine</span>: <span class="string">&#x27;auto&#x27;</span>, <span class="comment">// 文件换行格式 LF/CRLF</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>新增.prettierignore忽略文件</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></pre></td><td class="code"><pre><span class="line">/dist/*</span><br><span class="line">/html/*</span><br><span class="line">.local</span><br><span class="line">/node_modules/**</span><br><span class="line">**/*.svg</span><br><span class="line">**/*.sh</span><br><span class="line">/public/*</span><br></pre></td></tr></table></figure><p>npm run lint去检测语法，如果出现不规范格式</p><p>npm run fix修改</p><h4 id="stylelint配置"><a class="markdownIt-Anchor" href="#stylelint配置"></a> stylelint配置</h4><p><a href="https://stylelint.io/">stylelint</a>为css的lint工具。可格式化css代码，检查css语法错误与不合理的写法，指定css书写顺序等。</p><p>我们的项目中使用scss作为预处理器，安装以下依赖：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm add sass@1.71.1 sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D</span><br></pre></td></tr></table></figure><p>新增<code>.stylelintrc.cjs</code>配置文件</p><p><strong>官网:<a href="https://stylelint.bootcss.com/">https://stylelint.bootcss.com/</a></strong></p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// @see https://stylelint.bootcss.com/</span></span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">extends</span>: [</span><br><span class="line">    <span class="string">&#x27;stylelint-config-standard&#x27;</span>, <span class="comment">// 配置stylelint拓展插件</span></span><br><span class="line">    <span class="string">&#x27;stylelint-config-html/vue&#x27;</span>, <span class="comment">// 配置 vue 中 template 样式格式化</span></span><br><span class="line">    <span class="string">&#x27;stylelint-config-standard-scss&#x27;</span>, <span class="comment">// 配置stylelint scss插件</span></span><br><span class="line">    <span class="string">&#x27;stylelint-config-recommended-vue/scss&#x27;</span>, <span class="comment">// 配置 vue 中 scss 样式格式化</span></span><br><span class="line">    <span class="string">&#x27;stylelint-config-recess-order&#x27;</span>, <span class="comment">// 配置stylelint css属性书写顺序插件,</span></span><br><span class="line">    <span class="string">&#x27;stylelint-config-prettier&#x27;</span>, <span class="comment">// 配置stylelint和prettier兼容</span></span><br><span class="line">  ],</span><br><span class="line">  <span class="attr">overrides</span>: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">files</span>: [<span class="string">&#x27;**/*.(scss|css|vue|html)&#x27;</span>],</span><br><span class="line">      <span class="attr">customSyntax</span>: <span class="string">&#x27;postcss-scss&#x27;</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="attr">files</span>: [<span class="string">&#x27;**/*.(html|vue)&#x27;</span>],</span><br><span class="line">      <span class="attr">customSyntax</span>: <span class="string">&#x27;postcss-html&#x27;</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">  <span class="attr">ignoreFiles</span>: [<span class="string">&#x27;**/*.js&#x27;</span>, <span class="string">&#x27;**/*.jsx&#x27;</span>, <span class="string">&#x27;**/*.tsx&#x27;</span>, <span class="string">&#x27;**/*.ts&#x27;</span>, <span class="string">&#x27;**/*.json&#x27;</span>, <span class="string">&#x27;**/*.md&#x27;</span>, <span class="string">&#x27;**/*.yaml&#x27;</span>],</span><br><span class="line">  <span class="comment">/**</span></span><br><span class="line"><span class="comment">   * null  =&gt; 关闭该规则</span></span><br><span class="line"><span class="comment">   * always =&gt; 必须</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  <span class="attr">rules</span>: &#123;</span><br><span class="line">    <span class="string">&#x27;value-keyword-case&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 在 css 中使用 v-bind，不报错</span></span><br><span class="line">    <span class="string">&#x27;no-descending-specificity&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器</span></span><br><span class="line">    <span class="string">&#x27;function-url-quotes&#x27;</span>: <span class="string">&#x27;always&#x27;</span>, <span class="comment">// 要求或禁止 URL 的引号 &quot;always(必须加上引号)&quot;|&quot;never(没有引号)&quot;</span></span><br><span class="line">    <span class="string">&#x27;no-empty-source&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 关闭禁止空源码</span></span><br><span class="line">    <span class="string">&#x27;selector-class-pattern&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 关闭强制选择器类名的格式</span></span><br><span class="line">    <span class="string">&#x27;property-no-unknown&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 禁止未知的属性(true 为不允许)</span></span><br><span class="line">    <span class="string">&#x27;block-opening-brace-space-before&#x27;</span>: <span class="string">&#x27;always&#x27;</span>, <span class="comment">//大括号之前必须有一个空格或不能有空白符</span></span><br><span class="line">    <span class="string">&#x27;value-no-vendor-prefix&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 关闭 属性值前缀 --webkit-box</span></span><br><span class="line">    <span class="string">&#x27;property-no-vendor-prefix&#x27;</span>: <span class="literal">null</span>, <span class="comment">// 关闭 属性前缀 -webkit-mask</span></span><br><span class="line">    <span class="string">&#x27;selector-pseudo-class-no-unknown&#x27;</span>: [</span><br><span class="line">      <span class="comment">// 不允许未知的选择器</span></span><br><span class="line">      <span class="literal">true</span>,</span><br><span class="line">      &#123;</span><br><span class="line">        <span class="attr">ignorePseudoClasses</span>: [<span class="string">&#x27;global&#x27;</span>, <span class="string">&#x27;v-deep&#x27;</span>, <span class="string">&#x27;deep&#x27;</span>], <span class="comment">// 忽略属性，修改element默认样式的时候能使用到</span></span><br><span class="line">      &#125;,</span><br><span class="line">    ],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>新增.stylelintignore忽略文件</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/node_modules/*</span><br><span class="line">/dist/*</span><br><span class="line">/html/*</span><br><span class="line">/public/*</span><br></pre></td></tr></table></figure><p>运行脚本</p><figure class="highlight json"><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="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;lint:style&quot;</span><span class="punctuation">:</span> <span class="string">&quot;stylelint src/**/*.&#123;css,scss,vue&#125; --cache --fix&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>最后配置统一的prettier来格式化我们的js和css，html代码</p><figure class="highlight json"><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="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;dev&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vite --open&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;build&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vue-tsc &amp;&amp; vite build&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;preview&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vite preview&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;clean&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npx rimraf node_modules&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;clean:cache&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npx rimraf node_modules/.cache&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;i&quot;</span><span class="punctuation">:</span> <span class="string">&quot;pnpm install&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;lint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint src&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;fix&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint src --fix&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;format&quot;</span><span class="punctuation">:</span> <span class="string">&quot;prettier --write \&quot;./**/*.&#123;html,vue,ts,js,json,md&#125;\&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;lint:eslint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;eslint src/**/*.&#123;ts,vue&#125; --cache --fix&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;lint:style&quot;</span><span class="punctuation">:</span> <span class="string">&quot;stylelint src/**/*.&#123;css,scss,vue&#125; --cache --fix&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><strong>当我们运行<code>pnpm run format</code>的时候，会把代码直接格式化</strong></p><p>tsconfig.node.json内容修改</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;compilerOptions&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;composite&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;module&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ESNext&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;moduleResolution&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Node&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;allowSyntheticDefaultImports&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;include&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;vite.config.ts&quot;</span><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>tsconfig.json改</p><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;compilerOptions&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;target&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ESNext&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;useDefineForClassFields&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;module&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ESNext&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;moduleResolution&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Node&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;strict&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;jsx&quot;</span><span class="punctuation">:</span> <span class="string">&quot;preserve&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;resolveJsonModule&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;isolatedModules&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;esModuleInterop&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;lib&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;ESNext&quot;</span><span class="punctuation">,</span> <span class="string">&quot;DOM&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;skipLibCheck&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;noEmit&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;allowJs&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;types&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;jquery&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;baseUrl&quot;</span><span class="punctuation">:</span> <span class="string">&quot;./&quot;</span><span class="punctuation">,</span> <span class="comment">// 解析非相对模块的基地址，默认是当前目录</span></span><br><span class="line">    <span class="attr">&quot;paths&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="comment">//路径映射，相对于baseUrl</span></span><br><span class="line">      <span class="attr">&quot;@/*&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;src/*&quot;</span><span class="punctuation">]</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;include&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="string">&quot;src/**/*.ts&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;src/**/*.d.ts&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;src/**/*.tsx&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;src/**/*.vue&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="string">&quot;@/typings/auto-imports.d.ts&quot;</span> <span class="comment">// vue自带的ref，watch自动引入加这个防止爆红</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;references&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;path&quot;</span><span class="punctuation">:</span> <span class="string">&quot;./tsconfig.node.json&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h4 id="husky配置"><a class="markdownIt-Anchor" href="#husky配置"></a> husky配置</h4><p>在上面我们已经集成好了我们代码校验工具，但是需要每次手动的去执行命令才会格式化我们的代码。如果有人没有格式化就提交了远程仓库中，那这个规范就没什么用。所以我们需要强制让开发人员按照代码规范来提交。</p><p>要做到这件事情，就需要利用husky在代码提交之前触发git hook(git在客户端的钩子)，然后执行<code>pnpm run format</code>来自动的格式化我们的代码。</p><p>安装<code>husky</code></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm install -D husky@8.0.0</span><br></pre></td></tr></table></figure><p>先去.gitignore文件</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><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"># Logs</span><br><span class="line">logs</span><br><span class="line">*.log</span><br><span class="line">npm-debug.log*</span><br><span class="line">yarn-debug.log*</span><br><span class="line">yarn-error.log*</span><br><span class="line">pnpm-debug.log*</span><br><span class="line">lerna-debug.log*</span><br><span class="line"></span><br><span class="line">node_modules</span><br><span class="line">dist</span><br><span class="line">dist-ssr</span><br><span class="line">*.local</span><br><span class="line"></span><br><span class="line"># Editor directories and files</span><br><span class="line"># .vscode/*  上传，里面配置结合插件用</span><br><span class="line">!.vscode/extensions.json</span><br><span class="line">.idea</span><br><span class="line">.DS_Store</span><br><span class="line">*.suo</span><br><span class="line">*.ntvs*</span><br><span class="line">*.njsproj</span><br><span class="line">*.sln</span><br><span class="line">*.sw?</span><br><span class="line"></span><br><span class="line">#自动生成</span><br><span class="line"></span><br><span class="line">src/typings/components.d.ts</span><br><span class="line">src/typings/auto-imports.d.ts</span><br></pre></td></tr></table></figure><p>去新建github仓库并同步代码，上传完毕后执行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx husky-init</span><br></pre></td></tr></table></figure><p>会在根目录下生成个一个.husky目录，在这个目录下面会有一个pre-commit文件，这个文件里面的命令在我们执行commit的时候就会执行</p><p>在<code>.husky/pre-commit</code>文件添加如下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/usr/bin/env sh</span></span><br><span class="line">. &quot;$(dirname -- &quot;$0&quot;)/_/husky.sh&quot;</span><br><span class="line"></span><br><span class="line">pnpm run format &amp;&amp; pnpm run fix</span><br><span class="line"></span><br><span class="line">git add .</span><br></pre></td></tr></table></figure><p>当我们对代码进行commit操作的时候，就会执行命令，对代码进行格式化，然后再提交。</p><h4 id="commitlint配置"><a class="markdownIt-Anchor" href="#commitlint配置"></a> commitlint配置</h4><p>对于我们的commit信息，也是有统一规范的，不能随便写，要让每个人都按照统一的标准来执行，我们可以利用<strong>commitlint</strong>来实现。</p><p>安装包</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm add @commitlint/config-conventional @commitlint/cli -D</span><br></pre></td></tr></table></figure><p>新建<code>commitlint.config.cjs</code>，然后添加下面的代码：</p><figure class="highlight js"><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 class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="attr">extends</span>: [<span class="string">&#x27;@commitlint/config-conventional&#x27;</span>],</span><br><span class="line">  <span class="comment">// 校验规则</span></span><br><span class="line">  <span class="attr">rules</span>: &#123;</span><br><span class="line">    <span class="string">&#x27;type-enum&#x27;</span>: [</span><br><span class="line">      <span class="number">2</span>,</span><br><span class="line">      <span class="string">&#x27;always&#x27;</span>,</span><br><span class="line">      [</span><br><span class="line">        <span class="string">&#x27;feat&#x27;</span>, <span class="comment">// 新功能 feature</span></span><br><span class="line">        <span class="string">&#x27;fix&#x27;</span>, <span class="comment">// 修复 bug</span></span><br><span class="line">        <span class="string">&#x27;docs&#x27;</span>, <span class="comment">// 文档注释</span></span><br><span class="line">        <span class="string">&#x27;style&#x27;</span>, <span class="comment">// 代码格式(不影响代码运行的变动)</span></span><br><span class="line">        <span class="string">&#x27;refactor&#x27;</span>, <span class="comment">// 重构(既不增加新功能，也不是修复bug)</span></span><br><span class="line">        <span class="string">&#x27;perf&#x27;</span>, <span class="comment">// 性能优化</span></span><br><span class="line">        <span class="string">&#x27;test&#x27;</span>, <span class="comment">// 增加测试</span></span><br><span class="line">        <span class="string">&#x27;chore&#x27;</span>, <span class="comment">// 构建过程或辅助工具的变动</span></span><br><span class="line">        <span class="string">&#x27;revert&#x27;</span>, <span class="comment">// 回退</span></span><br><span class="line">        <span class="string">&#x27;build&#x27;</span>, <span class="comment">// 打包</span></span><br><span class="line">      ],</span><br><span class="line">    ],</span><br><span class="line">    <span class="string">&#x27;type-case&#x27;</span>: [<span class="number">0</span>],</span><br><span class="line">    <span class="string">&#x27;type-empty&#x27;</span>: [<span class="number">0</span>],</span><br><span class="line">    <span class="string">&#x27;scope-empty&#x27;</span>: [<span class="number">0</span>],</span><br><span class="line">    <span class="string">&#x27;scope-case&#x27;</span>: [<span class="number">0</span>],</span><br><span class="line">    <span class="string">&#x27;subject-full-stop&#x27;</span>: [<span class="number">0</span>, <span class="string">&#x27;never&#x27;</span>],</span><br><span class="line">    <span class="string">&#x27;subject-case&#x27;</span>: [<span class="number">0</span>, <span class="string">&#x27;never&#x27;</span>],</span><br><span class="line">    <span class="string">&#x27;header-max-length&#x27;</span>: [<span class="number">0</span>, <span class="string">&#x27;always&#x27;</span>, <span class="number">72</span>],</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在<code>package.json</code>中配置scripts命令</p><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;commitlint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;commitlint --config commitlint.config.cjs -e -V&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>在.husky下新增commit-msg文件，删除_文件夹后</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npx husky add .husky/commit-msg</span><br></pre></td></tr></table></figure><p>内容</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/usr/bin/env sh</span></span><br><span class="line">. &quot;$(dirname -- &quot;$0&quot;)/_/husky.sh&quot;</span><br><span class="line"></span><br><span class="line">pnpm commitlint</span><br></pre></td></tr></table></figure><p>当我们commit提交信息时，就不能再随意写了，必须是git commit -m 'fix: xxx’符合类型的才可以，<strong>需要注意的是类型的后面需要用英文的:，并且冒号后面是需要空一格的，这个是不能省略的</strong></p><h4 id="强制pnpm包管理"><a class="markdownIt-Anchor" href="#强制pnpm包管理"></a> 强制pnpm包管理</h4><p>团队开发项目的时候，需要统一包管理器工具,因为不同包管理器工具下载同一个依赖,可能版本不一样,导致项目出现bug问题,因此包管理器工具需要统一管理！！！</p><p>在根目录创建<code>scritps/preinstall.js</code>文件，添加下面的内容</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> (!<span class="regexp">/pnpm/</span>.<span class="title function_">test</span>(process.<span class="property">env</span>.<span class="property">npm_execpath</span> || <span class="string">&#x27;&#x27;</span>)) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">warn</span>(<span class="string">`[33mThis repository must using pnpm as the package manager `</span> + <span class="string">` for scripts to work properly.[39m\n`</span>)</span><br><span class="line">  process.<span class="title function_">exit</span>(<span class="number">1</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>配置命令</p><figure class="highlight json"><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="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;preinstall&quot;</span><span class="punctuation">:</span> <span class="string">&quot;node ./scripts/preinstall.js&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><strong>当我们使用npm或者yarn来安装包的时候，就会报错了。原理就是在install的时候会触发preinstall（npm提供的生命周期钩子）这个文件里面的代码。</strong></p><h2 id="2-项目集成"><a class="markdownIt-Anchor" href="#2-项目集成"></a> 2、项目集成</h2><h3 id="集成element-plus"><a class="markdownIt-Anchor" href="#集成element-plus"></a> 集成element-plus</h3><p>硅谷甄选运营平台,UI组件库采用的element-plus，因此需要集成element-plus插件！！！</p><p>官网地址:<a href="https://element-plus.gitee.io/zh-CN/">https://element-plus.gitee.io/zh-CN/</a></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm install element-plus@2.5.6 @element-plus/icons-vue@2.3.1</span><br></pre></td></tr></table></figure><p><strong>入口文件main.ts全局安装element-plus,element-plus默认支持语言英语设置为中文</strong></p><figure class="highlight js"><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 class="keyword">import</span> <span class="title class_">ElementPlus</span> <span class="keyword">from</span> <span class="string">&#x27;element-plus&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;element-plus/dist/index.css&#x27;</span></span><br><span class="line"><span class="comment">//@ts-ignore忽略当前文件ts类型的检测否则有红色提示(打包会失败)</span></span><br><span class="line"><span class="keyword">import</span> zhCn <span class="keyword">from</span> <span class="string">&#x27;element-plus/dist/locale/zh-cn.mjs&#x27;</span></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title class_">ElementPlus</span>, &#123;</span><br><span class="line">  <span class="attr">locale</span>: zhCn,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><p><strong>Element Plus全局组件类型声明</strong></p><figure class="highlight json"><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 class="comment">// tsconfig.json</span></span><br><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;compilerOptions&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">    <span class="attr">&quot;types&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;element-plus/global&quot;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>配置完毕可以测试element-plus组件与图标的使用。</p><h3 id="src别名的配置"><a class="markdownIt-Anchor" href="#src别名的配置"></a> src别名的配置</h3><p>在开发项目的时候文件与文件关系可能很复杂，因此我们需要给src文件夹配置一个别名！！！</p><figure class="highlight js"><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="comment">// vite.config.ts</span></span><br><span class="line"><span class="keyword">import</span> &#123; defineConfig &#125; <span class="keyword">from</span> <span class="string">&#x27;vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> vue <span class="keyword">from</span> <span class="string">&#x27;@vitejs/plugin-vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">&#x27;path&#x27;</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">defineConfig</span>(&#123;</span><br><span class="line">  <span class="attr">plugins</span>: [<span class="title function_">vue</span>()],</span><br><span class="line">  <span class="attr">resolve</span>: &#123;</span><br><span class="line">    <span class="attr">alias</span>: &#123;</span><br><span class="line">      <span class="string">&#x27;@&#x27;</span>: path.<span class="title function_">resolve</span>(<span class="string">&#x27;./src&#x27;</span>), <span class="comment">// 相对路径别名配置，使用 @ 代替 src</span></span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h3 id="环境变量的配置"><a class="markdownIt-Anchor" href="#环境变量的配置"></a> 环境变量的配置</h3><p><strong>项目开发过程中，至少会经历开发环境、测试环境和生产环境(即正式环境)三个阶段。不同阶段请求的状态(如接口地址等)不尽相同，若手动切换接口地址是相当繁琐且易出错的。于是环境变量配置的需求就应运而生，我们只需做简单的配置，把环境状态切换的工作交给代码。</strong></p><ul><li><p><strong>开发环境（development）</strong>：顾名思义，开发使用的环境，每位开发人员在自己的dev分支上干活，开发到一定程度，同事会合并代码，进行联调。</p></li><li><p><strong>测试环境（testing）</strong>：测试同事干活的环境啦，一般会由测试同事自己来部署，然后在此环境进行测试</p></li><li><p><strong>生产环境（production）</strong>：生产环境是指正式提供对外服务的，一般会关掉错误报告，打开错误日志。(正式提供给客户使用的环境。)</p></li></ul><p>注意:一般情况下，一个环境对应一台服务器,也有的公司开发与测试环境是一台服务器！！！</p><p>项目根目录分别添加开发、生产和测试环境的文件!</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">.env.development</span><br><span class="line">.env.production</span><br><span class="line">.env.test</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></pre></td><td class="code"><pre><span class="line"># 变量必须以 VITE_ 为前缀才能暴露给外部读取</span><br><span class="line">NODE_ENV = &#x27;development&#x27;</span><br><span class="line">VITE_APP_TITLE = &#x27;硅谷甄选运营平台&#x27;</span><br><span class="line">VITE_APP_BASE_API = &#x27;/dev-api&#x27;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">NODE_ENV = &#x27;production&#x27;</span><br><span class="line">VITE_APP_TITLE = &#x27;硅谷甄选运营平台&#x27;</span><br><span class="line">VITE_APP_BASE_API = &#x27;/prod-api&#x27;</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 变量必须以 VITE_ 为前缀才能暴露给外部读取</span><br><span class="line">NODE_ENV = &#x27;test&#x27;</span><br><span class="line">VITE_APP_TITLE = &#x27;硅谷甄选运营平台&#x27;</span><br><span class="line">VITE_APP_BASE_API = &#x27;/test-api&#x27;</span><br></pre></td></tr></table></figure><p>通过import.meta.env获取环境变量</p><h3 id="svg图标配置"><a class="markdownIt-Anchor" href="#svg图标配置"></a> SVG图标配置</h3><p>在开发项目的时候经常会用到svg矢量图,而且我们使用SVG以后，页面上加载的不再是图片资源,</p><p>这对页面性能来说是个很大的提升，而且我们SVG文件比img要小的很多，放在项目中几乎不占用资源。</p><p><strong>安装各种插件</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm install vite-plugin-svg-icons@2.0.1 -D unplugin-auto-import@0.17.5 unocss@0.58.5 unplugin-icons@0.18.5 unplugin-vue-components@0.26.0 mockjs@1.1.0 vite-plugin-mock@2.9.6 vite-plugin-progress@0.0.7 @intlify/unplugin-vue-i18n@2.0.0</span><br></pre></td></tr></table></figure><p><strong>在<code>vite.config.ts</code>中配置插件</strong></p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; resolve &#125; <span class="keyword">from</span> <span class="string">&#x27;path&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; defineConfig, loadEnv &#125; <span class="keyword">from</span> <span class="string">&#x27;vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> vue <span class="keyword">from</span> <span class="string">&#x27;@vitejs/plugin-vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> path <span class="keyword">from</span> <span class="string">&#x27;path&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">UnoCSS</span> <span class="keyword">from</span> <span class="string">&#x27;unocss/vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">AutoImport</span> <span class="keyword">from</span> <span class="string">&#x27;unplugin-auto-import/vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">ElementPlusResolver</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;unplugin-vue-components/resolvers&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; viteMockServe &#125; <span class="keyword">from</span> <span class="string">&#x27;vite-plugin-mock&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; createSvgIconsPlugin &#125; <span class="keyword">from</span> <span class="string">&#x27;vite-plugin-svg-icons&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Components</span> <span class="keyword">from</span> <span class="string">&#x27;unplugin-vue-components/vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Icons</span> <span class="keyword">from</span> <span class="string">&#x27;unplugin-icons/vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> progress <span class="keyword">from</span> <span class="string">&#x27;vite-plugin-progress&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">VueI18</span>nPlugin <span class="keyword">from</span> <span class="string">&#x27;@intlify/unplugin-vue-i18n/vite&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">IconsResolver</span> <span class="keyword">from</span> <span class="string">&#x27;unplugin-icons/resolver&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> pathSrc = path.<span class="title function_">resolve</span>(__dirname, <span class="string">&#x27;src&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="title function_">defineConfig</span>(<span class="function">(<span class="params">&#123; command, mode &#125;</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="comment">//获取各种环境下的对应的变量</span></span><br><span class="line">  <span class="keyword">let</span> env = <span class="title function_">loadEnv</span>(mode, process.<span class="title function_">cwd</span>())</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="attr">base</span>: <span class="string">&#x27;/&#x27;</span>, <span class="comment">// 在生产中服务时的基本公共路径</span></span><br><span class="line">    <span class="attr">publicDir</span>: <span class="string">&#x27;public&#x27;</span>, <span class="comment">// 静态资源服务的文件夹, 默认&quot;public&quot;</span></span><br><span class="line">    <span class="attr">build</span>: &#123;</span><br><span class="line">      <span class="attr">outDir</span>: <span class="string">&#x27;dist&#x27;</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">//--------------------------------------</span></span><br><span class="line">    <span class="attr">resolve</span>: &#123;</span><br><span class="line">      <span class="attr">alias</span>: &#123;</span><br><span class="line">        <span class="string">&#x27;@&#x27;</span>: pathSrc, <span class="comment">// 相对路径别名配置，使用 @ 代替 src</span></span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">//--------------------------------------</span></span><br><span class="line">    <span class="attr">css</span>: &#123;</span><br><span class="line">      <span class="comment">// CSS 预处理器,全局的scss格式如下往下面加即可</span></span><br><span class="line">      <span class="attr">preprocessorOptions</span>: &#123;</span><br><span class="line">        <span class="attr">scss</span>: &#123;</span><br><span class="line">          <span class="attr">javascriptEnabled</span>: <span class="literal">true</span>,</span><br><span class="line">          <span class="attr">additionalData</span>: <span class="string">`</span></span><br><span class="line"><span class="string">              @use &quot;./src/styles/variable.scss&quot; as * ;</span></span><br><span class="line"><span class="string">              @use &#x27;@/styles/ff-cloud/index.scss&#x27; as *;</span></span><br><span class="line"><span class="string">              `</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">//---------------------------------------</span></span><br><span class="line">    <span class="attr">plugins</span>: [</span><br><span class="line">      <span class="title function_">vue</span>(),</span><br><span class="line">      <span class="title function_">progress</span>(&#123;</span><br><span class="line">        <span class="attr">format</span>: <span class="string">&#x27;Building :bar :percent&#x27;</span>,</span><br><span class="line">        <span class="attr">total</span>: <span class="number">200</span>,</span><br><span class="line">        <span class="attr">width</span>: <span class="number">60</span>,</span><br><span class="line">        <span class="attr">complete</span>: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">        <span class="attr">incomplete</span>: <span class="string">&#x27;&#x27;</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="title class_">UnoCSS</span>(&#123;&#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title class_">AutoImport</span>(&#123;</span><br><span class="line">        <span class="comment">// 自动导入 Vue 相关函数，如：ref, reactive, toRef 等</span></span><br><span class="line">        <span class="attr">imports</span>: [</span><br><span class="line">          <span class="string">&#x27;vue&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;@vueuse/core&#x27;</span>,</span><br><span class="line">          <span class="string">&#x27;vue-router&#x27;</span>,</span><br><span class="line">          &#123;</span><br><span class="line">            <span class="string">&#x27;@/hooks/web/useMessage&#x27;</span>: [<span class="string">&#x27;useMessage&#x27;</span>], <span class="comment">//这样每个vue页都导入</span></span><br><span class="line">          &#125;,</span><br><span class="line">        ],</span><br><span class="line">        <span class="comment">// dts: &#x27;/auto-import.d.ts&#x27;,</span></span><br><span class="line">        <span class="attr">eslintrc</span>: &#123;</span><br><span class="line">          <span class="attr">enabled</span>: <span class="literal">false</span>, <span class="comment">//  Default `false`</span></span><br><span class="line">          <span class="attr">filepath</span>: <span class="string">&#x27;./.eslintrc-auto-import.json&#x27;</span>, <span class="comment">// Default `./.eslintrc-auto-import.json`</span></span><br><span class="line">          <span class="attr">globalsPropValue</span>: <span class="literal">true</span>, <span class="comment">// Default `true`, (true | false | &#x27;readonly&#x27; | &#x27;readable&#x27; | &#x27;writable&#x27; | &#x27;writeable&#x27;)</span></span><br><span class="line">        &#125;,</span><br><span class="line">        <span class="attr">resolvers</span>: [</span><br><span class="line">          <span class="comment">// 自动导入 Element Plus 相关函数，如：ElMessage, ElMessageBox... (带样式)</span></span><br><span class="line">          <span class="title class_">ElementPlusResolver</span>(&#123;</span><br><span class="line">            <span class="attr">importStyle</span>: <span class="string">&#x27;sass&#x27;</span>,</span><br><span class="line">          &#125;),</span><br><span class="line">          <span class="title class_">IconsResolver</span>(&#123;</span><br><span class="line">            <span class="attr">prefix</span>: <span class="string">&#x27;Icon&#x27;</span>,</span><br><span class="line">          &#125;), <span class="comment">// 自动导入图标组件</span></span><br><span class="line">        ],</span><br><span class="line">        <span class="attr">vueTemplate</span>: <span class="literal">true</span>, <span class="comment">// 是否在 vue 模板中自动导入</span></span><br><span class="line">        <span class="attr">dts</span>: path.<span class="title function_">resolve</span>(pathSrc, <span class="string">&#x27;typings&#x27;</span>, <span class="string">&#x27;auto-imports.d.ts&#x27;</span>), <span class="comment">//自动导包的存放路径</span></span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title class_">Components</span>(&#123;</span><br><span class="line">        <span class="attr">resolvers</span>: [</span><br><span class="line">          <span class="title class_">IconsResolver</span>(&#123;</span><br><span class="line">            <span class="attr">enabledCollections</span>: [<span class="string">&#x27;ep&#x27;</span>], <span class="comment">//@iconify-json/ep 是 Element Plus 的图标库</span></span><br><span class="line">          &#125;),</span><br><span class="line">          <span class="title class_">ElementPlusResolver</span>(), <span class="comment">// 自动导入 Element Plus 组件</span></span><br><span class="line">        ],</span><br><span class="line">        <span class="comment">// dirs: [&#x27;src/components&#x27;], //自动导入这个目录下的组件.下面这个也会包含这个</span></span><br><span class="line">        <span class="attr">dts</span>: path.<span class="title function_">resolve</span>(pathSrc, <span class="string">&#x27;typings&#x27;</span>, <span class="string">&#x27;components.d.ts&#x27;</span>),</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title class_">Icons</span>(&#123;</span><br><span class="line">        <span class="attr">autoInstall</span>: <span class="literal">true</span>, <span class="comment">// 自动安装图标库</span></span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title class_">VueI18</span>nPlugin(&#123;</span><br><span class="line">        <span class="attr">runtimeOnly</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">compositionOnly</span>: <span class="literal">true</span>,</span><br><span class="line">        <span class="attr">include</span>: [<span class="title function_">resolve</span>(__dirname, <span class="string">&#x27;src/locales/**&#x27;</span>)],</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title function_">createSvgIconsPlugin</span>(&#123;</span><br><span class="line">        <span class="comment">// 阿里icon就放icons下了</span></span><br><span class="line">        <span class="attr">iconDirs</span>: [path.<span class="title function_">resolve</span>(process.<span class="title function_">cwd</span>(), <span class="string">&#x27;src/assets/icons&#x27;</span>)],</span><br><span class="line">        <span class="attr">symbolId</span>: <span class="string">&#x27;icon-[dir]-[name]&#x27;</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="comment">//---------------------------------------</span></span><br><span class="line">      <span class="title function_">viteMockServe</span>(&#123;</span><br><span class="line">        <span class="attr">localEnabled</span>: command === <span class="string">&#x27;serve&#x27;</span>, <span class="comment">//保证开发阶段可以使用mock接口</span></span><br><span class="line">        <span class="comment">// localEnabled: false, //开发关闭</span></span><br><span class="line">        <span class="attr">prodEnabled</span>: <span class="literal">true</span>, <span class="comment">//mock生产接口开关</span></span><br><span class="line">      &#125;),</span><br><span class="line">    ],</span><br><span class="line">    <span class="comment">//代理跨域</span></span><br><span class="line">    <span class="attr">server</span>: &#123;</span><br><span class="line">      <span class="attr">port</span>: <span class="number">8000</span>,</span><br><span class="line">      <span class="attr">proxy</span>: &#123;</span><br><span class="line">        [env.<span class="property">VITE_APP_BASE_API</span>]: &#123;</span><br><span class="line">          <span class="comment">//获取数据的服务器地址设置</span></span><br><span class="line">          <span class="attr">target</span>: env.<span class="property">VITE_SERVE</span>,</span><br><span class="line">          <span class="comment">//需要代理跨域</span></span><br><span class="line">          <span class="attr">changeOrigin</span>: <span class="literal">true</span>,</span><br><span class="line">          <span class="comment">//路径重写</span></span><br><span class="line">          <span class="attr">rewrite</span>: <span class="function">(<span class="params">path</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> path.<span class="title function_">replace</span>(<span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">&#x27;^&#x27;</span> + env.<span class="property">VITE_APP_BASE_API</span>), <span class="string">&#x27;&#x27;</span>)</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">        [env.<span class="property">VITE_APP_BASE_API_YZM</span>]: &#123;</span><br><span class="line">          <span class="comment">//获取数据的服务器地址设置</span></span><br><span class="line">          <span class="attr">target</span>: env.<span class="property">VITE_SERVE_YZM</span>,</span><br><span class="line">          <span class="comment">//需要代理跨域</span></span><br><span class="line">          <span class="attr">changeOrigin</span>: <span class="literal">true</span>,</span><br><span class="line">          <span class="comment">//路径重写</span></span><br><span class="line">          <span class="attr">rewrite</span>: <span class="function">(<span class="params">path</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> path.<span class="title function_">replace</span>(<span class="keyword">new</span> <span class="title class_">RegExp</span>(<span class="string">&#x27;^&#x27;</span> + env.<span class="property">VITE_APP_BASE_API_YZM</span>), <span class="string">&#x27;&#x27;</span>)</span><br><span class="line">          &#125;,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">optimizeDeps</span>: &#123;</span><br><span class="line">      <span class="attr">include</span>: [</span><br><span class="line">        <span class="string">&#x27;vue&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;vue-router&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;pinia&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;axios&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/utils/index.mjs&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/form/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/form-item/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/button/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/input/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/input-number/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/switch/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/upload/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/menu/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/col/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/icon/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/row/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/tag/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/dialog/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/loading/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/radio/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/radio-group/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/popover/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/scrollbar/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/tooltip/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/dropdown/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/dropdown-menu/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/dropdown-item/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/sub-menu/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/menu-item/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/divider/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/card/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/link/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/breadcrumb/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/breadcrumb-item/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/table/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/tree-select/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/table-column/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/select/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/option/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/pagination/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/tree/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;element-plus/es/components/alert/style/css&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;@vueuse/core&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;echarts&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;vue-i18n&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;jquery&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;lodash-es&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;nprogress&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;dayjs&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;sass&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;qs&#x27;</span>,</span><br><span class="line">      ],</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h4 id="svg封装为全局组件"><a class="markdownIt-Anchor" href="#svg封装为全局组件"></a> svg封装为全局组件</h4><p>因为项目很多模块需要使用图标,因此把它封装为全局组件！！！</p><p><strong>在src/components目录下创建一个SvgIcon组件:代表如下</strong></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><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></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  &lt;div&gt;</span><br><span class="line">    &lt;svg :style=&quot;&#123; width: width, height: height &#125;&quot;&gt;</span><br><span class="line">      &lt;use :xlink:href=&quot;prefix + name&quot; :fill=&quot;color&quot;&gt;&lt;/use&gt;</span><br><span class="line">    &lt;/svg&gt;</span><br><span class="line">  &lt;/div&gt;</span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line">&lt;script setup lang=&quot;ts&quot;&gt;</span><br><span class="line">defineProps(&#123;</span><br><span class="line">  //xlink:href属性值的前缀</span><br><span class="line">  prefix: &#123;</span><br><span class="line">    type: String,</span><br><span class="line">    default: &#x27;#icon-&#x27;,</span><br><span class="line">  &#125;,</span><br><span class="line">  //svg矢量图的名字</span><br><span class="line">  name: String,</span><br><span class="line">  //svg图标的颜色</span><br><span class="line">  color: &#123;</span><br><span class="line">    type: String,</span><br><span class="line">    default: &#x27;&#x27;,</span><br><span class="line">  &#125;,</span><br><span class="line">  //svg宽度</span><br><span class="line">  width: &#123;</span><br><span class="line">    type: String,</span><br><span class="line">    default: &#x27;16px&#x27;,</span><br><span class="line">  &#125;,</span><br><span class="line">  //svg高度</span><br><span class="line">  height: &#123;</span><br><span class="line">    type: String,</span><br><span class="line">    default: &#x27;16px&#x27;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;)</span><br><span class="line">&lt;/script&gt;</span><br><span class="line">&lt;style scoped&gt;&lt;/style&gt;</span><br></pre></td></tr></table></figure><p>在src文件夹目录下创建一个index.ts文件：用于注册components文件夹内部全部全局组件！！！</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="title class_">SvgIcon</span> <span class="keyword">from</span> <span class="string">&#x27;./SvgIcon/index.vue&#x27;</span>;</span><br><span class="line"><span class="keyword">import</span> type &#123; <span class="title class_">App</span>, <span class="title class_">Component</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="attr">components</span>: &#123; [<span class="attr">name</span>: string]: <span class="title class_">Component</span> &#125; = &#123; <span class="title class_">SvgIcon</span> &#125;;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">    <span class="title function_">install</span>(<span class="params">app: App</span>) &#123;</span><br><span class="line">        <span class="title class_">Object</span>.<span class="title function_">keys</span>(components).<span class="title function_">forEach</span>(<span class="function">(<span class="params">key: string</span>) =&gt;</span> &#123;</span><br><span class="line">            app.<span class="title function_">component</span>(key, components[key]);</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在入口文件引入src/index.ts文件,通过app.use方法安装自定义插件</p><figure class="highlight js"><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="keyword">import</span> gloablComponent <span class="keyword">from</span> <span class="string">&#x27;./components/index&#x27;</span></span><br><span class="line">app.<span class="title function_">use</span>(gloablComponent)</span><br></pre></td></tr></table></figure><h3 id="集成sass"><a class="markdownIt-Anchor" href="#集成sass"></a> 集成sass</h3><p>我们目前在组件内部已经可以使用scss样式,因为在配置styleLint工具的时候，项目当中已经安装过sass sass-loader,因此我们再组件内可以使用scss语法！！！需要加上lang=“scss”</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;style scoped lang=&quot;scss&quot;&gt;&lt;/style&gt;</span><br></pre></td></tr></table></figure><p>接下来我们为项目添加一些全局的样式</p><p>在src/styles目录下创建一个index.scss文件，当然项目中需要用到清除默认样式，因此在index.scss引入reset.scss</p><figure class="highlight scss"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">@import</span> reset.scss;</span><br></pre></td></tr></table></figure><p>在入口文件引入</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> <span class="string">&#x27;@/styles&#x27;</span></span><br></pre></td></tr></table></figure><p>但是你会发现在src/styles/index.scss全局样式文件中没有办法使用<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>变量</mtext><mi mathvariant="normal">.</mi><mtext>因此需要给项目中引入全局变量</mtext></mrow><annotation encoding="application/x-tex">变量.因此需要给项目中引入全局变量</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.68333em;vertical-align:0em;"></span><span class="mord cjk_fallback">变</span><span class="mord cjk_fallback">量</span><span class="mord">.</span><span class="mord cjk_fallback">因</span><span class="mord cjk_fallback">此</span><span class="mord cjk_fallback">需</span><span class="mord cjk_fallback">要</span><span class="mord cjk_fallback">给</span><span class="mord cjk_fallback">项</span><span class="mord cjk_fallback">目</span><span class="mord cjk_fallback">中</span><span class="mord cjk_fallback">引</span><span class="mord cjk_fallback">入</span><span class="mord cjk_fallback">全</span><span class="mord cjk_fallback">局</span><span class="mord cjk_fallback">变</span><span class="mord cjk_fallback">量</span></span></span></span>。</p><p>在style/variable.scss创建一个variable.scss文件！</p><p>在vite.config.ts文件配置如下:</p><figure class="highlight js"><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="keyword">export</span> <span class="keyword">default</span> <span class="title function_">defineConfig</span>(<span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="attr">css</span>: &#123;</span><br><span class="line">      <span class="attr">preprocessorOptions</span>: &#123;</span><br><span class="line">        <span class="attr">scss</span>: &#123;</span><br><span class="line">          <span class="attr">javascriptEnabled</span>: <span class="literal">true</span>,</span><br><span class="line">          <span class="attr">additionalData</span>: <span class="string">&#x27;@import &quot;./src/styles/variable.scss&quot;;&#x27;</span>,</span><br><span class="line">        &#125;,</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;,</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong><code>@import &quot;./src/styles/variable.less&quot;;</code>后面的<code>;</code>不要忘记，不然会报错</strong>!</p><p>配置完毕你会发现scss提供这些全局变量可以在组件样式中使用了！！！</p><p><strong>安装axios</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm install axios@1.6.7</span><br></pre></td></tr></table></figure><p>最后通过axios测试接口！！！</p><h3 id="axios二次封装"><a class="markdownIt-Anchor" href="#axios二次封装"></a> axios二次封装</h3><p>在开发项目的时候避免不了与后端进行交互,因此我们需要使用axios插件实现发送网络请求。在开发项目的时候我们经常会把axios进行二次封装。</p><p>目的:</p><ul><li>使用请求拦截器，可以在请求拦截器中处理一些业务(开始进度条、请求头携带公共参数)</li><li>使用响应拦截器，可以在响应拦截器中处理一些业务(进度条结束、简化服务器返回的数据、处理http网络错误)</li></ul><p>在根目录下创建utils/request.ts</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&#x27;axios&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; <span class="title class_">ElMessage</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;element-plus&#x27;</span></span><br><span class="line"><span class="comment">//创建axios实例</span></span><br><span class="line"><span class="keyword">let</span> request = axios.<span class="title function_">create</span>(&#123;</span><br><span class="line">  <span class="attr">baseURL</span>: <span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">env</span>.<span class="property">VITE_APP_BASE_API</span>,</span><br><span class="line">  <span class="attr">timeout</span>: <span class="number">5000</span>,</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//请求拦截器</span></span><br><span class="line">request.<span class="property">interceptors</span>.<span class="property">request</span>.<span class="title function_">use</span>(<span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> config</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//响应拦截器</span></span><br><span class="line">request.<span class="property">interceptors</span>.<span class="property">response</span>.<span class="title function_">use</span>(</span><br><span class="line">  <span class="function">(<span class="params">response</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> response.<span class="property">data</span></span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">//处理网络错误</span></span><br><span class="line">    <span class="keyword">let</span> msg = <span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">let</span> status = error.<span class="property">response</span>.<span class="property">status</span></span><br><span class="line">    <span class="keyword">switch</span> (status) &#123;</span><br><span class="line">      <span class="keyword">case</span> <span class="number">401</span>:</span><br><span class="line">        msg = <span class="string">&#x27;token过期&#x27;</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">      <span class="keyword">case</span> <span class="number">403</span>:</span><br><span class="line">        msg = <span class="string">&#x27;无权访问&#x27;</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">      <span class="keyword">case</span> <span class="number">404</span>:</span><br><span class="line">        msg = <span class="string">&#x27;请求地址错误&#x27;</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">      <span class="keyword">case</span> <span class="number">500</span>:</span><br><span class="line">        msg = <span class="string">&#x27;服务器出现问题&#x27;</span></span><br><span class="line">        <span class="keyword">break</span></span><br><span class="line">      <span class="attr">default</span>:</span><br><span class="line">        msg = <span class="string">&#x27;无网络&#x27;</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="title class_">ElMessage</span>(&#123;</span><br><span class="line">      <span class="attr">type</span>: <span class="string">&#x27;error&#x27;</span>,</span><br><span class="line">      <span class="attr">message</span>: msg,</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(error)</span><br><span class="line">  &#125;,</span><br><span class="line">)</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> request</span><br></pre></td></tr></table></figure><h3 id="api接口统一管理"><a class="markdownIt-Anchor" href="#api接口统一管理"></a> API接口统一管理</h3><p>在开发项目的时候,接口可能很多需要统一管理。在src目录下去创建api文件夹去统一管理项目的接口；</p><p>比如:下面方式</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">//统一管理咱们项目用户相关的接口</span></span><br><span class="line"><span class="keyword">import</span> request <span class="keyword">from</span> <span class="string">&#x27;@/utils/request&#x27;</span></span><br><span class="line"><span class="keyword">import</span> type &#123;</span><br><span class="line">  loginFormData,</span><br><span class="line">  loginResponseData,</span><br><span class="line">  userInfoResponseData,</span><br><span class="line">&#125; <span class="keyword">from</span> <span class="string">&#x27;./type&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//项目用户相关的请求地址</span></span><br><span class="line">enum <span class="variable constant_">API</span> &#123;</span><br><span class="line">  <span class="variable constant_">LOGIN_URL</span> = <span class="string">&#x27;/admin/acl/index/login&#x27;</span>,</span><br><span class="line">  <span class="variable constant_">USERINFO_URL</span> = <span class="string">&#x27;/admin/acl/index/info&#x27;</span>,</span><br><span class="line">  <span class="variable constant_">LOGOUT_URL</span> = <span class="string">&#x27;/admin/acl/index/logout&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//登录接口</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">reqLogin</span> = (<span class="params">data: loginFormData</span>) =&gt;</span><br><span class="line">  request.<span class="property">post</span>&lt;any, loginResponseData&gt;(<span class="variable constant_">API</span>.<span class="property">LOGIN_URL</span>, data)</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取用户信息</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">reqUserInfo</span> = (<span class="params"></span>) =&gt;</span><br><span class="line">  request.<span class="property">get</span>&lt;any, userInfoResponseData&gt;(<span class="variable constant_">API</span>.<span class="property">USERINFO_URL</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//退出登录</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title function_">reqLogout</span> = (<span class="params"></span>) =&gt; request.<span class="property">post</span>&lt;any, any&gt;(<span class="variable constant_">API</span>.<span class="property">LOGOUT_URL</span>)</span><br></pre></td></tr></table></figure><h2 id="3-补充"><a class="markdownIt-Anchor" href="#3-补充"></a> 3、补充</h2><h3 id="常用依赖安装"><a class="markdownIt-Anchor" href="#常用依赖安装"></a> 常用依赖安装</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">自动导入的vue里的ref watch 等</span></span><br><span class="line">pnpm i -D unplugin-auto-import</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">自动引入组件 少了import &#123;&#125;...</span></span><br><span class="line">pnpm i unplugin-vue-components -D</span><br><span class="line"></span><br><span class="line">pnpm i unplugin-icons -D</span><br><span class="line"></span><br><span class="line">pnpm i @vueuse/core@4.9.0 lodash-es pinia@2.1.7 vue-router@4.3.0 vue-i18n@9.10.1</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">进度条</span></span><br><span class="line">pnpm i nprogress</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">打包进度条</span></span><br><span class="line">pnpm i vite-plugin-progress -D</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">带颜色</span></span><br><span class="line">pnpm i picocolors -D</span><br><span class="line"></span><br><span class="line">pnpm i moment</span><br><span class="line"></span><br><span class="line">pnpm i copy-to-clipboard</span><br><span class="line"></span><br><span class="line">pnpm i echarts@5.2.2</span><br></pre></td></tr></table></figure><p>参考链接: <a href="https://www.jb51.net/article/252596.htm">https://www.jb51.net/article/252596.htm</a></p>]]></content>
    
    
    <summary type="html">学而不思则罔，思而不学则殆</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://luckynwa.top/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>Vite项目中引入文件与jQuery的方法</title>
    <link href="https://luckynwa.top/posts/front10/"/>
    <id>https://luckynwa.top/posts/front10/</id>
    <published>2025-02-03T00:37:32.000Z</published>
    <updated>2026-07-07T16:19:34.062Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>在 Vite 构建的 Vue3 项目中，没有 require 命令去动态引入本地图片，本文提供相应的解决方案。</p><h2 id="引入图片方法"><a class="markdownIt-Anchor" href="#引入图片方法"></a> 引入图片方法</h2><h3 id="方式一静态引入"><a class="markdownIt-Anchor" href="#方式一静态引入"></a> 方式一：静态引入</h3><p>无法动态引入，适用于固定图片。</p><figure class="highlight html"><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 class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">img</span> <span class="attr">:src</span>=<span class="string">&quot;emptyImage&quot;</span> <span class="attr">class</span>=<span class="string">&quot;h-50 w-50&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">setup</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">import</span> emptyImage <span class="keyword">from</span> <span class="string">&#x27;@/assets/home/yd_4.png&#x27;</span></span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="方式二动态引入"><a class="markdownIt-Anchor" href="#方式二动态引入"></a> 方式二：动态引入</h3><p>使用 <code>new URL</code> 配合 <code>import.meta.url</code> 实现动态引入，支持 <code>v-for</code> 获取动态路径。</p><figure class="highlight html"><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="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">img</span> <span class="attr">:src</span>=<span class="string">&quot;getFilePath(&#x27;yd_4.png&#x27;)&quot;</span> /&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">setup</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">const</span> <span class="title function_">getFilePath</span> = (<span class="params">url: string</span>) =&gt; &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">let</span> imgH = <span class="keyword">new</span> <span class="title function_">URL</span>(<span class="string">`/src/assets/home/<span class="subst">$&#123;url&#125;</span>`</span>, <span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">url</span>).<span class="property">href</span></span></span><br><span class="line"><span class="language-javascript">    <span class="keyword">return</span> imgH</span></span><br><span class="line"><span class="language-javascript">  &#125;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="芋道框架解决方案"><a class="markdownIt-Anchor" href="#芋道框架解决方案"></a> 芋道框架解决方案</h3><p>在芋道框架中使用上面的方案会出现 <code>undefined</code>，因为 <code>import.meta.url</code> 返回的是包含查询参数的完整 URL，可能导致路径拼接错误。</p><p><strong>解决方案：</strong> 使用 <code>window.location</code> 获取当前页面的 URL 路径。</p><figure class="highlight javascript"><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="title function_">getFilePath</span>(<span class="params">url</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> img = <span class="keyword">new</span> <span class="title function_">URL</span>(<span class="string">`/src/assets/images/<span class="subst">$&#123;url&#125;</span>`</span>, <span class="variable language_">window</span>.<span class="property">location</span>.<span class="property">href</span>).<span class="property">href</span>;</span><br><span class="line">  <span class="keyword">return</span> img;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="引入-jquery"><a class="markdownIt-Anchor" href="#引入-jquery"></a> 引入 jQuery</h2><p>Vue2 项目由于第三方验证码组件需要 jQuery。</p><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i jquery -S</span><br></pre></td></tr></table></figure><h3 id="全局声明mainjs"><a class="markdownIt-Anchor" href="#全局声明mainjs"></a> 全局声明（main.js）</h3><figure class="highlight javascript"><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="keyword">import</span> $ <span class="keyword">from</span> <span class="string">&#x27;jquery&#x27;</span> <span class="comment">// 本地有也可以这样：import $ from &#x27;@/assets/captcha/js/jquery.min.js&#x27;</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">jQuery</span> = $</span><br><span class="line"><span class="variable language_">window</span>.<span class="property">$</span> = $</span><br></pre></td></tr></table></figure><p>声明完成后就可以直接全局使用了。</p><h3 id="验证是否成功"><a class="markdownIt-Anchor" href="#验证是否成功"></a> 验证是否成功</h3><p>新建一个 Vue 文件，打印 jQuery 对象即可验证。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(jQuery)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">知之者不如好之者，好之者不如乐之者</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Vue" scheme="https://luckynwa.top/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>双Token机制与OAuth2单点登录实战指南</title>
    <link href="https://luckynwa.top/posts/java8/"/>
    <id>https://luckynwa.top/posts/java8/</id>
    <published>2025-01-18T16:53:54.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h1 id="双-token"><a class="markdownIt-Anchor" href="#双-token"></a> 双 Token</h1><h2 id="什么是-token"><a class="markdownIt-Anchor" href="#什么是-token"></a> 什么是 Token</h2><p>Token（令牌）是在网络通信中用于验证身份和授权访问的一种机制。它是一串随机生成的字符串，用于标识用户的身份信息和权限。服务器可以根据令牌对用户进行身份鉴别，确保请求的合法性。令牌可以包含用户的权限信息，服务器可以根据令牌中的权限信息进行授权访问控制。令牌可以具有加密和签名等安全机制，保证信息的机密性和完整性。这样即使令牌被截获，也不能被篡改或者伪造。</p><h2 id="为什么需要双-token"><a class="markdownIt-Anchor" href="#为什么需要双-token"></a> 为什么需要双 Token</h2><p>假如 token 没有过期时间或者过期很长，那么显然 token 被劫持还是不安全的，token 就失去了意义。</p><p>所以这时候大家肯定都想：那么把 token 过期时间设置的短一点就行啦？</p><p>是的，一般来讲 accessToken 的过期时间应该要短一点，但是这时候对于用户来讲就麻烦了。</p><p>因为 token 过期就意味着要重新登录，想象下你正浏览的好好的，突然让你掉线了并且要求你重新登录，心里肯定是想骂人的。</p><h2 id="什么时候需要用户重新登录"><a class="markdownIt-Anchor" href="#什么时候需要用户重新登录"></a> 什么时候需要用户重新登录</h2><p>主要有三种情况：</p><ol><li>用户长时间无操作，也可以定义为不活跃用户，就会被自动踢下，自动重定向到登录页面，超时时间可以自定义设置</li><li>token 失效，通常是双 token 都失效后，会要求重新登录获取新的双 token</li><li>当检测到有风险的时候，可以要求重新登录，获取 token</li></ol><h2 id="双-token-机制详解"><a class="markdownIt-Anchor" href="#双-token-机制详解"></a> 双 Token 机制详解</h2><p>因此这时候就可以使用双 token 的设计，当两个 token 都过期了再要求用户重新登录。对于 refreshToken，它只用来获取 accessToken，不会频繁被用于请求；对于 accessToken，它过期时间非常短，即使被拦截了解密也需要时间，而 token 本身也很快过期，因此这样的设计更加安全。</p><h3 id="token-类型对比"><a class="markdownIt-Anchor" href="#token-类型对比"></a> Token 类型对比</h3><table><thead><tr><th>特性</th><th>accessToken</th><th>refreshToken</th></tr></thead><tbody><tr><td>用途</td><td>访问受保护资源</td><td>刷新 accessToken</td></tr><tr><td>过期时间</td><td>短（15-30分钟）</td><td>长（7-30天）</td></tr><tr><td>使用频率</td><td>频繁（每次请求）</td><td>低频（仅在 accessToken 过期时）</td></tr><tr><td>存储位置</td><td>内存/localStorage</td><td>HttpOnly Cookie</td></tr><tr><td>泄露风险</td><td>高（频繁传输）</td><td>低（仅特定接口使用）</td></tr></tbody></table><h3 id="双-token-工作流程"><a class="markdownIt-Anchor" href="#双-token-工作流程"></a> 双 Token 工作流程</h3><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">用户登录 → 服务器返回 accessToken + refreshToken</span><br><span class="line">    ↓</span><br><span class="line">携带 accessToken 请求接口</span><br><span class="line">    ↓</span><br><span class="line">accessToken 有效 → 正常返回数据</span><br><span class="line">    ↓</span><br><span class="line">accessToken 过期 → 携带 refreshToken 请求刷新接口</span><br><span class="line">    ↓</span><br><span class="line">refreshToken 有效 → 返回新的 accessToken</span><br><span class="line">    ↓</span><br><span class="line">refreshToken 过期 → 跳转登录页，要求重新登录</span><br></pre></td></tr></table></figure><h2 id="响应拦截器处理-token-过期"><a class="markdownIt-Anchor" href="#响应拦截器处理-token-过期"></a> 响应拦截器处理 Token 过期</h2><p>推荐在响应拦截器中拦截，后端判断 token 返回过期后，调用刷新 token 接口：</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 请求拦截</span></span><br><span class="line">http.<span class="property">interceptors</span>.<span class="property">request</span>.<span class="title function_">use</span>(</span><br><span class="line">  <span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">    config.<span class="property">headers</span>[<span class="string">&#x27;token&#x27;</span>] = <span class="title class_">Vue</span>.<span class="property">cookie</span>.<span class="title function_">get</span>(<span class="string">&#x27;token&#x27;</span>) <span class="comment">// 请求头带上token</span></span><br><span class="line">    config.<span class="property">headers</span>[<span class="string">&#x27;language&#x27;</span>] = <span class="variable language_">localStorage</span>.<span class="title function_">getItem</span>(<span class="string">&#x27;language&#x27;</span>) <span class="comment">// 请求头带上中英文切换</span></span><br><span class="line">    <span class="keyword">return</span> config</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(error)</span><br><span class="line">  &#125;,</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 响应拦截</span></span><br><span class="line">http.<span class="property">interceptors</span>.<span class="property">response</span>.<span class="title function_">use</span>(</span><br><span class="line">  <span class="function">(<span class="params">response</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (response.<span class="property">data</span> &amp;&amp; response.<span class="property">data</span>.<span class="property">code</span> === <span class="number">401</span>) &#123;</span><br><span class="line">      <span class="comment">// 401, token失效</span></span><br><span class="line">      <span class="title function_">clearLoginInfo</span>()</span><br><span class="line">      router.<span class="title function_">push</span>(&#123; <span class="attr">name</span>: <span class="string">&#x27;login&#x27;</span> &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> response</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(error)</span><br><span class="line">  &#125;,</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h3 id="完善的双-token-刷新实现"><a class="markdownIt-Anchor" href="#完善的双-token-刷新实现"></a> 完善的双 Token 刷新实现</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> isRefreshing = <span class="literal">false</span></span><br><span class="line"><span class="keyword">let</span> requests = []</span><br><span class="line"></span><br><span class="line">http.<span class="property">interceptors</span>.<span class="property">response</span>.<span class="title function_">use</span>(</span><br><span class="line">  <span class="function">(<span class="params">response</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; code &#125; = response.<span class="property">data</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (code === <span class="number">401</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (!isRefreshing) &#123;</span><br><span class="line">        isRefreshing = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 调用刷新 token 接口</span></span><br><span class="line">        <span class="keyword">return</span> http</span><br><span class="line">          .<span class="title function_">post</span>(<span class="string">&#x27;/auth/refresh&#x27;</span>, &#123;</span><br><span class="line">            <span class="attr">refreshToken</span>: <span class="title function_">getRefreshToken</span>(),</span><br><span class="line">          &#125;)</span><br><span class="line">          .<span class="title function_">then</span>(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">const</span> &#123; accessToken, refreshToken &#125; = res.<span class="property">data</span></span><br><span class="line">            <span class="title function_">setAccessToken</span>(accessToken)</span><br><span class="line">            <span class="title function_">setRefreshToken</span>(refreshToken)</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 重新执行之前失败的请求</span></span><br><span class="line">            requests.<span class="title function_">forEach</span>(<span class="function">(<span class="params">cb</span>) =&gt;</span> <span class="title function_">cb</span>(accessToken))</span><br><span class="line">            requests = []</span><br><span class="line"></span><br><span class="line">            <span class="comment">// 重新执行当前请求</span></span><br><span class="line">            <span class="keyword">return</span> <span class="title function_">http</span>(response.<span class="property">config</span>)</span><br><span class="line">          &#125;)</span><br><span class="line">          .<span class="title function_">catch</span>(<span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 刷新失败，跳转登录页</span></span><br><span class="line">            <span class="title function_">clearLoginInfo</span>()</span><br><span class="line">            router.<span class="title function_">push</span>(&#123; <span class="attr">name</span>: <span class="string">&#x27;login&#x27;</span> &#125;)</span><br><span class="line">            <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(err)</span><br><span class="line">          &#125;)</span><br><span class="line">          .<span class="title function_">finally</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            isRefreshing = <span class="literal">false</span></span><br><span class="line">          &#125;)</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 正在刷新中，将请求加入队列</span></span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve</span>) =&gt;</span> &#123;</span><br><span class="line">        requests.<span class="title function_">push</span>(<span class="function">(<span class="params">token</span>) =&gt;</span> &#123;</span><br><span class="line">          response.<span class="property">config</span>.<span class="property">headers</span>[<span class="string">&#x27;token&#x27;</span>] = token</span><br><span class="line">          <span class="title function_">resolve</span>(<span class="title function_">http</span>(response.<span class="property">config</span>))</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> response</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(error)</span><br><span class="line">  &#125;,</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h1 id="基于-oauth2-的单点登录及鉴权"><a class="markdownIt-Anchor" href="#基于-oauth2-的单点登录及鉴权"></a> 基于 OAuth2 的单点登录及鉴权</h1><h2 id="oauth2-简介"><a class="markdownIt-Anchor" href="#oauth2-简介"></a> OAuth2 简介</h2><p>OAuth2 是一个授权框架，允许第三方应用在不暴露用户密码的情况下，获得用户资源的访问权限。它通过令牌（Token）机制实现授权，是目前最流行的单点登录（SSO）解决方案之一。</p><h2 id="oauth2-四种授权模式"><a class="markdownIt-Anchor" href="#oauth2-四种授权模式"></a> OAuth2 四种授权模式</h2><h3 id="1-授权码模式authorization-code"><a class="markdownIt-Anchor" href="#1-授权码模式authorization-code"></a> 1. 授权码模式（Authorization Code）</h3><p>最安全、最常用的模式，适用于有后端的 Web 应用：</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></pre></td><td class="code"><pre><span class="line">用户 → 第三方应用 → 授权服务器</span><br><span class="line">    ↓</span><br><span class="line">用户授权 → 返回授权码（code）</span><br><span class="line">    ↓</span><br><span class="line">第三方应用 → 用授权码换取 access_token</span><br><span class="line">    ↓</span><br><span class="line">获得 access_token → 访问用户资源</span><br></pre></td></tr></table></figure><h3 id="2-隐式模式implicit"><a class="markdownIt-Anchor" href="#2-隐式模式implicit"></a> 2. 隐式模式（Implicit）</h3><p>简化版授权码模式，适用于纯前端应用（如 SPA）：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">用户 → 前端应用 → 授权服务器</span><br><span class="line">    ↓</span><br><span class="line">用户授权 → 直接返回 access_token（无授权码环节）</span><br><span class="line">    ↓</span><br><span class="line">前端应用 → 使用 access_token 访问资源</span><br></pre></td></tr></table></figure><h3 id="3-密码模式resource-owner-password-credentials"><a class="markdownIt-Anchor" href="#3-密码模式resource-owner-password-credentials"></a> 3. 密码模式（Resource Owner Password Credentials）</h3><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></pre></td><td class="code"><pre><span class="line">用户 → 提供用户名密码 → 第三方应用</span><br><span class="line">    ↓</span><br><span class="line">第三方应用 → 用用户名密码向授权服务器换取 access_token</span><br><span class="line">    ↓</span><br><span class="line">获得 access_token → 访问用户资源</span><br></pre></td></tr></table></figure><h3 id="4-客户端凭证模式client-credentials"><a class="markdownIt-Anchor" href="#4-客户端凭证模式client-credentials"></a> 4. 客户端凭证模式（Client Credentials）</h3><p>适用于机器对机器（M2M）的授权：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">第三方应用 → 直接向授权服务器申请 token</span><br><span class="line">    ↓</span><br><span class="line">提供 client_id 和 client_secret</span><br><span class="line">    ↓</span><br><span class="line">获得 access_token → 访问资源</span><br></pre></td></tr></table></figure><h2 id="单点登录sso原理"><a class="markdownIt-Anchor" href="#单点登录sso原理"></a> 单点登录（SSO）原理</h2><p>单点登录允许用户在多个应用系统中，只需登录一次就可以访问所有相互信任的应用系统。</p><h3 id="sso-工作流程"><a class="markdownIt-Anchor" href="#sso-工作流程"></a> SSO 工作流程</h3><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><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">用户 → 访问应用A → 未登录 → 重定向到SSO认证中心</span><br><span class="line">    ↓</span><br><span class="line">用户输入账号密码 → SSO认证中心验证</span><br><span class="line">    ↓</span><br><span class="line">验证通过 → 返回 Ticket 给应用A</span><br><span class="line">    ↓</span><br><span class="line">应用A → 携带 Ticket 向SSO验证 → 获取用户信息</span><br><span class="line">    ↓</span><br><span class="line">用户登录应用A → 访问应用B → 未登录 → 重定向到SSO认证中心</span><br><span class="line">    ↓</span><br><span class="line">SSO检测到已登录 → 直接返回 Ticket 给应用B</span><br><span class="line">    ↓</span><br><span class="line">应用B → 携带 Ticket 向SSO验证 → 获取用户信息</span><br><span class="line">    ↓</span><br><span class="line">用户无需再次登录 → 访问应用B成功</span><br></pre></td></tr></table></figure><h2 id="jwtjson-web-token"><a class="markdownIt-Anchor" href="#jwtjson-web-token"></a> JWT（JSON Web Token）</h2><p>JWT 是 OAuth2 中常用的令牌格式，由三部分组成：</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><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">Header.Payload.Signature</span><br><span class="line"></span><br><span class="line">Header: &#123;</span><br><span class="line">  &quot;alg&quot;: &quot;HS256&quot;,</span><br><span class="line">  &quot;typ&quot;: &quot;JWT&quot;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Payload: &#123;</span><br><span class="line">  &quot;sub&quot;: &quot;1234567890&quot;,</span><br><span class="line">  &quot;name&quot;: &quot;John Doe&quot;,</span><br><span class="line">  &quot;iat&quot;: 1516239022,</span><br><span class="line">  &quot;exp&quot;: 1516242622</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Signature: HMACSHA256(base64(header) + &quot;.&quot; + base64(payload), secret)</span><br></pre></td></tr></table></figure><h3 id="jwt-vs-session"><a class="markdownIt-Anchor" href="#jwt-vs-session"></a> JWT vs Session</h3><table><thead><tr><th>特性</th><th>JWT</th><th>Session</th></tr></thead><tbody><tr><td>存储位置</td><td>客户端</td><td>服务器</td></tr><tr><td>扩展性</td><td>无状态，易于分布式</td><td>有状态，需要共享存储</td></tr><tr><td>性能</td><td>无需查询数据库</td><td>需要查询数据库</td></tr><tr><td>安全性</td><td>可被篡改（需签名）</td><td>依赖服务器安全</td></tr><tr><td>跨域</td><td>天然支持</td><td>需要特殊配置</td></tr></tbody></table><h2 id="oauth2-安全最佳实践"><a class="markdownIt-Anchor" href="#oauth2-安全最佳实践"></a> OAuth2 安全最佳实践</h2><ol><li><strong>使用 HTTPS</strong>：所有 OAuth2 通信都应使用 HTTPS，防止令牌在传输过程中被窃取</li><li><strong>短期令牌</strong>：access_token 应设置较短的过期时间（如15分钟）</li><li><strong>刷新令牌轮换</strong>：每次使用 refresh_token 时，都应返回一个新的 refresh_token</li><li><strong>令牌绑定</strong>：将令牌与特定客户端或设备绑定，防止令牌被盗用</li><li><strong>最小权限原则</strong>：只申请必要的权限范围（scope）</li><li><strong>安全存储</strong>：refresh_token 应存储在 HttpOnly Cookie 中，防止 XSS 攻击</li></ol>]]></content>
    
    
    <summary type="html">大鹏一日同风起，扶摇直上九万里</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Token" scheme="https://luckynwa.top/tags/Token/"/>
    
  </entry>
  
  <entry>
    <title>Mac 常用软件安装指南</title>
    <link href="https://luckynwa.top/posts/tool6/"/>
    <id>https://luckynwa.top/posts/tool6/</id>
    <published>2025-01-04T23:45:01.000Z</published>
    <updated>2026-07-07T16:19:34.155Z</updated>
    
    <content type="html"><![CDATA[<p>Homebrew 是 macOS 的一个包管理器，使用 Homebrew 安装各种软件。</p><h2 id="安装-homebrew"><a class="markdownIt-Anchor" href="#安装-homebrew"></a> 安装 Homebrew</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/bin/bash -c &quot;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&quot;</span><br></pre></td></tr></table></figure><p>安装完成后，配置环境变量：</p><figure class="highlight shell"><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">echo &#x27;eval &quot;$(/opt/homebrew/bin/brew shellenv)&quot;&#x27; &gt;&gt; ~/.zshrc</span><br><span class="line">source ~/.zshrc</span><br></pre></td></tr></table></figure><h2 id="git"><a class="markdownIt-Anchor" href="#git"></a> Git</h2><figure class="highlight shell"><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">brew install git</span><br><span class="line">git --version  # 应显示最新版本（如 git version 2.42.0）</span><br></pre></td></tr></table></figure><blockquote><p>优点：版本最新，后续更新方便（<code>brew upgrade git</code>）</p></blockquote><h2 id="maven"><a class="markdownIt-Anchor" href="#maven"></a> Maven</h2><figure class="highlight shell"><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">brew install maven</span><br><span class="line">mvn -v</span><br></pre></td></tr></table></figure><h2 id="nvm"><a class="markdownIt-Anchor" href="#nvm"></a> NVM</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">brew install nvm</span><br><span class="line">mkdir ~/.nvm</span><br><span class="line">vim ~/.bash_profile</span><br></pre></td></tr></table></figure><p>在 <code>~/.bash_profile</code> 中添加以下内容：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export NVM_DIR=~/.nvm</span><br><span class="line">source $(brew --prefix nvm)/nvm.sh</span><br></pre></td></tr></table></figure><p>使配置生效并安装 Node.js：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">source ~/.bash_profile</span><br><span class="line">nvm -v</span><br><span class="line">nvm install 20.12.2</span><br></pre></td></tr></table></figure><p>TODO</p>]]></content>
    
    
    <summary type="html">朝闻道，夕死可矣</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>个人免费访客统计平台busuanzi搭建指南</title>
    <link href="https://luckynwa.top/posts/tool224/"/>
    <id>https://luckynwa.top/posts/tool224/</id>
    <published>2025-01-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:19:34.057Z</updated>
    
    <content type="html"><![CDATA[<h2 id="ng配置"><a class="markdownIt-Anchor" href="#ng配置"></a> NG配置</h2><figure class="highlight nginx"><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></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span>       <span class="number">80</span>;</span><br><span class="line">    <span class="attribute">listen</span>  [::]:<span class="number">80</span>;</span><br><span class="line">    <span class="attribute">server_name</span>  busuanzi.luckynwa.top;</span><br><span class="line">    <span class="attribute">charset</span> utf-<span class="number">8</span>;</span><br><span class="line">    <span class="attribute">listen</span>  <span class="number">443</span> ssl;</span><br><span class="line">    <span class="attribute">ssl_certificate</span> /etc/nginx/cert/busuanzi.luckynwa.top.cer;   <span class="comment">#证书文件路径</span></span><br><span class="line">    <span class="attribute">ssl_certificate_key</span> /etc/nginx/cert/busuanzi.luckynwa.top.key;      <span class="comment">#证书私钥文件路径</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#请按照以下协议配置</span></span><br><span class="line">    <span class="attribute">ssl_protocols</span> TLSv1 TLSv1.<span class="number">1</span> TLSv1.<span class="number">2</span>;</span><br><span class="line">    <span class="attribute">ssl_ciphers</span> ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;</span><br><span class="line">    <span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"></span><br><span class="line">    <span class="section">location</span> /&#123;</span><br><span class="line">        <span class="attribute">charset</span> utf-<span class="number">8</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://120.26.80.35:28080/;</span><br><span class="line">    &#125;</span><br><span class="line">        <span class="section">location</span> /api/api&#123;</span><br><span class="line">        <span class="attribute">charset</span> utf-<span class="number">8</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line">        <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line">        <span class="attribute">proxy_pass</span> http://ip:28080/api;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="docker-compose配置"><a class="markdownIt-Anchor" href="#docker-compose配置"></a> Docker Compose配置</h2><p>/nwa/busuanzi/docker-compose.yaml 新建它 28080端口开发</p><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></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&#x27;3.8&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">redis:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">&#x27;registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/redis:alpine&#x27;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./data/redis:/data</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">bsz:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">&#x27;registry.cn-hangzhou.aliyuncs.com/lucky-warehouse/busuanzi:v2.8.10&#x27;</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&#x27;28080:8080&#x27;</span> <span class="comment"># 修改映射到宿主机的端口 host:container</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./data/bsz:/app/expose</span></span><br><span class="line">    <span class="attr">links:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">redis</span></span><br><span class="line">    <span class="attr">depends_on:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">redis</span></span><br><span class="line">    <span class="attr">environment:</span></span><br><span class="line">      <span class="attr">WEB_LOG:</span> <span class="literal">true</span> <span class="comment"># 是否开启日志</span></span><br><span class="line">      <span class="attr">WEB_DEBUG:</span> <span class="literal">false</span> <span class="comment"># 是否开启debug模式</span></span><br><span class="line">      <span class="attr">WEB_CORS:</span> <span class="string">&#x27;*&#x27;</span> <span class="comment"># 跨域访问</span></span><br><span class="line">      <span class="attr">BSZ_EXPIRE:</span> <span class="number">0</span> <span class="comment"># 统计数据过期时间 单位秒, 请输入整数 (无任何访问, 超过这个时间后, 统计数据将被清空, 0为不过期)</span></span><br><span class="line">      <span class="attr">BSZ_SECRET:</span> <span class="string">&#x27;bsz&#x27;</span> <span class="comment"># 签名密钥 // 请设置为任意长度的随机值</span></span><br><span class="line">      <span class="attr">API_SERVER:</span> <span class="string">https:\/\/busuanzi.luckynwa.top\/api</span> <span class="comment"># 填写你的 API 地址 需要转译 (即 用 `\/` 替代 `/`)</span></span><br><span class="line">      <span class="attr">REDIS_ADDRESS:</span> <span class="string">redis:6379</span> <span class="comment"># redis 地址</span></span><br><span class="line">      <span class="attr">BSZ_PATHSTYLE:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">BSZ_ENCRYPT:</span> <span class="string">MD516</span></span><br></pre></td></tr></table></figure><h2 id="启动服务"><a class="markdownIt-Anchor" href="#启动服务"></a> 启动服务</h2><p>去shell那安装它</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">cd /nwa/busuanzi</span><br><span class="line"></span><br><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure><h2 id="hexo主题集成"><a class="markdownIt-Anchor" href="#hexo主题集成"></a> Hexo主题集成</h2><p>参考api <a href="https://gitee.com/soxft/busuanzi/wikis/api">https://gitee.com/soxft/busuanzi/wikis/api</a></p><p>搜</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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">    default</span><br><span class="line">      if theme.busuanzi.page_pv</span><br><span class="line">        +pvBlock(&#x27;&#x27;,&#x27;post-meta-pv-cv&#x27;,&#x27;&#x27;)</span><br><span class="line">          span#busuanzi_value_page_pv</span><br><span class="line">else if theme.busuanzi.page_pv</span><br><span class="line">  +pvBlock(&#x27;&#x27;,&#x27;post-meta-pv-cv&#x27;,&#x27;&#x27;)</span><br><span class="line">    span#busuanzi_value_page_pv</span><br><span class="line"></span><br><span class="line">   去除_value</span><br><span class="line"></span><br><span class="line">   .item-count#busuanzi_value_site_uv   也是</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">不积跬步，无以至千里</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Docker" scheme="https://luckynwa.top/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>Java实用工具类大全</title>
    <link href="https://luckynwa.top/posts/java9222/"/>
    <id>https://luckynwa.top/posts/java9222/</id>
    <published>2025-01-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:20:55.630Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1-collections"><a class="markdownIt-Anchor" href="#1-collections"></a> 1. Collections</h2><p>首先出场的是<code>java.util</code>包下的<code>Collections</code>类，该类主要用于操作集合或者返回集合，我个人非常喜欢用它。</p><h3 id="11-排序"><a class="markdownIt-Anchor" href="#11-排序"></a> 1.1 排序</h3><p>在工作中经常有对集合排序的需求。</p><p>看看使用<code>Collections</code>工具是如何实现升序和降序的：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line">Collections.sort(list);<span class="comment">//升序</span></span><br><span class="line">System.out.println(list);</span><br><span class="line">Collections.reverse(list);<span class="comment">//降序</span></span><br><span class="line">System.out.println(list);</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></pre></td><td class="code"><pre><span class="line">[1, 2, 3]</span><br><span class="line">[3, 2, 1]</span><br></pre></td></tr></table></figure><h3 id="12-获取最大或最小值"><a class="markdownIt-Anchor" href="#12-获取最大或最小值"></a> 1.2 获取最大或最小值</h3><p>有时候需要找出集合中的<code>最大值</code>或者<code>最小值</code>，这时可以使用Collections的<code>max</code>和<code>min</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"><span class="type">Integer</span> <span class="variable">max</span> <span class="operator">=</span> Collections.max(list);<span class="comment">//获取最大值</span></span><br><span class="line"><span class="type">Integer</span> <span class="variable">min</span> <span class="operator">=</span> Collections.min(list);<span class="comment">//获取最小值</span></span><br><span class="line">System.out.println(max);</span><br><span class="line">System.out.println(min);</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></pre></td><td class="code"><pre><span class="line">3</span><br><span class="line">1</span><br></pre></td></tr></table></figure><h3 id="13-转换线程安全集合"><a class="markdownIt-Anchor" href="#13-转换线程安全集合"></a> 1.3 转换线程安全集合</h3><p>我们都知道，java中的很多集合，比如：ArrayList、LinkedList、HashMap、HashSet等，都是线程不安全的。</p><p>换句话说，这些集合在多线程的环境中，添加数据会出现异常。</p><p>这时，可以用Collections的<code>synchronizedxxx</code>方法，将这些线程不安全的集合，直接转换成线程安全集合。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">List&lt;Integer&gt; integers = Collections.synchronizedList(list);<span class="comment">//将ArrayList转换成线程安全集合</span></span><br><span class="line">System.out.println(integers);</span><br></pre></td></tr></table></figure><p>它的底层会创建<code>SynchronizedRandomAccessList</code>或者<code>SynchronizedList</code>类，这两个类的很多方法都会用<code>synchronized</code>加锁。</p><h3 id="14-返回空集合"><a class="markdownIt-Anchor" href="#14-返回空集合"></a> 1.4 返回空集合</h3><p>有时，我们在判空之后，需要返回空集合，就可以使用<code>emptyList</code>方法，例如：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> List&lt;Integer&gt; <span class="title function_">fun</span><span class="params">(List&lt;Integer&gt; list)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (list == <span class="literal">null</span> || list.size() == <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> Collections.emptyList();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//业务处理</span></span><br><span class="line">    <span class="keyword">return</span> list;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="15-二分查找"><a class="markdownIt-Anchor" href="#15-二分查找"></a> 1.5 二分查找</h3><p><code>binarySearch</code>方法提供了一个非常好用的<code>二分查找</code>功能，只用传入指定集合和需要找到的key即可。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> Collections.binarySearch(list, <span class="number">3</span>);<span class="comment">//二分查找</span></span><br><span class="line">System.out.println(i );</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></pre></td><td class="code"><pre><span class="line">2</span><br></pre></td></tr></table></figure><h3 id="16-转换成不可修改集合"><a class="markdownIt-Anchor" href="#16-转换成不可修改集合"></a> 1.6 转换成不可修改集合</h3><p>为了防止后续的程序把某个集合的结果修改了，有时候我们需要把某个集合定义成不可修改的，使用Collections的<code>unmodifiablexxx</code>方法就能轻松实现：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">List&lt;Integer&gt; integers = Collections.unmodifiableList(list);</span><br><span class="line">integers.add(<span class="number">4</span>);</span><br><span class="line">System.out.println(integers);</span><br></pre></td></tr></table></figure><p>执行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Exception in thread &quot;main&quot; java.lang.UnsupportedOperationException</span><br><span class="line"> at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)</span><br><span class="line"> at com.sue.jump.service.test1.UtilTest.main(UtilTest.java:19)</span><br></pre></td></tr></table></figure><p>当然Collections工具类中还有很多常用的方法，在这里就不一一介绍了，需要你自己去探索。</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640_20260705182427A018.png" alt="图片" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640-17479907433513_20260705182606A033.png" alt="图片" /></p><h2 id="2-collectionutils"><a class="markdownIt-Anchor" href="#2-collectionutils"></a> 2. CollectionUtils</h2><p>对集合操作，除了前面说的<code>Collections</code>工具类之后，<code>CollectionUtils</code>工具类也非常常用。</p><p>目前比较主流的是<code>spring</code>的<code>org.springframework.util</code>包下的CollectionUtils工具类。<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-17479907630086_20260705182432A019.png" alt="图片" /></p><p>和<code>apache</code>的<code>org.apache.commons.collections</code>包下的CollectionUtils工具类。</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640-17479907693119_20260705182453A020.png" alt="图片" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799077484712_20260705182617A034.png" alt="图片" /></p><blockquote><p>我个人更推荐使用apache的包下的CollectionUtils工具类，因为它的工具更多更全面。</p></blockquote><p>举个简单的例子，<code>spring</code>的CollectionUtils工具类没有判断集合不为空的方法。而<code>apache</code>的CollectionUtils工具类却有。</p><p>下面我们以<code>apache</code>的CollectionUtils工具类为例，介绍一下常用方法。</p><h3 id="21-集合判空"><a class="markdownIt-Anchor" href="#21-集合判空"></a> 2.1 集合判空</h3><p>通过CollectionUtils工具类的<code>isEmpty</code>方法可以轻松判断集合是否为空，<code>isNotEmpty</code>方法判断集合不为空。</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">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (CollectionUtils.isEmpty(list)) &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;集合为空&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (CollectionUtils.isNotEmpty(list)) &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;集合不为空&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="22-对两个集合进行操作"><a class="markdownIt-Anchor" href="#22-对两个集合进行操作"></a> 2.2 对两个集合进行操作</h3><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><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">List&lt;Integer&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list.add(<span class="number">2</span>);</span><br><span class="line">list.add(<span class="number">1</span>);</span><br><span class="line">list.add(<span class="number">3</span>);</span><br><span class="line"></span><br><span class="line">List&lt;Integer&gt; list2 = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">list2.add(<span class="number">2</span>);</span><br><span class="line">list2.add(<span class="number">4</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取并集</span></span><br><span class="line">Collection&lt;Integer&gt; unionList = CollectionUtils.union(list, list2);</span><br><span class="line">System.out.println(unionList);</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取交集</span></span><br><span class="line">Collection&lt;Integer&gt; intersectionList = CollectionUtils.intersection(list, list2);</span><br><span class="line">System.out.println(intersectionList);</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取交集的补集</span></span><br><span class="line">Collection&lt;Integer&gt; disjunctionList = CollectionUtils.disjunction(list, list2);</span><br><span class="line">System.out.println(disjunctionList);</span><br><span class="line"></span><br><span class="line"><span class="comment">//获取差集</span></span><br><span class="line">Collection&lt;Integer&gt; subtractList = CollectionUtils.subtract(list, list2);</span><br><span class="line">System.out.println(subtractList);</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></pre></td><td class="code"><pre><span class="line">[1, 2, 3, 4]</span><br><span class="line">[2]</span><br><span class="line">[1, 3, 4]</span><br><span class="line">[1, 3]</span><br></pre></td></tr></table></figure><p>说句实话，对两个集合的操作，在实际工作中用得挺多的，特别是很多批量的场景中。以前我们需要写一堆代码，但没想到有现成的轮子。</p><h2 id="3-lists"><a class="markdownIt-Anchor" href="#3-lists"></a> 3. Lists</h2><p>如果你引入<code>com.google.guava</code>的pom文件，会获得很多好用的小工具。这里推荐一款<code>com.google.common.collect</code>包下的集合工具：<code>Lists</code>。</p><p>它是在太好用了，让我爱不释手。</p><h3 id="31-创建空集合"><a class="markdownIt-Anchor" href="#31-创建空集合"></a> 3.1 创建空集合</h3><p>有时候，我们想创建一个空集合。这时可以用Lists的<code>newArrayList</code>方法，例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = Lists.newArrayList();</span><br></pre></td></tr></table></figure><h3 id="32-快速初始化集合"><a class="markdownIt-Anchor" href="#32-快速初始化集合"></a> 3.2 快速初始化集合</h3><p>有时候，我们想给一个集合中初始化一些元素。这时可以用Lists的newArrayList方法，例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = Lists.newArrayList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</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></pre></td><td class="code"><pre><span class="line">[1, 2, 3]</span><br></pre></td></tr></table></figure><h3 id="33-笛卡尔积"><a class="markdownIt-Anchor" href="#33-笛卡尔积"></a> 3.3 笛卡尔积</h3><p>如果你想将两个集合做<code>笛卡尔积</code>，Lists的<code>cartesianProduct</code>方法可以帮你实现：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list1 = Lists.newArrayList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line">List&lt;Integer&gt; list2 = Lists.newArrayList(<span class="number">4</span>,<span class="number">5</span>);</span><br><span class="line">List&lt;List&lt;Integer&gt;&gt; productList = Lists.cartesianProduct(list1,list2);</span><br><span class="line">System.out.println(productList);</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></pre></td><td class="code"><pre><span class="line">[[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]</span><br></pre></td></tr></table></figure><h3 id="34-分页"><a class="markdownIt-Anchor" href="#34-分页"></a> 3.4 分页</h3><p>如果你想将一个<code>大集合</code>分成若干个<code>小集合</code>，可以使用Lists的<code>partition</code>方法：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = Lists.newArrayList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>);</span><br><span class="line">List&lt;List&lt;Integer&gt;&gt; partitionList = Lists.partition(list, <span class="number">2</span>);</span><br><span class="line">System.out.println(partitionList);</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></pre></td><td class="code"><pre><span class="line">[[1, 2], [3, 4], [5]]</span><br></pre></td></tr></table></figure><p>这个例子中，list有5条数据，我将list集合按大小为2，分成了3页，即变成3个小集合。</p><p>这个是我最喜欢的方法之一，经常在项目中使用。</p><p>比如有个需求：现在有5000个id，需要调用批量用户查询接口，查出用户数据。但如果你直接查5000个用户，单次接口响应时间可能会非常慢。如果改成分页处理，每次只查500个用户，异步调用10次接口，就不会有单次接口响应慢的问题。</p><h3 id="35-流处理"><a class="markdownIt-Anchor" href="#35-流处理"></a> 3.5 流处理</h3><p>如果我们想把某个集合转换成另外一个接口，可以使用Lists的<code>transform</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; list = Lists.newArrayList(<span class="string">&quot;a&quot;</span>,<span class="string">&quot;b&quot;</span>,<span class="string">&quot;c&quot;</span>);</span><br><span class="line">List&lt;String&gt; transformList = Lists.transform(list, x -&gt; x.toUpperCase());</span><br><span class="line">System.out.println(transformList);</span><br></pre></td></tr></table></figure><p>将小写字母转换成了大写字母。</p><h3 id="36-颠倒顺序"><a class="markdownIt-Anchor" href="#36-颠倒顺序"></a> 3.6 颠倒顺序</h3><p>Lists的有颠倒顺序的方法<code>reverse</code>。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;Integer&gt; list = Lists.newArrayList(<span class="number">3</span>, <span class="number">1</span>, <span class="number">2</span>);</span><br><span class="line">List&lt;Integer&gt; reverseList = Lists.reverse(list);</span><br><span class="line">System.out.println(reverseList);</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></pre></td><td class="code"><pre><span class="line">[2, 1, 3]</span><br></pre></td></tr></table></figure><p>list的原始顺序是312，使用<code>reverse</code>方法颠倒顺序之后，变成了213。</p><p>Lists还有其他的好用的工具，我在这里只是抛砖引玉，有兴趣的朋友，可以仔细研究一下。<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799078520715_20260705182458A021.png" alt="图片" /></p><h2 id="4-objects"><a class="markdownIt-Anchor" href="#4-objects"></a> 4. Objects</h2><p>在<code>jdk7</code>之后，提供了<code>Objects</code>工具类，我们可以通过它操作对象。</p><h3 id="41-对象判空"><a class="markdownIt-Anchor" href="#41-对象判空"></a> 4.1 对象判空</h3><p>在java中万事万物皆对象，对象的判空可以说无处不在。Objects的<code>isNull</code>方法判断对象是否为空，而<code>nonNull</code>方法判断对象是否不为空。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Integer</span> <span class="variable">integer</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (Objects.isNull(integer)) &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;对象为空&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (Objects.nonNull(integer)) &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;对象不为空&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="42-对象为空抛异常"><a class="markdownIt-Anchor" href="#42-对象为空抛异常"></a> 4.2 对象为空抛异常</h3><p>如果我们想在对象为空时，抛出空指针异常，可以使用Objects的<code>requireNonNull</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Integer</span> <span class="variable">integer1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">128</span>);</span><br><span class="line"></span><br><span class="line">Objects.requireNonNull(integer1);</span><br><span class="line">Objects.requireNonNull(integer1, <span class="string">&quot;参数不能为空&quot;</span>);</span><br><span class="line">Objects.requireNonNull(integer1, () -&gt; <span class="string">&quot;参数不能为空&quot;</span>);</span><br></pre></td></tr></table></figure><h3 id="43-判断两个对象是否相等"><a class="markdownIt-Anchor" href="#43-判断两个对象是否相等"></a> 4.3 判断两个对象是否相等</h3><p>我们经常需要判断两个对象是否相等，Objects给我们提供了<code>equals</code>方法，能非常方便的实现：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Integer</span> <span class="variable">integer1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">1</span>);</span><br><span class="line"><span class="type">Integer</span> <span class="variable">integer2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(Objects.equals(integer1, integer2));</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></pre></td><td class="code"><pre><span class="line">true</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="type">Integer</span> <span class="variable">integer1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Integer</span>(<span class="number">1</span>);</span><br><span class="line"><span class="type">Long</span> <span class="variable">integer2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Long</span>(<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(Objects.equals(integer1, integer2));</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></pre></td><td class="code"><pre><span class="line">false</span><br></pre></td></tr></table></figure><p>具体原因不细说了，有兴趣的小伙们可以看看我的另一篇文章《<a href="https://mp.weixin.qq.com/s?__biz=MzkwNjMwMTgzMQ==&amp;mid=2247493176&amp;idx=1&amp;sn=c445625478a7f8122a6715b64fe6770c&amp;chksm=c0e83ed0f79fb7c6cf2992d24e98f60fd78ca89525b5a3cc07f79dc801dd8e381b1fce03bf5c&amp;token=1124974571&amp;lang=zh_CN&amp;scene=21#wechat_redirect">Objects.equals有坑</a>》，里面有非常详细的讲解。</p><h3 id="44-获取对象的hashcode"><a class="markdownIt-Anchor" href="#44-获取对象的hashcode"></a> 4.4 获取对象的hashCode</h3><p>如果你想获取某个对象的hashCode，可以使用Objects的<code>hashCode</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;abc&quot;</span>);</span><br><span class="line">System.out.println(Objects.hashCode(str));</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></pre></td><td class="code"><pre><span class="line">96354</span><br></pre></td></tr></table></figure><p>Objects的内容先介绍到这里，有兴趣的小伙们，可以看看下面更多的方法：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799079008918_20260705182506A022.png" alt="图片" /></p><h2 id="5-booleanutils"><a class="markdownIt-Anchor" href="#5-booleanutils"></a> 5. BooleanUtils</h2><p>在java中布尔值，随处可见。</p><p>如果你使用了布尔的包装类：<code>Boolean</code>，总感觉有点麻烦，因为它有三种值：<code>null</code>、<code>true</code>、<code>false</code>。我们在处理Boolean对象时，需要经常判空。</p><p>头疼！！！</p><p>但如果使用<code>BooleanUtils</code>类处理布尔值，心情一下子就愉悦起来了。</p><h3 id="51-判断true或false"><a class="markdownIt-Anchor" href="#51-判断true或false"></a> 5.1 判断true或false</h3><p>如果你想判断某个参数的值是true或false，可以直接使用<code>isTrue</code>或<code>isFalse</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">true</span>);</span><br><span class="line">System.out.println(BooleanUtils.isTrue(aBoolean));</span><br><span class="line">System.out.println(BooleanUtils.isFalse(aBoolean));</span><br></pre></td></tr></table></figure><h3 id="52-判断不为true或不为false"><a class="markdownIt-Anchor" href="#52-判断不为true或不为false"></a> 5.2 判断不为true或不为false</h3><p>有时候，需要判断某个参数不为true，即是null或者false。或者判断不为false，即是null或者true。</p><p>可以使用<code>isNotTrue</code>或<code>isNotFalse</code>方法。例如：</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="type">Boolean</span> <span class="variable">aBoolean</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">true</span>);</span><br><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean1</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">System.out.println(BooleanUtils.isNotTrue(aBoolean));</span><br><span class="line">System.out.println(BooleanUtils.isNotTrue(aBoolean1));</span><br><span class="line">System.out.println(BooleanUtils.isNotFalse(aBoolean));</span><br><span class="line">System.out.println(BooleanUtils.isNotFalse(aBoolean1));</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></pre></td><td class="code"><pre><span class="line">false</span><br><span class="line">true</span><br><span class="line">true</span><br><span class="line">true</span><br></pre></td></tr></table></figure><h3 id="53-转换成数字"><a class="markdownIt-Anchor" href="#53-转换成数字"></a> 5.3 转换成数字</h3><p>如果你想将true转换成数字1，false转换成数字0，可以使用<code>toInteger</code>方法：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">true</span>);</span><br><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">false</span>);</span><br><span class="line">System.out.println(BooleanUtils.toInteger(aBoolean));</span><br><span class="line">System.out.println(BooleanUtils.toInteger(aBoolean1));</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></pre></td><td class="code"><pre><span class="line">1</span><br><span class="line">0</span><br></pre></td></tr></table></figure><h3 id="54-boolean转换成布尔值"><a class="markdownIt-Anchor" href="#54-boolean转换成布尔值"></a> 5.4 Boolean转换成布尔值</h3><p>我们有时候需要将包装类<code>Boolean</code>对象，转换成原始的<code>boolean</code>对象，可以使用<code>toBoolean</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Boolean</span>(<span class="literal">true</span>);</span><br><span class="line"><span class="type">Boolean</span> <span class="variable">aBoolean1</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">System.out.println(BooleanUtils.toBoolean(aBoolean));</span><br><span class="line">System.out.println(BooleanUtils.toBoolean(aBoolean1));</span><br><span class="line">System.out.println(BooleanUtils.toBooleanDefaultIfNull(aBoolean1, <span class="literal">false</span>));</span><br></pre></td></tr></table></figure><p>我们无需额外的判空了，而且还可以设置Boolean对象为空时返回的默认值。</p><p>BooleanUtils类的方法还有很多，有兴趣的小伙伴可以看看下面的内容：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799079862821_20260705182511A023.png" alt="图片" /></p><h2 id="6-stringutils"><a class="markdownIt-Anchor" href="#6-stringutils"></a> 6. StringUtils</h2><p><code>字符串</code>（String）在我们的日常工作中，用得非常非常非常多。</p><p>在我们的代码中经常需要对字符串判空，截取字符串、转换大小写、分隔字符串、比较字符串、去掉多余空格、拼接字符串、使用正则表达式等等。</p><p>如果只用String类提供的那些方法，我们需要手写大量的额外代码，不然容易出现各种异常。</p><p>现在有个好消息是：<code>org.apache.commons.lang3</code>包下的<code>StringUtils</code>工具类，给我们提供了非常丰富的选择。</p><h3 id="61-字符串判空"><a class="markdownIt-Anchor" href="#61-字符串判空"></a> 6.1 字符串判空</h3><p>其实空字符串，不只是null一种，还有&quot;“，” &quot;，&quot;null&quot;等等，多种情况。</p><p>StringUtils给我们提供了多个判空的静态方法，例如：</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="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">str2</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">str3</span> <span class="operator">=</span> <span class="string">&quot; &quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">str4</span> <span class="operator">=</span> <span class="string">&quot;abc&quot;</span>;</span><br><span class="line">System.out.println(StringUtils.isEmpty(str1));</span><br><span class="line">System.out.println(StringUtils.isEmpty(str2));</span><br><span class="line">System.out.println(StringUtils.isEmpty(str3));</span><br><span class="line">System.out.println(StringUtils.isEmpty(str4));</span><br><span class="line">System.out.println(<span class="string">&quot;=====&quot;</span>);</span><br><span class="line">System.out.println(StringUtils.isNotEmpty(str1));</span><br><span class="line">System.out.println(StringUtils.isNotEmpty(str2));</span><br><span class="line">System.out.println(StringUtils.isNotEmpty(str3));</span><br><span class="line">System.out.println(StringUtils.isNotEmpty(str4));</span><br><span class="line">System.out.println(<span class="string">&quot;=====&quot;</span>);</span><br><span class="line">System.out.println(StringUtils.isBlank(str1));</span><br><span class="line">System.out.println(StringUtils.isBlank(str2));</span><br><span class="line">System.out.println(StringUtils.isBlank(str3));</span><br><span class="line">System.out.println(StringUtils.isBlank(str4));</span><br><span class="line">System.out.println(<span class="string">&quot;=====&quot;</span>);</span><br><span class="line">System.out.println(StringUtils.isNotBlank(str1));</span><br><span class="line">System.out.println(StringUtils.isNotBlank(str2));</span><br><span class="line">System.out.println(StringUtils.isNotBlank(str3));</span><br><span class="line">System.out.println(StringUtils.isNotBlank(str4));</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><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></pre></td><td class="code"><pre><span class="line">true</span><br><span class="line">true</span><br><span class="line">false</span><br><span class="line">false</span><br><span class="line">=====</span><br><span class="line">false</span><br><span class="line">false</span><br><span class="line">true</span><br><span class="line">true</span><br><span class="line">=====</span><br><span class="line">true</span><br><span class="line">true</span><br><span class="line">true</span><br><span class="line">false</span><br><span class="line">=====</span><br><span class="line">false</span><br><span class="line">false</span><br><span class="line">false</span><br><span class="line">true</span><br></pre></td></tr></table></figure><p>示例中的：<code>isEmpty</code>、<code>isNotEmpty</code>、<code>isBlank</code>和<code>isNotBlank</code>，这4个判空方法你们可以根据实际情况使用。</p><blockquote><p>优先推荐使用<code>isBlank</code>和<code>isNotBlank</code>方法，因为它会把<code>&quot; &quot;</code>也考虑进去。</p></blockquote><h3 id="62-分隔字符串"><a class="markdownIt-Anchor" href="#62-分隔字符串"></a> 6.2 分隔字符串</h3><p>分隔字符串是常见需求，如果直接使用String类的split方法，就可能会出现空指针异常。</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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">System.out.println(StringUtils.split(str1,<span class="string">&quot;,&quot;</span>));</span><br><span class="line">System.out.println(str1.split(<span class="string">&quot;,&quot;</span>));</span><br></pre></td></tr></table></figure><p>执行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">null</span><br><span class="line">Exception in thread &quot;main&quot; java.lang.NullPointerException</span><br><span class="line"> at com.sue.jump.service.test1.UtilTest.main(UtilTest.java:21)</span><br></pre></td></tr></table></figure><p>使用StringUtils的split方法会返回null，而使用String的split方法会报指针异常。</p><h3 id="63-判断是否纯数字"><a class="markdownIt-Anchor" href="#63-判断是否纯数字"></a> 6.3 判断是否纯数字</h3><p>给定一个字符串，判断它是否为纯数字，可以使用<code>isNumeric</code>方法。例如：</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="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="string">&quot;123&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">str2</span> <span class="operator">=</span> <span class="string">&quot;123q&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">str3</span> <span class="operator">=</span> <span class="string">&quot;0.33&quot;</span>;</span><br><span class="line">System.out.println(StringUtils.isNumeric(str1));</span><br><span class="line">System.out.println(StringUtils.isNumeric(str2));</span><br><span class="line">System.out.println(StringUtils.isNumeric(str3));</span><br></pre></td></tr></table></figure><p>执行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">true</span><br><span class="line">false</span><br><span class="line">false</span><br></pre></td></tr></table></figure><h3 id="64-将集合拼接成字符串"><a class="markdownIt-Anchor" href="#64-将集合拼接成字符串"></a> 6.4 将集合拼接成字符串</h3><p>有时候，我们需要将某个集合的内容，拼接成一个字符串，然后输出，这时可以使用<code>join</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; list = Lists.newArrayList(<span class="string">&quot;a&quot;</span>, <span class="string">&quot;b&quot;</span>, <span class="string">&quot;c&quot;</span>);</span><br><span class="line">List&lt;Integer&gt; list2 = Lists.newArrayList(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>);</span><br><span class="line">System.out.println(StringUtils.join(list, <span class="string">&quot;,&quot;</span>));</span><br><span class="line">System.out.println(StringUtils.join(list2, <span class="string">&quot; &quot;</span>));</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></pre></td><td class="code"><pre><span class="line">a,b,c</span><br><span class="line">1 2 3</span><br></pre></td></tr></table></figure><p>当然还有很多实用的方法，我在这里就不一一介绍了。<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799080945524_20260705182516A024.png" alt="图片" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799081270227_20260705182523A025.png" alt="图片" /></p><h2 id="7-assert"><a class="markdownIt-Anchor" href="#7-assert"></a> 7. Assert</h2><p>很多时候，我们需要在代码中做判断：如果不满足条件，则抛异常。</p><p>有没有统一的封装呢?</p><p>其实<code>spring</code>给我们提供了<code>Assert</code>类，它表示<code>断言</code>。</p><h3 id="71-断言参数是否为空"><a class="markdownIt-Anchor" href="#71-断言参数是否为空"></a> 7.1 断言参数是否为空</h3><p>断言<code>参数</code>是否空，如果不满足条件，则直接抛异常。</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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">Assert.isNull(str, <span class="string">&quot;str必须为空&quot;</span>);</span><br><span class="line">Assert.isNull(str, () -&gt; <span class="string">&quot;str必须为空&quot;</span>);</span><br><span class="line">Assert.notNull(str, <span class="string">&quot;str不能为空&quot;</span>);</span><br></pre></td></tr></table></figure><p>如果不满足条件就会抛出<code>IllegalArgumentException</code>异常。</p><h3 id="72-断言集合是否为空"><a class="markdownIt-Anchor" href="#72-断言集合是否为空"></a> 7.2 断言集合是否为空</h3><p>断言<code>集合</code>是否空，如果不满足条件，则直接抛异常。</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></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; list = <span class="literal">null</span>;</span><br><span class="line">Map&lt;String, String&gt; map = <span class="literal">null</span>;</span><br><span class="line">Assert.notEmpty(list, <span class="string">&quot;list不能为空&quot;</span>);</span><br><span class="line">Assert.notEmpty(list, () -&gt; <span class="string">&quot;list不能为空&quot;</span>);</span><br><span class="line">Assert.notEmpty(map, <span class="string">&quot;map不能为空&quot;</span>);</span><br></pre></td></tr></table></figure><p>如果不满足条件就会抛出<code>IllegalArgumentException</code>异常。</p><h3 id="73-断言条件是否为空"><a class="markdownIt-Anchor" href="#73-断言条件是否为空"></a> 7.3 断言条件是否为空</h3><p>断言是否满足某个<code>条件</code>，如果不满足条件，则直接抛异常。</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></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; list = <span class="literal">null</span>;</span><br><span class="line">Assert.isTrue(CollectionUtils.isNotEmpty(list), <span class="string">&quot;list不能为空&quot;</span>);</span><br><span class="line">Assert.isTrue(CollectionUtils.isNotEmpty(list), () -&gt; <span class="string">&quot;list不能为空&quot;</span>);</span><br></pre></td></tr></table></figure><p>当然Assert类还有一些其他的功能，这里就不多介绍了。<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799081647530_20260705182528A026.png" alt="图片" /></p><h2 id="8-ioutils"><a class="markdownIt-Anchor" href="#8-ioutils"></a> 8. IOUtils</h2><p><code>IO</code>流在我们日常工作中也用得比较多，尽管java已经给我们提供了丰富的API。</p><p>但我们不得不每次读取文件，或者写入文件之后，写一些重复的的代码。手动在<code>finally</code>代码块中关闭流，不然可能会造成<code>内存溢出</code>。</p><p>有个好消息是：如果你使用<code>org.apache.commons.io</code>包下的<code>IOUtils</code>类，会节省大量的时间。</p><h3 id="81-读取文件"><a class="markdownIt-Anchor" href="#81-读取文件"></a> 8.1 读取文件</h3><p>如果你想将某个txt文件中的数据，读取到字符串当中，可以使用IOUtils类的<code>toString</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">str</span> <span class="operator">=</span> IOUtils.toString(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;/temp/a.txt&quot;</span>), StandardCharsets.UTF_8);</span><br><span class="line">System.out.println(str);</span><br></pre></td></tr></table></figure><h3 id="82-写入文件"><a class="markdownIt-Anchor" href="#82-写入文件"></a> 8.2 写入文件</h3><p>如果你想将某个字符串的内容，写入到指定文件当中，可以使用IOUtils类的<code>write</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">&quot;abcde&quot;</span>;</span><br><span class="line">IOUtils.write(str, <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;/temp/b.tx&quot;</span>), StandardCharsets.UTF_8);</span><br></pre></td></tr></table></figure><h3 id="83-文件拷贝"><a class="markdownIt-Anchor" href="#83-文件拷贝"></a> 8.3 文件拷贝</h3><p>如果你想将某个文件中的所有内容，都拷贝到另一个文件当中，可以使用IOUtils类的<code>copy</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">IOUtils.copy(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;/temp/a.txt&quot;</span>), <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;/temp/b.txt&quot;</span>));</span><br></pre></td></tr></table></figure><h3 id="84-读取文件内容到字节数组"><a class="markdownIt-Anchor" href="#84-读取文件内容到字节数组"></a> 8.4 读取文件内容到字节数组</h3><p>如果你想将某个文件中的内容，读取字节数组中，可以使用IOUtils类的<code>toByteArray</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">byte</span>[] bytes = IOUtils.toByteArray(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;/temp/a.txt&quot;</span>));</span><br></pre></td></tr></table></figure><p>IOUtils类非常实用，感兴趣的小伙们，可以看看下面内容。<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799082101833_20260705182533A027.png" alt="图片" /></p><h2 id="9-mdc"><a class="markdownIt-Anchor" href="#9-mdc"></a> 9. MDC</h2><p><code>MDC</code>是<code>org.slf4j</code>包下的一个类，它的全称是Mapped Diagnostic Context，我们可以认为它是一个线程安全的存放诊断日志的容器。</p><p>MDC的底层是用了<code>ThreadLocal</code>来保存数据的。</p><p>我们可以用它传递参数。</p><p>例如现在有这样一种场景：我们使用<code>RestTemplate</code>调用远程接口时，有时需要在<code>header</code>中传递信息，比如：traceId，source等，便于在查询日志时能够串联一次完整的请求链路，快速定位问题。</p><p>这种业务场景就能通过<code>ClientHttpRequestInterceptor</code>接口实现，具体做法如下：</p><p>第一步，定义一个LogFilter拦截所有接口请求，在MDC中设置traceId：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LogFilter</span> <span class="keyword">implements</span> <span class="title class_">Filter</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">init</span><span class="params">(FilterConfig filterConfig)</span> <span class="keyword">throws</span> ServletException &#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">doFilter</span><span class="params">(ServletRequest request, ServletResponse response, FilterChain chain)</span> <span class="keyword">throws</span> IOException, ServletException &#123;</span><br><span class="line">        MdcUtil.add(UUID.randomUUID().toString());</span><br><span class="line">        System.out.println(<span class="string">&quot;记录请求日志&quot;</span>);</span><br><span class="line">        chain.doFilter(request, response);</span><br><span class="line">        System.out.println(<span class="string">&quot;记录响应日志&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">destroy</span><span class="params">()</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>第二步，实现<code>ClientHttpRequestInterceptor</code>接口，MDC中获取当前请求的traceId，然后设置到header中：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RestTemplateInterceptor</span> <span class="keyword">implements</span> <span class="title class_">ClientHttpRequestInterceptor</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> ClientHttpResponse <span class="title function_">intercept</span><span class="params">(HttpRequest request, <span class="type">byte</span>[] body, ClientHttpRequestExecution execution)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        request.getHeaders().set(<span class="string">&quot;traceId&quot;</span>, MdcUtil.get());</span><br><span class="line">        <span class="keyword">return</span> execution.execute(request, body);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>第三步，定义配置类，配置上面定义的<code>RestTemplateInterceptor</code>类：</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Configuration</span></span><br><span class="line">publicclass RestTemplateConfiguration &#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> RestTemplate <span class="title function_">restTemplate</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">RestTemplate</span> <span class="variable">restTemplate</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RestTemplate</span>();</span><br><span class="line">        restTemplate.setInterceptors(Collections.singletonList(restTemplateInterceptor()));</span><br><span class="line">        <span class="keyword">return</span> restTemplate;</span><br><span class="line">    &#125;</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> RestTemplateInterceptor <span class="title function_">restTemplateInterceptor</span><span class="params">()</span> &#123;</span><br><span class="line">        returnnew <span class="title function_">RestTemplateInterceptor</span><span class="params">()</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>其中MdcUtil其实是利用MDC工具在ThreadLocal中存储和获取traceId</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">public</span> <span class="keyword">class</span> <span class="title class_">MdcUtil</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">TRACE_ID</span> <span class="operator">=</span> <span class="string">&quot;TRACE_ID&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> MDC.get(TRACE_ID);</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> <span class="keyword">void</span> <span class="title function_">add</span><span class="params">(String value)</span> &#123;</span><br><span class="line">        MDC.put(TRACE_ID, value);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>当然，这个例子中没有演示MdcUtil类的add方法具体调的地方，我们可以在filter中执行接口方法之前，生成traceId，调用MdcUtil类的add方法添加到MDC中，然后在同一个请求的其他地方就能通过MdcUtil类的get方法获取到该traceId。</p><p>能使用MDC保存traceId等参数的根本原因是，用户请求到应用服务器，Tomcat会从线程池中分配一个线程去处理该请求。</p><p>那么该请求的整个过程中，保存到MDC的ThreadLocal中的参数，也是该线程独享的，所以不会有线程安全问题。</p><h2 id="10-classutils"><a class="markdownIt-Anchor" href="#10-classutils"></a> 10. ClassUtils</h2><p>spring的<code>org.springframework.util</code>包下的<code>ClassUtils</code>类，它里面有很多让我们惊喜的功能。</p><p>它里面包含了类和对象相关的很多非常实用的方法。</p><h3 id="101-获取对象的所有接口"><a class="markdownIt-Anchor" href="#101-获取对象的所有接口"></a> 10.1 获取对象的所有接口</h3><p>如果你想获取某个对象的所有接口，可以使用ClassUtils的<code>getAllInterfaces</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Class&lt;?&gt;[] allInterfaces = ClassUtils.getAllInterfaces(<span class="keyword">new</span> <span class="title class_">User</span>());</span><br></pre></td></tr></table></figure><h3 id="102-获取某个类的包名"><a class="markdownIt-Anchor" href="#102-获取某个类的包名"></a> 10.2 获取某个类的包名</h3><p>如果你想获取某个类的包名，可以使用ClassUtils的<code>getPackageName</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">packageName</span> <span class="operator">=</span> ClassUtils.getPackageName(User.class);</span><br><span class="line">System.out.println(packageName);</span><br></pre></td></tr></table></figure><h3 id="103-判断某个类是否内部类"><a class="markdownIt-Anchor" href="#103-判断某个类是否内部类"></a> 10.3 判断某个类是否内部类</h3><p>如果你想判断某个类是否内部类，可以使用ClassUtils的<code>isInnerClass</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">System.out.println(ClassUtils.isInnerClass(User.class));</span><br></pre></td></tr></table></figure><h3 id="104-判断对象是否代理对象"><a class="markdownIt-Anchor" href="#104-判断对象是否代理对象"></a> 10.4 判断对象是否代理对象</h3><p>如果你想判断对象是否代理对象，可以使用ClassUtils的<code>isCglibProxy</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">System.out.println(ClassUtils.isCglibProxy(<span class="keyword">new</span> <span class="title class_">User</span>()));</span><br></pre></td></tr></table></figure><p>ClassUtils还有很多有用的方法，等待着你去发掘。感兴趣的朋友，可以看看下面内容：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799082569836_20260705182538A028.png" alt="图片" /></p><h2 id="11-beanutils"><a class="markdownIt-Anchor" href="#11-beanutils"></a> 11. BeanUtils</h2><p>spring给我们提供了一个<code>JavaBean</code>的工具类，它在<code>org.springframework.beans</code>包下面，它的名字叫做：<code>BeanUtils</code>。</p><p>让我们一起看看这个工具可以带给我们哪些惊喜。</p><h3 id="111-拷贝对象的属性"><a class="markdownIt-Anchor" href="#111-拷贝对象的属性"></a> 11.1 拷贝对象的属性</h3><p>曾几何时，你有没有这样的需求：把某个对象中的所有属性，都拷贝到另外一个对象中。这时就能使用BeanUtils的<code>copyProperties</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">User</span> <span class="variable">user1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">user1.setId(<span class="number">1L</span>);</span><br><span class="line">user1.setName(<span class="string">&quot;苏三说技术&quot;</span>);</span><br><span class="line">user1.setAddress(<span class="string">&quot;成都&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="type">User</span> <span class="variable">user2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">User</span>();</span><br><span class="line">BeanUtils.copyProperties(user1, user2);</span><br><span class="line">System.out.println(user2);</span><br></pre></td></tr></table></figure><h3 id="112-实例化某个类"><a class="markdownIt-Anchor" href="#112-实例化某个类"></a> 11.2 实例化某个类</h3><p>如果你想通过反射实例化一个类的对象，可以使用BeanUtils的<code>instantiateClass</code>方法。例如：</p><figure class="highlight java"><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="type">User</span> <span class="variable">user</span> <span class="operator">=</span> BeanUtils.instantiateClass(User.class);</span><br><span class="line">System.out.println(user);</span><br></pre></td></tr></table></figure><h3 id="113-获取指定类的指定方法"><a class="markdownIt-Anchor" href="#113-获取指定类的指定方法"></a> 11.3 获取指定类的指定方法</h3><p>如果你想获取某个类的指定方法，可以使用BeanUtils的<code>findDeclaredMethod</code>方法。例如：</p><figure class="highlight java"><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="type">Method</span> <span class="variable">declaredMethod</span> <span class="operator">=</span> BeanUtils.findDeclaredMethod(User.class, <span class="string">&quot;getId&quot;</span>);</span><br><span class="line">System.out.println(declaredMethod.getName());</span><br></pre></td></tr></table></figure><h3 id="114-获取指定方法的参数"><a class="markdownIt-Anchor" href="#114-获取指定方法的参数"></a> 11.4 获取指定方法的参数</h3><p>如果你想获取某个方法的参数，可以使用BeanUtils的<code>findPropertyForMethod</code>方法。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">Method</span> <span class="variable">declaredMethod</span> <span class="operator">=</span> BeanUtils.findDeclaredMethod(User.class, <span class="string">&quot;getId&quot;</span>);</span><br><span class="line"><span class="type">PropertyDescriptor</span> <span class="variable">propertyForMethod</span> <span class="operator">=</span> BeanUtils.findPropertyForMethod(declaredMethod);</span><br><span class="line">System.out.println(propertyForMethod.getName());</span><br></pre></td></tr></table></figure><p>如果你对BeanUtils比较感兴趣，可以看看下面内容：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799082880539_20260705182540A029.png" alt="图片" /></p><h2 id="12-reflectionutils"><a class="markdownIt-Anchor" href="#12-reflectionutils"></a> 12. ReflectionUtils</h2><p>有时候，我们需要在项目中使用<code>反射</code>功能，如果使用最原始的方法来开发，代码量会非常多，而且很麻烦，它需要处理一大堆异常以及访问权限等问题。</p><p>好消息是spring给我们提供了一个<code>ReflectionUtils</code>工具，它在<code>org.springframework.util</code>包下面。</p><h3 id="121-获取方法"><a class="markdownIt-Anchor" href="#121-获取方法"></a> 12.1 获取方法</h3><p>如果你想获取某个类的某个方法，可以使用ReflectionUtils类的<code>findMethod</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Method</span> <span class="variable">method</span> <span class="operator">=</span> ReflectionUtils.findMethod(User.class, <span class="string">&quot;getId&quot;</span>);</span><br></pre></td></tr></table></figure><h3 id="122-获取字段"><a class="markdownIt-Anchor" href="#122-获取字段"></a> 12.2 获取字段</h3><p>如果你想获取某个类的某个字段，可以使用ReflectionUtils类的<code>findField</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">Field</span> <span class="variable">field</span> <span class="operator">=</span> ReflectionUtils.findField(User.class, <span class="string">&quot;id&quot;</span>);</span><br></pre></td></tr></table></figure><h3 id="123-执行方法"><a class="markdownIt-Anchor" href="#123-执行方法"></a> 12.3 执行方法</h3><p>如果你想通过反射调用某个方法，传递参数，可以使用ReflectionUtils类的<code>invokeMethod</code>方法。例如：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ReflectionUtils.invokeMethod(method, springContextsUtil.getBean(beanName), param);</span><br></pre></td></tr></table></figure><h3 id="124-判断字段是否常量"><a class="markdownIt-Anchor" href="#124-判断字段是否常量"></a> 12.4 判断字段是否常量</h3><p>如果你想判断某个字段是否常量，可以使用ReflectionUtils类的<code>isPublicStaticFinal</code>方法。例如：</p><figure class="highlight java"><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="type">Field</span> <span class="variable">field</span> <span class="operator">=</span> ReflectionUtils.findField(User.class, <span class="string">&quot;id&quot;</span>);</span><br><span class="line">System.out.println(ReflectionUtils.isPublicStaticFinal(field));</span><br></pre></td></tr></table></figure><h3 id="125-判断是否equals方法"><a class="markdownIt-Anchor" href="#125-判断是否equals方法"></a> 12.5 判断是否equals方法</h3><p>如果你想判断某个方法是否equals方法，可以使用ReflectionUtils类的<code>isEqualsMethod</code>方法。例如：</p><figure class="highlight java"><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="type">Method</span> <span class="variable">method</span> <span class="operator">=</span> ReflectionUtils.findMethod(User.class, <span class="string">&quot;getId&quot;</span>);</span><br><span class="line">System.out.println(ReflectionUtils.isEqualsMethod(method));</span><br></pre></td></tr></table></figure><p>当然这个类还有不少有趣的方法，感兴趣的朋友，可以看看下面内容：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799083134142_20260705182543A030.png" alt="图片" /></p><h2 id="13-base64utils"><a class="markdownIt-Anchor" href="#13-base64utils"></a> 13. Base64Utils</h2><p>有时候，为了安全考虑，需要将参数只用<code>base64</code>编码。</p><p>这时就能直接使用<code>org.springframework.util</code>包下的<code>Base64Utils</code>工具类。</p><p>它里面包含：<code>encode</code>和<code>decode</code>方法，用于对数据进行加密和解密。例如：</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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">&quot;abc&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">encode</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(Base64Utils.encode(str.getBytes()));</span><br><span class="line">System.out.println(<span class="string">&quot;加密后：&quot;</span> + encode);</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">decode</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(Base64Utils.decode(encode.getBytes()), <span class="string">&quot;utf8&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;解密后：&quot;</span> + decode);</span><br><span class="line">&#125; <span class="keyword">catch</span> (UnsupportedEncodingException e) &#123;</span><br><span class="line">    e.printStackTrace();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>执行结果：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">加密后：YWJj</span><br><span class="line">解密后：abc</span><br></pre></td></tr></table></figure><h2 id="14-standardcharsets"><a class="markdownIt-Anchor" href="#14-standardcharsets"></a> 14. StandardCharsets</h2><p>我们在做字符转换的时候，经常需要指定字符编码，比如：UTF-8、ISO-8859-1等等。</p><p>这时就可以直接使用<code>java.nio.charset</code>包下的<code>StandardCharsets</code>类中静态变量。</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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">&quot;abc&quot;</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">encode</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(Base64Utils.encode(str.getBytes()));</span><br><span class="line">System.out.println(<span class="string">&quot;加密后：&quot;</span> + encode);</span><br><span class="line"><span class="type">String</span> <span class="variable">decode</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(Base64Utils.decode(encode.getBytes())</span><br><span class="line">, StandardCharsets.UTF_8);</span><br><span class="line">System.out.println(<span class="string">&quot;解密后：&quot;</span> + decode);</span><br></pre></td></tr></table></figure><h2 id="15-digestutils"><a class="markdownIt-Anchor" href="#15-digestutils"></a> 15. DigestUtils</h2><p>有时候，我们需要对数据进行加密处理，比如：md5或sha256。</p><p>可以使用apache的<code>org.apache.commons.codec.digest</code>包下的<code>DigestUtils</code>类。</p><h3 id="151-md5加密"><a class="markdownIt-Anchor" href="#151-md5加密"></a> 15.1 md5加密</h3><p>如果你想对数据进行md5加密，可以使用DigestUtils的<code>md5Hex</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">md5Hex</span> <span class="operator">=</span> DigestUtils.md5Hex(<span class="string">&quot;苏三说技术&quot;</span>);</span><br><span class="line">System.out.println(md5Hex);</span><br></pre></td></tr></table></figure><h3 id="152-sha256加密"><a class="markdownIt-Anchor" href="#152-sha256加密"></a> 15.2 sha256加密</h3><p>如果你想对数据进行sha256加密，可以使用DigestUtils的<code>sha256Hex</code>方法。例如：</p><figure class="highlight java"><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="type">String</span> <span class="variable">md5Hex</span> <span class="operator">=</span> DigestUtils.sha256Hex(<span class="string">&quot;苏三说技术&quot;</span>);</span><br><span class="line">System.out.println(md5Hex);</span><br></pre></td></tr></table></figure><p>当然这个工具还有很多其他的加密方法：<img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799083647945_20260705182549A031.png" alt="图片" /></p><h2 id="16-serializationutils"><a class="markdownIt-Anchor" href="#16-serializationutils"></a> 16. SerializationUtils</h2><p>有时候，我们需要把数据进行<code>序列化</code>和<code>反序列化</code>处理。</p><p>传统的做法是某个类实现<code>Serializable</code>接口，然后重新它的<code>writeObject</code>和<code>readObject</code>方法。</p><p>但如果使用<code>org.springframework.util</code>包下的<code>SerializationUtils</code>工具类，能更轻松实现序列化和反序列化功能。例如：</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></pre></td><td class="code"><pre><span class="line">Map&lt;String, String&gt; map = Maps.newHashMap();</span><br><span class="line">map.put(<span class="string">&quot;a&quot;</span>, <span class="string">&quot;1&quot;</span>);</span><br><span class="line">map.put(<span class="string">&quot;b&quot;</span>, <span class="string">&quot;2&quot;</span>);</span><br><span class="line">map.put(<span class="string">&quot;c&quot;</span>, <span class="string">&quot;3&quot;</span>);</span><br><span class="line"><span class="type">byte</span>[] serialize = SerializationUtils.serialize(map);</span><br><span class="line"><span class="type">Object</span> <span class="variable">deserialize</span> <span class="operator">=</span> SerializationUtils.deserialize(serialize);</span><br><span class="line">System.out.println(deserialize);</span><br></pre></td></tr></table></figure><h2 id="17-httpstatus"><a class="markdownIt-Anchor" href="#17-httpstatus"></a> 17. HttpStatus</h2><p>很多时候，我们会在代码中定义http的返回码，比如：接口正常返回200，异常返回500，接口找不到返回404，接口不可用返回502等。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="type">int</span> <span class="variable">SUCCESS_CODE</span> <span class="operator">=</span> <span class="number">200</span>;</span><br><span class="line"><span class="keyword">private</span> <span class="type">int</span> <span class="variable">ERROR_CODE</span> <span class="operator">=</span> <span class="number">500</span>;</span><br><span class="line"><span class="keyword">private</span> <span class="type">int</span> <span class="variable">NOT_FOUND_CODE</span> <span class="operator">=</span> <span class="number">404</span>;</span><br></pre></td></tr></table></figure><p>其实<code>org.springframework.http</code>包下的HttpStatus枚举，或者<code>org.apache.http</code>包下的<code>HttpStatus</code>接口，已经把常用的http返回码给我们定义好了，直接拿来用就可以了，真的不用再重复定义了。</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/640-174799083940548_20260705182551A032.png" alt="图片" /></p>]]></content>
    
    
    <summary type="html">假舆马者，非利足也，而致千里</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>pnpm包管理器详解</title>
    <link href="https://luckynwa.top/posts/front12/"/>
    <id>https://luckynwa.top/posts/front12/</id>
    <published>2024-12-17T01:17:54.000Z</published>
    <updated>2026-07-07T16:19:34.070Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p><strong>pnpm</strong>，全称是&quot;performant npm&quot;，意为&quot;高性能的npm&quot;，是一个现代的 JavaScript 包管理工具，类似于 npm 和 Yarn，用来管理项目中的依赖包。</p><h2 id="优势"><a class="markdownIt-Anchor" href="#优势"></a> 优势</h2><ol><li><p><strong>高效的磁盘利用</strong><br />pnpm 采用了独特的<strong>硬链接（hard link）技术</strong>，把所有项目共用的依赖包存放在全局的缓存目录里，不同项目之间不会重复安装相同的包，节省磁盘空间。</p></li><li><p><strong>快速安装</strong><br />因为依赖共享在缓存，安装速度比传统的 npm 和 Yarn 更快，尤其是在多个项目都使用相同依赖时优势明显。</p></li><li><p><strong>严格的依赖隔离</strong><br />pnpm 默认用的是严格的节点模块结构，避免了&quot;平滑依赖&quot;问题，能帮你发现项目中缺失的依赖，减少&quot;偶然能运行&quot;的情况，提高代码的可维护性。</p></li><li><p><strong>兼容 npm/Yarn</strong><br />pnpm 能安装 npm registry 上的包，且支持大多数 npm/yarn 的命令和配置，切换成本低。</p></li><li><p><strong>支持工作区（monorepo）</strong><br />pnpm 原生支持 monorepo 项目结构，方便管理多个包的复杂项目。</p></li></ol><h2 id="为什么使用-pnpm"><a class="markdownIt-Anchor" href="#为什么使用-pnpm"></a> 为什么使用 pnpm</h2><p>在使用之前，先了解 npm 和 yarn（特指 yarn v1）存在的问题。</p><p>扁平化的 <code>node_modules</code> 解决了&quot;依赖地狱&quot;问题，但出现了以下问题：</p><h3 id="1-幽灵依赖phantom-dependencies"><a class="markdownIt-Anchor" href="#1-幽灵依赖phantom-dependencies"></a> 1. 幽灵依赖（Phantom Dependencies）</h3><p>举个例子：你的项目只安装了 <code>A</code> 包（<code>npm install A</code>）。但是 <code>A</code> 包自己依赖了 <code>B</code> 包。因为是扁平化结构，<code>B</code> 包也会被提升到 <code>node_modules</code> 的根目录。</p><p>结果就是，你在你的代码里，明明没有在 <code>package.json</code> 里声明过 <code>B</code>，但你却可以 <code>import B from 'B'</code>，而且代码还能正常运行！</p><p>这就是&quot;幽灵依赖&quot;。它像一个幽灵，让你的项目依赖关系变得混乱不堪。万一有一天，<code>A</code> 包升级了，不再依赖 <code>B</code> 了，你的项目就会在某个意想不到的地方突然崩溃。</p><h3 id="2-磁盘空间的巨大浪费"><a class="markdownIt-Anchor" href="#2-磁盘空间的巨大浪费"></a> 2. 磁盘空间的巨大浪费</h3><p>如果你电脑上有 10 个项目，这 10 个项目都依赖了 <code>lodash</code>，那么在 npm/yarn 的模式下，你的磁盘上就会实实在在地存着 <strong>10 份</strong> 一模一样的 <code>lodash</code> 代码。</p><h3 id="3-安装速度的瓶颈"><a class="markdownIt-Anchor" href="#3-安装速度的瓶颈"></a> 3. 安装速度的瓶颈</h3><p>虽然 npm 和 yarn 都有缓存机制，但在安装依赖时，它们仍然需要做大量的 I/O 操作，去复制、移动那些文件。当项目越来越大，<code>node_modules</code> 动辄上 G 的时候，安装速度会很慢。</p><h2 id="符号链接"><a class="markdownIt-Anchor" href="#符号链接"></a> 符号链接</h2><h3 id="1-彻底告别幽灵依赖"><a class="markdownIt-Anchor" href="#1-彻底告别幽灵依赖"></a> 1. 彻底告别&quot;幽灵依赖&quot;</h3><p>在 pnpm 的 <code>node_modules</code> 里，你只会看到你在 <code>package.json</code> 里 <strong>明确声明</strong> 的那些依赖。</p><p>你项目里依赖的 <code>A</code> 包，它自己所依赖的 <code>B</code> 包，会被存放在 <code>node_modules/.pnpm/</code> 这个特殊的目录里，然后通过 <strong>符号链接（Symbolic Link）</strong> 的方式，链接到 <code>A</code> 包的 <code>node_modules</code> 里。</p><p>这意味着，在你的项目代码里，你根本访问不到 <code>B</code> 包。你想 <code>import B</code>？对不起，直接报错。这就从结构上保证了，你的项目依赖关系是绝对可靠和纯净的。</p><h3 id="2-磁盘空间的终极节约"><a class="markdownIt-Anchor" href="#2-磁盘空间的终极节约"></a> 2. 磁盘空间的&quot;终极节约&quot;</h3><p>pnpm 会在你的电脑上创建一个&quot;全局内容可寻址存储区&quot;（content-addressable store），通常在用户主目录下的 <code>.pnpm-store</code> 里。</p><p>你电脑上所有项目的所有依赖，<strong>都只会在这个全局仓库里，实实在在地只存一份</strong>。</p><p>当你的项目需要 <code>lodash</code> 时，pnpm 不会去复制一份 <code>lodash</code> 到你的 <code>node_modules</code> 里，而是通过 <strong>硬链接（Hard Link）</strong> 的方式，从全局仓库链接一份过来。硬链接几乎不占用磁盘空间。</p><p>这意味着，就算你有 100 个项目都用了 <code>lodash</code>，它在你的硬盘上也只占一份的空间。这个特性，对于磁盘空间紧张的同学来说，简直是福音。</p><h3 id="3-极速的安装体验"><a class="markdownIt-Anchor" href="#3-极速的安装体验"></a> 3. 极速的安装体验</h3><p>因为大部分依赖都是通过&quot;链接&quot;的方式实现的，而不是&quot;复制&quot;，所以 pnpm 在安装依赖时，大大减少了磁盘 I/O 操作。</p><p>它的安装速度，尤其是在有缓存的情况下，或者在安装一个已经存在于全局仓库里的包时，几乎是&quot;秒级&quot;的。这种&quot;飞一般&quot;的感觉，一旦体验过，就再也回不去了。</p>]]></content>
    
    
    <summary type="html">温故而知新，可以为师矣</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>JavaScript防抖与节流详解</title>
    <link href="https://luckynwa.top/posts/front9/"/>
    <id>https://luckynwa.top/posts/front9/</id>
    <published>2024-11-25T23:56:53.000Z</published>
    <updated>2026-07-07T16:19:34.029Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>当涉及到处理频繁触发的事件或函数时，防抖和节流是两种常用的技术，用于优化性能和改善用户体验。</p><h2 id="防抖"><a class="markdownIt-Anchor" href="#防抖"></a> 防抖</h2><p>防抖用于限制连续触发的事件的执行频率。当一个事件被触发时，防抖会延迟一定的时间执行对应的处理函数。如果在延迟时间内再次触发了同样的事件，那么之前的延迟执行将被取消，重新开始计时。</p><p><strong>总结：在单位时间内频繁触发事件，只有最后一次生效</strong></p><p><strong>应用场景：</strong></p><ul><li>用户在输入框输入字符时，全部输入完成才发送请求</li><li>鼠标悬浮在图表时，将 ToolsTip 里的数据回显到头部（避免多次请求后端接口）</li></ul><h3 id="vue-中实现防抖"><a class="markdownIt-Anchor" href="#vue-中实现防抖"></a> Vue 中实现防抖</h3><figure class="highlight javascript"><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="comment">// 防抖方法，传入函数和延迟</span></span><br><span class="line"><span class="title function_">debounce</span>(<span class="params">fn, delay</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> timer = <span class="literal">null</span>;              <span class="comment">// 默认是空</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (timer) &#123;                 <span class="comment">// 如果存在则</span></span><br><span class="line">      <span class="built_in">clearTimeout</span>(timer);       <span class="comment">// 清空定时器</span></span><br><span class="line">    &#125;</span><br><span class="line">    timer = <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;   <span class="comment">// 赋值定时器</span></span><br><span class="line">      <span class="title function_">fn</span>();</span><br><span class="line">    &#125;, delay);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="监听-echarts-的-tooltip-事件"><a class="markdownIt-Anchor" href="#监听-echarts-的-tooltip-事件"></a> 监听 echarts 的 tooltip 事件</h3><figure class="highlight javascript"><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="keyword">let</span> charts = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;line_charts&#x27;</span>)</span><br><span class="line"><span class="keyword">let</span> myChart = <span class="variable language_">this</span>.<span class="property">$echarts</span>.<span class="title function_">init</span>(charts)</span><br><span class="line">myChart.<span class="title function_">on</span>(</span><br><span class="line">  <span class="string">&#x27;showTip&#x27;</span>,</span><br><span class="line">  <span class="variable language_">this</span>.<span class="title function_">debounce</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    that.<span class="title function_">getData</span>()</span><br><span class="line">  &#125;, <span class="number">2000</span>),</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h3 id="监听-input-输入框"><a class="markdownIt-Anchor" href="#监听-input-输入框"></a> 监听 input 输入框</h3><figure class="highlight javascript"><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="keyword">const</span> inputDOM = <span class="variable language_">document</span>.<span class="title function_">getElementById</span>(<span class="string">&#x27;input&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">debounce</span>(<span class="params">fn, delay</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> timer = <span class="literal">null</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (timer) &#123;</span><br><span class="line">      <span class="built_in">clearTimeout</span>(timer)</span><br><span class="line">    &#125;</span><br><span class="line">    timer = <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">fn</span>()</span><br><span class="line">    &#125;, delay)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">inputDOM.<span class="title function_">addEventListener</span>(</span><br><span class="line">  <span class="string">&#x27;input&#x27;</span>,</span><br><span class="line">  <span class="title function_">debounce</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;发送请求&#x27;</span>)</span><br><span class="line">  &#125;, <span class="number">500</span>),</span><br><span class="line">)</span><br></pre></td></tr></table></figure><h2 id="节流"><a class="markdownIt-Anchor" href="#节流"></a> 节流</h2><p>节流是一种限制函数执行频率的技术。它可以确保在某个时间段内，函数不会被连续触发执行，而是以一定的时间间隔执行。</p><p><strong>总结：一段时间内只执行一次</strong></p><p><strong>应用场景：</strong></p><ul><li>验证码刷新</li><li>窗口滚动</li><li>鼠标点击等频繁触发的事件</li></ul><h3 id="通用节流函数"><a class="markdownIt-Anchor" href="#通用节流函数"></a> 通用节流函数</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 节流：一段时间内只执行一次</span></span><br><span class="line"><span class="comment">// 第一次执行 cd 为 true，执行定时器</span></span><br><span class="line"><span class="comment">// 快速第二次进入时，由于定时器还没有结束，cd 为 true，所以不执行</span></span><br><span class="line"><span class="comment">// 等待定时器结束，cd 为 false，执行新一轮</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">throttle</span>(<span class="params">fn, delay</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> cd = <span class="literal">false</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (cd) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;节流中&#x27;</span>)</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    cd = <span class="literal">true</span></span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="title function_">fn</span>()</span><br><span class="line">      cd = <span class="literal">false</span></span><br><span class="line">    &#125;, delay)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">学如逆水行舟，不进则退</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://luckynwa.top/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>JavaScript日期格式转换方法详解</title>
    <link href="https://luckynwa.top/posts/front8/"/>
    <id>https://luckynwa.top/posts/front8/</id>
    <published>2024-11-19T00:46:32.000Z</published>
    <updated>2026-07-07T16:19:33.858Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>日期转换在项目中经常需要使用，本文总结两种常用的时间转换方法。</p><h2 id="高级版dayjs"><a class="markdownIt-Anchor" href="#高级版dayjs"></a> 高级版：Day.js</h2><p>Day.js 是一个极简的 JavaScript 库，可以为现代浏览器解析、验证、操作和显示日期和时间。</p><p><a href="https://dayjs.fenxianglu.cn/category/manipulate.html#%E5%A2%9E%E5%8A%A0">Day.js 中文网</a></p><h3 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i dayjs</span><br></pre></td></tr></table></figure><h3 id="全局引入vue-2"><a class="markdownIt-Anchor" href="#全局引入vue-2"></a> 全局引入（Vue 2）</h3><figure class="highlight javascript"><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="keyword">import</span> dayjs <span class="keyword">from</span> <span class="string">&#x27;dayjs&#x27;</span></span><br><span class="line"><span class="title class_">Vue</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">dayjs</span> = dayjs</span><br></pre></td></tr></table></figure><h3 id="使用示例"><a class="markdownIt-Anchor" href="#使用示例"></a> 使用示例</h3><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">  <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span><br><span class="line"><span class="language-javascript">    <span class="attr">methods</span>: &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="title function_">init</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 基础调用</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> nowTime0 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">unix</span>() <span class="comment">// 时间戳（秒）</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> nowTime2 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">format</span>(<span class="string">&#x27;YYYY/MM/DD&#x27;</span>) <span class="comment">// 年月日格式化</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> nowTime3 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">format</span>(<span class="string">&#x27;YYYY-MM-DD HH:mm:ss&#x27;</span>) <span class="comment">// 年月日时分秒</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">var</span> nowTime4 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">valueOf</span>() <span class="comment">// 时间戳（毫秒）</span></span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 获取当天的开始和结束时间</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> nowStartDay = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">startOf</span>(<span class="string">&#x27;day&#x27;</span>).<span class="title function_">format</span>(<span class="string">&#x27;YYYY-MM-DD HH:mm:ss.SSS&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> nowEndDay = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>().<span class="title function_">startOf</span>(<span class="string">&#x27;day&#x27;</span>).<span class="title function_">format</span>(<span class="string">&#x27;YYYY-MM-DD HH:mm:ss.SSS&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 计算时间差</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> date1 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>(<span class="string">&#x27;2023-01-10&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> date2 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>(<span class="string">&#x27;2023-11-10&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> diffDay = date2.<span class="title function_">diff</span>(date1, <span class="string">&#x27;d&#x27;</span>) <span class="comment">// 时间差（天）</span></span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 时间戳转日期格式</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> convertTime1 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>(<span class="number">1706753478000</span>).<span class="title function_">format</span>(<span class="string">&#x27;YYYY-MM-DD HH:mm&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript"></span></span><br><span class="line"><span class="language-javascript">        <span class="comment">// 日期字符串格式化</span></span></span><br><span class="line"><span class="language-javascript">        <span class="keyword">const</span> convertTime2 = <span class="variable language_">this</span>.<span class="title function_">dayjs</span>(<span class="string">&#x27;2024/01/29 08:55:18&#x27;</span>).<span class="title function_">format</span>(<span class="string">&#x27;YYYY-MM-DD HH:mm&#x27;</span>)</span></span><br><span class="line"><span class="language-javascript">      &#125;,</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">    <span class="title function_">created</span>(<span class="params"></span>) &#123;</span></span><br><span class="line"><span class="language-javascript">      <span class="variable language_">this</span>.<span class="title function_">init</span>()</span></span><br><span class="line"><span class="language-javascript">    &#125;,</span></span><br><span class="line"><span class="language-javascript">  &#125;</span></span><br><span class="line"><span class="language-javascript"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="初级版原生-javascript"><a class="markdownIt-Anchor" href="#初级版原生-javascript"></a> 初级版：原生 JavaScript</h2><h3 id="日期数组转换"><a class="markdownIt-Anchor" href="#日期数组转换"></a> 日期数组转换</h3><p>将后端传来的日期数组：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">;[<span class="string">&#x27;2024/01/29 08:55:18&#x27;</span>, <span class="string">&#x27;2024/01/29 09:55:18&#x27;</span>, <span class="string">&#x27;2024/01/29 10:11:18&#x27;</span>]</span><br></pre></td></tr></table></figure><p>转为：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">;[<span class="string">&#x27;2024-01-29 08:55&#x27;</span>, <span class="string">&#x27;2024-01-29 09:55&#x27;</span>, <span class="string">&#x27;2024-01-29 10:11&#x27;</span>]</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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="title function_">convertDateTimeFormat</span>(<span class="params">arr</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> tempArr = arr.<span class="title function_">map</span>(<span class="keyword">function</span> (<span class="params">dateTime</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> date = <span class="keyword">new</span> <span class="title class_">Date</span>(dateTime)</span><br><span class="line">    <span class="keyword">var</span> formattedDateTime =</span><br><span class="line">      date.<span class="title function_">getFullYear</span>() + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">      (<span class="string">&#x27;0&#x27;</span> + (date.<span class="title function_">getMonth</span>() + <span class="number">1</span>)).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">      (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getDate</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27; &#x27;</span> +</span><br><span class="line">      (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getHours</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;:&#x27;</span> +</span><br><span class="line">      (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getMinutes</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>)</span><br><span class="line">    <span class="keyword">return</span> formattedDateTime</span><br><span class="line">  &#125;)</span><br><span class="line">  <span class="keyword">return</span> tempArr</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="单个日期字符串转换"><a class="markdownIt-Anchor" href="#单个日期字符串转换"></a> 单个日期字符串转换</h3><p>输入：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;2024/01/29 08:55:18&#x27;</span></span><br></pre></td></tr></table></figure><p>输出：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;2024-01-29 08:55&#x27;</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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="title function_">convertDateTimeFormat</span>(<span class="params">dateTime</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> date = <span class="keyword">new</span> <span class="title class_">Date</span>(dateTime)</span><br><span class="line">  <span class="keyword">var</span> formattedDateTime =</span><br><span class="line">    date.<span class="title function_">getFullYear</span>() + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + (date.<span class="title function_">getMonth</span>() + <span class="number">1</span>)).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getDate</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27; &#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getHours</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;:&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getMinutes</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>)</span><br><span class="line">  <span class="keyword">return</span> formattedDateTime</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="时间戳转换"><a class="markdownIt-Anchor" href="#时间戳转换"></a> 时间戳转换</h3><p>输入：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> curveTimestamp = <span class="number">1706753478000</span></span><br></pre></td></tr></table></figure><p>输出：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">&#x27;2024-02-01 10:11&#x27;</span></span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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="title function_">convertDateTimeFormat</span>(<span class="params">timestamp</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> date = <span class="keyword">new</span> <span class="title class_">Date</span>(timestamp)</span><br><span class="line">  <span class="keyword">var</span> formattedDateTime =</span><br><span class="line">    date.<span class="title function_">getFullYear</span>() + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + (date.<span class="title function_">getMonth</span>() + <span class="number">1</span>)).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;-&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getDate</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27; &#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getHours</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>) + <span class="string">&#x27;:&#x27;</span> +</span><br><span class="line">    (<span class="string">&#x27;0&#x27;</span> + date.<span class="title function_">getMinutes</span>()).<span class="title function_">slice</span>(-<span class="number">2</span>)</span><br><span class="line">  <span class="keyword">return</span> formattedDateTime</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">天行健，君子以自强不息</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://luckynwa.top/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>JavaScript数组常用方法详解</title>
    <link href="https://luckynwa.top/posts/front7/"/>
    <id>https://luckynwa.top/posts/front7/</id>
    <published>2024-11-11T18:44:34.000Z</published>
    <updated>2026-07-07T16:19:33.878Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>数组方法参数说明：</p><ul><li><code>item</code>：每个元素值（必填）</li><li><code>index</code>：索引（可选）</li><li><code>arr</code>：当前数组（可选）</li></ul><p>推荐使用 VSCode 插件 <strong>Quokka.js</strong>，可以直接在 js 文件中显示运行结果。</p><h2 id="常规方法"><a class="markdownIt-Anchor" href="#常规方法"></a> 常规方法</h2><blockquote><p>以下方法中，标注 <strong>改变原数组</strong> 的方法会直接修改原数组</p></blockquote><h3 id="改变原数组的方法"><a class="markdownIt-Anchor" href="#改变原数组的方法"></a> 改变原数组的方法</h3><table><thead><tr><th>方法</th><th>作用</th><th>返回值</th></tr></thead><tbody><tr><td><code>push()</code></td><td>末尾添加数据</td><td>数组的长度</td></tr><tr><td><code>pop()</code></td><td>末尾删除数据</td><td>删除的那个数据</td></tr><tr><td><code>unshift()</code></td><td>头部添加数据</td><td>数组的长度</td></tr><tr><td><code>shift()</code></td><td>头部删除数据</td><td>删除的那个数据</td></tr><tr><td><code>reverse()</code></td><td>翻转数组</td><td>翻转好的数组</td></tr><tr><td><code>sort()</code></td><td>排序</td><td>排序后的数组</td></tr></tbody></table><figure class="highlight javascript"><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">// sort() 排序示例</span></span><br><span class="line"><span class="keyword">var</span> myArray = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line">myArray.<span class="title function_">sort</span>() <span class="comment">// 没变化，正序</span></span><br><span class="line">myArray.<span class="title function_">sort</span>(<span class="function">(<span class="params">a, b</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> a - b</span><br><span class="line">&#125;) <span class="comment">// 从小到大</span></span><br><span class="line">myArray.<span class="title function_">sort</span>(<span class="function">(<span class="params">a, b</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="keyword">return</span> b - a</span><br><span class="line">&#125;) <span class="comment">// 从大到小</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(myArray)</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><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">// splice() 截取数组示例</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">var</span> res = arr.<span class="title function_">splice</span>(<span class="number">1</span>, <span class="number">2</span>) <span class="comment">// 参数1:开始索引, 参数2:截取个数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(res) <span class="comment">// [0, 44]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr) <span class="comment">// [1, 3]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// splice() 替换数组示例</span></span><br><span class="line"><span class="keyword">var</span> arr2 = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line">arr2.<span class="title function_">splice</span>(<span class="number">0</span>, arr2.<span class="property">length</span>, ...arr) <span class="comment">// 参数1表示开始索引,参数2表示多少个，后续可以无数个要插入的数据，这里用解构上面数组插入</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr2) <span class="comment">// [1, 3]</span></span><br></pre></td></tr></table></figure><h3 id="不改变原数组的方法"><a class="markdownIt-Anchor" href="#不改变原数组的方法"></a> 不改变原数组的方法</h3><table><thead><tr><th>方法</th><th>作用</th><th>返回值</th></tr></thead><tbody><tr><td><code>concat()</code></td><td>合并数组</td><td>新的数组</td></tr><tr><td><code>join()</code></td><td>数组转字符串</td><td>字符串</td></tr><tr><td><code>slice()</code></td><td>截取数组一部分</td><td>新的数组</td></tr></tbody></table><figure class="highlight javascript"><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="comment">// concat() 合并数组示例</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">var</span> res = arr.<span class="title function_">concat</span>(<span class="number">1</span>, <span class="number">2</span>) <span class="comment">//参数1表示开始索引,参数2表示截取2个</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(res)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arr) <span class="comment">// [1, 0, 44, 3]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// join() 数组转字符串示例</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">var</span> res = arr.<span class="title function_">join</span>(<span class="string">&#x27;-&#x27;</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(res) <span class="comment">// &#x27;1-0-44-3&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// slice() 截取数组示例（左闭合右开）</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">var</span> res = arr.<span class="title function_">slice</span>(<span class="number">1</span>, <span class="number">2</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(res) <span class="comment">// [0]</span></span><br></pre></td></tr></table></figure><h3 id="查找方法"><a class="markdownIt-Anchor" href="#查找方法"></a> 查找方法</h3><figure class="highlight javascript"><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">// indexOf() 从左查找</span></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>, <span class="number">0</span>, <span class="number">44</span>, <span class="number">3</span>]</span><br><span class="line">arr.<span class="title function_">indexOf</span>(<span class="number">44</span>) <span class="comment">// 返回索引 2</span></span><br><span class="line">arr.<span class="title function_">indexOf</span>(<span class="number">100</span>) <span class="comment">// 不存在返回 -1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// lastIndexOf() 从右查找</span></span><br><span class="line">arr.<span class="title function_">lastIndexOf</span>(<span class="number">44</span>) <span class="comment">// 返回索引 2</span></span><br><span class="line"></span><br><span class="line"><span class="title function_">dmeo1</span>(字符串中含-)</span><br><span class="line">      <span class="keyword">if</span>(s.<span class="title function_">indexof</span>(<span class="string">&#x27;-&#x27;</span>)&gt;<span class="number">0</span>)&#123;</span><br><span class="line">           <span class="keyword">let</span> parts= s.<span class="title function_">split</span>(<span class="string">&#x27;-&#x27;</span>)   切割成数组</span><br><span class="line">           parts[parts.<span class="property">length</span>-<span class="number">1</span>] <span class="comment">//获取最后一个的值</span></span><br><span class="line">     &#125;</span><br></pre></td></tr></table></figure><h2 id="数组遍历方法"><a class="markdownIt-Anchor" href="#数组遍历方法"></a> 数组遍历方法</h2><h3 id="forin"><a class="markdownIt-Anchor" href="#forin"></a> for…in</h3><p>遍历数组的<strong>索引</strong>（字符串型数字），会遍历所有可枚举属性，一般用于遍历对象。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myArray = [<span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line">myArray.<span class="property">name</span> = <span class="string">&#x27;name数组&#x27;</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> index <span class="keyword">in</span> myArray) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;字符串型数字:&#x27;</span>, index) <span class="comment">// &#x27;0&#x27; &#x27;1&#x27; &#x27;2&#x27;</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(myArray[index]) <span class="comment">// 1, 2, &quot;name数组&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="forof"><a class="markdownIt-Anchor" href="#forof"></a> for…of</h3><p>遍历数组的<strong>元素值</strong>。</p><figure class="highlight javascript"><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="keyword">let</span> arr = [</span><br><span class="line">  &#123; <span class="attr">name</span>: <span class="string">&#x27;张三&#x27;</span>, <span class="attr">age</span>: <span class="number">23</span> &#125;,</span><br><span class="line">  &#123; <span class="attr">name</span>: <span class="string">&#x27;张三&#x27;</span>, <span class="attr">age</span>: <span class="number">25</span> &#125;,</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> cont <span class="keyword">of</span> arr) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(cont) <span class="comment">// &#123;name:&#x27;张三&#x27;,age:23&#125;,&#123;name:&#x27;张三&#x27;,age:25&#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="foreach"><a class="markdownIt-Anchor" href="#foreach"></a> forEach</h3><p>不返回新数组，返回 undefined。不适合中止或跳出循环的情况，可直接修改原数组。</p><figure class="highlight javascript"><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 class="keyword">const</span> aa = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> a = aa.<span class="title function_">forEach</span>(<span class="function">(<span class="params">item, index, arr</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item, index, arr)</span><br><span class="line">  arr[index] = <span class="number">2</span> * item</span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// undefined</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(aa) <span class="comment">// [2, 4, 6, 8, 10, 12]</span></span><br></pre></td></tr></table></figure><h3 id="map"><a class="markdownIt-Anchor" href="#map"></a> map</h3><p>返回一个新的数组，遍历中没值返回 undefined，原数组不改变。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> bb = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, , <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> b = bb.<span class="title function_">map</span>(<span class="function">(<span class="params">item, index, arr</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(item)</span><br><span class="line">  <span class="keyword">return</span> <span class="number">2</span> * item</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">const</span> c = bb.<span class="title function_">map</span>(<span class="function">(<span class="params">v</span>) =&gt;</span> v * <span class="number">2</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b) <span class="comment">// [2, 4, 6, 8, undefined, 12]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(bb) <span class="comment">// [1, 2, 3, 4, undefined, 6]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c) <span class="comment">// [2, 4, 6, 8, undefined, 12]</span></span><br></pre></td></tr></table></figure><h3 id="every"><a class="markdownIt-Anchor" href="#every"></a> every</h3><p>返回布尔值，表示数组中所有元素是否都满足条件。顺序遍历，如果有一个不满足就打断并返回 false。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> cc = [<span class="number">11</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> c = cc.<span class="title function_">every</span>(<span class="function">(<span class="params">v</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(v) <span class="comment">// 11, 2</span></span><br><span class="line">  <span class="keyword">return</span> v &gt; <span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(c) <span class="comment">// false</span></span><br></pre></td></tr></table></figure><h3 id="some"><a class="markdownIt-Anchor" href="#some"></a> some</h3><p>返回布尔值，表示数组中是否存在满足条件的元素。顺序遍历，找到就马上返回 true，不再继续。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> dd = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> d = dd.<span class="title function_">some</span>(<span class="function">(<span class="params">v</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(v) <span class="comment">// 1, 2, 3</span></span><br><span class="line">  <span class="keyword">return</span> v &gt; <span class="number">2</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(d) <span class="comment">// true</span></span><br></pre></td></tr></table></figure><h3 id="find"><a class="markdownIt-Anchor" href="#find"></a> find</h3><p>返回数组中第一个满足条件的元素，都不满足则返回 undefined。findIndex 方法类似，返回索引，没找到则返回 -1。</p><figure class="highlight javascript"><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="keyword">const</span> ee = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> e = ee.<span class="title function_">find</span>(<span class="function">(<span class="params">v</span>) =&gt;</span> v &gt; <span class="number">3</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(e) <span class="comment">// 4</span></span><br></pre></td></tr></table></figure><h3 id="filter"><a class="markdownIt-Anchor" href="#filter"></a> filter</h3><p>返回一个新的数组，包含所有满足条件的元素。</p><figure class="highlight javascript"><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="keyword">const</span> ff = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="keyword">const</span> f = ff.<span class="title function_">filter</span>(<span class="function">(<span class="params">v</span>) =&gt;</span> v &gt; <span class="number">3</span>)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(f) <span class="comment">// [4, 5, 6]</span></span><br></pre></td></tr></table></figure><h3 id="reduce"><a class="markdownIt-Anchor" href="#reduce"></a> reduce</h3><p>返回一个值，通过将数组中的每个值（从左到右）应用 reducer 函数于初始值（或前一个结果）而计算得出。</p><p>参数说明：</p><ul><li><code>accumulator</code>：累加值，是上次返回的结果（必填）</li><li><code>currentValue</code>：当前元素（必填）</li><li><code>initValue</code>：初始值（可选），如果没有提供，则使用数组的第一个元素</li></ul><figure class="highlight javascript"><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 class="keyword">const</span> gg = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">const</span> initValue = <span class="number">0</span></span><br><span class="line"><span class="keyword">const</span> g = gg.<span class="title function_">reduce</span>(<span class="function">(<span class="params">accumulator, currentValue, index, arr</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(accumulator, currentValue) <span class="comment">// [0,1], [1,2], [3,3]</span></span><br><span class="line">  <span class="keyword">return</span> accumulator + currentValue</span><br><span class="line">&#125;, initValue)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(g) <span class="comment">// 6</span></span><br></pre></td></tr></table></figure><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><table><thead><tr><th>方法</th><th>作用</th><th>返回值</th></tr></thead><tbody><tr><td><code>forEach</code></td><td>遍历数组</td><td>undefined</td></tr><tr><td><code>map</code></td><td>映射转换</td><td>新数组</td></tr><tr><td><code>every</code></td><td>全部满足</td><td>布尔值</td></tr><tr><td><code>some</code></td><td>存在满足</td><td>布尔值</td></tr><tr><td><code>find</code></td><td>查找第一个</td><td>元素值</td></tr><tr><td><code>filter</code></td><td>过滤筛选</td><td>新数组</td></tr><tr><td><code>reduce</code></td><td>累加计算</td><td>计算结果</td></tr></tbody></table>]]></content>
    
    
    <summary type="html">千里之行，始于足下</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://luckynwa.top/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>JavaScript对象操作详解</title>
    <link href="https://luckynwa.top/posts/front6/"/>
    <id>https://luckynwa.top/posts/front6/</id>
    <published>2024-11-05T03:40:50.000Z</published>
    <updated>2026-07-07T16:19:34.024Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p><strong>浅拷贝：</strong> 创建一个新对象，但只复制了原始对象的第一层属性，而不是递归地复制整个对象的所有嵌套属性。新对象中的嵌套对象仍然是原始对象中嵌套对象的引用，修改新对象中的嵌套对象会影响原始对象。</p><p><strong>深拷贝：</strong> 创建一个全新的对象，同时递归地复制原始对象中的所有嵌套对象，使得新对象和原始对象完全独立，彼此不会互相影响。</p><p><strong>理解：</strong> 一个对象只有一层而且没有引用类型（对象|数组）时，用浅拷贝的方法效果和深拷贝是一样的，因为对于基本数据类型（如数字、字符串等），新对象会复制它们的值而不是引用。</p><h2 id="深拷贝实现"><a class="markdownIt-Anchor" href="#深拷贝实现"></a> 深拷贝实现</h2><h3 id="方法一jsonparse"><a class="markdownIt-Anchor" href="#方法一jsonparse"></a> 方法一：JSON.parse</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> target = &#123; <span class="attr">name</span>: <span class="string">&#x27;小艾&#x27;</span> &#125;</span><br><span class="line"><span class="keyword">let</span> source = &#123; <span class="attr">age</span>: <span class="number">20</span> &#125;</span><br><span class="line"><span class="keyword">let</span> deepClone = <span class="title class_">JSON</span>.<span class="title function_">parse</span>(<span class="title class_">JSON</span>.<span class="title function_">stringify</span>(target)) <span class="comment">// 深拷贝</span></span><br><span class="line">target.<span class="property">name</span> = <span class="string">&#x27;小羊&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(target) <span class="comment">// &#123; name: &#x27;小羊&#x27; &#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(deepClone) <span class="comment">// &#123; name: &#x27;小艾&#x27; &#125;</span></span><br></pre></td></tr></table></figure><h3 id="方法二lodash-的-clonedeep"><a class="markdownIt-Anchor" href="#方法二lodash-的-clonedeep"></a> 方法二：lodash 的 cloneDeep</h3><figure class="highlight javascript"><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="keyword">import</span> _ <span class="keyword">from</span> <span class="string">&#x27;lodash&#x27;</span></span><br><span class="line"><span class="keyword">const</span> deepClone = _.<span class="title function_">cloneDeep</span>(obj)</span><br></pre></td></tr></table></figure><h3 id="方法三递归实现"><a class="markdownIt-Anchor" href="#方法三递归实现"></a> 方法三：递归实现</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">deepClone</span>(<span class="params">obj</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> _toString = <span class="title class_">Object</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">toString</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// null, undefined, non-object, function</span></span><br><span class="line">  <span class="keyword">if</span> (!obj || <span class="keyword">typeof</span> obj !== <span class="string">&#x27;object&#x27;</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> obj</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// DOM Node</span></span><br><span class="line">  <span class="keyword">if</span> (obj.<span class="property">nodeType</span> &amp;&amp; <span class="string">&#x27;cloneNode&#x27;</span> <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    <span class="keyword">return</span> obj.<span class="title function_">cloneNode</span>(<span class="literal">true</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// Date</span></span><br><span class="line">  <span class="keyword">if</span> (_toString.<span class="title function_">call</span>(obj) === <span class="string">&#x27;[object Date]&#x27;</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Date</span>(obj.<span class="title function_">getTime</span>())</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// RegExp</span></span><br><span class="line">  <span class="keyword">if</span> (_toString.<span class="title function_">call</span>(obj) === <span class="string">&#x27;[object RegExp]&#x27;</span>) &#123;</span><br><span class="line">    <span class="keyword">const</span> flags = []</span><br><span class="line">    <span class="keyword">if</span> (obj.<span class="property">global</span>) flags.<span class="title function_">push</span>(<span class="string">&#x27;g&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> (obj.<span class="property">multiline</span>) flags.<span class="title function_">push</span>(<span class="string">&#x27;m&#x27;</span>)</span><br><span class="line">    <span class="keyword">if</span> (obj.<span class="property">ignoreCase</span>) flags.<span class="title function_">push</span>(<span class="string">&#x27;i&#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">RegExp</span>(obj.<span class="property">source</span>, flags.<span class="title function_">join</span>(<span class="string">&#x27;&#x27;</span>))</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> result = <span class="title class_">Array</span>.<span class="title function_">isArray</span>(obj) ? [] : obj.<span class="property">constructor</span> ? <span class="keyword">new</span> obj.<span class="title function_">constructor</span>(<span class="params"></span>) : &#123;&#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">const</span> key <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    result[key] = <span class="title function_">deepClone</span>(obj[key])</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="浅拷贝实现"><a class="markdownIt-Anchor" href="#浅拷贝实现"></a> 浅拷贝实现</h2><h3 id="方法一扩展运算符"><a class="markdownIt-Anchor" href="#方法一扩展运算符"></a> 方法一：扩展运算符</h3><figure class="highlight javascript"><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="keyword">const</span> original = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span> &#125;</span><br><span class="line"><span class="keyword">const</span> shallowCopy = &#123; ...original &#125;</span><br></pre></td></tr></table></figure><h3 id="方法二objectassign"><a class="markdownIt-Anchor" href="#方法二objectassign"></a> 方法二：Object.assign()</h3><figure class="highlight javascript"><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="keyword">const</span> original = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span> &#125;</span><br><span class="line"><span class="keyword">const</span> shallowCopy = <span class="title class_">Object</span>.<span class="title function_">assign</span>(&#123;&#125;, original)</span><br></pre></td></tr></table></figure><h3 id="方法三arrayprototypeslice适用于数组"><a class="markdownIt-Anchor" href="#方法三arrayprototypeslice适用于数组"></a> 方法三：Array.prototype.slice()（适用于数组）</h3><figure class="highlight javascript"><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="keyword">const</span> originalArray = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">const</span> shallowCopyArray = originalArray.<span class="title function_">slice</span>()</span><br></pre></td></tr></table></figure><h3 id="方法四arrayprototypeconcat适用于数组"><a class="markdownIt-Anchor" href="#方法四arrayprototypeconcat适用于数组"></a> 方法四：Array.prototype.concat()（适用于数组）</h3><figure class="highlight javascript"><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="keyword">const</span> originalArray = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">const</span> shallowCopyArray = originalArray.<span class="title function_">concat</span>()</span><br></pre></td></tr></table></figure><h2 id="objectkeys-values"><a class="markdownIt-Anchor" href="#objectkeys-values"></a> Object.keys | values</h2><p><code>Object.values</code> 传入对象，返回对象 value 的数组集。</p><p><code>Object.keys</code> 传入对象，返回对象 key 的数组集。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> obj = &#123;</span><br><span class="line">  <span class="attr">id</span>: <span class="string">&#x27;1&#x27;</span>,</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;小维&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Object.keys 遍历</span></span><br><span class="line"><span class="keyword">const</span> temp1 = []</span><br><span class="line"><span class="title class_">Object</span>.<span class="title function_">keys</span>(obj).<span class="title function_">forEach</span>(<span class="function">(<span class="params">key</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(key) <span class="comment">// &#x27;id&#x27;, &#x27;name&#x27;</span></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(obj[key]) <span class="comment">// &#x27;1&#x27;, &#x27;小维&#x27;</span></span><br><span class="line">  temp1.<span class="title function_">push</span>(obj[key])</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Object.values 获取</span></span><br><span class="line"><span class="keyword">const</span> temp2 = <span class="title class_">Object</span>.<span class="title function_">values</span>(obj)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(temp2) <span class="comment">// [&#x27;1&#x27;, &#x27;小维&#x27;]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(temp1) <span class="comment">// [&#x27;1&#x27;, &#x27;小维&#x27;]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(obj)) <span class="comment">// [&#x27;id&#x27;, &#x27;name&#x27;]</span></span><br></pre></td></tr></table></figure><p>这两个方法还能处理数组和字符串，<code>keys</code> 返回索引，<code>values</code> 返回每个值拆开的数组。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> str = <span class="string">&#x27;abcde&#x27;</span></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="string">&#x27;a&#x27;</span>, <span class="string">&#x27;b&#x27;</span>, <span class="string">&#x27;c&#x27;</span>, <span class="string">&#x27;d&#x27;</span>, <span class="string">&#x27;e&#x27;</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(str)) <span class="comment">// [&#x27;0&#x27;, &#x27;1&#x27;, &#x27;2&#x27;, &#x27;3&#x27;, &#x27;4&#x27;]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">values</span>(str)) <span class="comment">// [&#x27;a&#x27;, &#x27;b&#x27;, &#x27;c&#x27;, &#x27;d&#x27;, &#x27;e&#x27;]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">keys</span>(arr)) <span class="comment">// [&#x27;0&#x27;, &#x27;1&#x27;, &#x27;2&#x27;, &#x27;3&#x27;, &#x27;4&#x27;]</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title class_">Object</span>.<span class="title function_">values</span>(arr)) <span class="comment">// [&#x27;a&#x27;, &#x27;b&#x27;, &#x27;c&#x27;, &#x27;d&#x27;, &#x27;e&#x27;]</span></span><br></pre></td></tr></table></figure><h2 id="objectassign"><a class="markdownIt-Anchor" href="#objectassign"></a> Object.assign</h2><p><code>Object.assign(target, source_1, ···)</code> 将后面的值赋值给前面的，并返回一个新的对象。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> target = &#123; <span class="attr">name</span>: <span class="string">&#x27;小艾 &#x27;</span> &#125;</span><br><span class="line"><span class="keyword">let</span> source = &#123; <span class="attr">age</span>: <span class="number">20</span> &#125; <span class="comment">//就一层对象是深拷贝,如果里面还有&#123;&#125;,那么就是浅拷贝</span></span><br><span class="line"><span class="keyword">let</span> obj1 = <span class="title class_">Object</span>.<span class="title function_">assign</span>(target, source)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(source) <span class="comment">//&#123; age: 20&#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj1) <span class="comment">//&#123;name: &#x27;小艾 &#x27;, age: 20&#125;</span></span><br><span class="line">source.<span class="property">name</span> = <span class="string">&#x27;小维&#x27;</span></span><br><span class="line"><span class="keyword">let</span> obj2 = <span class="title class_">Object</span>.<span class="title function_">assign</span>(target, source) <span class="comment">// 如果目标对象和源对象有同名属性，则后面的属性会覆盖前面的属性</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj2) <span class="comment">//&#123;name: &#x27;小维&#x27;, age: 20&#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj1) <span class="comment">//&#123;name: &#x27;小维&#x27;, age: 20&#125;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(target) <span class="comment">//&#123;name: &#x27;小维&#x27;, age: 20&#125;</span></span><br></pre></td></tr></table></figure><h3 id="测试值变化"><a class="markdownIt-Anchor" href="#测试值变化"></a> 测试值变化</h3><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> objN = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;坤&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">24</span>,</span><br><span class="line">  <span class="attr">info</span>: &#123;</span><br><span class="line">    <span class="attr">test</span>: <span class="string">&#x27;zz&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> test = &#123;</span><br><span class="line">  <span class="attr">kun</span>: <span class="string">&#x27;ngm&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> newObjN = <span class="title class_">Object</span>.<span class="title function_">assign</span>(test, objN) <span class="comment">//将objN中的属性值赋值给test，并返回新的对象newObjN</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(test)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(newObjN)</span><br><span class="line">test.<span class="property">age</span> = <span class="number">26</span></span><br><span class="line">objN.<span class="property">age</span> = <span class="number">25</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(newObjN) <span class="comment">//浅跟随test的值变化，age为26</span></span><br><span class="line">test.<span class="property">info</span>.<span class="property">test</span> = <span class="string">&#x27;NN&#x27;</span> <span class="comment">//会影响原来的，所以是浅拷贝</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(objN)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(newObjN)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(test)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> original = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>, <span class="attr">info</span>: &#123; <span class="attr">name</span>: <span class="string">&#x27;小维&#x27;</span> &#125;, <span class="attr">arr</span>: [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>] &#125;</span><br><span class="line"><span class="keyword">const</span> shallowCopy = &#123; ...original &#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shallowCopy)</span><br><span class="line"><span class="comment">// shallowCopy.arr = [3, 5] //不触发,引用地址变化</span></span><br><span class="line">shallowCopy.<span class="property">arr</span>[<span class="number">0</span>] = <span class="number">34</span> <span class="comment">//修改新的会影响原来的，触发浅拷贝</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(original)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shallowCopy)</span><br></pre></td></tr></table></figure><h3 id="扩展运算符测试"><a class="markdownIt-Anchor" href="#扩展运算符测试"></a> 扩展运算符测试</h3><figure class="highlight javascript"><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 class="keyword">const</span> original = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>, <span class="attr">info</span>: &#123; <span class="attr">name</span>: <span class="string">&#x27;小维&#x27;</span> &#125;, <span class="attr">arr</span>: [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>] &#125;</span><br><span class="line"><span class="keyword">const</span> shallowCopy = &#123; ...original &#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// shallowCopy.arr = [3, 5]  // 不触发，引用地址变化</span></span><br><span class="line">shallowCopy.<span class="property">arr</span>[<span class="number">0</span>] = <span class="number">34</span> <span class="comment">// 修改新的会影响原来的，触发浅拷贝</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(original)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shallowCopy)</span><br></pre></td></tr></table></figure><h2 id="objectentries-fromentries"><a class="markdownIt-Anchor" href="#objectentries-fromentries"></a> Object.entries | fromEntries</h2><p><code>Object.entries</code> 将对象拆成数组，数组里包含多个小数组，每个小数组包含对象的 key 和 value。</p><p><code>Object.fromEntries</code> 将上面的格式还原为对象。</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> target = &#123; <span class="attr">name</span>: <span class="string">&#x27;小艾 &#x27;</span>, <span class="attr">age</span>: <span class="number">20</span> &#125;</span><br><span class="line"><span class="keyword">let</span> source = &#123; <span class="attr">age</span>: <span class="number">20</span> &#125;</span><br><span class="line"><span class="keyword">const</span> obj3 = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;LUCKY&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">20</span>,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> arrLucky = <span class="title class_">Object</span>.<span class="title function_">entries</span>(obj3)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(arrLucky) <span class="comment">//[[&#x27;name&#x27;, &#x27;LUCKY&#x27;], [&#x27;age&#x27;, 20]]</span></span><br><span class="line"><span class="comment">//将上面这种转对象 适合将 Map 结构转为对象</span></span><br><span class="line"><span class="keyword">const</span> obj4 = <span class="title class_">Object</span>.<span class="title function_">fromEntries</span>(arrLucky)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj4) <span class="comment">//&#123;name: &#x27;LUCKY&#x27;, age: 20&#125;</span></span><br><span class="line"><span class="comment">//删除属性</span></span><br><span class="line"><span class="keyword">delete</span> obj3.<span class="property">name</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(obj3) <span class="comment">//&#123;age: 20&#125;</span></span><br><span class="line"><span class="keyword">let</span> &#123; name, ...params &#125; = target <span class="comment">//除了name属性以外的target对象中的所有其他属性</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(params) <span class="comment">//&#123;age: 20&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//Object.assign 测试值变化</span></span><br><span class="line"><span class="keyword">const</span> objN = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;坤&#x27;</span>,</span><br><span class="line">  <span class="attr">age</span>: <span class="number">24</span>,</span><br><span class="line">  <span class="attr">info</span>: &#123;</span><br><span class="line">    <span class="attr">test</span>: <span class="string">&#x27;zz&#x27;</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> test = &#123;</span><br><span class="line">  <span class="attr">kun</span>: <span class="string">&#x27;ngm&#x27;</span>,</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">const</span> newObjN = <span class="title class_">Object</span>.<span class="title function_">assign</span>(test, objN)</span><br><span class="line">objN.<span class="property">age</span> = <span class="number">25</span></span><br><span class="line">test.<span class="property">age</span> = <span class="number">26</span></span><br><span class="line">test.<span class="property">info</span>.<span class="property">test</span> = <span class="string">&#x27;NN&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(objN, newObjN, test) <span class="comment">//发现age无法影响objN的值</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(objN, newObjN, test) <span class="comment">//发现info里的test影响objN的值</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> original = &#123; <span class="attr">a</span>: <span class="number">1</span>, <span class="attr">b</span>: <span class="number">2</span>, <span class="attr">info</span>: &#123; <span class="attr">name</span>: <span class="string">&#x27;小维&#x27;</span> &#125;, <span class="attr">arr</span>: [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>] &#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> shallowCopy = &#123; ...original &#125;</span><br><span class="line"><span class="comment">// shallowCopy.arr = [3, 5] //不触发,引用地址变化</span></span><br><span class="line">shallowCopy.<span class="property">arr</span>[<span class="number">0</span>] = <span class="number">34</span> <span class="comment">//这样才会触发浅拷贝</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(shallowCopy, original)</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">锲而不舍，金石可镂</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://luckynwa.top/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>Element UI开发指南</title>
    <link href="https://luckynwa.top/posts/front4/"/>
    <id>https://luckynwa.top/posts/front4/</id>
    <published>2024-10-22T01:04:29.000Z</published>
    <updated>2026-07-07T16:20:55.707Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>本专栏将记录 Element UI 以及 Element Plus 的使用，以便提高开发速度</p><p><a href="https://element.eleme.cn/#/zh-CN/component/installation">ElementUi官网</a></p><p><a href="https://element-plus.org/zh-CN/component/button.html">ElementPlus官网</a></p><h2 id="引用-element"><a class="markdownIt-Anchor" href="#引用-element"></a> 引用 Element</h2><p>Vue2版用的是ElementUi，一般都是在main.js中直接引入</p><figure class="highlight js"><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">npm i element-ui -S</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ElementUI</span> <span class="keyword">from</span> <span class="string">&#x27;element-ui&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;element-ui/lib/theme-chalk/index.css&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="title class_">Vue</span>.<span class="title function_">use</span>(<span class="title class_">ElementUI</span>)</span><br></pre></td></tr></table></figure><p>Vue3版用的是ElementPlus，不过一般都配合自动导入</p><figure class="highlight js"><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"> npm install element-plus --save</span><br><span class="line"></span><br><span class="line"><span class="comment">// main.ts</span></span><br><span class="line"><span class="keyword">import</span> &#123; createApp &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ElementPlus</span> <span class="keyword">from</span> <span class="string">&#x27;element-plus&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">&#x27;element-plus/dist/index.css&#x27;</span></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">App</span> <span class="keyword">from</span> <span class="string">&#x27;./App.vue&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> app = <span class="title function_">createApp</span>(<span class="title class_">App</span>)</span><br><span class="line"></span><br><span class="line">app.<span class="title function_">use</span>(<span class="title class_">ElementPlus</span>)</span><br><span class="line">app.<span class="title function_">mount</span>(<span class="string">&#x27;#app&#x27;</span>)</span><br></pre></td></tr></table></figure><h2 id="快速开始"><a class="markdownIt-Anchor" href="#快速开始"></a> 快速开始</h2><p>在前面已经知道如何去安装了，接下来搭建环境，采用下面2套模板去做实验，vue3模板已经实现了自动按需导入</p><h2 id="创建一个-vue-应用"><a class="markdownIt-Anchor" href="#创建一个-vue-应用"></a> 创建一个 Vue 应用</h2><p>环境：Node16 和 Node18 (nvm 来管理)</p><p>开发工具: VSCode</p><p>代码: 直接从本人的 Github 上拉取</p><p>::: info<br />Vue3 模板</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone -b test https://github.com/luckyNwa6/luckyVue3Template.git</span><br></pre></td></tr></table></figure><p>Vue2 模板</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone -b test https://github.com/luckyNwa6/luckyVue2Template.git</span><br></pre></td></tr></table></figure><h2 id="弹框组件封装"><a class="markdownIt-Anchor" href="#弹框组件封装"></a> 弹框组件封装</h2><p>vue2项目，封装的第一版弹框组件使用基于element-ui</p><p>在vue同级创建components/dialog文件夹</p><p>里面放paramDialog.vue</p><p>父组件引入 dialogVisible要是改变量名，这个也记得改</p><h2 id="弹框组件"><a class="markdownIt-Anchor" href="#弹框组件"></a> 弹框组件</h2><p>代码如下：</p><figure class="highlight js"><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">&lt;<span class="title class_">ParamDialog</span> :title=<span class="string">&quot;title&quot;</span> :dialogVisible.<span class="property">sync</span>=<span class="string">&quot;dialogVisible&quot;</span> @dialog-closed=<span class="string">&quot;handleDialogClosed&quot;</span> :dataRe=<span class="string">&quot;dataFa&quot;</span> /&gt;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">ParamDialog</span> <span class="keyword">from</span> <span class="string">&#x27;./components/dialog/paramDialog.vue&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="attr">components</span>: &#123;<span class="title class_">ParamDialog</span>&#125;,</span><br><span class="line"><span class="title function_">data</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">      <span class="comment">// 弹出框</span></span><br><span class="line">      <span class="attr">dialogVisible</span>: <span class="literal">false</span>,</span><br><span class="line">      <span class="comment">//要传给弹框的数据下面3个</span></span><br><span class="line">      <span class="attr">dataFa</span>: <span class="literal">null</span>,</span><br><span class="line">      <span class="attr">title</span>: <span class="string">&#x27;参数模板&#x27;</span></span><br><span class="line">        &#125;</span><br><span class="line">&#125;,</span><br><span class="line"><span class="attr">methods</span>: &#123;</span><br><span class="line">    <span class="title function_">handleView</span>(<span class="params">row</span>) &#123;   <span class="comment">//可以是修改也可以是新增</span></span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;打开dialog&#x27;</span>);</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">dialogVisible</span> = <span class="literal">true</span>;</span><br><span class="line">      <span class="comment">//下面看着传</span></span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">dataFa</span> = row;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">dataFa</span> = &#123; ...<span class="variable language_">this</span>.<span class="property">dataFa</span>, <span class="attr">time</span>: <span class="variable language_">this</span>.<span class="property">queryParams</span>.<span class="property">time</span>, &#125;;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="comment">//关闭弹框,子传父的自定义事件监听</span></span><br><span class="line">    <span class="title function_">handleDialogClosed</span>(<span class="params">closed</span>) &#123;</span><br><span class="line">      <span class="variable language_">this</span>.<span class="property">dialogVisible</span> = <span class="literal">false</span>;</span><br><span class="line">      <span class="comment">// 在这里处理关闭状态</span></span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;子组件弹框关闭状态:&#x27;</span>, closed);</span><br><span class="line">    &#125;,</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>子组件</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--参数模板弹框--&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;<span class="name">el-dialog</span> <span class="attr">:title</span>=<span class="string">&quot;title&quot;</span> <span class="attr">:data</span>=<span class="string">&quot;list&quot;</span> <span class="attr">width</span>=<span class="string">&quot;50%&quot;</span> <span class="attr">:visible.sync</span>=<span class="string">&quot;dialogVisible&quot;</span> <span class="attr">:before-close</span>=<span class="string">&quot;handleClose&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">div</span>&gt;</span>1<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">el-dialog</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">props</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">dialogVisible</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">type</span>: <span class="title class_">Boolean</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">default</span>: <span class="literal">false</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">dataRe</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">type</span>: <span class="title class_">Object</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">default</span>: &#123;&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">title</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">type</span>: <span class="title class_">String</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">queryParams</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">pageNo</span>: <span class="number">1</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">pageSize</span>: <span class="number">15</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">time</span>: <span class="string">&#x27;&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">deviceCode</span>: <span class="string">&#x27;&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">stationId</span>: <span class="literal">null</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">type</span>: <span class="literal">null</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">// 遮罩层</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">loading</span>: <span class="literal">true</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">// 表格</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">list</span>: []</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">watch</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">dialogVisible</span>(<span class="params">newValue</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">if</span> (newValue) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="comment">//说明是打开的,调用方法</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">this</span>.<span class="title function_">init</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">computed</span>: &#123;&#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="comment">//关闭弹框</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">handleClose</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.$emit(<span class="string">&#x27;dialog-closed&#x27;</span>, <span class="variable language_">this</span>.<span class="property">dialogVisible</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">init</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">loading</span> = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">//处理父组件传过来的对象</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">queryParams</span>.<span class="property">time</span> = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">time</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">queryParams</span>.<span class="property">stationId</span> = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">stationId</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">queryParams</span>.<span class="property">deviceCode</span> = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">deviceCode</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">queryParams</span>.<span class="property">type</span> = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">type</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">var</span> stationNameC = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">stationName</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">var</span> timeC = <span class="variable language_">this</span>.<span class="property">dataRe</span>.<span class="property">time</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">loading</span> = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ getList ~ this.queryParams:&#x27;</span>, <span class="variable language_">this</span>.<span class="property">queryParams</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">loading</span> = <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">style</span> <span class="attr">lang</span>=<span class="string">&quot;scss&quot;</span> &gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="上传功能实现"><a class="markdownIt-Anchor" href="#上传功能实现"></a> 上传功能实现</h2><p>本章节将实现一个上传功能，结合项目的真正需求</p><h3 id="原生上传"><a class="markdownIt-Anchor" href="#原生上传"></a> 原生上传</h3><p>由于需要校验压缩包中的内容</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm  i  jszip</span><br></pre></td></tr></table></figure><p>简单上传页</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">input</span> <span class="attr">ref</span>=<span class="string">&quot;fileInput&quot;</span> <span class="attr">type</span>=<span class="string">&quot;file&quot;</span> <span class="attr">multiple</span> @<span class="attr">change</span>=<span class="string">&quot;handleFileChange&quot;</span> <span class="attr">style</span>=<span class="string">&quot;display: none&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;openFileInput&quot;</span>&gt;</span>选择文件<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;resetFileInput&quot;</span>&gt;</span>重置<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">setup</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; ref &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> <span class="title class_">JSZip</span> <span class="keyword">from</span> <span class="string">&#x27;jszip&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileInput = <span class="title function_">ref</span>(<span class="literal">null</span>) <span class="comment">// 创建一个 ref 引用</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">openFileInput</span> = (<span class="params"></span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  fileInput.<span class="property">value</span>.<span class="title function_">click</span>() <span class="comment">// 打开文件选择对话框</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleFileChange</span> = (<span class="params">event</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> files = event.<span class="property">target</span>.<span class="property">files</span> <span class="comment">// 获取选中的文件列表</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(files)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 遍历文件列表</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; files.<span class="property">length</span>; i++) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> file = files[i]</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> reader = <span class="keyword">new</span> <span class="title class_">FileReader</span>()</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    reader.<span class="property">onload</span> = <span class="function">(<span class="params">e</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">const</span> zipData = e.<span class="property">target</span>.<span class="property">result</span> <span class="comment">// 获取ZIP文件的内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="comment">// 使用JSZip解压缩ZIP文件</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="title class_">JSZip</span>.<span class="title function_">loadAsync</span>(zipData).<span class="title function_">then</span>(<span class="function">(<span class="params">zip</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="comment">// 处理解压缩后的内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        zip.<span class="title function_">forEach</span>(<span class="function">(<span class="params">relativePath, zipEntry</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="keyword">if</span> (!zipEntry.<span class="property">dir</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="comment">// 如果是文件而不是目录</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            zipEntry.<span class="title function_">async</span>(<span class="string">&#x27;string&#x27;</span>).<span class="title function_">then</span>(<span class="function">(<span class="params">fileContent</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              <span class="comment">// 处理文件内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`文件名：<span class="subst">$&#123;zipEntry.name&#125;</span>`</span>)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              <span class="comment">// console.log(`文件内容：$&#123;fileContent&#125;`)</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    reader.<span class="title function_">readAsArrayBuffer</span>(file) <span class="comment">// 以ArrayBuffer格式读取文件内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">resetFileInput</span> = (<span class="params"></span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  fileInput.<span class="property">value</span>.<span class="property">value</span> = <span class="string">&#x27;&#x27;</span> <span class="comment">// 通过 .value 访问和修改引用的值</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">style</span> <span class="attr">scoped</span>&gt;</span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>在上传的过程中，如果第一次上传a文件，第二次再上传会没有效果，因为浏览器的缓存，需要去引用上传实例里的输入框设为空才能继续，由于业务要求，需要点击菜单下拉框里的按钮触发选择文件夹</p><figure class="highlight js"><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">uploadRef.<span class="property">value</span>.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>).<span class="property">value</span> = <span class="string">&#x27;&#x27;</span> <span class="comment">//可上传同名</span></span><br><span class="line">uploadRef.<span class="property">value</span>.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>).<span class="title function_">click</span>() <span class="comment">//触发点击选择文件框</span></span><br></pre></td></tr></table></figure><p>业务过程：</p><p>原是列表上有个上传按钮—&gt;点击弹框显示上传弹框—&gt;在这里上传，由于一旦关闭弹框就要重新传而且影响用户其他操作—&gt;采用新页面给它异步上传就不影响用户操作别的东西</p><p>新上传页面–&gt;文件有它的格式要求–&gt;用了部分的elementplus的上传组件（正常它的上传按钮都是在这个组件插槽里的，我这自定义按钮放外面所以都用不了该组件的方法如提交）–&gt;验证zip里的格式–&gt;进度条3种状态</p><p><img src="https://cloud.luckynwa.top/profile/mdS/image-20240629083303813.png" alt="" /></p><p>采用组合式写法</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;upload-container&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;text-align: center; width: 100%; padding: 20px 0&quot;</span>&gt;</span><span class="tag">&lt;<span class="name">h2</span>&gt;</span>导入模型<span class="tag">&lt;/<span class="name">h2</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">el-card</span> <span class="attr">style</span>=<span class="string">&quot;width: 90%; margin: 0 auto; padding: 10px 25px; height: 780px; overflow: auto&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;font-bold text-[14px]&quot;</span>&gt;</span>上传目标路径: 全部文件<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;text-[14px] mt-4 mb-4&quot;</span>&gt;</span>支持以下类型和格式的模型导入。<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">el-table</span> <span class="attr">:data</span>=<span class="string">&quot;tableData&quot;</span> <span class="attr">border</span> <span class="attr">style</span>=<span class="string">&quot;width: 35%&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;typeL&quot;</span> <span class="attr">label</span>=<span class="string">&quot;类型&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span> <span class="tag">&lt;<span class="name">span</span> <span class="attr">style</span>=<span class="string">&quot;font-weight: 600&quot;</span>&gt;</span>格式<span class="tag">&lt;/<span class="name">span</span>&gt;</span> <span class="tag">&lt;/<span class="name">template</span>&gt;</span>&lt;/el-table-column</span></span><br><span class="line"><span class="language-xml">        &gt;</span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;2DL&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">header</span>&gt;</span></span></span><br><span class="line"><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></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">el-tooltip</span> <span class="attr">placement</span>=<span class="string">&quot;right&quot;</span> <span class="attr">effect</span>=<span class="string">&quot;light&quot;</span> <span class="attr">popper-class</span>=<span class="string">&quot;image-tooltip&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">template</span> #<span class="attr">content</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">img</span> <span class="attr">:src</span>=<span class="string">&quot;image2d&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">i-ep-info-filled</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;/<span class="name">el-tooltip</span>&gt;</span></span></span><br><span class="line"><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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span> <span class="tag">&lt;<span class="name">span</span> <span class="attr">style</span>=<span class="string">&quot;font-weight: 600&quot;</span>&gt;</span>png<span class="tag">&lt;/<span class="name">span</span>&gt;</span><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;DYL&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">header</span>&gt;</span></span></span><br><span class="line"><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></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">el-tooltip</span> <span class="attr">placement</span>=<span class="string">&quot;right&quot;</span> <span class="attr">effect</span>=<span class="string">&quot;light&quot;</span> <span class="attr">popper-class</span>=<span class="string">&quot;image-tooltip&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">template</span> #<span class="attr">content</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">img</span> <span class="attr">:src</span>=<span class="string">&quot;imageDY&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">i-ep-info-filled</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;/<span class="name">el-tooltip</span>&gt;</span></span></span><br><span class="line"><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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span> <span class="tag">&lt;<span class="name">span</span> <span class="attr">style</span>=<span class="string">&quot;font-weight: 600&quot;</span>&gt;</span>pnts<span class="tag">&lt;/<span class="name">span</span>&gt;</span> <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;QXL&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">header</span>&gt;</span></span></span><br><span class="line"><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></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">el-tooltip</span> <span class="attr">placement</span>=<span class="string">&quot;right&quot;</span> <span class="attr">effect</span>=<span class="string">&quot;light&quot;</span> <span class="attr">popper-class</span>=<span class="string">&quot;image-tooltip&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">template</span> #<span class="attr">content</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                  <span class="tag">&lt;<span class="name">img</span> <span class="attr">:src</span>=<span class="string">&quot;imageQX&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">                <span class="tag">&lt;<span class="name">i-ep-info-filled</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;/<span class="name">el-tooltip</span>&gt;</span></span></span><br><span class="line"><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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span></span></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;font-weight: 600&quot;</span>&gt;</span>b3dm<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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;QJL&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">header</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">span</span>&gt;</span> 全景照片 <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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span> <span class="tag">&lt;<span class="name">span</span> <span class="attr">style</span>=<span class="string">&quot;font-weight: 600&quot;</span>&gt;</span>jpeg &amp;nbsp jpg<span class="tag">&lt;/<span class="name">span</span>&gt;</span> <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">el-table</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;text-[14px] h-20&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;mt-4&quot;</span>&gt;</span>除了全景照片可以直接上传文件（格式：jpg, jpeg）以外，其余类型的文件请将单个模型按照对应格式<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;mt-3&quot;</span>&gt;</span>的文件结构压缩成为zip包（小于 30GB）后，再进行上传。<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">el-dropdown</span> <span class="attr">class</span>=<span class="string">&quot;mb-4&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">&quot;primary&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">          &gt;</span><span class="tag">&lt;<span class="name">i-ep-upload</span> /&gt;</span> 导入<span class="tag">&lt;<span class="name">i-ep-arrow-down</span> <span class="attr">style</span>=<span class="string">&quot;margin-left: 5px&quot;</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">template</span> #<span class="attr">dropdown</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">el-dropdown-menu</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">el-dropdown-item</span> @<span class="attr">click</span>=<span class="string">&quot;openEditDialog(&#x27;QX&#x27;)&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span>&gt;</span>倾斜模型<span class="tag">&lt;/<span class="name">el-dropdown-item</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">el-dropdown-item</span> @<span class="attr">click</span>=<span class="string">&quot;openEditDialog(&#x27;DY&#x27;)&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span>&gt;</span>点云<span class="tag">&lt;/<span class="name">el-dropdown-item</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">el-dropdown-item</span> @<span class="attr">click</span>=<span class="string">&quot;openEditDialog(&#x27;2D&#x27;)&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span>&gt;</span>二维地图<span class="tag">&lt;/<span class="name">el-dropdown-item</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">el-dropdown-item</span> @<span class="attr">click</span>=<span class="string">&quot;openEditDialog(&#x27;QJ&#x27;)&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span>&gt;</span>全景照片<span class="tag">&lt;/<span class="name">el-dropdown-item</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">el-dropdown-menu</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">el-dropdown</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">el-upload</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">ref</span>=<span class="string">&quot;uploadRef&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:action</span>=<span class="string">&quot;addApi&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:headers</span>=<span class="string">&quot;headers&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:before-upload</span>=<span class="string">&quot;handleBeforeUpload&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:file-list</span>=<span class="string">&quot;fileList&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:show-file-list</span>=<span class="string">&quot;false&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:on-change</span>=<span class="string">&quot;handleChange&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:auto-upload</span>=<span class="string">&quot;false&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">v-show</span>=<span class="string">&quot;false&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">multiple</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">      &gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">el-upload</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">class</span>=<span class="string">&quot;mb-4&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">i-ep-warning-filled</span> <span class="attr">style</span>=<span class="string">&quot;color: #ff9900; margin-left: 5px&quot;</span> /&gt;</span></span></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: #ff9900; margin-left: 5px&quot;</span>&gt;</span>上传过程中请勿关闭浏览器或退出当前页面！<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>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">el-table</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:data</span>=<span class="string">&quot;tableFileData&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">border</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">class</span>=<span class="string">&quot;mb-4&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">highlight-current-row</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">v-loading</span>=<span class="string">&quot;loading&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">height</span>=<span class="string">&quot;290px&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">ref</span>=<span class="string">&quot;tableRef&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">      &gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;file_name&quot;</span> <span class="attr">label</span>=<span class="string">&quot;文件名称&quot;</span> <span class="attr">width</span>=<span class="string">&quot;380&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span> <span class="attr">show-overflow-tooltip</span> /&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">label</span>=<span class="string">&quot;上传进度&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span> <span class="attr">show-overflow-tooltip</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&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">v-if</span>=<span class="string">&quot;scope.row.showProgress&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">el-progress</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">                <span class="attr">:percentage</span>=<span class="string">&quot;scope.row.uploadProgress&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">                <span class="attr">:color</span>=<span class="string">&quot;customColorMethod(scope.row.uploadProgress, scope.row.state)&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">              /&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;/<span class="name">div</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">v-else-if</span>=<span class="string">&quot;scope.row.showProgress === 0 &amp;&amp; scope.row.file_tip === &#x27;&#x27;&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">span</span>&gt;</span><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>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-else</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">              <span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;&#123; scope.row.file_tip &#125;&#125;<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>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;state&quot;</span> <span class="attr">label</span>=<span class="string">&quot;上传状态&quot;</span> <span class="attr">width</span>=<span class="string">&quot;180&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span> <span class="attr">show-overflow-tooltip</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;&#123; fileUploadOption.find(item =&gt; item.value == scope.row.state)?.label &#125;&#125;<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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">prop</span>=<span class="string">&quot;state&quot;</span> <span class="attr">label</span>=<span class="string">&quot;模型类型&quot;</span> <span class="attr">width</span>=<span class="string">&quot;180&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span> <span class="attr">show-overflow-tooltip</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">span</span>&gt;</span>&#123;&#123; optionData.modelTypeOption.find(item =&gt; item.value == scope.row.model_type)?.label &#125;&#125;<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">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-table-column</span> <span class="attr">fixed</span>=<span class="string">&quot;right&quot;</span> <span class="attr">label</span>=<span class="string">&quot;操作&quot;</span> <span class="attr">align</span>=<span class="string">&quot;center&quot;</span> <span class="attr">width</span>=<span class="string">&quot;180&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</span>=<span class="string">&quot;scope&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">&quot;danger&quot;</span> <span class="attr">v-if</span>=<span class="string">&quot;!scope.row.showDel&quot;</span> <span class="attr">link</span> @<span class="attr">click.stop</span>=<span class="string">&quot;handleDelete(scope.row)&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">              &gt;</span>取消&lt;/el-button</span></span><br><span class="line"><span class="language-xml">            &gt;</span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">el-table-column</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">el-table</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">&quot;primary&quot;</span> @<span class="attr">click</span>=<span class="string">&quot;btDis&quot;</span> <span class="attr">:disabled</span>=<span class="string">&quot;btDisable&quot;</span>&gt;</span>&#123;&#123; uploadBtnName &#125;&#125;<span class="tag">&lt;/<span class="name">el-button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">el-card</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">setup</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; onMounted, ref &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> _ <span class="keyword">from</span> <span class="string">&#x27;lodash&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; <span class="title class_">ElMessage</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;element-plus&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> image2d <span class="keyword">from</span> <span class="string">&#x27;@/assets/model-import/image2d.png&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> imageDY <span class="keyword">from</span> <span class="string">&#x27;@/assets/model-import/imageDY.png&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> imageQX <span class="keyword">from</span> <span class="string">&#x27;@/assets/model-import/imageQX.png&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; useUserStoreHook &#125; <span class="keyword">from</span> <span class="string">&#x27;@/store/modules/user&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> <span class="title class_">JSZip</span> <span class="keyword">from</span> <span class="string">&#x27;jszip&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&#x27;axios&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> optionData <span class="keyword">from</span> <span class="string">&#x27;@/utils/option-data&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//文件上传状态</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileUploadOption = [</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">value</span>: <span class="number">3</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">label</span>: <span class="string">&#x27;待上传&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">value</span>: <span class="number">2</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">label</span>: <span class="string">&#x27;正在上传&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">value</span>: <span class="number">1</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">label</span>: <span class="string">&#x27;上传成功&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">value</span>: <span class="number">0</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">label</span>: <span class="string">&#x27;上传失败&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">value</span>: <span class="number">4</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">label</span>: <span class="string">&#x27;&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//占用一行，不用改</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> tableData = [</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">typeL</span>: <span class="string">&#x27;格式&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">QXL</span>: <span class="string">&#x27;zip&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">DYL</span>: <span class="string">&#x27;zip&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="string">&#x27;2DL&#x27;</span>: <span class="string">&#x27;zip&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">QJL</span>: <span class="string">&#x27;jpeg,jpg&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//上传的文件列表展示</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> tableFileData = <span class="title function_">ref</span>([]);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> loading = <span class="title function_">ref</span>(<span class="literal">false</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> uploadRef = <span class="title function_">ref</span>(<span class="literal">null</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> tableRef = <span class="title function_">ref</span>(<span class="string">&#x27;tableRef&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> uploadBtnName = <span class="title function_">ref</span>(<span class="string">&#x27;上传&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> addApi = <span class="title function_">ref</span>(<span class="literal">null</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> userStore = <span class="title function_">useUserStoreHook</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> headers = <span class="title function_">reactive</span>(&#123; <span class="string">&#x27;X-Auth-Token&#x27;</span>: userStore.<span class="property">token</span> &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> typeModel = <span class="title function_">ref</span>(<span class="literal">null</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> btDisable = <span class="title function_">ref</span>(<span class="literal">false</span>); <span class="comment">//上传和导入按钮是否禁用</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileList = <span class="title function_">ref</span>([]);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileType3 = [<span class="string">&#x27;zip&#x27;</span>]; <span class="comment">//倾斜、点云、二维都是zip格式</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileTypeQJ = [<span class="string">&#x27;jpeg&#x27;</span>, <span class="string">&#x27;jpg&#x27;</span>]; <span class="comment">//全景照片</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">openEditDialog</span> = type =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;当前要上传的类型是：&#x27;</span>, type);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  typeModel.<span class="property">value</span> = type; <span class="comment">//这里必须赋值，下面才知道类型</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;打开了选中文件框&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  uploadRef.<span class="property">value</span>.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>).<span class="property">value</span> = <span class="string">&#x27;&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  uploadRef.<span class="property">value</span>.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>).<span class="title function_">click</span>(); <span class="comment">//触发点击选择文件框</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//下面是文件上传生命周期-----------------------------------------------------------------------------</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileSize = <span class="number">30</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> isTypeOk = <span class="title function_">ref</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleChange</span> = <span class="keyword">async</span> (<span class="params">file, updatedFileList</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;=====================触发了handleChange的生命周期开始！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  file.<span class="property">modelType</span> = typeModel.<span class="property">value</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (file.<span class="property">name</span>.<span class="property">length</span> &gt; <span class="number">23</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">`文件名过长，请限制20字内!`</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> isLt = file.<span class="property">size</span> / <span class="number">1024</span> / <span class="number">1024</span> / <span class="number">1024</span> &lt; fileSize;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (!isLt) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">`上传文件大小不能超过 <span class="subst">$&#123;fileSize&#125;</span> GB!`</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> ob1 = fileList.<span class="property">value</span>.<span class="title function_">find</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">name</span> === file.<span class="property">name</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> ob2 = tableFileData.<span class="property">value</span>.<span class="title function_">find</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">file_name</span> === file.<span class="property">name</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (ob1 || ob2) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">`文件已在列表中!`</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">let</span> fileExtension = <span class="string">&#x27;&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (file.<span class="property">name</span>.<span class="title function_">lastIndexOf</span>(<span class="string">&#x27;.&#x27;</span>) &gt; -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    fileExtension = file.<span class="property">name</span>.<span class="title function_">slice</span>(file.<span class="property">name</span>.<span class="title function_">lastIndexOf</span>(<span class="string">&#x27;.&#x27;</span>) + <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~文件扩展后缀是:&#x27;</span>, fileExtension);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  isTypeOk.<span class="property">value</span> = (typeModel.<span class="property">value</span> === <span class="string">&#x27;QJ&#x27;</span> ? fileTypeQJ : fileType3).<span class="title function_">some</span>(<span class="function"><span class="params">type</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">if</span> (fileExtension &amp;&amp; fileExtension.<span class="title function_">toUpperCase</span>().<span class="title function_">indexOf</span>(type.<span class="title function_">toUpperCase</span>()) &gt; -<span class="number">1</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ file:&#x27;</span>, file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (typeModel.<span class="property">value</span> !== <span class="string">&#x27;QJ&#x27;</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;继续验证zip&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">try</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">const</span> res = <span class="keyword">await</span> <span class="title function_">unzipAndReadFiles</span>(file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ 解压回调:&#x27;</span>, res);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      isTypeOk.<span class="property">value</span> = res;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125; <span class="keyword">catch</span> (error) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      isTypeOk.<span class="property">value</span> = <span class="literal">false</span>; <span class="comment">//捕获里面的异常</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (!isTypeOk.<span class="property">value</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="comment">//格式有问题,加入列表中，不加入上传列表</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;格式有问题,加入列表中，不加入上传列表&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(file.<span class="property">name</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    tableFileData.<span class="property">value</span>.<span class="title function_">push</span>(&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">file_name</span>: file.<span class="property">name</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">showProgress</span>: <span class="number">0</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">file_tip</span>: <span class="string">&#x27;不支持的文件结构，请按照上传模型的结构要求上传文件。&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">state</span>: <span class="number">4</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">model_type</span>: typeModel.<span class="property">value</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125; <span class="keyword">else</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    fileList.<span class="property">value</span>.<span class="title function_">push</span>(file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    tableFileData.<span class="property">value</span>.<span class="title function_">push</span>(&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">file_name</span>: file.<span class="property">name</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">showProgress</span>: <span class="number">0</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">state</span>: <span class="number">3</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">uploadProgress</span>: <span class="number">0</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">model_type</span>: typeModel.<span class="property">value</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;通过格式验证&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ updatedFileList:&#x27;</span>, updatedFileList);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ 要上传的文件列表:&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;=====================触发了handleChange的生命周期结束！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">// 上传前校检格式和大小</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleBeforeUpload</span> = file =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;触发了上传前的校验handleBeforeUpload&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> config = &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">headers</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="string">&#x27;X-Auth-Token&#x27;</span>: userStore.<span class="property">token</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//手动上传</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">uploadFile</span> = <span class="keyword">async</span> (<span class="params"></span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ 手动上传时候uploadFile ~ fileList.value:&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (!fileList.<span class="property">value</span>.<span class="property">length</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">&#x27;请先导入模型！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  btDisable.<span class="property">value</span> = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  uploadBtnName.<span class="property">value</span> = <span class="string">&#x27;正在上传&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">let</span> arr = _.<span class="title function_">cloneDeep</span>(fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">let</span> flagPro = <span class="literal">false</span>; <span class="comment">//防止进度条上传成功还99</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; arr.<span class="property">length</span>; i++) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> file = arr[i];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ uploadFile ~ file:&#x27;</span>, file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="comment">// 使用FormData上传</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> formData = <span class="keyword">new</span> <span class="title class_">FormData</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    formData.<span class="title function_">append</span>(<span class="string">&#x27;file&#x27;</span>, file.<span class="property">raw</span>, file.<span class="property">name</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> index = tableFileData.<span class="property">value</span>.<span class="title function_">findIndex</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">file_name</span> === file.<span class="property">name</span>); <span class="comment">//在列表中删除提示那种没上传到服务器</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    tableFileData.<span class="property">value</span>[index].<span class="property">state</span> = <span class="number">2</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    tableFileData.<span class="property">value</span>[index].<span class="property">showProgress</span> = <span class="number">1</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">0</span>; <span class="comment">//进度条</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">try</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">const</span> response = <span class="keyword">await</span> axios.<span class="title function_">post</span>(</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">env</span>.<span class="property">VITE_APP_BASE_API</span> +</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="string">`/achievement/api/v1/model/<span class="subst">$&#123;userStore.userData.workspace_id&#125;</span>/uploadFile/<span class="subst">$&#123;file.modelType&#125;</span>`</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        formData,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          ...config,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          <span class="attr">onUploadProgress</span>: <span class="function"><span class="params">progressEvent</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="comment">// 计算进度百分比</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">const</span> percentCompleted = <span class="title class_">Math</span>.<span class="title function_">round</span>((progressEvent.<span class="property">loaded</span> * <span class="number">100</span>) / progressEvent.<span class="property">total</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">if</span> (percentCompleted === <span class="number">100</span> &amp;&amp; !flagPro) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;这是前端的100进度条改99等后端返回0才100&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">99</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (flagPro) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">100</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125; <span class="keyword">else</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = percentCompleted; <span class="comment">//更新实时进度条</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      );</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="keyword">if</span> (response.<span class="property">data</span>.<span class="property">code</span> === <span class="number">0</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;文件上传成功&#x27;</span>, response.<span class="property">data</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        flagPro = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        tableFileData.<span class="property">value</span>[index].<span class="property">state</span> = <span class="number">1</span>; <span class="comment">//状态改成功</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        tableFileData.<span class="property">value</span>[index].<span class="property">showDel</span> = <span class="number">1</span>; <span class="comment">//禁用删除</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="keyword">const</span> index2 = fileList.<span class="property">value</span>.<span class="title function_">findIndex</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">name</span> === file.<span class="property">name</span>); <span class="comment">//文件列表删除，这样下次上传就没有它了</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="keyword">if</span> (index2 !== -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          fileList.<span class="property">value</span>.<span class="title function_">splice</span>(index2, <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;后端返回0了，进度条该100了&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">100</span>; <span class="comment">//进度条拉满</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125; <span class="keyword">else</span> <span class="keyword">if</span> (response.<span class="property">data</span>.<span class="property">code</span> === -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        flagPro = <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">99</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;上传失败了，后端说的&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        tableFileData.<span class="property">value</span>[index].<span class="property">state</span> = <span class="number">0</span>; <span class="comment">//状态改失败</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125; <span class="keyword">catch</span> (error) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      tableFileData.<span class="property">value</span>[index].<span class="property">state</span> = <span class="number">0</span>; <span class="comment">//状态改失败</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      tableFileData.<span class="property">value</span>[index].<span class="property">uploadProgress</span> = <span class="number">99</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      flagPro = <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">`网络异常，文件上传失败！`</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">console</span>.<span class="title function_">error</span>(<span class="string">&#x27;文件上传失败&#x27;</span>, error);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">btDis</span> = <span class="keyword">async</span> (<span class="params"></span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">try</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> res = <span class="keyword">await</span> <span class="title function_">uploadFile</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~上传全部完毕，失败还能继续上传的列表：&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="comment">// 所有文件上传完成</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    btDisable.<span class="property">value</span> = <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    uploadBtnName.<span class="property">value</span> = <span class="string">&#x27;上传&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125; <span class="keyword">catch</span> (error) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    btDisable.<span class="property">value</span> = <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    uploadBtnName.<span class="property">value</span> = <span class="string">&#x27;上传&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">unzipAndReadFiles</span> = file =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">let</span> modelType = file.<span class="property">modelType</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    file = file.<span class="property">raw</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> reader = <span class="keyword">new</span> <span class="title class_">FileReader</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">let</span> tempBoolean = <span class="literal">false</span>; <span class="comment">//用来存是否满足条件</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">let</span> tempSum = <span class="number">0</span>; <span class="comment">//临时长度</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">try</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      reader.<span class="property">onload</span> = <span class="function"><span class="params">e</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="keyword">const</span> zipData = e.<span class="property">target</span>.<span class="property">result</span>; <span class="comment">// 获取ZIP文件的内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="comment">// 使用JSZip解压缩ZIP文件</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="title class_">JSZip</span>.<span class="title function_">loadAsync</span>(zipData)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          .<span class="title function_">then</span>(<span class="function"><span class="params">zip</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(zip);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="comment">// 处理解压缩后的内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            zip.<span class="title function_">forEach</span>(<span class="function">(<span class="params">relativePath, zipEntry</span>) =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              <span class="keyword">if</span> (modelType === <span class="string">&#x27;DY&#x27;</span> &amp;&amp; <span class="title function_">pathMatchesRuleDY</span>(relativePath)) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                tempSum++;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="keyword">if</span> (<span class="title class_">Object</span>.<span class="title function_">keys</span>(zip.<span class="property">files</span>).<span class="property">length</span> == tempSum) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                  <span class="comment">//同时满足正则</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                  tempBoolean = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              &#125; <span class="keyword">else</span> <span class="keyword">if</span> (modelType === <span class="string">&#x27;QX&#x27;</span> &amp;&amp; <span class="title function_">pathMatchesRuleQX</span>(relativePath)) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                tempSum++;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;QX满足压缩格式！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="keyword">if</span> (<span class="title class_">Object</span>.<span class="title function_">keys</span>(zip.<span class="property">files</span>).<span class="property">length</span> == tempSum) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                  <span class="comment">//同时满足正则</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                  tempBoolean = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              &#125; <span class="keyword">else</span> <span class="keyword">if</span> (modelType === <span class="string">&#x27;2D&#x27;</span> &amp;&amp; <span class="title function_">pathMatchesRule2D</span>(relativePath)) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;有xyz.png格式！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                tempBoolean = <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">              &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;当前&#x27;</span>, tempBoolean);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="title function_">resolve</span>(tempBoolean); <span class="comment">// 解压缩完成，将Promise标记为成功，并传递isTypeOk的值</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          .<span class="title function_">catch</span>(<span class="function"><span class="params">error</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;这是解压时候遇到的异常&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="title function_">reject</span>(error); <span class="comment">// 将Promise标记为失败，并传递错误信息</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">          &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      reader.<span class="title function_">readAsArrayBuffer</span>(file); <span class="comment">// 以ArrayBuffer格式读取文件内容</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125; <span class="keyword">catch</span> (error) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;这里是解压外层捕获的异常&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="title function_">reject</span>(error); <span class="comment">// 将Promise标记为失败，并传递错误信息</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">pathMatchesRuleDY</span> = path =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 根目录下第一个文件名为 &quot;tileset.json&quot;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> pathRegex = <span class="regexp">/^[^/]+\/tileset\.json/</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 其他文件必须是 .json 或 .pnts 后缀</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> fileRegex = <span class="regexp">/\.json$|\.pnts$/i</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 路径以 / 结尾</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> trailingSlashRegex = <span class="regexp">/\/$/</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> pathRegex.<span class="title function_">test</span>(path) || fileRegex.<span class="title function_">test</span>(path) || trailingSlashRegex.<span class="title function_">test</span>(path);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">pathMatchesRuleQX</span> = path =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 根目录下第一个文件名为 &quot;tileset.json&quot;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> pathRegex = <span class="regexp">/^[^/]+\/tileset\.json/</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 其他文件必须是 .json 或 .b3dm后缀</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> fileRegex = <span class="regexp">/\.json$|\.b3dm$/i</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 路径以 / 结尾</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> trailingSlashRegex = <span class="regexp">/\/$/</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> pathRegex.<span class="title function_">test</span>(path) || fileRegex.<span class="title function_">test</span>(path) || trailingSlashRegex.<span class="title function_">test</span>(path);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">pathMatchesRule2D</span> = path =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">//2D规则</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> regex = <span class="regexp">/^[^/]+\/\d+\/\d+\/\d+\.png$/</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> regex.<span class="title function_">test</span>(path);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">/**</span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> * 删除</span></span></span></span><br><span class="line"><span class="comment"><span class="language-javascript"><span class="language-xml"> */</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">function</span> <span class="title function_">handleDelete</span>(<span class="params">row</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title class_">ElMessageBox</span>.<span class="title function_">confirm</span>(<span class="string">`确认后将删除该条记录，且无法进行恢复`</span>, <span class="string">&#x27;确认取消？&#x27;</span>, &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">confirmButtonText</span>: <span class="string">&#x27;确定&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">cancelButtonText</span>: <span class="string">&#x27;取消&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">type</span>: <span class="string">&#x27;warning&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;).<span class="title function_">then</span>(<span class="function">() =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~当前行的数据:&#x27;</span>, row);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> index = tableFileData.<span class="property">value</span>.<span class="title function_">findIndex</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">file_name</span> === row.<span class="property">file_name</span>); <span class="comment">//在列表中删除提示那种没上传到服务器</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleDelete ~ tableFileData.value:&#x27;</span>, tableFileData.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ tableFileData ~ index:&#x27;</span>, index);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">const</span> index2 = fileList.<span class="property">value</span>.<span class="title function_">findIndex</span>(<span class="function"><span class="params">obj</span> =&gt;</span> obj.<span class="property">name</span> === row.<span class="property">file_name</span>); <span class="comment">//文件列表删除</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleDelete ~ fileList.value:&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ fileList ~ index2:&#x27;</span>, index2);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">if</span> (index !== -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      tableFileData.<span class="property">value</span>.<span class="title function_">splice</span>(index, <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">if</span> (index2 !== -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      fileList.<span class="property">value</span>.<span class="title function_">splice</span>(index2, <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    uploadRef.<span class="property">value</span>.<span class="property">$el</span>.<span class="title function_">querySelector</span>(<span class="string">&#x27;input&#x27;</span>).<span class="property">value</span> = <span class="string">&#x27;&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">success</span>(<span class="string">&#x27;删除成功&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//根据进度条百分比获取颜色</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">customColorMethod</span> = (<span class="params">percentage, state</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (percentage &lt; <span class="number">100</span> &amp;&amp; state) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="string">&#x27;#409eff&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (percentage &lt;= <span class="number">100</span> &amp;&amp; !state) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="string">&#x27;#ff3b30&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (percentage == <span class="number">100</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="string">&#x27;#4bd863&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">style</span> <span class="attr">scoped</span>&gt;</span><span class="language-css"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.upload-container</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">height</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin</span>: <span class="number">0</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">padding</span>: <span class="number">0</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">background-color</span>: <span class="number">#f9f9f9</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.upload-demo</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin-bottom</span>: <span class="number">20px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">border</span>: <span class="number">1px</span> dashed <span class="number">#d3d3d3</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">border-radius</span>: <span class="number">4px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">padding</span>: <span class="number">20px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">text-align</span>: center;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.el-upload__text</span> <span class="selector-tag">em</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">color</span>: <span class="number">#409eff</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">cursor</span>: pointer;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br></pre></td></tr></table></figure><h2 id="组件上传"><a class="markdownIt-Anchor" href="#组件上传"></a> 组件上传</h2><p>放在弹框中的</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">el-dialog</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">:title</span>=<span class="string">&quot;title&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">:model-value</span>=<span class="string">&quot;visible&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">width</span>=<span class="string">&quot;600px&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">align-center</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">:close-on-click-modal</span>=<span class="string">&quot;false&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    @<span class="attr">close</span>=<span class="string">&quot;closeDialog&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">  &gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;upload-container&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">el-upload</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">ref</span>=<span class="string">&quot;uploadImgRef&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:before-upload</span>=<span class="string">&quot;handleBeforeUpload&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:on-change</span>=<span class="string">&quot;handleChange&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:on-error</span>=<span class="string">&quot;handleError&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:on-remove</span>=<span class="string">&quot;handRemove&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:file-list</span>=<span class="string">&quot;fileList&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:on-success</span>=<span class="string">&quot;handleSuccess&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:action</span>=<span class="string">&quot;addApi&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">:headers</span>=<span class="string">&quot;headers&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">drag</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">        <span class="attr">multiple</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">      &gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">template</span> #<span class="attr">default</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">class</span>=<span class="string">&quot;upload-tip-box&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">            <span class="tag">&lt;<span class="name">i-ep-uploadFilled</span> <span class="attr">class</span>=<span class="string">&quot;el-icon-upload&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">class</span>=<span class="string">&quot;el-upload__text&quot;</span>&gt;</span>点击或拖动文件上传<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">          <span class="tag">&lt;/<span class="name">div</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">class</span>=<span class="string">&quot;tipB&quot;</span>&gt;</span>支持图片格式：JPEG<span class="tag">&lt;/<span class="name">div</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">class</span>=<span class="string">&quot;tipB&quot;</span>&gt;</span>支持视频格式：MP4<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">el-upload</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">template</span> #<span class="attr">footer</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">class</span>=<span class="string">&quot;dialog-footer&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">&quot;primary&quot;</span> @<span class="attr">click</span>=<span class="string">&quot;closeDialog&quot;</span> <span class="attr">v-loading</span>=<span class="string">&quot;loading&quot;</span>&gt;</span>确 定<span class="tag">&lt;/<span class="name">el-button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">el-button</span> @<span class="attr">click</span>=<span class="string">&quot;closeDialog&quot;</span>&gt;</span>取 消<span class="tag">&lt;/<span class="name">el-button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">el-dialog</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span> <span class="attr">setup</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; reactive, defineProps, defineEmits, ref, onMounted &#125; <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; <span class="title class_">ElMessage</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;element-plus&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; useUserStoreHook &#125; <span class="keyword">from</span> <span class="string">&#x27;@/store/modules/user&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> uploadImgRef = <span class="title function_">ref</span>(<span class="string">&#x27;uploadImgRef&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> props = <span class="title function_">defineProps</span>(&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">visible</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">type</span>: <span class="title class_">Boolean</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">default</span>: <span class="literal">false</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">title</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">type</span>: <span class="title class_">String</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">default</span>: <span class="string">&#x27;标题&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> emit = <span class="title function_">defineEmits</span>([<span class="string">&#x27;update:visible&#x27;</span>, <span class="string">&#x27;submit&#x27;</span>]);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> loading = <span class="title function_">ref</span>(<span class="literal">false</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">// 关闭弹窗</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">function</span> <span class="title function_">closeDialog</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  fileList.<span class="property">value</span> = [];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  uploadImgRef.<span class="property">value</span>.<span class="title function_">clearFiles</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;关闭弹框的文件列表：&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">emit</span>(<span class="string">&#x27;update:visible&#x27;</span>, <span class="literal">false</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">emit</span>(<span class="string">&#x27;submit&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//保存</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">function</span> <span class="title function_">handleSubmit</span>(<span class="params"></span>) &#123;&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//下面是上传相关</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileList = <span class="title function_">ref</span>([]);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> userStore = <span class="title function_">useUserStoreHook</span>();</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> addApi = <span class="keyword">import</span>.<span class="property">meta</span>.<span class="property">env</span>.<span class="property">VITE_APP_BASE_API</span> + <span class="string">`/media/api/v1/files/<span class="subst">$&#123;userStore.userData.workspace_id&#125;</span>/uploadFile`</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> headers = <span class="title function_">reactive</span>(&#123; <span class="string">&#x27;X-Auth-Token&#x27;</span>: userStore.<span class="property">token</span> &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> existingFileIndex = <span class="title function_">ref</span>(<span class="literal">null</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleChange</span> = (<span class="params">file, updatedFileList</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;=====================触发了handleChange的生命周期开始！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ updatedFileList:&#x27;</span>, updatedFileList);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ file:&#x27;</span>, file);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 查找目标元素的全部索引</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">let</span> indices = [];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">for</span> (<span class="keyword">let</span> i = updatedFileList.<span class="property">length</span> - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">if</span> (updatedFileList[i].<span class="property">name</span> === file.<span class="property">name</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;name相等！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      indices.<span class="title function_">push</span>(i);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ indices:&#x27;</span>, indices);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 如果有多个索引，删除第一个索引对应的元素</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (indices.<span class="property">length</span> &gt; <span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    updatedFileList.<span class="title function_">splice</span>(indices[<span class="number">0</span>], <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleChange ~ updatedFileList:&#x27;</span>, updatedFileList);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  fileList.<span class="property">value</span> = updatedFileList;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;=====================触发了handleChange的生命周期结束！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//上传失败</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleError</span> = (<span class="params">file, updatedFileList</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title class_">ElMessage</span>.<span class="title function_">error</span>(updatedFileList.<span class="property">name</span> + <span class="string">&#x27;上传失败&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;handleError的生命周期！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//文件列表移除文件时的钩子</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handRemove</span> = (<span class="params">file, updatedFileList</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  fileList.<span class="property">value</span> = updatedFileList;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;handRemove的生命周期！！！&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ 移除后的文件列表:&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">//上传成功</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleSuccess</span> = (<span class="params">file, updatedFileList</span>) =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ handleSuccess的生命周期！！！&#x27;</span>, updatedFileList);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(updatedFileList.<span class="property">name</span> + <span class="string">&#x27;上传成功&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ 上传成功后 ~ fileList.value:&#x27;</span>, fileList.<span class="property">value</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;-----------------------------------------------------&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileType = [<span class="string">&#x27;MP4&#x27;</span>, <span class="string">&#x27;JPEG&#x27;</span>];</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> fileSize = <span class="number">5</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="comment">// 上传前校检格式和大小</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">const</span> <span class="title function_">handleBeforeUpload</span> = file =&gt; &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="comment">// 校检文件类型</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">let</span> fileExtension = <span class="string">&#x27;&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (file.<span class="property">name</span>.<span class="title function_">lastIndexOf</span>(<span class="string">&#x27;.&#x27;</span>) &gt; -<span class="number">1</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    fileExtension = file.<span class="property">name</span>.<span class="title function_">slice</span>(file.<span class="property">name</span>.<span class="title function_">lastIndexOf</span>(<span class="string">&#x27;.&#x27;</span>) + <span class="number">1</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">const</span> isTypeOk = fileType.<span class="title function_">some</span>(<span class="function"><span class="params">type</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">if</span> (fileExtension &amp;&amp; fileExtension.<span class="title function_">toUpperCase</span>().<span class="title function_">indexOf</span>(type.<span class="title function_">toUpperCase</span>()) &gt; -<span class="number">1</span>) <span class="keyword">return</span> <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">if</span> (!isTypeOk) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">ElMessage</span>.<span class="title function_">warning</span>(<span class="string">`文件格式不正确, 请上传<span class="subst">$&#123;fileType.join(<span class="string">&#x27;/&#x27;</span>)&#125;</span>格式文件!`</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> <span class="literal">false</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;上传检查全部通过！正在上传文件，请稍候...&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="keyword">return</span> <span class="literal">true</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">style</span> <span class="attr">scoped</span> <span class="attr">lang</span>=<span class="string">&quot;scss&quot;</span>&gt;</span><span class="language-css"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.app-form</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  ::v-deep &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-input-number</span>,</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-select</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">      <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-input-number</span> <span class="selector-class">.el-input__inner</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">      <span class="attribute">text-align</span>: left;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-input-number</span><span class="selector-class">.is-controls-right</span> <span class="selector-class">.el-input__wrapper</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">      <span class="attribute">padding-left</span>: <span class="number">11px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-date-editor</span><span class="selector-class">.el-input</span>,</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    <span class="selector-class">.el-date-editor</span><span class="selector-class">.el-input__wrapper</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">      <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.upload-container</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">display</span>: flex;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">flex-direction</span>: column;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">height</span>: <span class="number">300px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">:<span class="built_in">deep</span>(.el-upload--picture-card) &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">height</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">width</span>: <span class="number">100%</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">:<span class="built_in">deep</span>(.el-upload__text) &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">font-size</span>: <span class="number">13px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin-bottom</span>: <span class="number">13px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin-top</span>: -<span class="number">5px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">:<span class="built_in">deep</span>(.el-upload-dragger) &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">width</span>: <span class="number">565px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">background-color</span>: <span class="number">#f9f9f9</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">:<span class="built_in">deep</span>(.el-upload-dragger:hover) &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">background-color</span>: white;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.el-icon-upload</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">color</span>: <span class="number">#b7d9fd</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">font-size</span>: <span class="number">70px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin-top</span>: -<span class="number">34px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"><span class="selector-class">.tipB</span> &#123;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">font-size</span>: <span class="number">13px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">color</span>: <span class="number">#cccccc</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">  <span class="attribute">margin-top</span>: <span class="number">10px</span>;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-css"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/image-20240629083303814.png" alt="" /></p>]]></content>
    
    
    <summary type="html">千磨万击还坚劲，任尔东西南北风</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="UI" scheme="https://luckynwa.top/tags/UI/"/>
    
  </entry>
  
  <entry>
    <title>ES6核心特性详解</title>
    <link href="https://luckynwa.top/posts/front3/"/>
    <id>https://luckynwa.top/posts/front3/</id>
    <published>2024-10-14T17:21:33.000Z</published>
    <updated>2026-07-07T16:19:33.825Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p>ES6（ECMAScript 2015）是 JavaScript 的一个重要版本，引入了许多新的语言特性和增强功能，为开发人员提供了更强大、更现代的编程工具和技术</p><h2 id="const-和-let"><a class="markdownIt-Anchor" href="#const-和-let"></a> const 和 let</h2><p>ES6 推荐使用 let 声明局部变量，相比之前的 var（无论声明在何处，都会被视为声明在函数的最顶部），let 具有块级作用域（即在使用 let 的那一对大括号 {}内起作用），可以避免变量提升和污染全局作用域的问题。</p><p>const 则用来声明常量，即一旦赋值就不能再改变。const 也具有块级作用域，并且必须在声明时就初始化。const 适合用来定义不会改变的值，如 PI、URL 等。</p><figure class="highlight js"><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="comment">// 使用var</span></span><br><span class="line"><span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">2</span> <span class="comment">// 这里会覆盖上面的a</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// 输出2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用let</span></span><br><span class="line"><span class="keyword">let</span> b = <span class="number">1</span></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> b = <span class="number">2</span> <span class="comment">// 这里不会影响外面的b</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b) <span class="comment">// 输出1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用const</span></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">PI</span> = <span class="number">3.14</span></span><br><span class="line"><span class="variable constant_">PI</span> = <span class="number">3.15</span> <span class="comment">// 报错：Assignment to constant variable.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="variable constant_">URL</span> = <span class="string">&#x27;https://www.bing.com&#x27;</span></span><br><span class="line"><span class="variable constant_">URL</span> = <span class="string">&#x27;https://www.google.com&#x27;</span> <span class="comment">// 报错：Assignment to constant variable.</span></span><br></pre></td></tr></table></figure><p>var的问题</p><p>越域</p><figure class="highlight js"><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">&#123;</span><br><span class="line">  <span class="keyword">var</span> a = <span class="number">1</span></span><br><span class="line">  <span class="keyword">let</span> b = <span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(a) <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(b) <span class="comment">// ReferenceError: b is not defined</span></span><br></pre></td></tr></table></figure><p>重复声明</p><figure class="highlight js"><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">// var 可以声明多次</span></span><br><span class="line"><span class="comment">// let 只能声明一次</span></span><br><span class="line"><span class="keyword">var</span> m = <span class="number">1</span></span><br><span class="line"><span class="keyword">var</span> m = <span class="number">2</span></span><br><span class="line"><span class="keyword">let</span> n = <span class="number">3</span></span><br><span class="line"><span class="comment">// let n = 4</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(m) <span class="comment">// 2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(n) <span class="comment">// Identifier &#x27;n&#x27; has already been declared</span></span><br></pre></td></tr></table></figure><p>变量提升</p><figure class="highlight js"><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">// var 会变量提升</span></span><br><span class="line"><span class="comment">// let 不存在变量提升</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(x) <span class="comment">// undefined</span></span><br><span class="line"><span class="keyword">var</span> x = <span class="number">10</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(y) <span class="comment">//ReferenceError: y is not defined</span></span><br><span class="line"><span class="keyword">let</span> y = <span class="number">20</span></span><br></pre></td></tr></table></figure><h2 id="解构赋值"><a class="markdownIt-Anchor" href="#解构赋值"></a> <strong>解构赋值</strong></h2><p>解构赋值是一种从数组或对象中提取数据并赋值给变量的简洁写法。它可以减少代码量，提高可读性，并且支持默认值、嵌套结构、别名等特性。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> &#123; <span class="attr">type</span>: typeName = <span class="string">&#x27;&#x27;</span>, id = <span class="string">&#x27;&#x27;</span> &#125; = <span class="variable language_">this</span>.<span class="property">$route</span>.<span class="property">query</span> <span class="comment">//es6语法   typeName是别名</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ mounted ~ id:&#x27;</span>, id)</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ activated ~ typeName:&#x27;</span>, typeName)</span><br><span class="line"><span class="keyword">let</span> &#123; <span class="attr">isPass</span>: formCheckRes = <span class="literal">false</span> &#125; = <span class="variable language_">this</span>.<span class="property">$refs</span>.<span class="property">serveInfo</span>.<span class="title function_">validateFn</span>() <span class="comment">//为空赋默认值</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;🚀 ~ checkForm ~ formCheckRes:&#x27;</span>, formCheckRes)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数组解构：按照数组元素位置对应赋值给变量</span></span><br><span class="line"><span class="keyword">let</span> [f, g, h] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(f) <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(g) <span class="comment">// 2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(h) <span class="comment">// 3</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 对象解构：按照对象属性名对应赋值给同名变量（也可以使用别名）</span></span><br><span class="line"><span class="keyword">let</span> &#123; name, age &#125; = &#123; <span class="attr">name</span>: <span class="string">&#x27;Alice&#x27;</span>, <span class="attr">age</span>: <span class="number">18</span> &#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(name) <span class="comment">// Alice</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(age) <span class="comment">// 18</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123; <span class="attr">name</span>: i, <span class="attr">age</span>: j &#125; = &#123; <span class="attr">name</span>: <span class="string">&#x27;Bob&#x27;</span>, <span class="attr">age</span>: <span class="number">19</span> &#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(i) <span class="comment">// Bob</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(j) <span class="comment">//19</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 默认值：如果没有匹配到相应的数据，则使用默认值（如果有）</span></span><br><span class="line"><span class="keyword">let</span> [k, l = <span class="number">0</span>] = [<span class="number">1</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(k) <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(l) <span class="comment">//0</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123; m = <span class="number">0</span>, n = <span class="number">0</span> &#125; = &#123; <span class="attr">m</span>: <span class="number">1</span> &#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(m) <span class="comment">//1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(n) <span class="comment">//0</span></span><br><span class="line"><span class="comment">// 嵌套结构：可以解构嵌套的数组或对象</span></span><br><span class="line"><span class="keyword">let</span> [o, [p, q]] = [<span class="number">1</span>, [<span class="number">2</span>, <span class="number">3</span>]]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(o) <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(p) <span class="comment">// 2</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(q) <span class="comment">// 3</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123;</span><br><span class="line">  <span class="attr">r</span>: &#123; s, t &#125;,</span><br><span class="line">&#125; = &#123; <span class="attr">r</span>: &#123; <span class="attr">s</span>: <span class="number">4</span>, <span class="attr">t</span>: <span class="number">5</span> &#125; &#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(s) <span class="comment">// 4</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(t) <span class="comment">// 5</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 解构赋值的应用场景：交换变量、函数参数、返回值等</span></span><br><span class="line"><span class="keyword">let</span> u = <span class="number">6</span></span><br><span class="line"><span class="keyword">let</span> v = <span class="number">7</span></span><br><span class="line">;[u, v] = [v, u] <span class="comment">// 不需要使用临时变量来交换u和v的值</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(u) <span class="comment">// 7</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(v) <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">foo</span>(<span class="params">[x, y]</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x + y</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">foo</span>([<span class="number">8</span>, <span class="number">9</span>])) <span class="comment">//17</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">bar</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> [<span class="number">10</span>, <span class="number">11</span>]</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> [w, z] = <span class="title function_">bar</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(w) <span class="comment">//10</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(z) <span class="comment">//11</span></span><br></pre></td></tr></table></figure><h2 id="箭头函数"><a class="markdownIt-Anchor" href="#箭头函数"></a> 箭头函数</h2><p>箭头函数是一种使用 =&gt; 符号定义函数的简洁写法 。它可以省略 function 关键字、参数括号、返回值括号等，使得代码更加简洁和清晰。箭头函数还有一个重要的特性，就是它不会改变 this 的指向，即箭头函数内部的 this 始终指向定义时所在的对象。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 普通函数和箭头函数的对比</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x + y</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">add</span> = (<span class="params">x, y</span>) =&gt; x + y <span class="comment">// 省略了 function 关键字、参数括号、返回值括号</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果只有一个参数，可以省略参数括号；如果没有参数，必须使用空括号</span></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">square</span> = (<span class="params">x</span>) =&gt; x * x</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">hello</span> = (<span class="params"></span>) =&gt; <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Hello&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果有多条语句，需要使用大括号包裹，并且显式返回（如果需要）</span></span><br><span class="line"><span class="keyword">let</span> <span class="title function_">max</span> = (<span class="params">x, y</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">if</span> (x &gt; y) &#123;</span><br><span class="line">    <span class="keyword">return</span> x</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> y</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 箭头函数不会改变 this 的指向，即箭头函数内部的 this 始终指向定义时所在的对象</span></span><br><span class="line"><span class="keyword">let</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;Alice&#x27;</span>,</span><br><span class="line">  <span class="attr">sayHi</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>) <span class="comment">// Alice</span></span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>) <span class="comment">// undefined （因为setTimeout中的this指向window）</span></span><br><span class="line">    &#125;, <span class="number">1000</span>)</span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="variable language_">this</span>.<span class="property">name</span>) <span class="comment">// Alice （因为箭头函数中的this指向obj）</span></span><br><span class="line">    &#125;, <span class="number">1000</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">sayHi</span>()</span><br><span class="line"></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  <span class="attr">name</span>: <span class="string">&#x27;John&#x27;</span>,</span><br><span class="line">  <span class="attr">sayHello</span>: <span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> that = <span class="variable language_">this</span> <span class="comment">//用它就可以拿到obj</span></span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">      <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;Hello, &#x27;</span> + that.<span class="property">name</span>)</span><br><span class="line">    &#125;, <span class="number">1000</span>)</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line">obj.<span class="title function_">sayHello</span>()</span><br></pre></td></tr></table></figure><h2 id="模板字符串"><a class="markdownIt-Anchor" href="#模板字符串"></a> 模板字符串</h2><p>模板字符串是一种使用反引号 `` 包裹字符串，并且支持插入变量或表达式的新语法 。它可以避免使用 + 号连接字符串和变量，并且支持多行字符串和标签模板等特性。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用模板字符串插入变量或表达式，用 $&#123;&#125; 包裹即可（注意是反引号而不是单引号）</span></span><br><span class="line"><span class="keyword">let</span> name = <span class="string">&quot;Bob&quot;</span>;</span><br><span class="line"><span class="keyword">let</span> age = <span class="number">19</span>;</span><br><span class="line"><span class="keyword">let</span> message = <span class="string">`Hello <span class="subst">$&#123;name&#125;</span>, you are <span class="subst">$&#123;age&#125;</span> years old.`</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用模板字符串可以直接换行，不需要使用 \n 或者 + 号连接多行字符串</span></span><br><span class="line"><span class="keyword">let</span> poem = <span class="string">`Do not go gentle into that good night,</span></span><br><span class="line"><span class="string">Old age should burn and rave at close of day;</span></span><br><span class="line"><span class="string">Rage, rage against the dying of the light.`</span>;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(poem);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用标签模板可以自定义模板字符串的处理方式（标签是一个函数名）</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">tag</span>(<span class="params">strings, ...values</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> result = <span class="string">&quot;&quot;</span>;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; strings.<span class="property">length</span>; i++) &#123;</span><br><span class="line">    result += strings[i];</span><br><span class="line">    <span class="keyword">if</span> (i &lt; values.<span class="property">length</span>) &#123;</span><br><span class="line">      result += values[i].<span class="title function_">toUpperCase</span>(); <span class="comment">// 将变量转为大写</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> name = <span class="string">&quot;Alice&quot;</span>;</span><br><span class="line"><span class="keyword">let</span> message = tag<span class="string">`Hello <span class="subst">$&#123;name&#125;</span>, how are you?`</span>; <span class="comment">// 使用tag函数处理模板字符串</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(message); <span class="comment">// Hello ALICE, how are you?</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> info = <span class="string">&quot;你好，我的名字是：【&quot;</span>+name+<span class="string">&quot;】，年龄是：【&quot;</span>+age+<span class="string">&quot;】，邮箱是：【】&quot;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(info);</span><br><span class="line"></span><br><span class="line"># 模板字符串的写法</span><br><span class="line"><span class="keyword">let</span> info = <span class="string">`你好，我的名字是：<span class="subst">$&#123;name&#125;</span>，年龄是：<span class="subst">$&#123;person.age&#125;</span>，邮箱是：<span class="subst">$&#123;person.email&#125;</span>`</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(info);</span><br></pre></td></tr></table></figure><h2 id="链判断"><a class="markdownIt-Anchor" href="#链判断"></a> 链判断</h2><figure class="highlight js"><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 class="keyword">let</span> message = <span class="literal">null</span></span><br><span class="line"><span class="comment">// 错误的写法</span></span><br><span class="line"><span class="keyword">const</span> firstName = message.<span class="property">body</span>.<span class="property">user</span>.<span class="property">firstName</span> || <span class="string">&#x27;default&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 正确的写法</span></span><br><span class="line"><span class="keyword">const</span> firstName = (message &amp;&amp; message.<span class="property">body</span> &amp;&amp; message.<span class="property">body</span>.<span class="property">user</span> &amp;&amp; message.<span class="property">body</span>.<span class="property">user</span>.<span class="property">firstName</span>) || <span class="string">&#x27;default&#x27;</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(firstName)</span><br></pre></td></tr></table></figure><p>这样的层层判断非常麻烦，因此 <a href="https://github.com/tc39/proposal-optional-chaining">ES2020</a> 引入了“链判断运算符”（optional chaining operator）<strong>?.</strong>，简化上面的写法。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> firstName = message?.<span class="property">body</span>?.<span class="property">user</span>?.<span class="property">firstName</span> || <span class="string">&#x27;default&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="默认参数-剩余参数和展开运算符"><a class="markdownIt-Anchor" href="#默认参数-剩余参数和展开运算符"></a> 默认参数、剩余参数和展开运算符</h2><p>ES6 提供了一些新的语法，可以让函数的参数更加灵活和方便。默认参数可以让函数在没有传入参数或传入 undefined 时，使用预设的默认值。剩余参数可以让函数接收任意数量的参数，并将它们存储在一个数组中。展开运算符可以将一个数组或对象展开为多个元素或属性，用于函数调用、数组合并、对象复制等场景。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 默认参数：在函数定义时，给参数赋予默认值（如果没有传入或传入undefined）</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">x = <span class="number">0</span>, y = <span class="number">0</span></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x + y</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>()) <span class="comment">// 0</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>(<span class="number">1</span>)) <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>(<span class="number">1</span>, <span class="number">2</span>)) <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>(<span class="number">1</span>, <span class="literal">undefined</span>)) <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 剩余参数：在函数定义时，使用 ... 符号表示剩余的所有参数，并将它们存储在一个数组中（必须是最后一个参数）</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">sum</span>(<span class="params">...numbers</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> result = <span class="number">0</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> number <span class="keyword">of</span> numbers) &#123;</span><br><span class="line">    result += number</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result</span><br><span class="line">&#125;</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>()) <span class="comment">// 0</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">1</span>)) <span class="comment">// 1</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">1</span>, <span class="number">2</span>)) <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>)) <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 展开运算符：在函数调用时，使用 ... 符号将一个数组或对象展开为多个元素或属性（相当于逐个传入）</span></span><br><span class="line"><span class="keyword">let</span> arr = [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">sum</span>(...arr)) <span class="comment">// 15 （相当于sum(4,5,6)）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 展开运算符也可以用于数组合并、对象复制等场景</span></span><br><span class="line"><span class="keyword">let</span> arr1 = [<span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line"><span class="keyword">let</span> arr2 = [<span class="number">3</span>, ...arr] <span class="comment">// [3,4,5,6]</span></span><br><span class="line"><span class="keyword">let</span> obj1 = &#123; <span class="attr">name</span>: <span class="string">&#x27;Alice&#x27;</span> &#125;</span><br><span class="line"><span class="keyword">let</span> obj2 = &#123; ...obj1 &#125; <span class="comment">// &#123;name: &quot;Alice&quot;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//在 ES6 以前，我们无法给一个函数参数设置默认值，只能采用变通写法：</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">a, b</span>) &#123;</span><br><span class="line">  <span class="comment">// 判断 b 是否为空，为空就给默认值 1</span></span><br><span class="line">  b = b || <span class="number">1</span></span><br><span class="line">  <span class="keyword">return</span> a + b</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 传一个参数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>(<span class="number">10</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment">//现在可以这么写：直接给参数写上默认值，没传就会自动使用默认值</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">add2</span>(<span class="params">a, b = <span class="number">1</span></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> a + b</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 传一个参数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add2</span>(<span class="number">10</span>))</span><br></pre></td></tr></table></figure><h2 id="类和继承"><a class="markdownIt-Anchor" href="#类和继承"></a> 类和继承</h2><p>ES6 提供了一种新的语法，可以让 JavaScript 支持类和继承这两个面向对象编程的重要概念。类是一种定义对象属性和方法的模板，可以通过 new 关键字创建类的实例。继承是一种让子类拥有父类属性和方法的机制，可以通过 extends 和 super 关键字实现。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义一个类：使用 class 关键字，并且提供一个 constructor 方法作为构造函数（初始化实例属性）</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age</span>) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">name</span> = name <span class="comment">// this 指向实例对象</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">age</span> = age</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 定义类的方法：直接在类中写函数名和函数体（不需要使用 function 关键字）</span></span><br><span class="line">  <span class="title function_">sayHi</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Hello <span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>, you are <span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span> years old.`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建类的实例：使用 new 关键字，并且传入构造函数所需的参数</span></span><br><span class="line"><span class="keyword">let</span> alice = <span class="keyword">new</span> <span class="title class_">Person</span>(<span class="string">&#x27;Alice&#x27;</span>, <span class="number">18</span>)</span><br><span class="line">alice.<span class="title function_">sayHi</span>() <span class="comment">// Hello Alice, you are 18 years old.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义一个子类：使用 extends 关键字继承父类，并且可以重写或新增属性和方法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span> <span class="keyword">extends</span> <span class="title class_ inherited__">Person</span> &#123;</span><br><span class="line">  <span class="title function_">constructor</span>(<span class="params">name, age, grade</span>) &#123;</span><br><span class="line">    <span class="variable language_">super</span>(name, age) <span class="comment">// 使用 super 关键字调用父类的构造函数（必须在子类构造函数中第一行执行）</span></span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">grade</span> = grade <span class="comment">// 子类可以新增自己的属性</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 子类可以重写或新增父类的方法</span></span><br><span class="line">  <span class="title function_">sayHi</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Hello <span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span>, you are <span class="subst">$&#123;<span class="variable language_">this</span>.age&#125;</span> years old and in grade <span class="subst">$&#123;<span class="variable language_">this</span>.grade&#125;</span>.`</span>)</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">study</span>(<span class="params"></span>) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;<span class="variable language_">this</span>.name&#125;</span> is studying hard.`</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建子类的实例：使用 new 关键字，并且传入构造函数所需的参数（包括父类和子类的参数）</span></span><br><span class="line"><span class="keyword">let</span> bob = <span class="keyword">new</span> <span class="title class_">Student</span>(<span class="string">&#x27;Bob&#x27;</span>, <span class="number">19</span>, <span class="number">12</span>)</span><br><span class="line">bob.<span class="title function_">sayHi</span>() <span class="comment">// Hello Bob, you are 19 years old and in grade 12.</span></span><br><span class="line">bob.<span class="title function_">study</span>() <span class="comment">// Bob is studying hard.</span></span><br></pre></td></tr></table></figure><h2 id="promise-和-asyncawait"><a class="markdownIt-Anchor" href="#promise-和-asyncawait"></a> Promise 和 async/await</h2><p>Promise 是一种用于处理异步操作的对象，它表示一个未来可能完成或失败的事件。Promise 有三种状态：pending（等待）、fulfilled（成功）、rejected（失败）。Promise 可以通过 then 方法添加成功或失败时执行的回调函数，也可以通过 catch 方法添加失败时执行的回调函数。Promise 还可以通过 all 和 race 方法组合多个 Promise 对象。</p><p>async/await 是一种基于 Promise 的新语法，可以让异步操作更加简洁和清晰。async 是一个修饰符，用于声明一个异步函数，该函数返回一个 Promise 对象。await 是一个运算符，用于等待一个 Promise 对象的结果，只能在异步函数中使用。</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个Promise对象：使用 new 关键字，并且传入一个执行器函数（该函数接收两个参数：resolve和reject）</span></span><br><span class="line"><span class="keyword">let</span> promise = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="comment">// 模拟一个异步操作</span></span><br><span class="line">    <span class="keyword">let</span> num = <span class="title class_">Math</span>.<span class="title function_">random</span>() <span class="comment">// 随机生成一个0到1之间的数</span></span><br><span class="line">    <span class="keyword">if</span> (num &gt; <span class="number">0.5</span>) &#123;</span><br><span class="line">      <span class="title function_">resolve</span>(num) <span class="comment">// 如果大于0.5，则表示成功，调用resolve并传入结果</span></span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="title function_">reject</span>(num) <span class="comment">// 如果小于等于0.5，则表示失败，调用reject并传入结果</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;, <span class="number">1000</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 then 方法添加成功或失败时执行的回调函数（可以链式调用）</span></span><br><span class="line">promise</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">(<span class="params">value</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Success: <span class="subst">$&#123;value&#125;</span>`</span>) <span class="comment">// 如果Promise状态变为fulfilled，打印成功的结果</span></span><br><span class="line">    <span class="keyword">return</span> value * <span class="number">2</span> <span class="comment">// 可以返回一个新的值，传递给下一个then</span></span><br><span class="line">  &#125;)</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">(<span class="params">value</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Double: <span class="subst">$&#123;value&#125;</span>`</span>) <span class="comment">// 打印上一个then返回的值乘以2</span></span><br><span class="line">  &#125;)</span><br><span class="line">  .<span class="title function_">catch</span>(<span class="function">(<span class="params">reason</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Fail: <span class="subst">$&#123;reason&#125;</span>`</span>) <span class="comment">// 如果Promise状态变为rejected，打印失败的结果</span></span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Promise.all 方法组合多个Promise对象，返回一个新的Promise对象，该对象在所有Promise都成功时成功，否则失败</span></span><br><span class="line"><span class="keyword">let</span> promise1 = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(<span class="number">1</span>) <span class="comment">// 创建一个立即成功的Promise对象</span></span><br><span class="line"><span class="keyword">let</span> promise2 = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(<span class="number">2</span>)</span><br><span class="line"><span class="keyword">let</span> promise3 = <span class="title class_">Promise</span>.<span class="title function_">resolve</span>(<span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> promise4 = <span class="title class_">Promise</span>.<span class="title function_">all</span>([promise1, promise2, promise3]) <span class="comment">// 组合三个Promise对象</span></span><br><span class="line"></span><br><span class="line">promise4</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">(<span class="params">values</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(values) <span class="comment">// [1,2,3] （如果所有Promise都成功，打印一个包含所有结果的数组）</span></span><br><span class="line">  &#125;)</span><br><span class="line">  .<span class="title function_">catch</span>(<span class="function">(<span class="params">reason</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(reason) <span class="comment">// 如果有任何一个Promise失败，打印失败的结果</span></span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 Promise.race 方法组合多个Promise对象，返回一个新的Promise对象，该对象在任何一个Promise完成时完成（无论成功或失败）</span></span><br><span class="line"><span class="keyword">let</span> promise5 = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">resolve</span>(<span class="number">5</span>)</span><br><span class="line">  &#125;, <span class="number">500</span>) <span class="comment">// 0.5秒后成功</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">let</span> promise6 = <span class="keyword">new</span> <span class="title class_">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">reject</span>(<span class="number">6</span>)</span><br><span class="line">  &#125;, <span class="number">1000</span>) <span class="comment">// 1秒后失败</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> promise7 = <span class="title class_">Promise</span>.<span class="title function_">race</span>([promise5, promise6]) <span class="comment">// 组合两个Promise对象</span></span><br><span class="line"></span><br><span class="line">promise7</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">(<span class="params">value</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(value) <span class="comment">// 5 （如果有任何一个Promise先成功，打印成功的结果）</span></span><br><span class="line">  &#125;)</span><br><span class="line">  .<span class="title function_">catch</span>(<span class="function">(<span class="params">reason</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(reason) <span class="comment">// 如果有任何一个Promise先失败，打印失败的结果</span></span><br><span class="line">  &#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 async/await 语法简化异步操作（需要在函数前加上 async 关键字，并且在等待的地方加上 await 关键字）</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">test</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="keyword">let</span> value = <span class="keyword">await</span> promise <span class="comment">// 等待promise对象的结果（如果成功，赋值给value；如果失败，抛出异常）</span></span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Success: <span class="subst">$&#123;value&#125;</span>`</span>) <span class="comment">// 如果成功，打印结果</span></span><br><span class="line">  &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`Fail: <span class="subst">$&#123;error&#125;</span>`</span>) <span class="comment">// 如果失败，打印错误</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="title function_">test</span>() <span class="comment">// 调用异步函数</span></span><br></pre></td></tr></table></figure><h2 id="模块化"><a class="markdownIt-Anchor" href="#模块化"></a> 模块化</h2><p>模块化是一种将代码分割为不同的文件或模块的方法，可以提高代码的可读性、可维护性和复用性。ES6 提供了一种原生的模块化语法，可以让 JavaScript 支持导入和导出模块。导入模块使用 import 关键字，导出模块使用 export 关键字。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个名为 math.js 的模块文件，并且导出两个函数：add 和 multiply</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">add</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x + y</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">function</span> <span class="title function_">multiply</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x * y</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 在另一个文件中，使用 import 关键字导入 math.js 模块，并且使用它们</span></span><br><span class="line"><span class="keyword">import</span> &#123; add, multiply &#125; <span class="keyword">from</span> <span class="string">&#x27;./math.js&#x27;</span> <span class="comment">// 导入指定的函数（需要使用花括号）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">add</span>(<span class="number">1</span>, <span class="number">2</span>)) <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">multiply</span>(<span class="number">2</span>, <span class="number">3</span>)) <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以使用 as 关键字给导入或导出的函数起别名</span></span><br><span class="line"><span class="keyword">import</span> &#123; add <span class="keyword">as</span> plus, multiply <span class="keyword">as</span> times &#125; <span class="keyword">from</span> <span class="string">&#x27;./math.js&#x27;</span> <span class="comment">// 导入并重命名函数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">plus</span>(<span class="number">1</span>, <span class="number">2</span>)) <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">times</span>(<span class="number">2</span>, <span class="number">3</span>)) <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> &#123; add <span class="keyword">as</span> plus, multiply <span class="keyword">as</span> times &#125; <span class="comment">// 导出并重命名函数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以使用 * 符号导入或导出所有的函数（需要起一个别名）</span></span><br><span class="line"><span class="keyword">import</span> * <span class="keyword">as</span> math <span class="keyword">from</span> <span class="string">&#x27;./math.js&#x27;</span> <span class="comment">// 导入所有函数并起一个别名为math</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(math.<span class="title function_">add</span>(<span class="number">1</span>, <span class="number">2</span>)) <span class="comment">// 3</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(math.<span class="title function_">multiply</span>(<span class="number">2</span>, <span class="number">3</span>)) <span class="comment">// 6</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> * <span class="keyword">from</span> <span class="string">&#x27;./math.js&#x27;</span> <span class="comment">// 导出所有函数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 可以使用 default 关键字指定一个默认的导出（只能有一个，默认导出不需要花括号）</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">function</span> <span class="title function_">subtract</span>(<span class="params">x, y</span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> x - y</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> subtract <span class="keyword">from</span> <span class="string">&#x27;./math.js&#x27;</span> <span class="comment">// 导入默认导出（不需要花括号）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="title function_">subtract</span>(<span class="number">5</span>, <span class="number">4</span>)) <span class="comment">// 1</span></span><br></pre></td></tr></table></figure><h2 id="迭代器和生成器"><a class="markdownIt-Anchor" href="#迭代器和生成器"></a> 迭代器和生成器</h2><p>迭代器是一种遵循迭代协议的对象，可以按照一定的顺序访问一个集合中的元素。迭代器有一个 next 方法，每次调用返回一个包含 value 和 done 属性的对象，value 表示当前元素的值，done 表示是否还有更多元素。ES6 提供了一种新的语法 for…of 循环，可以方便地遍历迭代器。</p><p>生成器是一种特殊的函数，可以返回一个迭代器对象，并且可以在函数体内使用 yield 关键字暂停和恢复执行。生成器使用 function* 关键字声明，并且可以接收参数。</p><figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个迭代器对象：使用 Symbol.iterator 符号作为属性名，并且返回一个具有 next 方法的对象</span></span><br><span class="line"><span class="keyword">let</span> iterator = &#123;</span><br><span class="line">  [<span class="title class_">Symbol</span>.<span class="property">iterator</span>]() &#123;</span><br><span class="line">    <span class="keyword">let</span> i = <span class="number">0</span></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">      <span class="title function_">next</span>(<span class="params"></span>) &#123;</span><br><span class="line">        <span class="keyword">if</span> (i &lt; <span class="number">5</span>) &#123;</span><br><span class="line">          <span class="keyword">return</span> &#123; <span class="attr">value</span>: i++, <span class="attr">done</span>: <span class="literal">false</span> &#125; <span class="comment">// 返回当前元素的值和状态</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="keyword">return</span> &#123; <span class="attr">done</span>: <span class="literal">true</span> &#125; <span class="comment">// 返回结束状态</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;,</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 for...of 循环遍历迭代器对象（不需要调用 next 方法）</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> value <span class="keyword">of</span> iterator) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value) <span class="comment">// 0 1 2 3 4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个生成器函数：使用 function* 关键字，并且在函数体内使用 yield 关键字暂停和恢复执行</span></span><br><span class="line"><span class="keyword">function</span>* <span class="title function_">generator</span>(<span class="params">n</span>) &#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">    <span class="keyword">yield</span> i <span class="comment">// 每次遇到 yield 关键字，返回当前值并暂停执行，直到下一次调用 next 方法</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 调用生成器函数返回一个迭代器对象（可以传入参数）</span></span><br><span class="line"><span class="keyword">let</span> iter = <span class="title function_">generator</span>(<span class="number">5</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 for...of 循环遍历迭代器对象（不需要调用 next 方法）</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> value <span class="keyword">of</span> iter) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value) <span class="comment">// 0 1 2 3 4</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="map-和-set"><a class="markdownIt-Anchor" href="#map-和-set"></a> Map 和 Set</h2><p>Map 和 Set 是两种新的数据结构，可以提供更高效和灵活的存储和操作方式。Map 是一种类似于对象的集合，但是它可以使用任意类型的值作为键（而不仅仅是字符串）。Set 是一种类似于数组的集合，但是它只存储唯一的值（不会出现重复）。</p><figure class="highlight js"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建一个Map对象：使用 new 关键字，并且可以传入一个可迭代的数组作为初始值（每个元素是一个键值对数组）</span></span><br><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line">  [<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;Alice&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;age&#x27;</span>, <span class="number">18</span>],</span><br><span class="line">])</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 set 方法添加或修改键值对（可以使用任意类型的值作为键）</span></span><br><span class="line">map.<span class="title function_">set</span>(<span class="string">&#x27;gender&#x27;</span>, <span class="string">&#x27;female&#x27;</span>)</span><br><span class="line">map.<span class="title function_">set</span>(<span class="literal">true</span>, <span class="string">&#x27;yes&#x27;</span>)</span><br><span class="line">map.<span class="title function_">set</span>([<span class="number">1</span>, <span class="number">2</span>], <span class="string">&#x27;array&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 get 方法根据键获取对应的值（如果不存在，返回 undefined）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(<span class="string">&#x27;name&#x27;</span>)) <span class="comment">// Alice</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>(<span class="literal">true</span>)) <span class="comment">// yes</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">get</span>([<span class="number">1</span>, <span class="number">2</span>])) <span class="comment">// undefined （因为数组是引用类型，不相等）</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 has 方法判断是否存在某个键</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">has</span>(<span class="string">&#x27;age&#x27;</span>)) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">has</span>(<span class="string">&#x27;grade&#x27;</span>)) <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 delete 方法删除某个键值对（返回一个布尔值表示是否删除成功）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">delete</span>(<span class="string">&#x27;age&#x27;</span>)) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="title function_">delete</span>(<span class="string">&#x27;age&#x27;</span>)) <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 size 属性获取Map中的元素个数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>) <span class="comment">// 4</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 clear 方法清空Map中的所有元素</span></span><br><span class="line">map.<span class="title function_">clear</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(map.<span class="property">size</span>) <span class="comment">// 0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建一个Set对象：使用 new 关键字，并且可以传入一个可迭代的数组作为初始值（重复的元素会被忽略）</span></span><br><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">4</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 add 方法添加元素（如果已经存在，不会重复添加）</span></span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">5</span>)</span><br><span class="line">set.<span class="title function_">add</span>(<span class="number">4</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 has 方法判断是否存在某个元素</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="title function_">has</span>(<span class="number">3</span>)) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="title function_">has</span>(<span class="number">6</span>)) <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 delete 方法删除某个元素（返回一个布尔值表示是否删除成功）</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="title function_">delete</span>(<span class="number">2</span>)) <span class="comment">// true</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="title function_">delete</span>(<span class="number">2</span>)) <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 size 属性获取Set中的元素个数</span></span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="property">size</span>) <span class="comment">// 5</span></span><br><span class="line"><span class="comment">// 使用 clear 方法清空Set中的所有元素</span></span><br><span class="line">set.<span class="title function_">clear</span>()</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(set.<span class="property">size</span>) <span class="comment">// 0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Map和Set都是可迭代的对象，可以使用 for...of 循环或扩展运算符遍历它们</span></span><br><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="title class_">Map</span>([</span><br><span class="line">  [<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;Alice&#x27;</span>],</span><br><span class="line">  [<span class="string">&#x27;age&#x27;</span>, <span class="number">18</span>],</span><br><span class="line">])</span><br><span class="line"><span class="keyword">let</span> set = <span class="keyword">new</span> <span class="title class_">Set</span>([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 for...of 循环遍历Map或Set（Map的每个元素是一个键值对数组，Set的每个元素是一个值）</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> [key, value] <span class="keyword">of</span> map) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">`<span class="subst">$&#123;key&#125;</span>: <span class="subst">$&#123;value&#125;</span>`</span>) <span class="comment">// name: Alice  age: 18</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> value <span class="keyword">of</span> set) &#123;</span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(value) <span class="comment">// 1 2 3</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用扩展运算符将Map或Set转换为数组（Map的每个元素是一个键值对数组，Set的每个元素是一个值）</span></span><br><span class="line"><span class="keyword">let</span> mapArr = [...map]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(mapArr) <span class="comment">// [[&quot;name&quot;,&quot;Alice&quot;],[&quot;age&quot;,18]]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> setArr = [...set]</span><br><span class="line"><span class="variable language_">console</span>.<span class="title function_">log</span>(setArr) <span class="comment">// [1,2,3]</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">操千曲而后晓声，观千剑而后识器</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="JavaScript" scheme="https://luckynwa.top/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>内网穿透配置指南</title>
    <link href="https://luckynwa.top/posts/tool16/"/>
    <id>https://luckynwa.top/posts/tool16/</id>
    <published>2024-10-13T18:43:03.000Z</published>
    <updated>2026-07-07T16:19:34.413Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h1><p>内网穿透可以很好的将本地服务暴露到互联网中</p><h1 id="本地部署"><a class="markdownIt-Anchor" href="#本地部署"></a> 本地部署</h1><p>穿透资源放在 E:\装机必备软件\SSSS开发相关\选装99999999999999999999\内网穿透</p><p>不能直接复制已有云服务器的frp文件，还是老实用下面</p><p>frp_0.46.1_linux_amd64.tar.gz 拷贝到 linux 服务器上 /nwa 下</p><figure class="highlight shell"><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">cd /nwa</span><br><span class="line">tar -xvf frp_0.46.1_linux_amd64.tar.gz</span><br></pre></td></tr></table></figure><p>解压后可以删除 frpc 相关的文件。frps 的都是服务端文件，frpc 的都是客户端文件</p><figure class="highlight shell"><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">cd frp_0.46.1_linux_amd64</span><br><span class="line">rm -f frpc*</span><br></pre></td></tr></table></figure><p><strong>服务端配置</strong></p><p>文件 frps.ini</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[common]</span></span><br><span class="line"><span class="comment">#默认端口7000，客户端和服务端通信的端口，可以不用修改</span></span><br><span class="line"><span class="attr">bind_port</span> = <span class="number">7000</span></span><br><span class="line"><span class="comment">#http服务监听的端口，即frp服务端向外部暴露出去的端口</span></span><br><span class="line"><span class="attr">token</span>=luckyNwa</span><br><span class="line"><span class="comment">#frp的web管理控制台的用户名和密码，7500是默认端口，可以通过服务端ip+7500端口登录</span></span><br><span class="line"><span class="attr">dashboard_port</span> = <span class="number">7500</span></span><br><span class="line"><span class="comment">#frp管理页面的账号密码，随意设置</span></span><br><span class="line"><span class="attr">dashboard_user</span> = admin</span><br><span class="line"><span class="attr">dashboard_pwd</span> = 自己填一个密码</span><br><span class="line"><span class="comment">#日志</span></span><br><span class="line"><span class="attr">log_file</span> = ./frps.log</span><br><span class="line"><span class="comment">#log_level = info</span></span><br><span class="line"><span class="attr">log_max_days</span> = <span class="number">3</span></span><br></pre></td></tr></table></figure><p>启动 frps 服务端</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">./frps -c ./frps.ini</span><br><span class="line"></span><br><span class="line">下面是正常</span><br><span class="line">[root@iZbp1cnztnu129tiwtcmslZ frp_0.46.1_linux_amd64]# ps aux | grep frps</span><br><span class="line">root     29888  0.8  0.8 720192 16892 pts/1    Sl   12:59   0:00 ./frps -c ./frps.ini</span><br><span class="line">root     29927  0.0  0.0 112812   976 pts/1    S+   13:00   0:00 grep --color=auto frps</span><br><span class="line"></span><br><span class="line">kill -9 29888  杀掉进程</span><br><span class="line"></span><br><span class="line">nohup ./frps -c ./frps.ini &gt; frps_output.log 2&gt;&amp;1 &amp;   不断执行</span><br></pre></td></tr></table></figure><p>端口记得开放7000、7500是web面板</p><p><a href="http://ip:7500">http://ip:7500</a> 访问，关闭shell终端就会退出，重命名文件夹为frp，重新进入</p><p>账号：admin</p><p>密码：xxx</p><figure class="highlight shell"><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">cd /nwa/frp</span><br><span class="line">./frps -c ./frps.ini &amp;</span><br></pre></td></tr></table></figure><p><strong>客户端配置</strong></p><p>解压，留下 4 个文件即可 frpc.exe | frpc.ini | frpc_full.ini | LICENSE</p><p>编辑 frpc.ini ,其中这种[] 里的标题不能重复</p><figure class="highlight ini"><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 class="section">[common]</span></span><br><span class="line"><span class="attr">server_addr</span> = ip</span><br><span class="line"><span class="comment">#与服务端通信的端口，与frps.ini文件中的bind_port一致，默认不变</span></span><br><span class="line"><span class="attr">server_port</span> = <span class="number">7000</span></span><br><span class="line"><span class="attr">token</span> = luckyNwa</span><br><span class="line"></span><br><span class="line"><span class="section">[ssh]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">22</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">6000</span></span><br><span class="line"></span><br><span class="line"><span class="section">[ssh-13311]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">13311</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">13311</span></span><br><span class="line"></span><br><span class="line"><span class="section">[windows-13306]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">3389</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">13306</span></span><br><span class="line"></span><br><span class="line"><span class="section">[docker-23998]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23998</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23998</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql-13307]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">192.168</span>.<span class="number">0.109</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">13307</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">13307</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql-13308]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">192.168</span>.<span class="number">0.109</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">13308</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">13308</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#xshell-23311   docker-23998  redis-26379</span></span><br><span class="line"><span class="comment">#mysql5.7-23307  mysql8-23308</span></span><br><span class="line"><span class="section">[range:FTP]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_port</span> = <span class="number">20000</span>-<span class="number">30000</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">20000</span>-<span class="number">30000</span></span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br></pre></td></tr></table></figure><p>1w个端口太卡了，上面仅供参考</p><h2 id="n100最新"><a class="markdownIt-Anchor" href="#n100最新"></a> N100最新</h2><figure class="highlight ini"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[common]</span></span><br><span class="line"><span class="attr">server_addr</span> = ip</span><br><span class="line"><span class="comment">#与服务端通信的端口，与frps.ini文件中的bind_port一致，默认不变</span></span><br><span class="line"><span class="attr">server_port</span> = <span class="number">7000</span></span><br><span class="line"><span class="attr">token</span> = luckyNwa</span><br><span class="line"></span><br><span class="line"><span class="section">[Xshell|Xftp-23311]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23311</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23311</span></span><br><span class="line"></span><br><span class="line"><span class="section">[1panel-33333]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">33333</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">33333</span></span><br><span class="line"></span><br><span class="line"><span class="section">[docker-23998]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23998</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23998</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql5.7-23307]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23307</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23307</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql8-23308]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23308</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23308</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql5.7主-23309]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23309</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23309</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mysql5.7从-23310]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">23310</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">23310</span></span><br><span class="line"></span><br><span class="line"><span class="section">[redis-26379]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">26379</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">26379</span></span><br><span class="line"></span><br><span class="line"><span class="section">[maxkb-18080]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">18080</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">18080</span></span><br><span class="line"></span><br><span class="line"><span class="section">[ollama-11434]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">11434</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">11434</span></span><br><span class="line"></span><br><span class="line"><span class="section">[minio-9000]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">9000</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">9000</span></span><br><span class="line"></span><br><span class="line"><span class="section">[minio-9001]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">9001</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">9001</span></span><br><span class="line"></span><br><span class="line"><span class="section">[kodbox-8787]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">8787</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">8787</span></span><br><span class="line"></span><br><span class="line"><span class="section">[joplin-22300]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">22300</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">22300</span></span><br><span class="line"></span><br><span class="line"><span class="section">[NodeExporter-9101]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">9100</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">9101</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="section">[portainer-9209]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">9209</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">9209</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#下面是直接主机跑的</span></span><br><span class="line"></span><br><span class="line"><span class="section">[nacos-8848]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">8848</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">8848</span></span><br><span class="line"></span><br><span class="line"><span class="section">[xxl-8088]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">8088</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">8088</span></span><br><span class="line"></span><br><span class="line"><span class="section">[xxl-executor-9999]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">9999</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">9999</span></span><br><span class="line"></span><br><span class="line"><span class="section">[xxl-executor-8999]</span></span><br><span class="line"><span class="attr">type</span> = tcp</span><br><span class="line"><span class="attr">local_ip</span> = <span class="number">127.0</span>.<span class="number">0.1</span></span><br><span class="line"><span class="attr">local_port</span> = <span class="number">8999</span></span><br><span class="line"><span class="attr">remote_port</span> = <span class="number">8999</span></span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>window配合run_frp.bat，快速启动，关闭小黑窗即关闭</p><figure class="highlight bat"><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">echo</span> off</span><br><span class="line"><span class="built_in">cd</span> /d D:\bgsoft\frp</span><br><span class="line"><span class="keyword">call</span> .\frpc.exe -c frpc.ini</span><br></pre></td></tr></table></figure><p>客户端启动命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.\frpc.exe -c frpc.ini</span><br></pre></td></tr></table></figure><h1 id="第三方穿透"><a class="markdownIt-Anchor" href="#第三方穿透"></a> 第三方穿透</h1><p><a href="https://natapp.cn/tunnel/lists">https://natapp.cn/tunnel/lists</a> 免费的内网穿透 luckyNwa Nw…</p><p>注册完购买免费的 ，再下载它的客户端</p><p>E:\other\装机必备软件\SSSS开发相关\natapp_windows_amd64_2_3_9 不用下载，直接复制这个文件夹并启动，或者修改里面的bat</p><p>解压，并新建 start.bat脚本，内容那个token再申请那可以找到</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">natapp.exe -authtoken=760fb2fc902fb7f5</span><br></pre></td></tr></table></figure><p>双击启动即可看到Online 用来测试各种第三方回调</p>]]></content>
    
    
    <summary type="html">苟日新，日日新，又日新</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>MinIO使用</title>
    <link href="https://luckynwa.top/posts/java6/"/>
    <id>https://luckynwa.top/posts/java6/</id>
    <published>2024-09-04T20:57:52.000Z</published>
    <updated>2026-07-07T16:19:34.413Z</updated>
    
    <content type="html"><![CDATA[<h1 id="基础使用"><a class="markdownIt-Anchor" href="#基础使用"></a> 基础使用</h1><h2 id="1-创建配置类"><a class="markdownIt-Anchor" href="#1-创建配置类"></a> 1. 创建配置类</h2><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></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_">MinIOConfig</span> &#123;</span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> MinioClient <span class="title function_">minioClient</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> MinioClient.builder()</span><br><span class="line">                .endpoint(<span class="string">&quot;http://47.98.230.128:9000&quot;</span>)</span><br><span class="line">                .credentials(<span class="string">&quot;minioadmin&quot;</span>, <span class="string">&quot;minioadmin&quot;</span>)</span><br><span class="line">                .build();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="2-引入pom依赖"><a class="markdownIt-Anchor" href="#2-引入pom依赖"></a> 2. 引入pom依赖</h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--minio依赖--&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>io.minio<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>minio<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>8.2.1<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></pre></td></tr></table></figure><h2 id="3-测试类"><a class="markdownIt-Anchor" href="#3-测试类"></a> 3. 测试类</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Resource</span></span><br><span class="line"><span class="keyword">private</span> MinioClient minioClient;</span><br><span class="line"></span><br><span class="line">System.out.println(minioClient);</span><br></pre></td></tr></table></figure><p>查看桶是否存在，返回值布尔</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minioClient.bucketExists(BucketExistsArgs.builder().bucket(<span class="string">&quot;lucky&quot;</span>).build());</span><br></pre></td></tr></table></figure><p>创建桶，无返回值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minioClient.makeBucket(MakeBucketArgs.builder().bucket(<span class="string">&quot;test&quot;</span>).build());</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">List&lt;Bucket&gt; buckets = minioClient.listBuckets();</span><br><span class="line">buckets.forEach(bucket -&gt; &#123;</span><br><span class="line">    System.out.println(<span class="string">&quot;name: &quot;</span> + bucket.name() + <span class="string">&quot;；creationDate: &quot;</span> + bucket.creationDate());</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>删除桶，无返回值</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">minioClient.removeBucket(RemoveBucketArgs.builder().bucket(<span class="string">&quot;test&quot;</span>).build());</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\load\\W200H1009.png&quot;</span>);</span><br><span class="line"><span class="type">FileInputStream</span> <span class="variable">stream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file);</span><br><span class="line"><span class="type">ObjectWriteResponse</span> <span class="variable">response</span> <span class="operator">=</span> minioClient.putObject(PutObjectArgs.builder()</span><br><span class="line">        .bucket(<span class="string">&quot;lucky&quot;</span>) <span class="comment">// 指定上传的桶</span></span><br><span class="line">        .object(<span class="string">&quot;my-test.png&quot;</span>) <span class="comment">// 上传到桶中之后的文件叫啥名字</span></span><br><span class="line">        <span class="comment">// 文件流，文件大小，分片大小（通常为 -1，自动推断，若手动填写，必须在 5M -5G 之间）</span></span><br><span class="line">        .stream(stream, file.length(), -<span class="number">1</span>)</span><br><span class="line">        .build());</span><br></pre></td></tr></table></figure><p>minio支持自动建文件夹比如a/b/my-test2.jpg，会创建2层</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></pre></td><td class="code"><pre><span class="line"><span class="type">ObjectWriteResponse</span> <span class="variable">response</span> <span class="operator">=</span> minioClient.uploadObject(UploadObjectArgs.builder()</span><br><span class="line">        .bucket(<span class="string">&quot;public-readonly-file&quot;</span>)</span><br><span class="line">        .object(<span class="string">&quot;my-test2.jpg&quot;</span>)</span><br><span class="line">        .filename(<span class="string">&quot;D:\\load\\W200H1009.png&quot;</span>)</span><br><span class="line">        .build());</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="type">StatObjectResponse</span> <span class="variable">response</span> <span class="operator">=</span> minioClient.statObject(StatObjectArgs.builder()</span><br><span class="line">        .bucket(<span class="string">&quot;lucky&quot;</span>) <span class="comment">// 查询的桶名</span></span><br><span class="line">        .object(<span class="string">&quot;my-test.png&quot;</span>) <span class="comment">// 文件名字</span></span><br><span class="line">        .build());</span><br><span class="line">System.out.println(response);</span><br></pre></td></tr></table></figure><p>GET生成可访问的签名 url 地址, Put生成的是上传链接前端通过上传链接去上传</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="type">String</span> <span class="variable">url</span> <span class="operator">=</span> minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()</span><br><span class="line">        .bucket(<span class="string">&quot;lucky&quot;</span>)</span><br><span class="line">        .object(<span class="string">&quot;my-test.png&quot;</span>)</span><br><span class="line">        .method(Method.GET)</span><br><span class="line">        .build());</span><br><span class="line">System.out.println(url);</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">minioClient.removeObject(RemoveObjectArgs.builder()</span><br><span class="line">        .bucket(<span class="string">&quot;lucky&quot;</span>)</span><br><span class="line">        .object(<span class="string">&quot;my-test.png&quot;</span>)</span><br><span class="line">        .build());</span><br></pre></td></tr></table></figure><p>公开 url 访问权限</p><ul><li>桶权限改成public，不推荐，任何人不使用用户名和密码认证，都可以对该桶的文件信息上传，下载和删除</li><li>使用 makeBucket 创建桶后，使用 setBucketPolicy 设置访问策略，用户只读权限</li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">bucketName</span> <span class="operator">=</span> <span class="string">&quot;public-readonly-file&quot;</span>;</span><br><span class="line"><span class="comment">// 创建桶</span></span><br><span class="line">minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());</span><br><span class="line"><span class="comment">// 需要的就是这一串代码访问策略</span></span><br><span class="line"><span class="type">String</span> <span class="variable">policyJsonString</span> <span class="operator">=</span> <span class="string">&quot;&#123;\&quot;Version\&quot;:\&quot;2024-07-11\&quot;,\&quot;Statement\&quot;:[&#123;\&quot;Sid\&quot;:\&quot;PublicRead\&quot;,\&quot;Effect\&quot;:\&quot;Allow\&quot;,\&quot;Principal\&quot;:&#123;\&quot;AWS\&quot;:\&quot;*\&quot;&#125;,\&quot;Action\&quot;:[\&quot;s3:GetObject\&quot;],\&quot;Resource\&quot;:[\&quot;arn:aws:s3:::&quot;</span> + bucketName + <span class="string">&quot;/*\&quot;]&#125;]&#125;&quot;</span>;</span><br><span class="line">minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()</span><br><span class="line">        .bucket(bucketName)</span><br><span class="line">        .config(policyJsonString)</span><br><span class="line">        .build());</span><br></pre></td></tr></table></figure><p>创完之后去（6-2）上传了一张</p><p>访问<a href="http://47.98.230.128:29000/public-readonly-file/my-test2.jpg">http://47.98.230.128:29000/public-readonly-file/my-test2.jpg</a></p><p>有点牛逼！！！</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> io.minio.MinioClient;</span><br><span class="line"><span class="keyword">import</span> io.minio.ObjectWriteResponse;</span><br><span class="line"><span class="keyword">import</span> io.minio.PutObjectArgs;</span><br><span class="line"><span class="keyword">import</span> io.minio.errors.*;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.test.context.SpringBootTest;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringRunner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.annotation.Resource;</span><br><span class="line"><span class="keyword">import</span> java.io.File;</span><br><span class="line"><span class="keyword">import</span> java.io.FileInputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.security.InvalidKeyException;</span><br><span class="line"><span class="keyword">import</span> java.security.NoSuchAlgorithmException;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2024/7/11 -15:06</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RunWith(SpringRunner.class)</span></span><br><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MinioTest</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> MinioClient minioClient;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">minioTest</span><span class="params">()</span> <span class="keyword">throws</span> ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException &#123;</span><br><span class="line">        <span class="comment">//System.out.println(minioClient);//打印是否有这个实例</span></span><br><span class="line">        <span class="comment">//  minioClient.bucketExists(BucketExistsArgs.builder().bucket(&quot;lucky&quot;).build());//查看是否存在，返回值布尔</span></span><br><span class="line">        <span class="comment">//  minioClient.makeBucket(MakeBucketArgs.builder().bucket(&quot;test&quot;).build());//创建桶，无返回值</span></span><br><span class="line">        <span class="comment">//查看全部有权访问的桶</span></span><br><span class="line"><span class="comment">//        List&lt;Bucket&gt; buckets = minioClient.listBuckets();</span></span><br><span class="line"><span class="comment">//        buckets.forEach(bucket -&gt; &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(&quot;name: &quot; + bucket.name() + &quot;；creationDate: &quot; + bucket.creationDate());</span></span><br><span class="line"><span class="comment">//        &#125;);</span></span><br><span class="line">        <span class="comment">// minioClient.removeBucket(RemoveBucketArgs.builder().bucket(&quot;test&quot;).build()); //删除桶，无返回值</span></span><br><span class="line">        <span class="comment">//上传文件到桶中、常用方法1</span></span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\load\\W200H1009.png&quot;</span>);</span><br><span class="line">        <span class="type">FileInputStream</span> <span class="variable">stream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file);</span><br><span class="line">        <span class="type">ObjectWriteResponse</span> <span class="variable">response</span> <span class="operator">=</span> minioClient.putObject(PutObjectArgs.builder()</span><br><span class="line">                .bucket(<span class="string">&quot;lucky&quot;</span>) <span class="comment">// 指定上传的桶</span></span><br><span class="line">                .object(<span class="string">&quot;my-test.png&quot;</span>) <span class="comment">// 上传到桶中之后的文件叫啥名字</span></span><br><span class="line">                <span class="comment">// 文件流，文件大小，分片大小（通常为 -1，自动推断，若手动填写，必须在 5M -5G 之间）</span></span><br><span class="line">                .stream(stream, file.length(), -<span class="number">1</span>)</span><br><span class="line">                .build());</span><br><span class="line">        <span class="comment">//新方法，minio支持自动建文件夹比如a/b/my-test2.jpg，会创建2层</span></span><br><span class="line"><span class="comment">//        ObjectWriteResponse response = minioClient.uploadObject(UploadObjectArgs.builder()</span></span><br><span class="line"><span class="comment">//                .bucket(&quot;public-readonly-file&quot;)</span></span><br><span class="line"><span class="comment">//                .object(&quot;my-test2.jpg&quot;)</span></span><br><span class="line"><span class="comment">//                .filename(&quot;D:\\load\\W200H1009.png&quot;)</span></span><br><span class="line"><span class="comment">//                .build());</span></span><br><span class="line"><span class="comment">//查不到该文件，会直接报异常，所以 statObject 是肯定可以正常返回数据的</span></span><br><span class="line"><span class="comment">//        StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder()</span></span><br><span class="line"><span class="comment">//                .bucket(&quot;lucky&quot;) // 查询的桶名</span></span><br><span class="line"><span class="comment">//                .object(&quot;my-test.png&quot;) // 文件名字</span></span><br><span class="line"><span class="comment">//                .build());</span></span><br><span class="line"><span class="comment">//        System.out.println(response);</span></span><br><span class="line"><span class="comment">//GET生成可访问的签名 url 地址, Put生成的是上传链接前端通过上传链接去上传</span></span><br><span class="line"><span class="comment">//        String url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()</span></span><br><span class="line"><span class="comment">//                .bucket(&quot;lucky&quot;)</span></span><br><span class="line"><span class="comment">//                .object(&quot;my-test.png&quot;)</span></span><br><span class="line"><span class="comment">//                .method(Method.GET)</span></span><br><span class="line"><span class="comment">//                .build());</span></span><br><span class="line"><span class="comment">//        System.out.println(url);</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//删除桶中的文件</span></span><br><span class="line"><span class="comment">//        minioClient.removeObject(RemoveObjectArgs.builder()</span></span><br><span class="line"><span class="comment">//                .bucket(&quot;lucky&quot;)</span></span><br><span class="line"><span class="comment">//                .object(&quot;my-test.png&quot;)</span></span><br><span class="line"><span class="comment">//                .build());</span></span><br><span class="line"><span class="comment">//公开 url 访问权限</span></span><br><span class="line">        <span class="comment">//1、桶权限改成public，不推荐，任何人不使用用户名和密码认证，都可以对该桶的文件信息上传，下载和删除</span></span><br><span class="line">        <span class="comment">//2、使用 makeBucket 创建桶后，使用 setBucketPolicy 设置访问策略，用户只读权限</span></span><br><span class="line"><span class="comment">//        String bucketName = &quot;public-readonly-file&quot;;</span></span><br><span class="line"><span class="comment">//// 创建桶</span></span><br><span class="line"><span class="comment">//        minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());</span></span><br><span class="line"><span class="comment">//// 需要的就是这一串代码访问策略</span></span><br><span class="line"><span class="comment">//        String policyJsonString = &quot;&#123;\&quot;Version\&quot;:\&quot;2024-07-11\&quot;,\&quot;Statement\&quot;:[&#123;\&quot;Sid\&quot;:\&quot;PublicRead\&quot;,\&quot;Effect\&quot;:\&quot;Allow\&quot;,\&quot;Principal\&quot;:&#123;\&quot;AWS\&quot;:\&quot;*\&quot;&#125;,\&quot;Action\&quot;:[\&quot;s3:GetObject\&quot;],\&quot;Resource\&quot;:[\&quot;arn:aws:s3:::&quot; + bucketName + &quot;/*\&quot;]&#125;]&#125;&quot;;</span></span><br><span class="line"><span class="comment">//        minioClient.setBucketPolicy(SetBucketPolicyArgs.builder()</span></span><br><span class="line"><span class="comment">//                .bucket(bucketName)</span></span><br><span class="line"><span class="comment">//                .config(policyJsonString)</span></span><br><span class="line"><span class="comment">//                .build());//去上面上传了一张 通过http://47.98.230.128:29000/public-readonly-file/my-test2.jpg访问有点牛逼</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="封装使用"><a class="markdownIt-Anchor" href="#封装使用"></a> 封装使用</h1><p>简单封装使用</p><p>（1）yml配置</p><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></pre></td><td class="code"><pre><span class="line"><span class="attr">minio:</span></span><br><span class="line">  <span class="comment">#accessKey ,secretKey值的获取在配置accessKey步骤体现</span></span><br><span class="line">  <span class="attr">accessKey:</span> <span class="string">luckynwa.top</span></span><br><span class="line">  <span class="attr">secretKey:</span> <span class="string">f4e2e52034348f86b67cde581c0f9eb5[luckynwa.top]</span></span><br><span class="line">  <span class="comment"># 存放文件的桶</span></span><br><span class="line">  <span class="attr">bucket:</span> <span class="string">lucky</span></span><br><span class="line">  <span class="comment"># 访问路径</span></span><br><span class="line">  <span class="attr">endpoint:</span> <span class="string">http://47.98.230.128:9000</span></span><br><span class="line">  <span class="attr">readPath:</span> <span class="string">http://47.98.230.128:9000</span></span><br><span class="line">  <span class="attr">servlet:</span></span><br><span class="line">    <span class="attr">multipart:</span></span><br><span class="line">      <span class="attr">max-file-size:</span> <span class="string">200MB</span></span><br><span class="line">      <span class="attr">max-request-size:</span> <span class="string">200MB</span></span><br></pre></td></tr></table></figure><p>（2）yml类</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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> lombok.Data;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.ConfigurationProperties;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.Serializable;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2024/7/11 -16:27</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@ConfigurationProperties(prefix = &quot;minio&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MinIOYml</span> <span class="keyword">implements</span> <span class="title class_">Serializable</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String accessKey;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String secretKey;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String bucket;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String endpoint;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String readPath;</span><br><span class="line"></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> io.minio.MinioClient;</span><br><span class="line"><span class="keyword">import</span> lombok.Data;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.EnableConfigurationProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableConfigurationProperties(&#123;MinIOYml.class&#125;)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MinIOConfig</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> MinIOYml minIOYml;</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> MinioClient <span class="title function_">buildMinioClient</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> MinioClient</span><br><span class="line">                .builder()</span><br><span class="line">                .credentials(minIOYml.getAccessKey(), minIOYml.getSecretKey())</span><br><span class="line">                .endpoint(minIOYml.getEndpoint())</span><br><span class="line">                .build();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>（4）MinIO处理接口</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.modules.bed.service;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.common.utils.R;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">MinIOService</span> &#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上传图片文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> prefix      文件前缀</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> filename    文件名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> inputStream 文件流</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 文件全路径</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">uploadImgFile</span><span class="params">(String prefix, String filename, InputStream inputStream)</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上传html文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> prefix      文件前缀</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> filename    文件名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> inputStream 文件流</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 文件全路径</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">uploadHtmlFile</span><span class="params">(String prefix, String filename, InputStream inputStream)</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> pathUrl 文件全路径</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">delete</span><span class="params">(String pathUrl)</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 下载文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> pathUrl 文件全路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">byte</span>[] downLoadFile(String pathUrl);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>（5）MinIO接口实现类</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.modules.bed.service.impl;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2024/7/12 -10:46</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.common.utils.R;</span><br><span class="line"><span class="keyword">import</span> com.nwa.config.MinIOConfig;</span><br><span class="line"><span class="keyword">import</span> com.nwa.config.MinIOYml;</span><br><span class="line"><span class="keyword">import</span> com.nwa.modules.bed.service.MinIOService;</span><br><span class="line"><span class="keyword">import</span> io.minio.GetObjectArgs;</span><br><span class="line"><span class="keyword">import</span> io.minio.MinioClient;</span><br><span class="line"><span class="keyword">import</span> io.minio.PutObjectArgs;</span><br><span class="line"><span class="keyword">import</span> io.minio.RemoveObjectArgs;</span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.context.properties.EnableConfigurationProperties;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Import;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Service;</span><br><span class="line"><span class="keyword">import</span> org.springframework.util.StringUtils;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.annotation.Resource;</span><br><span class="line"><span class="keyword">import</span> java.io.ByteArrayOutputStream;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStream;</span><br><span class="line"><span class="keyword">import</span> java.text.SimpleDateFormat;</span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Service</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="meta">@EnableConfigurationProperties(MinIOYml.class)</span></span><br><span class="line"><span class="meta">@Import(MinIOConfig.class)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MinIOServiceImpl</span> <span class="keyword">implements</span> <span class="title class_">MinIOService</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> MinioClient minioClient;</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> MinIOYml minIOYml;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">static</span> <span class="type">String</span> <span class="variable">separator</span> <span class="operator">=</span> <span class="string">&quot;/&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 文件前缀为空则用当前时间</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> dirPath</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> filename yyyy/mm/dd/file.jpg</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">builderFilePath</span><span class="params">(String dirPath, String filename)</span> &#123;</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">stringBuilder</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(<span class="number">50</span>);</span><br><span class="line">        <span class="keyword">if</span> (!StringUtils.isEmpty(dirPath)) &#123;</span><br><span class="line">            stringBuilder.append(dirPath).append(separator);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">SimpleDateFormat</span> <span class="variable">sdf</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SimpleDateFormat</span>(<span class="string">&quot;yyyy/MM/dd&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">todayStr</span> <span class="operator">=</span> sdf.format(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">        stringBuilder.append(todayStr).append(separator);</span><br><span class="line">        stringBuilder.append(filename);</span><br><span class="line">        <span class="keyword">return</span> stringBuilder.toString();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上传图片文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> prefix      文件前缀</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> filename    文件名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> inputStream 文件流</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 文件全路径</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">uploadImgFile</span><span class="params">(String prefix, String filename, InputStream inputStream)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> builderFilePath(prefix, filename);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">PutObjectArgs</span> <span class="variable">putObjectArgs</span> <span class="operator">=</span> PutObjectArgs.builder()</span><br><span class="line">                    .object(filePath)</span><br><span class="line">                    .contentType(<span class="string">&quot;image/jpg&quot;</span>)</span><br><span class="line">                    .bucket(minIOYml.getBucket()).stream(inputStream, inputStream.available(), -<span class="number">1</span>)</span><br><span class="line">                    .build();</span><br><span class="line">            minioClient.putObject(putObjectArgs);</span><br><span class="line">            <span class="type">StringBuilder</span> <span class="variable">urlPath</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(minIOYml.getReadPath());</span><br><span class="line">            urlPath.append(separator + minIOYml.getBucket());</span><br><span class="line">            urlPath.append(separator);</span><br><span class="line">            urlPath.append(filePath);</span><br><span class="line">            <span class="keyword">return</span> urlPath.toString();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;minio put file error.&quot;</span>, ex);</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;上传文件失败&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 上传html文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> prefix      文件前缀</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> filename    文件名</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> inputStream 文件流</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 文件全路径</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">uploadHtmlFile</span><span class="params">(String prefix, String filename, InputStream inputStream)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> builderFilePath(prefix, filename);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">PutObjectArgs</span> <span class="variable">putObjectArgs</span> <span class="operator">=</span> PutObjectArgs.builder()</span><br><span class="line">                    .object(filePath)</span><br><span class="line">                    .contentType(<span class="string">&quot;text/html&quot;</span>)</span><br><span class="line">                    .bucket(minIOYml.getBucket()).stream(inputStream, inputStream.available(), -<span class="number">1</span>)</span><br><span class="line">                    .build();</span><br><span class="line">            minioClient.putObject(putObjectArgs);</span><br><span class="line">            <span class="type">StringBuilder</span> <span class="variable">urlPath</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(minIOYml.getReadPath());</span><br><span class="line">            urlPath.append(separator + minIOYml.getBucket());</span><br><span class="line">            urlPath.append(separator);</span><br><span class="line">            urlPath.append(filePath);</span><br><span class="line">            <span class="keyword">return</span> urlPath.toString();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception ex) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;minio put file error.&quot;</span>, ex);</span><br><span class="line">            ex.printStackTrace();</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(<span class="string">&quot;上传文件失败&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 删除文件</span></span><br><span class="line"><span class="comment">     * 文件全路径</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> pathUrl http://47.98.230.128:9000/public-readonly-file/my-test2.jpg</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">delete</span><span class="params">(String pathUrl)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">key</span> <span class="operator">=</span> pathUrl.replace(minIOYml.getEndpoint() + <span class="string">&quot;/&quot;</span>, <span class="string">&quot;&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> key.indexOf(separator);</span><br><span class="line">        <span class="type">String</span> <span class="variable">bucket</span> <span class="operator">=</span> key.substring(<span class="number">0</span>, index);</span><br><span class="line">        <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> key.substring(index + <span class="number">1</span>);</span><br><span class="line">        <span class="comment">// 删除Objects</span></span><br><span class="line">        <span class="type">RemoveObjectArgs</span> <span class="variable">removeObjectArgs</span> <span class="operator">=</span> RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            minioClient.removeObject(removeObjectArgs);</span><br><span class="line">            <span class="keyword">return</span> R.ok(<span class="string">&quot;删除成功&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;minio remove file error.  pathUrl:&#123;&#125;&quot;</span>, pathUrl);</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">return</span> R.ok(<span class="string">&quot;删除失败&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 下载文件</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@param</span> pathUrl http://47.98.230.128:9000/lucky/pic/W200H1002.png 文件全路径</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> 文件流</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">byte</span>[] downLoadFile(String pathUrl) &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">key</span> <span class="operator">=</span> pathUrl.replace(minIOYml.getEndpoint() + <span class="string">&quot;/&quot;</span>, <span class="string">&quot;&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">index</span> <span class="operator">=</span> key.indexOf(separator);</span><br><span class="line">        <span class="type">String</span> <span class="variable">bucket</span> <span class="operator">=</span> key.substring(<span class="number">0</span>, index);</span><br><span class="line">        <span class="type">String</span> <span class="variable">filePath</span> <span class="operator">=</span> key.substring(index + <span class="number">1</span>);</span><br><span class="line">        <span class="type">InputStream</span> <span class="variable">inputStream</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOYml.getBucket()).object(filePath).build());</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;minio down file error.  pathUrl:&#123;&#125;&quot;</span>, pathUrl);</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">ByteArrayOutputStream</span> <span class="variable">byteArrayOutputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ByteArrayOutputStream</span>();</span><br><span class="line">        <span class="type">byte</span>[] buff = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">100</span>];</span><br><span class="line">        <span class="type">int</span> <span class="variable">rc</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> (!((rc = inputStream.read(buff, <span class="number">0</span>, <span class="number">100</span>)) &gt; <span class="number">0</span>)) <span class="keyword">break</span>;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">                e.printStackTrace();</span><br><span class="line">            &#125;</span><br><span class="line">            byteArrayOutputStream.write(buff, <span class="number">0</span>, rc);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> byteArrayOutputStream.toByteArray();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>（6）MinIO调用</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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Resource</span></span><br><span class="line">MinIOServiceImpl minIOFileStorageService;</span><br><span class="line"></span><br><span class="line"><span class="meta">@ApiOperation(&quot;上传到MinIO&quot;)</span></span><br><span class="line"><span class="meta">@PostMapping(&quot;/fileupload&quot;)</span></span><br><span class="line"><span class="keyword">public</span> R <span class="title function_">minIo</span><span class="params">(MultipartFile multipartFile)</span> &#123;</span><br><span class="line">    <span class="comment">// 检查multipartFile是否为空</span></span><br><span class="line">    <span class="keyword">if</span> (multipartFile == <span class="literal">null</span> || multipartFile.isEmpty()) &#123;</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="string">&quot;文件为空，无法处理&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">try</span> (<span class="type">InputStream</span> <span class="variable">inputStream</span> <span class="operator">=</span> multipartFile.getInputStream()) &#123;  <span class="comment">// 将MultipartFile转换为InputStream</span></span><br><span class="line">        <span class="comment">// 上传到MinIO服务器</span></span><br><span class="line">        <span class="comment">// 这里的文件名可以生成随机的名称，防止重复</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">url</span> <span class="operator">=</span> minIOFileStorageService.uploadImgFile(<span class="string">&quot;testjpg&quot;</span>, <span class="string">&quot;test1.jpg&quot;</span>, inputStream);</span><br><span class="line">        <span class="keyword">return</span> R.ok(url);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">        <span class="comment">// 处理异常，可能是getInputStream()失败</span></span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="string">&quot;获取InputStream失败：&quot;</span> + e.getMessage());</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@ApiOperation(&quot;删除MinIO文件&quot;)</span></span><br><span class="line"><span class="meta">@PostMapping(&quot;/deleteMinIoFile&quot;)</span></span><br><span class="line"><span class="keyword">public</span> R <span class="title function_">deleteMinIoFile</span><span class="params">(String pathUrl)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> minIOFileStorageService.delete(pathUrl);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@ApiOperation(&quot;下载MinIO文件&quot;)</span></span><br><span class="line"><span class="meta">@GetMapping(&quot;/downLoadMinIOFile&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="type">byte</span>[] downLoadMinIOFile(String pathUrl) &#123;</span><br><span class="line">    <span class="keyword">return</span> minIOFileStorageService.downLoadFile(pathUrl);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="其他"><a class="markdownIt-Anchor" href="#其他"></a> 其他</h1><p>我采用人人框架为后台，将采取策略模式，将MinIO兼容进桶中</p>]]></content>
    
    
    <summary type="html">沉舟侧畔千帆过，病树前头万木春</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Middleware" scheme="https://luckynwa.top/tags/Middleware/"/>
    
  </entry>
  
  <entry>
    <title>Node 环境</title>
    <link href="https://luckynwa.top/posts/tool10/"/>
    <id>https://luckynwa.top/posts/tool10/</id>
    <published>2024-09-02T02:42:54.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h2 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h2><p>Nvm（Node Version Manager）是一款用于管理 Node.js 版本的工具，可以轻松地在一个系统中切换和安装多个 Node.js 版本。<strong>现在只推荐用它来管理 Node</strong>，因为不同的项目可能需要不同版本。</p><h2 id="卸载已有的-node"><a class="markdownIt-Anchor" href="#卸载已有的-node"></a> 卸载已有的 Node</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node -v      # 查看当前版本</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></pre></td><td class="code"><pre><span class="line">C:\Program Files (x86)\Nodejs</span><br><span class="line">C:\Program Files\Nodejs</span><br><span class="line">C:\Users\用户名\AppData\Roaming\npm</span><br><span class="line">C:\Users\用户名\AppData\Roaming\npm-cache</span><br></pre></td></tr></table></figure><p>再去删除环境变量，然后查看版本确认已清除。</p><h2 id="安装-nvm"><a class="markdownIt-Anchor" href="#安装-nvm"></a> 安装 Nvm</h2><blockquote><p>Nvm 文件夹不需要手动建，nodejs 文件夹要建。</p></blockquote><ul><li>安装路径：<code>D:\soft\nvm</code></li><li>Node 资源路径：<code>D:\soft\nodejs</code></li></ul><h2 id="常用命令"><a class="markdownIt-Anchor" href="#常用命令"></a> 常用命令</h2><table><thead><tr><th>命令</th><th>说明</th></tr></thead><tbody><tr><td><code>nvm install &lt;version&gt;</code></td><td>安装指定版本的 Node.js</td></tr><tr><td><code>nvm use &lt;version&gt;</code></td><td>切换到指定版本的 Node.js</td></tr><tr><td><code>nvm ls</code></td><td>列出已安装的所有 Node.js 版本</td></tr><tr><td><code>nvm alias &lt;name&gt; &lt;version&gt;</code></td><td>给指定版本创建别名</td></tr><tr><td><code>nvm run &lt;version&gt; &lt;script&gt;</code></td><td>在指定版本下运行脚本</td></tr><tr><td><code>nvm current</code></td><td>显示当前正在使用的 Node.js 版本</td></tr><tr><td><code>nvm uninstall &lt;version&gt;</code></td><td>卸载指定版本的 Node.js</td></tr></tbody></table><h2 id="实际使用示例"><a class="markdownIt-Anchor" href="#实际使用示例"></a> 实际使用示例</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">nvm install 16.20.1</span><br><span class="line">nvm install 14.0.0</span><br><span class="line">nvm use 14.0.0</span><br><span class="line"></span><br><span class="line">nvm install 14.17.6       # 人人前端最少需要的版本</span><br><span class="line">nvm use 14.17.6</span><br><span class="line"></span><br><span class="line">nvm install 18.16.1</span><br><span class="line">nvm install 24.13.0</span><br><span class="line"></span><br><span class="line">node -v</span><br><span class="line"></span><br><span class="line">npm config set registry https://registry.npmmirror.com      # 国内镜像</span><br><span class="line"></span><br><span class="line">npm config set registry https://registry.npmjs.org          # 重置镜像为官网</span><br><span class="line"></span><br><span class="line">nvm use 16.20.1</span><br><span class="line">nvm use 18.16.1</span><br></pre></td></tr></table></figure><h2 id="vscode-使用-pnpm-报错解决"><a class="markdownIt-Anchor" href="#vscode-使用-pnpm-报错解决"></a> VSCode 使用 pnpm 报错解决</h2><p>在 VSCode 终端运行：</p><figure class="highlight shell"><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">Get-ExecutionPolicy          # 发现 Restricted 不允许运行任何脚本文件</span><br><span class="line">Set-ExecutionPolicy RemoteSigned   # 允许运行本地创建的脚本</span><br></pre></td></tr></table></figure><h2 id="node-sass-安装问题"><a class="markdownIt-Anchor" href="#node-sass-安装问题"></a> node-sass 安装问题</h2><p>遇到 node-sass 无法安装，切 14 版本：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">宣父犹能畏后生，丈夫未可轻年少</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Vue" scheme="https://luckynwa.top/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>Java多线程与锁详解</title>
    <link href="https://luckynwa.top/posts/java5/"/>
    <id>https://luckynwa.top/posts/java5/</id>
    <published>2024-08-29T00:48:13.000Z</published>
    <updated>2026-07-07T16:19:34.366Z</updated>
    
    <content type="html"><![CDATA[<h2 id="synchronized关键字"><a class="markdownIt-Anchor" href="#synchronized关键字"></a> synchronized关键字</h2><p><code>synchronized</code> 是 Java 中用于实现线程同步的关键字。它可以用于修饰代码块或方法，确保在同一时间只有一个线程可以访问被 <code>synchronized</code> 修饰的代码块或方法。</p><p>任何一个对象都有&quot;一把锁&quot;</p><h3 id="加锁地方1同步代码块"><a class="markdownIt-Anchor" href="#加锁地方1同步代码块"></a> 加锁地方1：同步代码块</h3><p>synchronized 写在块级内容上的格式：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">synchronized</span>(多线程共享对象) &#123;</span><br><span class="line">    线程同步代码块</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 共享的一般是 this，指的是这个类的实例</span></span><br></pre></td></tr></table></figure><h3 id="加锁地方2实例方法"><a class="markdownIt-Anchor" href="#加锁地方2实例方法"></a> 加锁地方2：实例方法</h3><p>synchronized 出现在实例方法上，一定锁的是 <code>this</code></p><h3 id="执行流程"><a class="markdownIt-Anchor" href="#执行流程"></a> 执行流程</h3><ol><li>假设 t1 和 t2 线程并发，开始执行时肯定有一个先一个后</li><li>假设 t1 先执行，遇到 synchronized，自动找&quot;后面共享对象&quot;的对象锁，找到后占有这把锁，执行同步代码块，直到代码结束才释放锁</li><li>假设 t1 已经占有锁，t2 也遇到 synchronized，也会去占有这把锁，但锁被 t1 占有，t2 只能在外面等待，直到 t1 执行结束归还锁</li><li>这样就达到了线程排队执行</li></ol><h3 id="静态方法加锁"><a class="markdownIt-Anchor" href="#静态方法加锁"></a> 静态方法加锁</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">method</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 锁的是当前类的Class对象，而不是this</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="wait和notify"><a class="markdownIt-Anchor" href="#wait和notify"></a> wait和notify</h2><p>wait 和 notify 方法<strong>不是线程对象的方法</strong>，是 java 中任何一个对象都有的方法，因为这两个方法是 <code>Object类中自带</code> 的</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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 线程1执行</span></span><br><span class="line"><span class="keyword">synchronized</span>(lock) &#123;</span><br><span class="line">    <span class="keyword">while</span>(condition不满足) &#123;</span><br><span class="line">        lock.wait();    <span class="comment">// 释放锁，进入等待队列</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">// 执行业务逻辑</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 线程2执行</span></span><br><span class="line"><span class="keyword">synchronized</span>(lock) &#123;</span><br><span class="line">    <span class="comment">// 修改condition</span></span><br><span class="line">    lock.notify();     <span class="comment">// 唤醒等待队列中的一个线程</span></span><br><span class="line">    <span class="comment">// 或 lock.notifyAll(); 唤醒所有等待线程</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>注意</strong>：wait和notify必须在synchronized块内调用，否则会抛出IllegalMonitorStateException</p><h2 id="线程基础"><a class="markdownIt-Anchor" href="#线程基础"></a> 线程基础</h2><h3 id="线程的创建方式"><a class="markdownIt-Anchor" href="#线程的创建方式"></a> 线程的创建方式</h3><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 1. 继承Thread</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyThread</span> <span class="keyword">extends</span> <span class="title class_">Thread</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;线程执行&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">MyThread</span>().start();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 2. 实现Runnable（推荐）</span></span><br><span class="line"><span class="type">Runnable</span> <span class="variable">task</span> <span class="operator">=</span> () -&gt; System.out.println(<span class="string">&quot;线程执行&quot;</span>);</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Thread</span>(task).start();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 3. 实现Callable + FutureTask（有返回值）</span></span><br><span class="line">Callable&lt;Integer&gt; callable = () -&gt; &#123;</span><br><span class="line">    Thread.sleep(<span class="number">1000</span>);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">100</span>;</span><br><span class="line">&#125;;</span><br><span class="line">FutureTask&lt;Integer&gt; future = <span class="keyword">new</span> <span class="title class_">FutureTask</span>&lt;&gt;(callable);</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Thread</span>(future).start();</span><br><span class="line"><span class="type">Integer</span> <span class="variable">result</span> <span class="operator">=</span> future.get();  <span class="comment">// 阻塞获取结果</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 4. 线程池（推荐）</span></span><br><span class="line"><span class="type">ExecutorService</span> <span class="variable">executor</span> <span class="operator">=</span> Executors.newFixedThreadPool(<span class="number">5</span>);</span><br><span class="line">executor.submit(() -&gt; System.out.println(<span class="string">&quot;线程执行&quot;</span>));</span><br><span class="line">executor.shutdown();</span><br></pre></td></tr></table></figure><h3 id="线程生命周期"><a class="markdownIt-Anchor" href="#线程生命周期"></a> 线程生命周期</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">新建（New）→ 就绪（Runnable）→ 运行（Running）→ 死亡（Dead）</span><br><span class="line">                  ↓                    ↓</span><br><span class="line">                阻塞（Blocked）←-------→</span><br></pre></td></tr></table></figure><ul><li><strong>新建</strong>：new Thread()后进入新建状态</li><li><strong>就绪</strong>：调用start()后进入就绪状态，等待CPU调度</li><li><strong>运行</strong>：获得CPU时间片，执行run()方法</li><li><strong>阻塞</strong>：sleep()、wait()、等待锁等进入阻塞状态</li><li><strong>死亡</strong>：run()执行完毕或异常退出</li></ul><h3 id="thread常用方法"><a class="markdownIt-Anchor" href="#thread常用方法"></a> Thread常用方法</h3><table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>sleep(long ms)</code></td><td>当前线程休眠指定毫秒，不释放锁</td></tr><tr><td><code>join()</code></td><td>等待该线程执行完毕</td></tr><tr><td><code>yield()</code></td><td>让出CPU时间片，回到就绪状态</td></tr><tr><td><code>interrupt()</code></td><td>中断线程</td></tr><tr><td><code>setPriority(int)</code></td><td>设置线程优先级（1-10）</td></tr><tr><td><code>isAlive()</code></td><td>判断线程是否存活</td></tr></tbody></table><h2 id="锁的分类大全"><a class="markdownIt-Anchor" href="#锁的分类大全"></a> 锁的分类大全</h2><h3 id="按乐观悲观分类"><a class="markdownIt-Anchor" href="#按乐观悲观分类"></a> 按乐观/悲观分类</h3><table><thead><tr><th>类型</th><th>说明</th><th>代表</th></tr></thead><tbody><tr><td>悲观锁</td><td>假设会发生冲突，每次访问都加锁</td><td>synchronized、ReentrantLock</td></tr><tr><td>乐观锁</td><td>假设不会冲突，更新时才检查</td><td>CAS、版本号机制</td></tr></tbody></table><h3 id="按独占共享分类"><a class="markdownIt-Anchor" href="#按独占共享分类"></a> 按独占/共享分类</h3><table><thead><tr><th>类型</th><th>说明</th><th>代表</th></tr></thead><tbody><tr><td>独占锁</td><td>一次只能被一个线程持有</td><td>synchronized、ReentrantLock</td></tr><tr><td>共享锁</td><td>可以被多个线程同时持有</td><td>ReadDownLatch、CountDownLatch、ReadWriteLock的读锁</td></tr></tbody></table><h3 id="按公平非公平分类"><a class="markdownIt-Anchor" href="#按公平非公平分类"></a> 按公平/非公平分类</h3><table><thead><tr><th>类型</th><th>说明</th><th>代表</th></tr></thead><tbody><tr><td>公平锁</td><td>按照线程请求顺序获取锁</td><td>ReentrantLock(true)</td></tr><tr><td>非公平锁</td><td>线程可以插队获取锁</td><td>synchronized、ReentrantLock(false)</td></tr></tbody></table><h3 id="按可重入不可重入分类"><a class="markdownIt-Anchor" href="#按可重入不可重入分类"></a> 按可重入/不可重入分类</h3><table><thead><tr><th>类型</th><th>说明</th><th>代表</th></tr></thead><tbody><tr><td>可重入锁</td><td>同一线程可以多次获取同一把锁</td><td>synchronized、ReentrantLock</td></tr><tr><td>不可重入锁</td><td>同一线程不能重复获取</td><td>自旋锁（部分实现）</td></tr></tbody></table><h3 id="按自旋阻塞分类"><a class="markdownIt-Anchor" href="#按自旋阻塞分类"></a> 按自旋/阻塞分类</h3><table><thead><tr><th>类型</th><th>说明</th><th>代表</th></tr></thead><tbody><tr><td>自旋锁</td><td>获取不到锁时循环重试</td><td>CAS、TicketLock</td></tr><tr><td>阻塞锁</td><td>获取不到锁时线程挂起</td><td>synchronized（重量级）、ReentrantLock</td></tr></tbody></table><h3 id="按偏向轻量重量分类synchronized升级"><a class="markdownIt-Anchor" href="#按偏向轻量重量分类synchronized升级"></a> 按偏向/轻量/重量分类（synchronized升级）</h3><table><thead><tr><th>锁状态</th><th>适用场景</th><th>实现方式</th></tr></thead><tbody><tr><td>偏向锁</td><td>单线程访问</td><td>在Mark Word中记录线程ID</td></tr><tr><td>轻量级锁</td><td>线程交替访问</td><td>CAS + Mark Word复制到栈帧</td></tr><tr><td>重量级锁</td><td>多线程同时竞争</td><td>Monitor监视器锁</td></tr></tbody></table><h2 id="锁机制详解"><a class="markdownIt-Anchor" href="#锁机制详解"></a> 锁机制详解</h2><h3 id="synchronized底层原理"><a class="markdownIt-Anchor" href="#synchronized底层原理"></a> synchronized底层原理</h3><p>synchronized基于<strong>Monitor监视器锁</strong>实现：</p><ul><li>每个对象都有一个关联的Monitor</li><li>进入同步块时，执行monitorenter指令，获取Monitor</li><li>退出同步块时，执行monitorexit指令，释放Monitor</li></ul><p><strong>对象头Mark Word结构</strong>（64位JVM）：</p><table><thead><tr><th>锁状态</th><th>Mark Word内容</th><th>标志位</th></tr></thead><tbody><tr><td>无锁</td><td>hashCode + 分代年龄</td><td>01</td></tr><tr><td>偏向锁</td><td>线程ID + epoch + 分代年龄</td><td>01</td></tr><tr><td>轻量级锁</td><td>指向栈中锁记录的指针</td><td>00</td></tr><tr><td>重量级锁</td><td>指向Monitor的指针</td><td>10</td></tr><tr><td>GC标记</td><td>空</td><td>11</td></tr></tbody></table><h3 id="锁升级过程"><a class="markdownIt-Anchor" href="#锁升级过程"></a> 锁升级过程</h3><p><strong>无锁 → 偏向锁 → 轻量级锁 → 重量级锁</strong>（只能升级不能降级）</p><ol><li><strong>偏向锁</strong>：只有一个线程访问时，在Mark Word中记录线程ID，下次同一线程访问时无需竞争</li><li><strong>轻量级锁</strong>：多个线程交替访问时，通过CAS将Mark Word复制到线程栈帧中</li><li><strong>重量级锁</strong>：多个线程同时访问时，膨胀为重量级锁，未获取锁的线程阻塞等待</li></ol><h3 id="volatile关键字"><a class="markdownIt-Anchor" href="#volatile关键字"></a> volatile关键字</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">volatile</span> <span class="type">boolean</span> <span class="variable">flag</span> <span class="operator">=</span> <span class="literal">true</span>;</span><br></pre></td></tr></table></figure><p><strong>特性</strong>：</p><ul><li><strong>可见性</strong>：一个线程修改后，其他线程立即可见</li><li><strong>有序性</strong>：禁止指令重排序</li><li><strong>不保证原子性</strong>：如i++不是原子操作</li></ul><p><strong>底层原理</strong>：通过内存屏障（Memory Barrier）实现，写操作后会刷新到主内存，读操作会从主内存读取</p><h3 id="cascompare-and-swap"><a class="markdownIt-Anchor" href="#cascompare-and-swap"></a> CAS（Compare And Swap）</h3><p>CAS是一种无锁的原子操作，包含三个操作数：</p><ul><li><strong>V</strong>：要更新的变量</li><li><strong>E</strong>：预期值</li><li><strong>N</strong>：新值</li></ul><p>只有V == E时，才将V更新为N，否则不更新。AtomicInteger等原子类底层使用CAS</p><p><strong>CAS问题</strong>：</p><ul><li><strong>ABA问题</strong>：值从A改为B再改回A，CAS会认为没变化。解决：使用AtomicStampedReference添加版本号</li><li><strong>自旋开销</strong>：竞争激烈时，CAS会一直自旋消耗CPU</li><li><strong>只能保证一个变量的原子操作</strong></li></ul><h3 id="lock接口"><a class="markdownIt-Anchor" href="#lock接口"></a> Lock接口</h3><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></pre></td><td class="code"><pre><span class="line"><span class="type">ReentrantLock</span> <span class="variable">lock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantLock</span>();</span><br><span class="line">lock.lock();</span><br><span class="line"><span class="keyword">try</span> &#123;</span><br><span class="line">    <span class="comment">// 业务逻辑</span></span><br><span class="line">&#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">    lock.unlock();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>ReentrantLock vs synchronized</strong>：</p><table><thead><tr><th>特性</th><th>synchronized</th><th>ReentrantLock</th></tr></thead><tbody><tr><td>加锁方式</td><td>自动获取释放</td><td>手动lock/unlock</td></tr><tr><td>公平性</td><td>非公平</td><td>可选公平/非公平</td></tr><tr><td>可中断</td><td>不可中断</td><td>可中断</td></tr><tr><td>条件变量</td><td>1个</td><td>多个Condition</td></tr><tr><td>底层实现</td><td>JVM层面</td><td>API层面（AQS）</td></tr></tbody></table><h3 id="读写锁readwritelock"><a class="markdownIt-Anchor" href="#读写锁readwritelock"></a> 读写锁（ReadWriteLock）</h3><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></pre></td><td class="code"><pre><span class="line"><span class="type">ReentrantReadWriteLock</span> <span class="variable">rwLock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantReadWriteLock</span>();</span><br><span class="line">rwLock.readLock().lock();     <span class="comment">// 读锁：多个线程可同时持有</span></span><br><span class="line">rwLock.writeLock().lock();    <span class="comment">// 写锁：独占锁</span></span><br></pre></td></tr></table></figure><p><strong>读写规则</strong>：</p><ul><li>读锁与读锁：兼容</li><li>读锁与写锁：互斥</li><li>写锁与写锁：互斥</li></ul><h2 id="线程池"><a class="markdownIt-Anchor" href="#线程池"></a> 线程池</h2><h3 id="核心参数"><a class="markdownIt-Anchor" href="#核心参数"></a> 核心参数</h3><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></pre></td><td class="code"><pre><span class="line"><span class="type">ThreadPoolExecutor</span> <span class="variable">pool</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ThreadPoolExecutor</span>(</span><br><span class="line">    corePoolSize,      <span class="comment">// 核心线程数</span></span><br><span class="line">    maximumPoolSize,   <span class="comment">// 最大线程数</span></span><br><span class="line">    keepAliveTime,     <span class="comment">// 空闲线程存活时间</span></span><br><span class="line">    TimeUnit.SECONDS,  <span class="comment">// 时间单位</span></span><br><span class="line">    workQueue,         <span class="comment">// 任务队列</span></span><br><span class="line">    threadFactory,     <span class="comment">// 线程工厂</span></span><br><span class="line">    handler            <span class="comment">// 拒绝策略</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="执行流程-2"><a class="markdownIt-Anchor" href="#执行流程-2"></a> 执行流程</h3><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></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><br><span class="line">                                             ↓ 否              ↓ 是</span><br><span class="line">                                        创建非核心线程    执行拒绝策略</span><br></pre></td></tr></table></figure><h3 id="常用线程池"><a class="markdownIt-Anchor" href="#常用线程池"></a> 常用线程池</h3><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></pre></td><td class="code"><pre><span class="line">Executors.newFixedThreadPool(n);      <span class="comment">// 固定线程数</span></span><br><span class="line">Executors.newSingleThreadExecutor();  <span class="comment">// 单线程</span></span><br><span class="line">Executors.newCachedThreadPool();      <span class="comment">// 缓存线程（按需创建）</span></span><br><span class="line">Executors.newScheduledThreadPool(n);  <span class="comment">// 定时线程池</span></span><br></pre></td></tr></table></figure><p><strong>注意</strong>：阿里规约建议使用ThreadPoolExecutor手动创建线程池，避免OOM</p><h3 id="拒绝策略"><a class="markdownIt-Anchor" href="#拒绝策略"></a> 拒绝策略</h3><table><thead><tr><th>策略</th><th>说明</th></tr></thead><tbody><tr><td>AbortPolicy</td><td>抛出异常（默认）</td></tr><tr><td>CallerRunsPolicy</td><td>由调用线程执行</td></tr><tr><td>DiscardPolicy</td><td>静默丢弃</td></tr><tr><td>DiscardOldestPolicy</td><td>丢弃队列中最老的任务</td></tr></tbody></table><h2 id="面试题精选"><a class="markdownIt-Anchor" href="#面试题精选"></a> 面试题精选</h2><h3 id="1-synchronized和lock的区别"><a class="markdownIt-Anchor" href="#1-synchronized和lock的区别"></a> 1. synchronized和Lock的区别？</h3><ul><li>synchronized是JVM层面的关键字，Lock是API层面的类</li><li>synchronized自动释放锁，Lock需要手动unlock（建议在finally中释放）</li><li>synchronized非公平锁，Lock可选公平/非公平</li><li>synchronized不可中断，Lock可中断</li><li>synchronized只有一个等待队列，Lock支持多个Condition</li><li>synchronized底层是Monitor，Lock底层是AQS</li></ul><h3 id="2-volatile的底层原理"><a class="markdownIt-Anchor" href="#2-volatile的底层原理"></a> 2. volatile的底层原理？</h3><p>volatile通过内存屏障实现：</p><ul><li>写操作后插入StoreStore和StoreLoad屏障，确保写操作对其他线程可见</li><li>读操作前插入LoadLoad和LoadStore屏障，确保读取最新值</li><li>禁止指令重排序</li></ul><h3 id="3-线程池参数怎么设置"><a class="markdownIt-Anchor" href="#3-线程池参数怎么设置"></a> 3. 线程池参数怎么设置？</h3><ul><li><strong>CPU密集型</strong>：核心线程数 = CPU核数 + 1</li><li><strong>IO密集型</strong>：核心线程数 = CPU核数 * 2 或 CPU核数 / (1 - 阻塞系数)</li><li><strong>混合型</strong>：根据任务类型调整，可通过压测确定</li></ul><h3 id="4-死锁的条件和避免"><a class="markdownIt-Anchor" href="#4-死锁的条件和避免"></a> 4. 死锁的条件和避免？</h3><p><strong>四个必要条件</strong>：</p><ul><li>互斥条件：资源一次只能被一个线程持有</li><li>持有并等待：线程持有资源并等待其他资源</li><li>不可剥夺：已获取的资源不能被强制剥夺</li><li>循环等待：线程之间形成资源的循环等待链</li></ul><p><strong>避免方法</strong>：</p><ul><li>固定加锁顺序</li><li>使用超时锁（tryLock）</li><li>避免嵌套锁</li><li>申请资源时一次性申请所有需要的资源</li></ul><h3 id="5-threadlocal原理"><a class="markdownIt-Anchor" href="#5-threadlocal原理"></a> 5. ThreadLocal原理？</h3><p>每个线程都有一个ThreadLocalMap，以ThreadLocal对象为key，存储线程的本地变量。ThreadLocal的get/set操作实际是对当前线程的ThreadLocalMap进行操作。</p><p><strong>内存泄漏问题</strong>：ThreadLocalMap的key是弱引用，value是强引用，GC后key为null但value还在。建议使用后调用remove()方法清理。</p><h3 id="6-aqs队列同步器原理"><a class="markdownIt-Anchor" href="#6-aqs队列同步器原理"></a> 6. AQS（队列同步器）原理？</h3><p>AQS是Lock的底层框架，维护一个state变量和一个CLH队列：</p><ul><li>state = 0表示锁空闲，state &gt; 0表示锁被占用</li><li>获取锁时，通过CAS修改state，失败则加入CLH队列排队</li><li>释放锁时，修改state并唤醒队列中的下一个线程</li></ul><p>ReentrantLock、ReentrantReadWriteLock、CountDownLatch等都基于AQS实现。</p>]]></content>
    
    
    <summary type="html">生当作人杰，死亦为鬼雄</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Nacos</title>
    <link href="https://luckynwa.top/posts/tool9/"/>
    <id>https://luckynwa.top/posts/tool9/</id>
    <published>2024-08-25T19:19:26.000Z</published>
    <updated>2026-07-07T16:19:34.210Z</updated>
    
    <content type="html"><![CDATA[<h1 id="启动配置"><a class="markdownIt-Anchor" href="#启动配置"></a> 启动配置</h1><p>Nacos 是 1.4.1 版本。</p><p>修改 <code>startup.cmd</code> 配置：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set MODE=&quot;standalone&quot;</span><br></pre></td></tr></table></figure><p>移动文件夹的不需要配置，直接打开 <code>D:\bgsoft\nacos\bin</code> 里的 <code>startup.cmd</code> 即可启动。</p><ul><li><strong>访问地址：</strong> <a href="http://localhost:8848/nacos/index.html">http://localhost:8848/nacos/index.html</a></li><li><strong>账号：</strong> <code>nacos</code></li><li><strong>密码：</strong> <code>nacos</code></li></ul><blockquote><p>⚠️ 2.2.0 以及之前都有漏洞，这个版本只适合单机。</p></blockquote>]]></content>
    
    
    <summary type="html">时人不识凌云木，直待凌云始道高</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Middleware" scheme="https://luckynwa.top/tags/Middleware/"/>
    
  </entry>
  
  <entry>
    <title>Java IO流详解</title>
    <link href="https://luckynwa.top/posts/java3/"/>
    <id>https://luckynwa.top/posts/java3/</id>
    <published>2024-08-14T18:37:39.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h1 id="概念"><a class="markdownIt-Anchor" href="#概念"></a> 概念</h1><p>IO 流：按照流动的方向，以内存为基准，分为输入 input 和输出 output，即流向内存是输入流，流出内存是输出流</p><p>进行IO操作前需要明确四个关键点：</p><ol><li>明确要操作的数据是数据源还是数据目的（读还是写）</li><li>明确要操作的设备上的数据是字节还是文本</li><li>明确数据所在的具体设备</li><li>明确是否需要额外功能（转换流、高效流等）</li></ol><p>输入流（读数据）、输出流（写数据）</p><h2 id="分类"><a class="markdownIt-Anchor" href="#分类"></a> 分类</h2><table><thead><tr><th>类型</th><th>输入流</th><th>输出流</th></tr></thead><tbody><tr><td>字节流</td><td>InputStream</td><td>OutputStream</td></tr><tr><td>字符流</td><td>Reader</td><td>Writer</td></tr></tbody></table><p>字符流的由来：因为数据编码的不同，字节流直接读中文会乱码。字符流 = 字节流 + 编码表</p><p>1 个字符 = 2 个字节</p><ul><li>字节流适合读取视频、音乐、图片等二进制文件</li><li>字符流适合读取纯文本文件</li></ul><h1 id="file-类"><a class="markdownIt-Anchor" href="#file-类"></a> File 类</h1><p>java.io.File 类是专门对文件进行操作的类，只能对文件本身进行操作，不能对文件进行读和写（输入和输出）</p><p>File 类构造方法不会检验文件或文件夹是否真实存在，无论该路径下是否存在文件或目录，都不影响 File 对象的创建。</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/10 -10:34</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FileDemo</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">// 就算文件1.txt不存在也不影响file对象的创建</span></span><br><span class="line">        <span class="type">File</span> <span class="variable">f</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;C:\\Users\\FF\\Desktop\\1.txt&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (!f.exists()) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;是否创建:&quot;</span> + f.createNewFile()); <span class="comment">// true 如果没有文件则创建并返回true</span></span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;是否创建:&quot;</span> + f.createNewFile());  <span class="comment">// 已经存在，所以就false了</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件绝对路径:&quot;</span> + f.getAbsolutePath());</span><br><span class="line">        System.out.println(<span class="string">&quot;文件构造路径:&quot;</span> + f.getPath());</span><br><span class="line">        System.out.println(<span class="string">&quot;文件名称:&quot;</span> + f.getName());</span><br><span class="line">        System.out.println(<span class="string">&quot;文件长度:&quot;</span> + f.length() + <span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;文件:&quot;</span> + f.isFile());</span><br><span class="line">        System.out.println(<span class="string">&quot;目录:&quot;</span> + f.isDirectory());</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">public</span> <span class="keyword">void</span> <span class="title function_">testDemo2</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 目录的创建（使用相对路径）</span></span><br><span class="line">        <span class="type">File</span> <span class="variable">f2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;是否存在:&quot;</span> + f2.exists());  <span class="comment">// false</span></span><br><span class="line">        System.out.println(<span class="string">&quot;是否创建:&quot;</span> + f2.mkdir());    <span class="comment">// true</span></span><br><span class="line">        System.out.println(<span class="string">&quot;是否存在:&quot;</span> + f2.exists());  <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 创建多级目录</span></span><br><span class="line">        <span class="type">File</span> <span class="variable">f3</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira\\newDirb&quot;</span>);</span><br><span class="line">        System.out.println(f3.mkdir());     <span class="comment">// false，mkdir只能创建单层目录</span></span><br><span class="line">        System.out.println(f3.mkdirs());    <span class="comment">// true，mkdirs可以创建多级目录</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 删除：目录必须为空才能删除</span></span><br><span class="line">        System.out.println(f2.delete());    <span class="comment">// false，目录不为空</span></span><br><span class="line">        System.out.println(f3.delete());    <span class="comment">// true，删除最底层目录</span></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">public</span> <span class="keyword">void</span> <span class="title function_">demo3</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\other\\study\\学习sp\\实用篇&quot;</span>);</span><br><span class="line">        printFile(file);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 递归遍历目录下所有文件</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">printFile</span><span class="params">(File file)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (!file.isDirectory()) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        File[] files = file.listFiles();</span><br><span class="line">        <span class="keyword">for</span> (File f : files) &#123;</span><br><span class="line">            <span class="keyword">if</span> (f.isDirectory()) &#123;</span><br><span class="line">                printFile(f);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(f.getName());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="io-流详解"><a class="markdownIt-Anchor" href="#io-流详解"></a> IO 流详解</h1><p>数据流向内存就是输入流，流出内存就是输出流</p><h2 id="fileoutputstream"><a class="markdownIt-Anchor" href="#fileoutputstream"></a> FileOutputStream</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">FileOutputStream</span> <span class="variable">outputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;abc.txt&quot;</span>);</span><br></pre></td></tr></table></figure><p>创建输出流对象时做了三件事：</p><ol><li>调用系统功能去创建文件（输出流对象才会自动创建）</li><li>创建 outputStream 对象</li><li>把 outputStream 对象指向这个文件</li></ol><p>注意事项：</p><ul><li>创建输出流对象时，如果没有这个文件，会创建该文件</li><li>如果有这个文件，会清空这个文件的数据</li><li>创建输入流对象时，文件不存在则会抛出 FileNotFoundException</li></ul><p>追加数据构造方法：</p><ul><li><code>public FileOutputStream(File file, boolean append)</code></li><li><code>public FileOutputStream(String name, boolean append)</code> — true 表示追加数据</li></ul><p>换行符说明：</p><ul><li>Windows 系统：回车+换行 <code>\r\n</code></li><li>Unix 系统：换行 <code>\n</code></li><li>Mac 系统（OS X 起）：换行 <code>\n</code></li></ul><h2 id="fileinputstream"><a class="markdownIt-Anchor" href="#fileinputstream"></a> FileInputStream</h2><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="comment">// 逐字节读取</span></span><br><span class="line"><span class="type">int</span> b;</span><br><span class="line"><span class="keyword">while</span> ((b = fis.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">    System.out.print((<span class="type">char</span>) b);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用字节数组读取（效率更高）</span></span><br><span class="line"><span class="type">int</span> len;</span><br><span class="line"><span class="type">byte</span>[] bys = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="keyword">while</span> ((len = fis.read(bys)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(bys, <span class="number">0</span>, len));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="filewriter"><a class="markdownIt-Anchor" href="#filewriter"></a> FileWriter</h2><p>写出字符到文件的便利类（输出流）</p><p>关闭 close 和刷新 flush 的区别：</p><ul><li>flush：刷新缓冲区，流对象可以继续使用</li><li>close：先刷新缓冲区，然后通知系统释放资源，流对象不可再使用</li></ul><p>如果不关闭输出流，数据只是保存到缓冲区，并未保存到文件。</p><h2 id="缓冲流"><a class="markdownIt-Anchor" href="#缓冲流"></a> 缓冲流</h2><p>缓冲流原理：</p><ol><li>使用底层流对象从具体设备上获取数据，存储到缓冲区数组内</li><li>通过缓冲区的 read() 方法获取具体字符数据，提高效率</li><li>readLine() 功能：读取到换行符时，将临时存储的数据转成字符串返回</li></ol><p>在创建流对象时，会创建一个内置的默认大小的缓冲区数组，通过缓冲区读写，减少系统 IO 次数，从而提高读写效率。</p><table><thead><tr><th>类型</th><th>输入流</th><th>输出流</th></tr></thead><tbody><tr><td>字节缓冲流</td><td>BufferedInputStream</td><td>BufferedOutputStream</td></tr><tr><td>字符缓冲流</td><td>BufferedReader</td><td>BufferedWriter</td></tr></tbody></table><p>BufferedReader 特有方法：</p><ul><li><code>public String readLine()</code> — 读一行数据，读取到最后返回 null</li></ul><p>BufferedWriter 特有方法：</p><ul><li><code>public void newLine()</code> — 换行，由系统属性定义符号</li></ul><h2 id="转换流"><a class="markdownIt-Anchor" href="#转换流"></a> 转换流</h2><p>编码与解码：</p><ul><li>编码：字符（能看懂的）→ 字节（看不懂的）<code>String → byte[]</code></li><li>解码：字节（看不懂的）→ 字符（能看懂的）<code>byte[] → String</code></li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 通过指定的字符集解码字节数组</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">String</span>(<span class="type">byte</span>[] bytes, String charsetName)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用指定的字符集合把字符串编码为字节数组</span></span><br><span class="line"><span class="type">byte</span>[] getBytes(String charsetName)</span><br></pre></td></tr></table></figure><p>转换流 java.io.InputStreamReader 是 Reader 的子类，从字节流到字符流的桥梁。它读取字节，并使用指定的字符集将其解码为字符。</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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用默认字符集</span></span><br><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;in.txt&quot;</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指定GBK编码</span></span><br><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;in.txt&quot;</span>), <span class="string">&quot;GBK&quot;</span>);</span><br></pre></td></tr></table></figure><h1 id="实战案例"><a class="markdownIt-Anchor" href="#实战案例"></a> 实战案例</h1><h2 id="字节流写入"><a class="markdownIt-Anchor" href="#字节流写入"></a> 字节流写入</h2><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="comment">// 写出字节</span></span><br><span class="line"><span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;a.txt&quot;</span>, <span class="literal">true</span>); <span class="comment">// true追加数据</span></span><br><span class="line">fos.write(<span class="number">97</span>);                        <span class="comment">// 写出单个字节，97对应&#x27;a&#x27;</span></span><br><span class="line">fos.write(<span class="string">&quot;我要吃汉堡&quot;</span>.getBytes());    <span class="comment">// 写出字节数组</span></span><br><span class="line">fos.close();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 写出指定长度字节数组</span></span><br><span class="line"><span class="type">FileOutputStream</span> <span class="variable">fos2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;a2.txt&quot;</span>);</span><br><span class="line"><span class="type">byte</span>[] b = <span class="string">&quot;abcde&quot;</span>.getBytes();</span><br><span class="line">fos2.write(b, <span class="number">2</span>, <span class="number">2</span>);  <span class="comment">// 从索引2开始，写出2个字节，即&quot;cd&quot;</span></span><br><span class="line">fos2.close();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 写出字节数组并换行</span></span><br><span class="line"><span class="type">FileOutputStream</span> <span class="variable">fos3</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;fos.txt&quot;</span>);</span><br><span class="line"><span class="type">byte</span>[] words = &#123;<span class="number">97</span>, <span class="number">98</span>, <span class="number">99</span>, <span class="number">100</span>, <span class="number">101</span>&#125;;</span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; words.length; i++) &#123;</span><br><span class="line">    fos3.write(words[i]);</span><br><span class="line">    fos3.write(<span class="string">&quot;\r\n&quot;</span>.getBytes());</span><br><span class="line">&#125;</span><br><span class="line">fos3.close();</span><br></pre></td></tr></table></figure><h2 id="图片复制"><a class="markdownIt-Anchor" href="#图片复制"></a> 图片复制</h2><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></pre></td><td class="code"><pre><span class="line"><span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;C:\\Users\\FF\\Desktop\\6.png&quot;</span>);</span><br><span class="line"><span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;1.png&quot;</span>);</span><br><span class="line"><span class="type">byte</span>[] b = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="type">int</span> len;</span><br><span class="line"><span class="keyword">while</span> ((len = fis.read(b)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    fos.write(b, <span class="number">0</span>, len);</span><br><span class="line">&#125;</span><br><span class="line">fos.close();</span><br><span class="line">fis.close();</span><br></pre></td></tr></table></figure><h2 id="字符流复制文本"><a class="markdownIt-Anchor" href="#字符流复制文本"></a> 字符流复制文本</h2><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></pre></td><td class="code"><pre><span class="line"><span class="type">FileWriter</span> <span class="variable">fileWriter</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileWriter</span>(<span class="string">&quot;66.md&quot;</span>);</span><br><span class="line"><span class="type">FileReader</span> <span class="variable">fileReader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;E:\\后端代码接收解析.md&quot;</span>);</span><br><span class="line"><span class="type">char</span>[] c = <span class="keyword">new</span> <span class="title class_">char</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="type">int</span> len;</span><br><span class="line"><span class="keyword">while</span> ((len = fileReader.read(c)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    fileWriter.write(c, <span class="number">0</span>, len);</span><br><span class="line">&#125;</span><br><span class="line">fileWriter.flush();</span><br><span class="line">fileWriter.close();</span><br><span class="line">fileReader.close();</span><br></pre></td></tr></table></figure><h2 id="缓冲流效率对比"><a class="markdownIt-Anchor" href="#缓冲流效率对比"></a> 缓冲流效率对比</h2><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="comment">// 普通流复制（约33000毫秒）</span></span><br><span class="line"><span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;ps2015.zip&quot;</span>);</span><br><span class="line"><span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;E:\\other\\装机必备软件\\必备软件\\ps2015.zip&quot;</span>);</span><br><span class="line"><span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="type">int</span> len;</span><br><span class="line"><span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    fos.write(bytes, <span class="number">0</span>, len);</span><br><span class="line">&#125;</span><br><span class="line">fis.close();</span><br><span class="line">fos.close();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 缓冲流复制（约4314毫秒）</span></span><br><span class="line"><span class="type">BufferedOutputStream</span> <span class="variable">bos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedOutputStream</span>(<span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;ps2015.zip&quot;</span>));</span><br><span class="line"><span class="type">BufferedInputStream</span> <span class="variable">bis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedInputStream</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;E:\\other\\装机必备软件\\必备软件\\ps2015.zip&quot;</span>));</span><br><span class="line"><span class="type">byte</span>[] bytes2 = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="type">int</span> len2;</span><br><span class="line"><span class="keyword">while</span> ((len2 = bis.read(bytes2)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    bos.write(bytes2, <span class="number">0</span>, len2);</span><br><span class="line">&#125;</span><br><span class="line">bis.close();</span><br><span class="line">bos.close();</span><br></pre></td></tr></table></figure><h2 id="bufferedreader-读取一行"><a class="markdownIt-Anchor" href="#bufferedreader-读取一行"></a> BufferedReader 读取一行</h2><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="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;b.txt&quot;</span>));</span><br><span class="line">String len;</span><br><span class="line"><span class="keyword">while</span> ((len = br.readLine()) != <span class="literal">null</span>) &#123;</span><br><span class="line">    System.out.println(len);</span><br><span class="line">&#125;</span><br><span class="line">br.close();</span><br></pre></td></tr></table></figure><h2 id="转换流解决乱码"><a class="markdownIt-Anchor" href="#转换流解决乱码"></a> 转换流解决乱码</h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 文件为GBK编码，使用UTF-8读取会乱码</span></span><br><span class="line"><span class="type">String</span> <span class="variable">fileName</span> <span class="operator">=</span> <span class="string">&quot;C:\\Users\\FF\\Desktop\\1.txt&quot;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 默认UTF8编码读取（乱码）</span></span><br><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(fileName));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 指定GBK编码读取（正常）</span></span><br><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(fileName), <span class="string">&quot;GBK&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> read;</span><br><span class="line"><span class="keyword">while</span> ((read = isr2.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">    System.out.print((<span class="type">char</span>) read);</span><br><span class="line">&#125;</span><br><span class="line">isr2.close();</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">知己知彼，百战不殆</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Python基础知识与进阶实战</title>
    <link href="https://luckynwa.top/posts/ai3/"/>
    <id>https://luckynwa.top/posts/ai3/</id>
    <published>2024-06-14T18:25:34.000Z</published>
    <updated>2026-07-07T16:19:34.146Z</updated>
    
    <content type="html"><![CDATA[<h1 id="基础语法"><a class="markdownIt-Anchor" href="#基础语法"></a> 基础语法</h1><h2 id="标识符"><a class="markdownIt-Anchor" href="#标识符"></a> 标识符</h2><ul><li>第一个字符必须是字母表中字母或下划线 <strong>_</strong> 。</li><li>标识符的其他的部分由字母、数字和下划线组成。</li><li>标识符对大小写敏感。</li><li>Python3 版本支持中文作为标识符</li></ul><figure class="highlight python"><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="keyword">import</span> keyword</span><br><span class="line"><span class="built_in">print</span>(keyword.kwlist)</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[&#x27;False&#x27;, &#x27;None&#x27;, &#x27;True&#x27;, &#x27;and&#x27;, &#x27;as&#x27;, &#x27;assert&#x27;, &#x27;async&#x27;, &#x27;await&#x27;, &#x27;break&#x27;, &#x27;class&#x27;, &#x27;continue&#x27;, &#x27;def&#x27;, &#x27;del&#x27;, &#x27;elif&#x27;, &#x27;else&#x27;, &#x27;except&#x27;, &#x27;finally&#x27;, &#x27;for&#x27;, &#x27;from&#x27;, &#x27;global&#x27;, &#x27;if&#x27;, &#x27;import&#x27;, &#x27;in&#x27;, &#x27;is&#x27;, &#x27;lambda&#x27;, &#x27;nonlocal&#x27;, &#x27;not&#x27;, &#x27;or&#x27;, &#x27;pass&#x27;, &#x27;raise&#x27;, &#x27;return&#x27;, &#x27;try&#x27;, &#x27;while&#x27;, &#x27;with&#x27;, &#x27;yield&#x27;]</span><br></pre></td></tr></table></figure><p>Python 自带的标识符（变量），变量不需要声明类型，可以同时为多个变量赋值：<code>a, b = 1, 2</code>，也可以 <code>a = b = c = 1</code> 同时赋值。</p><h2 id="标准数据类型"><a class="markdownIt-Anchor" href="#标准数据类型"></a> 标准数据类型</h2><p>Python3 中常见的数据类型有：</p><ul><li><p><strong>Number（数字类型）</strong> int、float、bool、complex（复数）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">a, b, c, d = <span class="number">20</span>, <span class="number">5.5</span>, <span class="literal">True</span>, <span class="number">4</span>+<span class="number">3j</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(a), <span class="built_in">type</span>(b), <span class="built_in">type</span>(c), <span class="built_in">type</span>(d))</span><br><span class="line"><span class="built_in">isinstance</span>(a, <span class="built_in">int</span>)</span><br></pre></td></tr></table></figure></li><li><p><strong>String（字符串）</strong></p></li><li><p><strong>bool（布尔类型）</strong></p><p><code>True == 1</code>、<code>False == 0</code> 会返回 <code>True</code></p></li><li><p><strong>List（列表）</strong></p></li><li><p><strong>Tuple（元组）</strong></p></li><li><p><strong>Set（集合）</strong></p></li><li><p><strong>Dictionary（字典）</strong></p></li></ul><p>Python3 的六个标准数据类型中：</p><ul><li><strong>不可变数据（3个）：</strong> Number（数字）、String（字符串）、Tuple（元组）</li><li><strong>可变数据（3个）：</strong> List（列表）、Dictionary（字典）、Set（集合）</li></ul><p>此外还有高级数据类型，如字节数组类型 <code>bytes</code>。</p><h2 id="运算符"><a class="markdownIt-Anchor" href="#运算符"></a> 运算符</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">5</span> + <span class="number">4</span>  <span class="comment"># 加法</span></span><br><span class="line"><span class="number">9</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">4.3</span> - <span class="number">2</span>  <span class="comment"># 减法</span></span><br><span class="line"><span class="number">2.3</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">3</span> * <span class="number">7</span>  <span class="comment"># 乘法 优先级2</span></span><br><span class="line"><span class="number">21</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">2</span> / <span class="number">4</span>  <span class="comment"># 除法，得到一个浮点数 优先级3</span></span><br><span class="line"><span class="number">0.5</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">2</span> // <span class="number">4</span>  <span class="comment"># 除法，得到一个整数 优先级4</span></span><br><span class="line"><span class="number">0</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">17</span> % <span class="number">3</span>  <span class="comment"># 取余</span></span><br><span class="line"><span class="number">2</span></span><br><span class="line"><span class="meta">&gt;&gt;&gt; </span><span class="number">2</span> ** <span class="number">5</span>  <span class="comment"># 乘方 优先级1</span></span><br><span class="line"><span class="number">32</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">X = <span class="built_in">int</span>(<span class="built_in">input</span>(<span class="string">&quot;输入X值:&quot;</span>))</span><br><span class="line">Y = <span class="built_in">int</span>(<span class="built_in">input</span>(<span class="string">&quot;输入Y值:&quot;</span>))  <span class="comment"># 记得转换，默认字符串相加</span></span><br><span class="line"><span class="built_in">print</span>(X + Y)</span><br></pre></td></tr></table></figure><blockquote><p>float 类型会有精度损失，计算机底层基于二进制，二进制无法准确表示所有小数，因此涉及浮点数运算会损失精度。</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ==  !=  &gt;  &lt;  &gt;=            比较运算符</span></span><br><span class="line"><span class="comment"># +=  num += 2 等效于 num = num + 2</span></span><br><span class="line"><span class="comment"># -=</span></span><br><span class="line"><span class="comment"># and  or  not 取反           逻辑运算符</span></span><br><span class="line"><span class="comment"># in                          包括字符串，列表或元组</span></span><br><span class="line"><span class="comment"># not in</span></span><br><span class="line"><span class="comment"># is                          查看是否引用同一对象</span></span><br><span class="line"><span class="comment"># is not</span></span><br></pre></td></tr></table></figure><h2 id="注释"><a class="markdownIt-Anchor" href="#注释"></a> 注释</h2><ul><li>单行注释以 <strong>#</strong> 开头</li><li>多行注释可以用多个 <strong>#</strong> 号，还有 <strong>‘’’</strong> 和 <strong>“”&quot;</strong></li></ul><h2 id="行与缩进"><a class="markdownIt-Anchor" href="#行与缩进"></a> 行与缩进</h2><p>Python 最具特色的就是使用缩进来表示代码块，不需要使用大括号 <code>&#123;&#125;</code>。</p><p>如果语句很长，可以使用反斜杠 <code>\</code> 来实现多行语句。在 <code>[]</code>、<code>&#123;&#125;</code>、<code>()</code> 中的多行语句，不需要使用反斜杠。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">total = item_one + \</span><br><span class="line">        item_two + \</span><br><span class="line">        item_three</span><br><span class="line"></span><br><span class="line">total = [<span class="string">&#x27;item_one&#x27;</span>, <span class="string">&#x27;item_two&#x27;</span>, <span class="string">&#x27;item_three&#x27;</span>,</span><br><span class="line">        <span class="string">&#x27;item_four&#x27;</span>, <span class="string">&#x27;item_five&#x27;</span>]</span><br></pre></td></tr></table></figure><h2 id="字符串"><a class="markdownIt-Anchor" href="#字符串"></a> 字符串</h2><p>不可修改，有序性，可迭代性。</p><p>字符串截取的语法格式：</p><figure class="highlight plaintext"><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>从0开始，左闭右开。转义符 <code>\</code>。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">str</span> = <span class="string">&#x27;123456789&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>)                 <span class="comment"># 输出字符串</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[<span class="number">0</span>:-<span class="number">1</span>])           <span class="comment"># 输出第一个到倒数第二个的所有字符</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[<span class="number">0</span>])              <span class="comment"># 输出字符串第一个字符</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[<span class="number">2</span>:<span class="number">5</span>])            <span class="comment"># 输出从第三个开始到第六个的字符（不包含）</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[<span class="number">2</span>:])             <span class="comment"># 输出从第三个开始后的所有字符</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[<span class="number">1</span>:<span class="number">5</span>:<span class="number">2</span>])          <span class="comment"># 输出从第二个开始到第五个且每隔一个的字符（步长为2）</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span> * <span class="number">2</span>)             <span class="comment"># 输出字符串两次</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span> + <span class="string">&#x27;你好&#x27;</span>)         <span class="comment"># 连接字符串</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">str</span>[-<span class="number">1</span>:-<span class="number">7</span>:-<span class="number">1</span>])       <span class="comment"># 987654 反转</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;hello\nrunoob&#x27;</span>)     <span class="comment"># 使用反斜杠(\)+n转义特殊字符</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">r&#x27;hello\nrunoob&#x27;</span>)    <span class="comment"># 在字符串前面添加一个r，表示原始字符串，不会发生转义</span></span><br></pre></td></tr></table></figure><p>字符串格式化 <code>%f</code> 浮点数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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">name = <span class="string">&#x27;小米&#x27;</span></span><br><span class="line">age = <span class="number">10</span></span><br><span class="line">num = <span class="number">11.2356</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;my name is&quot;</span> + name + <span class="string">&quot;age=&gt;&quot;</span>, <span class="built_in">str</span>(age))  <span class="comment"># 这里相加需要转str类型</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;我叫%s今年%d岁!&quot;</span> % (name, age))</span><br><span class="line"></span><br><span class="line">name = <span class="built_in">input</span>(<span class="string">&quot;请输入名称&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;我叫<span class="subst">&#123;name&#125;</span>&quot;</span>)  <span class="comment"># 推荐这种写法</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&quot;分数：<span class="subst">&#123;num:<span class="number">.1</span>f&#125;</span>&quot;</span>)  <span class="comment"># 保留一位小数</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">round</span>(num, <span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;网站名：&#123;name&#125;, 地址 &#123;url&#125;&quot;</span>.<span class="built_in">format</span>(name=<span class="string">&quot;菜鸟教程&quot;</span>, url=<span class="string">&quot;www.runoob.com&quot;</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过字典设置参数</span></span><br><span class="line">site = &#123;<span class="string">&quot;name&quot;</span>: <span class="string">&quot;菜鸟教程&quot;</span>, <span class="string">&quot;url&quot;</span>: <span class="string">&quot;www.runoob.com&quot;</span>&#125;</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;网站名：&#123;name&#125;, 地址 &#123;url&#125;&quot;</span>.<span class="built_in">format</span>(**site))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 通过列表索引设置参数</span></span><br><span class="line">my_list = [<span class="string">&#x27;菜鸟教程&#x27;</span>, <span class="string">&#x27;www.runoob.com&#x27;</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;网站名：&#123;0[0]&#125;, 地址 &#123;0[1]&#125;&quot;</span>.<span class="built_in">format</span>(my_list))  <span class="comment"># &quot;0&quot; 是必须的</span></span><br></pre></td></tr></table></figure><p>数字格式化 <code>&#123;:.0f&#125;</code> 不带小数，<code>&#123;:.2%&#125;</code> 百分比格式：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="string">&quot;&#123;:.2f&#125;&quot;</span>.<span class="built_in">format</span>(<span class="number">3.1415926</span>))</span><br></pre></td></tr></table></figure><p>字符串内建函数（参考 <a href="https://www.runoob.com/python/python-strings.html">https://www.runoob.com/python/python-strings.html</a> ）：</p><table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>find()</code></td><td>传入查找的子字符串，返回第一次出现的索引位置，找不到返回-1</td></tr><tr><td><code>count()</code></td><td>统计子字符串在字符串中出现的次数并返回</td></tr><tr><td><code>upper()</code></td><td>字符串全转大写</td></tr><tr><td><code>lower()</code></td><td>字符串全转小写</td></tr><tr><td><code>split()</code></td><td>将字符串按指定分隔符分割成列表</td></tr><tr><td><code>strip()</code></td><td>去除字符串两端的空字符串或指定字符</td></tr><tr><td><code>replace()</code></td><td>将指定的字串转新的</td></tr><tr><td><code>startswith()</code></td><td>检查是否以这个参数开头，并返回布尔值</td></tr></tbody></table><h2 id="条件语句"><a class="markdownIt-Anchor" href="#条件语句"></a> 条件语句</h2><p>任何非0和非空（null）值为 true，0 或者 null 为 false。</p><p>if 语句的判断条件可以用 <code>&gt;</code>、<code>&lt;</code>、<code>==</code>、<code>&gt;=</code>、<code>&lt;=</code> 来表示其关系。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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 class="keyword">if</span> 判断条件:</span><br><span class="line">    执行语句</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    执行语句</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> 判断条件<span class="number">1</span>:</span><br><span class="line">    执行语句<span class="number">1</span></span><br><span class="line"><span class="keyword">elif</span> 判断条件<span class="number">2</span>:</span><br><span class="line">    执行语句<span class="number">2</span></span><br><span class="line"><span class="keyword">elif</span> 判断条件<span class="number">3</span>:</span><br><span class="line">    执行语句<span class="number">3</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    执行语句<span class="number">4</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># match-case（Python 3.10+）</span></span><br><span class="line">day = <span class="built_in">int</span>(<span class="built_in">input</span>(<span class="string">&quot;请输入天数:&quot;</span>))</span><br><span class="line"><span class="keyword">match</span> day:</span><br><span class="line">    <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期一&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期二&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">3</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期三&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">4</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期四&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">5</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期五&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">6</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期六&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="number">7</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;是星期日&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> _:  <span class="comment"># 匹配其他情况</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;输入错误&quot;</span>)</span><br></pre></td></tr></table></figure><h2 id="循环语句"><a class="markdownIt-Anchor" href="#循环语句"></a> 循环语句</h2><h3 id="while-循环"><a class="markdownIt-Anchor" href="#while-循环"></a> while 循环</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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 class="keyword">while</span> 判断条件:</span><br><span class="line">    执行语句</span><br><span class="line"></span><br><span class="line">count = <span class="number">0</span></span><br><span class="line"><span class="keyword">while</span> count &lt; <span class="number">5</span>:</span><br><span class="line">    <span class="built_in">print</span>(count, <span class="string">&quot; is less than 5&quot;</span>)</span><br><span class="line">    count = count + <span class="number">1</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(count, <span class="string">&quot; is not less than 5&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 计算1到100之间偶数的累加和</span></span><br><span class="line"><span class="built_in">sum</span> = <span class="number">0</span></span><br><span class="line">i = <span class="number">1</span></span><br><span class="line"><span class="keyword">while</span> i &lt;= <span class="number">100</span>:</span><br><span class="line">    <span class="keyword">if</span> i % <span class="number">2</span> == <span class="number">0</span>:</span><br><span class="line">        <span class="built_in">sum</span> += i</span><br><span class="line">    i += <span class="number">1</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;1到100之间偶数的累加和为:&quot;</span>, <span class="built_in">sum</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 猜数字游戏</span></span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line">rand_num = random.randint(<span class="number">1</span>, <span class="number">10</span>)  <span class="comment"># 生成1-10之间的随机整数，包含10</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">    num = <span class="built_in">int</span>(<span class="built_in">input</span>(<span class="string">&#x27;请输入你猜的数字:&#x27;</span>))</span><br><span class="line">    <span class="keyword">if</span> num &gt; rand_num:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;太大了，重新输入&#x27;</span>)</span><br><span class="line">    <span class="keyword">elif</span> num &lt; rand_num:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;太小了，重新输入&#x27;</span>)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;恭喜你猜对了&#x27;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;游戏结束,随机值是:&#x27;</span>, rand_num)</span><br><span class="line">        <span class="keyword">break</span></span><br></pre></td></tr></table></figure><h3 id="for-循环"><a class="markdownIt-Anchor" href="#for-循环"></a> for 循环</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># range 用法</span></span><br><span class="line"><span class="built_in">range</span>(end)            <span class="comment"># 获取从0开始，不含end本身</span></span><br><span class="line"><span class="built_in">range</span>(start, end)     <span class="comment"># 从start开始，不含end</span></span><br><span class="line"><span class="built_in">range</span>(start, end, step)</span><br><span class="line"><span class="built_in">range</span>(<span class="number">0</span>, <span class="number">10</span>, <span class="number">2</span>)       <span class="comment"># 0,2,4,6,8</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 计算1到100之间偶数的累加和</span></span><br><span class="line"><span class="built_in">sum</span> = <span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2</span>, <span class="number">101</span>, <span class="number">2</span>):</span><br><span class="line">    <span class="built_in">sum</span> += i</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;1到100之间偶数的累加和为:&quot;</span>, <span class="built_in">sum</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 遍历字符串和列表</span></span><br><span class="line"><span class="keyword">for</span> letter <span class="keyword">in</span> <span class="string">&#x27;Python&#x27;</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;当前字母: %s&quot;</span> % letter)</span><br><span class="line"></span><br><span class="line">fruits = [<span class="string">&#x27;apple&#x27;</span>, <span class="string">&#x27;banana&#x27;</span>, <span class="string">&#x27;orange&#x27;</span>, <span class="string">&#x27;peach&#x27;</span>]</span><br><span class="line"><span class="keyword">for</span> fruit <span class="keyword">in</span> fruits:</span><br><span class="line">    <span class="built_in">print</span>(fruit)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;-----------------&#x27;</span>)</span><br><span class="line"><span class="keyword">for</span> index <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(fruits)):</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;当前水果: %s&#x27;</span> % fruits[index])</span><br><span class="line"></span><br><span class="line"><span class="comment"># 嵌套循环 - 打印矩形</span></span><br><span class="line">w = <span class="number">10</span>; h = <span class="number">5</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(h):</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(w):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;*&#x27;</span>, end=<span class="string">&#x27;&#x27;</span>)  <span class="comment"># end=&#x27;&#x27;表示不换行</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 九九乘法表</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">10</span>):</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, i + <span class="number">1</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;%d*%d=%d &#x27;</span> % (i, j, i * j), end=<span class="string">&#x27;\t&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;&#x27;</span>)</span><br></pre></td></tr></table></figure><ul><li><code>break</code> — 跳出整个循环</li><li><code>continue</code> — 结束当前循环，继续下一个循环</li><li><code>return</code> — 从函数返回</li></ul><h2 id="list列表"><a class="markdownIt-Anchor" href="#list列表"></a> List（列表）</h2><p>列表是写在方括号 <code>[]</code> 之间、用逗号分隔开的元素列表，可以重复、可以修改、有序。列表截取语法同字符串。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span> = [<span class="string">&#x27;abcd&#x27;</span>, <span class="number">786</span>, <span class="number">2.23</span>, <span class="string">&#x27;runoob&#x27;</span>, <span class="number">70.2</span>]  <span class="comment"># 定义一个列表</span></span><br><span class="line">tinylist = [<span class="number">123</span>, <span class="string">&#x27;runoob&#x27;</span>]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>)            <span class="comment"># 打印整个列表</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>[<span class="number">0</span>])         <span class="comment"># 打印列表的第一个元素</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>[<span class="number">1</span>:<span class="number">3</span>])       <span class="comment"># 打印列表第二到第四个元素（不包含第四个元素）</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>[<span class="number">1</span>:<span class="number">4</span>:<span class="number">2</span>])     <span class="comment"># 打印列表第二到第五个元素间隔1个位置</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>[<span class="number">2</span>:])        <span class="comment"># 打印列表从第三个元素开始到末尾</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span>[<span class="number">0</span>:<span class="number">4</span>:<span class="number">1</span>])     <span class="comment"># 等价于 list[:4:1]  list[:4:]  list[:4]</span></span><br><span class="line"><span class="built_in">print</span>(tinylist * <span class="number">2</span>)    <span class="comment"># 打印tinylist列表两次</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">list</span> + tinylist)  <span class="comment"># 打印两个列表拼接在一起的结果</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">list</span> = []                    <span class="comment"># 空列表</span></span><br><span class="line"><span class="built_in">list</span>.append(<span class="string">&#x27;Google&#x27;</span>)        <span class="comment"># 使用 append() 添加元素到列表尾部</span></span><br><span class="line"><span class="built_in">list</span>.append(<span class="string">&#x27;Runoob&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">del</span> <span class="built_in">list</span>[<span class="number">1</span>]                  <span class="comment"># 删除指定索引的元素</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 常用方法</span></span><br><span class="line"><span class="built_in">list</span>.count(obj)              <span class="comment"># 统计某个元素在列表中出现的次数</span></span><br><span class="line"><span class="built_in">list</span>.insert(index, obj)      <span class="comment"># 将对象插入列表  list.insert(0, 666)</span></span><br><span class="line"><span class="built_in">list</span>.pop([index=-<span class="number">1</span>])         <span class="comment"># 移除列表中的一个元素（默认最后一个元素），并返回该元素的值</span></span><br><span class="line"><span class="built_in">list</span>.remove(obj)             <span class="comment"># 移除列表中某个值的第一个匹配项</span></span><br><span class="line"><span class="built_in">list</span>.reverse()               <span class="comment"># 反向列表中元素</span></span><br><span class="line"><span class="built_in">list</span>.sort()                  <span class="comment"># 对列表进行排序，需要一样的数据类型</span></span><br><span class="line"><span class="built_in">sum</span>(num_list)/<span class="built_in">len</span>(num_list)  <span class="comment"># 求平均值</span></span><br><span class="line"><span class="built_in">min</span>(num_list)</span><br><span class="line"><span class="built_in">max</span>(num_list)</span><br></pre></td></tr></table></figure><p>合并列表并去重：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 方式1：遍历追加（消耗性能）</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> b:</span><br><span class="line">    a.append(i)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式2：解包（推荐）</span></span><br><span class="line">a_new = [*a, *b]  <span class="comment"># 或者直接 a + b</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 列表推导式</span></span><br><span class="line"><span class="comment"># 求1-20的平方</span></span><br><span class="line">num_list = [i**<span class="number">2</span> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">21</span>)]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 从一个数字列表提取所有偶数，并计算平方组成新的列表</span></span><br><span class="line">num_list1 = [i**<span class="number">2</span> <span class="keyword">for</span> i <span class="keyword">in</span> num_list <span class="keyword">if</span> i % <span class="number">2</span> == <span class="number">0</span>]</span><br></pre></td></tr></table></figure><h2 id="tuple元组"><a class="markdownIt-Anchor" href="#tuple元组"></a> Tuple（元组）</h2><p>元组与列表类似，但不允许修改值。元组中只包含一个元素时，需要在元素后面添加逗号。元组中的元素值不允许删除，但可以使用 <code>del</code> 语句删除整个元组。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="built_in">tuple</span> = (<span class="string">&#x27;abcd&#x27;</span>, <span class="number">786</span>, <span class="number">2.23</span>, <span class="string">&#x27;runoob&#x27;</span>, <span class="number">70.2</span>)</span><br><span class="line">t2 = ()</span><br><span class="line">t3 = <span class="built_in">tuple</span>()  <span class="comment"># 3种定义方式</span></span><br><span class="line">tinytuple = (<span class="number">123</span>,)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">tuple</span>)              <span class="comment"># 输出完整元组</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">tuple</span>[<span class="number">0</span>])           <span class="comment"># 输出元组的第一个元素</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">tuple</span>[<span class="number">1</span>:<span class="number">3</span>])         <span class="comment"># 输出从第二个元素开始到第三个元素</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">tuple</span>[<span class="number">2</span>:])          <span class="comment"># 输出从第三个元素开始的所有元素</span></span><br><span class="line"><span class="built_in">print</span>(tinytuple * <span class="number">2</span>)      <span class="comment"># 输出两次元组</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">tuple</span> + tinytuple)  <span class="comment"># 连接元组</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 组包和解包</span></span><br><span class="line">t1 = <span class="number">1</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">2</span>            <span class="comment"># 组包，不加括号也行，也是元组</span></span><br><span class="line">a, b, c, d = t1            <span class="comment"># 解包，将元组每一项都对应赋值</span></span><br><span class="line"></span><br><span class="line">x, *y, z = t1  <span class="comment"># x=1, y=[4,5], z=2  *是扩展解包，来处理不确定的元素</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 变量交换（无需第三个变量）</span></span><br><span class="line">a, b = b, a  <span class="comment"># 组包 + 解包，一一对应赋值</span></span><br></pre></td></tr></table></figure><blockquote><p>只有 <code>count()</code> 和 <code>index()</code> 方法。</p></blockquote><h2 id="set集合"><a class="markdownIt-Anchor" href="#set集合"></a> Set（集合）</h2><p>创建一个<strong>空集合</strong>必须用 <code>set()</code> 而不是 <code>&#123;&#125;</code>，因为 <code>&#123;&#125;</code> 是用来创建一个空字典。</p><p>集合是一种<strong>无序</strong>、可变的数据类型，用于存储唯一的元素。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">sites = &#123;<span class="string">&#x27;Google&#x27;</span>, <span class="string">&#x27;Taobao&#x27;</span>, <span class="string">&#x27;Runoob&#x27;</span>, <span class="string">&#x27;Facebook&#x27;</span>, <span class="string">&#x27;Zhihu&#x27;</span>, <span class="string">&#x27;Baidu&#x27;</span>&#125;</span><br><span class="line"><span class="built_in">print</span>(sites)  <span class="comment"># 输出集合，重复的元素被自动去掉</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 成员测试</span></span><br><span class="line"><span class="keyword">if</span> <span class="string">&#x27;Runoob&#x27;</span> <span class="keyword">in</span> sites:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Runoob 在集合中&#x27;</span>)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;Runoob 不在集合中&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 集合运算</span></span><br><span class="line">a = <span class="built_in">set</span>(<span class="string">&#x27;abracadabra&#x27;</span>)</span><br><span class="line">b = <span class="built_in">set</span>(<span class="string">&#x27;alacazam&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(a)</span><br><span class="line"><span class="built_in">print</span>(a - b)  <span class="comment"># a 和 b 的差集</span></span><br><span class="line"><span class="built_in">print</span>(a | b)  <span class="comment"># a 和 b 的并集</span></span><br><span class="line"><span class="built_in">print</span>(a &amp; b)  <span class="comment"># a 和 b 的交集</span></span><br><span class="line"><span class="built_in">print</span>(a ^ b)  <span class="comment"># a 和 b 中不同时存在的元素</span></span><br></pre></td></tr></table></figure><p>常用方法：</p><table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>add()</code></td><td>添加元素到集合，随机位置</td></tr><tr><td><code>remove()</code></td><td>移除指定元素，不存在则报错</td></tr><tr><td><code>pop()</code></td><td>随机删除一个元素，并返回</td></tr><tr><td><code>clear()</code></td><td>清空集合</td></tr><tr><td><code>union()</code></td><td>求并集，全部并去重，<code>|</code> 也行</td></tr><tr><td><code>intersection()</code></td><td>求交集，相交的部分，<code>s1 &amp; s2 &amp; s3</code> 也能求交集</td></tr><tr><td><code>difference()</code></td><td>求差集，存在s2但不存在于s3</td></tr></tbody></table><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 差集示例</span></span><br><span class="line">s2.difference(s3)  <span class="comment"># s2&#123;1,2,3,4&#125; s3&#123;2,3,4,5&#125; 结果&#123;1&#125;</span></span><br><span class="line">s2 - s1  <span class="comment"># 也是求差集</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 集合推导式</span></span><br><span class="line">&#123;s <span class="keyword">for</span> s <span class="keyword">in</span> s2 <span class="keyword">if</span> s <span class="keyword">not</span> <span class="keyword">in</span> s3&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 统计元素出现次数</span></span><br><span class="line">a_set = &#123;<span class="string">&#x27;韩立&#x27;</span>, <span class="string">&#x27;紫林&#x27;</span>, <span class="string">&#x27;温岭&#x27;</span>&#125;</span><br><span class="line">b_set = &#123;<span class="string">&#x27;通天&#x27;</span>, <span class="string">&#x27;紫林&#x27;</span>, <span class="string">&#x27;温岭&#x27;</span>&#125;</span><br><span class="line">c_set = &#123;<span class="string">&#x27;韩立&#x27;</span>, <span class="string">&#x27;通天&#x27;</span>, <span class="string">&#x27;温岭&#x27;</span>&#125;</span><br><span class="line">all_set = a_set | b_set | c_set</span><br><span class="line">all_list = [*a_set, *b_set, *c_set]</span><br><span class="line"><span class="built_in">print</span>(all_list)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> all_set:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&quot;<span class="subst">&#123;i&#125;</span> 出现了次数<span class="subst">&#123;all_list.count(i)&#125;</span>&quot;</span>)</span><br></pre></td></tr></table></figure><h2 id="dictionary字典"><a class="markdownIt-Anchor" href="#dictionary字典"></a> Dictionary（字典）</h2><p>字典是一种映射类型，用 <code>&#123;&#125;</code> 标识，是一个无序的 <strong>键(key) : 值(value)</strong> 的集合。</p><p>键(key) 必须是唯一的而且是不可变类型（字符串、int、float、tuple），不能重复（如果重复后面覆盖前面），可修改。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">dict</span> = &#123;&#125;</span><br><span class="line">dict2 = <span class="built_in">dict</span>()</span><br><span class="line">tinydict = &#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;runoob&#x27;</span>, <span class="string">&#x27;code&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;site&#x27;</span>: <span class="string">&#x27;www.runoob.com&#x27;</span>&#125;</span><br><span class="line"><span class="comment"># 上面都是定义字典</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">dict</span>[<span class="string">&#x27;one&#x27;</span>] = <span class="string">&quot;1 - 菜鸟教程&quot;</span></span><br><span class="line"><span class="built_in">dict</span>[<span class="number">2</span>] = <span class="string">&quot;2 - 菜鸟工具&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">dict</span>[<span class="string">&#x27;one&#x27;</span>])       <span class="comment"># 输出键为 &#x27;one&#x27; 的值</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">dict</span>[<span class="number">2</span>])           <span class="comment"># 输出键为 2 的值</span></span><br><span class="line"><span class="built_in">print</span>(tinydict)          <span class="comment"># 输出完整的字典</span></span><br><span class="line"><span class="built_in">print</span>(tinydict.keys())   <span class="comment"># 输出所有键</span></span><br><span class="line"><span class="built_in">print</span>(tinydict.values()) <span class="comment"># 输出所有值</span></span><br><span class="line">tinydict[<span class="string">&#x27;name&#x27;</span>] = <span class="string">&#x27;wei&#x27;</span>  <span class="comment"># 更新</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">del</span> tinydict[<span class="string">&#x27;name&#x27;</span>]     <span class="comment"># 删除键是&#x27;name&#x27;的条目</span></span><br><span class="line">tinydict.clear()         <span class="comment"># 清空字典所有条目</span></span><br><span class="line"><span class="keyword">del</span> tinydict             <span class="comment"># 删除字典</span></span><br></pre></td></tr></table></figure><p>添加和修改语法一样：<code>dict['one'] = &quot;1 - 菜鸟教程&quot;</code>，不存在则新加，存在则修改。</p><table><thead><tr><th>操作</th><th>方法</th></tr></thead><tbody><tr><td>删除</td><td><code>字典名称.pop(key)</code> / <code>del 字典名称[key]</code></td></tr><tr><td>查找</td><td><code>字典名称[key]</code> / <code>字典名称.get(key)</code></td></tr><tr><td>获取全部key</td><td><code>字典名称.keys()</code> 类型 dict_keys</td></tr><tr><td>获取全部value</td><td><code>字典名称.values()</code> 类型 dict_values</td></tr><tr><td>获取全部键值对</td><td><code>字典名称.items()</code></td></tr></tbody></table><table><thead><tr><th>特性</th><th>字符串 (str)</th><th>列表 (list)</th><th>元组 (tuple)</th><th>集合 (set)</th><th>字典 (dict)</th></tr></thead><tbody><tr><td>有序性</td><td>有序</td><td>有序</td><td>有序</td><td>无序</td><td>有序 (3.7+)</td></tr><tr><td>重复元素</td><td>允许</td><td>允许</td><td>允许</td><td>不允许</td><td>key 不允许</td></tr><tr><td>可变性</td><td>不可变</td><td>可变</td><td>不可变</td><td>可变</td><td>可变</td></tr><tr><td>索引访问</td><td>支持</td><td>支持</td><td>支持</td><td>不支持</td><td>不支持</td></tr><tr><td>切片操作</td><td>支持</td><td>支持</td><td>支持</td><td>不支持</td><td>不支持</td></tr><tr><td>使用场景</td><td>文本处理</td><td>有序可重复数据集合</td><td>固定数据记录</td><td>去重数据集合</td><td>键值对</td></tr></tbody></table><h2 id="方法函数"><a class="markdownIt-Anchor" href="#方法函数"></a> 方法（函数）</h2><p>函数必须先定义，再去调用。<strong>def</strong> 关键词开头，后接函数标识符名称和圆括号 <code>()</code>，以冒号起始，并且缩进。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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 class="comment"># 定义函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">函数名</span>(<span class="params">参数列表</span>):</span><br><span class="line">    函数体</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">return</span> 返回值  <span class="comment"># 多个返回值逗号，元组去解包即可</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用</span></span><br><span class="line">函数名(参数)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">printinfo</span>(<span class="params">name, age=<span class="number">18</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    该函数用来格式化人物信息</span></span><br><span class="line"><span class="string">    :param name: 人名</span></span><br><span class="line"><span class="string">    :param age: 年龄</span></span><br><span class="line"><span class="string">    :return: 返回值为空</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;Name: &quot;</span>, name)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;Age &quot;</span>, age)</span><br><span class="line">    <span class="keyword">return</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用printinfo函数</span></span><br><span class="line">printinfo(age=<span class="number">50</span>, name=<span class="string">&quot;miki&quot;</span>)  <span class="comment"># 关键字参数，位置参数就默认顺序传进去，混用必须先位置参数再关键字</span></span><br><span class="line">printinfo(<span class="string">&quot;LUCKY&quot;</span>)  <span class="comment"># 默认参数的值如果没有传入，则使用函数里的默认值</span></span><br></pre></td></tr></table></figure><p>函数的嵌套调用遵循栈结构，后进先出 LIFO。每次调用函数时，会把该函数压入栈中（push），函数执行完毕后从栈中弹出（pop），类似于&quot;子弹夹&quot;一层层往上压，最上面的先被取出。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">def</span> <span class="title function_">function_a</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;a ... before&quot;</span>)</span><br><span class="line">    function_b()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;a ... after&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">function_b</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;b ... before&quot;</span>)</span><br><span class="line">    function_c()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;b ... after&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">function_c</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;c ...&quot;</span>)</span><br><span class="line"></span><br><span class="line">function_a()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出：</span></span><br><span class="line"><span class="comment"># a ... before</span></span><br><span class="line"><span class="comment"># b ... before</span></span><br><span class="line"><span class="comment"># c ...</span></span><br><span class="line"><span class="comment"># b ... after</span></span><br><span class="line"><span class="comment"># a ... after</span></span><br></pre></td></tr></table></figure><p><code>global</code> 关键字在函数里使用，明确这个变量和外面那个同名变量是全局变量，这样函数里面修改外面的值。没有这个关键字，各赋各的。</p><p>不定长参数 <code>*args</code> -&gt; 元组：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">calc_data</span>(<span class="params">*args, **kwargs</span>):  <span class="comment"># **kwargs 传进来是封装成字典的类型</span></span><br><span class="line">    <span class="string">&quot;求最大值，最小值，平均数&quot;</span></span><br><span class="line">    max_data = <span class="built_in">max</span>(args)</span><br><span class="line">    min_data = <span class="built_in">min</span>(args)</span><br><span class="line">    avg_data = <span class="built_in">sum</span>(args) / <span class="built_in">len</span>(args)</span><br><span class="line">    <span class="keyword">if</span> kwargs.get(<span class="string">&#x27;round&#x27;</span>):</span><br><span class="line">        avg_data = <span class="built_in">round</span>(avg_data, kwargs.get(<span class="string">&#x27;round&#x27;</span>))</span><br><span class="line">    <span class="keyword">return</span> max_data, min_data, avg_data</span><br><span class="line"></span><br><span class="line"><span class="comment"># 调用</span></span><br><span class="line"><span class="built_in">print</span>(calc_data(<span class="number">70</span>, <span class="number">66</span>, <span class="number">50.2123</span>, <span class="number">30</span>, <span class="built_in">round</span>=<span class="number">1</span>, count=<span class="number">0</span>))</span><br></pre></td></tr></table></figure><p>函数的参数类型除了普通参数（数字、布尔、字符串、列表、元组、集合、字典等），还能是函数：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a + b</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">subtract</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a - b</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">multiply</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a * b</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">divide</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a / b</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calc</span>(<span class="params">x, y, oper</span>):</span><br><span class="line">    <span class="keyword">return</span> oper(x, y)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(calc(<span class="number">1</span>, <span class="number">2</span>, multiply))</span><br></pre></td></tr></table></figure><p>匿名函数 <code>lambda</code>，如果是单行表达式并只在一个地方使用，考虑用这个：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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="keyword">lambda</span> 参数列表: 函数体</span><br><span class="line"></span><br><span class="line">hh = <span class="keyword">lambda</span>: <span class="built_in">print</span>(<span class="string">&#x27;hello world&#x27;</span>)  <span class="comment"># 无参数</span></span><br><span class="line">hh()</span><br><span class="line"></span><br><span class="line">add = <span class="keyword">lambda</span> arg1, arg2: arg1 + arg2  <span class="comment"># 默认有return</span></span><br><span class="line"><span class="built_in">print</span>(add(<span class="number">1</span>, <span class="number">2</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 排序示例</span></span><br><span class="line">data_list = [<span class="string">&#x27;c++&#x27;</span>, <span class="string">&#x27;python&#x27;</span>, <span class="string">&#x27;java&#x27;</span>, <span class="string">&#x27;javascript&#x27;</span>, <span class="string">&#x27;php&#x27;</span>, <span class="string">&#x27;c&#x27;</span>]</span><br><span class="line">data_list.sort(key=<span class="keyword">lambda</span> item: <span class="built_in">len</span>(item), reverse=<span class="literal">True</span>)</span><br><span class="line"><span class="built_in">print</span>(data_list)</span><br><span class="line"><span class="comment"># 按字符串长度排序，从长到短</span></span><br></pre></td></tr></table></figure><p>递归：函数自己调用自己。求 n 的阶乘（5的阶乘为 5×4×3×2×1），规律 <code>f(n) = n * f(n-1)</code>。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">jc</span>(<span class="params">n</span>):</span><br><span class="line">    <span class="keyword">if</span> n == <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> n * jc(n - <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">res = jc(<span class="number">3</span>)</span><br><span class="line"><span class="built_in">print</span>(res)</span><br></pre></td></tr></table></figure><h2 id="类型注解"><a class="markdownIt-Anchor" href="#类型注解"></a> 类型注解</h2><p>用来提示变量类型：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">a: <span class="built_in">int</span> = <span class="number">10</span></span><br><span class="line">score: <span class="built_in">float</span> = <span class="number">90.5</span></span><br><span class="line">hobby: <span class="built_in">str</span> = <span class="string">&#x27;篮球&#x27;</span></span><br><span class="line">flag: <span class="built_in">bool</span> = <span class="literal">True</span></span><br><span class="line">pic: <span class="literal">None</span> = <span class="literal">None</span></span><br><span class="line">names: <span class="built_in">list</span>[<span class="built_in">str</span> | <span class="built_in">int</span>] = [<span class="string">&#x27;张三&#x27;</span>, <span class="string">&#x27;李四&#x27;</span>, <span class="string">&#x27;王五&#x27;</span>]</span><br><span class="line">phones: <span class="built_in">list</span>[<span class="built_in">str</span>] = [<span class="string">&#x27;13800000000&#x27;</span>, <span class="string">&#x27;13900000000&#x27;</span>, <span class="string">&#x27;13700000000&#x27;</span>]</span><br><span class="line">options: <span class="built_in">dict</span>[<span class="built_in">str</span>, <span class="built_in">int</span>] = &#123;<span class="string">&#x27;age&#x27;</span>: <span class="number">18</span>, <span class="string">&#x27;hobby&#x27;</span>: <span class="number">1</span>&#125;</span><br><span class="line">goods: <span class="built_in">tuple</span>[<span class="built_in">str</span>, <span class="built_in">str</span>, <span class="built_in">int</span>] = (<span class="string">&#x27;apple&#x27;</span>, <span class="string">&#x27;orange&#x27;</span>, <span class="number">1</span>)</span><br></pre></td></tr></table></figure><h2 id="模块导入"><a class="markdownIt-Anchor" href="#模块导入"></a> 模块导入</h2><p>在 Python 用 <code>import</code> 或者 <code>from...import</code> 来导入相应的模块。</p><table><thead><tr><th>方式</th><th>格式</th></tr></thead><tbody><tr><td>导入整个模块</td><td><code>import somemodule</code></td></tr><tr><td>起别名</td><td><code>import random as rd</code></td></tr><tr><td>导入某个函数</td><td><code>from somemodule import somefunction</code></td></tr><tr><td>导入多个函数</td><td><code>from somemodule import firstfunc, secondfunc, thirdfunc as tunc</code></td></tr><tr><td>导入全部函数</td><td><code>from a import *</code></td></tr></tbody></table><p><code>*</code> 导入的并不一定是 a 里的全部功能，如果 a 定义了 <code>__all__</code> 变量，就是列表里的功能，没有则全部：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">__all__ = [<span class="string">&#x27;fun1&#x27;</span>, <span class="string">&#x27;fun2&#x27;</span>, pi]</span><br></pre></td></tr></table></figure><p>如果 a 引入 b，b 里面有测试代码也会执行。可以在 b 里将测试代码放在：</p><figure class="highlight python"><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="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    log.test()</span><br></pre></td></tr></table></figure><blockquote><p>b 里面 <code>__name__</code> 是 <code>'__main__'</code>，如果 a 运行引入，<code>__name__</code> 值是 <a href="http://b.py">b.py</a></p></blockquote><p>包：本质是一个文件夹，里面有很多 py 文件，文件夹下有 <code>__init__.py</code> 文件（空文件即可）。</p><figure class="highlight python"><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="keyword">import</span> 包名.somemodule</span><br><span class="line"><span class="keyword">from</span> 包名.somemodule <span class="keyword">import</span> somefunction</span><br></pre></td></tr></table></figure><h2 id="日期和时间"><a class="markdownIt-Anchor" href="#日期和时间"></a> 日期和时间</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">ticks = time.time()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;当前时间戳为:&quot;</span>, ticks)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 格式化成 2016-03-20 11:45:39 形式</span></span><br><span class="line"><span class="built_in">print</span>(time.strftime(<span class="string">&quot;%Y-%m-%d %H:%M:%S&quot;</span>, time.localtime()))</span><br><span class="line"><span class="comment"># 格式化成 Sat Mar 28 22:24:24 2016 形式</span></span><br><span class="line"><span class="built_in">print</span>(time.strftime(<span class="string">&quot;%a %b %d %H:%M:%S %Y&quot;</span>, time.localtime()))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将格式字符串转换为时间戳</span></span><br><span class="line">a = <span class="string">&quot;Sat Mar 28 22:24:24 2016&quot;</span></span><br><span class="line"><span class="built_in">print</span>(time.mktime(time.strptime(a, <span class="string">&quot;%a %b %d %H:%M:%S %Y&quot;</span>)))</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> calendar</span><br><span class="line">cal = calendar.month(<span class="number">2024</span>, <span class="number">8</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;以下输出2024年8月份的日历:&quot;</span>, cal)</span><br><span class="line"><span class="built_in">print</span>(calendar.isleap(<span class="number">2024</span>))  <span class="comment"># 闰年返回True，否则为False</span></span><br></pre></td></tr></table></figure><h2 id="文件io"><a class="markdownIt-Anchor" href="#文件io"></a> 文件I/O</h2><p><strong>open 函数</strong> — 创建一个 file 对象，相关的方法才可以调用它进行读写。</p><p><code>w</code> 覆盖内容，<code>a</code> 追加内容，文件不存在会自动创建。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 推荐用 with 语句，自动关闭文件</span></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;古诗.txt&quot;</span>, <span class="string">&#x27;w&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    f.write(<span class="string">&quot;静夜思（李白）\n&quot;</span>)</span><br><span class="line">    f.write(<span class="string">&quot;窗前明月光,\n&quot;</span>)</span><br><span class="line">    f.write(<span class="string">&quot;疑是地上霜.\n&quot;</span>)</span><br><span class="line">    f.write(<span class="string">&quot;举头望明月,\n&quot;</span>)</span><br><span class="line">    f.write(<span class="string">&quot;低头思故乡.\n&quot;</span>)</span><br></pre></td></tr></table></figure><h2 id="异常"><a class="markdownIt-Anchor" href="#异常"></a> 异常</h2><p>也称 bug，程序运行过程中的错误，它会中断程序的正常执行逻辑。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;我是&#x27;</span>[<span class="number">3</span>])</span><br><span class="line"><span class="keyword">except</span> NameError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;变量不存在，异常信息是&#x27;</span>, e)</span><br><span class="line"><span class="keyword">except</span> ZeroDivisionError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;除数不能为0，异常信息是&#x27;</span>, e)</span><br><span class="line"><span class="keyword">except</span> IndexError <span class="keyword">as</span> e:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;索引超出范围，异常信息是&#x27;</span>, e)</span><br><span class="line"><span class="keyword">except</span> Exception <span class="keyword">as</span> e:  <span class="comment"># 捕获所有异常</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;其他异常，异常信息是&#x27;</span>, e)</span><br><span class="line"><span class="keyword">finally</span>:  <span class="comment"># 无论是否有异常，都会执行finally中的代码</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;资源释放&#x27;</span>)</span><br></pre></td></tr></table></figure><p>异常传递就是异常在函数调用中层层上报的过程，直到有人处理它，或者程序崩溃。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">function_a</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;a ... before&quot;</span>)</span><br><span class="line">    function_b()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;a ... after&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">function_b</span>():</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;b ... before&quot;</span>)</span><br><span class="line">    function_c()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;b ... after&quot;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">function_c</span>():</span><br><span class="line">    <span class="built_in">print</span>(myname)  <span class="comment"># 异常一层一层抛出</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        function_a()</span><br><span class="line">    <span class="keyword">except</span> NameError <span class="keyword">as</span> e:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;程序运行错误，请联系管理员，错误信息是&#x27;</span>, e)</span><br></pre></td></tr></table></figure><h2 id="类面向对象"><a class="markdownIt-Anchor" href="#类面向对象"></a> 类（面向对象）</h2><p>遵循大驼峰命名法。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 定义类（不推荐动态添加属性）</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Car</span>:</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 实例化对象</span></span><br><span class="line">new_car = Car()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 动态添加属性</span></span><br><span class="line">new_car.color = <span class="string">&#x27;red&#x27;</span></span><br><span class="line">new_car.price = <span class="number">1000000</span></span><br><span class="line">new_car.brand = <span class="string">&#x27;Benz&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(new_car.color)</span><br><span class="line"><span class="comment"># 查看对象的属性，以字典形式展示</span></span><br><span class="line"><span class="built_in">print</span>(new_car.__dict__)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Car</span>:</span><br><span class="line">    <span class="comment"># 类属性，类名.属性名，所有实例对象都共享</span></span><br><span class="line">    wheel = <span class="number">4</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color, price, brand</span>):  <span class="comment"># 魔法方法，自动调用</span></span><br><span class="line">        <span class="comment"># 实例属性，实例名.属性名</span></span><br><span class="line">        self.color = color</span><br><span class="line">        self.price = price</span><br><span class="line">        self.brand = brand</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">running</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;我是一个车&#x27;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;我是一个&#x27;</span>, self.brand, <span class="string">&#x27;车&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 魔法方法 __xxx__ 特殊方法，py会在合适时机自动调用</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__str__</span>(<span class="params">self</span>) -&gt; <span class="built_in">str</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="string">f&#x27;我是一个<span class="subst">&#123;self.brand&#125;</span>车&#x27;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__eq__</span>(<span class="params">self, value: <span class="built_in">object</span></span>) -&gt; <span class="built_in">bool</span>:</span><br><span class="line">        <span class="keyword">return</span> self.brand == value.brand <span class="keyword">and</span> self.price == value.price <span class="keyword">and</span> self.color == value.color</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__lt__</span>(<span class="params">self, value: <span class="built_in">object</span></span>) -&gt; <span class="built_in">bool</span>:</span><br><span class="line">        <span class="keyword">return</span> self.price &lt; value.price</span><br><span class="line"></span><br><span class="line"><span class="comment"># 实例化对象</span></span><br><span class="line">new_car = Car(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>)</span><br><span class="line">new_car.running()</span><br><span class="line">new_car2 = Car(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(new_car)           <span class="comment"># 默认是地址，重写了__str__方法</span></span><br><span class="line"><span class="built_in">print</span>(new_car2)</span><br><span class="line"><span class="built_in">print</span>(new_car2 == new_car)  <span class="comment"># 默认是地址比较，所以2个不相等</span></span><br><span class="line"><span class="built_in">print</span>(new_car.__dict__)</span><br><span class="line"></span><br><span class="line">new_car3 = Car(<span class="string">&#x27;red&#x27;</span>, <span class="number">1200</span>, <span class="string">&#x27;Benz&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(new_car3 &lt; new_car2)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Employee</span>:</span><br><span class="line">    <span class="string">&#x27;所有员工的基类&#x27;</span></span><br><span class="line">    empCount = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, salary</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.salary = salary</span><br><span class="line">        Employee.empCount += <span class="number">1</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">displayCount</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;Total Employee %d&quot;</span> % Employee.empCount)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">displayEmployee</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;Name : &quot;</span>, self.name, <span class="string">&quot;, Salary: &quot;</span>, self.salary)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__del__</span>(<span class="params">self</span>):</span><br><span class="line">        class_name = self.__class__.__name__</span><br><span class="line">        <span class="built_in">print</span>(class_name, <span class="string">&quot;销毁&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">parentMethod</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;调用父类方法&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Child</span>(<span class="title class_ inherited__">Employee</span>):  <span class="comment"># 定义子类</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;调用子类构造方法&quot;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">childMethod</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;调用子类方法&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建 Employee 类的对象</span></span><br><span class="line">emp1 = Employee(<span class="string">&quot;Zara&quot;</span>, <span class="number">2000</span>)</span><br><span class="line">emp2 = Employee(<span class="string">&quot;Manni&quot;</span>, <span class="number">5000</span>)</span><br><span class="line">emp1.displayEmployee()</span><br><span class="line">emp2.displayEmployee()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Total Employee %d&quot;</span> % Employee.empCount)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">getattr</span>(emp1, <span class="string">&#x27;name&#x27;</span>))</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Employee.__doc__:&quot;</span>, Employee.__doc__)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Employee.__name__:&quot;</span>, Employee.__name__)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Employee.__module__:&quot;</span>, Employee.__module__)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Employee.__bases__:&quot;</span>, Employee.__bases__)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;Employee.__dict__:&quot;</span>, Employee.__dict__)</span><br><span class="line"></span><br><span class="line">c = Child()</span><br><span class="line">c.childMethod()</span><br><span class="line">c.parentMethod()</span><br></pre></td></tr></table></figure><table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>getattr(obj, name[, default])</code></td><td>访问对象的属性</td></tr><tr><td><code>hasattr(obj, name)</code></td><td>检查是否存在一个属性</td></tr><tr><td><code>setattr(obj, name, value)</code></td><td>设置一个属性，不存在则创建新属性</td></tr><tr><td><code>delattr(obj, name)</code></td><td>删除属性</td></tr></tbody></table><table><thead><tr><th>属性</th><th>说明</th></tr></thead><tbody><tr><td><code>__dict__</code></td><td>类的属性（包含一个字典）</td></tr><tr><td><code>__doc__</code></td><td>类的文档字符串</td></tr><tr><td><code>__name__</code></td><td>类名</td></tr><tr><td><code>__module__</code></td><td>类定义所在的模块</td></tr><tr><td><code>__bases__</code></td><td>类的所有父类构成元素</td></tr></tbody></table><h3 id="封装"><a class="markdownIt-Anchor" href="#封装"></a> 封装</h3><p>把数据和操作数据的方法都放一起，形成一个类，并隐藏内部的实现细节（私有属性、私有方法），只对外暴露必要的方法（公共属性、公共方法）。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="keyword">class</span> <span class="title class_">Car</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color, model, brand, c_owner</span>):</span><br><span class="line">        self.color = color</span><br><span class="line">        self.model = model</span><br><span class="line">        self.brand = brand</span><br><span class="line">        self.__owner = c_owner  <span class="comment"># __下划线 私有属性</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">running</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在启动....&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__control_fuel</span>(<span class="params">self</span>):  <span class="comment"># __下划线 私有方法</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在控制油门...S&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    car = Car(<span class="string">&#x27;red&#x27;</span>, <span class="string">&#x27;GLB&#x27;</span>, <span class="string">&#x27;Benz&#x27;</span>, <span class="string">&#x27;lucky&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(car.brand)</span><br><span class="line">    <span class="comment"># python中没有真正的私有机制，默认的调用不行，再加个类名点就可以了</span></span><br><span class="line">    <span class="built_in">print</span>(car._Car__owner)</span><br><span class="line">    car.running()</span><br></pre></td></tr></table></figure><h3 id="继承"><a class="markdownIt-Anchor" href="#继承"></a> 继承</h3><p>子类继承父类，可以获取到父类的属性和方法（非私有），所有类都有一个父类 Object。</p><figure class="highlight python"><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="keyword">class</span> <span class="title class_">子类</span>(<span class="title class_ inherited__">父类</span>):</span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><p>子类想重写父类方法，直接写个一样即可。如果需要调用父类的方法，可以通过 <code>父类名.方法名(self)</code> / <code>super().方法名()</code> 来调用。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Car</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color, model, brand, c_owner</span>):</span><br><span class="line">        self.color = color</span><br><span class="line">        self.model = model</span><br><span class="line">        self.brand = brand</span><br><span class="line">        self.__owner = c_owner</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">running</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在启动....（模板）&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__control_fuel</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在控制油门...S&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">FuelCar</span>(<span class="title class_ inherited__">Car</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color, model, brand, c_owner, fuel_type</span>):</span><br><span class="line">        <span class="built_in">super</span>().__init__(color, model, brand, c_owner)  <span class="comment"># 继承</span></span><br><span class="line">        self.fuel_type = fuel_type</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">running</span>(<span class="params">self</span>):  <span class="comment"># 方法重写</span></span><br><span class="line">        <span class="comment"># super().running()  # 调用父类的方法  方式1</span></span><br><span class="line">        Car.running(self)  <span class="comment"># 调用父类方法  方式2</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在启动....S&#x27;</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在启动油门...S&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ElectricCar</span>(<span class="title class_ inherited__">Car</span>):</span><br><span class="line">    <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    c1 = FuelCar(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>, <span class="string">&#x27;lucky&#x27;</span>, <span class="string">&#x27;gas&#x27;</span>)</span><br><span class="line">    c1.running()</span><br><span class="line">    c2 = ElectricCar(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>, <span class="string">&#x27;lucky&#x27;</span>)</span><br><span class="line">    c2.running()</span><br></pre></td></tr></table></figure><p>一个类继承了多个父类的情况，默认使用第一个父类中的同名属性或方法。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(类名.__mro__)  <span class="comment"># 查看执行属性</span></span><br><span class="line"><span class="built_in">print</span>(类名.mro())    <span class="comment"># 同上</span></span><br></pre></td></tr></table></figure><h3 id="多态"><a class="markdownIt-Anchor" href="#多态"></a> 多态</h3><p>多态指的是同一个方法，有不同的形态、行为、表现。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Car</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, color, model, brand</span>):</span><br><span class="line">        self.color = color</span><br><span class="line">        self.model = model</span><br><span class="line">        self.brand = brand</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">running</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在启动....（模板）&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">FuelCar</span>(<span class="title class_ inherited__">Car</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">charge</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在加油&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">ElectricCar</span>(<span class="title class_ inherited__">Car</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">charge</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.brand&#125;</span><span class="subst">&#123;self.model&#125;</span>正在充电&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">handle_charge</span>(<span class="params">car: Car</span>):</span><br><span class="line">    car.charge()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    handle_charge(FuelCar(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>))</span><br><span class="line">    handle_charge(ElectricCar(<span class="string">&#x27;red&#x27;</span>, <span class="number">100</span>, <span class="string">&#x27;Benz&#x27;</span>))</span><br></pre></td></tr></table></figure><p>Python 中的多态不依赖继承（Java 依赖），Python 中只要它走起来像鸭子，叫起来像鸭子，就是鸭子 —— <strong>鸭子类型</strong>，关注对象的行为，而不是类。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">swimming</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.age&#125;</span> 岁的 <span class="subst">&#123;self.name&#125;</span> 正在游泳...&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Duck</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">swimming</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.age&#125;</span> 岁的 <span class="subst">&#123;self.name&#125;</span> 正在游泳...&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Pig</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, name, age</span>):</span><br><span class="line">        self.name = name</span><br><span class="line">        self.age = age</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">swimming</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;self.age&#125;</span> 岁的 <span class="subst">&#123;self.name&#125;</span> 正在游泳...&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">go_swimming</span>(<span class="params">duck</span>):</span><br><span class="line">    duck.swimming()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试代码</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    go_swimming(Dog(<span class="string">&quot;旺财&quot;</span>, <span class="number">4</span>))</span><br><span class="line">    go_swimming(Duck(<span class="string">&quot;唐老鸭&quot;</span>, <span class="number">2</span>))</span><br><span class="line">    go_swimming(Pig(<span class="string">&quot;佩奇&quot;</span>, <span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出：</span></span><br><span class="line"><span class="comment"># 4 岁的 旺财 正在游泳...</span></span><br><span class="line"><span class="comment"># 2 岁的 唐老鸭 正在游泳...</span></span><br><span class="line"><span class="comment"># 1 岁的 佩奇 正在游泳...</span></span><br></pre></td></tr></table></figure><p><strong>抽象类</strong> — 只能被继承，不能被实例化，作用是规定子类必须实现哪些方法，强制子类必须遵守统一代码规范。抽象类要继承 abc 模块中的 ABC 类（Abstract Base Class）。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> abc <span class="keyword">import</span> ABC, abstractmethod</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Car</span>(<span class="title class_ inherited__">ABC</span>):</span><br><span class="line"><span class="meta">    @abstractmethod  </span><span class="comment"># 这个必须在子类中实现</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fun</span>(<span class="params">self</span>):</span><br><span class="line">        ...</span><br></pre></td></tr></table></figure><p><strong>静态方法和类方法</strong> — 类方法是类所拥有的方法，需要使用装饰器 <code>@classmethod</code> 来标识。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Student</span>:</span><br><span class="line">    school = <span class="string">&#x27;学校啊&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @classmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">cls</span>):</span><br><span class="line">        <span class="built_in">print</span>(cls.school)  <span class="comment"># cls指向这个实例</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @staticmethod</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">show2</span>():</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;静态方法&#x27;</span>)</span><br></pre></td></tr></table></figure><p>property 属性可以把函数当变量来用。方式1：装饰器；方式2：类属性。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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">class</span> <span class="title class_">Student</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line">        self.__age = <span class="number">20</span></span><br><span class="line"></span><br><span class="line"><span class="meta">    @property</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="keyword">return</span> self.__age</span><br><span class="line"></span><br><span class="line"><span class="meta">    @age.setter</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">age</span>(<span class="params">self, age</span>):</span><br><span class="line">        self.__age = age</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 方式2</span></span><br><span class="line">    <span class="comment"># def get_age(self):</span></span><br><span class="line">    <span class="comment">#     return self.__age</span></span><br><span class="line">    <span class="comment"># def set_age(self, age):</span></span><br><span class="line">    <span class="comment">#     self.__age = age</span></span><br><span class="line">    <span class="comment"># age = property(get_age, set_age)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    s = Student()</span><br><span class="line">    s.age = <span class="number">18</span>  <span class="comment"># 使用property设置年龄</span></span><br><span class="line">    <span class="built_in">print</span>(s.age)  <span class="comment"># 使用property获取年龄</span></span><br></pre></td></tr></table></figure><h2 id="闭包"><a class="markdownIt-Anchor" href="#闭包"></a> 闭包</h2><p>使用外部函数变量的内部函数称为闭包。作用：外部函数执行完毕，内部函数依旧可以使用外部函数的变量。</p><p>函数名 -&gt; 对象；函数名() -&gt; 调用函数返回值。</p><p><strong>条件：</strong></p><ol><li>外部函数<strong>嵌套</strong>内部函数</li><li>内部函数<strong>引用</strong>外部函数的变量</li><li><strong>返回</strong>内部函数名（对象）</li></ol><p><code>global</code>：声明全局变量。<code>nonlocal</code>：内部函数可以修改外部函数的变量值。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">fn_outer</span>(<span class="params">num1</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fn_inner</span>(<span class="params">num2</span>):  <span class="comment"># 有嵌套</span></span><br><span class="line">        <span class="built_in">sum</span> = num1 + num2  <span class="comment"># 有引用</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;sum&quot;</span>, <span class="built_in">sum</span>)</span><br><span class="line">    <span class="keyword">return</span> fn_inner  <span class="comment"># 返回内层函数</span></span><br><span class="line"></span><br><span class="line">fn = fn_outer(<span class="number">30</span>)  <span class="comment"># 调用外层函数，返回内层函数</span></span><br><span class="line">fn(<span class="number">20</span>)</span><br><span class="line"></span><br><span class="line">fn_outer(<span class="number">40</span>)(<span class="number">46</span>)  <span class="comment"># 直接调用外层函数，返回内层函数，再调用内层函数</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fn_outer2</span>():</span><br><span class="line">    a = <span class="number">100</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fn_inner</span>():</span><br><span class="line">        <span class="keyword">nonlocal</span> a  <span class="comment"># 内部修改a的值</span></span><br><span class="line">        a = a + <span class="number">1</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;a&quot;</span>, a)</span><br><span class="line">    <span class="keyword">return</span> fn_inner</span><br><span class="line"></span><br><span class="line">fn2 = fn_outer2()</span><br><span class="line">fn2()</span><br><span class="line">fn2()</span><br><span class="line"></span><br><span class="line"><span class="comment"># 输出：</span></span><br><span class="line"><span class="comment"># sum 50</span></span><br><span class="line"><span class="comment"># sum 86</span></span><br><span class="line"><span class="comment"># a 101</span></span><br><span class="line"><span class="comment"># a 102</span></span><br></pre></td></tr></table></figure><h2 id="装饰器"><a class="markdownIt-Anchor" href="#装饰器"></a> 装饰器</h2><p>不改变原有函数的基础上，给原有函数增加额外的功能。本质是个闭包函数，特点多了一个有额外功能。</p><p>装饰器的内部函数格式要和被装饰的原函数一致。多个装饰器装饰1个原函数，用 <code>@</code> 来装饰，从上到下执行。装饰器只能有1个参数，如果有2个，外部再套一层。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">cheke_login</span>(<span class="params">fn_name</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fn_inner</span>():  <span class="comment"># 内部函数 无参</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;检查登录&quot;</span>)  <span class="comment"># 有额外功能</span></span><br><span class="line">        fn_name()</span><br><span class="line">    <span class="keyword">return</span> fn_inner</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@cheke_login  </span><span class="comment"># 调用方式1</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">comment</span>():  <span class="comment"># 被装饰的函数 无参</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&quot;发布评论&quot;</span>)</span><br><span class="line"></span><br><span class="line">comment()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&quot;-----------------&quot;</span>)</span><br><span class="line">cheke_login(comment)()  <span class="comment"># 调用方式2</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mydecorator</span>(<span class="params">fn_name</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">fn_inner</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;努力计算中。。。&quot;</span>)</span><br><span class="line">        <span class="keyword">return</span> fn_name(*args, **kwargs)</span><br><span class="line">    <span class="keyword">return</span> fn_inner</span><br><span class="line"></span><br><span class="line"><span class="meta">@mydecorator</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">calc_data</span>(<span class="params">*args, **kwargs</span>):</span><br><span class="line">    <span class="built_in">print</span>(args)</span><br><span class="line">    <span class="built_in">print</span>(kwargs)</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">sum</span>(args) + <span class="built_in">sum</span>(kwargs.values())</span><br><span class="line"></span><br><span class="line">result = calc_data(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, num=<span class="number">22</span>)</span><br><span class="line"><span class="built_in">print</span>(result)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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="comment"># 实现加减的装饰器</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">out</span>(<span class="params">flag</span>):</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">mydecorator</span>(<span class="params">fn_name</span>):</span><br><span class="line">        <span class="keyword">def</span> <span class="title function_">fn_inner</span>(<span class="params">a, b</span>):</span><br><span class="line">            <span class="keyword">if</span> flag == <span class="string">&quot;+&quot;</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;进行加法&quot;</span>)</span><br><span class="line">            <span class="keyword">elif</span> flag == <span class="string">&quot;-&quot;</span>:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">&quot;进行减法&quot;</span>)</span><br><span class="line">            <span class="keyword">return</span> fn_name(a, b)</span><br><span class="line">        <span class="keyword">return</span> fn_inner</span><br><span class="line">    <span class="keyword">return</span> mydecorator</span><br><span class="line"></span><br><span class="line"><span class="meta">@out(<span class="params"><span class="string">&quot;+&quot;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fn_add</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a + b</span><br><span class="line"></span><br><span class="line"><span class="meta">@out(<span class="params"><span class="string">&quot;-&quot;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">fn_sub</span>(<span class="params">a, b</span>):</span><br><span class="line">    <span class="keyword">return</span> a - b</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(fn_add(<span class="number">10</span>, <span class="number">20</span>))</span><br><span class="line"><span class="built_in">print</span>(fn_sub(<span class="number">100</span>, <span class="number">20</span>))</span><br></pre></td></tr></table></figure><h2 id="深拷贝和浅拷贝"><a class="markdownIt-Anchor" href="#深拷贝和浅拷贝"></a> 深拷贝和浅拷贝</h2><ul><li><strong>浅拷贝</strong>：只拷贝了最外围的对象本身，元素内部只拷贝了一个引用</li><li><strong>深拷贝</strong>：拷贝所有层</li></ul><p>使用 <code>copy</code> 模块的 <code>copy()</code> 和 <code>deepcopy()</code>。</p><blockquote><p>深浅拷贝针对不可变类型如元组，和普通用法一样，不会开新空间。</p></blockquote><h2 id="正则表达式"><a class="markdownIt-Anchor" href="#正则表达式"></a> 正则表达式</h2><p>用来匹配字符串中符合规则的字符序列，就是一种匹配工具。</p><p>参考工具：<a href="https://luckynwa6.github.io/lucky-tools/lucky-regular">https://luckynwa6.github.io/lucky-tools/lucky-regular</a></p><table><thead><tr><th>表达式</th><th>描述</th></tr></thead><tbody><tr><td>普通字符</td><td>字母、数字、汉字及大多数字符，直接匹配自身</td></tr><tr><td><code>.</code></td><td>匹配任意一个字符（除 <code>\n</code>）</td></tr><tr><td><code>\d</code></td><td>匹配数字 0-9</td></tr><tr><td><code>\D</code></td><td>匹配非数字</td></tr><tr><td><code>\w</code></td><td>匹配单词字符，即 a-z、A-Z、0-9、_、其他语言字符</td></tr><tr><td><code>\W</code></td><td>匹配非单词字符 ,.@$</td></tr><tr><td><code>[aeiou]</code></td><td>匹配其中的任何单个字符</td></tr><tr><td><code>[^aeiou]</code></td><td>求反，匹配不在字符列表中的任何单个字符</td></tr><tr><td><code>[0-5]</code></td><td>表示范围</td></tr></tbody></table><hr /><table><thead><tr><th>表达式</th><th>描述</th></tr></thead><tbody><tr><td><code>*</code></td><td>出现任意次（0次或无数次）</td></tr><tr><td><code>+</code></td><td>至少出现1次（1次或无数次）</td></tr><tr><td><code>?</code></td><td>至多出现一次（0次或1次）</td></tr><tr><td><code>&#123;m&#125;</code></td><td>出现 m 次</td></tr><tr><td><code>&#123;m,&#125;</code></td><td>至少出现 m 次</td></tr><tr><td><code>&#123;m,n&#125;</code></td><td>出现 m 到 n 次</td></tr><tr><td><code>|</code></td><td>或的意思，匹配左右任意一个表达式</td></tr><tr><td><code>()</code></td><td>分组，将括号里的多个字符视为一个单元</td></tr><tr><td><code>^</code></td><td>匹配字符串开头</td></tr><tr><td><code>$</code></td><td>匹配字符串结尾</td></tr></tbody></table><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line">s1 = <span class="string">&quot;18809090000是我的手机号，188开头的，以00结尾的；我的另一个手机号是15500008888，两个QQ号分别是1259989092和13809091293821，邮箱为python666@163.com&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 常用匹配</span></span><br><span class="line"><span class="built_in">print</span>(re.findall(<span class="string">r&quot;188\d&#123;8&#125;&quot;</span>, s1))</span><br><span class="line"><span class="built_in">print</span>(re.findall(<span class="string">r&quot;155\d&#123;6,10&#125;&quot;</span>, s1))</span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;1[38]\d&#123;8&#125;&quot;</span>, string=s1))</span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;1[3-9]\d&#123;8&#125;&quot;</span>, string=s1))</span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;^1[3-9]\d&#123;9&#125;&quot;</span>, string=s1))</span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;^1[3-9]\d&#123;9&#125;$&quot;</span>, string=s1))</span><br><span class="line"></span><br><span class="line">s2 = <span class="string">&quot;现在的时间是2026-02-06 10:05:25，今天的天气还可以，气温是28度&quot;</span></span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;\d&#123;4&#125;-\d&#123;2&#125;-\d&#123;2&#125;&quot;</span>, string=s2))</span><br><span class="line"><span class="built_in">print</span>(re.findall(pattern=<span class="string">r&quot;(\d&#123;4&#125;)-(\d&#123;2&#125;)-(\d&#123;2&#125;)&quot;</span>, string=s2))</span><br><span class="line"><span class="comment"># 结果：</span></span><br><span class="line"><span class="comment"># [&#x27;2026-02-06&#x27;]</span></span><br><span class="line"><span class="comment"># [(&#x27;2026&#x27;, &#x27;02&#x27;, &#x27;06&#x27;)]</span></span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配邮箱（163/126/qq的邮箱，字母下划线4-20）</span></span><br><span class="line">email = <span class="string">&#x27;1656213092@qq.com&#x27;</span></span><br><span class="line">result = re.<span class="keyword">match</span>(<span class="string">r&#x27;(^[a-zA-Z0-9]&#123;4,20&#125;)@(163|126|qq)\.com$&#x27;</span>, email)</span><br><span class="line"><span class="built_in">print</span>(result.group() <span class="keyword">if</span> result <span class="keyword">else</span> <span class="string">&#x27;未匹配&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(result.group(<span class="number">1</span>))  <span class="comment"># () 包起来就是分组了，可以通过索引拿值</span></span><br><span class="line"><span class="built_in">print</span>(result.group(<span class="number">2</span>))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 匹配手机号</span></span><br><span class="line">phone = <span class="string">&#x27;13850694839&#x27;</span></span><br><span class="line">result2 = re.<span class="keyword">match</span>(<span class="string">r&#x27;1[3-9]\d&#123;9&#125;&#x27;</span>, phone)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;匹配的值为：<span class="subst">&#123;result2.group()&#125;</span>&#x27;</span> <span class="keyword">if</span> result2 <span class="keyword">else</span> <span class="string">&#x27;未匹配&#x27;</span>)</span><br></pre></td></tr></table></figure><h2 id="网络编程和多线程"><a class="markdownIt-Anchor" href="#网络编程和多线程"></a> 网络编程和多线程</h2><p>服务器给客户端发送消息，客户端给出回执信息。</p><blockquote><p>英文字母、数字、特殊符号都只占1个字节，中文在 gbk 中占2个字节，在 utf-8 里是3个字节。</p></blockquote><h3 id="socket-通信"><a class="markdownIt-Anchor" href="#socket-通信"></a> socket 通信</h3><p>服务端：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> socket</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建服务器socket对象，指定地址族为IPv4，套类型为TCP</span></span><br><span class="line">server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)</span><br><span class="line"><span class="comment"># 绑定服务器地址和端口</span></span><br><span class="line">server_socket.bind((<span class="string">&#x27;127.0.0.1&#x27;</span>, <span class="number">10087</span>))</span><br><span class="line"><span class="comment"># 设置最大连接数</span></span><br><span class="line">server_socket.listen(<span class="number">5</span>)</span><br><span class="line"><span class="comment"># 等待客户端连接</span></span><br><span class="line">accept_socket, client_info = server_socket.accept()</span><br><span class="line"><span class="comment"># 给客户端发送数据</span></span><br><span class="line">accept_socket.send(<span class="string">b&quot;hello client&quot;</span>)</span><br><span class="line"><span class="comment"># 接收客户端发送的数据</span></span><br><span class="line">client_data = accept_socket.recv(<span class="number">1024</span>).decode(<span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;服务端接受的数据来自<span class="subst">&#123;client_info&#125;</span>为：<span class="subst">&#123;client_data&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 关闭连接</span></span><br><span class="line">accept_socket.close()</span><br></pre></td></tr></table></figure><p>客户端：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> socket</span><br><span class="line"></span><br><span class="line"><span class="comment"># 发送信息给服务器</span></span><br><span class="line">client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)</span><br><span class="line">client_socket.connect((<span class="string">&#x27;127.0.0.1&#x27;</span>, <span class="number">10087</span>))</span><br><span class="line">client_data = client_socket.recv(<span class="number">1024</span>).decode(<span class="string">&#x27;utf-8&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f&#x27;客户端接受的数据为：<span class="subst">&#123;client_data&#125;</span>&#x27;</span>)</span><br><span class="line">client_socket.send(<span class="string">&#x27;socket很好玩&#x27;</span>.encode(<span class="string">&#x27;utf-8&#x27;</span>))</span><br><span class="line">client_socket.close()</span><br></pre></td></tr></table></figure><h3 id="多进程"><a class="markdownIt-Anchor" href="#多进程"></a> 多进程</h3><ul><li><strong>多任务</strong>：同一时间内执行多个任务</li><li><strong>并发</strong>：在一段时间内，交替执行任务（单核只能并发）</li><li><strong>并行</strong>：在一段时间内，真正的同时一起执行多个任务</li></ul><p>进程之间不共享全局变量。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> multiprocessing</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">listen_music</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;听音乐第<span class="subst">&#123;i&#125;</span>首&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;进程pid为<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">write_code</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;敲代码第<span class="subst">&#123;i&#125;</span>行&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;进程pid为<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">swimming</span>(<span class="params">name, num</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, num + <span class="number">1</span>):</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;<span class="subst">&#123;name&#125;</span>游泳第<span class="subst">&#123;i&#125;</span>次&#x27;</span>)</span><br><span class="line"></span><br><span class="line">p1 = multiprocessing.Process(target=listen_music)</span><br><span class="line">p2 = multiprocessing.Process(target=write_code)</span><br><span class="line">p3 = multiprocessing.Process(target=swimming, kwargs=&#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;张三&#x27;</span>, <span class="string">&#x27;num&#x27;</span>: <span class="number">3</span>&#125;)</span><br><span class="line">p4 = multiprocessing.Process(target=swimming, args=(<span class="string">&#x27;李四&#x27;</span>, <span class="number">3</span>))</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;main进程pid为<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line">    p1.start()</span><br><span class="line">    p2.start()</span><br><span class="line">    p3.start()</span><br><span class="line">    p4.start()</span><br><span class="line">    time.sleep(<span class="number">1</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;main进程结束了&#x27;</span>)</span><br></pre></td></tr></table></figure><h3 id="多线程"><a class="markdownIt-Anchor" href="#多线程"></a> 多线程</h3><p>线程依附<strong>进程</strong>执行，是 cpu 调度的基本单元。同一进程的线程数据可以共享全局变量，会出现互斥锁问题。线程之间是无序的，主线程会等待所有子线程执行结束再结束。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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 class="keyword">import</span> threading</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">listen_music</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;听音乐第<span class="subst">&#123;i&#125;</span>首&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;线程名：<span class="subst">&#123;threading.current_thread().name&#125;</span>, 进程pid：<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">write_code</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">        time.sleep(<span class="number">0.1</span>)</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;敲代码第<span class="subst">&#123;i&#125;</span>行&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;线程名：<span class="subst">&#123;threading.current_thread().name&#125;</span>, 进程pid：<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># daemon=True 表示子线程，主线程结束时自动结束</span></span><br><span class="line">t1 = threading.Thread(target=listen_music, name=<span class="string">&#x27;听音乐线程&#x27;</span>, daemon=<span class="literal">True</span>)</span><br><span class="line">t2 = threading.Thread(target=write_code, name=<span class="string">&#x27;敲代码线程&#x27;</span>, daemon=<span class="literal">True</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;main线程名：<span class="subst">&#123;threading.current_thread().name&#125;</span>, 进程pid：<span class="subst">&#123;os.getpid()&#125;</span>&#x27;</span>)</span><br><span class="line">    t1.start()</span><br><span class="line">    t2.start()</span><br></pre></td></tr></table></figure><h3 id="互斥锁"><a class="markdownIt-Anchor" href="#互斥锁"></a> 互斥锁</h3><p>使用互斥锁要在合适的时机释放，否则可能出现<strong>死锁</strong>（等待对方释放锁，对面不释放）或<strong>锁不住</strong>的情况（2把锁或以上导致互斥失效）。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> threading</span><br><span class="line"></span><br><span class="line"><span class="comment"># 全局变量</span></span><br><span class="line">global_num = <span class="number">0</span></span><br><span class="line"><span class="comment"># 创建互斥锁</span></span><br><span class="line">lock = threading.Lock()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">target_fun1</span>():</span><br><span class="line">    <span class="keyword">global</span> global_num</span><br><span class="line">    lock.acquire()</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1000000</span>):</span><br><span class="line">        global_num += <span class="number">1</span></span><br><span class="line">    lock.release()  <span class="comment"># 如果这里注释，1先抢到线程，就会出现死锁</span></span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;线程1全局变量值：<span class="subst">&#123;global_num&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">target_fun2</span>():</span><br><span class="line">    lock.acquire()</span><br><span class="line">    <span class="keyword">global</span> global_num</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">2000000</span>):</span><br><span class="line">        global_num += <span class="number">1</span></span><br><span class="line">    lock.release()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;线程2全局变量值：<span class="subst">&#123;global_num&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    t1 = threading.Thread(target=target_fun1, name=<span class="string">&#x27;线程1&#x27;</span>)</span><br><span class="line">    t2 = threading.Thread(target=target_fun2, name=<span class="string">&#x27;线程2&#x27;</span>)</span><br><span class="line">    t1.start()</span><br><span class="line">    t2.start()</span><br></pre></td></tr></table></figure><h2 id="迭代器"><a class="markdownIt-Anchor" href="#迭代器"></a> 迭代器</h2><p>Python 中的一种对象，用于数据集合中逐个访问元素，而不需要暴露数据集合的底层实现。适用于支持迭代的数据类型（列表、元组等），range 函数就是一个迭代器。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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 class="comment"># 隐藏底层逻辑，让用户更方便</span></span><br><span class="line"><span class="comment"># 惰性加载，只在需要时才加载数据</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyIterator</span>:</span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, start, end</span>):</span><br><span class="line">        self.current_value = start</span><br><span class="line">        self.end = end</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__iter__</span>(<span class="params">self</span>):  <span class="comment"># 1</span></span><br><span class="line">        <span class="keyword">return</span> self</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__next__</span>(<span class="params">self</span>):  <span class="comment"># 2 实现这2个方法就是迭代器</span></span><br><span class="line">        <span class="keyword">if</span> self.current_value &gt;= self.end:</span><br><span class="line">            <span class="keyword">raise</span> StopIteration  <span class="comment"># 停止迭代</span></span><br><span class="line">        self.current_value += <span class="number">1</span></span><br><span class="line">        <span class="keyword">return</span> self.current_value - <span class="number">1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> MyIterator(<span class="number">1</span>, <span class="number">10</span>):</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line">my_iter = MyIterator(<span class="number">5</span>, <span class="number">15</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_iter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_iter))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_iter))</span><br></pre></td></tr></table></figure><h2 id="生成器"><a class="markdownIt-Anchor" href="#生成器"></a> 生成器</h2><p>基于数据规则，一部分在生成一部分，而不是一下生成完所有，节省大量的内存。推导式写法 | <code>yield</code> 关键字。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 生成1-10的整数</span></span><br><span class="line">my_generator = (i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>))</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">type</span>(my_generator))  <span class="comment"># &lt;class &#x27;generator&#x27;&gt;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> my_generator:</span><br><span class="line">    <span class="built_in">print</span>(i)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成1-10的偶数</span></span><br><span class="line">my_generator = (i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>) <span class="keyword">if</span> i % <span class="number">2</span> == <span class="number">0</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_generator))  <span class="comment"># 2</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_generator))  <span class="comment"># 4</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> my_generator:</span><br><span class="line">    <span class="built_in">print</span>(i)  <span class="comment"># 6 8 10</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 对比列表推导式和生成器的内存占用</span></span><br><span class="line">my_list = [i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10000000</span>)]</span><br><span class="line">my_gt3 = (i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10000000</span>))</span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;mylist内存占用&#x27;</span>, sys.getsizeof(my_list))  <span class="comment"># 89095160</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;mygt3内存占用&#x27;</span>, sys.getsizeof(my_gt3))    <span class="comment"># 104  类似懒汉模式</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># yield</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">my_generator</span>():</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>):</span><br><span class="line">        <span class="keyword">yield</span> i</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">my_generator2</span>():</span><br><span class="line">    <span class="keyword">return</span> [i <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">11</span>)]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">next</span>(my_generator()))</span><br><span class="line"><span class="built_in">print</span>(my_generator2())</span><br></pre></td></tr></table></figure><h1 id="ai应用"><a class="markdownIt-Anchor" href="#ai应用"></a> AI应用</h1><p>提示词工程：</p><ol><li>给大模型设定角色与能力</li><li>明确核心请求与任务</li><li>按步骤拆解复杂任务</li><li>指定风格与语气</li><li>明确要求输出格式</li><li>提供输入输出的实例</li></ol><h2 id="streamlit"><a class="markdownIt-Anchor" href="#streamlit"></a> streamlit</h2><p>用于快速开发 Python 代码构建 web 网页的 py 库。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">streamlit run xxx.py</span><br></pre></td></tr></table></figure><h1 id="爬虫"><a class="markdownIt-Anchor" href="#爬虫"></a> 爬虫</h1><p>网站根目录存放一个 <code>robots.txt</code>，君子协议 robots 协议，告诉爬虫哪些页面可以抓取，哪些不行。</p><p>csv 是一个简单通用的文本文件格式，用来存储表格数据，可以直接使用 excel 打开。格式逗号隔开，命名 <code>xxx.csv</code>，另存为编码 ansi。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">姓名,性别,年龄</span><br><span class="line">小维,男,18</span><br><span class="line">小李,男,12</span><br></pre></td></tr></table></figure><table><thead><tr><th>指令</th><th>值</th><th>说明</th></tr></thead><tbody><tr><td>User-agent</td><td><code>*</code></td><td>适用于所有爬虫</td></tr><tr><td>Disallow</td><td><code>/wp-admin/</code></td><td>禁止访问后台目录</td></tr><tr><td>Allow</td><td><code>/wp-admin/admin-ajax.php</code></td><td>允许异步接口访问</td></tr><tr><td>Sitemap</td><td><code>https://www.tiobe.com/sitemap_index.xml</code></td><td>指定网站地图位置</td></tr><tr><td>Crawl-delay</td><td><code>5</code></td><td>爬取间隔5秒</td></tr></tbody></table><p><a href="https://www.baidu.com/robots.txt">https://www.baidu.com/robots.txt</a> — 全部都不让爬。</p><p><a href="https://www.tiobe.com/robots.txt">https://www.tiobe.com/robots.txt</a> — 不能爬取后台，其他都行。</p><h2 id="xpath"><a class="markdownIt-Anchor" href="#xpath"></a> Xpath</h2><p>用来解析 html、xml，快速定位特定元素、属性或文本，索引从1开始就是第一个标签。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install lxml</span><br></pre></td></tr></table></figure><table><thead><tr><th>表达式</th><th>描述</th><th>样例</th></tr></thead><tbody><tr><td><code>/</code></td><td>从根节点的直接子元素</td><td><code>/html/body/div/h1</code></td></tr><tr><td><code>//</code></td><td>从任意位置选择节点</td><td><code>//h1</code></td></tr><tr><td><code>.</code></td><td>当前节点下查找</td><td><code>./a</code>、<code>./*/a</code></td></tr><tr><td><code>[n]</code></td><td>选择第 n 个元素</td><td><code>//p[2]</code></td></tr><tr><td><code>[last()]</code></td><td>选择最后一个元素</td><td><code>//p[last()]</code> 也能 <code>//p[last()-1]</code></td></tr><tr><td><code>[@attr]</code></td><td>选择有该属性的元素</td><td><code>//p[@color]</code> 或 <code>//p[@class]</code></td></tr><tr><td><code>[@attr='value']</code></td><td>属性值等于指定值</td><td><code>//p[@color='red']</code></td></tr><tr><td><code>*</code></td><td>匹配任何元素节点</td><td><code>//body/div/*</code></td></tr><tr><td><code>@*</code></td><td>匹配元素的任何属性</td><td><code>//body/div/a/@*</code></td></tr><tr><td><code>text()</code></td><td>获取文本内容</td><td><code>//div/p/text()</code></td></tr></tbody></table><h3 id="热门语言榜单"><a class="markdownIt-Anchor" href="#热门语言榜单"></a> 热门语言榜单</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">from</span> lxml <span class="keyword">import</span> html</span><br><span class="line"></span><br><span class="line"><span class="comment"># 先爬取页面，保存到本地，再去本地解析它，避免爬虫被封</span></span><br><span class="line"><span class="comment"># url = &#x27;https://www.tiobe.com/tiobe-index/&#x27;</span></span><br><span class="line"><span class="comment"># response = requests.get(url, headers=&#123;&#x27;User-Agent&#x27;: &#x27;Mozilla/5.0&#x27;&#125;)</span></span><br><span class="line"><span class="comment"># with open(&#x27;./pages/tiobe.html&#x27;, &#x27;w&#x27;, encoding=&#x27;utf-8&#x27;) as f:</span></span><br><span class="line"><span class="comment">#     f.write(response.text)</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./pages/tiobe.html&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    html_text = f.read()</span><br><span class="line">    document = html.fromstring(html_text)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析表头</span></span><br><span class="line">    tb_head = document.xpath(<span class="string">&#x27;//*[@id=&quot;top20&quot;]/thead/tr/th/text()&#x27;</span>)</span><br><span class="line">    tb_head.remove(<span class="string">&#x27;Change&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(tb_head)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./pages/tiobe.csv&#x27;</span>, <span class="string">&#x27;w&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">        f.write(<span class="string">&#x27;,&#x27;</span>.join(tb_head) + <span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># 解析表格</span></span><br><span class="line">    tr_list = document.xpath(<span class="string">&#x27;//table[@id=&quot;top20&quot;]/tbody/tr&#x27;</span>)</span><br><span class="line">    <span class="keyword">for</span> tr <span class="keyword">in</span> tr_list:</span><br><span class="line">        td_list = tr.xpath(<span class="string">&#x27;./td/text()&#x27;</span>)</span><br><span class="line">        <span class="built_in">print</span>(td_list)</span><br><span class="line">        <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./pages/tiobe.csv&#x27;</span>, <span class="string">&#x27;a&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">            f.write(<span class="string">&#x27;,&#x27;</span>.join(td_list) + <span class="string">&#x27;\n&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 推荐用csv模块来操作csv</span></span><br><span class="line"><span class="keyword">import</span> csv</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./pages/demoCsv.csv&#x27;</span>, <span class="string">&#x27;w&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>, newline=<span class="string">&#x27;&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    writer = csv.DictWriter(f, [<span class="string">&#x27;name&#x27;</span>, <span class="string">&#x27;age&#x27;</span>, <span class="string">&#x27;sex&#x27;</span>])</span><br><span class="line">    writer.writeheader()</span><br><span class="line">    writer.writerow(&#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;张三&#x27;</span>, <span class="string">&#x27;age&#x27;</span>: <span class="number">18</span>, <span class="string">&#x27;sex&#x27;</span>: <span class="string">&#x27;男&#x27;</span>&#125;)</span><br><span class="line">    writer.writerow(&#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;李四&#x27;</span>, <span class="string">&#x27;age&#x27;</span>: <span class="number">28</span>, <span class="string">&#x27;sex&#x27;</span>: <span class="string">&#x27;男&#x27;</span>&#125;)</span><br><span class="line">    writer.writerow(&#123;<span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;王五&#x27;</span>, <span class="string">&#x27;age&#x27;</span>: <span class="number">48</span>, <span class="string">&#x27;sex&#x27;</span>: <span class="string">&#x27;男&#x27;</span>&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&#x27;./pages/demoCsv.csv&#x27;</span>, <span class="string">&#x27;r&#x27;</span>, encoding=<span class="string">&#x27;utf-8&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    reader = csv.DictReader(f)</span><br><span class="line">    <span class="keyword">for</span> row <span class="keyword">in</span> reader:</span><br><span class="line">        <span class="built_in">print</span>(row)</span><br></pre></td></tr></table></figure><h3 id="高分电影top100"><a class="markdownIt-Anchor" href="#高分电影top100"></a> 高分电影top100</h3><p><a href="https://www.themoviedb.org/robots.txt">https://www.themoviedb.org/robots.txt</a> — 发现列举的 agent 是不让爬的，个人可以。</p><h1 id="数据分析"><a class="markdownIt-Anchor" href="#数据分析"></a> 数据分析</h1><p><strong>数据收集</strong> -&gt; <strong>数据清洗处理</strong> -&gt; <strong>数据分析</strong> -&gt; <strong>数据可视化</strong></p><p>Pandas：订单号一样需去重，处理缺失值 NaN，处理异常值（单价是负的），日期格式一致性。</p><h2 id="pandas"><a class="markdownIt-Anchor" href="#pandas"></a> Pandas</h2><p>核心 DataFrame（类似表格）和 Series（示例：Name列）。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pandas==<span class="number">2.2</span><span class="number">.2</span></span><br></pre></td></tr></table></figure><table><thead><tr><th style="text-align:right">index</th><th>Name</th><th style="text-align:right">Age</th><th>Sex</th></tr></thead><tbody><tr><td style="text-align:right">0</td><td>Jay</td><td style="text-align:right">18</td><td>male</td></tr><tr><td style="text-align:right">1</td><td>Leo</td><td style="text-align:right">22</td><td>male</td></tr><tr><td style="text-align:right">2</td><td>Lily</td><td style="text-align:right">25</td><td>female</td></tr><tr><td style="text-align:right">3</td><td>Jerry</td><td style="text-align:right">19</td><td>male</td></tr><tr><td style="text-align:right">4</td><td>Cici</td><td style="text-align:right">21</td><td>female</td></tr></tbody></table><h2 id="matplotlib"><a class="markdownIt-Anchor" href="#matplotlib"></a> Matplotlib</h2><p>用于 Python 创建静态、动画和交互式可视化。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install matplotlib==<span class="number">3.9</span><span class="number">.2</span></span><br></pre></td></tr></table></figure><h1 id="fastapi"><a class="markdownIt-Anchor" href="#fastapi"></a> FastAPI</h1><p>现代、快速、高性能的 Python web 框架，用来搭建 api 服务接口。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> fastapi <span class="keyword">import</span> FastAPI</span><br><span class="line">app = FastAPI()</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.get(<span class="params"><span class="string">&#x27;/&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">index</span>():</span><br><span class="line">    <span class="keyword">return</span> &#123;<span class="string">&#x27;message&#x27;</span>: <span class="string">&#x27;hello world&#x27;</span>&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.get(<span class="params"><span class="string">&#x27;/user&#x27;</span></span>)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">user</span>():</span><br><span class="line">    <span class="keyword">return</span> [&#123;<span class="string">&#x27;id&#x27;</span>: <span class="number">1</span>, <span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;lucky&#x27;</span>&#125;, &#123;<span class="string">&#x27;id&#x27;</span>: <span class="number">2</span>, <span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;lucky2&#x27;</span>&#125;, &#123;<span class="string">&#x27;id&#x27;</span>: <span class="number">3</span>, <span class="string">&#x27;name&#x27;</span>: <span class="string">&#x27;lucky3&#x27;</span>&#125;]</span><br></pre></td></tr></table></figure><p>运行方式2种：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 方式1：命令行</span></span><br><span class="line">fastapi dev .\fastapi入门.py</span><br><span class="line"></span><br><span class="line"><span class="comment"># 方式2：代码中直接运行</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="keyword">import</span> uvicorn</span><br><span class="line">    uvicorn.run(app, host=<span class="string">&quot;127.0.0.1&quot;</span>, port=<span class="number">8000</span>)</span><br></pre></td></tr></table></figure><p><strong>REST 风格</strong>：URL 定义资源，动词描述操作。</p><table><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td>GET</td><td>查询</td></tr><tr><td>POST</td><td>新增</td></tr><tr><td>PUT</td><td>修改</td></tr><tr><td>DELETE</td><td>删除</td></tr></tbody></table>]]></content>
    
    
    <summary type="html">海阔凭鱼跃，天高任鸟飞</summary>
    
    
    
    <category term="人工智能" scheme="https://luckynwa.top/categories/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/"/>
    
    
    <category term="Python" scheme="https://luckynwa.top/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>图床搭建与 CDN 加速指南</title>
    <link href="https://luckynwa.top/posts/website_construction3/"/>
    <id>https://luckynwa.top/posts/website_construction3/</id>
    <published>2024-01-14T23:44:29.000Z</published>
    <updated>2026-07-07T16:20:55.812Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h1><p>本章节讲解图床的搭建、管理图片工具以及如何访问图片。</p><h1 id="github-图床"><a class="markdownIt-Anchor" href="#github-图床"></a> GitHub 图床</h1><h2 id="创建仓库"><a class="markdownIt-Anchor" href="#创建仓库"></a> 创建仓库</h2><ol><li>在 GitHub 创建一个仓库，记得勾选<strong>公开</strong>和 <strong>md 文档</strong></li><li>访问 <a href="https://github.com/settings/apps">https://github.com/settings/apps</a></li><li>点击 <strong>Personal access tokens</strong> → <strong>Tokens</strong> → <strong>New personal access token (classic)</strong></li><li>时间选择<strong>永久过期</strong>，勾选 <code>repo</code> 再生成</li><li>保存好 token 等会用</li></ol><blockquote><p>💡 也可以将这个仓库同步到 Vercel，再配置一个二级域名进行访问</p></blockquote><h1 id="picgo"><a class="markdownIt-Anchor" href="#picgo"></a> PicGo</h1><p>管理上传的图片工具，结合 Typora 使用。</p><ul><li><strong>下载地址：</strong> <a href="https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.1">https://github.com/Molunerfinn/PicGo/releases/tag/v2.3.1</a></li></ul><p>下载并启用，如果不能启动，右键勾起兼容模式，管理员身份启动。</p><h2 id="配置"><a class="markdownIt-Anchor" href="#配置"></a> 配置</h2><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa6/lucky-pic-bed@main/img/20240630112936.png" alt="PicGo配置" /></p><p>配置示例：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">仓库名：luckyNwa/lucky-pic-bed</span><br><span class="line">分支：main</span><br><span class="line">路径：img/</span><br><span class="line">自定义域名：https://cdn.jsdelivr.net/gh/luckyNwa/lucky-pic-bed@main</span><br></pre></td></tr></table></figure><h2 id="注意事项"><a class="markdownIt-Anchor" href="#注意事项"></a> 注意事项</h2><ul><li><strong>自定义域名格式：</strong> <code>https://cdn.jsdelivr.net/gh/[GitHub用户名]/[仓库名]@main</code></li><li><strong>分支必须填 <code>@main</code></strong>，否则默认使用 master 分支，会导致图片上传失败</li><li><strong>picgo-server 端口：</strong> PicGo 设置 → 设置 Server → <code>36677</code></li><li><strong>仓库大小限制：</strong> GitHub 图床仓库大小不能超过 1G，超过后会有人工审核，轻则删库重则封号</li></ul><h1 id="typora"><a class="markdownIt-Anchor" href="#typora"></a> Typora</h1><p>Typora 支持粘贴或拖入图片时自动上传到图床，这里用了脚本将图片传到自己的服务器。</p><h2 id="配置步骤"><a class="markdownIt-Anchor" href="#配置步骤"></a> 配置步骤</h2><ol><li>打开 <code>文件</code> → <code>偏好设置</code> → <code>图像</code></li><li><strong>上传服务</strong> 选择 <code>Custom Command</code></li><li><strong>命令</strong> 填写上传脚本路径：</li></ol><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">D:\workspace\java\lucky-admin2\lucky-api-v2\bin\upload_prod.bat</span><br></pre></td></tr></table></figure><blockquote><p>💡 配置完成后，插入图片时会自动调用脚本上传并返回图床链接，无需手动处理图片托管。</p></blockquote><h1 id="npm-图床"><a class="markdownIt-Anchor" href="#npm-图床"></a> npm 图床</h1><p>采用提交到 GitHub，让 GitHub Actions 自动打包到 npm，通过加速访问 npm 里的资源。</p><h2 id="注册与登录"><a class="markdownIt-Anchor" href="#注册与登录"></a> 注册与登录</h2><ol><li>去 <a href="https://www.npmjs.com/">npm 官网</a> 注册账号并绑定邮箱</li><li>拉取上面 GitHub 仓库，进入根目录，CMD 执行：</li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm config set registry https://registry.npmjs.org</span><br><span class="line">npm adduser   # 仅第一次使用需要添加用户，浏览器验证</span><br><span class="line">npm login     # 非第一次使用直接登录即可，浏览器验证</span><br></pre></td></tr></table></figure><h2 id="初始化与发布"><a class="markdownIt-Anchor" href="#初始化与发布"></a> 初始化与发布</h2><p>运行 npm 初始化指令，把整个图床仓库打包，按照指示进行配置。</p><blockquote><p>⚠️ 需要事先确认包名没有和别人已发布的包重复，可以在 npm 官网搜索，搜不到说明还没被占用。</p></blockquote><figure class="highlight shell"><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">npm init      # 绑定 npm 仓库，配置唯一包名、版本、作者名</span><br><span class="line">npm publish   # 提交</span><br></pre></td></tr></table></figure><p><img src="https://cdn.jsdelivr.net/gh/luckyNwa6/lucky-pic-bed@main/img/bedConfig.jpg" alt="npm配置" /></p><h2 id="github-actions-自动发布"><a class="markdownIt-Anchor" href="#github-actions-自动发布"></a> GitHub Actions 自动发布</h2><p>每次本地 <code>npm publish</code> 需要架梯子且耗时，交给 GitHub Actions 自动完成。</p><h3 id="1-获取-npm-token"><a class="markdownIt-Anchor" href="#1-获取-npm-token"></a> 1. 获取 npm Token</h3><p>npm 官网 → 头像 → Access Tokens → Generate New Token → 勾选 <strong>Automation</strong></p><blockquote><p>💡 Token 只会显示这一次，务必保存好</p></blockquote><h3 id="2-配置-github-secrets"><a class="markdownIt-Anchor" href="#2-配置-github-secrets"></a> 2. 配置 GitHub Secrets</h3><p>在 GitHub 图床仓库设置项里添加一个名为 <code>NPM_TOKEN</code> 的 secrets，把 npm 的 Access Token 输入进去。</p><h3 id="3-添加-github-actions"><a class="markdownIt-Anchor" href="#3-添加-github-actions"></a> 3. 添加 GitHub Actions</h3><p>新增文件 <code>.github/workflows/autopublish.yml</code>：</p><figure class="highlight yml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Node.js</span> <span class="string">Package</span></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="attr">branches:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">main</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">publish-npm:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/setup-node@v1</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">node-version:</span> <span class="string">&#x27;12.x&#x27;</span></span><br><span class="line">          <span class="attr">registry-url:</span> <span class="string">https://registry.npmjs.org/</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">run:</span> <span class="string">npm</span> <span class="string">publish</span></span><br><span class="line">        <span class="attr">env:</span></span><br><span class="line">          <span class="attr">NODE_AUTH_TOKEN:</span> <span class="string">$&#123;&#123;secrets.npm_token&#125;&#125;</span></span><br></pre></td></tr></table></figure><h3 id="4-更新与提交"><a class="markdownIt-Anchor" href="#4-更新与提交"></a> 4. 更新与提交</h3><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">将更改提交</span></span><br><span class="line">git add .</span><br><span class="line">git commit -m &quot;npm publish&quot;</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">更新 package 版本号</span></span><br><span class="line">npm version patch</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">推送至 GitHub 触发 action</span></span><br><span class="line">git push</span><br></pre></td></tr></table></figure><blockquote><p>⚠️ 此处四行指令顺序严格。每次更新 npm 图床都需要先修改 <code>package.json</code> 里的 version。<code>npm version patch</code> 会将末尾版本号 +1（如 0.0.1 → 0.0.2）。大版本更新还是需要手动改的。</p></blockquote><h1 id="cloudflare-图床"><a class="markdownIt-Anchor" href="#cloudflare-图床"></a> Cloudflare 图床</h1><p>先去GitHub上fork，<a href="https://github.com/MarSeventh/CloudFlare-ImgBed">https://github.com/MarSeventh/CloudFlare-ImgBed</a></p><p>再去<a href="https://dash.cloudflare.com/">Cloudflare 官网</a> 用luckywei015@gmail.com|1656213092@qq.com登录，密码N…@</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/06/image-20260706173327016_20260706173328A001.png" alt="image-20260706173327016" /></p><p>开始使用，导入现有Git存储库，开始使用，连接GitHub</p><p>(1)找到 <strong>Pages</strong> → 创建 → 连接到 GitHub</p><p>(2)登录发现往下看，可以选择仓库，选刚刚fork过来的那个</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">npm install      构建命令</span><br><span class="line"></span><br><span class="line">frontend-dist    输出目录</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/2026/07/06/image-20260706173927373_20260706173928A002.png" alt="image-20260706173927373" /></p><p>保存并部署</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/06/image-20260706174132156_20260706174132A003.png" alt="image-20260706174132156" /></p><p>命名空间：cloud</p><p>再去worker 和pages下找到项目里的设置，去绑定这个kv空间</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/06/image-20260706174355941_20260706174356A004.png" alt="image-20260706174355941" /></p><p>变量名：img_url (必须是这个)</p><p>再去部署—&gt;最下面下面…，重新部署</p><p>再去存储和数据库那，点击R2存储里概述，闲鱼买了个邮箱转移的，不然没卡绑定</p><p>桶名字：cloud 创建</p><p>再去和绑定kv一样，绑定–&gt;添加，R2，变量名：cloudR2</p><p>重新部署，等待部署完，点击域名查看</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/06/image-20260706194341275_20260706194343A005.png" alt="image-20260706194341275" /></p><p>上传不了，服了，还是用java弄一个吧，集成到自己的后台管理系统里</p><p>R2对象存储的 跨域策略：</p><figure class="highlight json"><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="punctuation">[</span></span><br><span class="line">  <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;AllowedOrigins&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;*&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;AllowedMethods&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;GET&quot;</span><span class="punctuation">,</span> <span class="string">&quot;PUT&quot;</span><span class="punctuation">,</span> <span class="string">&quot;HEAD&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;AllowedHeaders&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;*&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;MaxAgeSeconds&quot;</span><span class="punctuation">:</span> <span class="number">3600</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">]</span></span><br></pre></td></tr></table></figure><p>安全性<br />└── 安全规则</p><p>创建规则：非中国访问观察</p><p>表达式</p><figure class="highlight json"><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">(ip.geoip.country ne <span class="string">&quot;CN&quot;</span> and not http.host in <span class="punctuation">&#123;</span></span><br><span class="line"><span class="string">&quot;nextchat.luckynwa.top&quot;</span></span><br><span class="line"><span class="string">&quot;tw.luckynwa.top&quot;</span></span><br><span class="line"><span class="string">&quot;lobechat.luckynwa.top&quot;</span></span><br><span class="line"><span class="string">&quot;calendar.luckynwa.top&quot;</span></span><br><span class="line"><span class="string">&quot;imgs.luckynwa.top&quot;</span></span><br><span class="line"><span class="string">&quot;imgs.luckynwa.top&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span>)</span><br></pre></td></tr></table></figure><p>外国人访问要走机器人认证</p><h1 id="回源加速"><a class="markdownIt-Anchor" href="#回源加速"></a> 回源加速</h1><p>提交完就可以访问了，国内有 CDN 加速访问 <a href="https://www.jsdelivr.com/">jsdelivr 官网</a></p><h2 id="jsdelivr-npm"><a class="markdownIt-Anchor" href="#jsdelivr-npm"></a> jsdelivr + npm</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/npm/lucky-img/img/lucky675.png</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></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/npm/lucky-img@1.0.0/img/lucky675.png</span><br></pre></td></tr></table></figure><h2 id="jsdelivr-github"><a class="markdownIt-Anchor" href="#jsdelivr-github"></a> jsdelivr + GitHub</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdn.jsdelivr.net/gh/luckyNwa6/lucky-pic-bed@main/pic/Somewhere.jpg</span><br></pre></td></tr></table></figure><h2 id="unpkg-回源-npm"><a class="markdownIt-Anchor" href="#unpkg-回源-npm"></a> unpkg 回源 npm</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://unpkg.com/lucky-img@1.0.0/pic/Somewhere.jpg</span><br></pre></td></tr></table></figure><h2 id="其他-cdn-回源"><a class="markdownIt-Anchor" href="#其他-cdn-回源"></a> 其他 CDN 回源</h2><table><thead><tr><th>CDN</th><th>格式</th><th>说明</th></tr></thead><tbody><tr><td><strong><a href="http://npm.onmicrosoft.cn">npm.onmicrosoft.cn</a></strong></td><td><code>https://npm.onmicrosoft.cn/:package@:version/:file</code></td><td>推荐使用</td></tr><tr><td><strong><a href="http://npm.elemecdn.com">npm.elemecdn.com</a></strong></td><td><code>https://npm.elemecdn.com/:package@:version/:file</code></td><td>百度出品，网宿国内节点</td></tr><tr><td><strong><a href="http://code.bdstatic.com">code.bdstatic.com</a></strong></td><td><code>https://code.bdstatic.com/npm/:package@:version/:file</code></td><td>饿了么出品，网宿国内节点</td></tr><tr><td><strong><a href="http://unpkg.com">unpkg.com</a></strong></td><td><code>https://unpkg.com/:package@:version/:file</code></td><td>香港节点</td></tr></tbody></table><blockquote><p>⚠️ Cloudflare Pages 回源在国内访问不稳定，推荐使用 <code>npm.onmicrosoft.cn</code> 回源。</p></blockquote><h2 id="效果展示"><a class="markdownIt-Anchor" href="#效果展示"></a> 效果展示</h2><p><img src="https://cdn.jsdelivr.net/npm/lucky-img/pic/Somewhere.jpg" alt="效果" /></p>]]></content>
    
    
    <summary type="html">咬定青山不放松，立根原在破岩中</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>Vue静态网站生成器：VitePress与VuePress实战指南</title>
    <link href="https://luckynwa.top/posts/tool223S/"/>
    <id>https://luckynwa.top/posts/tool223S/</id>
    <published>2024-01-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:20:55.590Z</updated>
    
    <content type="html"><![CDATA[<h1 id="vitepress"><a class="markdownIt-Anchor" href="#vitepress"></a> VitePress</h1><h2 id="介绍"><a class="markdownIt-Anchor" href="#介绍"></a> 介绍</h2><p>VitePress是Vue.js驱动的静态网站生成器。</p><p><strong>环境要求：</strong> 最少Node.js v18.16.1版本</p><blockquote><p>node安装与配置看我的其他文章</p></blockquote><h2 id="安装配置"><a class="markdownIt-Anchor" href="#安装配置"></a> 安装配置</h2><ol><li>新建一个文件夹叫VitePress，cmd打开后输入：</li></ol><figure class="highlight shell"><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">pnpm add -D vitepress</span><br><span class="line">pnpm vitepress init</span><br></pre></td></tr></table></figure><ol start="2"><li>其他配置查看本仓库项目和官网进行2次配置</li></ol><p><strong>参考链接：</strong></p><ul><li>官网：<a href="https://vitepress.dev/reference/default-theme-home-page">https://vitepress.dev/reference/default-theme-home-page</a></li></ul><p>用来部署静态博客或者前端文档很不错</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705154825453_20260705154826A015.png" alt="image-20260705154825453" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705154917198_20260705154917A016.png" alt="image-20260705154917198" /></p><h1 id="vuepress"><a class="markdownIt-Anchor" href="#vuepress"></a> VuePress</h1><h2 id="介绍-2"><a class="markdownIt-Anchor" href="#介绍-2"></a> 介绍</h2><p>VuePress是Vue.js驱动的静态网站生成器。</p><p><strong>环境要求：</strong> 最少Node.js v16.14版本</p><blockquote><p>node安装与配置看别的文章</p></blockquote><h2 id="安装配置-2"><a class="markdownIt-Anchor" href="#安装配置-2"></a> 安装配置</h2><ol><li>新建一个文件夹叫vuepress，cmd打开后输入：</li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">pnpm init    对包管理器进行初始化</span><br><span class="line">pnpm add -D vuepress   安装vuepress的本地依赖</span><br><span class="line"></span><br><span class="line">mkdir docs &amp;&amp; echo &#x27;# Hello VuePress&#x27; &gt; docs/README.md  创建你的第一篇文档</span><br></pre></td></tr></table></figure><ol start="2"><li>在package.json里修改成下面的：</li></ol><figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;lucky&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;main&quot;</span><span class="punctuation">:</span> <span class="string">&quot;index.js&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;docs:dev&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vuepress dev docs&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;docs:build&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vuepress build docs&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;keywords&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;license&quot;</span><span class="punctuation">:</span> <span class="string">&quot;ISC&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;devDependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;vuepress&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.9.9&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><ol start="3"><li>在本地服务器启动：</li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pnpm docs:dev</span><br></pre></td></tr></table></figure><p>可以搭建公司的UI组件库</p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705152448812_20260705152449A014.png" alt="image-20260705152448812" /></p><p><img src="https://cloud.luckynwa.top/profile/2026/07/05/image-20260705152353176_20260705152353A013.png" alt="image-20260705152353176" /></p><h2 id="常见问题"><a class="markdownIt-Anchor" href="#常见问题"></a> 常见问题</h2><p><strong>无法启动解决方案：</strong></p><p>正常Node.js 16版本就不会有问题的，如果遇到启动失败，尝试以下命令：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set NODE_OPTIONS=--openssl-legacy-provider &amp;&amp; vuepress dev docs</span><br></pre></td></tr></table></figure><p>配置放入启动那也行，一般是node版本太低了。</p><p><strong>VSCode中pnpm运行问题：</strong></p><p>如果VSCode不能运行pnpm，去管理员终端运行这个：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">set-ExecutionPolicy RemoteSigned</span><br></pre></td></tr></table></figure><h2 id="访问地址"><a class="markdownIt-Anchor" href="#访问地址"></a> 访问地址</h2><p>启动成功后访问：<a href="http://localhost:8080/">http://localhost:8080/</a></p>]]></content>
    
    
    <summary type="html">工欲善其事，必先利其器</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Vue" scheme="https://luckynwa.top/tags/Vue/"/>
    
  </entry>
  
  <entry>
    <title>Java进阶知识点速查</title>
    <link href="https://luckynwa.top/posts/jav56222/"/>
    <id>https://luckynwa.top/posts/jav56222/</id>
    <published>2024-01-01T03:22:21.000Z</published>
    <updated>2026-07-07T16:20:55.675Z</updated>
    
    <content type="html"><![CDATA[<h2 id="一-数据结构"><a class="markdownIt-Anchor" href="#一-数据结构"></a> 一、数据结构</h2><p>Java 的 <code>java.util</code> 包中提供了许多数据结构的实现，配合集合框架进行理解。</p><h3 id="q1java-中常见的数据结构有哪些"><a class="markdownIt-Anchor" href="#q1java-中常见的数据结构有哪些"></a> Q1：Java 中常见的数据结构有哪些？</h3><ul><li><p><strong>数组（Array）</strong>：固定大小，存储相同类型的元素，需要一块连续的内存空间来存储元素，而这块内存空间的大小是根据元素类型确定的。随机访问时具有高效性（连续的内存空间 O(1) 的时间复杂度内访问任何元素；预先计算索引，无需遍历；现代计算机体系结构中的缓存系统通常会以缓存行为单位，访问一个元素时候很可能获取相邻的元素，提高了访问效率）</p></li><li><p><strong>列表（List）</strong>：动态数组，可变大小，如 ArrayList 和 LinkedList</p></li><li><p><strong>集合（Set）</strong>：用于存储不重复的元素，常见的实现有 HashSet 和 TreeSet</p></li><li><p><strong>映射（Map）</strong>：用于存储键值对，常见的实现有 HashMap 和 TreeMap</p></li><li><p><strong>栈（Stack）</strong>：后进先出（LIFO）的数据结构，只允许在栈顶进行插入和删除操作</p></li><li><p><strong>队列（Queue）</strong>：先进先出（FIFO）的数据结构，可以在队尾进行插入操作，在队首进行删除操作。Java 提供了 Queue 接口以及其实现类，如 LinkedList 和 PriorityQueue</p></li><li><p><strong>树（Tree）</strong>：层次结构的数据结构，由节点和边组成。Java 提供了多种树的实现，如二叉树、红黑树等</p></li><li><p><strong>图（Graph）</strong>：由节点和边组成的非线性数据结构，用于表示元素之间的关系。Java 提供了图的实现，如有向图和无向图</p></li></ul><h3 id="q2arraylist-和-linkedlist-的区别"><a class="markdownIt-Anchor" href="#q2arraylist-和-linkedlist-的区别"></a> Q2：ArrayList 和 LinkedList 的区别？</h3><p><strong>ArrayList：</strong></p><ul><li><strong>特点：</strong> 动态数组，可变大小</li><li><strong>优点：</strong> 高效的随机访问和快速尾部插入</li><li><strong>缺点：</strong> 中间插入和删除相对较慢</li></ul><p><strong>LinkedList：</strong></p><ul><li><strong>特点：</strong> 双向链表，元素之间通过指针连接</li><li><strong>优点：</strong> 插入和删除元素高效，迭代器性能好</li><li><strong>缺点：</strong> 随机访问相对较慢</li></ul><h3 id="q3hashset-和-treeset-的区别"><a class="markdownIt-Anchor" href="#q3hashset-和-treeset-的区别"></a> Q3：HashSet 和 TreeSet 的区别？</h3><figure class="highlight java"><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">Set&lt;String&gt; hashSet = <span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;();</span><br><span class="line">Set&lt;Integer&gt; treeSet = <span class="keyword">new</span> <span class="title class_">TreeSet</span>&lt;&gt;();</span><br></pre></td></tr></table></figure><p><strong>HashSet：</strong></p><ul><li><strong>特点：</strong> 无序集合，基于 HashMap 实现</li><li><strong>优点：</strong> 高效的查找和插入操作</li><li><strong>缺点：</strong> 不保证顺序</li></ul><p><strong>TreeSet：</strong></p><ul><li><strong>特点：</strong> 有序集合，底层基于红黑树实现，不允许重复元素</li><li><strong>优点：</strong> 提供自动排序功能，适用于需要按顺序存储元素的场景</li><li><strong>缺点：</strong> 性能相对较差，不允许插入 null 元素</li></ul><h3 id="q4hashmap-和-treemap-的区别"><a class="markdownIt-Anchor" href="#q4hashmap-和-treemap-的区别"></a> Q4：HashMap 和 TreeMap 的区别？</h3><figure class="highlight java"><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">Map&lt;String, Integer&gt; hashMap = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">Map&lt;String, Integer&gt; treeMap = <span class="keyword">new</span> <span class="title class_">TreeMap</span>&lt;&gt;();</span><br></pre></td></tr></table></figure><p><strong>HashMap：</strong></p><ul><li><strong>特点：</strong> 基于哈希表实现的键值对存储结构</li><li><strong>优点：</strong> 高效的查找、插入和删除操作</li><li><strong>缺点：</strong> 无序，不保证顺序</li></ul><p><strong>TreeMap：</strong></p><ul><li><strong>特点：</strong> 基于红黑树实现的有序键值对存储结构</li><li><strong>优点：</strong> 有序，支持按照键的顺序遍历</li><li><strong>缺点：</strong> 插入和删除相对较慢</li></ul><h3 id="q5什么是栈stack有什么特点"><a class="markdownIt-Anchor" href="#q5什么是栈stack有什么特点"></a> Q5：什么是栈（Stack）？有什么特点？</h3><p>栈（Stack）是一种线性数据结构，它按照后进先出（Last In, First Out，LIFO）的原则管理元素。在栈中，新元素被添加到栈的顶部，而只能从栈的顶部移除元素。这就意味着最后添加的元素是第一个被移除的。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Stack&lt;Integer&gt; stack = <span class="keyword">new</span> <span class="title class_">Stack</span>&lt;&gt;();</span><br></pre></td></tr></table></figure><h3 id="q6什么是堆heap"><a class="markdownIt-Anchor" href="#q6什么是堆heap"></a> Q6：什么是堆（Heap）？</h3><p>堆（Heap）是优先队列的基础，可以实现最大堆和最小堆。</p><figure class="highlight java"><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">PriorityQueue&lt;Integer&gt; minHeap = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;();</span><br><span class="line">PriorityQueue&lt;Integer&gt; maxHeap = <span class="keyword">new</span> <span class="title class_">PriorityQueue</span>&lt;&gt;(Collections.reverseOrder());</span><br></pre></td></tr></table></figure><h3 id="q7treenode-的基本结构是什么"><a class="markdownIt-Anchor" href="#q7treenode-的基本结构是什么"></a> Q7：TreeNode 的基本结构是什么？</h3><p>Java 提供了 TreeNode 类型，可以用于构建二叉树等数据结构。</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="keyword">class</span> <span class="title class_">TreeNode</span> &#123;</span><br><span class="line">    <span class="type">int</span> val;</span><br><span class="line">    TreeNode left;</span><br><span class="line">    TreeNode right;</span><br><span class="line">    TreeNode(<span class="type">int</span> x) &#123; val = x; &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="二-集合框架"><a class="markdownIt-Anchor" href="#二-集合框架"></a> 二、集合框架</h2><h3 id="q8java-集合框架的体系结构是怎样的"><a class="markdownIt-Anchor" href="#q8java-集合框架的体系结构是怎样的"></a> Q8：Java 集合框架的体系结构是怎样的？</h3><p>整个集合框架围绕一组标准接口而设计。你可以直接使用这些接口的标准实现，诸如 <code>LinkedList</code>、<code>HashSet</code> 和 <code>TreeSet</code> 等。</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java10.png" alt="" /></p><p><strong>Collection</strong> 接口有 3 种子类型，List、Set 和 Queue，再下面是一些抽象类，最后是具体实现类，常用的有 <code>ArrayList</code>、<code>LinkedList</code>、<code>HashSet</code>、<code>LinkedHashSet</code>、<code>HashMap</code>、<code>LinkedHashMap</code> 等。</p><ul><li><strong>接口：</strong> 是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口，是为了以不同的方式操作集合对象</li><li><strong>实现（类）：</strong> 是集合接口的具体实现。从本质上讲，它们是可重复使用的数据结构，例如：ArrayList、LinkedList、HashSet、HashMap</li><li><strong>算法：</strong> 是实现集合接口的对象里的方法执行的一些有用的计算，例如：搜索和排序，这些算法实现了多态，那是因为相同的方法可以在相似的接口上有着不同的实现</li></ul><h3 id="q9collections-和-collection-有什么区别"><a class="markdownIt-Anchor" href="#q9collections-和-collection-有什么区别"></a> Q9：Collections 和 Collection 有什么区别？</h3><ul><li><strong>Collection</strong> 是集合接口，List、Set、Queue 都继承自它</li><li><strong>Collections</strong> 是工具类，提供了对集合进行排序、遍历等各种算法实现</li></ul><h2 id="三-日志"><a class="markdownIt-Anchor" href="#三-日志"></a> 三、日志</h2><h3 id="q10springboot-默认的日志组合是什么"><a class="markdownIt-Anchor" href="#q10springboot-默认的日志组合是什么"></a> Q10：SpringBoot 默认的日志组合是什么？</h3><p><strong>SpringBoot 默认 SLF4J + LogBack 的组合。</strong></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LuckyTest</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">Logger</span> <span class="variable">logger</span> <span class="operator">=</span> Logger.getLogger(Main.class.getName());</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="comment">// 设置日志级别为 SEVERE，只输出比警告级别更严重的日志消息</span></span><br><span class="line">        logger.setLevel(Level.SEVERE);</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 输出不同级别的日志消息</span></span><br><span class="line">        logger.severe(<span class="string">&quot;This is a severe message.&quot;</span>);   <span class="comment">// 输出</span></span><br><span class="line">        logger.warning(<span class="string">&quot;This is a warning message.&quot;</span>); <span class="comment">// 不输出</span></span><br><span class="line">        logger.info(<span class="string">&quot;This is an info message.&quot;</span>);       <span class="comment">// 不输出</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="q11如何通过-yml-配置日志生成到本地"><a class="markdownIt-Anchor" href="#q11如何通过-yml-配置日志生成到本地"></a> Q11：如何通过 Yml 配置日志生成到本地？</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></pre></td><td class="code"><pre><span class="line"><span class="attr">logging:</span></span><br><span class="line">  <span class="attr">file:</span> <span class="string">D:/lucky.log</span> <span class="comment"># 不指定的情况下默认生成在项目根目录，按照配置生成所需的日志名称</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">output/logs</span> <span class="comment"># 按照默认的名称spring.log，生成到指定路径及日志。</span></span><br></pre></td></tr></table></figure><h2 id="四-jvm"><a class="markdownIt-Anchor" href="#四-jvm"></a> 四、JVM</h2><h3 id="q12jvm-中堆与栈的区别"><a class="markdownIt-Anchor" href="#q12jvm-中堆与栈的区别"></a> Q12：JVM 中堆与栈的区别？</h3><ul><li><strong>寄存器：</strong> 最快的存储区，由编译器根据需求进行分配，我们在程序中无法控制</li><li><strong>栈：</strong> 存放基本类型的变量数据和对象的引用，对象本身不存放在栈中，而存放在堆（new 出来的对象）或者常量池中（字符串常量存放在常量池中）</li><li><strong>堆：</strong> 存放所有 new 出来的对象</li><li><strong>静态域（属于方法区）：</strong> 存放静态成员（static 定义的）</li><li><strong>常量池（属于方法区）：</strong> 存放字符串常量和基本类型常量（public static final）</li><li><strong>非 RAM 存储：</strong> 硬盘等永久存储空间</li></ul><p>普通数据类型里的变量名放在栈里面，数据放堆里面。</p><h2 id="五-字节与数据库"><a class="markdownIt-Anchor" href="#五-字节与数据库"></a> 五、字节与数据库</h2><h3 id="q13字节和位的关系是什么"><a class="markdownIt-Anchor" href="#q13字节和位的关系是什么"></a> Q13：字节和位的关系是什么？</h3><p>1 字节（byte）= 8 位（bit）。数据存储是以字节为单位，数据传输大多是以位为单位。</p><h3 id="q14mysql-中-int-类型的长度是多少"><a class="markdownIt-Anchor" href="#q14mysql-中-int-类型的长度是多少"></a> Q14：MySQL 中 int 类型的长度是多少？</h3><p>int 永远是 4 字节也就是 32 位，TINYINT 是 1 字节。int 存储数值的范围是：-2^31 至 2^31-1（即 -2147483648 至 2147483647 之间的所有正负整数），所以 int 是不需要指定长度的。</p><p>varchar 里的长度是字节也是最大字节，会自适应实际的长度。正常一个汉字占 2 个字节可能是 4，一个字母占 1 字节不分大小写。</p><h3 id="q15sql-的基本操作有哪些"><a class="markdownIt-Anchor" href="#q15sql-的基本操作有哪些"></a> Q15：SQL 的基本操作有哪些？</h3><figure class="highlight sql"><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"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> 表名 <span class="keyword">WHERE</span> 条件</span><br><span class="line"><span class="comment">-- 删</span></span><br><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> 表名 <span class="keyword">WHERE</span> 条件</span><br><span class="line"><span class="comment">-- 改</span></span><br><span class="line"><span class="keyword">UPDATE</span> 表名 <span class="keyword">SET</span> 字段<span class="number">1</span><span class="operator">=</span>对应值<span class="number">1</span>,..  <span class="keyword">WHERE</span> 条件</span><br><span class="line"><span class="comment">-- 增</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> 表名(字段<span class="number">1</span>,字段<span class="number">2.</span>.) <span class="keyword">VALUES</span>(对应值<span class="number">1</span>,对应值<span class="number">2.</span>..)</span><br></pre></td></tr></table></figure><p>查和删不加条件，则全部查找、删除；增也可以不加字段，直接 values 对应上值也行，而且也可以插入多条，直接 values 后面再逗号继续插入值。多表查的时候有共同的字段，需要声明一下是哪个表里面的。MySQL 里运行不区分大小写，尽量都大写。</p><p><code>HAVING</code> 是分组之后加的条件。</p><h3 id="q16数据库有哪些分类"><a class="markdownIt-Anchor" href="#q16数据库有哪些分类"></a> Q16：数据库有哪些分类？</h3><ul><li><strong>关系型数据库</strong>（表格的方式，表和表的关系）：MySQL、Oracle</li><li><strong>对象数据库</strong>：SE</li><li><strong>键值对数据库</strong>：Redis、HBase、Hadoop</li></ul><p>按数据容量分类：大（Oracle）、中（MySQL）、小（Excel、Access、SQLite）</p><h3 id="q17sql-的分类有哪些"><a class="markdownIt-Anchor" href="#q17sql-的分类有哪些"></a> Q17：SQL 的分类有哪些？</h3><ul><li><strong>DDL（数据定义语言）：</strong> 用来创建表、删除表、修改表（视图、触发器）等，如 create</li><li><strong>DML（数据操作语言）：</strong> insert、update、delete</li><li><strong>DCL（数据控制语言）：</strong> use database、权限赋值、超级管理员、root 用户</li></ul><h2 id="六-六大范式"><a class="markdownIt-Anchor" href="#六-六大范式"></a> 六、六大范式</h2><h3 id="q18什么是数据库的第一范式1nf"><a class="markdownIt-Anchor" href="#q18什么是数据库的第一范式1nf"></a> Q18：什么是数据库的第一范式（1NF）？</h3><p>第一范式强调属性的原子性，即属性不可再分。<strong>不允许表中还有表</strong>，一个字段只存储一项信息。</p><p>比如学生表中，字段&quot;家庭地址&quot;包含省市区这些值，这些值也可以看出一张表，所以不满足 1NF。</p><h3 id="q19什么是第二范式2nf"><a class="markdownIt-Anchor" href="#q19什么是第二范式2nf"></a> Q19：什么是第二范式（2NF）？</h3><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></pre></td><td class="code"><pre><span class="line">学号 姓名  课程  班级 分数</span><br><span class="line">1    小嗯  语文  1班  99</span><br><span class="line">1    小嗯  数学  1班  98</span><br><span class="line">2    小维  语文  2班  97</span><br><span class="line">2    小维  科学  2班  100</span><br></pre></td></tr></table></figure><p>可以看出：(课程) → (分数)，(学号) → (姓名, 班级)。其中 <strong>学号和课程组成主键</strong>，这属于部分函数依赖，不满足 2NF，需要拆成 2 张表即可满足。</p><p><strong>关键概念：</strong></p><ol><li><strong>元组：</strong> 表中的一行就是一个元组</li><li><strong>码：</strong> 一个表中，可以唯一决定一个元组的属性&quot;集合&quot;</li><li><strong>主属性：</strong> 码里面的属性就是主属性</li><li><strong>部分函数依赖：</strong> 比如 Z=X+Y，输入一个 X 不知道 Y 无法得到 Z，而 Z=X 就是部分函数依赖</li></ol><h3 id="q20什么是第三范式3nf"><a class="markdownIt-Anchor" href="#q20什么是第三范式3nf"></a> Q20：什么是第三范式（3NF）？</h3><p>第三范式在 2NF 的基础上，消除了非主属性对于码的传递函数依赖。即如果存在非主属性对于码的传递函数依赖，则不符合 3NF。</p><figure class="highlight plaintext"><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">订单id  商品id  商品尺寸</span><br><span class="line">1        1      22</span><br></pre></td></tr></table></figure><p>可以看出主键订单 id 满足第二范式，但商品 id 依赖订单 id，商品尺寸依赖商品 id，属于传递函数依赖，不满足 3NF。分成 2 张表即可满足。</p><h2 id="七-spring"><a class="markdownIt-Anchor" href="#七-spring"></a> 七、Spring</h2><h3 id="q21spring-是什么"><a class="markdownIt-Anchor" href="#q21spring-是什么"></a> Q21：Spring 是什么？</h3><p>Spring 是轻量级企业应用开发框架，是 IoC 和 AOP 的容器框架，全能具备 MVC 三层功能，不替换任何框架而是来整合 N 框架。</p><h3 id="q22spring-中常用的注解有哪些"><a class="markdownIt-Anchor" href="#q22spring-中常用的注解有哪些"></a> Q22：Spring 中常用的注解有哪些？</h3><ul><li><strong><code>@Component</code>：</strong> 类似于给需要注解这个的类 new 了一下，可以给 <code>('变量名')</code> 默认小驼峰</li><li><strong><code>@Controller</code>：</strong> 收发功能，@Component+</li><li><strong><code>@Service</code>：</strong> @Component+</li></ul><h3 id="q23什么是自定义注解"><a class="markdownIt-Anchor" href="#q23什么是自定义注解"></a> Q23：什么是自定义注解？</h3><p><code>@interface</code> 形式（<code>public @interface A</code>），没有 <code>@</code> 的时候是接口，有 <code>@</code> 时候只能裸这种形式，自动继承了 <code>java.lang.annotation.Annotation</code> 接口，这是自定义了一个注解 A。</p><h3 id="q24注解相关的元注解有哪些"><a class="markdownIt-Anchor" href="#q24注解相关的元注解有哪些"></a> Q24：注解相关的元注解有哪些？</h3><ul><li><strong><code>@Target</code>：</strong> 说明了 Annotation 所修饰的对象范围，取值有：CONSTRUCTOR（构造器）、FIELD（域）、LOCAL_VARIABLE（局部变量）、METHOD（方法）、PACKAGE（包）、PARAMETER（参数）、TYPE（类、接口或 enum 声明）</li><li><strong><code>@Documented</code>：</strong> 修饰的注解生成 JavaDoc 文档时会显示</li><li><strong><code>@Retention</code>：</strong> 注解的生命周期，SOURCE &lt; CLASS &lt; RUNTIME</li><li><strong><code>@Retention(RetentionPolicy.RUNTIME)</code>：</strong> 注解不仅被保存到 class 文件中，JVM 加载 class 文件之后仍然存在</li></ul><h3 id="q25aop-的核心注解有哪些"><a class="markdownIt-Anchor" href="#q25aop-的核心注解有哪些"></a> Q25：AOP 的核心注解有哪些？</h3><ul><li><strong><code>@Aspect</code>：</strong> 标识为一个切面供容器读取，作用于类</li><li><strong><code>@Pointcut</code>：</strong> 切入点，就是带有通知的连接点</li><li><strong><code>@Before</code>：</strong> 前置通知</li><li><strong><code>@AfterThrowing</code>：</strong> 异常抛出通知</li><li><strong><code>@After</code>：</strong> 后置通知</li><li><strong><code>@AfterReturning</code>：</strong> 后置增强，执行顺序在 @After 之后</li><li><strong><code>@Around</code>：</strong> 环绕通知</li></ul><h3 id="q26aop-的使用场景有哪些切点表达式怎么写"><a class="markdownIt-Anchor" href="#q26aop-的使用场景有哪些切点表达式怎么写"></a> Q26：AOP 的使用场景有哪些？切点表达式怎么写？</h3><p><strong>使用场景：</strong> 异常、安全、日志、权限、事务</p><p><strong>位置：</strong> 前置、后置、环绕、异常、最终</p><p><strong>切点表达式：</strong></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">execution(<span class="keyword">public</span> * *(..))              <span class="comment">// 任意的公共方法</span></span><br><span class="line">execution(* set*(..))                  <span class="comment">// 以 set 开头的所有方法</span></span><br><span class="line">execution(* com.LoggerApply.*(..))     <span class="comment">// com.LoggerApply 这个类里的所有方法</span></span><br><span class="line">execution(* com.annotation.*.*(..))    <span class="comment">// com.annotation 包下的所有类的所有方法</span></span><br><span class="line">execution(* com.annotation..*.*(..))   <span class="comment">// com.annotation 包及子包下所有类的所有方法</span></span><br><span class="line">execution(* com.annotation..*.*(String,?,Long))  <span class="comment">// 有三个参数，第一个 String，第二个任意，第三个 Long</span></span><br></pre></td></tr></table></figure><h2 id="八-配置类与-yaml"><a class="markdownIt-Anchor" href="#八-配置类与-yaml"></a> 八、配置类与 YAML</h2><h3 id="q27如何通过-configurationproperties-读取-yml-配置"><a class="markdownIt-Anchor" href="#q27如何通过-configurationproperties-读取-yml-配置"></a> Q27：如何通过 @ConfigurationProperties 读取 yml 配置？</h3><p><strong>application.yml 配置：</strong></p><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></pre></td><td class="code"><pre><span class="line"><span class="attr">lucky:</span></span><br><span class="line">  <span class="attr">jwt:</span></span><br><span class="line">    <span class="attr">secret:</span> <span class="string">xxxxxxxxxxxxxxxxxxx</span></span><br></pre></td></tr></table></figure><p><strong>配置类：</strong></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="meta">@ConfigurationProperties(prefix = &quot;lucky.jwt&quot;)</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">YamlConfig</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String secret;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">generateToken</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> secret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="q28如何在单元测试中读取配置"><a class="markdownIt-Anchor" href="#q28如何在单元测试中读取配置"></a> Q28：如何在单元测试中读取配置？</h3><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Slf4j</span>                        <span class="comment">// 日志注解</span></span><br><span class="line"><span class="meta">@RunWith(SpringRunner.class)</span>   <span class="comment">// 获取上下文</span></span><br><span class="line"><span class="meta">@SpringBootTest</span>               <span class="comment">// SpringBoot 测试注解</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ReadConfig</span> &#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> YamlConfig yamlConfig;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">secret</span> <span class="operator">=</span> yamlConfig.getSecret();</span><br><span class="line">        System.out.println(secret);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="q29如何通过工具类读取-yaml-配置"><a class="markdownIt-Anchor" href="#q29如何通过工具类读取-yaml-配置"></a> Q29：如何通过工具类读取 YAML 配置？</h3><p><strong>依赖：</strong></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></pre></td><td class="code"><pre><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.yaml<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>snakeyaml<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>1.29<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></pre></td></tr></table></figure><p><strong>工具类（单例模式）：</strong></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">YamlUtils</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> YamlUtils instance;</span><br><span class="line">    <span class="keyword">private</span> Map&lt;String, Object&gt; jwtConfig;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">YamlUtils</span><span class="params">()</span> &#123;</span><br><span class="line">        loadConfig();</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> <span class="keyword">synchronized</span> YamlUtils <span class="title function_">getInstance</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (instance == <span class="literal">null</span>) &#123;</span><br><span class="line">            instance = <span class="keyword">new</span> <span class="title class_">YamlUtils</span>();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> instance;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">loadConfig</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Yaml</span> <span class="variable">yaml</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Yaml</span>();</span><br><span class="line">        <span class="keyword">try</span> (<span class="type">InputStream</span> <span class="variable">inputStream</span> <span class="operator">=</span> YamlUtils.class.getClassLoader().getResourceAsStream(<span class="string">&quot;application.yml&quot;</span>)) &#123;</span><br><span class="line">            Map&lt;String, Object&gt; config = yaml.load(inputStream);</span><br><span class="line">            Map&lt;String, Object&gt; customConfig = (Map&lt;String, Object&gt;) config.get(<span class="string">&quot;custom&quot;</span>);</span><br><span class="line">            jwtConfig = (Map&lt;String, Object&gt;) customConfig.get(<span class="string">&quot;jwt&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getJwtSecret</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> (String) jwtConfig.get(<span class="string">&quot;secret&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="type">int</span> <span class="title function_">getJwtExpireDate</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> (<span class="type">int</span>) jwtConfig.get(<span class="string">&quot;expire&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>调用：</strong></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></pre></td><td class="code"><pre><span class="line"><span class="type">YamlUtils</span> <span class="variable">config</span> <span class="operator">=</span> YamlUtils.getInstance();</span><br><span class="line"><span class="type">String</span> <span class="variable">tokenSecret</span> <span class="operator">=</span> config.getJwtSecret();</span><br><span class="line"><span class="type">Integer</span> <span class="variable">expireDate</span> <span class="operator">=</span> config.getJwtExpireDate();</span><br></pre></td></tr></table></figure><h2 id="九-jdbc"><a class="markdownIt-Anchor" href="#九-jdbc"></a> 九、JDBC</h2><h3 id="q30jdbc-是什么如何使用"><a class="markdownIt-Anchor" href="#q30jdbc-是什么如何使用"></a> Q30：JDBC 是什么？如何使用？</h3><p>JDBC 是 Java 处理数据库的一种技术，其中包含大量的类和接口等 API，及连接 DB 驱动程序。</p><p><strong>使用步骤：</strong></p><ol><li>加载驱动，得到连接（不同数据库有不同的驱动类）</li><li>建立连接</li><li>编写 SQL 语句</li><li>得到执行者对象</li><li>执行：查询返回虚拟的表，增删改返回行数（int 即可）</li><li>处理结果</li><li>释放资源</li></ol><h2 id="十-连接池"><a class="markdownIt-Anchor" href="#十-连接池"></a> 十、连接池</h2><h3 id="q31什么是连接池为什么需要连接池"><a class="markdownIt-Anchor" href="#q31什么是连接池为什么需要连接池"></a> Q31：什么是连接池？为什么需要连接池？</h3><p>自己的程序如果用户量大，都会进行 JDBC 操作，性能很低，需要优化。解决方案：预先建立多个连接（conn），有需要自己从池中获取。若只有一个 conn，无法满足应用使用，要排队，响应速度慢。多建几个 conn 就是连接池，这是池化的概念。</p><p><strong>流程：</strong></p><ol><li>建立 10 个连接</li><li>从连接池获得 conn</li><li>操作结束后，将 conn 返回给连接池</li></ol><p>空闲时连接对象就是浪费，可设置 6 个活动、4 个不活动。</p><h3 id="q32什么是单例模式在连接池中有什么应用"><a class="markdownIt-Anchor" href="#q32什么是单例模式在连接池中有什么应用"></a> Q32：什么是单例模式？在连接池中有什么应用？</h3><p>一个应用里只要一个对象，性能提升。不能 new → 构造方法设为 private，提供一个共有方法返回对象，这就是单例模式。</p><p>第三方连接池有 c3p0、dbcp。</p><h2 id="十一-io-流"><a class="markdownIt-Anchor" href="#十一-io-流"></a> 十一、IO 流</h2><h3 id="q33什么是-io-流"><a class="markdownIt-Anchor" href="#q33什么是-io-流"></a> Q33：什么是 IO 流？</h3><p>IO 流就是指读写文件的技术。I 是 input 输入流，O 是 output 输出流，用一句话记忆就是：<strong>输入到内存再从内存输出到硬盘</strong>。针对的是内存而言。</p><h3 id="q34如何查找文件夹里的所有文件"><a class="markdownIt-Anchor" href="#q34如何查找文件夹里的所有文件"></a> Q34：如何查找文件夹里的所有文件？</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">path</span> <span class="operator">=</span> <span class="string">&quot;D:\\workspace&quot;</span>;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(path);</span><br><span class="line">        printFile(file);</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> <span class="keyword">void</span> <span class="title function_">printFile</span><span class="params">(File file)</span> &#123;</span><br><span class="line">        File[] files = file.listFiles();</span><br><span class="line">        <span class="keyword">for</span> (File a : files) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a.isFile()) &#123;</span><br><span class="line">                System.out.println(a.getName());</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                printFile(a);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="q35如何实现文件拷贝"><a class="markdownIt-Anchor" href="#q35如何实现文件拷贝"></a> Q35：如何实现文件拷贝？</h3><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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">File</span> <span class="variable">file1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\a.txt&quot;</span>);  <span class="comment">// 源文件</span></span><br><span class="line">            <span class="type">long</span> <span class="variable">flen</span> <span class="operator">=</span> file1.length();</span><br><span class="line">            System.out.println(<span class="string">&quot;源文件的大小是&quot;</span> + flen + <span class="string">&quot;字节&quot;</span>);</span><br><span class="line">            <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file1);</span><br><span class="line">            <span class="type">File</span> <span class="variable">file2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\b.txt&quot;</span>);  <span class="comment">// 复制到的地方</span></span><br><span class="line">            <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(file2);</span><br><span class="line">            <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];  <span class="comment">// 1兆1兆传</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="type">long</span> <span class="variable">readSize</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;  <span class="comment">// -1 就是最后一个结束</span></span><br><span class="line">                fos.write(bytes, <span class="number">0</span>, len);  <span class="comment">// 比如一个文件是 1024*8+244，那么 len 就是 244</span></span><br><span class="line">                fos.flush();  <span class="comment">// 强制输出，推送数据</span></span><br><span class="line">                readSize += len;</span><br><span class="line">                <span class="keyword">if</span> (readSize == flen) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;读的大小&quot;</span> + readSize + <span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="十二-网络编程"><a class="markdownIt-Anchor" href="#十二-网络编程"></a> 十二、网络编程</h2><h3 id="q36什么是协议-ip-和端口"><a class="markdownIt-Anchor" href="#q36什么是协议-ip-和端口"></a> Q36：什么是协议、IP 和端口？</h3><ul><li><strong>协议：</strong> 双方约定好的规则</li><li><strong>HTTP：</strong> 默认端口 80</li><li><strong>FTP：</strong> 默认端口 21（文件传输）</li><li><strong>Telnet：</strong> 默认端口 22（网络聊天）</li><li><strong>SMTP/POP3：</strong> 邮件</li></ul><h3 id="q37socket-是什么客户端和服务端分别用什么"><a class="markdownIt-Anchor" href="#q37socket-是什么客户端和服务端分别用什么"></a> Q37：Socket 是什么？客户端和服务端分别用什么？</h3><p>客户端用 <code>Socket</code> 发送数据，服务端用 <code>ServerSocket</code>，本机地址可以用 <code>127.0.0.1</code> 或 <code>localhost</code>。</p><p>Socket 此类实现客户端套接字（也可以就叫&quot;套接字&quot;），套接字是两台机器间通信的端点。</p><h3 id="q38tcp-三次握手和四次挥手是什么"><a class="markdownIt-Anchor" href="#q38tcp-三次握手和四次挥手是什么"></a> Q38：TCP 三次握手和四次挥手是什么？</h3><p><strong>三次握手：</strong></p><ol><li>Client 发送 SYN 500 → Server</li><li>Server 发送 SYN 600 + ACK 确认号 500+1 给客户端</li><li>客户端再发 ACK 600+1 给服务器</li></ol><p><strong>四次挥手：</strong> qq 正在下载东西，点击关闭发送给服务器，服务器发出一个提示框正在下载东西是否确定退出，点确定后，服务器再关闭一下其他东西，再发送可以关闭了，客户端发关闭了。</p><h3 id="q39字符串拼接有什么性能问题"><a class="markdownIt-Anchor" href="#q39字符串拼接有什么性能问题"></a> Q39：字符串拼接有什么性能问题？</h3><p>字符串拼接很浪费资源，每个字符串相加就是一个对象开辟，可以使用 <code>StringBuffer</code> 和 <code>StringBuilder</code> 类解决性能问题（不解决拼接问题）。JSON 数据格式作为通讯协议。</p><p><code>JSONObject cannot be cast to com.nwa.bean.Tbaccount</code> 异常：不能强制转换，必须是继承关系的类。</p><h2 id="十三-多线程"><a class="markdownIt-Anchor" href="#十三-多线程"></a> 十三、多线程</h2><h3 id="q40线程的实现方法有哪些"><a class="markdownIt-Anchor" href="#q40线程的实现方法有哪些"></a> Q40：线程的实现方法有哪些？</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">extends</span> <span class="title class_">Thread</span></span><br><span class="line"><span class="keyword">implements</span> <span class="title class_">Runnable</span></span><br><span class="line"><span class="keyword">implements</span> <span class="title class_">Callable</span></span><br></pre></td></tr></table></figure><h3 id="q41线程的状态有哪些"><a class="markdownIt-Anchor" href="#q41线程的状态有哪些"></a> Q41：线程的状态有哪些？</h3><p>新建 <code>new</code> → 就绪 <code>start</code> → 运行 <code>run</code> → 死亡 <code>stop</code> → 等待 <code>wait</code>（对应唤醒 <code>notify</code>）→ 挂起 <code>suspend</code>（对应恢复 <code>resume</code>，已被反对）→ 睡眠 <code>sleep</code></p><p><code>t.start()</code> 线程启动处于就绪状态（不是 run，只有 CPU 分配到才运行）。</p><p>运行中的线程会出现阻塞问题：IO 非 IO 阻塞（sleep、wait 等待/唤醒、挂起 suspend/恢复 resume）。</p><h3 id="q42什么是线程安全问题"><a class="markdownIt-Anchor" href="#q42什么是线程安全问题"></a> Q42：什么是线程安全问题？</h3><p>面试题线程安全，讲买票场景：模拟 3 个人连续购买 10 张票，每买一张耗时 1-3s，假设一共 5 张票。全局和静态变量引起线程安全问题。</p><h3 id="q43什么是生产者-消费者模型"><a class="markdownIt-Anchor" href="#q43什么是生产者-消费者模型"></a> Q43：什么是生产者-消费者模型？</h3><p>生产者-消费者模型：仓库状态满时消费者消费，空时生产者生产。</p><ul><li><strong>仓库类：</strong> 状态 1/0、货物编号、入库/出库</li><li><strong>消费者类：</strong> 消费（到仓库取货——出库）</li><li><strong>生产者类：</strong> 生产（给仓库入库）</li></ul>]]></content>
    
    
    <summary type="html">青，取之于蓝，而青于蓝</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Hexo + Butterfly 博客搭建指南</title>
    <link href="https://luckynwa.top/posts/website_construction1/"/>
    <id>https://luckynwa.top/posts/website_construction1/</id>
    <published>2024-01-01T02:32:48.000Z</published>
    <updated>2024-07-03T12:32:48.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="准备"><a class="markdownIt-Anchor" href="#准备"></a> 准备</h1><p>用 Hexo 框架可以快速搭建一个博客网站，再配合 butterfly 主题可以搭建出较为好看的页面，需遵循它的配置。</p><p>安装 <code>node</code>、<code>git</code>、<code>vscode</code>可以本站查找安装攻略</p><h1 id="创建博客"><a class="markdownIt-Anchor" href="#创建博客"></a> 创建博客</h1><p>桌面新建文件夹 <code>blog</code>，进入根目录 cmd 打开终端，安装 hexo 脚手架：</p><figure class="highlight shell"><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">hexo version               # 查看版本</span><br><span class="line">npm install hexo-cli -g    # 没装则运行</span><br></pre></td></tr></table></figure><p>初始化项目：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo init</span><br></pre></td></tr></table></figure><p>等待完成，生成本地页面：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">hexo s</span><br></pre></td></tr></table></figure><p>浏览器访问 <a href="http://localhost:4000/">http://localhost:4000/</a> 即可看到本地版。</p><h1 id="部署博客"><a class="markdownIt-Anchor" href="#部署博客"></a> 部署博客</h1><h2 id="github"><a class="markdownIt-Anchor" href="#github"></a> GitHub</h2><p>去 Github 新建仓库 <code>luckyNwa.github.io</code>，必须这个格式，第一个名称改自己的 GitHub 名称。</p><p>打开 <code>_config.yml</code> 最后一行改成下面：</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># Deployment</span></span><br><span class="line"><span class="comment">## Docs: https://hexo.io/docs/one-command-deployment</span></span><br><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line">  <span class="attr">repository:</span> <span class="string">git@github.com:luckyNwa/luckyNwa.github.io.git</span></span><br><span class="line">  <span class="attr">branch:</span> <span class="string">main</span></span><br></pre></td></tr></table></figure><p>在 <code>blog</code> 文件夹路径 cmd 打开终端，安装自动部署发布工具：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-deployer-git --save</span><br></pre></td></tr></table></figure><p>生成页面并上传到 GitHub：</p><figure class="highlight shell"><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">hexo g    # 生成静态文件</span><br><span class="line">hexo d    # 部署到远程</span><br></pre></td></tr></table></figure><p>访问 <a href="https://luckynwa.github.io/">https://luckynwa.github.io/</a> （需要等它部署几分钟）。</p><h2 id="vercel"><a class="markdownIt-Anchor" href="#vercel"></a> Vercel</h2><p>官网 <a href="https://vercel.com/">https://vercel.com/</a> 用 GitHub 登录即可。</p><p>点击 new 一个项目，找到刚刚那个博客导入，点部署，它会分配一个二级域名免费用，也可以绑定自己的国内域名。</p><p>示例地址：<a href="https://lucky-blog.vercel.app/">https://lucky-blog.vercel.app/</a></p><h1 id="安装主题"><a class="markdownIt-Anchor" href="#安装主题"></a> 安装主题</h1><h2 id="常用指令"><a class="markdownIt-Anchor" href="#常用指令"></a> 常用指令</h2><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></pre></td><td class="code"><pre><span class="line">hexo cl                        # 清除缓存</span><br><span class="line">hexo g                         # 生成静态文件</span><br><span class="line">hexo s                         # 本地预览 → http://localhost:4000/</span><br><span class="line">hexo d                         # 同步远程</span><br><span class="line">hexo cl &amp;&amp; hexo g &amp;&amp; hexo s    # 多合一生成到本地</span><br><span class="line">hexo new post &quot;博客搭建笔记&quot;    # 创建文章</span><br><span class="line">hexo new page categories       # 创建页面</span><br><span class="line">hexo version                   # 查看版本</span><br></pre></td></tr></table></figure><h2 id="packagejson-脚本说明"><a class="markdownIt-Anchor" href="#packagejson-脚本说明"></a> package.json 脚本说明</h2><figure class="highlight json"><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="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;iNode18&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npm install&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;dev&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo clean &amp;&amp; hexo generate &amp;&amp; hexo server&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo clean &amp;&amp; hexo generate &amp;&amp; hexo server&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;build&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo generate&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;deploy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo deploy&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;clean&quot;</span><span class="punctuation">:</span> <span class="string">&quot;npx rimraf node_modules&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><ul><li><code>iNode18</code> / <code>clean</code> → 安装依赖、删除依赖</li><li><code>dev</code> / <code>server</code> → 运行，同时删除缓存重新生成</li><li><code>build</code> → 打包</li><li><code>deploy</code> → 推送到 GitHub</li></ul><h2 id="butterfly-主题"><a class="markdownIt-Anchor" href="#butterfly-主题"></a> Butterfly 主题</h2><ul><li>中文文档：<a href="https://butterfly.js.org/">https://butterfly.js.org/</a> （最好科学上网）</li><li>开源地址：<a href="https://github.com/jerryc127/hexo-theme-butterfly">https://github.com/jerryc127/hexo-theme-butterfly</a></li></ul><h3 id="安装主题-2"><a class="markdownIt-Anchor" href="#安装主题-2"></a> 安装主题</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly</span><br></pre></td></tr></table></figure><p>打开 <code>_config.yml</code> 修改主题：</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 class="attr">theme:</span> <span class="string">butterfly</span></span><br></pre></td></tr></table></figure><blockquote><p><strong>重要</strong>：<code>_config.yml</code> 同级别创建 <code>_config.butterfly.yml</code>，把 <code>themes/butterfly</code> 文件夹下的 config 内容复制进去，删除 <code>_config.landscape.yml</code>。</p></blockquote><h3 id="安装渲染器"><a class="markdownIt-Anchor" href="#安装渲染器"></a> 安装渲染器</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-renderer-pug hexo-renderer-stylus --save</span><br></pre></td></tr></table></figure><h3 id="url-优化"><a class="markdownIt-Anchor" href="#url-优化"></a> URL 优化</h3><p>安装 abbrlink 插件：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-abbrlink --save</span><br></pre></td></tr></table></figure><p><code>_config.yml</code> 找到 <code>permalink</code> 修改：</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 原始</span></span><br><span class="line"><span class="attr">permalink:</span> <span class="string">:year/:month/:day/:title/</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改为</span></span><br><span class="line"><span class="attr">permalink:</span> <span class="string">post/:abbrlink.html</span></span><br><span class="line"><span class="attr">abbrlink:</span></span><br><span class="line">  <span class="attr">alg:</span> <span class="string">crc32</span></span><br><span class="line">  <span class="attr">rep:</span> <span class="string">hex</span></span><br></pre></td></tr></table></figure><h3 id="本地搜索"><a class="markdownIt-Anchor" href="#本地搜索"></a> 本地搜索</h3><p>安装搜索插件：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i hexo-generator-search --save</span><br></pre></td></tr></table></figure><p><code>_config.yml</code> 下新增：</p><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 本地搜索</span></span><br><span class="line"><span class="attr">search:</span></span><br><span class="line">  <span class="attr">path:</span> <span class="string">search.xml</span></span><br><span class="line">  <span class="attr">field:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">content:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>主题配置 <code>_config.butterfly.yml</code> 中，<code>local_search</code> 下两个值都设为 <code>true</code>。</p><h1 id="问题"><a class="markdownIt-Anchor" href="#问题"></a> 问题</h1><h2 id="vs-code-中不能启动项目"><a class="markdownIt-Anchor" href="#vs-code-中不能启动项目"></a> VS Code 中不能启动项目</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">get-ExecutionPolicy</span>          <span class="comment"># 必须是 RemoteSigned 才行</span></span><br><span class="line"><span class="built_in">set-ExecutionPolicy</span> RemoteSigned   <span class="comment"># 不是则运行这条</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">千锤万凿出深山，烈火焚烧若等闲</summary>
    
    
    
    <category term="网站搭建" scheme="https://luckynwa.top/categories/%E7%BD%91%E7%AB%99%E6%90%AD%E5%BB%BA/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>正则表达式速查手册</title>
    <link href="https://luckynwa.top/posts/tool17/"/>
    <id>https://luckynwa.top/posts/tool17/</id>
    <published>2023-10-20T21:53:09.000Z</published>
    <updated>2026-07-07T16:19:34.198Z</updated>
    
    <content type="html"><![CDATA[<h2 id="定义"><a class="markdownIt-Anchor" href="#定义"></a> 定义</h2><p><strong>正则表达式（Regular Expression，简称 regex 或 regexp）</strong> 是一种用于匹配字符串中字符模式的工具。它由一系列字符和特殊符号组成，用来描述搜索模式</p><p>通过使用正则表达式，你可以执行复杂的字符串操作，如查找、替换、分割等</p><h2 id="基本语法元素"><a class="markdownIt-Anchor" href="#基本语法元素"></a> 基本语法元素</h2><p><strong>普通字符</strong>：大多数字符，如字母和数字，在正则表达式中代表它们自己。例如，<code>cat</code> 匹配单词 “cat”</p><p><strong>元字符</strong>：某些字符具有特殊含义，称为元字符</p><table><thead><tr><th>元字符</th><th>含义</th><th>示例</th></tr></thead><tbody><tr><td><code>.</code></td><td>匹配除换行符以外的任意单个字符</td><td><code>a.c</code> 匹配 abc、aXc</td></tr><tr><td><code>^</code></td><td>匹配字符串的开头</td><td><code>^cat</code> 匹配以cat开头</td></tr><tr><td><code>$</code></td><td>匹配字符串的结尾</td><td><code>cat$</code> 匹配以cat结尾</td></tr><tr><td><code>*</code></td><td>匹配前面的字符零次或多次</td><td><code>ab*c</code> 匹配 ac、abc、abbc</td></tr><tr><td><code>+</code></td><td>匹配前面的字符一次或多次</td><td><code>ab+c</code> 匹配 abc、abbc</td></tr><tr><td><code>?</code></td><td>匹配前面的字符零次或一次</td><td><code>ab?c</code> 匹配 ac、abc</td></tr><tr><td><code>&#123;n&#125;</code></td><td>匹配前面的字符恰好 n 次</td><td><code>a&#123;3&#125;</code> 匹配 aaa</td></tr><tr><td><code>&#123;n,&#125;</code></td><td>匹配前面的字符至少 n 次</td><td><code>a&#123;2,&#125;</code> 匹配 aa、aaa…</td></tr><tr><td><code>&#123;n,m&#125;</code></td><td>匹配前面的字符至少 n 次但不超过 m 次</td><td><code>a&#123;2,4&#125;</code> 匹配 aa~aaaa</td></tr></tbody></table><p><strong>字符集</strong>：用方括号 <code>[]</code> 表示一个字符集合，匹配其中任何一个字符。例如，<code>[aeiou]</code> 匹配任何元音字母</p><p><strong>反义字符集</strong>：用 <code>[^...]</code> 表示，匹配不在括号内的任意字符。例如，<code>[^0-9]</code> 匹配任何非数字字符</p><p><strong>分组和捕获</strong>：用圆括号 <code>()</code> 将部分模式组合在一起。例如，<code>(ab)+</code> 匹配一个或多个 “ab” 组合</p><p><strong>选择</strong>：用竖线 <code>|</code> 分隔选项，表示&quot;或&quot;的关系。例如，<code>gray|grey</code> 匹配 “gray” 或 “grey”</p><h2 id="量词和贪婪模式"><a class="markdownIt-Anchor" href="#量词和贪婪模式"></a> 量词和贪婪模式</h2><ul><li><strong>贪婪模式</strong>：默认情况下，量词 (<code>*</code>, <code>+</code>, <code>?</code>, <code>&#123;n,m&#125;</code> 等) 是贪婪的，会尽可能多地匹配字符</li><li><strong>非贪婪模式</strong>：在量词后面加上 <code>?</code> 可使其变为非贪婪模式，尽可能少地匹配字符。例如，<code>.*?</code> 匹配任意数量的字符直到遇到第一个满足条件的字符</li></ul><h2 id="应用场景"><a class="markdownIt-Anchor" href="#应用场景"></a> 应用场景</h2><ul><li><strong>JavaScript</strong>：使用 <code>RegExp</code> 对象或字面量创建，使用 <code>test()</code>, <code>match()</code>, <code>replace()</code>, <code>split()</code> 等方法</li><li><strong>命令行工具</strong>：如 <code>grep</code>, <code>sed</code>, <code>awk</code> 等支持正则的文本处理工具</li><li><strong>编程语言</strong>：Python 的 <code>re</code> 模块，Java 的 <code>java.util.regex</code> 包等</li></ul><h2 id="常用简写"><a class="markdownIt-Anchor" href="#常用简写"></a> 常用简写</h2><p>Java中需要 <code>\\</code>（字符串转义），JavaScript不需要</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></pre></td><td class="code"><pre><span class="line">\d          一个数字</span><br><span class="line">\D          非数字</span><br><span class="line">\w          一个字母（大小写均可）、数字或下划线</span><br><span class="line">\W          非字母数字下划线（特殊符号或空格）</span><br><span class="line">\s          空白字符（空格或制表符Tab）</span><br><span class="line">\S          非空白字符（可见符号）</span><br><span class="line">.           任意一个字符（除换行符）</span><br><span class="line">....        任意四个字符</span><br></pre></td></tr></table></figure><h2 id="语法详解"><a class="markdownIt-Anchor" href="#语法详解"></a> 语法详解</h2><h3 id="字符集"><a class="markdownIt-Anchor" href="#字符集"></a> 字符集</h3><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></pre></td><td class="code"><pre><span class="line">[]          匹配其中任意一个字符</span><br><span class="line">a[bcd]e     a和e中间须是b或c或d其中的一个</span><br><span class="line">[^]         不与中括号里的任意字符匹配</span><br><span class="line">a[^bcd]e    a和e中间除b、c、d外的字符都满足</span><br><span class="line">[a-z]       匹配a到z之间的所有字符</span><br><span class="line">a[b-d]e     等同于a[bcd]e</span><br><span class="line">a[0-9]e     a和e中间是一个数字，等同于a\de</span><br><span class="line">a[^1-3]e    a和e中间只要不是1、2、3都满足</span><br></pre></td></tr></table></figure><h3 id="分组与反向引用"><a class="markdownIt-Anchor" href="#分组与反向引用"></a> 分组与反向引用</h3><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></pre></td><td class="code"><pre><span class="line">(ab)+       匹配一个或多个&quot;ab&quot;组合</span><br><span class="line">(ab|cd)     匹配ab或cd</span><br><span class="line">\num        num是数字，引用第num个分组的值</span><br><span class="line">ab(c)d\1    对应abcdc（\1引用第一个分组c）</span><br><span class="line">ab(c)(d)\1\2  对应abcdcd，等同于ab(cd)\1</span><br></pre></td></tr></table></figure><h3 id="选择与分组"><a class="markdownIt-Anchor" href="#选择与分组"></a> 选择与分组</h3><figure class="highlight shell"><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">(a|b|c)     匹配a、b或c中的一个</span><br><span class="line">幸(a|b|c)运  必须幸开头运结尾，中间是a或b或c</span><br></pre></td></tr></table></figure><h3 id="量词详解"><a class="markdownIt-Anchor" href="#量词详解"></a> 量词详解</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">?           匹配前面的子表达式零次或一次</span><br><span class="line">abc?de      匹配abde（0次c）或abcde（1次c）</span><br><span class="line"></span><br><span class="line">+           匹配前面的子表达式一次或多次（至少1次）</span><br><span class="line">abc+de      ab和de之间至少有一个c</span><br><span class="line"></span><br><span class="line">&#123;n&#125;         匹配确定的n次</span><br><span class="line">abc&#123;3&#125;de    ab和de之间有3个c</span><br><span class="line"></span><br><span class="line">&#123;n,m&#125;       最少n次且最多m次</span><br><span class="line">abc&#123;2,3&#125;de  ab和de之间有2到3个c</span><br><span class="line"></span><br><span class="line">*           匹配任意次（包括0次）</span><br><span class="line">abc*de      ab和de之间有任意个数（包括0）的c</span><br><span class="line"></span><br><span class="line">&#123;x|y&#125;&#123;n&#125;    x或y的组合出现n次</span><br><span class="line">a(x|y)&#123;3&#125;d  a和d之间x和y合计3个</span><br></pre></td></tr></table></figure><h2 id="常用正则表达式"><a class="markdownIt-Anchor" href="#常用正则表达式"></a> 常用正则表达式</h2><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></pre></td><td class="code"><pre><span class="line">^[0-9]*$                    纯数字</span><br><span class="line"></span><br><span class="line">[a-zA-Z]+://[^\s]*          URL</span><br><span class="line"></span><br><span class="line">^1[3-9]\d&#123;9&#125;$               手机号</span><br><span class="line"></span><br><span class="line">^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]&#123;2,&#125;$  邮箱</span><br><span class="line"></span><br><span class="line">^\d&#123;15&#125;|\d&#123;18&#125;$             身份证号（15位或18位）</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">穷则变，变则通，通则久</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Doc" scheme="https://luckynwa.top/tags/Doc/"/>
    
  </entry>
  
  <entry>
    <title>VSCode 配置</title>
    <link href="https://luckynwa.top/posts/tool15/"/>
    <id>https://luckynwa.top/posts/tool15/</id>
    <published>2023-10-07T03:48:40.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h1 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h1><p>直接安装软件包，记得添加到 Win 资源管理器（右键文件可以用它打开）。</p><ol><li>设置 → 搜 <code>Update mode</code> → <code>default</code> 改成 <code>none</code></li><li>搜 <code>update</code> → 取消第一个后台更新</li><li>弄完再去安装语言插件，再重启 VSCode</li></ol><p><strong>新版本：</strong> <code>VSCodeUserSetup-x64-1.127.0</code>，使用 GitHub <code>luckyNwa6</code> 登录</p><h1 id="卸载"><a class="markdownIt-Anchor" href="#卸载"></a> 卸载</h1><ol><li>卸载软件</li><li>删除 <code>C:\Users\用户名\.vscode</code> 文件夹</li><li><code>Win+R</code> 输入 <code>%appdata%</code>，找到 <code>Code</code> 和 <code>Visual Studio Setup</code> 文件夹删除</li></ol><h1 id="推荐插件"><a class="markdownIt-Anchor" href="#推荐插件"></a> 推荐插件</h1><table><thead><tr><th>插件名</th><th>说明</th></tr></thead><tbody><tr><td><strong>Chinese (Simplified)</strong></td><td>简体中文，去设置里搜缩略图关掉</td></tr><tr><td><strong>Atom One Dark Theme</strong></td><td>颜色主题</td></tr><tr><td><strong>vscode-icons</strong></td><td>文件夹图标</td></tr><tr><td><strong>:emojisense:</strong></td><td>代码中输入 <code>:smile_cat:</code> → 😸</td></tr><tr><td><strong>Auto Close Tag</strong></td><td>键入开始标记自动插入结束标记</td></tr><tr><td><strong>Auto Rename Tag</strong></td><td>同步修改 HTML/XML 标签</td></tr><tr><td><strong>Live Server</strong></td><td>快速启动本地服务，自动监听</td></tr><tr><td><strong>Image Preview</strong></td><td>鼠标悬停图片地址查看图片</td></tr><tr><td><strong>Code Spell Checker</strong></td><td>拼写检查器，配合驼峰大小写</td></tr><tr><td><strong>Vetur</strong></td><td>语法高亮、智能感知、Emmet 等（Vue2）</td></tr><tr><td><strong>Quokka.js</strong></td><td>练习 JS，<code>Ctrl+Shift+P</code> 输入 Quokka 找到 newFile，设置快捷键 <code>Ctrl+N</code></td></tr><tr><td><strong>vue-component</strong></td><td>template 输入组件名称自动导入</td></tr><tr><td><strong>CodeSnap</strong></td><td>选中代码右键使用，代码截图更美观</td></tr><tr><td><strong>IntelliCode</strong></td><td>代码智能提示</td></tr><tr><td><strong>Path Intellisense</strong></td><td>路径提示</td></tr><tr><td><strong>Prettier</strong></td><td>前端代码格式化，记得使用最后的配置</td></tr><tr><td><strong>vue-format</strong></td><td>Vue2 格式化插件（Vue3 会删除 setup），快捷键 <code>Ctrl+Alt+P</code></td></tr><tr><td><strong>Bracket Pair Colorizer</strong></td><td>彩虹 <code>&#123;&#125;</code>，被弃用也装，比内置的好</td></tr><tr><td><strong>Highlight Matching Tag</strong></td><td>突出标签</td></tr><tr><td><strong>Markdown Preview Enhanced</strong></td><td>MD 文档预览，右键 MPE 打开</td></tr><tr><td><strong>Codelf</strong></td><td>变量起名神器，变量名右键打开</td></tr><tr><td><strong>Turbo Console Log</strong></td><td>点击变量生成 <code>console.log</code>，默认 <code>Ctrl+Alt+L</code> 改成 <code>Ctrl+Shift+R</code></td></tr><tr><td><strong>Vue Peek</strong></td><td>快速跳转到组件、模块定义的文件</td></tr><tr><td><strong>Git Graph</strong></td><td>可视化版本控制插件</td></tr><tr><td><strong>GitLens</strong></td><td>代码行上显示 Git 提交信息</td></tr><tr><td><strong>Git History</strong></td><td>查看 Git 提交历史记录</td></tr><tr><td><strong>Git Blame</strong></td><td>轻量的提交信息查看</td></tr><tr><td><strong>koroFileHeader</strong></td><td>头部注释自动生成，快捷键 <code>Alt+/</code></td></tr><tr><td><strong>Jest Runner</strong></td><td>测试用，加上 debugger 点右键</td></tr><tr><td><strong>vue-helper</strong></td><td>左键点击方法能跳转</td></tr><tr><td><strong>会了吧</strong></td><td>帮助看懂英文</td></tr></tbody></table><p><strong>VSCode 快捷键参考：</strong> <a href="https://www.bilibili.com/read/cv9699783/">https://www.bilibili.com/read/cv9699783/</a></p><h2 id="自定义快捷键"><a class="markdownIt-Anchor" href="#自定义快捷键"></a> 自定义快捷键</h2><table><thead><tr><th>原快捷键</th><th>改为</th><th>说明</th></tr></thead><tbody><tr><td><code>Ctrl+Enter</code></td><td><code>Ctrl+Shift+Enter</code></td><td>换行</td></tr><tr><td><code>Ctrl+.</code></td><td><code>Ctrl+.</code></td><td>i18n 插件提取文案，选中中文再快捷键直接回车生成</td></tr></tbody></table><h1 id="settingsjson-配置"><a class="markdownIt-Anchor" href="#settingsjson-配置"></a> settings.json 配置</h1><figure class="highlight json"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;update.enableWindowsBackgroundUpdates&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;update.mode&quot;</span><span class="punctuation">:</span> <span class="string">&quot;none&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.colorTheme&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Atom One Dark&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.formatOnSave&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;esbenp.prettier-vscode&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.bracketPairColorization.enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.guides.bracketPairs&quot;</span><span class="punctuation">:</span> <span class="string">&quot;active&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;extensions.ignoreRecommendations&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.iconTheme&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vscode-icons&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.startupEditor&quot;</span><span class="punctuation">:</span> <span class="string">&quot;none&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;bracket-pair-colorizer-2.depreciation-notice&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.minimap.enabled&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;vetur.ignoreProjectWarning&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;path-intellisense.mappings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;@&quot;</span><span class="punctuation">:</span> <span class="string">&quot;$&#123;workspaceRoot&#125;/src&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;[vue]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;esbenp.prettier-vscode&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.editor.enablePreview&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.editor.wrapTabs&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;explorer.confirmDelete&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;security.workspace.trust.untrustedFiles&quot;</span><span class="punctuation">:</span> <span class="string">&quot;open&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.fontSize&quot;</span><span class="punctuation">:</span> <span class="number">18</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;liveServer.settings.donotVerifyTags&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;explorer.confirmDragAndDrop&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;Codegeex.Comment.LanguagePreference&quot;</span><span class="punctuation">:</span> <span class="string">&quot;zh-CN&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;Codegeex.Privacy&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;[javascript]&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;editor.defaultFormatter&quot;</span><span class="punctuation">:</span> <span class="string">&quot;esbenp.prettier-vscode&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.tabSize&quot;</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.tokenColorCustomizations&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;comments&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#6A9955&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;keywords&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#ff55ff&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;variables&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#5eccf8&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;strings&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#CE9178&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;functions&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#DCDCAA&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;numbers&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#00eeff&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;types&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#55bbff&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;textMateRules&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;scope&quot;</span><span class="punctuation">:</span> <span class="string">&quot;string.quoted.double&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">          <span class="attr">&quot;foreground&quot;</span><span class="punctuation">:</span> <span class="string">&quot;#9CDCFE&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;workbench.editor.untitled.hint&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hidden&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;git.enableSmartCommit&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;git.confirmSync&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;typescript.updateImportsOnFileMove.enabled&quot;</span><span class="punctuation">:</span> <span class="string">&quot;always&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;javascript.updateImportsOnFileMove.enabled&quot;</span><span class="punctuation">:</span> <span class="string">&quot;always&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;editor.maxTokenizationLineLength&quot;</span><span class="punctuation">:</span> <span class="number">1.1111111111111111e22</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;fileheader.customMade&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;Author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;LuckyNwa⭐️&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;Date&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;FilePath&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;LastEditTime&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;Description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;fileheader.cursorMode&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;description&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;param&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;return&quot;</span><span class="punctuation">:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;fileheader.configObj&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;autoAdd&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;autoAddLine&quot;</span><span class="punctuation">:</span> <span class="number">2</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;designAddHead&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;headDesignName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;grassHorse2&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;headDesign&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;prohibitAutoAdd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;json&quot;</span><span class="punctuation">,</span> <span class="string">&quot;md&quot;</span><span class="punctuation">,</span> <span class="string">&quot;vue&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.cjs&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.conf&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.yaml&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.d.ts&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.scss&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.svg&quot;</span><span class="punctuation">,</span> <span class="string">&quot;.ts&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;prohibitItemAutoAdd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;test_vue&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;moveCursor&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;dateFormat&quot;</span><span class="punctuation">:</span> <span class="string">&quot;YYYY-MM-DD HH:mm:ss&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;folderBlacklist&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;node_modules&quot;</span><span class="punctuation">,</span> <span class="string">&quot;vite.config.ts&quot;</span><span class="punctuation">,</span> <span class="string">&quot;vite.config.js&quot;</span><span class="punctuation">,</span> <span class="string">&quot;main.js&quot;</span><span class="punctuation">,</span> <span class="string">&quot;main.ts&quot;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;explorer.compactFolders&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;notebook.compactView&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h1 id="vue3-插件"><a class="markdownIt-Anchor" href="#vue3-插件"></a> Vue3 插件</h1><blockquote><p>⚠️ 记得禁用或删除 Vetur，不然会爆红很多地方</p></blockquote><table><thead><tr><th>插件名</th><th>说明</th></tr></thead><tbody><tr><td><strong>Vue VSCode Snippets</strong></td><td>新 Vue 文件输入 <code>vbase</code> 选模板</td></tr><tr><td><strong>TypeScript Vue Plugin (Volar)</strong></td><td>用于 TypeScript 的 Vue 插件</td></tr><tr><td><strong>Vue Language Features (Volar)</strong></td><td>Vue3.0 语法支持</td></tr><tr><td><strong>WindiCSS IntelliSense</strong></td><td>自动完成、语法高亮、代码折叠</td></tr><tr><td><strong>Iconify IntelliSense</strong></td><td>Iconify 预览和搜索</td></tr><tr><td><strong>i18n Ally</strong></td><td>国际化智能提示</td></tr><tr><td><strong>Stylelint</strong></td><td>CSS 格式化</td></tr><tr><td><strong>Prettier</strong></td><td>代码格式化</td></tr><tr><td><strong>ESLint</strong></td><td>脚本代码检查</td></tr><tr><td><strong>DotENV</strong></td><td><code>.env</code> 文件高亮</td></tr></tbody></table><h1 id="头部注释插件配置"><a class="markdownIt-Anchor" href="#头部注释插件配置"></a> 头部注释插件配置</h1><p>先商店下载 <a href="https://marketplace.visualstudio.com/items?itemName=OBKoro1.korofileheader">koroFileHeader</a>。</p><p>配置路径：VSCode 左下角齿轮 → 设置 → 搜 <code>fileheader.customMade</code> → 点击在 settings.json 中编辑</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;fileheader.customMade&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;Author&quot;</span><span class="punctuation">:</span> <span class="string">&quot;NWA&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;Date&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;FilePath&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;LastEditors&quot;</span><span class="punctuation">:</span> <span class="string">&quot;git config user.name&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;LastEditTime&quot;</span><span class="punctuation">:</span> <span class="string">&quot;Do not edit&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;fileheader.configObj&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;designAddHead&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;headDesignName&quot;</span><span class="punctuation">:</span> <span class="string">&quot;grassHorse2&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;headDesign&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;prohibitAutoAdd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;json&quot;</span><span class="punctuation">,</span> <span class="string">&quot;md&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;prohibitItemAutoAdd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;test_vue&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;autoAddLine&quot;</span><span class="punctuation">:</span> <span class="number">100</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;folderBlacklist&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;node_modules&quot;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h2 id="图案可选代码"><a class="markdownIt-Anchor" href="#图案可选代码"></a> 图案可选代码</h2><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><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></pre></td><td class="code"><pre><span class="line">random            随机</span><br><span class="line">buddhalImg        佛祖</span><br><span class="line">buddhalImgSay     佛祖+佛曰</span><br><span class="line">buddhalSay        佛曰</span><br><span class="line">totemDragon       龙图腾</span><br><span class="line">belle             美女</span><br><span class="line">coderSong         程序员之歌</span><br><span class="line">loitumaGirl       甩葱少女</span><br><span class="line">keyboardAll       全键盘</span><br><span class="line">keyboardSmall     小键盘</span><br><span class="line">totemWestDragon   喷火龙</span><br><span class="line">jesus             耶稣</span><br><span class="line">dog               狗</span><br><span class="line">grassHorse        草泥马</span><br><span class="line">grassHorse2       草泥马2</span><br><span class="line">totemBat          蝙蝠</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">落红不是无情物，化作春泥更护花</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>CSS选择器详解与使用技巧</title>
    <link href="https://luckynwa.top/posts/front1/"/>
    <id>https://luckynwa.top/posts/front1/</id>
    <published>2023-09-30T18:40:10.000Z</published>
    <updated>2026-07-07T16:20:55.846Z</updated>
    
    <content type="html"><![CDATA[<h2 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h2><p><strong>选择器优先级：</strong></p><p>默认(继承) &lt; 通配符选择器 &lt; 标签选择器 &lt; 类选择器 &lt; ID选择器 &lt; 行内样式 &lt; !important</p><h2 id="选择器示例"><a class="markdownIt-Anchor" href="#选择器示例"></a> 选择器示例</h2><figure class="highlight html"><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">exitButton</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;mt-2&quot;</span>&gt;</span>UnoCss的使用<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;w-125 bg-pink h-25 text-5 rounded-full&quot;</span>&gt;</span>直接类里就是样式，原子化Css确实不错<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;h-[10px] mt-[30px]&quot;</span>&gt;</span>指定高度和margin-top，配合vs插件 WindiCSS IntelliSense使用<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;text-[20px] mt-4&quot;</span>&gt;</span>文本20大小，不指定则X4，比如mt-4就是margin-top:16px<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">el-button</span> <span class="attr">type</span>=<span class="string">&quot;success&quot;</span>&gt;</span>深度选择器使用 &gt;&gt;&gt; ::v-deep /deep/ :deep()<span class="tag">&lt;/<span class="name">el-button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">br</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;mt-2&quot;</span>&gt;</span>其他选择器的使用<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">span</span>&gt;</span>标签选择器aqua<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cls&quot;</span>&gt;</span></span><br><span class="line">      类选择器blueviolet</span><br><span class="line">      <span class="tag">&lt;<span class="name">span</span>&gt;</span>类子代，如果span有声明颜色则使用申明的，否则继承cls颜色aqua<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;id1&quot;</span>&gt;</span>id选择器red<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">hr</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span> <span class="attr">class</span>=<span class="string">&quot;mt-2&quot;</span>&gt;</span>复合选择器的使用<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;clsF&quot;</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;children1&quot;</span>&gt;</span></span><br><span class="line">        子代选择器 和 后代选择器</span><br><span class="line">        <span class="tag">&lt;<span class="name">span</span>&gt;</span></span><br><span class="line">          你干嘛1</span><br><span class="line">          <span class="tag">&lt;<span class="name">span</span>&gt;</span></span><br><span class="line">            你干嘛2</span><br><span class="line">            <span class="tag">&lt;<span class="name">span</span>&gt;</span>你干嘛3<span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">          <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;clsB1&quot;</span>&gt;</span>并集选择器1<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;clsB2&quot;</span>&gt;</span>并集选择器2<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;clsB1 clsJ2 clsJ1&quot;</span>&gt;</span>交集选择器<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">&quot;hoverT&quot;</span>&gt;</span>伪类选择器<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">&quot;text&quot;</span> /&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">style</span> <span class="attr">lang</span>=<span class="string">&quot;scss&quot;</span> <span class="attr">scoped</span>&gt;</span><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 属性选择器：<span class="selector-attr">[type]</span>、<span class="selector-attr">[type^=a]</span>、<span class="selector-attr">[title$=a]</span></span></span><br><span class="line"><span class="language-css">  // 包含这个属性以属性值<span class="selector-tag">a</span>开头、以<span class="selector-tag">a</span>结尾</span></span><br><span class="line"><span class="language-css">  <span class="selector-attr">[type=<span class="string">&#x27;text&#x27;</span>]</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: blue;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 结构伪类选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsF</span> &gt; <span class="selector-tag">p</span><span class="selector-pseudo">:first</span>-child &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: skyblue <span class="meta">!important</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsF</span> &gt; <span class="selector-tag">p</span><span class="selector-pseudo">:nth-child</span>(<span class="number">2</span>n) &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: red <span class="meta">!important</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsF</span> &gt; <span class="selector-tag">p</span><span class="selector-pseudo">:last-child</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: skyblue <span class="meta">!important</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 伪类选择器：鼠标悬停变红</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.hoverT</span><span class="selector-pseudo">:hover</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: crimson;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 交集选择器：多个类名无空格</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsJ2</span><span class="selector-class">.clsJ1</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">font-weight</span>: <span class="number">600</span>;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">background</span>: green;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsJ2</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">background</span>: gray <span class="meta">!important</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 并集选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsB2</span>,</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsB1</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">background</span>: pink;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 子代选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsF</span> &gt; <span class="selector-class">.children1</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">font-weight</span>: <span class="number">800</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 后代选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.clsF</span> <span class="selector-tag">span</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: chartreuse;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 标签选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-tag">span</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: aqua;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 类选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-class">.cls</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: blueviolet;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // ID选择器</span></span><br><span class="line"><span class="language-css">  <span class="selector-id">#id1</span> &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: red;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 通配符选择器</span></span><br><span class="line"><span class="language-css">  * &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">font-size</span>: <span class="number">20px</span>;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span></span><br><span class="line"><span class="language-css">  // 深度选择器</span></span><br><span class="line"><span class="language-css">  :<span class="built_in">deep</span>(.el-button &gt; span) &#123;</span></span><br><span class="line"><span class="language-css">    <span class="attribute">color</span>: pink;</span></span><br><span class="line"><span class="language-css">  &#125;</span></span><br><span class="line"><span class="language-css"></span><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br></pre></td></tr></table></figure><h2 id="深度选择器"><a class="markdownIt-Anchor" href="#深度选择器"></a> 深度选择器</h2><p>深度选择器用于修改第三方组件（如 Element-UI）的内部样式。当 <code>&lt;style&gt;</code> 使用 <code>scoped</code> 时，不加深度选择器则无法修改子组件的样式。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">// Vue2 写法</span><br><span class="line">::<span class="built_in">v-deep</span>(.el-button &gt; span) &#123;</span><br><span class="line">  <span class="attribute">color</span>: green;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// Vue3 写法</span><br><span class="line">:<span class="built_in">deep</span>(.el-button &gt; span) &#123;</span><br><span class="line">  <span class="attribute">color</span>: green;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// Vue2 另一种写法</span><br><span class="line">::v-deep .dv-scroll-board .header &#123;</span><br><span class="line">  <span class="attribute">margin-bottom</span>: <span class="number">15px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>使用方式：</strong></p><ul><li><code>.el-form &gt;&gt;&gt; .el-form-item__error</code>（Vue2）</li><li><code>::v-deep</code>（Vue2）</li><li><code>:deep()</code>（Vue3 推荐）</li></ul><h2 id="常用居中方式"><a class="markdownIt-Anchor" href="#常用居中方式"></a> 常用居中方式</h2><p><img src="https://cloud.luckynwa.top/profile/mdS/cssCenter.png" alt="flex居中示意图" /></p><h3 id="方案一绝对定位"><a class="markdownIt-Anchor" href="#方案一绝对定位"></a> 方案一：绝对定位</h3><p>子绝父相，通过 <code>transform</code> 实现居中。</p><figure class="highlight html"><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="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;position: relative; width: 100%; height: 600px; background: pink&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)&quot;</span>&gt;</span>测试<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="方案二flex-布局"><a class="markdownIt-Anchor" href="#方案二flex-布局"></a> 方案二：Flex 布局</h3><p>使用 Flexbox 实现居中，代码更简洁。</p><figure class="highlight html"><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="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;display: flex; justify-content: center; align-items: center; width: 100%; height: 600px; background: pink&quot;</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">style</span>=<span class="string">&quot;background-color: green&quot;</span>&gt;</span>测试<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">不畏浮云遮望眼，自缘身在最高层</summary>
    
    
    
    <category term="前端" scheme="https://luckynwa.top/categories/%E5%89%8D%E7%AB%AF/"/>
    
    
    <category term="Css" scheme="https://luckynwa.top/tags/Css/"/>
    
  </entry>
  
  <entry>
    <title>规则引擎AviatorScript与Spring Validation校验实践</title>
    <link href="https://luckynwa.top/posts/java9/"/>
    <id>https://luckynwa.top/posts/java9/</id>
    <published>2023-09-25T23:45:23.000Z</published>
    <updated>2026-07-07T16:19:34.409Z</updated>
    
    <content type="html"><![CDATA[<h1 id="规则引擎"><a class="markdownIt-Anchor" href="#规则引擎"></a> 规则引擎</h1><p>依赖</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></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!--规则引擎AviatorScript--&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.googlecode.aviator<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>aviator<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.3.3<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></pre></td></tr></table></figure><p>封装成 bean</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.googlecode.aviator.AviatorEvaluator;</span><br><span class="line"><span class="keyword">import</span> lombok.Data;</span><br><span class="line"><span class="keyword">import</span> org.springframework.core.io.ClassPathResource;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> com.googlecode.aviator.Expression;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/31 -14:09</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RuleAv</span>&#123;</span><br><span class="line">    <span class="keyword">private</span>  Expression exp;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">RuleAv</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">String</span> <span class="variable">scriptPath</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathResource</span>(<span class="string">&quot;script/photoController.av&quot;</span>).getPath();</span><br><span class="line">            exp = AviatorEvaluator.getInstance().compileScript(scriptPath);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Error loading script file: &quot;</span> + e.getMessage());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注入</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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Resource</span></span><br><span class="line"><span class="keyword">private</span> RuleAv ruleAv;</span><br><span class="line"></span><br><span class="line">      Map&lt;String, Object&gt; context=<span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();<span class="comment">//传入参数</span></span><br><span class="line">       context.put(<span class="string">&quot;acc&quot;</span>,acc);</span><br><span class="line">       <span class="type">Boolean</span> <span class="variable">flag</span> <span class="operator">=</span>(Boolean) ruleAv.getExp().execute(context);</span><br><span class="line">       <span class="keyword">if</span> (!flag) &#123;</span><br><span class="line">           <span class="keyword">return</span> R.error(<span class="string">&quot;格式有误！&quot;</span>);</span><br><span class="line">       &#125;</span><br></pre></td></tr></table></figure><p>脚本位置放在项目 <code>src/main/resources</code> 下面新建文件夹 <code>script</code>，文件名 <code>photoController.av</code></p><figure class="highlight js"><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="keyword">let</span> regex = <span class="regexp">/^[a-zA-Z]&#123;5,10&#125;$/</span></span><br><span class="line"><span class="title function_">println</span>(regex)</span><br><span class="line"><span class="keyword">return</span> (acc = ~regex)</span><br></pre></td></tr></table></figure><p>demo----测试类</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.other;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.googlecode.aviator.AviatorEvaluator;</span><br><span class="line"><span class="keyword">import</span> com.googlecode.aviator.Expression;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.springframework.core.io.ClassPathResource;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/10 -19:17</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RuleDemo</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testHello</span><span class="params">()</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//AviatorScript脚本的运行，分为两步，编译和执行</span></span><br><span class="line">        <span class="comment">//编译支持编译脚本文件和脚本文本，分别使用compileScript和compile方法。</span></span><br><span class="line">        <span class="comment">//编译产生的  Expression 对象，最终都是调用 execute() 方法执行。</span></span><br><span class="line">        <span class="comment">//这里有个重要能力，execute 方法可以接受一个变量列表组成的 map，来注入执行的上下文</span></span><br><span class="line">        <span class="comment">//获取路径</span></span><br><span class="line">        <span class="type">ClassPathResource</span> <span class="variable">resource</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ClassPathResource</span>(<span class="string">&quot;script/rule.av&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">scriptPath</span> <span class="operator">=</span> resource.getPath();</span><br><span class="line">        <span class="comment">//编译</span></span><br><span class="line">        <span class="type">Expression</span> <span class="variable">exp</span> <span class="operator">=</span> AviatorEvaluator.getInstance().compileScript(scriptPath);<span class="comment">//compileScripti编译路径脚本</span></span><br><span class="line">        <span class="comment">//执行</span></span><br><span class="line">        exp.execute();</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">script2</span> <span class="operator">=</span> <span class="string">&quot;println(\&quot;Hello, AviatorScript!\&quot;);&quot;</span>;</span><br><span class="line">        <span class="comment">//编译</span></span><br><span class="line">        <span class="type">Expression</span> <span class="variable">exp2</span> <span class="operator">=</span> AviatorEvaluator.getInstance().compile(script2); <span class="comment">//compile编译自定义脚本</span></span><br><span class="line">        <span class="comment">//执行</span></span><br><span class="line">        exp2.execute();</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">expression</span> <span class="operator">=</span> <span class="string">&quot;a-(b-c) &gt; 100&quot;</span>;</span><br><span class="line">        <span class="type">Expression</span> <span class="variable">compiledExp</span> <span class="operator">=</span> AviatorEvaluator.compile(expression);</span><br><span class="line"><span class="comment">//上下文</span></span><br><span class="line">        <span class="type">double</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">100.3</span>, b = <span class="number">45</span>, c = -<span class="number">199.100</span>;</span><br><span class="line">        Map&lt;String, Object&gt; context = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        context.put(<span class="string">&quot;a&quot;</span>, a);</span><br><span class="line">        context.put(<span class="string">&quot;b&quot;</span>, b);</span><br><span class="line">        context.put(<span class="string">&quot;c&quot;</span>, c);</span><br><span class="line"><span class="comment">//通过注入的上下文执行</span></span><br><span class="line">        <span class="type">Boolean</span> <span class="variable">result</span> <span class="operator">=</span> (Boolean) compiledExp.execute(context);</span><br><span class="line">        System.out.println(result);</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">public</span> <span class="keyword">void</span> <span class="title function_">demo2</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line"></span><br><span class="line">        <span class="type">Expression</span> <span class="variable">exp</span> <span class="operator">=</span> AviatorEvaluator.getInstance().compileScript(<span class="keyword">new</span> <span class="title class_">ClassPathResource</span>(<span class="string">&quot;script/rule.av&quot;</span>).getPath()); <span class="comment">//获取规则</span></span><br><span class="line">        Map&lt;String, Object&gt; context = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();<span class="comment">//传入参数</span></span><br><span class="line">        context.put(<span class="string">&quot;amount&quot;</span>, <span class="number">1000</span>);</span><br><span class="line">        context.put(<span class="string">&quot;rating&quot;</span>, <span class="number">2</span>);</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> (String) exp.execute(context);</span><br><span class="line">        System.out.println(result);</span><br><span class="line">        <span class="comment">//它还能解析一个实例对象，脚本里直接调用testBeanIns.print(testBean);这个实例的print的方法</span></span><br><span class="line"><span class="comment">//        AviatorEvaluator.addInstanceFunctions(&quot;testBeanIns&quot;, TestBean.class);</span></span><br><span class="line"><span class="comment">//        Expression exp = AviatorEvaluator.getInstance().compileScript(&quot;example.av&quot;, true);//true是开启缓存</span></span><br><span class="line"><span class="comment">//        Map&lt;String, Object&gt; env = new HashMap&lt;String, Object&gt;();</span></span><br><span class="line"><span class="comment">//        env.put(&quot;testBean&quot;, testBean);</span></span><br><span class="line"><span class="comment">//        exp.execute(env);</span></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">public</span> <span class="keyword">void</span> <span class="title function_">fun88</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">Expression</span> <span class="variable">exp</span> <span class="operator">=</span> AviatorEvaluator.getInstance().compileScript(<span class="keyword">new</span> <span class="title class_">ClassPathResource</span>(<span class="string">&quot;script/rule.av&quot;</span>).getPath()); <span class="comment">//获取规则</span></span><br><span class="line">        Map&lt;String, Object&gt; context = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();<span class="comment">//传入参数</span></span><br><span class="line">        context.put(<span class="string">&quot;acc&quot;</span>, <span class="string">&quot;lucky&quot;</span>);</span><br><span class="line">        <span class="type">Boolean</span> <span class="variable">result</span> <span class="operator">=</span> (Boolean) exp.execute(context);</span><br><span class="line">        System.out.println(result);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="spring-validation"><a class="markdownIt-Anchor" href="#spring-validation"></a> Spring Validation</h1><p>参考：<a href="https://blog.51cto.com/u_15964717/6093652">https://blog.51cto.com/u_15964717/6093652</a></p><p>如果 spring-boot 版本小于 2.3.x，spring-boot-starter-web 会自动传入 hibernate-validator 依赖；</p><p>如果 spring-boot 版本大于 2.3.x，则需要手动引入依赖：</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></pre></td><td class="code"><pre><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.hibernate<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>hibernate-validator<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>6.0.18.Final<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></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.hibernate.validator.HibernateValidator;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.validation.beanvalidation.MethodValidationPostProcessor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.validation.Validation;</span><br><span class="line"><span class="keyword">import</span> javax.validation.Validator;</span><br><span class="line"><span class="keyword">import</span> javax.validation.ValidatorFactory;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * web参数验证配置</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> luckyNwa</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2023/10/20</span></span><br><span class="line"><span class="comment"> */</span></span><br><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_">WebParamValidateConfig</span> &#123;</span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> Validator <span class="title function_">validator</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">ValidatorFactory</span> <span class="variable">validatorFactory</span> <span class="operator">=</span> Validation.byProvider(HibernateValidator.class)</span><br><span class="line">                .configure()</span><br><span class="line">                .failFast(<span class="literal">true</span>)   <span class="comment">//只要出现校验失败的情况，就立即结束校验，不再进行后续的</span></span><br><span class="line">                .buildValidatorFactory();</span><br><span class="line">        <span class="keyword">return</span> validatorFactory.getValidator();</span><br><span class="line">    &#125;</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> MethodValidationPostProcessor <span class="title function_">methodValidationPostProcessor</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">MethodValidationPostProcessor</span> <span class="variable">methodValidationPostProcessor</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">MethodValidationPostProcessor</span>();</span><br><span class="line">        methodValidationPostProcessor.setValidator(validator());</span><br><span class="line">        <span class="keyword">return</span> methodValidationPostProcessor;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.common.exception;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.common.untils.Constant;</span><br><span class="line"><span class="keyword">import</span> com.nwa.common.untils.R;</span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.springframework.dao.DuplicateKeyException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.validation.BindException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.MethodArgumentNotValidException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.ExceptionHandler;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.ResponseBody;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RestControllerAdvice;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.NoHandlerFoundException;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.config.annotation.EnableWebMvc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.validation.ConstraintViolationException;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 处理自定义异常</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> luckyNwa</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@date</span> 2023/10/16</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RestControllerAdvice</span></span><br><span class="line"><span class="meta">@EnableWebMvc</span>  <span class="comment">//开启这个和配置mvc才能自定义404页面信息返回</span></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RRExceptionHandler</span> &#123;</span><br><span class="line">    <span class="meta">@ExceptionHandler(LukcyException.class)</span><span class="comment">//继承运行时异常</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleRRException</span><span class="params">(LukcyException e)</span> &#123;</span><br><span class="line">        <span class="type">R</span> <span class="variable">r</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">        r.put(<span class="string">&quot;code&quot;</span>, e.getCode());</span><br><span class="line">        r.put(<span class="string">&quot;msg&quot;</span>, e.getMessage());</span><br><span class="line">        <span class="keyword">return</span> r;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@ExceptionHandler(NoHandlerFoundException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">noHandlerFoundException</span><span class="params">(Exception e)</span> &#123;</span><br><span class="line">        log.error(<span class="string">&quot;路径不存在，请检查接口是否正确,&quot;</span> + e.getMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="number">404</span>, <span class="string">&quot;路径不存在，请检查接口是否正确&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@ExceptionHandler(DuplicateKeyException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">duplicateKeyException</span><span class="params">(DuplicateKeyException e)</span> &#123;</span><br><span class="line">        log.error(<span class="string">&quot;数据库中已存在该记录&quot;</span> + e.getMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="number">400</span>, <span class="string">&quot;数据库中已存在该记录&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//    @ExceptionHandler(HttpMessageNotReadableException.class)</span></span><br><span class="line"><span class="comment">//    @ResponseBody</span></span><br><span class="line"><span class="comment">//    public R HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) &#123;</span></span><br><span class="line"><span class="comment">//        log.error(e.getMessage());</span></span><br><span class="line"><span class="comment">//        return R.error(Constant.VALIDATOR_ERROR, Constant.PARAM_ERROR);</span></span><br><span class="line"><span class="comment">//    &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 处理请求参数格式错误 <span class="doctag">@RequestBody</span>上使用<span class="doctag">@Valid</span> 实体上使用<span class="doctag">@NotNull</span>等，验证失败后抛出的异常是MethodArgumentNotValidException异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(MethodArgumentNotValidException.class)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">methodArgumentNotValidException</span><span class="params">(MethodArgumentNotValidException e)</span> &#123;</span><br><span class="line">        log.error(e.getBindingResult().getFieldError().getDefaultMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error(Constant.VALIDATOR_ERROR, e.getBindingResult().getFieldError().getDefaultMessage());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 处理Get请求中 使用<span class="doctag">@Valid</span> 验证路径中请求实体校验失败后抛出的异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(BindException.class)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">BindExceptionHandler</span><span class="params">(BindException e)</span> &#123;</span><br><span class="line">        log.error(e.getBindingResult().getFieldError().getDefaultMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error(Constant.VALIDATOR_ERROR, e.getBindingResult().getFieldError().getDefaultMessage());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 处理请求参数格式错误 <span class="doctag">@RequestParam</span>上validate失败后抛出的异常是ConstraintViolationException</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(ConstraintViolationException.class)</span></span><br><span class="line">    <span class="meta">@ResponseBody</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">ConstraintViolationExceptionHandler</span><span class="params">(ConstraintViolationException e)</span> &#123;</span><br><span class="line">        log.error(e.getMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error(Constant.VALIDATOR_ERROR, e.getMessage());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="meta">@ExceptionHandler(Exception.class)</span><span class="comment">//最大的异常处理</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleException</span><span class="params">(Exception e)</span> &#123;</span><br><span class="line">        log.error(e.getMessage());</span><br><span class="line">        <span class="keyword">return</span> R.error();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.common.exception;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">LukcyException</span> <span class="keyword">extends</span> <span class="title class_">RuntimeException</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">serialVersionUID</span> <span class="operator">=</span> <span class="number">1L</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> String msg;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">code</span> <span class="operator">=</span> <span class="number">400</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LukcyException</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LukcyException</span><span class="params">(String msg, Throwable e)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg, e);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LukcyException</span><span class="params">(String msg, <span class="type">int</span> code)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">LukcyException</span><span class="params">(String msg, <span class="type">int</span> code, Throwable e)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg, e);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getMsg</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> msg;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setMsg</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getCode</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> code;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCode</span><span class="params">(<span class="type">int</span> code)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.common.untils;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 返回数据</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">R</span> <span class="keyword">extends</span> <span class="title class_">HashMap</span>&lt;String, Object&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">serialVersionUID</span> <span class="operator">=</span> <span class="number">1L</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">R</span><span class="params">()</span> &#123;</span><br><span class="line">        put(<span class="string">&quot;code&quot;</span>, <span class="number">200</span>);</span><br><span class="line">        put(<span class="string">&quot;msg&quot;</span>, <span class="string">&quot;数据返回成功!&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> R <span class="title function_">error</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> error(<span class="number">500</span>, <span class="string">&quot;未知异常，请联系管理员&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> R <span class="title function_">error</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> error(<span class="number">400</span>, msg);</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> R <span class="title function_">error</span><span class="params">(<span class="type">int</span> code, String msg)</span> &#123;</span><br><span class="line">        <span class="type">R</span> <span class="variable">r</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">        r.put(<span class="string">&quot;code&quot;</span>, code);</span><br><span class="line">        r.put(<span class="string">&quot;msg&quot;</span>, msg);</span><br><span class="line">        <span class="keyword">return</span> r;</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> R <span class="title function_">ok</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="type">R</span> <span class="variable">r</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">        r.put(<span class="string">&quot;msg&quot;</span>, msg);</span><br><span class="line">        <span class="keyword">return</span> r;</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> R <span class="title function_">ok</span><span class="params">(Map&lt;String, Object&gt; map)</span> &#123;</span><br><span class="line">        <span class="type">R</span> <span class="variable">r</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">        r.putAll(map);</span><br><span class="line">        <span class="keyword">return</span> r;</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> R <span class="title function_">ok</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">put</span><span class="params">(String key, Object value)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>.put(key, value);</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@NotEmpty(message = &quot;添加课程名称不能为空&quot;,groups=&#123;ValidationGroups.Inster.class&#125;)</span></span><br><span class="line"><span class="meta">@NotEmpty(message = &quot;修改课程名称不能为空&quot;,groups=&#123;ValidationGroups.Update.class&#125;)</span></span><br><span class="line"><span class="meta">@ApiModelProperty(value = &quot;课程名称&quot;, required = true)</span></span><br><span class="line"><span class="keyword">private</span> String name;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">ValidationGroups</span> &#123;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//用于添加校验</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Inster</span>&#123;&#125;;</span><br><span class="line"> <span class="comment">//用于修改校验</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Update</span>&#123;&#125;;</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">Delete</span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>调用在 Controller 方法上，选择方式</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Validated(ValidationGroups.Inster.class)</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">雄关漫道真如铁，而今迈步从头越</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Tomcat 环境</title>
    <link href="https://luckynwa.top/posts/tool13/"/>
    <id>https://luckynwa.top/posts/tool13/</id>
    <published>2023-09-22T23:01:33.000Z</published>
    <updated>2026-07-07T16:19:34.192Z</updated>
    
    <content type="html"><![CDATA[<h1 id="环境变量配置"><a class="markdownIt-Anchor" href="#环境变量配置"></a> 环境变量配置</h1><p>版本：<code>apache-tomcat-8.5.83</code></p><p>新建环境变量：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CATALINA_HOME    D:\bgsoft\apache-tomcat-8.5.83</span><br><span class="line">CATALINA_BASE    D:\bgsoft\apache-tomcat-8.5.83</span><br></pre></td></tr></table></figure><p><code>Path</code> 中添加：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%CATALINA_HOME%\bin</span><br></pre></td></tr></table></figure><h1 id="乱码问题修复"><a class="markdownIt-Anchor" href="#乱码问题修复"></a> 乱码问题修复</h1><p>修改 <code>D:\bgsoft\apache-tomcat-8.5.83\conf\logging.properties</code></p><p>第 47 行：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java.util.logging.ConsoleHandler.encoding = UTF-8</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></pre></td><td class="code"><pre><span class="line">java.util.logging.ConsoleHandler.encoding = GBK</span><br></pre></td></tr></table></figure><h1 id="启动与访问"><a class="markdownIt-Anchor" href="#启动与访问"></a> 启动与访问</h1><p>去 <code>bin</code> 目录 CMD 运行 <code>startup.bat</code> 打开服务器，浏览器访问：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://localhost:8080/</span><br></pre></td></tr></table></figure><h1 id="部署-war-包"><a class="markdownIt-Anchor" href="#部署-war-包"></a> 部署 WAR 包</h1><ul><li>将 WAR 包放在 <code>D:\bgsoft\apache-tomcat-8.5.83\webapps</code> 中</li><li>访问 <code>http://localhost:8080/luckyNwa</code>（后面是 WAR 的名称）</li><li>静态页面：<code>http://localhost:8080/luckyDemo/goodsTb.html</code></li><li>也可以上传 WAR 包到 Tomcat 服务器，点击 <code>Manager App</code>，输入账号 <code>root</code> 密码 <code>123456</code></li></ul><h1 id="idea-使用本地-tomcat"><a class="markdownIt-Anchor" href="#idea-使用本地-tomcat"></a> IDEA 使用本地 Tomcat</h1><p>IDEA 上面点编辑 → <code>+</code> → 找到 Tomcat 本地 → Name 起个名 → Deployment 选择 Artifact 的项目编译 WAR → 确定即可运行。</p>]]></content>
    
    
    <summary type="html">苟利国家生死以，岂因祸福避趋之</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>RocketMQ</title>
    <link href="https://luckynwa.top/posts/tool12/"/>
    <id>https://luckynwa.top/posts/tool12/</id>
    <published>2023-09-15T19:40:11.000Z</published>
    <updated>2026-07-07T16:19:34.210Z</updated>
    
    <content type="html"><![CDATA[<h1 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h1><p>移动包到 <code>D:\bgsoft\rocketmq-4.9.3</code></p><ol><li>运行 <code>bin</code> 下 <code>mqnamesrv.cmd</code></li><li>在 <code>bin</code> 目录下打开 CMD，输入：</li></ol><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mqbroker.cmd -n localhost:9876</span><br></pre></td></tr></table></figure><h1 id="配置修改文件夹中已配置"><a class="markdownIt-Anchor" href="#配置修改文件夹中已配置"></a> 配置修改（文件夹中已配置）</h1><p><strong>修改 <code>bin/runserver.cmd</code> 的 <code>JAVA_OPT</code>：</strong></p><figure class="highlight shell"><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">rem set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g&quot;</span><br><span class="line">set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms256m -Xmx512m&quot;</span><br></pre></td></tr></table></figure><p><strong>修改 <code>bin/runbroker.cmd</code> 的 <code>JAVA_OPT</code>：</strong></p><figure class="highlight shell"><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">rem set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g&quot;</span><br><span class="line">set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms256m -Xmx512m&quot;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">男儿何不带吴钩，收取关山五十州</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Middleware" scheme="https://luckynwa.top/tags/Middleware/"/>
    
  </entry>
  
  <entry>
    <title>MySQL核心知识点总结</title>
    <link href="https://luckynwa.top/posts/java7/"/>
    <id>https://luckynwa.top/posts/java7/</id>
    <published>2023-09-12T00:11:17.000Z</published>
    <updated>2026-07-07T16:19:34.409Z</updated>
    
    <content type="html"><![CDATA[<h1 id="常用以及总结"><a class="markdownIt-Anchor" href="#常用以及总结"></a> 常用以及总结</h1><p>设计数据库时候：</p><p>一个汉字占 3 个字节，varchar(255)最多存 85 汉字</p><p>理论上可以存 255 字符、如果是中文字符(占 2 个字节)，127 个中文字符</p><p>位（bit）：数据存储的最小单位。每个二进制数字 0 或者 1 就是 1 个位；</p><p>字节（byte）： 8 个位构成一个字节；即：1 byte (字节)= 8 bit(位)；</p><p>字符：是指计算机中使用的字母、数字、字和符号。</p><p>int 是整型而且有 4 个字节=32 位，并且符号位占一位，它有自己的范围-2<sup>31，2</sup>31-1 即</p><p>[-2147483648,2147483647] 有 10 位 如果数字超过它的最大值，手机号 是 11 位，共五个字节(11 位)则用 long 类型或者 String</p><h1 id="数据类型"><a class="markdownIt-Anchor" href="#数据类型"></a> 数据类型</h1><h2 id="int"><a class="markdownIt-Anchor" href="#int"></a> int</h2><p>int(11)、tinyint(4) 、smallint(6)、mediumint(9)、bigint(20) 整形选个合适长度，不改它</p><p>varchar(255)、char(1) 这边需要根据需求改长度，这里的长度是字符，255 就是可以存 255 个字符</p><p><em>tip：括号里面是它的默认长度也是固定长度，比如 int 是默认长度你有一个值 199，这个长度小于 3 所以它会填 0 来补充 00000000199</em></p><h2 id="char"><a class="markdownIt-Anchor" href="#char"></a> char</h2><p>char 是一个是固定长度,varchar 是可变长度</p><p>为了提高 char 类型的性能，可以采取以下措施：</p><ul><li><p>使用 char 类型的等值查询，避免使用模糊查询。</p></li><li><p>避免使用过长的 char 类型，尽量选择合适的长度。</p></li><li><p>将 char 类型的列设置为 NOT NULL，以提高查询速度。</p></li><li><p>将 char 类型的列设置为索引，以提高查询速度。</p></li></ul><p>从空间上考虑，用 varchar 合适；从效率上考虑，用 char 合适，关键是根据实际情况找到权衡点，所有当需要大量查询需求的时候，用 char。当对于保存数据量过大的需求时，为了节省储存空间用 varchar。</p><h2 id="text"><a class="markdownIt-Anchor" href="#text"></a> text</h2><p>没有默认长度，最大长度为 65,535(2 的 16 次方–1)字符的 TEXT 列。</p><p>Text 主要是用来存放非二进制的文本，如论坛帖子,题目，或者百度知道的问题和回答之类。TEXT 列不能有默认值，存储或检索过程中，不存在大小写转换，后面如果指定长度，不会报错误，但是这个长度是不起作用的，意思就是你插入数据的时候，超过你指定的长度还是可以正常插入。其实可以总结为用来储存大批量的文本信息的时候，使用 TEXT。</p><h2 id="日期"><a class="markdownIt-Anchor" href="#日期"></a> 日期</h2><p>datetime 显示 YYYY-MM-DD HH:MM:SS’格式显示 日期时间</p><p>date 只有日期</p><p>time 只有时间</p><p>timestamp 列类型可以使用它自动地用当前的日期和时间标记 INSERT 或 UPDATE 的操作。</p><p>它有 2 个属性值 CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP</p><h1 id="数据库操作"><a class="markdownIt-Anchor" href="#数据库操作"></a> 数据库操作</h1><p>（创建 Create、检索 Retrieve、更改 Update、删除 Delete）</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">查：select * from 表名 where 条件</span><br><span class="line">删：delect from 表名 where 条件</span><br><span class="line">改：update 表名 set 字段1=对应值1，..  where 条件</span><br><span class="line">增：insert into 表名(字段1,字段2..) values(对应值1,对应值2...)</span><br></pre></td></tr></table></figure><p>查和删不加条件，则全部查找、删除；</p><p>增也可以不加字段 1、…，直接 values 对应上值也行，而且也可以插入多条，直接 values 后面再逗号继续插入值</p><p>多表查的时候有共同的字段，需要声明一下是哪个表里面的.</p><p>mysql 里运行不区分大小写，尽量都大写</p><p>– (默认升序 asc 数据条从上到下递增 降序 desc)</p><p>HAVING 是分组之后加的条件</p><h1 id="六大范式"><a class="markdownIt-Anchor" href="#六大范式"></a> 六大范式</h1><p>英文 Normal form</p><p>第一范式（1NF）、第二范式（2NF）、第三范式（3NF）、巴斯-科德范式（BCNF）、第四范式(4NF）和第五范式（5NF，又称完美范式）。满足最低要求的范式是第一范式（1NF）。在第一范式的基础上进一步满足更多规范要求的称为第二范式（2NF），其余范式以次类推。一般数据库只需满足第三范式(3NF）。</p><p><strong>第一范式（1NF）</strong>：强调属性的原子性。即属性不可再分。</p><p>比如：学生表中</p><p>id 学生姓名 学生学号 学生人数 手机号 符合</p><p>id 学生姓名 学生（学生学号 学生人数） 手机号 不符合</p><p>再比如一个字段家庭地址，那肯定有省市区这些值，这些值也可以看出一张表，所以不满足，<strong>不允许表中还有表</strong>，一个字段只存储一项信息</p><p><strong>第二范式（2NF）</strong>：第二范式就是在第一范式的基础上属性完全依赖于主键。也可以说是在第一范式的基础上，消除了非主属性对码的部分函数依赖。</p><p>比如：学生表中</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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    小嗯  语文  1班  99</span><br><span class="line">1    小嗯  数学  1班  98</span><br><span class="line">2    小维  语文  2班  97</span><br><span class="line">2    小维  科学  2班  100</span><br></pre></td></tr></table></figure><p>可以看出(课程) → (分数)<br />(学号) → (姓名, 班级)</p><p>1.元组：表中的一行就是一个元组。</p><p>2.码:一个表中,可以唯一决定一个元组的属性&quot;集合&quot;。假设 k 为表中的某个属性,在 k 确定的情况下,这个表中的其他属性都可以确定,那么 k 就叫做候选码，也叫码。</p><p>(学号，课程)这个属性组就叫做码。</p><p>3.主属性:码里面的属性就是主属性。</p><p>4.部分函数依赖：比如上表中<strong>学号和课程组成主键</strong>已经不满足 2NF，那么你必须知道这 2 个的值才能知道后面列对应的值，就像 Z=X+Y 一样，你输入一个 X 不知道 Y 无法得到 Z，而 Z=X，Z=Y 就是部分函数依赖。而且这张表数据冗余，可以分成 2 张表</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">学号 课程 分数                  学号  姓名  班级</span><br><span class="line">1    语文  99                   1    小嗯  1班</span><br><span class="line">1    数学  98                   2    小维  2班</span><br><span class="line">2    语文  97</span><br><span class="line">2    科学  100</span><br></pre></td></tr></table></figure><p>上面 2 张表属性都完全依赖于主键学号，这就是第二范式</p><p><strong>第三范式（3NF）</strong>： 在 2NF 的基础上，消除了非主属性对于码的传递函数依赖。即，如果存在非主属性对于码的传递函数依赖,则不符合 3NF。</p><figure class="highlight plaintext"><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">订单id  商品id  商品尺寸</span><br><span class="line">1        1      22</span><br></pre></td></tr></table></figure><p>可以看出主键订单 id，满足第二范式，商品 id 依赖订单 id，商品尺寸依赖商品 id，所以不满足第三范式，分成下面 2 张表即可满足</p><figure class="highlight plaintext"><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">订单id  商品id            商品id   商品尺寸</span><br><span class="line">1        1                 1        22</span><br></pre></td></tr></table></figure><p>再比如有字段 学号 学生 系名称 系主任 ，可以看出系名称依赖学号，系主任依赖系名称，像上面拆成 2 表即可</p><h1 id="常用语法"><a class="markdownIt-Anchor" href="#常用语法"></a> 常用语法</h1><h2 id="对数据库的操作"><a class="markdownIt-Anchor" href="#对数据库的操作"></a> 对数据库的操作</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> databases;                      <span class="comment">-- 查看所有的数据库</span></span><br><span class="line"><span class="keyword">create</span> database test;                <span class="comment">-- 创建一个叫test的数据库</span></span><br><span class="line"><span class="keyword">drop</span> database test;                  <span class="comment">-- 删除一个叫test的数据库</span></span><br><span class="line"><span class="keyword">show</span> <span class="keyword">create</span> database 库名;           <span class="comment">-- 查看创建库的详细信息</span></span><br><span class="line">use test;                            <span class="comment">-- 选中库，建表之前必须要选择数据库</span></span><br></pre></td></tr></table></figure><h2 id="表的操作"><a class="markdownIt-Anchor" href="#表的操作"></a> 表的操作</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> tables;                         <span class="comment">-- 在选中的数据库之中查看所有的表</span></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> 表名 (字段<span class="number">1</span> 类型, 字段<span class="number">2</span> 类型);</span><br><span class="line"><span class="keyword">desc</span> 表名;                           <span class="comment">-- 查看所在的表的字段</span></span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> 表名;                     <span class="comment">-- 删除表</span></span><br><span class="line"><span class="keyword">show</span> <span class="keyword">create</span> <span class="keyword">table</span> 表名;              <span class="comment">-- 查看创建表的详细信息</span></span><br></pre></td></tr></table></figure><p>修改表结构：</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 modify 字段 字段类型;                    <span class="comment">-- 修改字段类型</span></span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">add</span> 字段 字段类型;                       <span class="comment">-- 添加新的字段</span></span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">add</span> 字段 字段类型 after 字段;            <span class="comment">-- 添加字段并指定位置</span></span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 <span class="keyword">drop</span> 字段名;                             <span class="comment">-- 删除表字段</span></span><br><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> 表名 change 原字段名字 新的字段名字 字段类型;  <span class="comment">-- 修改指定的字段</span></span><br></pre></td></tr></table></figure><h2 id="增"><a class="markdownIt-Anchor" href="#增"></a> 增</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> 表名[(字段<span class="number">1</span>，字段<span class="number">2</span>，…)] <span class="keyword">values</span>(<span class="string">&#x27;值1&#x27;</span>,<span class="string">&#x27;值2&#x27;</span>,…);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 1.1 不指定字段（很少用）</span></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> 表名 <span class="keyword">values</span>(值<span class="number">1</span>，值<span class="number">2</span>，…);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 1.2 指定字段（较常用）</span></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> 表名(字段<span class="number">1</span>，字段<span class="number">2</span>…) <span class="keyword">values</span>(值<span class="number">1</span>，值<span class="number">2</span>，…);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 1.3 批量插入</span></span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> 表名(字段<span class="number">1</span>，字段<span class="number">2</span>…) <span class="keyword">values</span>(值<span class="number">1</span>，值<span class="number">2</span>，…),(值<span class="number">1</span>，值<span class="number">2</span>，…),(值<span class="number">1</span>，值<span class="number">2</span>，…);</span><br></pre></td></tr></table></figure><h2 id="删"><a class="markdownIt-Anchor" href="#删"></a> 删</h2><figure class="highlight sql"><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="keyword">delete</span> <span class="keyword">from</span> 表名 <span class="keyword">where</span> 条件;</span><br><span class="line"><span class="comment">-- 注意：where 条件必须加，否则数据会被全部删除</span></span><br></pre></td></tr></table></figure><h2 id="改"><a class="markdownIt-Anchor" href="#改"></a> 改</h2><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 class="keyword">update</span> 表名 <span class="keyword">set</span> 字段<span class="number">1</span> <span class="operator">=</span> 值<span class="number">1</span>, 字段<span class="number">2</span> <span class="operator">=</span> 值<span class="number">2</span> <span class="keyword">where</span> 条件;</span><br></pre></td></tr></table></figure><h2 id="查"><a class="markdownIt-Anchor" href="#查"></a> 查</h2><figure class="highlight sql"><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="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> 表名;                          <span class="comment">-- 查询表中的所有数据</span></span><br><span class="line"><span class="keyword">select</span> 字段 <span class="keyword">from</span> 表名;                       <span class="comment">-- 指定数据查询</span></span><br><span class="line"><span class="keyword">select</span> 字段 <span class="keyword">from</span> 表名 <span class="keyword">where</span> 条件;            <span class="comment">-- 根据条件查询（最常用）</span></span><br></pre></td></tr></table></figure><h2 id="where语句"><a class="markdownIt-Anchor" href="#where语句"></a> where语句</h2><p>关系：&gt;,&lt;,&gt;=,&lt;=,!=</p><p>逻辑：or或, and并且</p><p>区间：id between 4 and 6 ;闭区间，包含边界</p><h2 id="多表查询"><a class="markdownIt-Anchor" href="#多表查询"></a> 多表查询</h2><h3 id="内连接"><a class="markdownIt-Anchor" href="#内连接"></a> 内连接</h3><figure class="highlight sql"><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="comment">-- 隐式内连接</span></span><br><span class="line"><span class="keyword">select</span> username,name <span class="keyword">from</span> <span class="keyword">user</span>,goods <span class="keyword">where</span> user.gid<span class="operator">=</span>goods.gid;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 显示内连接</span></span><br><span class="line"><span class="keyword">select</span> username <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">inner</span> <span class="keyword">join</span> goods <span class="keyword">on</span> user.gid<span class="operator">=</span>goods.gid;</span><br></pre></td></tr></table></figure><h3 id="外连接"><a class="markdownIt-Anchor" href="#外连接"></a> 外连接</h3><figure class="highlight sql"><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="comment">-- 左连接：包含所有的左边表中的记录以及右边表中没有和他匹配的记录</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">left</span> <span class="keyword">join</span> goods <span class="keyword">on</span> user.gid<span class="operator">=</span>goods.gid;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 右连接</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">right</span> <span class="keyword">join</span> goods <span class="keyword">on</span> user.gid<span class="operator">=</span>goods.gid;</span><br></pre></td></tr></table></figure><h3 id="子查询"><a class="markdownIt-Anchor" href="#子查询"></a> 子查询</h3><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 class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">where</span> gid <span class="keyword">in</span>(<span class="keyword">select</span> gid <span class="keyword">from</span> goods);</span><br></pre></td></tr></table></figure><h3 id="联合查询"><a class="markdownIt-Anchor" href="#联合查询"></a> 联合查询</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">left</span> <span class="keyword">join</span> goods <span class="keyword">on</span> user.gid<span class="operator">=</span>goods.gid</span><br><span class="line"><span class="keyword">union</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> <span class="keyword">user</span> <span class="keyword">right</span> <span class="keyword">join</span> goods <span class="keyword">on</span> user.gid<span class="operator">=</span>goods.gid;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 两个表同时更新</span></span><br><span class="line"><span class="keyword">update</span> <span class="keyword">user</span> u, goods g <span class="keyword">set</span> u.gid<span class="operator">=</span><span class="number">12</span>, g.price<span class="operator">=</span><span class="number">1</span> <span class="keyword">where</span> u.id<span class="operator">=</span><span class="number">2</span> <span class="keyword">and</span> u.gid<span class="operator">=</span>g.gid;</span><br></pre></td></tr></table></figure><h1 id="进阶查询"><a class="markdownIt-Anchor" href="#进阶查询"></a> 进阶查询</h1><h2 id="基础查询"><a class="markdownIt-Anchor" href="#基础查询"></a> 基础查询</h2><figure class="highlight sql"><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="comment">-- 全表查询</span></span><br><span class="line"><span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> student;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 选择查询</span></span><br><span class="line"><span class="keyword">select</span> name, gender <span class="keyword">from</span> students;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 别名</span></span><br><span class="line"><span class="keyword">select</span> name <span class="keyword">as</span> 员工姓名, position <span class="keyword">as</span> 职位名称 <span class="keyword">from</span> employees;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 常量和运算</span></span><br><span class="line"><span class="keyword">select</span> order_id, unit_price, quantity, unit_price <span class="operator">*</span> quantity <span class="keyword">as</span> total_amount <span class="keyword">from</span> orders;</span><br></pre></td></tr></table></figure><h2 id="条件查询"><a class="markdownIt-Anchor" href="#条件查询"></a> 条件查询</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- where</span></span><br><span class="line"><span class="keyword">select</span> name, price, stock <span class="keyword">from</span> products <span class="keyword">where</span> stock <span class="operator">&lt;=</span> <span class="number">20</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 运算符</span></span><br><span class="line"><span class="keyword">select</span> name, age, salary <span class="keyword">from</span> employees <span class="keyword">where</span> name <span class="operator">!=</span> <span class="string">&#x27;小张&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 空值</span></span><br><span class="line"><span class="keyword">select</span> name, age <span class="keyword">from</span> employees <span class="keyword">where</span> hire_date <span class="keyword">is</span> <span class="keyword">null</span>;  <span class="comment">-- 还有IS NOT NULL</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 模糊查询</span></span><br><span class="line"><span class="keyword">select</span> name, age, position <span class="keyword">from</span> employees <span class="keyword">where</span> name <span class="keyword">like</span> <span class="string">&#x27;%张%&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 逻辑运算</span></span><br><span class="line"><span class="keyword">select</span> name, age, salary <span class="keyword">from</span> employees <span class="keyword">where</span> name <span class="keyword">like</span> <span class="string">&#x27;%李%&#x27;</span> <span class="keyword">and</span> age <span class="operator">&lt;</span> <span class="number">30</span>;</span><br></pre></td></tr></table></figure><h2 id="去重与排序"><a class="markdownIt-Anchor" href="#去重与排序"></a> 去重与排序</h2><figure class="highlight sql"><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="comment">-- 去重</span></span><br><span class="line"><span class="keyword">select</span> <span class="keyword">distinct</span> class_id <span class="keyword">from</span> students;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 排序 默认升序（ASC）或降序（DESC）</span></span><br><span class="line"><span class="keyword">select</span> name, score <span class="keyword">from</span> students <span class="keyword">order</span> <span class="keyword">by</span> score <span class="keyword">desc</span>;</span><br></pre></td></tr></table></figure><h2 id="分页"><a class="markdownIt-Anchor" href="#分页"></a> 分页</h2><figure class="highlight sql"><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="comment">-- LIMIT 后只跟一个整数，表示要截断的数据条数（一次获取几条）</span></span><br><span class="line"><span class="keyword">select</span> task_name, due_date <span class="keyword">from</span> tasks limit <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- LIMIT 后跟 2 个整数，依次表示所从第几条数据开始、一次获取几条 索引0开始</span></span><br><span class="line"><span class="keyword">select</span> task_name, due_date <span class="keyword">from</span> tasks limit <span class="number">2</span>, <span class="number">2</span>;</span><br></pre></td></tr></table></figure><h2 id="条件分支"><a class="markdownIt-Anchor" href="#条件分支"></a> 条件分支</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">  name,</span><br><span class="line">  <span class="keyword">CASE</span> <span class="keyword">WHEN</span> (name <span class="operator">=</span> <span class="string">&#x27;鸡哥&#x27;</span>) <span class="keyword">THEN</span> <span class="string">&#x27;会&#x27;</span> <span class="keyword">ELSE</span> <span class="string">&#x27;不会&#x27;</span> <span class="keyword">END</span> <span class="keyword">AS</span> can_rap</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">  student;</span><br></pre></td></tr></table></figure><h2 id="内置函数"><a class="markdownIt-Anchor" href="#内置函数"></a> 内置函数</h2><figure class="highlight sql"><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 class="comment">-- 时间函数</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="type">DATE</span>() <span class="keyword">AS</span> <span class="built_in">current_date</span>;        <span class="comment">-- 获取当前日期</span></span><br><span class="line"><span class="keyword">SELECT</span> DATETIME() <span class="keyword">AS</span> current_datetime; <span class="comment">-- 获取当前日期时间</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="type">TIME</span>() <span class="keyword">AS</span> <span class="built_in">current_time</span>;        <span class="comment">-- 获取当前时间</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 字符串处理  UPPER转大写 LENGTH获长度 LOWER转小写</span></span><br><span class="line"><span class="keyword">SELECT</span> name, <span class="built_in">UPPER</span>(name) <span class="keyword">AS</span> upper_name <span class="keyword">FROM</span> employees;</span><br></pre></td></tr></table></figure><h2 id="聚合函数"><a class="markdownIt-Anchor" href="#聚合函数"></a> 聚合函数</h2><p>COUNT：计算指定列的行数或非空值的数量。</p><p>SUM：计算指定列的数值之和。</p><p>AVG：计算指定列的数值平均值。</p><p>MAX：找出指定列的最大值。</p><p>MIN：找出指定列的最小值。</p><figure class="highlight sql"><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="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> order_num <span class="keyword">FROM</span> orders;</span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="keyword">DISTINCT</span> customer_id) <span class="keyword">AS</span> customer_num <span class="keyword">FROM</span> orders;  <span class="comment">-- 订单表中不同客户的数量</span></span><br></pre></td></tr></table></figure><h2 id="分组与过滤"><a class="markdownIt-Anchor" href="#分组与过滤"></a> 分组与过滤</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 单|多字段分组</span></span><br><span class="line"><span class="keyword">SELECT</span> customer_id <span class="keyword">FROM</span> orders <span class="keyword">GROUP</span> <span class="keyword">BY</span> customer_id, product_id;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- having 子句</span></span><br><span class="line"><span class="comment">-- WHERE 子句用于在分组之前进行过滤，而 HAVING 子句用于在分组之后进行过滤</span></span><br><span class="line"><span class="keyword">SELECT</span> customer_id, <span class="built_in">COUNT</span>(order_id) <span class="keyword">AS</span> order_num    <span class="comment">-- 查询订单数超过 1 的客户</span></span><br><span class="line"><span class="keyword">FROM</span> orders</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span> customer_id</span><br><span class="line"><span class="keyword">HAVING</span> <span class="built_in">COUNT</span>(order_id) <span class="operator">&gt;</span> <span class="number">1</span>;</span><br></pre></td></tr></table></figure><h2 id="关联查询"><a class="markdownIt-Anchor" href="#关联查询"></a> 关联查询</h2><h3 id="cross-join"><a class="markdownIt-Anchor" href="#cross-join"></a> CROSS JOIN</h3><p>CROSS JOIN 是一种简单的关联查询，不需要任何条件来匹配行，它直接将左表的每一行与右表的每一行进行组合，返回的结果是两个表的笛卡尔积</p><figure class="highlight sql"><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 class="keyword">SELECT</span> e.emp_name, e.salary, d.department, d.manager</span><br><span class="line"><span class="keyword">FROM</span> employees e</span><br><span class="line"><span class="keyword">CROSS</span> <span class="keyword">JOIN</span> departments d;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 等价于</span></span><br><span class="line"><span class="keyword">SELECT</span> e.emp_name, e.salary, d.department, d.manager</span><br><span class="line"><span class="keyword">FROM</span> employees e, departments d;</span><br></pre></td></tr></table></figure><h3 id="inner-join"><a class="markdownIt-Anchor" href="#inner-join"></a> INNER JOIN</h3><p>INNER JOIN 只返回两个表中满足关联条件的交集部分，即在两个表中都存在的匹配行</p><figure class="highlight sql"><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="keyword">SELECT</span> e.emp_name, e.salary, e.department, d.manager</span><br><span class="line"><span class="keyword">FROM</span> employees e</span><br><span class="line"><span class="keyword">JOIN</span> departments d <span class="keyword">ON</span> e.department <span class="operator">=</span> d.department;</span><br></pre></td></tr></table></figure><h3 id="outer-join"><a class="markdownIt-Anchor" href="#outer-join"></a> OUTER JOIN</h3><p>OUTER JOIN 中，包括 LEFT OUTER JOIN 和 RIGHT OUTER JOIN 两种类型，它们分别表示查询左表和右表的所有行（即使没有被匹配），再加上满足条件的交集部分</p><figure class="highlight sql"><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="keyword">SELECT</span> e.emp_name, e.salary, e.department, d.manager</span><br><span class="line"><span class="keyword">FROM</span> employees e</span><br><span class="line"><span class="keyword">LEFT</span> <span class="keyword">JOIN</span> departments d <span class="keyword">ON</span> e.department <span class="operator">=</span> d.department;</span><br></pre></td></tr></table></figure><h2 id="子查询-2"><a class="markdownIt-Anchor" href="#子查询-2"></a> 子查询</h2><p>子查询是指在一个查询语句内部嵌套另一个完整的查询语句，内层查询被称为子查询。子查询可以用于获取更复杂的查询结果或者用于过滤数据</p><figure class="highlight sql"><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">-- 订单总金额 &gt; 200 的客户的姓名和城市信息</span></span><br><span class="line"><span class="keyword">SELECT</span> name, city</span><br><span class="line"><span class="keyword">FROM</span> customers</span><br><span class="line"><span class="keyword">WHERE</span> customer_id <span class="keyword">IN</span> (</span><br><span class="line">    <span class="keyword">SELECT</span> <span class="keyword">DISTINCT</span> customer_id</span><br><span class="line">    <span class="keyword">FROM</span> orders</span><br><span class="line">    <span class="keyword">WHERE</span> total_amount <span class="operator">&gt;</span> <span class="number">200</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="exists"><a class="markdownIt-Anchor" href="#exists"></a> EXISTS</h3><p>子查询中的一种特殊类型是 “exists” 子查询，用于检查主查询的结果集是否存在满足条件的记录，它返回布尔值（True 或 False），而不返回实际的数据</p><figure class="highlight sql"><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"><span class="keyword">SELECT</span> name, total_amount</span><br><span class="line"><span class="keyword">FROM</span> customers</span><br><span class="line"><span class="keyword">WHERE</span> <span class="keyword">EXISTS</span> (</span><br><span class="line">    <span class="keyword">SELECT</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">FROM</span> orders</span><br><span class="line">    <span class="keyword">WHERE</span> orders.customer_id <span class="operator">=</span> customers.customer_id</span><br><span class="line">);</span><br></pre></td></tr></table></figure><h2 id="组合查询"><a class="markdownIt-Anchor" href="#组合查询"></a> 组合查询</h2><p>UNION 两个或多个查询的结果集合并，并去除重复的行；UNION ALL 全部保留</p><figure class="highlight sql"><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="keyword">SELECT</span> name, age, department <span class="keyword">FROM</span> table1</span><br><span class="line"><span class="keyword">UNION</span></span><br><span class="line"><span class="keyword">SELECT</span> name, age, department <span class="keyword">FROM</span> table2;</span><br></pre></td></tr></table></figure><h2 id="开窗函数"><a class="markdownIt-Anchor" href="#开窗函数"></a> 开窗函数</h2><p>开窗函数可以与聚合函数（如 SUM、AVG、COUNT 等）结合使用，但与普通聚合函数不同，开窗函数不会导致结果集的行数减少</p><p>将开窗函数想象成一种 “透视镜”，它能够将我们聚焦在某个特定的分组，同时还能看到整体的全景</p><h3 id="sum-over"><a class="markdownIt-Anchor" href="#sum-over"></a> SUM OVER</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 每个客户的订单总金额，并显示每个订单的详细信息</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    order_id,</span><br><span class="line">    customer_id,</span><br><span class="line">    order_date,</span><br><span class="line">    total_amount,</span><br><span class="line">    <span class="built_in">SUM</span>(total_amount) <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> customer_id) <span class="keyword">AS</span> customer_total_amount</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    orders;</span><br></pre></td></tr></table></figure><h3 id="rank"><a class="markdownIt-Anchor" href="#rank"></a> RANK</h3><p>Rank 开窗函数的常见用法是在查询结果中查找前几名（Top N）或排名最高的行</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 每个客户的订单按照订单金额降序排名，并显示每个订单的详细信息</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    order_id,</span><br><span class="line">    customer_id,</span><br><span class="line">    order_date,</span><br><span class="line">    total_amount,</span><br><span class="line">    <span class="built_in">RANK</span>() <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> customer_id <span class="keyword">ORDER</span> <span class="keyword">BY</span> total_amount <span class="keyword">DESC</span>) <span class="keyword">AS</span> customer_rank</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    orders;</span><br></pre></td></tr></table></figure><p>PARTITION BY 子句可选，用于指定分组列；ORDER BY 子句用于指定排序列及排序方式</p><h3 id="row_number"><a class="markdownIt-Anchor" href="#row_number"></a> ROW_NUMBER</h3><p>Row_Number 函数为每一行都分配一个唯一的整数值，不管是否存在并列（相同排序值）的情况。每一行都有一个唯一的行号，从 1 开始连续递增</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 每个客户的订单按照订单金额降序排列，并且分配一个 row_number 编号</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    order_id,</span><br><span class="line">    customer_id,</span><br><span class="line">    order_date,</span><br><span class="line">    total_amount,</span><br><span class="line">    <span class="built_in">ROW_NUMBER</span>() <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> customer_id <span class="keyword">ORDER</span> <span class="keyword">BY</span> total_amount <span class="keyword">DESC</span>) <span class="keyword">AS</span> row_number</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    orders;</span><br></pre></td></tr></table></figure><h3 id="lag-lead"><a class="markdownIt-Anchor" href="#lag-lead"></a> LAG / LEAD</h3><p>Lag 函数用于获取当前行之前的某一列的值。Lead 函数用于获取当前行之后的某一列的值。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">LAG</span>(column_name, <span class="keyword">offset</span>, default_value) <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> partition_column <span class="keyword">ORDER</span> <span class="keyword">BY</span> sort_column)</span><br><span class="line"><span class="comment">-- column_name：要获取值的列名</span></span><br><span class="line"><span class="comment">-- offset：表示要向上偏移的行数。例如，offset为1表示获取上一行的值</span></span><br><span class="line"><span class="comment">-- default_value：可选参数，用于指定当没有前一行时的默认值</span></span><br></pre></td></tr></table></figure><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- 查询每个学生的考试日期和上一次考试的成绩，以及下一次考试的成绩</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    student_id,</span><br><span class="line">    exam_date,</span><br><span class="line">    score,</span><br><span class="line">    <span class="built_in">LAG</span>(score, <span class="number">1</span>, <span class="keyword">NULL</span>) <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> student_id <span class="keyword">ORDER</span> <span class="keyword">BY</span> exam_date) <span class="keyword">AS</span> previous_score,</span><br><span class="line">    <span class="built_in">LEAD</span>(score, <span class="number">1</span>, <span class="keyword">NULL</span>) <span class="keyword">OVER</span> (<span class="keyword">PARTITION</span> <span class="keyword">BY</span> student_id <span class="keyword">ORDER</span> <span class="keyword">BY</span> exam_date) <span class="keyword">AS</span> next_score</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    scores;</span><br></pre></td></tr></table></figure><h2 id="实战案例"><a class="markdownIt-Anchor" href="#实战案例"></a> 实战案例</h2><h3 id="英雄胜率统计"><a class="markdownIt-Anchor" href="#英雄胜率统计"></a> 英雄胜率统计</h3><figure class="highlight sql"><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="comment">-- 统计每个英雄定位的胜率（胜利场次/总场次*100）</span></span><br><span class="line"><span class="comment">-- 只显示对局数大于等于5场的英雄定位</span></span><br><span class="line"><span class="keyword">SELECT</span></span><br><span class="line">    hero_role,</span><br><span class="line">    ROUND(<span class="built_in">SUM</span>(<span class="keyword">CASE</span> <span class="keyword">WHEN</span> game_result <span class="operator">=</span> <span class="string">&#x27;胜利&#x27;</span> <span class="keyword">THEN</span> <span class="number">1</span> <span class="keyword">ELSE</span> <span class="number">0</span> <span class="keyword">END</span>) <span class="operator">*</span> <span class="number">100.0</span> <span class="operator">/</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>), <span class="number">1</span>) <span class="operator">||</span> <span class="string">&#x27;%&#x27;</span> <span class="keyword">AS</span> win_rate,</span><br><span class="line">    ROUND(<span class="built_in">AVG</span>((kills <span class="operator">+</span> assists) <span class="operator">*</span> <span class="number">1.0</span> <span class="operator">/</span> <span class="keyword">CASE</span> <span class="keyword">WHEN</span> deaths <span class="operator">=</span> <span class="number">0</span> <span class="keyword">THEN</span> <span class="number">1</span> <span class="keyword">ELSE</span> deaths <span class="keyword">END</span>), <span class="number">2</span>) <span class="keyword">AS</span> avg_kda,</span><br><span class="line">    <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> total_matches</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    game_matches</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span></span><br><span class="line">    hero_role</span><br><span class="line"><span class="keyword">HAVING</span></span><br><span class="line">    <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="operator">&gt;=</span> <span class="number">5</span></span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span></span><br><span class="line">    ROUND(<span class="built_in">SUM</span>(<span class="keyword">CASE</span> <span class="keyword">WHEN</span> game_result <span class="operator">=</span> <span class="string">&#x27;胜利&#x27;</span> <span class="keyword">THEN</span> <span class="number">1</span> <span class="keyword">ELSE</span> <span class="number">0</span> <span class="keyword">END</span>) <span class="operator">*</span> <span class="number">100.0</span> <span class="operator">/</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>), <span class="number">1</span>) <span class="keyword">DESC</span>;</span><br></pre></td></tr></table></figure><h3 id="股票交易分析"><a class="markdownIt-Anchor" href="#股票交易分析"></a> 股票交易分析</h3><figure class="highlight sql"><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">SELECT</span></span><br><span class="line">    sector,</span><br><span class="line">    ROUND(<span class="built_in">SUM</span>(quantity <span class="operator">*</span> price_per_share), <span class="number">2</span>) <span class="keyword">AS</span> total_amount,</span><br><span class="line">    <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">AS</span> transaction_count,</span><br><span class="line">    ROUND(<span class="built_in">AVG</span>(price_per_share), <span class="number">2</span>) <span class="keyword">AS</span> avg_price,</span><br><span class="line">    CONCAT(ROUND(<span class="built_in">SUM</span>(<span class="keyword">CASE</span> <span class="keyword">WHEN</span> transaction_type <span class="operator">=</span> <span class="string">&#x27;买入&#x27;</span> <span class="keyword">THEN</span> <span class="number">1</span> <span class="keyword">ELSE</span> <span class="number">0</span> <span class="keyword">END</span>) <span class="operator">*</span> <span class="number">100.0</span> <span class="operator">/</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>), <span class="number">1</span>), <span class="string">&#x27;%&#x27;</span>) <span class="keyword">AS</span> buy_ratio,</span><br><span class="line">    CONCAT(ROUND(<span class="built_in">SUM</span>(<span class="keyword">CASE</span> <span class="keyword">WHEN</span> investor_type <span class="operator">=</span> <span class="string">&#x27;机构&#x27;</span> <span class="keyword">THEN</span> <span class="number">1</span> <span class="keyword">ELSE</span> <span class="number">0</span> <span class="keyword">END</span>) <span class="operator">*</span> <span class="number">100.0</span> <span class="operator">/</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>), <span class="number">1</span>), <span class="string">&#x27;%&#x27;</span>) <span class="keyword">AS</span> institution_ratio,</span><br><span class="line">    ROUND(<span class="built_in">AVG</span>(commission_fee), <span class="number">2</span>) <span class="keyword">AS</span> avg_commission,</span><br><span class="line">    (</span><br><span class="line">        <span class="keyword">SELECT</span> stock_name</span><br><span class="line">        <span class="keyword">FROM</span> stock_transactions s2</span><br><span class="line">        <span class="keyword">WHERE</span> s2.sector <span class="operator">=</span> stock_transactions.sector</span><br><span class="line">        <span class="keyword">GROUP</span> <span class="keyword">BY</span> stock_name</span><br><span class="line">        <span class="keyword">ORDER</span> <span class="keyword">BY</span> <span class="built_in">SUM</span>(quantity <span class="operator">*</span> price_per_share) <span class="keyword">DESC</span></span><br><span class="line">        LIMIT <span class="number">1</span></span><br><span class="line">    ) <span class="keyword">AS</span> top_stock,</span><br><span class="line">    CONCAT(ROUND((<span class="built_in">MAX</span>(price_per_share) <span class="operator">-</span> <span class="built_in">MIN</span>(price_per_share)) <span class="operator">*</span> <span class="number">100.0</span> <span class="operator">/</span> <span class="built_in">AVG</span>(price_per_share), <span class="number">1</span>), <span class="string">&#x27;%&#x27;</span>) <span class="keyword">AS</span> volatility</span><br><span class="line"><span class="keyword">FROM</span></span><br><span class="line">    stock_transactions</span><br><span class="line"><span class="keyword">GROUP</span> <span class="keyword">BY</span></span><br><span class="line">    sector</span><br><span class="line"><span class="keyword">ORDER</span> <span class="keyword">BY</span></span><br><span class="line">    total_amount <span class="keyword">DESC</span>;</span><br></pre></td></tr></table></figure><h1 id="索引"><a class="markdownIt-Anchor" href="#索引"></a> 索引</h1><h2 id="回表"><a class="markdownIt-Anchor" href="#回表"></a> 回表</h2><h3 id="为什么会回表"><a class="markdownIt-Anchor" href="#为什么会回表"></a> 为什么会回表</h3><ul><li><strong>主键索引（聚集索引）</strong>：InnoDB 的叶子节点存储了整行数据，不需要回表。</li><li><strong>非主键索引（辅助索引/二级索引）</strong>：叶子节点只存了索引列和主键列，要查其他列就必须回表</li></ul><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> stock_transactions (</span><br><span class="line">    transaction_id <span class="type">INT</span> <span class="keyword">PRIMARY</span> KEY,</span><br><span class="line">    investor_id <span class="type">INT</span>,</span><br><span class="line">    sector <span class="type">VARCHAR</span>(<span class="number">20</span>),</span><br><span class="line">    quantity <span class="type">INT</span>,</span><br><span class="line">    price_per_share <span class="type">DECIMAL</span>(<span class="number">10</span>,<span class="number">2</span>),</span><br><span class="line">    commission_fee <span class="type">DECIMAL</span>(<span class="number">10</span>,<span class="number">2</span>)</span><br><span class="line">);</span><br><span class="line"><span class="keyword">CREATE</span> INDEX idx_investor_id <span class="keyword">ON</span> stock_transactions(investor_id);</span><br></pre></td></tr></table></figure><p>查询：</p><figure class="highlight sql"><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="keyword">SELECT</span> sector, quantity</span><br><span class="line"><span class="keyword">FROM</span> stock_transactions</span><br><span class="line"><span class="keyword">WHERE</span> investor_id <span class="operator">=</span> <span class="number">123</span>;</span><br></pre></td></tr></table></figure><p>idx_investor_id 是二级索引，只包含 investor_id 和 transaction_id（主键）</p><p>查询过程：</p><ol><li>用 idx_investor_id 找到 transaction_id（索引列 + 主键）</li><li>再回表去 stock_transactions 表找到 sector 和 quantity</li><li>这个访问表的过程就叫回表</li></ol><h3 id="如何避免回表"><a class="markdownIt-Anchor" href="#如何避免回表"></a> 如何避免回表</h3><ol><li><strong>查询的字段都在索引中</strong> - 不需要访问表数据，直接从索引返回</li></ol><figure class="highlight sql"><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 class="keyword">CREATE</span> INDEX idx_sector_quantity_investor</span><br><span class="line">    <span class="keyword">ON</span> stock_transactions(investor_id, sector, quantity);</span><br><span class="line"></span><br><span class="line"><span class="keyword">SELECT</span> sector, quantity</span><br><span class="line"><span class="keyword">FROM</span> stock_transactions</span><br><span class="line"><span class="keyword">WHERE</span> investor_id <span class="operator">=</span> <span class="number">123</span>;</span><br><span class="line"><span class="comment">-- 现在索引已经覆盖查询字段，不会回表</span></span><br></pre></td></tr></table></figure><ol start="2"><li><strong>选择性高的索引 + 合理联合索引</strong> - 可以减少回表的次数，对大表性能提升明显</li></ol><h3 id="小结"><a class="markdownIt-Anchor" href="#小结"></a> 小结</h3><ul><li><strong>回表</strong> = 使用二级索引时，为了获取非索引列数据，需要访问主表</li><li><strong>影响</strong>：增加 I/O，查询慢</li><li><strong>优化方法</strong>：尽量用覆盖索引，让索引包含所有查询列</li></ul><p>InnoDB 主键就是聚簇索引，辅助索引是非聚簇索引，回表是非聚簇索引的代价</p><h2 id="什么时候索引反而降低性能"><a class="markdownIt-Anchor" href="#什么时候索引反而降低性能"></a> 什么时候索引反而降低性能</h2><ol><li><strong>小表查询</strong>：全表扫描比索引更快</li><li><strong>选择性低</strong>：列重复值多，索引命中率低</li><li><strong>频繁写操作</strong>：INSERT/UPDATE/DELETE，每次都要维护索引</li><li><strong>索引列做函数运算</strong>：索引失效，增加查询成本</li><li><strong>LIKE 前置通配符</strong>：<code>LIKE '%abc'</code> 索引无效</li></ol><p>记忆法：<strong>索引是为了加速读，代价是写与存储</strong>。</p><h1 id="面试题精选"><a class="markdownIt-Anchor" href="#面试题精选"></a> 面试题精选</h1><h2 id="count1-count-count列-区别与优化"><a class="markdownIt-Anchor" href="#count1-count-count列-区别与优化"></a> COUNT(1)、COUNT(*)、COUNT(列) 区别与优化</h2><h3 id="区别"><a class="markdownIt-Anchor" href="#区别"></a> 区别</h3><table><thead><tr><th>写法</th><th>含义</th><th>NULL值</th></tr></thead><tbody><tr><td>COUNT(*)</td><td>统计总行数，包含NULL</td><td>包含</td></tr><tr><td>COUNT(1)</td><td>等同于COUNT(*)，统计总行数</td><td>包含</td></tr><tr><td>COUNT(列)</td><td>统计该列非NULL的行数</td><td>不包含</td></tr></tbody></table><h3 id="性能对比"><a class="markdownIt-Anchor" href="#性能对比"></a> 性能对比</h3><ul><li><strong>COUNT(*)</strong> 和 <strong>COUNT(1)</strong>：MySQL优化器会自动选择最小的索引树来遍历，性能基本相同</li><li><strong>COUNT(列)</strong>：需要判断该列是否为NULL，如果列上没有索引，还会触发全表扫描</li></ul><h3 id="优化建议"><a class="markdownIt-Anchor" href="#优化建议"></a> 优化建议</h3><figure class="highlight sql"><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">-- 慢：需要检查name列是否为NULL</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(name) <span class="keyword">FROM</span> users;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 快：直接统计行数</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="built_in">COUNT</span>(<span class="operator">*</span>) <span class="keyword">FROM</span> users;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 如果业务需要统计非NULL值，给列加NOT NULL约束</span></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span> users MODIFY name <span class="type">VARCHAR</span>(<span class="number">50</span>) <span class="keyword">NOT</span> <span class="keyword">NULL</span>;</span><br></pre></td></tr></table></figure><p><strong>结论</strong>：优先使用 <code>COUNT(*)</code>，性能最好且语义最清晰</p><h2 id="sql优化"><a class="markdownIt-Anchor" href="#sql优化"></a> SQL优化</h2><h3 id="1-避免select"><a class="markdownIt-Anchor" href="#1-避免select"></a> 1. 避免SELECT *</h3><figure class="highlight sql"><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="comment">-- 慢：返回所有列，浪费IO</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> user_id <span class="operator">=</span> <span class="number">100</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 快：只查需要的列</span></span><br><span class="line"><span class="keyword">SELECT</span> order_id, amount, create_time <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> user_id <span class="operator">=</span> <span class="number">100</span>;</span><br></pre></td></tr></table></figure><h3 id="2-小表驱动大表"><a class="markdownIt-Anchor" href="#2-小表驱动大表"></a> 2. 小表驱动大表</h3><figure class="highlight sql"><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 class="comment">-- 慢：大表在前，用IN</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> user_id <span class="keyword">IN</span> (<span class="keyword">SELECT</span> id <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> status <span class="operator">=</span> <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 快：小表驱动大表，用EXISTS</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders o <span class="keyword">WHERE</span> <span class="keyword">EXISTS</span> (</span><br><span class="line">    <span class="keyword">SELECT</span> <span class="number">1</span> <span class="keyword">FROM</span> users u <span class="keyword">WHERE</span> u.id <span class="operator">=</span> o.user_id <span class="keyword">AND</span> u.status <span class="operator">=</span> <span class="number">1</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="3-避免索引失效"><a class="markdownIt-Anchor" href="#3-避免索引失效"></a> 3. 避免索引失效</h3><figure class="highlight sql"><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 class="comment">-- 索引失效的常见情况：</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 1. 对索引列做函数运算</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> <span class="keyword">YEAR</span>(create_time) <span class="operator">=</span> <span class="number">2024</span>;   <span class="comment">-- 失效</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> create_time <span class="operator">&gt;=</span> <span class="string">&#x27;2024-01-01&#x27;</span>  <span class="comment">-- 生效</span></span><br><span class="line">  <span class="keyword">AND</span> create_time <span class="operator">&lt;</span> <span class="string">&#x27;2025-01-01&#x27;</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 2. 隐式类型转换</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> phone <span class="operator">=</span> <span class="number">13800138000</span>;  <span class="comment">-- 失效（phone是字符串）</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> phone <span class="operator">=</span> <span class="string">&#x27;13800138000&#x27;</span>; <span class="comment">-- 生效</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 3. LIKE左模糊</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> name <span class="keyword">LIKE</span> <span class="string">&#x27;%张&#x27;</span>;   <span class="comment">-- 失效</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> name <span class="keyword">LIKE</span> <span class="string">&#x27;张%&#x27;</span>;   <span class="comment">-- 生效</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 4. OR连接非索引列</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> users <span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">1</span> <span class="keyword">OR</span> name <span class="operator">=</span> <span class="string">&#x27;张三&#x27;</span>; <span class="comment">-- 如果name无索引则失效</span></span><br></pre></td></tr></table></figure><h3 id="4-分页优化"><a class="markdownIt-Anchor" href="#4-分页优化"></a> 4. 分页优化</h3><figure class="highlight sql"><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">-- 慢：OFFSET越大越慢</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">ORDER</span> <span class="keyword">BY</span> id LIMIT <span class="number">1000000</span>, <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 快：游标分页（记住上一页最后一条的id）</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> id <span class="operator">&gt;</span> <span class="number">1000000</span> <span class="keyword">ORDER</span> <span class="keyword">BY</span> id LIMIT <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 或者子查询优化</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> id <span class="operator">&gt;=</span> (</span><br><span class="line">    <span class="keyword">SELECT</span> id <span class="keyword">FROM</span> orders <span class="keyword">ORDER</span> <span class="keyword">BY</span> id LIMIT <span class="number">1000000</span>, <span class="number">1</span></span><br><span class="line">) <span class="keyword">ORDER</span> <span class="keyword">BY</span> id LIMIT <span class="number">10</span>;</span><br></pre></td></tr></table></figure><h3 id="5-批量插入"><a class="markdownIt-Anchor" href="#5-批量插入"></a> 5. 批量插入</h3><figure class="highlight sql"><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="keyword">INSERT</span> <span class="keyword">INTO</span> users(name, age) <span class="keyword">VALUES</span>(<span class="string">&#x27;张三&#x27;</span>, <span class="number">20</span>);</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> users(name, age) <span class="keyword">VALUES</span>(<span class="string">&#x27;李四&#x27;</span>, <span class="number">22</span>);</span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> users(name, age) <span class="keyword">VALUES</span>(<span class="string">&#x27;王五&#x27;</span>, <span class="number">25</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 快：批量插入</span></span><br><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> users(name, age) <span class="keyword">VALUES</span></span><br><span class="line">(<span class="string">&#x27;张三&#x27;</span>, <span class="number">20</span>),</span><br><span class="line">(<span class="string">&#x27;李四&#x27;</span>, <span class="number">22</span>),</span><br><span class="line">(<span class="string">&#x27;王五&#x27;</span>, <span class="number">25</span>);</span><br></pre></td></tr></table></figure><h3 id="6-使用explain分析"><a class="markdownIt-Anchor" href="#6-使用explain分析"></a> 6. 使用EXPLAIN分析</h3><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">EXPLAIN <span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> orders <span class="keyword">WHERE</span> user_id <span class="operator">=</span> <span class="number">100</span>;</span><br></pre></td></tr></table></figure><p>重点关注：</p><ul><li><strong>type</strong>：const &gt; eq_ref &gt; ref &gt; range &gt; index &gt; ALL</li><li><strong>key</strong>：实际使用的索引</li><li><strong>rows</strong>：预估扫描行数</li><li><strong>Extra</strong>：Using index（覆盖索引）、Using filesort（文件排序需优化）</li></ul><h2 id="锁机制"><a class="markdownIt-Anchor" href="#锁机制"></a> 锁机制</h2><h3 id="锁的分类"><a class="markdownIt-Anchor" href="#锁的分类"></a> 锁的分类</h3><table><thead><tr><th>类型</th><th>说明</th></tr></thead><tbody><tr><td>全局锁</td><td>锁定整个数据库，用于全库备份</td></tr><tr><td>表级锁</td><td>锁定整张表，MyISAM使用</td></tr><tr><td>行级锁</td><td>锁定某一行，InnoDB使用，粒度最小</td></tr></tbody></table><h3 id="行锁类型"><a class="markdownIt-Anchor" href="#行锁类型"></a> 行锁类型</h3><ol><li><strong>记录锁（Record Lock）</strong>：锁定单行记录</li><li><strong>间隙锁（Gap Lock）</strong>：锁定索引记录之间的间隙，防止幻读</li><li><strong>临键锁（Next-Key Lock）</strong>：记录锁 + 间隙锁，InnoDB默认锁类型</li></ol><h3 id="死锁"><a class="markdownIt-Anchor" href="#死锁"></a> 死锁</h3><figure class="highlight sql"><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="comment">-- 死锁场景：两个事务互相等待对方释放锁</span></span><br><span class="line"><span class="comment">-- 事务A</span></span><br><span class="line"><span class="keyword">BEGIN</span>;</span><br><span class="line"><span class="keyword">UPDATE</span> accounts <span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">-</span> <span class="number">100</span> <span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">1</span>;  <span class="comment">-- 锁住id=1</span></span><br><span class="line"><span class="keyword">UPDATE</span> accounts <span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">+</span> <span class="number">100</span> <span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">2</span>;  <span class="comment">-- 等待id=2的锁</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 事务B（同时执行）</span></span><br><span class="line"><span class="keyword">BEGIN</span>;</span><br><span class="line"><span class="keyword">UPDATE</span> accounts <span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">-</span> <span class="number">100</span> <span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">2</span>;  <span class="comment">-- 锁住id=2</span></span><br><span class="line"><span class="keyword">UPDATE</span> accounts <span class="keyword">SET</span> balance <span class="operator">=</span> balance <span class="operator">+</span> <span class="number">100</span> <span class="keyword">WHERE</span> id <span class="operator">=</span> <span class="number">1</span>;  <span class="comment">-- 等待id=1的锁</span></span><br><span class="line"><span class="comment">-- 死锁！</span></span><br></pre></td></tr></table></figure><h3 id="如何避免死锁"><a class="markdownIt-Anchor" href="#如何避免死锁"></a> 如何避免死锁</h3><ol><li><strong>固定加锁顺序</strong>：所有事务按相同顺序访问表和行</li><li><strong>缩小事务范围</strong>：减少持锁时间</li><li><strong>使用低隔离级别</strong>：在允许的情况下使用READ COMMITTED</li><li><strong>添加合理索引</strong>：避免行锁升级为表锁</li><li><strong>设置锁等待超时</strong>：<code>innodb_lock_wait_timeout=50</code></li></ol><h3 id="查看锁信息"><a class="markdownIt-Anchor" href="#查看锁信息"></a> 查看锁信息</h3><figure class="highlight sql"><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"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> information_schema.INNODB_LOCK_WAITS;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查看正在持有的锁</span></span><br><span class="line"><span class="keyword">SELECT</span> <span class="operator">*</span> <span class="keyword">FROM</span> information_schema.INNODB_LOCKS;</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 查看事务</span></span><br><span class="line"><span class="keyword">SHOW</span> ENGINE INNODB STATUS;</span><br></pre></td></tr></table></figure><h2 id="事务"><a class="markdownIt-Anchor" href="#事务"></a> 事务</h2><h3 id="acid特性"><a class="markdownIt-Anchor" href="#acid特性"></a> ACID特性</h3><ul><li><strong>A（原子性）</strong>：事务要么全部成功，要么全部回滚</li><li><strong>C（一致性）</strong>：事务前后数据保持一致</li><li><strong>I（隔离性）</strong>：并发事务之间互不干扰</li><li><strong>D（持久性）</strong>：事务提交后数据永久保存</li></ul><h3 id="隔离级别"><a class="markdownIt-Anchor" href="#隔离级别"></a> 隔离级别</h3><table><thead><tr><th>级别</th><th>脏读</th><th>不可重复读</th><th>幻读</th></tr></thead><tbody><tr><td>READ UNCOMMITTED</td><td>有</td><td>有</td><td>有</td></tr><tr><td>READ COMMITTED</td><td>无</td><td>有</td><td>有</td></tr><tr><td>REPEATABLE READ（默认）</td><td>无</td><td>无</td><td>有</td></tr><tr><td>SERIALIZABLE</td><td>无</td><td>无</td><td>无</td></tr></tbody></table><h3 id="mvcc多版本并发控制"><a class="markdownIt-Anchor" href="#mvcc多版本并发控制"></a> MVCC（多版本并发控制）</h3><p>InnoDB在REPEATABLE READ级别下，通过MVCC解决脏读和不可重复读：</p><ul><li>每行数据有两个隐藏列：<code>DB_TRX_ID</code>（事务ID）、<code>DB_ROLL_PTR</code>（回滚指针）</li><li>事务启动时生成<strong>ReadView</strong>，包含活跃事务列表</li><li>读取数据时，根据ReadView判断版本可见性</li><li>实现<strong>快照读</strong>，不需要加锁</li></ul><h2 id="主从复制"><a class="markdownIt-Anchor" href="#主从复制"></a> 主从复制</h2><h3 id="原理"><a class="markdownIt-Anchor" href="#原理"></a> 原理</h3><ol><li><strong>Master</strong>将数据变更记录到<strong>Binlog</strong>（二进制日志）</li><li><strong>Slave</strong>的<strong>IO线程</strong>请求Master的Binlog，写入本地<strong>Relay Log</strong></li><li><strong>Slave</strong>的<strong>SQL线程</strong>读取Relay Log，重放数据变更</li></ol><h3 id="复制方式"><a class="markdownIt-Anchor" href="#复制方式"></a> 复制方式</h3><ul><li><strong>异步复制</strong>：Master不等待Slave确认（默认）</li><li><strong>半同步复制</strong>：Master至少等待一个Slave确认收到Binlog</li><li><strong>全同步复制</strong>：Master等待所有Slave确认（性能差）</li></ul><h3 id="常见问题"><a class="markdownIt-Anchor" href="#常见问题"></a> 常见问题</h3><ul><li><strong>主从延迟</strong>：Slave单线程重放、网络延迟、大事务</li><li><strong>解决方案</strong>：并行复制、读写分离、强制走主库</li></ul>]]></content>
    
    
    <summary type="html">春风得意马蹄疾，一日看尽长安花</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Mysql" scheme="https://luckynwa.top/tags/Mysql/"/>
    
  </entry>
  
  <entry>
    <title>RocketMQ 环境搭建与代码示例</title>
    <link href="https://luckynwa.top/posts/tool11/"/>
    <id>https://luckynwa.top/posts/tool11/</id>
    <published>2023-09-08T20:34:07.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h2 id="1-安装和配置"><a class="markdownIt-Anchor" href="#1-安装和配置"></a> 1、安装和配置</h2><p><strong>版本</strong>: rocketmq-4.9.3</p><p>设置环境变量：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ROCKETMQ_HOME = E:\LuckySoft\rocketmq-4.9.3</span><br></pre></td></tr></table></figure><p><strong>修改JVM内存参数</strong></p><p>进入 bin 目录，修改 <code>runserver.cmd</code> 和 <code>runbroker.cmd</code> 中的 JAVA_OPT 参数，根据本地机器配置调整内存大小：</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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">修改前（默认配置）</span></span><br><span class="line">rem set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms2g -Xmx2g -Xmn1g&quot;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">修改后（本地开发环境）</span></span><br><span class="line">set &quot;JAVA_OPT=%JAVA_OPT% -server -Xms256m -Xmx512m&quot;</span><br></pre></td></tr></table></figure><h2 id="2-启动服务"><a class="markdownIt-Anchor" href="#2-启动服务"></a> 2、启动服务</h2><p><strong>启动 NameServer</strong></p><p>直接运行 bin 目录下的 <code>mqnamesrv.cmd</code></p><p><strong>启动 Broker</strong></p><p>打开 cmd 终端，执行以下命令连接到 NameServer：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">bin&gt;</span><span class="language-bash">mqbroker.cmd -n localhost:9876</span></span><br></pre></td></tr></table></figure><h2 id="3-spring-boot-集成代码"><a class="markdownIt-Anchor" href="#3-spring-boot-集成代码"></a> 3、Spring Boot 集成代码</h2><p><strong>引入依赖</strong></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></pre></td><td class="code"><pre><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.rocketmq<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>rocketmq-spring-boot-starter<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.0.4<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></pre></td></tr></table></figure><p><strong>配置 application.yml</strong></p><figure class="highlight yml"><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="attr">rocketmq:</span></span><br><span class="line">  <span class="attr">name-server:</span> <span class="number">127.0</span><span class="number">.0</span><span class="number">.1</span><span class="string">:9876</span></span><br><span class="line">  <span class="attr">producer:</span></span><br><span class="line">    <span class="attr">group:</span> <span class="string">producer-demo1</span></span><br><span class="line">  <span class="attr">consumer:</span></span><br><span class="line">    <span class="attr">group:</span> <span class="string">consumer-demo1</span></span><br></pre></td></tr></table></figure><p><strong>消费者示例</strong></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="keyword">package</span> com.nwa.Lis;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.aop.SysLog;</span><br><span class="line"><span class="keyword">import</span> org.apache.rocketmq.spring.annotation.RocketMQMessageListener;</span><br><span class="line"><span class="keyword">import</span> org.apache.rocketmq.spring.core.RocketMQListener;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/2/27 -13:03</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RocketMQMessageListener(topic = &quot;rocket-send1&quot;, consumerGroup = &quot;$&#123;rocketmq.consumer.group&#125;&quot;)</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RocketConsumerListener</span> <span class="keyword">implements</span> <span class="title class_">RocketMQListener</span>&lt;String&gt; &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="meta">@SysLog(operationType = &quot;接收&quot;, operationName = &quot;接收,并展示&quot;, value = &quot;200&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onMessage</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;consumer 收到消息：&quot;</span> + s);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>生产者示例</strong></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><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 class="keyword">package</span> com.nwa.controller;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.aop.SysLog;</span><br><span class="line"><span class="keyword">import</span> org.apache.rocketmq.spring.core.RocketMQTemplate;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RequestMapping;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/2/27 -13:02</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RestController</span></span><br><span class="line"><span class="meta">@RequestMapping(&quot;/rocket/producer&quot;)</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RocketProducerHandler</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> RocketMQTemplate rocketMQTemplate;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@SysLog(operationType = &quot;用户操作&quot;, operationName = &quot;发送,并展示&quot;, value = &quot;200&quot;)</span></span><br><span class="line">    <span class="meta">@RequestMapping(&quot;/send&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">send</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            rocketMQTemplate.convertAndSend(<span class="string">&quot;rocket-send1&quot;</span>, <span class="string">&quot;rocket-testA-&quot;</span> + i);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;send ok&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">黄沙百战穿金甲，不破楼兰终不还</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Middleware" scheme="https://luckynwa.top/tags/Middleware/"/>
    
  </entry>
  
  <entry>
    <title>数据结构和算法入门</title>
    <link href="https://luckynwa.top/posts/base2/"/>
    <id>https://luckynwa.top/posts/base2/</id>
    <published>2023-09-07T23:24:35.000Z</published>
    <updated>2026-07-07T16:19:33.749Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h1><p>数据结构：线性结构和非线性结构，用来存储数据的方式</p><p>算法：就是解决问题的思路和方法，要有设计出好的数据结构才能更好用算法</p><p>特性：有输入、有输出、有穷性、确定性、可行性</p><h1 id="时间复杂度"><a class="markdownIt-Anchor" href="#时间复杂度"></a> 时间复杂度</h1><p>表示随着问题规模不断变化的主要趋势，衡量算法的优劣</p><p>大O标记法：将次要条件省掉，最终形成一个表达式</p><p>比如说：嵌套的3次for循环，最里面是if什么的，再打印，只看最外的3次循环，都是</p><figure class="highlight plaintext"><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">n*n*n</span><br><span class="line">时间复杂度T(n)=O(n^3)</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">for i in range(0,5):    O(1)                              如果是0，n       O(n)</span><br><span class="line">  for j in range(0,n):  O(n)</span><br><span class="line">    print(i)            O(1)* O(n)= O(n)                  最终就  O(n^2)</span><br></pre></td></tr></table></figure><p>时间复杂度<strong>取最高次项</strong>，即最坏的复杂度</p><p>最优时间复杂度指的算法完成工作最少需要多少基本操作</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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">| 12               | O(1)     | 常数阶     |</span><br><span class="line">| 2n+3             | O(n)     | 线性阶     |</span><br><span class="line">| 3n²+2n+1         | O(n²)    | 平方阶     |</span><br><span class="line">| 5log₂n+20        | O(logn)  | 对数阶     |</span><br><span class="line">| 6n³+2n²+3n+4     | O(n³)    | 立方阶     |</span><br></pre></td></tr></table></figure><p>所消耗的时间从小到大:</p><p>O(1) &lt; O(logn) &lt; O(n) &lt; O(nlogn) &lt; O(n²) &lt; O(n³)</p><p>时间复杂度越低，效率越高 O(1) 最高</p><p>备注：<br />O(logn)：二分法<br />O(nlogn)：一个for循环是n 另外一个for循环是二分法，组合在一起</p><h1 id="空间复杂度"><a class="markdownIt-Anchor" href="#空间复杂度"></a> 空间复杂度</h1><p>空间复杂度（S(n)）对算法在运行过程中临时占用存储空间大小，也可以用大O记法</p><p>O(1) &lt; O(logn) &lt; O(n) &lt; O(n²) &lt; O(n³)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n):</span><br><span class="line">    a = i                       <span class="comment"># 这里的a一直被覆盖，没有开辟新的空间，所以空间复杂度:  O(1)</span></span><br><span class="line">    <span class="built_in">print</span>(a)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 如果是列表，新增插入一直再开空间     空间复杂度: O(n)</span></span><br><span class="line"><span class="built_in">list</span>=[]</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>,n):</span><br><span class="line">    <span class="built_in">list</span>.append(i)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 下面空间复杂度: O(n²)  矩阵  [[],[]]</span></span><br><span class="line">list_1 = []</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n):</span><br><span class="line">    list_2 = []</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, n):</span><br><span class="line">        list_2.append(j)</span><br><span class="line">    list_1.append(list_2)</span><br></pre></td></tr></table></figure><h1 id="存储结构"><a class="markdownIt-Anchor" href="#存储结构"></a> 存储结构</h1><p>内存以字节为基本存储单位，每个存储空间有自己的地址，一个地址代表1个字节8bit</p><p>整形 4个字节 如10 占用4个字节 字符串1个</p><p>数据结构分类:</p><p>（1）线性结构 一个父节点 ，1个子节点</p><ul><li><p><strong>顺序表</strong> (栈, 队列) 适合查（时间复杂度O（1））和改</p><p>一站式存储（列表同一类型） 数据区、信息区</p><p>分离式存储（列表不同类型）</p><p><strong>链表</strong> 适合 增和删 没有索引 由节点组成，其中节点由 元素域（数值域） 和 地址域组成</p><p>单向链表：节点由1个数值域和1个地址域组成，前边节点的地址域存储后续节点的地址，最后一个地址域为None</p><pre><code>  自定义代码模拟链表</code></pre></li></ul><p>（2）非线性结构</p><ul><li>树</li><li>图</li><li>…</li></ul><p><strong>1. 顺序表中如何增加元素？</strong></p><ul><li><strong>a.</strong> 尾端加入元素，时间复杂度为 O(1)</li><li><strong>b.</strong> 非保序的加入元素（不常见），时间复杂度为 O(1)</li><li><strong>c.</strong> 保序的元素加入，时间复杂度为 O(n)</li></ul><p><strong>2. 顺序表中如何删除元素？</strong></p><ul><li><strong>a.</strong> 删除表尾元素，时间复杂度为 O(1)</li><li><strong>b.</strong> 非保序的元素删除（不常见），时间复杂度为 O(1)</li><li><strong>c.</strong> 保序的元素删除，时间复杂度为 O(n)</li></ul><p><strong>自定义代码模拟链表，思路分析：</strong></p><ol><li>自定义 <code>SingleNode</code> 类，表示 <strong>节点类</strong>。<ul><li>属性：<ul><li><code>item</code>：数值域（元素域）</li><li><code>next</code>：地址域（链接域）</li></ul></li></ul></li><li>自定义 <code>SingleLinkedList</code> 类，表示：<strong>链表</strong><ul><li>属性：<ul><li><code>head</code>：表示头结点，指向第 1 个节点。</li></ul></li></ul></li></ol><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">SingleNode</span>:</span><br><span class="line">    <span class="string">&quot;&quot;&quot;单链表的节点类&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, item</span>):</span><br><span class="line">        <span class="comment"># 数值域：保存数据元素</span></span><br><span class="line">        self.item = item</span><br><span class="line">        <span class="comment"># 地址域：指向下一个节点的引用，初始化为 None</span></span><br><span class="line">        self.<span class="built_in">next</span> = <span class="literal">None</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SingleLinkedList</span>:</span><br><span class="line">    <span class="string">&quot;&quot;&quot;单向链表类&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,node=<span class="literal">None</span></span>):</span><br><span class="line">        <span class="comment"># 头结点属性：初始时链表为空，head 指向 None</span></span><br><span class="line">        self.head = node</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">is_empty</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;判断头节点是否为空&quot;&quot;&quot;</span></span><br><span class="line">        <span class="keyword">return</span> self.head <span class="keyword">is</span> <span class="literal">None</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">length</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;获取链表长度&quot;&quot;&quot;</span></span><br><span class="line">        <span class="comment"># cur 是游标（指针），用来遍历链表</span></span><br><span class="line">        cur = self.head</span><br><span class="line">        count = <span class="number">0</span></span><br><span class="line">        <span class="keyword">while</span> cur <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            count += <span class="number">1</span></span><br><span class="line">            <span class="comment"># 将游标移动到下一个节点</span></span><br><span class="line">            cur = cur.<span class="built_in">next</span></span><br><span class="line">        <span class="keyword">return</span> count</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">travel</span>(<span class="params">self</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;遍历整个链表并打印元素&quot;&quot;&quot;</span></span><br><span class="line">        cur = self.head</span><br><span class="line">        <span class="keyword">while</span> cur <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="built_in">print</span>(cur.item, end=<span class="string">&quot; &quot;</span>)</span><br><span class="line">            cur = cur.<span class="built_in">next</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&quot;&quot;</span>)  <span class="comment"># 换行</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">self, item</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;在链表头部添加元素 (头插法)&quot;&quot;&quot;</span></span><br><span class="line">        node = SingleNode(item)</span><br><span class="line">        <span class="comment"># 1. 新节点的 next 指向原来的头结点</span></span><br><span class="line">        node.<span class="built_in">next</span> = self.head</span><br><span class="line">        <span class="comment"># 2. 将链表的 head 指向新节点</span></span><br><span class="line">        self.head = node</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">append</span>(<span class="params">self, item</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;在链表尾部添加元素 (尾插法)&quot;&quot;&quot;</span></span><br><span class="line">        node = SingleNode(item)</span><br><span class="line">        <span class="comment"># 如果链表为空，直接将 head 指向新节点</span></span><br><span class="line">        <span class="keyword">if</span> self.is_empty():</span><br><span class="line">            self.head = node</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            cur = self.head</span><br><span class="line">            <span class="comment"># 移动到链表的最后一个节点</span></span><br><span class="line">            <span class="keyword">while</span> cur.<span class="built_in">next</span> <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">                cur = cur.<span class="built_in">next</span></span><br><span class="line">            <span class="comment"># 将最后一个节点的 next 指向新节点</span></span><br><span class="line">            cur.<span class="built_in">next</span> = node</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">insert</span>(<span class="params">self, pos, item</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;在指定位置 pos 添加元素&quot;&quot;&quot;</span></span><br><span class="line">        <span class="comment"># 如果指定位置在第一个位置之前，执行头部插入</span></span><br><span class="line">        <span class="keyword">if</span> pos &lt;= <span class="number">0</span>:</span><br><span class="line">            self.add(item)</span><br><span class="line">        <span class="comment"># 如果指定位置超过链表长度，执行尾部插入</span></span><br><span class="line">        <span class="keyword">elif</span> pos &gt; (self.length() - <span class="number">1</span>):</span><br><span class="line">            self.append(item)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            node = SingleNode(item)</span><br><span class="line">            count = <span class="number">0</span></span><br><span class="line">            pre = self.head</span><br><span class="line">            <span class="comment"># 移动到 pos 位置的前一个节点</span></span><br><span class="line">            <span class="keyword">while</span> count &lt; (pos - <span class="number">1</span>):</span><br><span class="line">                count += <span class="number">1</span></span><br><span class="line">                pre = pre.<span class="built_in">next</span></span><br><span class="line">            <span class="comment"># 1. 新节点指向 pos 位置的节点</span></span><br><span class="line">            node.<span class="built_in">next</span> = pre.<span class="built_in">next</span></span><br><span class="line">            <span class="comment"># 2. 前一个节点指向新节点</span></span><br><span class="line">            pre.<span class="built_in">next</span> = node</span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">remove</span>(<span class="params">self, item</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;删除节点&quot;&quot;&quot;</span></span><br><span class="line">        cur = self.head</span><br><span class="line">        pre = <span class="literal">None</span></span><br><span class="line">        <span class="keyword">while</span> cur <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="comment"># 找到了要删除的元素</span></span><br><span class="line">            <span class="keyword">if</span> cur.item == item:</span><br><span class="line">                <span class="comment"># 如果要删除的是头结点</span></span><br><span class="line">                <span class="keyword">if</span> cur == self.head:</span><br><span class="line">                    self.head = cur.<span class="built_in">next</span></span><br><span class="line">                <span class="keyword">else</span>:</span><br><span class="line">                    <span class="comment"># 将前一个节点的 next 指向当前节点的下一个节点</span></span><br><span class="line">                    pre.<span class="built_in">next</span> = cur.<span class="built_in">next</span></span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                <span class="comment"># 继续向后遍历</span></span><br><span class="line">                pre = cur</span><br><span class="line">                cur = cur.<span class="built_in">next</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">search</span>(<span class="params">self, item</span>):</span><br><span class="line">        <span class="string">&quot;&quot;&quot;查找节点是否存在，存在返回 True，否则返回 False&quot;&quot;&quot;</span></span><br><span class="line">        cur = self.head</span><br><span class="line">        <span class="keyword">while</span> cur <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">            <span class="keyword">if</span> cur.item == item:</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">            cur = cur.<span class="built_in">next</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># --- 测试代码 ---</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    <span class="comment"># 测试节点创建</span></span><br><span class="line">    node1 = SingleNode(<span class="number">10</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;节点1的数值域: <span class="subst">&#123;node1.item&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;节点1的地址域: <span class="subst">&#123;node1.<span class="built_in">next</span>&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;node1对象: <span class="subst">&#123;node1&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;node1类型: <span class="subst">&#123;<span class="built_in">type</span>(node1)&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="comment"># 测试链表创建</span></span><br><span class="line">    my_linkedlist = SingleLinkedList(node1)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;头节点为: <span class="subst">&#123;my_linkedlist.head&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;头节点元素域: <span class="subst">&#123;my_linkedlist.head.item&#125;</span>&#x27;</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;头节点地址域: <span class="subst">&#123;my_linkedlist.head.<span class="built_in">next</span>&#125;</span>&#x27;</span>)</span><br><span class="line"></span><br><span class="line">    node2 = SingleNode(<span class="string">&#x27;赵云&#x27;</span>)</span><br><span class="line">    single_linkedlist = SingleLinkedList(node2)</span><br><span class="line">    <span class="built_in">print</span>(single_linkedlist.is_empty())</span><br><span class="line">    <span class="built_in">print</span>(single_linkedlist.length())</span><br><span class="line">    single_linkedlist.travel()</span><br></pre></td></tr></table></figure><h1 id="递归"><a class="markdownIt-Anchor" href="#递归"></a> 递归</h1><p>即函数自己调用自己</p><p>核心要点：</p><p>1、必须有出口，否则造成死递归</p><p>2、调用次数不能过多，否则容易死递归</p><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><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"><span class="keyword">def</span> <span class="title function_">show</span>(<span class="params">n</span>):</span><br><span class="line">  <span class="comment"># 递归出口</span></span><br><span class="line">  <span class="keyword">if</span> n == <span class="number">1</span>:</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">  <span class="comment"># 递归规律</span></span><br><span class="line">  <span class="keyword">return</span> n * show(n-<span class="number">1</span>)</span><br><span class="line"><span class="built_in">print</span>(show(<span class="number">5</span>))</span><br></pre></td></tr></table></figure><h1 id="算法"><a class="markdownIt-Anchor" href="#算法"></a> 算法</h1><p>排序算法：按照其中某个关键字的大小，递增或递减的排列起来操作</p><p>稳定性算法：相同元素的 相对位置 不改变</p><ul><li><strong>不稳定的排序算法：</strong> 选择排序、快速排序、希尔排序、堆排序</li><li><strong>稳定的排序算法：</strong> 冒泡排序、插入排序、归并排序和基数排序</li></ul><h2 id="冒泡排序"><a class="markdownIt-Anchor" href="#冒泡排序"></a> 冒泡排序</h2><p>相邻两两比较，前面的比后面大就交换</p><p>比如：5个人身高排序，第一轮两两比较就能知道最高的，第二轮，第二高，4轮就能排完</p><p>名字由来：最小元素会慢慢交换浮到数列的顶端。如二氧化碳的气泡</p><p>[5,3,4,7,2]</p><p>1、比较的总轮数 2、每轮比较的总次数 3、谁和谁比较</p><p><strong>原理</strong></p><p>相邻元素两两比较，大的往后走，这样第一轮比较完毕后，最大值就在最大索引处。重复此动作，直至排序完成。</p><p><strong>流程（假设共 5 个元素）</strong></p><table><thead><tr><th style="text-align:left">第几轮(索引)</th><th style="text-align:left">该轮比较的总次数</th><th style="text-align:left">公式</th></tr></thead><tbody><tr><td style="text-align:left">第1轮(0)</td><td style="text-align:left">4次</td><td style="text-align:left">5−1−0=4</td></tr><tr><td style="text-align:left">第2轮(1)</td><td style="text-align:left">3次</td><td style="text-align:left">5−1−1=3</td></tr><tr><td style="text-align:left">第3轮(2)</td><td style="text-align:left">2次</td><td style="text-align:left">5−1−2=2</td></tr><tr><td style="text-align:left">第4轮(3)</td><td style="text-align:left">1次</td><td style="text-align:left">5−1−3=1</td></tr></tbody></table><p><strong>要点</strong></p><ol><li><strong>比较的总轮数</strong>：列表长度 - 1</li><li><strong>每轮比较的总次数</strong>：列表长度 - 1 - 轮数的索引(从0开始)</li><li><strong>谁和谁比较</strong>：索引 <code>j</code> 和 <code>j + 1</code> 位置的元素比较</li></ol><p><strong>时间复杂度</strong></p><ul><li>最优：O(n)</li><li>最坏：O(n²)</li></ul><p><strong>扩展</strong></p><ul><li>外循环-1：减少比较次数、提高效率</li><li>内循环-1：为了防止索引越界 内循环 -i：减少每轮的比较次数，提高效率</li></ul><p>冒泡排序 = 稳定 排序算法 比如[3,2,7,6,6] 6 7 6 | 6 6 7 发现 6 6 的相对位置没有变化就是稳定的</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 默认版本</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">dubble_sort</span>(<span class="params"><span class="built_in">list</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;冒泡排序&quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(<span class="built_in">list</span>) - <span class="number">1</span>):   <span class="comment">#外循环，控制排序的轮数</span></span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(<span class="built_in">list</span>) - <span class="number">1</span> - i):   <span class="comment">#内循环，控制每轮排序的比较次数</span></span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">list</span>[j] &gt; <span class="built_in">list</span>[j + <span class="number">1</span>]:</span><br><span class="line">                <span class="built_in">list</span>[j], <span class="built_in">list</span>[j + <span class="number">1</span>] = <span class="built_in">list</span>[j + <span class="number">1</span>], <span class="built_in">list</span>[j]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 优化版本</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">dubble_sort_optimize</span>(<span class="params"><span class="built_in">list</span></span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;冒泡排序&quot;&quot;&quot;</span></span><br><span class="line">    count=<span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(<span class="built_in">list</span>) - <span class="number">1</span>):   <span class="comment">#外循环，控制排序的轮数</span></span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(<span class="built_in">list</span>) - <span class="number">1</span> - i):   <span class="comment">#内循环，控制每轮排序的比较次数</span></span><br><span class="line">            <span class="keyword">if</span> <span class="built_in">list</span>[j] &gt; <span class="built_in">list</span>[j + <span class="number">1</span>]:</span><br><span class="line">                count+=<span class="number">1</span></span><br><span class="line">                <span class="built_in">list</span>[j], <span class="built_in">list</span>[j + <span class="number">1</span>] = <span class="built_in">list</span>[j + <span class="number">1</span>], <span class="built_in">list</span>[j]</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&quot;第<span class="subst">&#123;i+<span class="number">1</span>&#125;</span>轮数，交换次数为<span class="subst">&#123;count&#125;</span>&quot;</span>)</span><br><span class="line">        <span class="keyword">if</span> count==<span class="number">0</span>: <span class="comment"># 如果某一轮没有交换，说明已经有序，直接跳出循环</span></span><br><span class="line">            <span class="built_in">print</span>(<span class="string">&quot;已经有序&quot;</span>)</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&quot;__main__&quot;</span>:</span><br><span class="line">    <span class="built_in">list</span> = [<span class="number">5</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">7</span>, <span class="number">2</span>]</span><br><span class="line">    list1=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]</span><br><span class="line">    dubble_sort_optimize(list1)</span><br><span class="line">    <span class="built_in">print</span>(<span class="built_in">list</span>)</span><br></pre></td></tr></table></figure><h2 id="选择排序"><a class="markdownIt-Anchor" href="#选择排序"></a> 选择排序</h2><p>不稳定 排序算法 5 3 5 7 2 第一轮交换2 3 5 7 5 本来是前5，交换后变后5，位置变化了，所以不稳定</p><p>待排序的数据元素中选最小或最大的一个元素，放序列的起始位置</p><ul><li>最优：O(n²)</li><li>最坏：O(n²)</li></ul><p><strong>要点：</strong></p><ol><li>比较的总轮数。n - 1</li><li>每轮比较的总次数。i+1, n</li><li>谁和谁比较(交换)。i 和 min_index</li></ol><p><strong>第1轮(索引:0)</strong> 0 和 1,2,3,4比较 <strong>共4次</strong><br /><strong>第2轮(索引:1)</strong> 1 和 2,3,4比较 <strong>共3次</strong><br /><strong>第3轮(索引:2)</strong> 2 和 3,4比较 <strong>共2次</strong><br /><strong>第4轮(索引:3)</strong> 3 和 4比较 <strong>共1次</strong></p><p>[5, 3, 4, 7, 2]</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">selection_sort</span>(<span class="params">arr</span>):</span><br><span class="line">    n = <span class="built_in">len</span>(arr)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>,n-<span class="number">1</span>):</span><br><span class="line">      min_idx = i</span><br><span class="line">      <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(i+<span class="number">1</span>,n):</span><br><span class="line">        <span class="keyword">if</span> arr[j] &lt; arr[min_idx]:</span><br><span class="line">          min_idx = j</span><br><span class="line">      <span class="keyword">if</span> min_idx != i:</span><br><span class="line">        arr[i], arr[min_idx] = arr[min_idx], arr[i]</span><br><span class="line">    <span class="keyword">return</span> arr</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    arr = [<span class="number">5</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">7</span>, <span class="number">2</span>]</span><br><span class="line">    <span class="built_in">print</span>(selection_sort(arr))</span><br></pre></td></tr></table></figure><h2 id="插入排序"><a class="markdownIt-Anchor" href="#插入排序"></a> 插入排序</h2><p>将一个数据插入到已经排好序的有序数据</p><p>默认第一个是有序的，其他默认无序</p><p>稳定排序</p><table><thead><tr><th>第几轮(索引)</th><th>该轮比较的总次数</th><th>公式(具体的谁和谁比较)</th></tr></thead><tbody><tr><td>第1轮(1)：</td><td>1次</td><td>索引1和 0比较</td></tr><tr><td>第2轮(2)：</td><td>2次</td><td>索引2和1， 2和0比较</td></tr><tr><td>第3轮(3)：</td><td>3次</td><td>索引3和2， 3和1， 3和0比较</td></tr><tr><td>第4轮(4)：</td><td>4次</td><td>索引4和3， 4和2， 4和1， 4和0比较</td></tr></tbody></table><p><strong>时间复杂度</strong></p><ul><li>最优：O(n)</li><li>最坏：O(n²)</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">insertion_sort</span>(<span class="params">arr</span>):</span><br><span class="line">    n = <span class="built_in">len</span>(arr)</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>,n):     <span class="comment"># i的值 1    2     3          4</span></span><br><span class="line">      <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(i,<span class="number">0</span>,-<span class="number">1</span>):<span class="comment"># j的值 1   2,1  3,2,1      4,3,2,1  包左不包右</span></span><br><span class="line">        <span class="keyword">if</span> arr[j] &lt; arr[j-<span class="number">1</span>]:</span><br><span class="line">          arr[j], arr[j-<span class="number">1</span>] = arr[j-<span class="number">1</span>], arr[j]</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">          <span class="comment"># 如果当前元素大于等于前一个元素，说明已经有序，不需要交换</span></span><br><span class="line">          <span class="keyword">break</span></span><br><span class="line">    <span class="keyword">return</span> arr</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    arr = [<span class="number">5</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">7</span>, <span class="number">2</span>]</span><br><span class="line">    <span class="built_in">print</span>(insertion_sort(arr))</span><br></pre></td></tr></table></figure><h2 id="快速排序"><a class="markdownIt-Anchor" href="#快速排序"></a> 快速排序</h2><p>首先设置一个分界值，将数组分为左右两边</p><p>大于或等于的放分界值右边，小于的放左边</p><p><strong>时间复杂度</strong></p><ul><li>最优：O(nlogn)</li><li>最坏：O(n²)</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">quick_sort</span>(<span class="params">arr, start, end</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    快速排序</span></span><br><span class="line"><span class="string">    :param arr: 待排序数组</span></span><br><span class="line"><span class="string">    :param start: 起始索引 0</span></span><br><span class="line"><span class="string">    :param end: 结束索引 len(arr)-1</span></span><br><span class="line"><span class="string">    :return: 排序后的数组</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">if</span> start &gt;= end:</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    left = start</span><br><span class="line">    right = end</span><br><span class="line">    <span class="comment"># 定义遍历mid: 假设列表起始值为分界值</span></span><br><span class="line">    mid = arr[start]</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> left &lt; right:</span><br><span class="line">        <span class="comment"># 把分界值右边比分界值小的元素放到左边</span></span><br><span class="line">        <span class="keyword">while</span> left &lt; right <span class="keyword">and</span> arr[right] &gt;= mid:</span><br><span class="line">            right -= <span class="number">1</span></span><br><span class="line">        arr[left]=arr[right]</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> left &lt; right <span class="keyword">and</span> arr[left] &lt; mid:</span><br><span class="line">            left += <span class="number">1</span></span><br><span class="line">        <span class="comment">#说明arry[left]大于或等于mid，需要放到右边</span></span><br><span class="line">        arr[right]=arr[left]</span><br><span class="line">        <span class="comment">#中介值放到正确位置</span></span><br><span class="line">        arr[left]=mid</span><br><span class="line"></span><br><span class="line">        <span class="comment">#递归处理左边子数组</span></span><br><span class="line">        quick_sort(arr, start, left-<span class="number">1</span>)</span><br><span class="line">        <span class="comment">#递归处理右边子数组</span></span><br><span class="line">        quick_sort(arr, left+<span class="number">1</span>, end)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line"></span><br><span class="line">    my_list = [<span class="number">3</span>, <span class="number">2</span>,  <span class="number">4</span>, <span class="number">1</span>,<span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>,  <span class="number">9</span>, <span class="number">8</span>]</span><br><span class="line">    quick_sort(my_list, <span class="number">0</span>, <span class="built_in">len</span>(my_list)-<span class="number">1</span>)</span><br><span class="line">    <span class="built_in">print</span>(my_list)</span><br></pre></td></tr></table></figure><h2 id="二分查找"><a class="markdownIt-Anchor" href="#二分查找"></a> 二分查找</h2><p>属于查找类算法，相对效率比较高，<strong>时间复杂度</strong> O(logn)</p><p>原理： 假设列表是升序 0 1 3 5 7 9 10</p><p>1、比较要查找的元素和列表的中值，如果一样就返回True，程序结束</p><p>2、如果要查找的元素比中值小，去前半段（中值前）查找</p><p>3、如果 要查找的元素 比中值大，去后半段（中值后）查找</p><p>4、重复上面操作，直到找完，如果找完了还是没有，就返回False</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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 class="keyword">def</span> <span class="title function_">binary_search_recursive</span>(<span class="params">my_list, target</span>):</span><br><span class="line">  <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">  二分查找递归版</span></span><br><span class="line"><span class="string">  :param my_list: 有序列表</span></span><br><span class="line"><span class="string">  :param target: 目标值</span></span><br><span class="line"><span class="string">  :return: True在列表中/False不在</span></span><br><span class="line"><span class="string">  &quot;&quot;&quot;</span></span><br><span class="line">  n = <span class="built_in">len</span>(my_list)</span><br><span class="line">  <span class="keyword">if</span> n == <span class="number">0</span>:</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line">  mid = n // <span class="number">2</span></span><br><span class="line">  <span class="keyword">if</span> my_list[mid] == target:</span><br><span class="line">    <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">  <span class="keyword">elif</span> my_list[mid] &gt; target:</span><br><span class="line">    <span class="comment"># 目标值在左半部分</span></span><br><span class="line">    <span class="comment"># 递归调用二分查找函数，传入左半部分的列表</span></span><br><span class="line">    <span class="keyword">return</span> binary_search_recursive(my_list[:mid], target)</span><br><span class="line">  <span class="keyword">else</span>:</span><br><span class="line">    <span class="comment"># 目标值在右半部分</span></span><br><span class="line">    <span class="comment"># 递归调用二分查找函数，传入右半部分的列表</span></span><br><span class="line">    <span class="keyword">return</span> binary_search_recursive(my_list[mid+<span class="number">1</span>:], target)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">binary_search</span>(<span class="params">my_list, target</span>):</span><br><span class="line">  <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">  二分查找非递归版 定义start,end指针分别指向列表首尾索引</span></span><br><span class="line"><span class="string">  :param my_list: 有序列表</span></span><br><span class="line"><span class="string">  :param target: 目标值</span></span><br><span class="line"><span class="string">  :return: True在列表中/False不在</span></span><br><span class="line"><span class="string">  &quot;&quot;&quot;</span></span><br><span class="line">  start = <span class="number">0</span></span><br><span class="line">  end = <span class="built_in">len</span>(my_list) - <span class="number">1</span></span><br><span class="line">  <span class="keyword">while</span> start &lt;= end:</span><br><span class="line">    mid = (start + end) // <span class="number">2</span></span><br><span class="line">    <span class="comment"># 比较 要查找的元素 和 中值</span></span><br><span class="line">    <span class="keyword">if</span> my_list[mid] == target:</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line">    <span class="keyword">elif</span> my_list[mid] &gt; target:</span><br><span class="line">      <span class="comment"># 目标值在左半部分</span></span><br><span class="line">      end = mid - <span class="number">1</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">      <span class="comment"># 目标值在右半部分</span></span><br><span class="line">      start = mid + <span class="number">1</span></span><br><span class="line">  <span class="comment"># 目标值不在列表中</span></span><br><span class="line">  <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="comment"># 测试用例</span></span><br><span class="line">    my_list = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">10</span>]</span><br><span class="line">    <span class="built_in">print</span>(binary_search(my_list, <span class="number">6</span>))</span><br></pre></td></tr></table></figure><h1 id="树"><a class="markdownIt-Anchor" href="#树"></a> 树</h1><p>非线性结构</p><ul><li><strong>节点的度</strong>：一个节点含有的子节点的个数称为该节点的度</li><li><strong>树的度</strong>：一棵树中，最大的节点的度称为树的度</li><li><strong>叶节点或终端节点</strong>：度为零的节点</li><li><strong>父亲节点或父节点</strong>：若一个节点含有子节点，则这个节点称为其子节点的父节点</li><li><strong>孩子节点或子节点</strong>：一个节点含有的子树的根节点称为该节点的子节点</li><li><strong>兄弟节点</strong>：具有相同父节点的节点互称为兄弟节点</li><li><strong>节点的层次</strong>：从根开始定义起，根为第1层，根的子节点为第2层，以此类推</li><li><strong>树的高度或深度</strong>：树中节点的最大层次</li><li><strong>堂兄弟节点</strong>：父节点在同一层的节点互为堂兄弟</li><li><strong>节点的祖先</strong>：从根到该节点所经分支上的所有节点</li><li><strong>子孙</strong>：以某节点为根的子树中任一节点都称为该节点的子孙</li><li><strong>森林</strong>：由m（m&gt;=0）棵互不相交的树的集合称为森林</li></ul><p><strong>分类：</strong></p><p>有序树：</p><p>无序树：</p><p>二叉树：</p><p>完全二叉树：最后一层不满，其他都是满</p><p>非完全二叉树：中间有断的</p><p>满二叉树：全满</p><p>平衡二叉树：任意节点的两个子树高度不超过1</p><p>广度优先遍历算法：一层一层按顺序</p><p>深度优先遍历：中序（中序遍历 左根右）、先序（前序遍历 根左右）、后序（后序遍历 左右根）</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Node</span>:</span><br><span class="line">  <span class="comment">#节点包含元素域，以及左右子节点的指针</span></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, item</span>):</span><br><span class="line">    self.item = item</span><br><span class="line">    self.left = <span class="literal">None</span></span><br><span class="line">    self.right = <span class="literal">None</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">BinaryTree</span>:</span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self,node=<span class="literal">None</span></span>):</span><br><span class="line">    self.root = node</span><br><span class="line"></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">add</span>(<span class="params">self,item</span>):</span><br><span class="line">    new_node = Node(item)</span><br><span class="line">    <span class="keyword">if</span> self.root <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">      self.root = new_node</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    <span class="comment">#创建队列</span></span><br><span class="line">    queue=[]</span><br><span class="line">    queue.append(self.root)</span><br><span class="line">    <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line">      node=queue.pop(<span class="number">0</span>)</span><br><span class="line">      <span class="comment">#判断node是否有左右子节点</span></span><br><span class="line">      <span class="keyword">if</span> node.left <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">        node.left=new_node</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">      <span class="keyword">else</span>:</span><br><span class="line">        queue.append(node.left)</span><br><span class="line">      <span class="keyword">if</span> node.right <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">        node.right=new_node</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">      <span class="keyword">else</span>:</span><br><span class="line">        queue.append(node.right)</span><br><span class="line"></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">breadth_travel</span>(<span class="params">self</span>):</span><br><span class="line">    <span class="keyword">if</span> self.root <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    queue=[]</span><br><span class="line">    queue.append(self.root)</span><br><span class="line">    <span class="keyword">while</span> <span class="built_in">len</span>(queue)&gt;<span class="number">0</span>:</span><br><span class="line">      node=queue.pop(<span class="number">0</span>)</span><br><span class="line">      <span class="built_in">print</span>(node.item,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">      <span class="comment"># 判断node是否有左右子节点</span></span><br><span class="line">      <span class="keyword">if</span> node.left <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">        queue.append(node.left)</span><br><span class="line">      <span class="keyword">if</span> node.right <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">None</span>:</span><br><span class="line">        queue.append(node.right)</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 前序遍历 根左右</span></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">preorder</span>(<span class="params">self,root</span>):</span><br><span class="line">    <span class="keyword">if</span> root <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    <span class="built_in">print</span>(root.item,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">    self.preorder(root.left)</span><br><span class="line">    self.preorder(root.right)</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 中序遍历 左根右</span></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">inorder</span>(<span class="params">self,root</span>):</span><br><span class="line">    <span class="keyword">if</span> root <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    self.inorder(root.left)</span><br><span class="line">    <span class="built_in">print</span>(root.item,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">    self.inorder(root.right)</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 后序遍历 左右根</span></span><br><span class="line">  <span class="keyword">def</span> <span class="title function_">postorder</span>(<span class="params">self,root</span>):</span><br><span class="line">    <span class="keyword">if</span> root <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    self.postorder(root.left)</span><br><span class="line">    self.postorder(root.right)</span><br><span class="line">    <span class="built_in">print</span>(root.item,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">#测试函数</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">demo_binary_tree</span>():</span><br><span class="line">  node1 = Node(<span class="string">&quot;A&quot;</span>)</span><br><span class="line">  <span class="built_in">print</span>(node1.item)</span><br><span class="line">  <span class="built_in">print</span>(node1.left)</span><br><span class="line">  <span class="built_in">print</span>(node1.right)</span><br><span class="line">  <span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">20</span>)</span><br><span class="line">  bt=BinaryTree(node1)</span><br><span class="line">  <span class="built_in">print</span>(bt.root.item)</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">demo_binary_tree2</span>():</span><br><span class="line">  <span class="comment">#二叉树如下： 广度优先遍历结果A B C D E F G H I J ，一层一层遍历</span></span><br><span class="line">  <span class="comment">#      a</span></span><br><span class="line">  <span class="comment">#    b         c</span></span><br><span class="line">  <span class="comment">#  d    e    f    g</span></span><br><span class="line">  <span class="comment">#h  i j</span></span><br><span class="line">  <span class="comment"># 队列那种，先进先出，第一个A，然后去查左右子节点，有就入队，再pop[0]将A出队，</span></span><br><span class="line">  <span class="comment"># 继续判断B是否有左右子节点，有就入队，再pop[0]将B出队，</span></span><br><span class="line">  <span class="comment"># 继续判断C是否有左右子节点，有就入队，再pop[0]将C出队....</span></span><br><span class="line">    bt=BinaryTree()</span><br><span class="line">    bt.add(<span class="string">&quot;A&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;B&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;C&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;D&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;E&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;F&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;G&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;H&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;I&quot;</span>)</span><br><span class="line">    bt.add(<span class="string">&quot;J&quot;</span>)</span><br><span class="line">    bt.breadth_travel()</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">demo_binary_tree3</span>():</span><br><span class="line">  <span class="comment">#树结构如下</span></span><br><span class="line">  <span class="comment">#      0</span></span><br><span class="line">  <span class="comment">#    1         2</span></span><br><span class="line">  <span class="comment">#  3    4    5    6</span></span><br><span class="line">  <span class="comment">#7  8 9</span></span><br><span class="line">  <span class="comment">#先序遍历结果：0 1 3 7 8 4 9 2 5 6   根左右</span></span><br><span class="line">  <span class="comment">#中序遍历结果：7 3 8 1 9 4 0 5 2 6   左根右</span></span><br><span class="line">  <span class="comment">#后序遍历结果：7 8 3 9 4 1 5 6 2 0   左右根</span></span><br><span class="line"></span><br><span class="line">    bt=BinaryTree()</span><br><span class="line">    bt.add(<span class="number">0</span>)</span><br><span class="line">    bt.add(<span class="number">1</span>)</span><br><span class="line">    bt.add(<span class="number">2</span>)</span><br><span class="line">    bt.add(<span class="number">3</span>)</span><br><span class="line">    bt.add(<span class="number">4</span>)</span><br><span class="line">    bt.add(<span class="number">5</span>)</span><br><span class="line">    bt.add(<span class="number">6</span>)</span><br><span class="line">    bt.add(<span class="number">7</span>)</span><br><span class="line">    bt.add(<span class="number">8</span>)</span><br><span class="line">    bt.add(<span class="number">9</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;先序 根左右：&#x27;</span>,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">    bt.preorder(bt.root)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">20</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;中序 左根右：&#x27;</span>,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">    bt.inorder(bt.root)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;-&#x27;</span>*<span class="number">20</span>)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">&#x27;后序 左右根：&#x27;</span>,end=<span class="string">&#x27; &#x27;</span>)</span><br><span class="line">    bt.postorder(bt.root)</span><br><span class="line">    <span class="built_in">print</span>()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    <span class="comment"># 测试用例</span></span><br><span class="line">    <span class="comment"># demo_binary_tree()</span></span><br><span class="line">    <span class="comment"># demo_binary_tree2()</span></span><br><span class="line">    demo_binary_tree3()</span><br></pre></td></tr></table></figure><p><strong>二叉树遍历结果反推 二叉树结构</strong></p><p>先序遍历结果：0 1 3 7 8 4 9 2 5 6 根左右<br />中序遍历结果：7 3 8 1 9 4 0 5 2 6 左根右</p><p>通过先序，确定根是0，再根据中序，0的位置，切分为左右树</p>]]></content>
    
    
    <summary type="html">路漫漫其修远兮，吾将上下而求索</summary>
    
    
    
    <category term="编程基础" scheme="https://luckynwa.top/categories/%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80/"/>
    
    
    <category term="Algorithm" scheme="https://luckynwa.top/tags/Algorithm/"/>
    
  </entry>
  
  <entry>
    <title>Java 常见案例与排序算法</title>
    <link href="https://luckynwa.top/posts/base1/"/>
    <id>https://luckynwa.top/posts/base1/</id>
    <published>2023-09-01T01:01:16.000Z</published>
    <updated>2026-07-07T16:20:55.731Z</updated>
    
    <content type="html"><![CDATA[<h1 id="入门案例"><a class="markdownIt-Anchor" href="#入门案例"></a> 入门案例</h1><h2 id="九九乘法表"><a class="markdownIt-Anchor" href="#九九乘法表"></a> 九九乘法表</h2><p><img src="https://cloud.luckynwa.top/profile/mdS/javaS1.png" alt="" /></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><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">9</span>; i++) &#123;  <span class="comment">//控制行,从1开始循环</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= i; j++) &#123; <span class="comment">//控制每行对应的数</span></span><br><span class="line">                System.out.print(i + <span class="string">&quot;*&quot;</span> + j + <span class="string">&quot;=&quot;</span> + i * j + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//第一次循环i是1 j也是1 结果1*1=1    这是图1第一种</span></span><br><span class="line">            <span class="comment">//第二次循环i是2  j是1和2 结果2*1=2  2*2=4</span></span><br><span class="line">            <span class="comment">//第三次循环i是3  j是1、2、3 结果3*1=3    3*2=6  3*3=9</span></span><br><span class="line">            <span class="comment">//同理</span></span><br><span class="line">            System.out.println();<span class="comment">//每次循环完换行</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/javaS2.png" alt="" /></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><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">9</span>; i &gt;= <span class="number">1</span>; i--) &#123;  <span class="comment">//控制行,从9开始循环</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= i; j++) &#123; <span class="comment">//控制每行对应的数</span></span><br><span class="line">                System.out.print(i + <span class="string">&quot;*&quot;</span> + j + <span class="string">&quot;=&quot;</span> + i * j + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//第一次循环i是9 j也是1到9  9*1 9*2....   这是第二图</span></span><br><span class="line">            <span class="comment">//第二次循环i是8  j是1到8</span></span><br><span class="line">            <span class="comment">//同理</span></span><br><span class="line">            System.out.println();<span class="comment">//每次循环完换行</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/javaS3.png" alt="" /></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;<span class="comment">//发现是第二图从第二行开始往右边移动2个\t(制表符差不多空格的意思),只要再j循环的**上面**先弄空白就会把它挤到右边</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">9</span>; i &gt;= <span class="number">1</span>; i--) &#123;  <span class="comment">//控制行,从9开始循环</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">1</span>; m &lt;= <span class="number">9</span> - i; m++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;\t\t&quot;</span>);<span class="comment">//控制每行对应的数</span></span><br><span class="line">                <span class="comment">//第一次i=9的时候m是false不运行</span></span><br><span class="line">                <span class="comment">//第二次i=8的时候m是1，运行一次</span></span><br><span class="line">                <span class="comment">//i=7，运行2次 同理 关键是9-i要想到</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= i; j++) &#123; <span class="comment">//控制每行对应的数</span></span><br><span class="line">                System.out.print(i + <span class="string">&quot;*&quot;</span> + j + <span class="string">&quot;=&quot;</span> + i * j + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//第一次循环i是9 j也是1到9</span></span><br><span class="line">            <span class="comment">//第二次循环i是8  j是1到8</span></span><br><span class="line">            <span class="comment">//同理</span></span><br><span class="line">            System.out.println();<span class="comment">//每次循环完换行</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/javaS4.png" alt="" /></p><p>发现第一行是1，第二行是2 说明i是从1开始的，那个空白第一行有8个，所以循环从9开始，因为不等于i，所以第一次就循环8次空格，就可以把数字挤到右边去了</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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">9</span>; i++) &#123;  <span class="comment">//控制行,从9开始循环</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">9</span>; m &gt; i; m--) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;\t\t&quot;</span>);<span class="comment">//控制每行对应的数</span></span><br><span class="line">                <span class="comment">//第一次i=1的时候m循环8次</span></span><br><span class="line">                <span class="comment">//第二次i=2的时m循环7次</span></span><br><span class="line">                <span class="comment">//同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= i; j++) &#123; <span class="comment">//控制每行对应的数</span></span><br><span class="line">                System.out.print(i + <span class="string">&quot;*&quot;</span> + j + <span class="string">&quot;=&quot;</span> + i * j + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">//第一次循环i是1 j也是1到1</span></span><br><span class="line">            <span class="comment">//第二次循环i是2  j是1和2</span></span><br><span class="line">            <span class="comment">//同理</span></span><br><span class="line">            System.out.println();<span class="comment">//每次循环完换行</span></span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="星星"><a class="markdownIt-Anchor" href="#星星"></a> 星星</h2><p><img src="https://cloud.luckynwa.top/profile/2026/07/04/image-20260704161127840_20260704161129A005.png" alt="image-20260704161127840" /></p><p>(1)</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">1</span>; k &lt;= <span class="number">5</span>; k++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                <span class="comment">//K控制每行多少个 都是5个</span></span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>(2)</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">1</span>; k &lt;= (<span class="number">2</span> * i) - <span class="number">1</span>; k++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                <span class="comment">//i=1 k=1</span></span><br><span class="line">                <span class="comment">//i=2 K=3同理，3就是循环了3次*</span></span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>(3)第三题的思路：发现和第二图加倒三角 那我们只要再画一个倒的三角就行，在2图的基础上</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> <span class="number">1</span>; k &lt;= (<span class="number">2</span> * i) - <span class="number">1</span>; k++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                <span class="comment">//i=1 k=1</span></span><br><span class="line">                <span class="comment">//i=2 K=3同理，3就是循环了3次*</span></span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;<span class="comment">//下面新的循环是控制倒的三角</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">ii</span> <span class="operator">=</span> <span class="number">4</span>; ii &gt;= <span class="number">1</span>; ii--) &#123;  <span class="comment">//ii控制行，共4行,倒3角有4行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">jj</span> <span class="operator">=</span> <span class="number">1</span>; jj &lt;= <span class="number">5</span> - ii; jj++) &#123;<span class="comment">//jj控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);</span><br><span class="line">                <span class="comment">//发现ii=4时候 jj循环1次 ii=3 jj循环2次</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">kk</span> <span class="operator">=</span> <span class="number">1</span>; kk &lt;= (<span class="number">2</span> * ii) - <span class="number">1</span>; kk++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                <span class="comment">//ii=4 kk=7 就是7颗*</span></span><br><span class="line">                <span class="comment">//ii=3 Kk=3同理，3就是循环了3次*</span></span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>(4-1)思路：再上个代码改，可以考虑先画靠近m的那几个*,再画空格，然后再画最右边的*即可</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> i; k == i; k++) &#123;<span class="comment">//即每次循环画1次</span></span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                <span class="comment">//前面画完空格 再接1颗*即可</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">2</span>; m &lt; <span class="number">2</span> * i - <span class="number">1</span>; m++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);<span class="comment">//这是空格的规律从第二行开始</span></span><br><span class="line">                <span class="comment">//i=1,不运行 i=2 2&lt;3  第二行只循环1次空格</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (i &gt; <span class="number">1</span>) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">kk</span> <span class="operator">=</span> i; kk == i; kk++) &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                    <span class="comment">//因为第一行已经有了。所以第二行开始</span></span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;<span class="comment">//下面新的循环是控制倒的三角，同理</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">ii</span> <span class="operator">=</span> <span class="number">4</span>; ii &gt;= <span class="number">1</span>; ii--) &#123;  <span class="comment">//ii控制行，共4行,倒3角有4行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">jj</span> <span class="operator">=</span> <span class="number">1</span>; jj &lt;= <span class="number">5</span> - ii; jj++) &#123;<span class="comment">//jj控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot;m&quot;</span>);</span><br><span class="line">                <span class="comment">//发现ii=4时候 jj循环1次 ii=3 jj循环2次</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">kk</span> <span class="operator">=</span> ii; kk &lt;= ii; kk++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">2</span>; m &lt; <span class="number">2</span> * ii - <span class="number">1</span>; m++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (ii &gt; <span class="number">1</span>) &#123;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">kk</span> <span class="operator">=</span> ii; kk &lt;= ii; kk++) &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>(4-2)更简单的方法</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">1</span>; m &lt;= <span class="number">2</span> * i - <span class="number">1</span>; m++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (m == <span class="number">1</span> || m == <span class="number">2</span> * i - <span class="number">1</span>) &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot;*&quot;</span>);<span class="comment">//这是直接来判断开头和结尾</span></span><br><span class="line">                    <span class="comment">//i=1 m=1 进判断 循环1次*</span></span><br><span class="line">                    <span class="comment">//i=2 m=1,2,3 正常循环3次 进判断，1时候打印*，m==2*2-1==3 所以m=2时候是空格 3时候才是*</span></span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;<span class="comment">//下面新的循环是控制倒的三角，同理</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">ii</span> <span class="operator">=</span> <span class="number">4</span>; ii &gt;= <span class="number">1</span>; ii--) &#123;  <span class="comment">//ii控制行，共4行,倒3角有4行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">jj</span> <span class="operator">=</span> <span class="number">1</span>; jj &lt;= <span class="number">5</span> - ii; jj++) &#123;</span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">1</span>; m &lt;= <span class="number">2</span> * ii - <span class="number">1</span>; m++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (m == <span class="number">1</span> || m == <span class="number">2</span> * ii - <span class="number">1</span>) &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot;*&quot;</span>);</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>(5)在第四图的基础上改一下就可以</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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= <span class="number">5</span>; i++) &#123;<span class="comment">//i控制行，共5行</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">5</span>; j &gt; i; j--) &#123;<span class="comment">//j控制每一行的数量</span></span><br><span class="line">                System.out.print(<span class="string">&quot; &quot;</span>);<span class="comment">//用m代替空格先测试，如果正确变空格</span></span><br><span class="line">                <span class="comment">//i=1 j=4,3,2,1 输出4个m</span></span><br><span class="line">                <span class="comment">//i=2 j循环3次m 同理</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">1</span>; m &lt;= <span class="number">2</span> * i - <span class="number">1</span>; m++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (m == <span class="number">1</span> || m == <span class="number">2</span> * i - <span class="number">1</span> || i == <span class="number">5</span>) &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot;*&quot;</span>);<span class="comment">//这是直接来判断开头和结尾</span></span><br><span class="line">                    <span class="comment">//i=1 m=1 进判断 循环1次*</span></span><br><span class="line">                    <span class="comment">//i=2 m=1,2,3 正常循环3次 进判断，1时候打印*，m==2*2-1==3 所以m=2时候是空格 3时候才是*</span></span><br><span class="line">                    <span class="comment">//补一个i==5就行了,就直接打印9颗，m&lt;=9</span></span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    System.out.print(<span class="string">&quot; &quot;</span>);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="完数"><a class="markdownIt-Anchor" href="#完数"></a> 完数</h2><p>输入一个数，判断这个数是不是完数<br />完数：一个数恰好等于它的除了它本身之外所有因数之和，这个数就称为“完数”。<br />例如：6的因数有：1、2、3；由于6=1+2+3，所以6是完数。</p><p>6是完数<br />28是完数<br />496是完数</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">scanner</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        System.out.println(<span class="string">&quot;请输入一个整数:&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> scanner.nextInt();</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; a; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (a % i == <span class="number">0</span>) &#123;</span><br><span class="line">                sum += i;</span><br><span class="line">                System.out.println(i);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (sum == a) &#123;</span><br><span class="line">            System.out.println(a + <span class="string">&quot;是完数&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(a + <span class="string">&quot;不是完数&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">        demo();<span class="comment">//多余的测试一下100到999有多少个完数</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> <span class="keyword">void</span> <span class="title function_">demo</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">100</span>; a &lt; <span class="number">1000</span>; a++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; a; i++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (a % i == <span class="number">0</span>) &#123;</span><br><span class="line">                    sum += i;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (sum == a) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;100到999之间的完数有：&quot;</span> + a);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="斐波纳契数列fibonacci-series"><a class="markdownIt-Anchor" href="#斐波纳契数列fibonacci-series"></a> 斐波纳契数列（Fibonacci series）</h2><p>两个元素的总和确定了下一个数 1 1 2 3 5 8</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">1</span>; m &lt; <span class="number">6</span>; m++) &#123;</span><br><span class="line">            System.out.print(a + <span class="string">&quot;\t&quot;</span> + b + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            a = a + b;</span><br><span class="line">            b = a + b;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="水仙花数"><a class="markdownIt-Anchor" href="#水仙花数"></a> 水仙花数</h2><p>水仙花数必须是3位数，它的每个位上的数字的 3次幂之和等于它本身。例如：1^3 + 5^3+ 3^3 = 153</p><p>水仙花数共有4个：153，370，371，407；</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">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">100</span>; a &lt; <span class="number">1000</span>; a++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> a / <span class="number">100</span>;  <span class="comment">//百位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">c</span> <span class="operator">=</span> a % <span class="number">10</span>;   <span class="comment">//个位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">d</span> <span class="operator">=</span> a / <span class="number">10</span> % <span class="number">10</span>;<span class="comment">//十位 a == Math.pow(b,3) +  Math.pow(c,3) +  Math.pow(d,3)</span></span><br><span class="line">            <span class="keyword">if</span> (a == b * b * b + c * c * c + d * d * d) &#123;</span><br><span class="line">                System.out.println(a + <span class="string">&quot;这是水仙数&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Scanner</span> <span class="variable">scanner</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">            System.out.print(<span class="string">&quot;请输入一个三位的正整数：&quot;</span>);<span class="comment">//判断输入的是否是水仙数</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> scanner.nextInt();</span><br><span class="line">            <span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> a / <span class="number">100</span>;  <span class="comment">//百位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">c</span> <span class="operator">=</span> a % <span class="number">10</span>;   <span class="comment">//个位</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">d</span> <span class="operator">=</span> a / <span class="number">10</span> % <span class="number">10</span>;<span class="comment">//十位</span></span><br><span class="line">            <span class="keyword">if</span> (a == b * b * b + c * c * c + d * d * d) &#123;</span><br><span class="line">                System.out.println(a + <span class="string">&quot;这是水仙数&quot;</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(a + <span class="string">&quot;不是水仙数&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;您的输入有误!&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="阶乘"><a class="markdownIt-Anchor" href="#阶乘"></a> 阶乘</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">long</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">6</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt;= n; i += <span class="number">2</span>) &#123;  <span class="comment">//这里求1！+3！+5！</span></span><br><span class="line">            <span class="type">long</span> <span class="variable">temp</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= i; j++) &#123;</span><br><span class="line">                temp *= j;</span><br><span class="line">            &#125;</span><br><span class="line">            sum = sum + temp;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;1！+3！+5！= &quot;</span> + sum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">1</span>; j &lt;= <span class="number">5</span>; j++) &#123;</span><br><span class="line">            i *= j;</span><br><span class="line">            sum += i;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;1到5的阶乘和:&quot;</span> + sum);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="回文数"><a class="markdownIt-Anchor" href="#回文数"></a> 回文数</h2><p>输入一个数 如121 反过来也是一样 1221 也是</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">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Scanner</span> <span class="variable">scanner</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">            System.out.println(<span class="string">&quot;请输入一个数：&quot;</span>);</span><br><span class="line">            <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> scanner.nextInt();</span><br><span class="line">            <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> i;</span><br><span class="line">            <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="keyword">while</span> (i != <span class="number">0</span>) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">ge</span> <span class="operator">=</span> i % <span class="number">10</span>;</span><br><span class="line">                i = i / <span class="number">10</span>;</span><br><span class="line">                num = num * <span class="number">10</span> + ge;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (temp == num) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;这是回文数&quot;</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;这不是回文数&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;输入有误!&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="输入10个数输出最大值和最小值"><a class="markdownIt-Anchor" href="#输入10个数输出最大值和最小值"></a> 输入10个数，输出最大值和最小值</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        getMaxAndMin();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">getMaxAndMin</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">            System.out.println(<span class="string">&quot;请输入第1个数：&quot;</span>);</span><br><span class="line">            <span class="comment">//把第一次输入的数字赋给max和min</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">num1</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">            <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> num1;</span><br><span class="line">            <span class="type">int</span> <span class="variable">min</span> <span class="operator">=</span> num1;</span><br><span class="line">            <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">while</span> (count &lt;= <span class="number">10</span>) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;请输入第&quot;</span> + count + <span class="string">&quot;个数字：&quot;</span>);</span><br><span class="line">                <span class="type">int</span> <span class="variable">numx</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">                <span class="keyword">if</span> (numx &gt; max) &#123;</span><br><span class="line">                    max = numx;<span class="comment">//比最大的值还大</span></span><br><span class="line">                &#125; <span class="keyword">else</span> <span class="keyword">if</span> (numx &lt; min) &#123;</span><br><span class="line">                    min = numx;<span class="comment">//比最小的值还小</span></span><br><span class="line">                &#125;</span><br><span class="line">                count++;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;最大值：&quot;</span> + max + <span class="string">&quot;, 最小值：&quot;</span> + min);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;输入错误，请重新输入！！！&quot;</span>);</span><br><span class="line">            getMaxAndMin();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>优化</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        getMaxAndMin();</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> <span class="keyword">void</span> <span class="title function_">getMaxAndMin</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Scanner</span> <span class="variable">sc</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">            System.out.println(<span class="string">&quot;请输入第1个数：&quot;</span>);</span><br><span class="line">            <span class="comment">//把第一次输入的数字赋给max和min</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">num1</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line"></span><br><span class="line">            <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> num1;</span><br><span class="line">            <span class="type">int</span> <span class="variable">min</span> <span class="operator">=</span> num1;</span><br><span class="line">            <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line">            <span class="keyword">while</span> (count &lt;= <span class="number">3</span>) &#123;</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;请输入第&quot;</span> + count + <span class="string">&quot;个数字：&quot;</span>);</span><br><span class="line">                    <span class="type">int</span> <span class="variable">numx</span> <span class="operator">=</span> sc.nextInt();</span><br><span class="line">                    <span class="keyword">if</span> (numx &gt; max) &#123;</span><br><span class="line">                        max = numx;<span class="comment">//比最大的值还大</span></span><br><span class="line">                    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (numx &lt; min) &#123;</span><br><span class="line">                        min = numx;<span class="comment">//比最小的值还小</span></span><br><span class="line">                    &#125;</span><br><span class="line">                    count++;</span><br><span class="line">                &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                    System.out.println(<span class="string">&quot;输入错误，请重新输入！！！&quot;</span>);</span><br><span class="line">                    sc = <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;最大值：&quot;</span> + max + <span class="string">&quot;, 最小值：&quot;</span> + min);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;输入错误，请重新输入！！！&quot;</span>);</span><br><span class="line">            getMaxAndMin();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="时间复杂度"><a class="markdownIt-Anchor" href="#时间复杂度"></a> 时间复杂度</h1><p>O(1)：常数时间复杂度，表示算法的执行时间不随输入规模变化而变化。比如数组访问操作，无论数组大小为多少，其访问时间都是O(1)。</p><p>O(log n)：对数时间复杂度，表示算法的执行时间与输入规模呈对数关系。比如二分查找算法，每次能够将搜索区间缩小一半，所以时间复杂度为O(log n)。</p><p>O(n)：线性时间复杂度，表示算法的执行时间与输入规模呈线性关系。比如顺序查找算法，需要逐个比较所有元素，所以时间复杂度为O(n)。</p><p>O(n log n)：常见的排序算法时间复杂度都为O(n log n)，包括快速排序、归并排序等。</p><p>O(n^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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">100</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;lucky&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>第一眼肯定看不出算法的运行时间，而且n的值可能1000000</p><p>现在我们把每一条语句的执行时间都看做是一样的，记为一个<strong>时间单元</strong></p><p>① 初始化int i和n，花费两个时间单元 n=100来理解</p><p>②i&lt;n(最后一次也要比较)，花费n+1个时间单元</p><p>③打印和i++两条语句，花费2*n个时间单元</p><p>共3n+3的时间单元 也就是数学的线性关系 当值越大+3就可以忽略变3n</p><p>T(n)来标识程序消耗的时间</p><p>T(n)=n+1 忽略常数项 T(n)~n</p><p>T(n)=n+n^2 忽略低阶项 T(n)~n^2</p><p>T(n)=3n 忽略最高阶的系数 T(n)~n</p><p>所谓的<strong>时间复杂度</strong>：只关心问题规模n趋于无穷时函数对结果影响最大的项，最高次项</p><p>时间复杂度越低越好。时间复杂度表示算法的执行时间与输入规模之间的增长关系，通常用大 O 表示法表示。较低的时间复杂度意味着算法在处理大规模问题时更高效。当涉及大规模数据处理或复杂计算时，拥有较低的时间复杂度可以极大地提高算法的执行效率和性能。因此，更低的时间复杂度通常是我们追求的目标。然而，时间复杂度并不是唯一考虑的因素。还要综合考虑其他因素，如空间复杂度、算法的可读性、代码的可维护性等。有时候，在时间复杂度较低的算法之间进行选择时，我们也需要权衡其他因素，以找到最适合特定问题和实际需求的解决方案。</p><p>简化后的值就是时间复杂度了下面那个，如刚刚上面那个O(f(n))</p><p>T(n)=3n+3 简化 T(n)~f(n)=n 记做O(n)</p><p><img src="https://cloud.luckynwa.top/profile/mdS/shijianfuzdu.png" alt="时间复杂度" /></p><p>一、得出运行时间的函数 二、对函数进行简化</p><p>准确地说O代表了运行时间函数的一个渐进上界，即<strong>T(n)在数量级上小于等于f(n)</strong></p><figure class="highlight java"><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="type">int</span> <span class="variable">n</span> <span class="operator">=</span> <span class="number">100</span>;</span><br><span class="line">System.out.println(n);</span><br></pre></td></tr></table></figure><p>像这种只运行一次，时间复杂度就是O(1)</p><p>一般循环看最内层打印的规律即可，n增加线性增加直接O(n)</p><p>嵌套循环2层，时间复杂度就是O(n^2) 内层语句随n的增加呈现2次函数的规律</p><p>对数函数趋势是随着自变量增大，因变量增长越慢 log</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></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">1</span>;</span><br><span class="line"><span class="keyword">while</span> (sum &lt; n) &#123;</span><br><span class="line">    sum *= <span class="number">2</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>while循环的条件是 <code>sum &lt; n</code>，每次循环中sum都会乘以2。我们可以观察到，在循环中，<strong>sum的值会以指数级别增长</strong>，直到sum不小于n为止。 假设起始时 <code>sum = 1</code>，循环在 sum 不超过 n 的情况下进行。 第一次循环，sum变为2，第二次循环，sum变为4，以此类推，直到 sum 不小于 n。 由于每次循环中 sum 都会乘以2，因此循环次数为 log2(n)。也就是说，<strong>循环次数与 n 的大小呈对数关系</strong>。 因此，该代码的时间复杂度为 O(log n)</p><h1 id="经典排序算法"><a class="markdownIt-Anchor" href="#经典排序算法"></a> 经典排序算法</h1><p>1、冒泡排序 2、选择排序 3、插入排序 4、归并排序 5、希尔排序 6、快速排序 7、堆排序 8、基数排序</p><h2 id="冒泡排序"><a class="markdownIt-Anchor" href="#冒泡排序"></a> 冒泡排序</h2><p>基本思路： 就比如数组里面[3,1,6,2,5] 就是两两比较，首先3 1比较3大则3到右边，3 6比较6大，6本身右边则不变，同理6 2</p><p>第一轮遍历：3 1 6 2 5 -&gt; 1 3 6 2 5 -&gt; 1 3 6 2 5 -&gt; 1 3 2 6 5 -&gt; 1 3 2 5 6</p><p>第二轮遍历：1 3 2 5 6 -&gt; 1 2 3 5 6 -&gt; 1 2 3 5 6</p><p>经过两轮遍历后，数组已经排序完成</p><p>冒泡排序的时间复杂度是O(n^2)，其中n是数组的长度。尽管冒泡排序是一种简单的排序算法，但对于小规模的数据集，它仍然是一个可行的选择</p><p><strong>分析</strong></p><p>从开始第一对到结尾的最后一对-----&gt;最后的元素是最大的数</p><p>—&gt;除了最后一个，最多需要进行length-1</p><p>首先肯定要明确是双重for循环，因为数组从0开始，所以int i=0，i&lt; arr.length - 1是因为两个比较肯定少1轮，外循环确定，每一次外循环后内循环次数会在 arr.length - 1基础上再-i次</p><p>内循环只要判断相邻大小互换即可</p><p><img src="https://cloud.luckynwa.top/profile/mdS/maopao.gif" alt="冒泡" /></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = <span class="keyword">new</span> <span class="title class_">int</span>[]&#123;<span class="number">3</span>, <span class="number">1</span>, <span class="number">6</span>, <span class="number">2</span>, <span class="number">5</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; arr.length - <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; arr.length - <span class="number">1</span> - i; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (arr[j] &gt; arr[j + <span class="number">1</span>]) &#123;</span><br><span class="line">                    <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> arr[j];<span class="comment">//为什么不直接覆盖 arr[j + 1]=arr[j]，这样arr[j + 1]值就没了需要临时存一个</span></span><br><span class="line">                    arr[j] = arr[j + <span class="number">1</span>];</span><br><span class="line">                    arr[j + <span class="number">1</span>] = temp;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> item : arr) &#123;</span><br><span class="line">            System.out.print(item + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>优化：如果一个数组已经是完全有序的情况下，冒泡排序法仍然会进行逐轮的比较，这无疑是浪费性能的行为</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><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 class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = <span class="keyword">new</span> <span class="title class_">int</span>[]&#123;<span class="number">3</span>, <span class="number">1</span>, <span class="number">6</span>, <span class="number">2</span>, <span class="number">5</span>&#125;;</span><br><span class="line">        <span class="type">Boolean</span> <span class="variable">Sort</span> <span class="operator">=</span> <span class="literal">false</span>;<span class="comment">//定义一个开关</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; arr.length - <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (!Sort) &#123;</span><br><span class="line">                Sort = <span class="literal">true</span>;</span><br><span class="line">                <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; arr.length - <span class="number">1</span> - i; j++) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (arr[j] &gt; arr[j + <span class="number">1</span>]) &#123;</span><br><span class="line">                        <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> arr[j];</span><br><span class="line">                        arr[j] = arr[j + <span class="number">1</span>];</span><br><span class="line">                        arr[j + <span class="number">1</span>] = temp;</span><br><span class="line">                        Sort = <span class="literal">false</span>;<span class="comment">//说明这一轮有交换</span></span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">break</span>;<span class="comment">//停止循环</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> item : arr) &#123;</span><br><span class="line">            System.out.print(item + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="选择排序"><a class="markdownIt-Anchor" href="#选择排序"></a> 选择排序</h2><p>基本思路：通过一轮比较，选出最小的那个元素的下标，然后和第一个元素进行交换，第一个元素的位置就可以确定。数组11, 2, 33, 24, 15</p><p>第一次遍历，找到最小元素2，将其与第一个元素11交换位置：2 11 33 24 15</p><p>第二次遍历，找到最小元素11，不需要交换位置：2 11 33 24 15</p><p>第三次遍历，找到最小元素15，将其与第三个元素33交换位置：2 11 15 24 33</p><p>第四次遍历，找到最小元素24，将其与第四个元素33交换位置：2 11 15 24 33</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><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = <span class="keyword">new</span> <span class="title class_">int</span>[]&#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; arr.length - <span class="number">1</span>; i++) &#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> i;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> k + <span class="number">1</span>; j &lt; arr.length; j++) &#123;</span><br><span class="line">                <span class="keyword">if</span> (arr[j] &lt; arr[k]) &#123;</span><br><span class="line">                    k = j;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span> (k != i) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">t</span> <span class="operator">=</span> arr[k];</span><br><span class="line">                arr[k] = arr[i];</span><br><span class="line">                arr[i] = t;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">0</span>; m &lt; arr.length; m++) &#123;</span><br><span class="line">            System.out.print(arr[m] + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>选择排序比较的轮数和冒泡排序比较的轮数是一样的</li><li>K表示当前最小值的下标，当前是第几轮，k就先代表第几个元素的下标，然后依次和后面的元素进行比较，如果发现比k位置元素小的元素时，改变k的下标，这样一轮过后k代表的位置就是本轮最小的元素，和i进行交换即可</li><li>如果一轮过后k==i，则说明i本来就是最小的元素，则无需交换提高性能。</li></ul><h2 id="插入排序"><a class="markdownIt-Anchor" href="#插入排序"></a> 插入排序</h2><p>假设一个数组已经基本有序，则这个时候插入排序就是一个不错的选择。插入排序是先保证左边元素是基本有序的，然后将后面的元素依次和左边元素进行比较，如果比较到一个比自己小的元素时就可以停止比较了，因为左边已经呈现有序状态，找到比自己小的元素时，就不用再往后比较了，对数组[11, 2, 33, 24, 15]</p><p>初始状态：11 | 2 33 24 15</p><p>第一次插入：2 11 | 33 24 15</p><p>第二次插入：2 11 33 | 24 15</p><p>第三次插入：2 11 24 33 | 15</p><p>第四次插入：2 11 15 24 33 |</p><p>已排序部分的初始状态只有一个元素，即数组的第一个元素。在这个例子中，已排序部分为 11 |右边都是未排序的</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><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = <span class="keyword">new</span> <span class="title class_">int</span>[]&#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">            <span class="comment">//arr[j]~arr[j-1]</span></span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> i; j &gt; <span class="number">0</span>; j--) &#123;</span><br><span class="line">                <span class="keyword">if</span> (arr[j] &lt; arr[j - <span class="number">1</span>]) &#123;</span><br><span class="line">                    <span class="type">int</span> <span class="variable">t</span> <span class="operator">=</span> arr[j];</span><br><span class="line">                    arr[j] = arr[j - <span class="number">1</span>];</span><br><span class="line">                    arr[j - <span class="number">1</span>] = t;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> <span class="number">0</span>; m &lt; arr.length; m++) &#123;</span><br><span class="line">            System.out.print(arr[m] + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li><p>插入排序的轮数和冒泡排序一样，但是i从1开始，因为我们假设第一个元素已经是呈现有序状态了。</p></li><li><p>内部循环依次从当前位置开始，和前面元素进行比较，如果找到了比自己小的元素，则停止比较，直接退出本轮比较，进行下一轮比较</p></li></ul><h2 id="归并排序"><a class="markdownIt-Anchor" href="#归并排序"></a> 归并排序</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        mergeSort(arr);</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorted array: &quot;</span> + Arrays.toString(arr));</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> <span class="keyword">void</span> <span class="title function_">mergeSort</span><span class="params">(<span class="type">int</span>[] arr)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr == <span class="literal">null</span> || arr.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span>[] temp = <span class="keyword">new</span> <span class="title class_">int</span>[arr.length];</span><br><span class="line">        mergeSort(arr, temp, <span class="number">0</span>, arr.length - <span class="number">1</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">mergeSort</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span>[] temp, <span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (left &gt;= right) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> <span class="variable">mid</span> <span class="operator">=</span> (left + right) / <span class="number">2</span>;</span><br><span class="line">        mergeSort(arr, temp, left, mid);</span><br><span class="line">        mergeSort(arr, temp, mid + <span class="number">1</span>, right);</span><br><span class="line">        merge(arr, temp, left, mid, right);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">merge</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span>[] temp, <span class="type">int</span> left, <span class="type">int</span> mid, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> left;</span><br><span class="line">        <span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> mid + <span class="number">1</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">k</span> <span class="operator">=</span> left;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (i &lt;= mid &amp;&amp; j &lt;= right) &#123;</span><br><span class="line">            <span class="keyword">if</span> (arr[i] &lt;= arr[j]) &#123;</span><br><span class="line">                temp[k++] = arr[i++];</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                temp[k++] = arr[j++];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (i &lt;= mid) &#123;</span><br><span class="line">            temp[k++] = arr[i++];</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (j &lt;= right) &#123;</span><br><span class="line">            temp[k++] = arr[j++];</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">m</span> <span class="operator">=</span> left; m &lt;= right; m++) &#123;</span><br><span class="line">            arr[m] = temp[m];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="希尔排序"><a class="markdownIt-Anchor" href="#希尔排序"></a> 希尔排序</h2><p>基于插入排序的排序算法，它通过将原始数组分割成多个较小的子数组来改进插入排序的性能</p><p>希尔排序的核心思想是通过比较和交换相距一定间隔的元素来实现部分排序，逐步减小间隔直至为1，最后进行一次完整的插入排序</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        shellSort(arr);</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorted array: &quot;</span> + Arrays.toString(arr));</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> <span class="keyword">void</span> <span class="title function_">shellSort</span><span class="params">(<span class="type">int</span>[] arr)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr == <span class="literal">null</span> || arr.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> arr.length;</span><br><span class="line">        <span class="type">int</span> <span class="variable">gap</span> <span class="operator">=</span> n / <span class="number">2</span>; <span class="comment">// 初始间隔</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">while</span> (gap &gt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> gap; i &lt; n; i++) &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> arr[i];</span><br><span class="line">                <span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> i;</span><br><span class="line"></span><br><span class="line">                <span class="keyword">while</span> (j &gt;= gap &amp;&amp; arr[j - gap] &gt; temp) &#123;</span><br><span class="line">                    arr[j] = arr[j - gap];</span><br><span class="line">                    j -= gap;</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">                arr[j] = temp;</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">            gap = gap / <span class="number">2</span>; <span class="comment">// 缩小间隔</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>在方法中，我们首先检查数组的长度是否小于等于1，如果是，则直接返回，无需排序。</p><p>然后，我们定义了变量 <code>n</code> 来表示数组的长度，并初始化变量 <code>gap</code> 为 <code>n / 2</code>，即初始间隔。接下来，我们进入一个循环，当间隔 <code>gap</code> 大于0时，执行循环体内的操作。</p><p>在循环体内，我们使用插入排序的思想对每个间隔进行排序。我们从 <code>gap</code> 开始，依次遍历数组中的元素。对于当前位置 <code>i</code>，我们将其与其对应间隔位置 <code>i - gap</code> 的元素进行比较。如果间隔位置的元素较大，则将其后移 <code>gap</code> 个位置，并继续向前比较，直到找到合适的位置插入当前元素。</p><p>最后，我们将当前元素插入到合适的位置，并重复上述过程直到遍历完整个��组。</p><p>随着循环的进行，间隔 <code>gap</code> 逐步减小，直到为1，此时进行最后一次完整的插入排序。排序完成后，数组中的元素就按照从小到大的顺序排列。</p><p>希尔排序的优点是相对于插入排序来说，它可以更快地对部分有序的数组进行排序，但其实现相对复杂一些。</p><h2 id="快速排序"><a class="markdownIt-Anchor" href="#快速排序"></a> 快速排序</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        quickSort(arr, <span class="number">0</span>, arr.length - <span class="number">1</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorted array: &quot;</span> + Arrays.toString(arr));</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> <span class="keyword">void</span> <span class="title function_">quickSort</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> low, <span class="type">int</span> high)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr == <span class="literal">null</span> || arr.length &lt;= <span class="number">1</span> || low &gt;= high) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 分区操作，返回基准元素的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">pivotIndex</span> <span class="operator">=</span> partition(arr, low, high);</span><br><span class="line">        <span class="comment">// 对左半部分进行递归排序</span></span><br><span class="line">        quickSort(arr, low, pivotIndex - <span class="number">1</span>);</span><br><span class="line">        <span class="comment">// 对右半部分进行递归排序</span></span><br><span class="line">        quickSort(arr, pivotIndex + <span class="number">1</span>, high);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">partition</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> low, <span class="type">int</span> high)</span> &#123;</span><br><span class="line">        <span class="comment">// 选择第一个元素作为基准元素</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">pivot</span> <span class="operator">=</span> arr[low];</span><br><span class="line">        <span class="comment">// 初始化左右指针</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> low;</span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> high;</span><br><span class="line">        <span class="keyword">while</span> (left &lt; right) &#123;</span><br><span class="line">            <span class="comment">// 从右边开始，找到第一个小于基准元素的元素</span></span><br><span class="line">            <span class="keyword">while</span> (left &lt; right &amp;&amp; arr[right] &gt;= pivot) &#123;</span><br><span class="line">                right--;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 从左边开始，找到第一个大于基准元素的元素</span></span><br><span class="line">            <span class="keyword">while</span> (left &lt; right &amp;&amp; arr[left] &lt;= pivot) &#123;</span><br><span class="line">                left++;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="comment">// 交换左右指针指向的元素</span></span><br><span class="line">            <span class="keyword">if</span> (left &lt; right) &#123;</span><br><span class="line">                swap(arr, left, right);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 将基准元素放到正确的位置</span></span><br><span class="line">        swap(arr, low, left);</span><br><span class="line">        <span class="comment">// 返回基准元素的索引</span></span><br><span class="line">        <span class="keyword">return</span> left;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> arr[i];</span><br><span class="line">        arr[i] = arr[j];</span><br><span class="line">        arr[j] = temp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>我们首先定义了快速排序的方法 <code>quickSort</code>。在方法中，我们首先检查数组的长度是否小于等于1或者低位索引 <code>low</code> 是否大于等于高位索引 <code>high</code>，如果是，则直接返回，无需排序</p><p>然后，我们调用 <code>partition</code> 方法对当前的子数组进行分区操作，得到基准元素的索引 <code>pivotIndex</code></p><p>接着，我们对基准元素左边的子数组进行递归调用快速排序，即 <code>quickSort(arr, low, pivotIndex - 1)</code>，对左半部分进行排序</p><p>然后，我们对基准元素右边的子数组进行递归调用快速排序，即 <code>quickSort(arr, pivotIndex + 1, high)</code>，对右半部分进行排序</p><p>最后，我们通过交换元素的方式将基准元素放到正确的位置，完成分区操作</p><p>在 <code>partition</code> 方法中，我们选择第一个元素作为基准元素 <code>pivot</code>，然后初始化左指针 <code>left</code> 为 <code>low</code>，右指针 <code>right</code> 为<code>high</code></p><p>接下来，我们使用左右指针的方式进行分区操作。我们从右边开始，找到第一个小于基准元素的元素，然后从左边开始，找到第一个大于基准元素的元素，然后交换这两个元素。重复这个过程，直到左指针大于或等于右指针</p><p>最后，将基准元素放到正确的位置，即将基准元素与左指针指向的元素进行交换</p><p>最后，我们返回基准元素的索引 <code>left</code>，作为分区操作的结果</p><p>快速排序的核心思想是分治法，通过不断地分区操作将数组分解成较小的子数组，然后对子数组进行递归排序。相较于其他排序算法，快速排序的平均时间复杂度为 O(nlogn)，具有较好的性能</p><h2 id="堆排序"><a class="markdownIt-Anchor" href="#堆排序"></a> 堆排序</h2><p>一种基于二叉堆数据结构的排序算法，它利用堆的性质进行排序操作。堆排序分为两个主要步骤：建堆和排序</p><p>基本思路：</p><ol><li><strong>建堆</strong>：将待排序的数组看作是一个完全二叉树，并根据元素的大小构建一个最大堆或最小堆。最大堆的性质是父节点的值大于或等于其子节点的值，最小堆的性质则相反。建堆的过程可以从最后一个非叶子节点开始，依次向上调整堆的结构，使得每个父节点的值都大于或等于（或小于或等于）其子节点的值。</li><li><strong>排序</strong>：将堆顶元素与堆的最后一个元素交换位置，然后将剩余元素重新调整为一个新的堆。重复这个过程，每次将堆中的最大（或最小）元素放到数组的末尾，直到堆中只剩下一个元素为止。</li></ol><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">11</span>, <span class="number">2</span>, <span class="number">33</span>, <span class="number">24</span>, <span class="number">15</span>&#125;;</span><br><span class="line">        heapSort(arr);</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorted array: &quot;</span> + Arrays.toString(arr));</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> <span class="keyword">void</span> <span class="title function_">heapSort</span><span class="params">(<span class="type">int</span>[] arr)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr == <span class="literal">null</span> || arr.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> arr.length;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 建堆，从最后一个非叶子节点开始向下调整堆</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n / <span class="number">2</span> - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            heapify(arr, n, i);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 排序，每次将堆顶元素与堆的最后一个元素交换，并重新调整堆</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            swap(arr, <span class="number">0</span>, i); <span class="comment">// 将堆顶元素与当前最后一个元素交换</span></span><br><span class="line">            heapify(arr, i, <span class="number">0</span>); <span class="comment">// 重新调整堆</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">heapify</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> n, <span class="type">int</span> i)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">largest</span> <span class="operator">=</span> i; <span class="comment">// 当前节点的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">left</span> <span class="operator">=</span> <span class="number">2</span> * i + <span class="number">1</span>; <span class="comment">// 左子节点的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">right</span> <span class="operator">=</span> <span class="number">2</span> * i + <span class="number">2</span>; <span class="comment">// 右子节点的索引</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 找到左右子节点中较大的节点</span></span><br><span class="line">        <span class="keyword">if</span> (left &lt; n &amp;&amp; arr[left] &gt; arr[largest]) &#123;</span><br><span class="line">            largest = left;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (right &lt; n &amp;&amp; arr[right] &gt; arr[largest]) &#123;</span><br><span class="line">            largest = right;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 如果最大节点不是当前节点，则交换它们，并递归调整交换后的子树</span></span><br><span class="line">        <span class="keyword">if</span> (largest != i) &#123;</span><br><span class="line">            swap(arr, i, largest);</span><br><span class="line">            heapify(arr, n, largest);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">swap</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> i, <span class="type">int</span> j)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> arr[i];</span><br><span class="line">        arr[i] = arr[j];</span><br><span class="line">        arr[j] = temp;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>首先定义了堆排序的方法 <code>heapSort</code>。在方法中，我们首先检查数组的长度是否小于等于1，如果是，则直接返回，无需排序</p><p>然后，我们获取数组的长度 <code>n</code></p><p>接下来，我们利用 <code>heapify</code> 方法从最后一个非叶子节点开始，向下调整堆的结构，使得满足堆的性质</p><p>然后，我们进行排序操作。每次将堆顶元素与堆的最后一个元素交换位置，并将剩余元素重新调整为一个新的堆。重复这个过程，每次交换后的堆规模减小，直到堆中只剩下一个元素，排序完成</p><p>在 <code>heapify</code> 方法中，我们首先将数组中的第 <code>i</code> 个元素作为当前节点 <code>largest</code>，并获取其左子节点 <code>left</code> 和右子节点 <code>right</code> 的索引</p><p>然后，我们比较当前节点与其左右子节点的值，将较大（或较小）的节点的索引赋值给 <code>largest</code></p><p>如果 <code>largest</code> 不等于 <code>i</code>，即当前节点不是最大（或最小）节点，则交换当前节点与 <code>largest</code> 节点的值，并递归调用 <code>heapify</code> 方法调整交换后的子树。</p><p>最后，我们通过 <code>swap</code> 方法实现元素交换的操作</p><p>堆排序的时间复杂度是 O(nlogn)，其中 n 是数组的长度。堆排序具有不稳定性，因为在调整堆的过程中，可能会改变相同元素的相对顺序。然而，堆排序的优点是不需要额外的空间，可以原地排序</p><h2 id="基数排序"><a class="markdownIt-Anchor" href="#基数排序"></a> 基数排序</h2><p>是一种非比较性的排序算法，它根据元素的每个位上的值来进行排序。基数排序适用于待排序元素为非负整数的情况</p><p>基本思路：</p><ol><li><strong>确定排序的位数</strong>：首先确定待排序元素中最大值的位数，假设为 d。这样我们就需要进行 d 轮排序操作</li><li><strong>按位进行排序</strong>：从最低位开始，依次对每一位进行排序。可以使用稳定的排序算法，例如计数排序或桶排序，对每一位进行排序。排序的过程可以从最低位到最高位，也可以从最高位到最低位</li><li><strong>合并结果</strong>：经过 d 轮排序后，最终得到的排序结果就是有序的</li></ol><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">170</span>, <span class="number">45</span>, <span class="number">75</span>, <span class="number">90</span>, <span class="number">802</span>, <span class="number">24</span>, <span class="number">2</span>, <span class="number">66</span>&#125;;</span><br><span class="line">        radixSort(arr);</span><br><span class="line">        System.out.println(<span class="string">&quot;Sorted array: &quot;</span> + Arrays.toString(arr));</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> <span class="keyword">void</span> <span class="title function_">radixSort</span><span class="params">(<span class="type">int</span>[] arr)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (arr == <span class="literal">null</span> || arr.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> getMax(arr); <span class="comment">// 获取数组中的最大值</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 从最低位到最高位进行排序</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">exp</span> <span class="operator">=</span> <span class="number">1</span>; max / exp &gt; <span class="number">0</span>; exp *= <span class="number">10</span>) &#123;</span><br><span class="line">            countingSort(arr, exp);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="type">int</span> <span class="title function_">getMax</span><span class="params">(<span class="type">int</span>[] arr)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> arr[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (arr[i] &gt; max) &#123;</span><br><span class="line">                max = arr[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">countingSort</span><span class="params">(<span class="type">int</span>[] arr, <span class="type">int</span> exp)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">n</span> <span class="operator">=</span> arr.length;</span><br><span class="line">        <span class="type">int</span>[] output = <span class="keyword">new</span> <span class="title class_">int</span>[n]; <span class="comment">// 存储排序结果的临时数组</span></span><br><span class="line">        <span class="type">int</span>[] count = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">10</span>]; <span class="comment">// 计数数组，用于统计每个数字出现的次数</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 统计每个数字出现的次数</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            count[(arr[i] / exp) % <span class="number">10</span>]++;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 对计数数组进行累加，得到每个数字的正确位置</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; <span class="number">10</span>; i++) &#123;</span><br><span class="line">            count[i] += count[i - <span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 从后往前遍历原数组，根据计数数组将元素放到正确的位置</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> n - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">            output[count[(arr[i] / exp) % <span class="number">10</span>] - <span class="number">1</span>] = arr[i];</span><br><span class="line">            count[(arr[i] / exp) % <span class="number">10</span>]--;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 将排序结果复制回原数组</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            arr[i] = output[i];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>首先定义了基数排序的方法 <code>radixSort</code>。在方法中，我们首先获取待排序数组中的最大值 <code>max</code>，以确定需要进行多少轮排序</p><p>然后，我们使用 <code>countingSort</code> 方法对每一位进行排序。<code>countingSort</code> 方法使用计数排序的思想，先创建一个临时数组 <code>output</code> 来存储排序结果，再创建一个计数数组 <code>count</code> 来统计每个数字出现的次数</p><p>在 <code>countingSort</code> 方法中，我们首先遍历原数组，统计每个数字出现的次数，并存储在 <code>count</code> 数组中</p><p>然后，我们对计数数组进行累加操作，得到每个数字的正确位置</p><p>接下来，我们从后往前遍历原数组，根据计数数组将每个元素放到正确的位置上</p><p>最后，我们将排序结果复制回原数组</p><p>在 <code>radixSort</code> 方法中，我们使用循环来进行多轮排序，每次将排序的位数乘以 10（即 exp *= 10）</p><p>基数排序的时间复杂度是 O(d * (n + k))，其中 d 是最大值的位数，n 是数组的长度，k 是基数的大小（这里是 10）。基数排序的空间复杂度是 O(n+k)，其中 n 是数组的长度，k 是基数的大小。基数排序是一种稳定的排序算法</p><p>需要注意的是，基数排序适用于待排序元素为非负整数的情况。对于其他类型的数据，可以通过映射为非负整数来进行基数排序</p>]]></content>
    
    
    <summary type="html">古人学问无遗力，少壮工夫老始成</summary>
    
    
    
    <category term="编程基础" scheme="https://luckynwa.top/categories/%E7%BC%96%E7%A8%8B%E5%9F%BA%E7%A1%80/"/>
    
    
    <category term="Algorithm" scheme="https://luckynwa.top/tags/Algorithm/"/>
    
  </entry>
  
  <entry>
    <title>Java后端参数接收方式汇总</title>
    <link href="https://luckynwa.top/posts/java4/"/>
    <id>https://luckynwa.top/posts/java4/</id>
    <published>2023-08-21T22:50:40.000Z</published>
    <updated>2026-07-07T16:19:34.207Z</updated>
    
    <content type="html"><![CDATA[<h1 id="前言"><a class="markdownIt-Anchor" href="#前言"></a> 前言</h1><p>在后端开发中，正确接收和解析前端传来的参数是基础且关键的环节。本文将详细介绍 Spring MVC 中常见的参数接收方式，帮助开发者根据实际场景选择最合适的方案。</p><h1 id="基础概念"><a class="markdownIt-Anchor" href="#基础概念"></a> 基础概念</h1><p><strong>请求数据格式</strong></p><ul><li><p>对于 GET 方法，会将数据转换为 query string。例如 <code>&#123; name: 'name', age: 18 &#125;</code> 转换后的结果是 <code>name=name&amp;age=18</code>。</p></li><li><p>对于 POST 方法且 <code>header['content-type']</code> 为 <code>application/json</code> 的数据，会进行 JSON 序列化。</p></li><li><p>对于 POST 方法且 <code>header['content-type']</code> 为 <code>application/x-www-form-urlencoded</code> 的数据，会将数据转换为 query string。</p></li></ul><p><strong>前端传递注意事项</strong></p><p>如果前端是 POST 请求，后端直接指定请求字段，那么前端发送的需要 qs 包装一下：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">this</span>.<span class="property">$qs</span>.<span class="title function_">stringify</span>(&#123; <span class="attr">acc</span>: <span class="variable language_">this</span>.<span class="property">form</span>.<span class="property">acc</span>, <span class="attr">pwd</span>: <span class="variable language_">this</span>.<span class="property">form</span>.<span class="property">pwd</span> &#125;)</span><br></pre></td></tr></table></figure><h1 id="方法一简单参数传参"><a class="markdownIt-Anchor" href="#方法一简单参数传参"></a> 方法一：简单参数传参</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/method01&quot;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method01</span><span class="params">(String name, Integer age, Double mon)</span> &#123;</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><br><span class="line">    user.setName(name);</span><br><span class="line">    user.setAge(age);</span><br><span class="line">    user.setMoney(mon);</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这种方式接收的是 <code>method01?name=zhangsan&amp;age=15&amp;mon=20.0</code> 格式的传参，并且要求参数名与 URL 地址中携带的参数名完全一致。</p><p>这种形式传参与请求方式无关，GET、POST、PUT 等皆可使用。</p><h1 id="方法二requestparam-注解"><a class="markdownIt-Anchor" href="#方法二requestparam-注解"></a> 方法二：@RequestParam 注解</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(value = &quot;/method02&quot;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method02</span><span class="params">(<span class="meta">@RequestParam(&quot;name&quot;)</span> String name,</span></span><br><span class="line"><span class="params">                       <span class="meta">@RequestParam(&quot;age&quot;)</span> Integer age,</span></span><br><span class="line"><span class="params">                       <span class="meta">@RequestParam(value = &quot;money&quot;, required = false)</span> Double mon)</span> &#123;</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><br><span class="line">    user.setName(name);</span><br><span class="line">    user.setAge(age);</span><br><span class="line">    user.setMoney(mon);</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>方式原理上与第一种一致，都是接收请求 URL 地址中的参数，所以与请求方式无关。</p><p>这种方式注解中的 value 值会去映射请求 URL 中的同名参数取参然后赋值给加注解的形参，所以注解中的参数名必须与 URL 中一致，而方法形参名可以根据自身需求灵活变更。</p><p><strong>注意事项</strong></p><ul><li>加此注解的 <code>required</code> 属性默认为 <code>true</code>，也就是接收请求时会根据 value 去 URL 寻找同名参数，如果没找到会报错。</li><li>所以如果有某一参数可能不传的情况，需要将 <code>required</code> 属性设为 <code>false</code>。</li></ul><h1 id="方法三requestbody-json-接收"><a class="markdownIt-Anchor" href="#方法三requestbody-json-接收"></a> 方法三：@RequestBody JSON 接收</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(value = &quot;/method03&quot;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method03</span><span class="params">(<span class="meta">@RequestBody</span> User user)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>@RequestBody</code> 则是接收请求体中的 JSON 字符串参数直接映射实体对象，所以 body 类型必须是 JSON 字符串。</p><p><strong>注意事项</strong></p><ul><li>实体类中的属性名称必须与 JSON 串中的参数 key 名称完全一致，不同名参数无法正确接收。</li><li>通常 GET 请求通过 URL 携带参数可以根据 URL 作为 key 缓存资源，常用的静态资源服务器都是这种原理，如果参数在 body 中这种方式就失效了。</li><li>适用于 POST 请求携带 body 参数。</li></ul><h1 id="方法四实体类直接接收"><a class="markdownIt-Anchor" href="#方法四实体类直接接收"></a> 方法四：实体类直接接收</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(value = &quot;/method04&quot;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method04</span><span class="params">(User user)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这种方式要求请求中的参数名与实体中的属性名一致即可自动映射到实体属性中。</p><p><strong>支持的传参方式</strong></p><ul><li>支持 URL 拼接的多个 params 传参</li><li>支持 POST 请求的 form 类型传参（form-data、x-www-form-urlencoded）</li><li>不支持 JSON 传参</li></ul><h1 id="方法五httpservletrequest-获取"><a class="markdownIt-Anchor" href="#方法五httpservletrequest-获取"></a> 方法五：HttpServletRequest 获取</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(&quot;/method05&quot;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method05</span><span class="params">(HttpServletRequest request)</span> &#123;</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><br><span class="line">    user.setName(request.getParameter(<span class="string">&quot;name&quot;</span>));</span><br><span class="line">    user.setAge(Integer.valueOf(request.getParameter(<span class="string">&quot;age&quot;</span>)));</span><br><span class="line">    user.setMoney(Double.parseDouble(request.getParameter(<span class="string">&quot;money&quot;</span>)));</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>传统的接收参数方式，可以接收 URL params 传参，支持 POST form 类型传参，不支持 JSON 传参。</p><p><strong>注意事项</strong></p><ul><li>如果请求中未传递指定名称的参数，取参时会报错，需要做好空值处理。</li></ul><h1 id="方法六pathvariable-restful-风格"><a class="markdownIt-Anchor" href="#方法六pathvariable-restful-风格"></a> 方法六：@PathVariable RESTful 风格</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RequestMapping(value = &#123;&quot;/method06/&#123;name&#125;/&#123;age&#125;/&#123;money&#125;&quot;, &quot;/method06/&#123;name&#125;/&#123;money&#125;&quot;&#125;)</span></span><br><span class="line"><span class="keyword">public</span> String <span class="title function_">method06</span><span class="params">(<span class="meta">@PathVariable(&quot;name&quot;)</span> String name,</span></span><br><span class="line"><span class="params">                       <span class="meta">@PathVariable(value = &quot;age&quot;, required = false)</span> Integer age,</span></span><br><span class="line"><span class="params">                       <span class="meta">@PathVariable(&quot;money&quot;)</span> Double money)</span> &#123;</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><br><span class="line">    user.setName(name);</span><br><span class="line">    user.setMoney(money);</span><br><span class="line">    user.setAge(age);</span><br><span class="line">    <span class="keyword">return</span> JSON.toJSONString(user);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>通过 <code>@PathVariable</code> 实现 RESTful 风格传参，直接将参数拼接到 URL 地址中，支持 GET、POST、PUT、DELETE 等多种请求。</p><p><strong>注意事项</strong></p><ul><li><code>required</code> 属性默认为 <code>true</code>，不传递参数会报错。</li><li>如果出现某个参数未传递的情况，可以通过设置 <code>required</code> 属性为 <code>false</code> 并设置多个 value 字符串的形式实现。</li></ul><h1 id="方法七map-接收查询参数"><a class="markdownIt-Anchor" href="#方法七map-接收查询参数"></a> 方法七：Map 接收查询参数</h1><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">@GetMapping(&quot;/list&quot;)</span></span><br><span class="line"><span class="meta">@RequiresPermissions(&quot;sys:config:list&quot;)</span></span><br><span class="line"><span class="keyword">public</span> R <span class="title function_">list</span><span class="params">(<span class="meta">@RequestParam</span> Map&lt;String, Object&gt; params)</span> &#123;</span><br><span class="line">    <span class="type">PageUtils</span> <span class="variable">page</span> <span class="operator">=</span> sysConfigService.queryPage(params);</span><br><span class="line">    <span class="keyword">return</span> R.ok().put(<span class="string">&quot;page&quot;</span>, page);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>适用于接收不确定数量的查询参数，常用于分页查询等场景。通过 <code>@RequestParam Map</code> 可以灵活获取所有传递的参数。</p><h1 id="方法八路径参数与权限校验"><a class="markdownIt-Anchor" href="#方法八路径参数与权限校验"></a> 方法八：路径参数与权限校验</h1><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">@GetMapping(&quot;/info/&#123;id&#125;&quot;)</span></span><br><span class="line"><span class="meta">@RequiresPermissions(&quot;sys:config:info&quot;)</span></span><br><span class="line"><span class="keyword">public</span> R <span class="title function_">info</span><span class="params">(<span class="meta">@PathVariable(&quot;id&quot;)</span> Long id)</span> &#123;</span><br><span class="line">    <span class="type">SysConfigEntity</span> <span class="variable">config</span> <span class="operator">=</span> sysConfigService.getById(id);</span><br><span class="line">    <span class="keyword">return</span> R.ok().put(<span class="string">&quot;config&quot;</span>, config);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结合 <code>@PathVariable</code> 获取路径参数，并使用 <code>@RequiresPermissions</code> 进行权限校验，是实际项目中常见的写法。</p><h1 id="方法九json-实体接收与参数校验"><a class="markdownIt-Anchor" href="#方法九json-实体接收与参数校验"></a> 方法九：JSON 实体接收与参数校验</h1><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@SysLog(&quot;保存配置&quot;)</span></span><br><span class="line"><span class="meta">@PostMapping(&quot;/save&quot;)</span></span><br><span class="line"><span class="meta">@RequiresPermissions(&quot;sys:config:save&quot;)</span></span><br><span class="line"><span class="keyword">public</span> R <span class="title function_">save</span><span class="params">(<span class="meta">@RequestBody</span> SysConfigEntity config)</span> &#123;</span><br><span class="line">    ValidatorUtils.validateEntity(config);</span><br><span class="line">    sysConfigService.saveConfig(config);</span><br><span class="line">    <span class="keyword">return</span> R.ok();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>使用 <code>@RequestBody</code> 接收 JSON 实体，配合参数校验工具和日志注解，是保存数据的标准写法。</p><h1 id="方法十jsonobject-灵活接收"><a class="markdownIt-Anchor" href="#方法十jsonobject-灵活接收"></a> 方法十：JSONObject 灵活接收</h1><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></pre></td><td class="code"><pre><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.alibaba.fastjson2<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>fastjson2<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.0.7<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></pre></td></tr></table></figure><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">@PostMapping(&quot;/login&quot;)</span></span><br><span class="line"><span class="keyword">public</span> ResultVO <span class="title function_">loginHome</span><span class="params">(<span class="meta">@RequestBody</span> JSONObject obj)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">userAcc</span> <span class="operator">=</span> obj.getString(<span class="string">&quot;userAcc&quot;</span>);</span><br><span class="line">    <span class="type">String</span> <span class="variable">userPwd</span> <span class="operator">=</span> obj.getString(<span class="string">&quot;userPwd&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> indexService.login(userAcc, userPwd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>当请求参数结构不固定或需要动态获取字段时，可以使用 <code>JSONObject</code> 接收，然后通过 <code>getString</code>、<code>getList</code> 等方法灵活取值。</p><h1 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h1><p>Spring MVC 提供了丰富的参数接收方式，开发者应根据实际场景选择合适的方法：</p><ul><li>简单键值对传参优先使用 <code>@RequestParam</code></li><li>JSON 数据接收使用 <code>@RequestBody</code></li><li>RESTful 风格使用 <code>@PathVariable</code></li><li>灵活场景可使用 <code>Map</code> 或 <code>JSONObject</code></li></ul><p>掌握这些方法能够帮助开发者更加高效地处理前后端数据交互，提升代码的可读性和可维护性。</p>]]></content>
    
    
    <summary type="html">业精于勤，荒于嬉；行成于思，毁于随</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Maven依赖和工具类</title>
    <link href="https://luckynwa.top/posts/tool8/"/>
    <id>https://luckynwa.top/posts/tool8/</id>
    <published>2023-08-18T19:34:54.000Z</published>
    <updated>2026-07-07T16:19:34.222Z</updated>
    
    <content type="html"><![CDATA[<h1 id="maven-依赖汇总"><a class="markdownIt-Anchor" href="#maven-依赖汇总"></a> Maven 依赖汇总</h1><h2 id="lombok"><a class="markdownIt-Anchor" href="#lombok"></a> Lombok</h2><p>用处：一个注解完成大量的 get、set 操作，推荐用 properties 标签管理版本</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></pre></td><td class="code"><pre><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">lombok.version</span>&gt;</span>1.18.4<span class="tag">&lt;/<span class="name">lombok.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><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">version</span>&gt;</span>$&#123;lombok.version&#125;<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></pre></td></tr></table></figure><h2 id="单元测试"><a class="markdownIt-Anchor" href="#单元测试"></a> 单元测试</h2><p>springboot 中直接引入 starter-test 即可</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><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">&lt;!-- 包含junit4.12，没有它无法调用springboot上下文对象 --&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><br><span class="line"><span class="comment">&lt;!-- 仅调用junit，不涉及项目模块 --&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>junit<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<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>4.12<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><h2 id="fastjson2"><a class="markdownIt-Anchor" href="#fastjson2"></a> Fastjson2</h2><p>推荐使用 2 版本</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></pre></td><td class="code"><pre><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.alibaba.fastjson2<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>fastjson2<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.0.7<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></pre></td></tr></table></figure><h2 id="pagehelper-分页"><a class="markdownIt-Anchor" href="#pagehelper-分页"></a> PageHelper 分页</h2><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></pre></td><td class="code"><pre><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.github.pagehelper<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>pagehelper-spring-boot-starter<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>1.4.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></pre></td></tr></table></figure><h2 id="jwt-token"><a class="markdownIt-Anchor" href="#jwt-token"></a> JWT Token</h2><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></pre></td><td class="code"><pre><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.auth0<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>java-jwt<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.10.3<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><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>io.jsonwebtoken<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>jjwt<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.9.1<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></pre></td></tr></table></figure><h2 id="md5-加密"><a class="markdownIt-Anchor" href="#md5-加密"></a> MD5 加密</h2><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></pre></td><td class="code"><pre><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>commons-codec<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-codec<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></pre></td></tr></table></figure><h2 id="mybatis-代码生成器"><a class="markdownIt-Anchor" href="#mybatis-代码生成器"></a> MyBatis 代码生成器</h2><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></pre></td><td class="code"><pre><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.baomidou<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>mybatis-plus-generator<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.5.1<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><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.freemarker<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>freemarker<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.3.30<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><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.baomidou<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>mybatis-plus<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.4.3.4<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></pre></td></tr></table></figure><h2 id="aop-日志"><a class="markdownIt-Anchor" href="#aop-日志"></a> AOP 日志</h2><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></pre></td><td class="code"><pre><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-aop<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></pre></td></tr></table></figure><h2 id="swagger2"><a class="markdownIt-Anchor" href="#swagger2"></a> Swagger2</h2><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></pre></td><td class="code"><pre><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>io.springfox<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>springfox-swagger2<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.9.2<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><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>io.springfox<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>springfox-swagger-ui<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.9.2<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><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.github.xiaoymin<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>swagger-bootstrap-ui<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>1.9.6<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></pre></td></tr></table></figure><h2 id="knife4j"><a class="markdownIt-Anchor" href="#knife4j"></a> Knife4j</h2><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></pre></td><td class="code"><pre><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.github.xiaoymin<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>knife4j-spring-boot-starter<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.0.9<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></pre></td></tr></table></figure><hr /><h1 id="工具类代码"><a class="markdownIt-Anchor" href="#工具类代码"></a> 工具类代码</h1><h2 id="jwtutils-token-工具"><a class="markdownIt-Anchor" href="#jwtutils-token-工具"></a> JWTUtils - Token 工具</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.auth0.jwt.JWT;</span><br><span class="line"><span class="keyword">import</span> com.auth0.jwt.algorithms.Algorithm;</span><br><span class="line"><span class="keyword">import</span> com.auth0.jwt.interfaces.DecodedJWT;</span><br><span class="line"><span class="keyword">import</span> com.auth0.jwt.interfaces.JWTVerifier;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">JWTUtils</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">EXPIRE_DATE</span> <span class="operator">=</span> <span class="number">30</span> * <span class="number">610</span> * <span class="number">100000</span>;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">String</span> <span class="variable">TOKEN_SECRET</span> <span class="operator">=</span> <span class="string">&quot;LuckyNWA666&quot;</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 生成 Token</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">token</span><span class="params">(String username, String password)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Date</span> <span class="variable">date</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Date</span>(System.currentTimeMillis() + EXPIRE_DATE);</span><br><span class="line">            <span class="type">Algorithm</span> <span class="variable">algorithm</span> <span class="operator">=</span> Algorithm.HMAC256(TOKEN_SECRET);</span><br><span class="line">            Map&lt;String, Object&gt; header = <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">            header.put(<span class="string">&quot;typ&quot;</span>, <span class="string">&quot;JWT&quot;</span>);</span><br><span class="line">            header.put(<span class="string">&quot;alg&quot;</span>, <span class="string">&quot;HS256&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span> JWT.create()</span><br><span class="line">                    .withHeader(header)</span><br><span class="line">                    .withClaim(<span class="string">&quot;username&quot;</span>, username)</span><br><span class="line">                    .withClaim(<span class="string">&quot;password&quot;</span>, password)</span><br><span class="line">                    .withExpiresAt(date)</span><br><span class="line">                    .sign(algorithm);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 验证 Token</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">boolean</span> <span class="title function_">verify</span><span class="params">(String token)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">Algorithm</span> <span class="variable">algorithm</span> <span class="operator">=</span> Algorithm.HMAC256(TOKEN_SECRET);</span><br><span class="line">            <span class="type">JWTVerifier</span> <span class="variable">verifier</span> <span class="operator">=</span> JWT.require(algorithm).build();</span><br><span class="line">            verifier.verify(token);</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="md5utils-加密工具"><a class="markdownIt-Anchor" href="#md5utils-加密工具"></a> MD5Utils - 加密工具</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.math.BigInteger;</span><br><span class="line"><span class="keyword">import</span> java.security.MessageDigest;</span><br><span class="line"><span class="keyword">import</span> java.security.NoSuchAlgorithmException;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MD5Utils</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> String <span class="title function_">md5</span><span class="params">(String pwd)</span> &#123;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">MessageDigest</span> <span class="variable">md5</span> <span class="operator">=</span> MessageDigest.getInstance(<span class="string">&quot;MD5&quot;</span>);</span><br><span class="line">            md5.update(pwd.getBytes());</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">BigInteger</span>(<span class="number">1</span>, md5.digest()).toString(<span class="number">16</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (NoSuchAlgorithmException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="codegenerator-代码生成器"><a class="markdownIt-Anchor" href="#codegenerator-代码生成器"></a> CodeGenerator - 代码生成器</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.baomidou.mybatisplus.generator.FastAutoGenerator;</span><br><span class="line"><span class="keyword">import</span> com.baomidou.mybatisplus.generator.config.OutputFile;</span><br><span class="line"><span class="keyword">import</span> com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.Collections;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CodeGenerator</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        FastAutoGenerator.create(<span class="string">&quot;jdbc:mysql://127.0.0.1:3306/weeklydb?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false&amp;serverTimezone=UTC&quot;</span>, <span class="string">&quot;root&quot;</span>, <span class="string">&quot;123456&quot;</span>)</span><br><span class="line">                .globalConfig(builder -&gt; &#123;</span><br><span class="line">                    builder.author(<span class="string">&quot;luckyNwa&quot;</span>)</span><br><span class="line">                            .enableSwagger()</span><br><span class="line">                            .fileOverride()</span><br><span class="line">                            .outputDir(System.getProperty(<span class="string">&quot;user.dir&quot;</span>) + <span class="string">&quot;/src/main/java&quot;</span>);</span><br><span class="line">                &#125;)</span><br><span class="line">                .packageConfig(builder -&gt; &#123;</span><br><span class="line">                    builder.parent(<span class="string">&quot;com.nwa&quot;</span>)</span><br><span class="line">                            .moduleName(<span class="string">&quot;&quot;</span>)</span><br><span class="line">                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty(<span class="string">&quot;user.dir&quot;</span>) + <span class="string">&quot;/src/main/resources/mapper&quot;</span>));</span><br><span class="line">                &#125;)</span><br><span class="line">                .strategyConfig(builder -&gt; &#123;</span><br><span class="line">                    builder.addInclude(<span class="string">&quot;tb_weeks&quot;</span>)</span><br><span class="line">                            .addTablePrefix(<span class="string">&quot;tb_&quot;</span>, <span class="string">&quot;sys_&quot;</span>);</span><br><span class="line">                &#125;)</span><br><span class="line">                .templateEngine(<span class="keyword">new</span> <span class="title class_">FreemarkerTemplateEngine</span>())</span><br><span class="line">                .execute();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="swaggerconfig-swagger-配置"><a class="markdownIt-Anchor" href="#swaggerconfig-swagger-配置"></a> SwaggerConfig - Swagger 配置</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.builders.RequestHandlerSelectors;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.ApiInfo;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.ApiKey;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.Contact;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.spi.DocumentationType;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.spring.web.plugins.Docket;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.swagger2.annotations.EnableSwagger2;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.ArrayList;</span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableSwagger2</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SwaggerConfig</span> &#123;</span><br><span class="line">    <span class="meta">@Bean</span></span><br><span class="line">    <span class="keyword">public</span> Docket <span class="title function_">docket</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Docket</span>(DocumentationType.SWAGGER_2)</span><br><span class="line">                .apiInfo(apiInfo())</span><br><span class="line">                .select()</span><br><span class="line">                .apis(RequestHandlerSelectors.basePackage(<span class="string">&quot;com.nwa.controller&quot;</span>))</span><br><span class="line">                .build()</span><br><span class="line">                .securitySchemes(security());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> ApiInfo <span class="title function_">apiInfo</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Contact</span> <span class="variable">luckyNWA</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Contact</span>(<span class="string">&quot;luckyNWA&quot;</span>, <span class="string">&quot;www.nwa.com&quot;</span>, <span class="string">&quot;1656213092@qq.com&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ApiInfo</span>(</span><br><span class="line">                <span class="string">&quot;小维的API接口说明&quot;</span>,</span><br><span class="line">                <span class="string">&quot;此文档详细说明了小维前后端项目端口规范&quot;</span>,</span><br><span class="line">                <span class="string">&quot;v1.0&quot;</span>,</span><br><span class="line">                <span class="string">&quot;www.nwa.com&quot;</span>,</span><br><span class="line">                luckyNWA,</span><br><span class="line">                <span class="string">&quot;apache 2.0&quot;</span>,</span><br><span class="line">                <span class="string">&quot;www.nwa.com&quot;</span>,</span><br><span class="line">                <span class="keyword">new</span> <span class="title class_">ArrayList</span>()</span><br><span class="line">        );</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;ApiKey&gt; <span class="title function_">security</span><span class="params">()</span> &#123;</span><br><span class="line">        ArrayList&lt;ApiKey&gt; list = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        list.add(<span class="keyword">new</span> <span class="title class_">ApiKey</span>(<span class="string">&quot;token&quot;</span>, <span class="string">&quot;token&quot;</span>, <span class="string">&quot;header&quot;</span>));</span><br><span class="line">        <span class="keyword">return</span> list;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="knife4jconfiguration-knife4j-配置"><a class="markdownIt-Anchor" href="#knife4jconfiguration-knife4j-配置"></a> Knife4jConfiguration - Knife4j 配置</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.config;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;</span><br><span class="line"><span class="keyword">import</span> io.swagger.annotations.ApiOperation;</span><br><span class="line"><span class="keyword">import</span> lombok.AllArgsConstructor;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.builders.ApiInfoBuilder;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.builders.PathSelectors;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.builders.RequestHandlerSelectors;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.ApiInfo;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.ApiKey;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.service.Contact;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.spi.DocumentationType;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.spring.web.plugins.Docket;</span><br><span class="line"><span class="keyword">import</span> springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="keyword">static</span> com.github.xiaoymin.knife4j.core.util.CollectionUtils.newArrayList;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="meta">@EnableSwagger2WebMvc</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Knife4jConfiguration</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> OpenApiExtensionResolver openApiExtensionResolver;</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> Docket <span class="title function_">createRestApi</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Docket</span>(DocumentationType.SWAGGER_2)</span><br><span class="line">                .apiInfo(apiInfo())</span><br><span class="line">                .select()</span><br><span class="line">                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))</span><br><span class="line">                .paths(PathSelectors.any())</span><br><span class="line">                .build()</span><br><span class="line">                .extensions(openApiExtensionResolver.buildSettingExtensions())</span><br><span class="line">                .securitySchemes(security());</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> List&lt;ApiKey&gt; <span class="title function_">security</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> newArrayList(<span class="keyword">new</span> <span class="title class_">ApiKey</span>(<span class="string">&quot;Token&quot;</span>, <span class="string">&quot;token&quot;</span>, <span class="string">&quot;header&quot;</span>));</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> ApiInfo <span class="title function_">apiInfo</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">Contact</span> <span class="variable">luckyNWA</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Contact</span>(<span class="string">&quot;luckyNWA&quot;</span>, <span class="string">&quot;http://luckynwa.top&quot;</span>, <span class="string">&quot;1656213092@qq.com&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ApiInfoBuilder</span>()</span><br><span class="line">                .title(<span class="string">&quot;小维的API接口说明&quot;</span>)</span><br><span class="line">                .description(<span class="string">&quot;多个应用系统之间的身份验证和访问控制的接口&quot;</span>)</span><br><span class="line">                .termsOfServiceUrl(<span class="string">&quot;http://luckynwa.top&quot;</span>)</span><br><span class="line">                .version(<span class="string">&quot;1.0&quot;</span>)</span><br><span class="line">                .contact(luckyNWA)</span><br><span class="line">                .license(<span class="string">&quot;apache 2.0&quot;</span>)</span><br><span class="line">                .build();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="checktokeninterceptor-token-拦截器"><a class="markdownIt-Anchor" href="#checktokeninterceptor-token-拦截器"></a> CheckTokenInterceptor - Token 拦截器</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.fasterxml.jackson.databind.ObjectMapper;</span><br><span class="line"><span class="keyword">import</span> com.nwa.bean.ResultVO;</span><br><span class="line"><span class="keyword">import</span> io.jsonwebtoken.*;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.HandlerInterceptor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.io.PrintWriter;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">CheckTokenInterceptor</span> <span class="keyword">implements</span> <span class="title class_">HandlerInterceptor</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">preHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">method</span> <span class="operator">=</span> request.getMethod();</span><br><span class="line">        <span class="keyword">if</span> (<span class="string">&quot;OPTIONS&quot;</span>.equalsIgnoreCase(method)) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">String</span> <span class="variable">token</span> <span class="operator">=</span> request.getHeader(<span class="string">&quot;token&quot;</span>);</span><br><span class="line">        <span class="keyword">if</span> (token == <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="type">ResultVO</span> <span class="variable">resultVO</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ResultVO</span>(ResStatus.FAIL, <span class="string">&quot;请先登录&quot;</span>, <span class="literal">null</span>);</span><br><span class="line">            doResponse(response, resultVO);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> JWTUtils.verify(token);</span><br><span class="line">            &#125; <span class="keyword">catch</span> (ExpiredJwtException e) &#123;</span><br><span class="line">                doResponse(response, <span class="keyword">new</span> <span class="title class_">ResultVO</span>(ResStatus.FAIL, <span class="string">&quot;登录过期&quot;</span>, <span class="literal">null</span>));</span><br><span class="line">            &#125; <span class="keyword">catch</span> (UnsupportedJwtException e) &#123;</span><br><span class="line">                doResponse(response, <span class="keyword">new</span> <span class="title class_">ResultVO</span>(ResStatus.FAIL, <span class="string">&quot;token不合法&quot;</span>, <span class="literal">null</span>));</span><br><span class="line">            &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">                doResponse(response, <span class="keyword">new</span> <span class="title class_">ResultVO</span>(ResStatus.FAIL, <span class="string">&quot;请先登录&quot;</span>, <span class="literal">null</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">doResponse</span><span class="params">(HttpServletResponse response, ResultVO resultVO)</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        response.setContentType(<span class="string">&quot;application/json&quot;</span>);</span><br><span class="line">        response.setCharacterEncoding(<span class="string">&quot;utf-8&quot;</span>);</span><br><span class="line">        <span class="type">PrintWriter</span> <span class="variable">out</span> <span class="operator">=</span> response.getWriter();</span><br><span class="line">        out.println(<span class="keyword">new</span> <span class="title class_">ObjectMapper</span>().writeValueAsString(resultVO));</span><br><span class="line">        out.flush();</span><br><span class="line">        out.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="syslog-自定义日志注解"><a class="markdownIt-Anchor" href="#syslog-自定义日志注解"></a> SysLog - 自定义日志注解</h2><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">package</span> com.nwa.aop;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.lang.annotation.*;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Target(ElementType.METHOD)</span></span><br><span class="line"><span class="meta">@Retention(RetentionPolicy.RUNTIME)</span></span><br><span class="line"><span class="meta">@Documented</span></span><br><span class="line"><span class="keyword">public</span> <span class="meta">@interface</span> SysLog &#123;</span><br><span class="line">    String <span class="title function_">operationType</span><span class="params">()</span> <span class="keyword">default</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    String <span class="title function_">operationName</span><span class="params">()</span> <span class="keyword">default</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">    String <span class="title function_">value</span><span class="params">()</span> <span class="keyword">default</span> <span class="string">&quot;&quot;</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="sysloga-aop-日志切面"><a class="markdownIt-Anchor" href="#sysloga-aop-日志切面"></a> SysLogA - AOP 日志切面</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.aop;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.nwa.bean.Client;</span><br><span class="line"><span class="keyword">import</span> com.nwa.service.impl.SysLogService;</span><br><span class="line"><span class="keyword">import</span> com.nwa.until.ClientInfoUtil;</span><br><span class="line"><span class="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.JoinPoint;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.After;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Aspect;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Pointcut;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.reflect.MethodSignature;</span><br><span class="line"><span class="keyword">import</span> org.springframework.stereotype.Component;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.context.request.RequestContextHolder;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.context.request.ServletRequestAttributes;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.annotation.Resource;</span><br><span class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Method;</span><br><span class="line"><span class="keyword">import</span> java.util.Date;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">SysLogA</span> &#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> SysLogService sysLogService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Pointcut(&quot;execution(* com.nwa.controller.IndexController.*(..))&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logPointCut</span><span class="params">()</span> &#123;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@After(&quot;logPointCut()&quot;)</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">logTest</span><span class="params">(JoinPoint joinPoint)</span> <span class="keyword">throws</span> Exception &#123;</span><br><span class="line">        <span class="type">HttpServletRequest</span> <span class="variable">request</span> <span class="operator">=</span> ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();</span><br><span class="line">        <span class="type">String</span> <span class="variable">browser</span> <span class="operator">=</span> ClientInfoUtil.getBrowserInfo(request);</span><br><span class="line">        <span class="type">String</span> <span class="variable">os</span> <span class="operator">=</span> ClientInfoUtil.getOperatingSystem(request);</span><br><span class="line">        <span class="type">String</span> <span class="variable">ip</span> <span class="operator">=</span> ClientInfoUtil.getIP(request);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">MethodSignature</span> <span class="variable">signature</span> <span class="operator">=</span> (MethodSignature) joinPoint.getSignature();</span><br><span class="line">            <span class="type">Method</span> <span class="variable">method</span> <span class="operator">=</span> signature.getMethod();</span><br><span class="line">            <span class="type">SysLog</span> <span class="variable">sysLog</span> <span class="operator">=</span> method.getAnnotation(SysLog.class);</span><br><span class="line"></span><br><span class="line">            <span class="type">Client</span> <span class="variable">client1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Client</span>();</span><br><span class="line">            client1.setCreateBy(sysLog.operationType());</span><br><span class="line">            client1.setRequestIp(ip);</span><br><span class="line">            client1.setLogTip(sysLog.operationName());</span><br><span class="line">            client1.setLogSys(os);</span><br><span class="line">            client1.setLogBrowser(browser);</span><br><span class="line">            client1.setCreateDate(<span class="keyword">new</span> <span class="title class_">Date</span>());</span><br><span class="line">            sysLogService.save(client1);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            log.error(<span class="string">&quot;==后置通知异常==&quot;</span>);</span><br><span class="line">            log.error(<span class="string">&quot;异常信息:&#123;&#125;------&quot;</span> + e.getMessage());</span><br><span class="line">            <span class="keyword">throw</span> e;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><hr /><h1 id="配置参考"><a class="markdownIt-Anchor" href="#配置参考"></a> 配置参考</h1><h2 id="拦截器配置"><a class="markdownIt-Anchor" href="#拦截器配置"></a> 拦截器配置</h2><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa.until;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.config.annotation.InterceptorRegistry;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;</span><br><span class="line"><span class="keyword">import</span> org.springframework.web.servlet.config.annotation.WebMvcConfigurer;</span><br><span class="line"></span><br><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_">InterceptorConfig</span> <span class="keyword">implements</span> <span class="title class_">WebMvcConfigurer</span> &#123;</span><br><span class="line">    <span class="meta">@Autowired</span></span><br><span class="line">    <span class="keyword">private</span> CheckTokenInterceptor checkTokenInterceptor;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addInterceptors</span><span class="params">(InterceptorRegistry registry)</span> &#123;</span><br><span class="line">        registry.addInterceptor(checkTokenInterceptor)</span><br><span class="line">                .addPathPatterns(<span class="string">&quot;/home/**&quot;</span>)</span><br><span class="line">                .excludePathPatterns(<span class="string">&quot;/index/**&quot;</span>, <span class="string">&quot;/home/getLogList&quot;</span>,</span><br><span class="line">                        <span class="string">&quot;/swagger-ui/**&quot;</span>, <span class="string">&quot;/swagger2.html&quot;</span>, <span class="string">&quot;/doc.html&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addResourceHandlers</span><span class="params">(ResourceHandlerRegistry registry)</span> &#123;</span><br><span class="line">        registry.addResourceHandler(<span class="string">&quot;/**&quot;</span>).addResourceLocations(<span class="string">&quot;classpath:/static/&quot;</span>);</span><br><span class="line">        registry.addResourceHandler(<span class="string">&quot;swagger-ui.html&quot;</span>)</span><br><span class="line">                .addResourceLocations(<span class="string">&quot;classpath:/META-INF/resources/&quot;</span>);</span><br><span class="line">        registry.addResourceHandler(<span class="string">&quot;doc.html&quot;</span>)</span><br><span class="line">                .addResourceLocations(<span class="string">&quot;classpath:/META-INF/resources/&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="knife4j-yml-配置"><a class="markdownIt-Anchor" href="#knife4j-yml-配置"></a> Knife4j YML 配置</h2><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">knife4j:</span></span><br><span class="line">  <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">production:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">basic:</span></span><br><span class="line">    <span class="attr">enable:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">username:</span> <span class="string">test</span></span><br><span class="line">    <span class="attr">password:</span> <span class="number">123</span></span><br><span class="line">  <span class="attr">setting:</span></span><br><span class="line">    <span class="attr">enableSearch:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">enableHomeCustom:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">homeCustomLocation:</span> <span class="string">classpath:markdown/home.md</span></span><br></pre></td></tr></table></figure><h2 id="前端-token-配置"><a class="markdownIt-Anchor" href="#前端-token-配置"></a> 前端 Token 配置</h2><figure class="highlight javascript"><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">// 登录后保存 token</span></span><br><span class="line"><span class="variable language_">window</span>.<span class="property">sessionStorage</span>.<span class="title function_">setItem</span>(<span class="string">&#x27;token&#x27;</span>, data.<span class="property">token</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 请求拦截器自动携带</span></span><br><span class="line">request.<span class="property">interceptors</span>.<span class="property">request</span>.<span class="title function_">use</span>(</span><br><span class="line">  <span class="function">(<span class="params">config</span>) =&gt;</span> &#123;</span><br><span class="line">    config.<span class="property">headers</span>.<span class="property">token</span> = <span class="variable language_">window</span>.<span class="property">sessionStorage</span>.<span class="title function_">getItem</span>(<span class="string">&#x27;token&#x27;</span>)</span><br><span class="line">    <span class="keyword">return</span> config</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="function">(<span class="params">error</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="title class_">Promise</span>.<span class="title function_">reject</span>(error)</span><br><span class="line">  &#125;,</span><br><span class="line">)</span><br></pre></td></tr></table></figure><hr /><h1 id="使用示例"><a class="markdownIt-Anchor" href="#使用示例"></a> 使用示例</h1><h2 id="lombok-实体类"><a class="markdownIt-Anchor" href="#lombok-实体类"></a> Lombok 实体类</h2><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> lombok.AllArgsConstructor;</span><br><span class="line"><span class="keyword">import</span> lombok.Data;</span><br><span class="line"><span class="keyword">import</span> lombok.NoArgsConstructor;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Data</span></span><br><span class="line"><span class="meta">@NoArgsConstructor</span></span><br><span class="line"><span class="meta">@AllArgsConstructor</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Client</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> userAcc;</span><br><span class="line">    <span class="keyword">private</span> String userPwd;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="单元测试-2"><a class="markdownIt-Anchor" href="#单元测试-2"></a> 单元测试</h2><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="keyword">import</span> lombok.extern.slf4j.Slf4j;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.springframework.boot.test.context.SpringBootTest;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringRunner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Slf4j</span></span><br><span class="line"><span class="meta">@RunWith(SpringRunner.class)</span></span><br><span class="line"><span class="meta">@SpringBootTest</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">TestWiring</span> &#123;</span><br><span class="line">    <span class="meta">@Resource</span></span><br><span class="line">    <span class="keyword">private</span> DeviceTopoService deviceTopoService;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">DeviceTopoEntity</span> <span class="variable">info</span> <span class="operator">=</span> deviceTopoService.getById(<span class="number">1</span>);</span><br><span class="line">        log.info(String.valueOf(info));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="pagehelper-分页-2"><a class="markdownIt-Anchor" href="#pagehelper-分页-2"></a> PageHelper 分页</h2><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> ResultVO <span class="title function_">getMyWeekList</span><span class="params">(String months, String id, <span class="type">int</span> page, <span class="type">int</span> limit)</span> &#123;</span><br><span class="line">    PageHelper.startPage(page, limit);</span><br><span class="line">    List&lt;Client&gt; clientS = adHomeMapper.getMyWeekList(months, id);</span><br><span class="line">    <span class="keyword">if</span> (clientS != <span class="literal">null</span>) &#123;</span><br><span class="line">        PageInfo&lt;Client&gt; pageInfo = <span class="keyword">new</span> <span class="title class_">PageInfo</span>&lt;&gt;(clientS, <span class="number">3</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> (<span class="type">int</span>) pageInfo.getTotal();</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ResultVO</span>(ResStatus.OK, <span class="string">&quot;列表信息返回成功!&quot;</span>, count, clientS);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> resultVO;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="fastjson2-接收参数"><a class="markdownIt-Anchor" href="#fastjson2-接收参数"></a> Fastjson2 接收参数</h2><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">@PostMapping(&quot;/login&quot;)</span></span><br><span class="line"><span class="keyword">public</span> ResultVO <span class="title function_">loginHome</span><span class="params">(<span class="meta">@RequestBody</span> JSONObject obj)</span> &#123;</span><br><span class="line">    <span class="type">String</span> <span class="variable">userAcc</span> <span class="operator">=</span> obj.getString(<span class="string">&quot;userAcc&quot;</span>);</span><br><span class="line">    <span class="type">String</span> <span class="variable">userPwd</span> <span class="operator">=</span> obj.getString(<span class="string">&quot;userPwd&quot;</span>);</span><br><span class="line">    <span class="keyword">return</span> indexService.login(userAcc, userPwd);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="swagger-注解"><a class="markdownIt-Anchor" href="#swagger-注解"></a> Swagger 注解</h2><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 控制器类</span></span><br><span class="line"><span class="meta">@Api(value = &quot;提供了后台主页面的各种接口&quot;, tags = &quot;后台主页面接口&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 控制器方法</span></span><br><span class="line"><span class="meta">@ApiOperation(&quot;修改密码&quot;)</span></span><br><span class="line"><span class="meta">@ApiImplicitParams(&#123;</span></span><br><span class="line"><span class="meta">    @ApiImplicitParam(dataType = &quot;string&quot;, name = &quot;userAcc&quot;, value = &quot;账号&quot;, required = true),</span></span><br><span class="line"><span class="meta">    @ApiImplicitParam(dataType = &quot;string&quot;, name = &quot;newPassword&quot;, value = &quot;新密码&quot;, required = true),</span></span><br><span class="line"><span class="meta">&#125;)</span></span><br><span class="line"><span class="meta">@PutMapping(&quot;/modifyPwd&quot;)</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 实体类</span></span><br><span class="line"><span class="meta">@ApiModel(value = &quot;周报里面的实体&quot;, description = &quot;封装的周报对象&quot;)</span></span><br><span class="line"><span class="meta">@ApiModelProperty(&quot;用户id&quot;)</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">少壮不努力，老大徒伤悲</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Maven" scheme="https://luckynwa.top/tags/Maven/"/>
    
  </entry>
  
  <entry>
    <title>Maven 环境</title>
    <link href="https://luckynwa.top/posts/tool7/"/>
    <id>https://luckynwa.top/posts/tool7/</id>
    <published>2023-08-11T18:02:07.000Z</published>
    <updated>2026-07-07T16:19:34.052Z</updated>
    
    <content type="html"><![CDATA[<h1 id="安装配置"><a class="markdownIt-Anchor" href="#安装配置"></a> 安装配置</h1><p>直接将解压好的文件复制到 <code>D:\bgsoft</code> 下面（下载镜像源和本地仓库地址都在 <code>conf/settings.xml</code> 里写好了）。</p><p><strong>新建环境变量 <code>MAVEN_HOME</code>：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">D:\bgsoft\apache-maven-3.6.3</span><br></pre></td></tr></table></figure><p><strong>编辑 <code>Path</code>，添加：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%MAVEN_HOME%\bin</span><br></pre></td></tr></table></figure><h1 id="验证"><a class="markdownIt-Anchor" href="#验证"></a> 验证</h1><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mvn -version</span><br></pre></td></tr></table></figure><h1 id="settingsxml-配置"><a class="markdownIt-Anchor" href="#settingsxml-配置"></a> settings.xml 配置</h1><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</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><br><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment">Licensed to the Apache Software Foundation (ASF) under one</span></span><br><span class="line"><span class="comment">or more contributor license agreements.  See the NOTICE file</span></span><br><span class="line"><span class="comment">distributed with this work for additional information</span></span><br><span class="line"><span class="comment">regarding copyright ownership.  The ASF licenses this file</span></span><br><span class="line"><span class="comment">to you under the Apache License, Version 2.0 (the</span></span><br><span class="line"><span class="comment">&quot;License&quot;); you may not use this file except in compliance</span></span><br><span class="line"><span class="comment">with the License.  You may obtain a copy of the License at</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    http://www.apache.org/licenses/LICENSE-2.0</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Unless required by applicable law or agreed to in writing,</span></span><br><span class="line"><span class="comment">software distributed under the License is distributed on an</span></span><br><span class="line"><span class="comment">&quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY</span></span><br><span class="line"><span class="comment">KIND, either express or implied.  See the License for the</span></span><br><span class="line"><span class="comment">specific language governing permissions and limitations</span></span><br><span class="line"><span class="comment">under the License.</span></span><br><span class="line"><span class="comment">--&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!--</span></span><br><span class="line"><span class="comment"> | This is the configuration file for Maven. It can be specified at two levels:</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |  1. User Level. This settings.xml file provides configuration for a single user,</span></span><br><span class="line"><span class="comment"> |                 and is normally provided in $&#123;user.home&#125;/.m2/settings.xml.</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |                 <span class="doctag">NOTE:</span> This location can be overridden with the CLI option:</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |                 -s /path/to/user/settings.xml</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |  2. Global Level. This settings.xml file provides configuration for all Maven</span></span><br><span class="line"><span class="comment"> |                 users on a machine (assuming they&#x27;re all using the same Maven</span></span><br><span class="line"><span class="comment"> |                 installation). It&#x27;s normally provided in</span></span><br><span class="line"><span class="comment"> |                 $&#123;maven.conf&#125;/settings.xml.</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |                 <span class="doctag">NOTE:</span> This location can be overridden with the CLI option:</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |                 -gs /path/to/global/settings.xml</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> | The sections in this sample file are intended to give you a running start at</span></span><br><span class="line"><span class="comment"> | getting the most out of your Maven installation. Where appropriate, the default</span></span><br><span class="line"><span class="comment"> | values (values used when the setting is not specified) are provided.</span></span><br><span class="line"><span class="comment"> |</span></span><br><span class="line"><span class="comment"> |--&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">settings</span> <span class="attr">xmlns</span>=<span class="string">&quot;http://maven.apache.org/SETTINGS/1.0.0&quot;</span></span></span><br><span class="line"><span class="tag">          <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/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;<span class="name">localRepository</span>&gt;</span>D:\bgsoft\apache-maven-3.6.3\repository<span class="tag">&lt;/<span class="name">localRepository</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">pluginGroups</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">pluginGroups</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">proxies</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">proxies</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">servers</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">servers</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;<span class="name">mirrors</span>&gt;</span></span><br><span class="line"></span><br><span class="line">   <span class="tag">&lt;<span class="name">mirror</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">id</span>&gt;</span>alimaven<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">name</span>&gt;</span>aliyun maven<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">url</span>&gt;</span>http://maven.aliyun.com/nexus/content/groups/public/<span class="tag">&lt;/<span class="name">url</span>&gt;</span></span><br><span class="line">      <span class="tag">&lt;<span class="name">mirrorOf</span>&gt;</span>central<span class="tag">&lt;/<span class="name">mirrorOf</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">mirror</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;/<span class="name">mirrors</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">profiles</span>&gt;</span></span><br><span class="line">    <span class="comment">&lt;!-- 在 profiles 标签中 添加 profile 标签内容 明确新建项目 默认 JDK 为 1.8--&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">profile</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">id</span>&gt;</span>JDK8<span class="tag">&lt;/<span class="name">id</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">activation</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">activeByDefault</span>&gt;</span>true<span class="tag">&lt;/<span class="name">activeByDefault</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">jdk</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">jdk</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">activation</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">maven.compiler.source</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">maven.compiler.source</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">maven.compiler.target</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">maven.compiler.target</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">maven.compiler.compilerVersion</span>&gt;</span>1.8<span class="tag">&lt;/<span class="name">maven.compiler.compilerVersion</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">profile</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">profiles</span>&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- 添加的  profile 生效 --&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">activeProfiles</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">activeProfile</span>&gt;</span>JDK8<span class="tag">&lt;/<span class="name">activeProfile</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">activeProfiles</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;/<span class="name">settings</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">欲穷千里目，更上一层楼</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Maven" scheme="https://luckynwa.top/tags/Maven/"/>
    
  </entry>
  
  <entry>
    <title>Java基础入门笔记</title>
    <link href="https://luckynwa.top/posts/jva382/"/>
    <id>https://luckynwa.top/posts/jva382/</id>
    <published>2023-08-10T06:12:00.000Z</published>
    <updated>2026-07-07T16:20:55.798Z</updated>
    
    <content type="html"><![CDATA[<h2 id="环境"><a class="markdownIt-Anchor" href="#环境"></a> 环境</h2><p>安装JDK8并配置环境变量</p><p>jvm+核心类库=jre</p><p>jre+开发工具=jdk</p><p>Java基础运行流程，代码从上到下，从左往右，只运行一次</p><p>桌面—&gt;新建文件夹—&gt;新建记事本—&gt;打开编写代码</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Hello</span>&#123;</span><br><span class="line">     <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Hello luckyNwa &quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>—&gt;修改记事本名称为 Hello.java ----&gt;路径栏输入cmd回车出现终端----&gt;</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">javac Hello.java</span><br></pre></td></tr></table></figure><p>----&gt;生成class文件—&gt;运行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java Hello</span><br></pre></td></tr></table></figure><p>过程：源文件A.java—&gt;javac编译—&gt;A.class—&gt;java运行到JVM中</p><p>在打印中加入中文发现乱码，解决</p><p>文件改成ANSI格式另存覆盖原来的utf-8 或者在javac那指令改成如下</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">javac -encoding UTF-8 Hello.java</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/java1.png" alt="" /></p><h2 id="idea的快捷键"><a class="markdownIt-Anchor" href="#idea的快捷键"></a> IDEA的快捷键</h2><p>ctrl+/ 单行注释</p><p>/**回车 文档注释</p><p>/* */ 多行注释</p><p>shift+ctrl+enter 光标到下一行，也可以补齐;</p><p>mian 生成入口函数</p><p>alt +enter 用于前面的变量定义 比如 new Scanner(<a href="http://System.in">System.in</a>);</p><p>ctrl+n 查类的说明文档 比如Math类</p><p>fori 回车直接打出循环 数组a.for回车 foreach快捷键</p><p>shift+tab 向前退一格</p><p>ctrl+alt+t 可以添for while try catch 等</p><h2 id="命名规范"><a class="markdownIt-Anchor" href="#命名规范"></a> 命名规范</h2><p>标识符（变量）规则：由字母，数字，下划线和$组成，不能以数字开头 ，不能用关键字</p><p>业内规定：</p><p>类：首字母大写，驼峰命名法</p><p>包：小写字母组成，域名倒置</p><p>变量/方法：首字母小写，驼峰命名法，需要语义化，见名知意</p><p>常量：全部大写字母，单词之间下划线隔开 要加个final修饰，不可改变</p><p>关键字：Java官方用掉的名字</p><h2 id="数据类型"><a class="markdownIt-Anchor" href="#数据类型"></a> 数据类型</h2><p>数据类型分为基本数据类型和引用数据类型(复合数据类型)</p><p><strong>基本数据类型（四类八型)</strong></p><p>整数类型: byte 8 short 16 int(默认) 32 long 64 数字是位数</p><p>浮点类型: float 32 单精度 double(默认) 64 双精度 float范围比long大因为它是小数的。浮点数不能用来表示精确的值，如货币</p><p>字符型: char 只有这用单引号，其他基本都是双引号 char letter = ‘A’;</p><p>布尔型 Boolean: true false(默认)</p><p><strong>引用数据类型</strong></p><p>它们是通过类来定义的。Java 中的引用数据类型包括：</p><ul><li>类</li><li>接口</li><li>数组</li></ul><p>复合数据类型有无数种，自带方法和属性，如String、Scanner、Random等</p><p>基本数据类型在内存中存储实际的值，而引用数据类型则存储对对象的引用（即内存地址）。在使用基本数据类型时，实际的值直接存储在变量中，而在使用引用数据类型时，变量存储的是对象的引用，对象本身存储在堆内存</p><p><strong>数据类型转换</strong></p><p>低的变高，是自动转换；高的变低必须强转，会精度损失</p><p>浮点转整需要舍弃小数位</p><p>byte到double 从低到高，byte 类型是 8 位，最大值为127，所以当 int 强制转换为 byte 类型时，值 128 时候就会导致溢出</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></pre></td><td class="code"><pre><span class="line">低  ------------------------------------&gt;  高</span><br><span class="line"></span><br><span class="line"><span class="type">byte</span>,<span class="type">short</span>,<span class="type">char</span>—&gt; <span class="type">int</span> —&gt; <span class="type">long</span>—&gt; <span class="type">float</span> —&gt; <span class="type">double</span></span><br><span class="line"><span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span><span class="number">128</span>;</span><br><span class="line"><span class="type">byte</span> <span class="variable">b</span> <span class="operator">=</span> (<span class="type">byte</span>)i;</span><br></pre></td></tr></table></figure><p>float型转换为double型</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></pre></td><td class="code"><pre><span class="line"><span class="type">float</span> f1=<span class="number">100.00f</span>;</span><br><span class="line">Float F1=<span class="keyword">new</span> <span class="title class_">Float</span>(f1);</span><br><span class="line"><span class="type">double</span> d1=F1.doubleValue();<span class="comment">//F1.doubleValue()为Float类的返回double值型的方法</span></span><br></pre></td></tr></table></figure><p>简单类型的变量转换为相应的包装类，可以利用包装类的构造函数。即：Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value)</p><p>而在各个包装类中，总有形为××Value()的方法，来得到其对应的简单类型数据</p><p><strong>补充</strong></p><p>string 转 int</p><ul><li><p>传入字符串返回整形、这是Integer的静态方法、不会产生多余对象、会抛异常</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> i=Integer.parseInt(s)</span><br></pre></td></tr></table></figure></li><li><p>Integer.valueOf (s) 相当于 new Integer (Integer.parseInt (s))， 返回一个Integer类型，也会抛异常，会多出一个对象，.intValue()获取其对应的基本类型值</p><figure class="highlight java"><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="type">int</span> <span class="variable">i</span> <span class="operator">=</span> Integer.valueOf(s).intValue();</span><br><span class="line"><span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> Integer.valueOf(s)                会自动拆箱这样写就行了</span><br></pre></td></tr></table></figure></li></ul><p>int 转String</p><ul><li><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></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">s1</span> <span class="operator">=</span> String.valueOf(i);        <span class="comment">//第一种</span></span><br><span class="line"><span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> Integer.toString(i);      <span class="comment">//第二种</span></span><br><span class="line"><span class="type">String</span> <span class="variable">s3</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span> + i;                   <span class="comment">//第三种</span></span><br></pre></td></tr></table></figure></li></ul><h2 id="运算符"><a class="markdownIt-Anchor" href="#运算符"></a> 运算符</h2><ul><li><p>算术运算符</p><p>+、-、*、/、% 、++、-- （%取余5%2=1）</p></li><li><p>关系运算符</p><p>== 、!=、&gt;、&lt;、&gt;=、&lt;=</p></li><li><p>位运算符</p><p>＆ |(计算二进制的，用处少)</p><p>7 二进制过程—&gt; 7/2 =3 1 3/2=1 1 1/2= 1 0111 7的二进制结果倒着余数 111</p><p>9 二进制过程—&gt; 9/2=4 1 4/2=2 0 2/2=1 0 1/2= 1 1001 结果倒着余数 1001</p><p>0001 7&amp;9结果1 &amp;必须2个是1才是1</p></li><li><p>逻辑运算符</p><p>&amp;&amp;（逻辑与，2真才真，也叫短路运算符，1假则不会继续下个判断了） 、||(逻辑或，1真就真)、 !(逻辑非)</p></li><li><p>赋值运算符</p><p>=、+=，-=…（c-=a 等价于 c=c-a 其他同理）</p></li><li><p>条件运算符</p><p>条件运算符也被称为三元运算符。该运算符有3个操作数，并且需要判断布尔表达式的值。该运算符的主要是决定哪个值应该赋值给变量。</p></li></ul><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></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">a</span> <span class="operator">=</span> <span class="number">10</span>;</span><br><span class="line"><span class="type">int</span> <span class="variable">b</span> <span class="operator">=</span> <span class="number">20</span>;</span><br><span class="line"><span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> a &lt; b ? b : a;  <span class="comment">//10&lt;20所以将b的值给max否则a，就是三元运算符</span></span><br></pre></td></tr></table></figure><h2 id="条件"><a class="markdownIt-Anchor" href="#条件"></a> 条件</h2><p>Java 中的条件语句允许 程序 <strong>根据条件的不同执行不同的代码块</strong></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span>(布尔表达式 <span class="number">1</span>)&#123;</span><br><span class="line">   <span class="comment">//如果布尔表达式 1的值为true执行代码</span></span><br><span class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(布尔表达式 <span class="number">2</span>)&#123;</span><br><span class="line">   <span class="comment">//如果布尔表达式 2的值为true执行代码</span></span><br><span class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(布尔表达式 <span class="number">3</span>)&#123;</span><br><span class="line">   <span class="comment">//如果布尔表达式 3的值为true执行代码</span></span><br><span class="line">&#125;<span class="keyword">else</span> &#123;</span><br><span class="line">   <span class="comment">//如果以上布尔表达式都不为true执行代码</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>上面可以各种用</p><p><strong>switch case</strong></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">switch</span>(expression)&#123;</span><br><span class="line">    <span class="keyword">case</span> value :</span><br><span class="line">       <span class="comment">//语句</span></span><br><span class="line">       <span class="keyword">break</span>; <span class="comment">//可选</span></span><br><span class="line">    <span class="keyword">case</span> value :</span><br><span class="line">       <span class="comment">//语句</span></span><br><span class="line">       <span class="keyword">break</span>; <span class="comment">//可选</span></span><br><span class="line">    <span class="comment">//你可以有任意数量的case语句</span></span><br><span class="line">    <span class="keyword">default</span> : <span class="comment">//可选</span></span><br><span class="line">       <span class="comment">//语句</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span> &#123;</span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String args[])</span>&#123;</span><br><span class="line">      <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">2</span>;</span><br><span class="line">      <span class="keyword">switch</span>(i)&#123;</span><br><span class="line">         <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">            System.out.println(<span class="string">&quot;0&quot;</span>);</span><br><span class="line">         <span class="keyword">case</span> <span class="number">1</span>:</span><br><span class="line">            System.out.println(<span class="string">&quot;1&quot;</span>);</span><br><span class="line">         <span class="keyword">case</span> <span class="number">2</span>:</span><br><span class="line">            System.out.println(<span class="string">&quot;2&quot;</span>);</span><br><span class="line">         <span class="keyword">default</span>:</span><br><span class="line">            System.out.println(<span class="string">&quot;default&quot;</span>);</span><br><span class="line">      &#125;</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>匹配成功后，从当前 case 开始，后续所有 case 的值都会输出</p><p>2<br />default</p><p>如果i是6，都匹配不到则返回默认的default里的值，一般匹配到就break打断了</p><h2 id="循环"><a class="markdownIt-Anchor" href="#循环"></a> 循环</h2><p>Java中有三种主要的循环结构：</p><ul><li><p><strong>while</strong> 循环</p><p>只要布尔表达式为 true，循环就会一直执行下去。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">while</span>( 布尔表达式 ) &#123;</span><br><span class="line">  <span class="comment">//循环内容</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p><strong>do…while</strong> 循环</p><p>do…while 循环和 while 循环相似，不同的是，do…while 循环至少会执行一次。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">do</span> &#123;</span><br><span class="line">       <span class="comment">//代码语句</span></span><br><span class="line">&#125;<span class="keyword">while</span>(布尔表达式);</span><br><span class="line"></span><br></pre></td></tr></table></figure></li><li><p><strong>for</strong> 循环</p><p>for循环执行的次数是在执行前就确定的</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(初始化; 布尔表达式; 更新) &#123;</span><br><span class="line">    <span class="comment">//代码语句</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li></ul><p>java5引入foreach—&gt;数组的增强型 for 循环 数组a.for回车快速生成</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(声明语句 : 表达式)</span><br><span class="line">&#123;</span><br><span class="line">   <span class="comment">//代码句子</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] numbers = &#123;<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">40</span>, <span class="number">50</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> item : numbers) &#123;</span><br><span class="line">            System.out.println(item);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>配合的关键字</strong></p><p>break主要用于停止，整个循环语句或者 switch 语句，循环语句后面的代码还会运行</p><p>continue用于循环里面让程序跳过当前循环，立刻进入下一次的循环</p><p>return用于返回方法类型指定的值也可以是对象，还能可以结束后面代码的执行</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">int</span>[] numbers = &#123;<span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span>, <span class="number">40</span>, <span class="number">50</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> item : numbers) &#123;</span><br><span class="line"><span class="comment">//            if (item == 10) &#123;</span></span><br><span class="line"><span class="comment">//                continue;//跳过当前满足的条件,继续循环          ----&gt;20,30,40,50,哈哈</span></span><br><span class="line"><span class="comment">//            &#125;</span></span><br><span class="line">            System.out.print(item);</span><br><span class="line">            System.out.print(<span class="string">&quot;,&quot;</span>);</span><br><span class="line">            <span class="keyword">if</span> (item == <span class="number">10</span>) &#123;</span><br><span class="line"><span class="comment">//                break;//满足条件时候跳出循环，循环后面的哈哈还是打印----&gt;10,哈哈</span></span><br><span class="line">                <span class="keyword">return</span>;<span class="comment">//直接返回,不执行后续代码                  ----&gt;10</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;哈哈&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>总结</strong></p><p>for和while都被称为前置判断循环 do…while是后置判断循环</p><p>while和do while都属于不确定次数的循环语句</p><p>for 是属于确定次数的循环语句</p><h2 id="数组"><a class="markdownIt-Anchor" href="#数组"></a> 数组</h2><p>数组的创建</p><p>入口函数那是推荐main(String[] args) 或者写main(String args[])</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></pre></td><td class="code"><pre><span class="line">dataType[] arrayRefVar;   <span class="comment">// 首选的方法</span></span><br><span class="line">或</span><br><span class="line">dataType arrayRefVar[];  <span class="comment">// 效果相同，但不是首选方法</span></span><br><span class="line">arrayRefVar = <span class="keyword">new</span> <span class="title class_">dataType</span>[arraySize];</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">dataType[] arrayRefVar = <span class="keyword">new</span> <span class="title class_">dataType</span>[arraySize];  <span class="comment">//动态声明</span></span><br><span class="line">dataType[] arrayRefVar = <span class="keyword">new</span> <span class="title class_">dataType</span>[]&#123;value0, value1, ..., valuek&#125;;<span class="comment">//用的少，使用1、3</span></span><br><span class="line">dataType[] arrayRefVar = &#123;value0, value1, ..., valuek&#125;; <span class="comment">//静态声明方式</span></span><br></pre></td></tr></table></figure><p><strong>一维数组</strong></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">// 数组大小</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">size</span> <span class="operator">=</span> <span class="number">5</span>;</span><br><span class="line">        <span class="type">double</span>[] myList = <span class="keyword">new</span> <span class="title class_">double</span>[size];</span><br><span class="line">        myList[<span class="number">0</span>] = <span class="number">5.6</span>;</span><br><span class="line">        myList[<span class="number">1</span>] = <span class="number">4.5</span>;</span><br><span class="line">        myList[<span class="number">2</span>] = <span class="number">3.3</span>;</span><br><span class="line">        myList[<span class="number">3</span>] = <span class="number">13.2</span>;</span><br><span class="line">        myList[<span class="number">4</span>] = <span class="number">4.0</span>;</span><br><span class="line">        <span class="comment">// 计算所有元素的总和</span></span><br><span class="line">        <span class="type">double</span> <span class="variable">total</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; size; i++) &#123;</span><br><span class="line">            total += myList[i];</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;总和为： &quot;</span> + total);</span><br><span class="line">        <span class="comment">// 查找最大元素</span></span><br><span class="line">        <span class="type">double</span> <span class="variable">max</span> <span class="operator">=</span> myList[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; myList.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (myList[i] &gt; max) max = myList[i];</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;Max is &quot;</span> + max);</span><br><span class="line">        System.out.println(<span class="string">&quot;-------------------&quot;</span>);</span><br><span class="line">        <span class="type">int</span>[] arr = &#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> x : arr) &#123;  <span class="comment">//这里x只是变量名</span></span><br><span class="line">            System.out.println(x);<span class="comment">//如果里面还有一个循环int y ：x</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>二维数组</strong></p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">type[][] typeName = <span class="keyword">new</span> <span class="title class_">type</span>[typeLength1][typeLength2];</span><br></pre></td></tr></table></figure><p>type 可以为基本数据类型和复合数据类型，typeLength1 和 typeLength2 必须为正整数，typeLength1 为行数，typeLength2 为列数</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span>[][] a = <span class="keyword">new</span> <span class="title class_">int</span>[<span class="number">2</span>][<span class="number">3</span>];</span><br></pre></td></tr></table></figure><p>a 可以看成一个两行三列的数组</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        String[][] s = <span class="keyword">new</span> <span class="title class_">String</span>[<span class="number">2</span>][];</span><br><span class="line">        s[<span class="number">0</span>] = <span class="keyword">new</span> <span class="title class_">String</span>[<span class="number">2</span>];</span><br><span class="line">        s[<span class="number">1</span>] = <span class="keyword">new</span> <span class="title class_">String</span>[<span class="number">3</span>];</span><br><span class="line">        s[<span class="number">0</span>][<span class="number">0</span>] = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;Good&quot;</span>);</span><br><span class="line">        s[<span class="number">0</span>][<span class="number">1</span>] = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;Luck&quot;</span>);</span><br><span class="line">        s[<span class="number">1</span>][<span class="number">0</span>] = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;to&quot;</span>);</span><br><span class="line">        s[<span class="number">1</span>][<span class="number">1</span>] = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;you&quot;</span>);</span><br><span class="line">        s[<span class="number">1</span>][<span class="number">2</span>] = <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;!&quot;</span>);</span><br><span class="line"><span class="comment">//        System.out.println(s[0][1]);//Lucky</span></span><br><span class="line">        <span class="keyword">for</span> (String[] strings : s) &#123;</span><br><span class="line">            <span class="keyword">for</span> (String string : strings) &#123;</span><br><span class="line">                System.out.print(string.concat(<span class="string">&quot;\t&quot;</span>));</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        String[] stu1 = &#123;<span class="string">&quot;张三&quot;</span>, <span class="string">&quot;Jx202211&quot;</span>, <span class="string">&quot;男&quot;</span>, <span class="string">&quot;22&quot;</span>&#125;;</span><br><span class="line">        String[] stu2 = &#123;<span class="string">&quot;李四&quot;</span>, <span class="string">&quot;Jx202212&quot;</span>, <span class="string">&quot;女&quot;</span>, <span class="string">&quot;21&quot;</span>&#125;;</span><br><span class="line">        String[] stu3 = &#123;<span class="string">&quot;王五&quot;</span>, <span class="string">&quot;Jx202213&quot;</span>, <span class="string">&quot;男&quot;</span>, <span class="string">&quot;25&quot;</span>&#125;;</span><br><span class="line">        String[] stu4 = &#123;<span class="string">&quot;小六&quot;</span>, <span class="string">&quot;Jx202214&quot;</span>, <span class="string">&quot;女&quot;</span>, <span class="string">&quot;20&quot;</span>&#125;;</span><br><span class="line">        String[][] stu = &#123;stu1, stu2, stu3, stu4&#125;;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; stu.length; i++) &#123;</span><br><span class="line">            <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j &lt; stu[i].length; j++) &#123;</span><br><span class="line">                System.out.print(stu[i][j] + <span class="string">&quot;\t&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="函数方法"><a class="markdownIt-Anchor" href="#函数方法"></a> 函数(方法)</h2><p>函数是一段具备特定功能的、高度封装的代码块</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></pre></td><td class="code"><pre><span class="line">修饰符 返回值类型 方法名(参数类型 参数名)&#123;</span><br><span class="line">    ...</span><br><span class="line">    方法体</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">return</span> 返回值;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>1、修饰符 public static 公开的 静态的<br />2、返回值类 void 表返回值为null，就不需要return，其他都需要<br />3、函数名 小驼峰命名<br />4、参数列表<br />5、方法体 要执行的代码块</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java1.png" alt="" /></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        Demo1.nPrintln(<span class="string">&quot;lucky&quot;</span>, <span class="number">2</span>);<span class="comment">//正常静态方法调用--&gt;类名.方法名称()</span></span><br><span class="line">        <span class="type">Demo1</span> <span class="variable">demo1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Demo1</span>();<span class="comment">//如果不是静态在类上需要new出来再.</span></span><br><span class="line">        System.out.println(<span class="string">&quot;最大值是&quot;</span> + demo1.max(<span class="number">1</span>, <span class="number">2</span>));</span><br><span class="line">        System.out.println(<span class="string">&quot;最大值是&quot;</span> + demo1.max(<span class="number">11.2</span>, <span class="number">32.2</span>));</span><br><span class="line">        printMax(<span class="keyword">new</span> <span class="title class_">double</span>[]&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;);<span class="comment">//在本类中可以直接调用，无需类名</span></span><br><span class="line">        printMax(<span class="keyword">new</span> <span class="title class_">double</span>[]&#123;&#125;);</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> <span class="keyword">void</span> <span class="title function_">nPrintln</span><span class="params">(String message, <span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            System.out.println(message);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">max</span><span class="params">(<span class="type">int</span> num1, <span class="type">int</span> num2)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> num1 &gt; num2 ? num1 : num2;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> Double <span class="title function_">max</span><span class="params">(Double num1, Double num2)</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> num1 &gt; num2 ? num1 : num2;</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> <span class="keyword">void</span> <span class="title function_">printMax</span><span class="params">(<span class="type">double</span>... numbers)</span> &#123;<span class="comment">//JDK 1.5 开始，Java支持传递同类型的可变参数给一个方法</span></span><br><span class="line">        <span class="keyword">if</span> (numbers.length == <span class="number">0</span>) &#123;                  <span class="comment">//在指定参数类型后加一个省略号...，传了个数组过来</span></span><br><span class="line">            System.out.println(<span class="string">&quot;No argument passed&quot;</span>);</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">double</span> <span class="variable">result</span> <span class="operator">=</span> numbers[<span class="number">0</span>];</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">1</span>; i &lt; numbers.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span> (numbers[i] &gt; result) &#123;</span><br><span class="line">                result = numbers[i];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;The max value is &quot;</span> + result);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>形参与实参：函数声明里就是形参，而调用那里输入则是实参</p><p>返回值：看声明里返回值类，void则没有返回值，如int则返回整型n，如果是类，返回一个对象类</p><p>函数的递归：即函数里调用函数自己</p><p>变量作用域：方法内声明的变量（局部变量），方法外不可用</p><p>方法重载：同一类中方法名相同，参数数量和类型不同。构造方法（对象里的）就可以利用重载</p><h2 id="对象"><a class="markdownIt-Anchor" href="#对象"></a> 对象</h2><p>世界万物皆对象，对象的特点是属性、对象的行为是方法，对象的行为必须是自发的</p><p>特征</p><ul><li>封装</li><li>继承</li><li>多态</li></ul><h3 id="封装"><a class="markdownIt-Anchor" href="#封装"></a> 封装</h3><p>私有化属性并设置公有的get、set方法 IDEA右键—&gt;生成—选择需要的</p><p>封装可以被认为是一个保护屏障，防止该类的代码和数据被外部类定义的代码随机访问</p><p>比如该类是公开的属性，那么外部new这个对象时候便可以直接.属性去修改，现在我们封装了它无法直接修改需要调用set方法去修改，比如年龄想修改1000岁是不正常的，我们便可以再set方法中加逻辑</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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Lucky</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Lucky</span><span class="params">()</span> &#123;                    <span class="comment">//默认存在这个空构造</span></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Lucky</span><span class="params">(String name)</span> &#123;            <span class="comment">//方法的重载</span></span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getName</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setName</span><span class="params">(String name)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span>                 <span class="comment">//方法的重写，原来是打印这个对象的引用地址</span></span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">toString</span><span class="params">()</span> &#123;<span class="comment">//下面的值</span></span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Lucky&#123;&quot;</span> +</span><br><span class="line">                <span class="string">&quot;name=&#x27;&quot;</span> + name + <span class="string">&#x27;\&#x27;&#x27;</span> +</span><br><span class="line">                <span class="string">&#x27;&#125;&#x27;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Lucky</span> <span class="variable">name</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Lucky</span>(<span class="string">&quot;小维&quot;</span>);</span><br><span class="line">        System.out.println(name);</span><br><span class="line">        <span class="type">Lucky</span> <span class="variable">name2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Lucky</span>();</span><br><span class="line">        name2.setName(<span class="string">&quot;小米&quot;</span>);</span><br><span class="line">        System.out.println(name2);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果：</p><p>Lucky{name=‘小维’}<br />Lucky{name=‘小米’}</p><p><strong>this</strong> 关键字是为了解决实例变量（private String name）和局部变量（setName(String name)中的name变量）之间发生的同名的冲突</p><h3 id="构造函数"><a class="markdownIt-Anchor" href="#构造函数"></a> 构造函数</h3><p><strong>是一个没有返回值，并且函数名和类型相同的函数</strong>，在对象实例化的一瞬间就会执行，利用构造函数的参数，对属性进行赋值</p><h3 id="继承"><a class="markdownIt-Anchor" href="#继承"></a> 继承</h3><p>继承就是子类继承父类的属性和方法 苹果是水果可以继承水果类 食草动物是动物可以继承动物类</p><p>必须满足is-a关系 父类更通用 子类更具体</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java8.png" alt="" /></p><p>关键字是extends 写在类名后面</p><p>一个类只能继承一个抽象类， 继承不可滥用，牵一发而动全身，父类改变一次，其他全部受到影响，即耦合性过高，</p><p>继承一般继承Java官方的类</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></pre></td><td class="code"><pre><span class="line">class 父类 &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">class 子类 extends 父类 &#123;</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><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Penguin</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Penguin</span><span class="params">(String myName, <span class="type">int</span> myid)</span> &#123;</span><br><span class="line">        name = myName;</span><br><span class="line">        id = myid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;正在吃&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">void</span> <span class="title function_">sleep</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;正在睡&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">void</span> <span class="title function_">introduction</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;大家好！我是&quot;</span> + id + <span class="string">&quot;号&quot;</span> + name + <span class="string">&quot;.&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Mouse</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Mouse</span><span class="params">(String myName, <span class="type">int</span> myid)</span> &#123;</span><br><span class="line">        name = myName;</span><br><span class="line">        id = myid;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;正在吃&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">void</span> <span class="title function_">sleep</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(name + <span class="string">&quot;正在睡&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">void</span> <span class="title function_">introduction</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;大家好！我是&quot;</span> + id + <span class="string">&quot;号&quot;</span> + name + <span class="string">&quot;.&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Penguin</span> <span class="variable">penguin</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Penguin</span>(<span class="string">&quot;企鹅&quot;</span>, <span class="number">1</span>);</span><br><span class="line">        penguin.eat();</span><br><span class="line">        penguin.sleep();</span><br><span class="line">        penguin.introduction();</span><br><span class="line">        <span class="type">Mouse</span> <span class="variable">mouse</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Mouse</span>(<span class="string">&quot;老鼠&quot;</span>, <span class="number">2</span>);</span><br><span class="line">        mouse.eat();</span><br><span class="line">        mouse.sleep();</span><br><span class="line">        mouse.introduction();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>会发现代码存在重复，导致代码量大且臃肿，而且维护性不高(主要表现是后期需要修改的时候，需要修改很多的代码，容易出错)</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><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 class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> id;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Animal</span><span class="params">(String myName, <span class="type">int</span> myid)</span> &#123;</span><br><span class="line">        name = myName;</span><br><span class="line">        id = myid;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(name+<span class="string">&quot;正在吃&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">sleep</span><span class="params">()</span>&#123;</span><br><span class="line">        System.out.println(name+<span class="string">&quot;正在睡&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">introduction</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;大家好！我是&quot;</span>         + id + <span class="string">&quot;号&quot;</span> + name + <span class="string">&quot;.&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>改造子类，extends单继承，子类只能有一个父类，可以多重继承比如a给b继承，b给c继承，没用过。子类不继承父类的构造器</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Penguin</span>  <span class="keyword">extends</span> <span class="title class_">Animal</span>&#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Penguin</span><span class="params">(String myName, <span class="type">int</span> myid)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(myName, myid);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Mouse</span> <span class="keyword">extends</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Mouse</span><span class="params">(String myName, <span class="type">int</span> myid)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(myName, myid);<span class="comment">//调用父类的构造并传入参数</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><strong>关键字 super</strong> ：放在代码里 用来子类给父类的构造函数的参数传参，还能调用父类的方法 ，不过继承就有父方法了</p><p>如果父类构造器没有参数，则在子类的构造器中不需要使用 <strong>super</strong> 关键字调用父类构造器，系统会自动调用父类的无参构造器</p><p><strong>继承关系下</strong></p><p>首先，会调用父类的构造函数。如果子类构造函数的第一行没有显式调用父类构造函数（通过 <code>super()</code>），则会自动调用父类的无参构造函数。如果父类没有无参构造函数，并且子类没有显式调用父类的其他构造函数，则编译器会报错</p><p>然后，执行父类的构造函数体</p><p>接着，再执行子类的构造函数。如果子类构造函数的第一行没有显式调用其他构造函数（通过 <code>this()</code> 或 <code>super()</code>），则会自动调用父类的无参构造函数，然后执行子类的构造函数体</p><p>最后，执行子类的构造函数体</p><p><strong>重写（Override）</strong></p><p>子类定义了一个与其父类中具有相同名称、参数列表和返回类型的方法，并且子类方法的实现覆盖了父类方法的实现。 <strong>即外壳不变，核心重写！</strong></p><p>父类的方法，子类写的一模一样，最终执行的是子类的方法</p><p>重写规则：修饰符不能强于父类，返回值类型、方法名、参数列表必须一样</p><p><strong>重载(overloading)</strong></p><p>在一个类里面，方法名字相同，而参数不同。返回类型可以相同也可以不同</p><h3 id="多态"><a class="markdownIt-Anchor" href="#多态"></a> 多态</h3><p>多态指同一个事物能呈现出多种形态的能力 多态是<strong>继承的一种体现</strong></p><p>方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现</p><p>多态就是同一个接口，使用不同的实例而执行不同操作</p><p>多态存在的三个必要条件：</p><ul><li>继承</li><li>重写</li><li>父类引用指向子类对象：<strong>Parent p = new Child();</strong></li></ul><p><img src="https://cloud.luckynwa.top/profile/mdS/java9.png" alt="" /></p><p>AnimalT能呈现出多种形态的能力</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><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">AnimalT</span> <span class="variable">a</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Lion</span>();<span class="comment">//父类引用指向子类对象,执行的是子类的方法，这就是多态   向上转型</span></span><br><span class="line">        a.eat();</span><br><span class="line">        a.sleep();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 动物类 AnimalT.java</span></span><br><span class="line"><span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">AnimalT</span> &#123;</span><br><span class="line">    <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span>;</span><br><span class="line">    <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">sleep</span><span class="params">()</span>;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 狮子类 Lion.java</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Lion</span> <span class="keyword">extends</span> <span class="title class_">AnimalT</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;狮子吃&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">sleep</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;狮子睡&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 老虎类 Tiger.java</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Tiger</span> <span class="keyword">extends</span> <span class="title class_">AnimalT</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;老虎吃&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">sleep</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;老虎睡&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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 class="keyword">class</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">makeSound</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;动物发出声音&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Dog</span> <span class="keyword">extends</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">makeSound</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;狗发出汪汪声&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Cat</span> <span class="keyword">extends</span> <span class="title class_">Animal</span> &#123;</span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">makeSound</span><span class="params">()</span> &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;猫发出喵喵声&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Main</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Animal</span> <span class="variable">animal1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Dog</span>(); <span class="comment">// 使用父类引用指向子类对象</span></span><br><span class="line">        <span class="type">Animal</span> <span class="variable">animal2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Cat</span>(); <span class="comment">// 使用父类引用指向另一个子类对象</span></span><br><span class="line"></span><br><span class="line">        animal1.makeSound(); <span class="comment">// 调用被重写的方法，输出：狗发出汪汪声</span></span><br><span class="line">        animal2.makeSound(); <span class="comment">// 调用被重写的方法，输出：猫发出喵喵声</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这就是多态的体现，通过父类的引用调用被子类重写的方法</p><h3 id="接口"><a class="markdownIt-Anchor" href="#接口"></a> 接口</h3><p>接口并不是类，类描述对象的属性和方法。接口则包含类要实现的方法</p><p>接口无法被实例化，但是可以被实现。一个实现接口的类，必须实现接口内所描述的所有方法，否则就必须声明为抽象类</p><p>接口：没有方法体的方法的集合</p><ul><li>接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 <strong>public abstract</strong>（JDK8后default也行，其他修饰符会报错）</li><li>JDK 1.8 以后，接口里可以有静态方法和方法体</li></ul><p><strong>implements关键字</strong></p><p>使用 implements 关键字可以变相的使java具有多继承的特性，使用范围为类继承接口的情况，可以同时继承多个接口（接口跟接口之间采用逗号分隔）</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">A</span> &#123;              <span class="comment">//定义A接口interface关键字</span></span><br><span class="line">     <span class="keyword">void</span> <span class="title function_">eat</span><span class="params">()</span>;</span><br><span class="line">     <span class="keyword">void</span> <span class="title function_">sleep</span><span class="params">()</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">interface</span> <span class="title class_">B</span> &#123;               <span class="comment">//定义B接口</span></span><br><span class="line">     <span class="keyword">void</span> <span class="title function_">show</span><span class="params">()</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">class</span> <span class="title class_">C</span> <span class="keyword">implements</span> <span class="title class_">A</span>,B &#123;    <span class="comment">//实现类 需要全部实现接口中的方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>有方法体的方法 被称为 实例方法</p><p>没方法体的方法 被称为 抽象方法</p><h3 id="包装类"><a class="markdownIt-Anchor" href="#包装类"></a> 包装类</h3><p>所有的包装类**（Integer、Long、Byte、Double、Float、Short）**都是抽象类 Number 的子类</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java2.png" alt="" /></p><p>这种由编译器特别支持的包装称为装箱，所以当内置数据类型被当作对象使用的时候，编译器会把内置类型装箱为包装类。相似的，编译器也可以把一个对象拆箱为内置类型。Number 类属于 java.lang 包</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span>&#123;</span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span>&#123;</span><br><span class="line">      <span class="type">Integer</span> <span class="variable">x</span> <span class="operator">=</span> <span class="number">5</span>; <span class="comment">// x 被赋为整型值时，由于x是一个对象，所以编译器要对x进行装箱</span></span><br><span class="line">      x =  x + <span class="number">10</span>;   <span class="comment">//为了使x能进行加运算，所以要对x进行拆箱</span></span><br><span class="line">      System.out.println(x);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="修饰符"><a class="markdownIt-Anchor" href="#修饰符"></a> 修饰符</h3><h4 id="访问控制修饰符"><a class="markdownIt-Anchor" href="#访问控制修饰符"></a> 访问控制修饰符</h4><p>Java中，可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。</p><ul><li><strong>default</strong> (无修饰）: 本类、同一包的类可见</li><li><strong>private</strong> : 私有的 能且仅能在本类中使用 <strong>注意：不能修饰类（private class Demo1 ）错误</strong></li><li><strong>public</strong> : 对所有类可见。使用对象：类、接口、变量、方法</li><li><strong>protected</strong> : 本类、子类、同一包的类可见 <strong>注意：不能修饰类（外部类）</strong></li></ul><h4 id="static"><a class="markdownIt-Anchor" href="#static"></a> static</h4><p>static 关键字用来声明独立于对象的静态变量，无论一个类实例化多少对象，它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量</p><p>static 关键字用来声明独立于对象的静态方法。静态方法不能使用类的非静态变量。静态方法从参数列表得到数据，然后计算这些数据</p><p>它的特性:只会在类加载的时候执行一次。</p><h4 id="final"><a class="markdownIt-Anchor" href="#final"></a> final</h4><p>final 表示&quot;最后的、最终的&quot;含义，变量一旦赋值后，不能被重新赋值。被 final 修饰的<strong>实例</strong>变量必须显式指定初始值</p><p>final修饰类中的属性或者变量 无论属性是基本类型还是引用类型，final所起的作用都是变量里面存放的&quot;值&quot;不能变，这个值，对于基本类型来说，变量里面放的就是实实在在的值，而引用类型变量里面放的是个地址，所以用final修饰引用类型变量指的是它里面的地址不能变，并不是说这个地址所指向的对象或数组的内容不可以变，这个一定要注意</p><p>final 修饰符通常和 static 修饰符一起使用来创建类常量。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">MyClass</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="type">int</span> <span class="variable">count</span> <span class="operator">=</span> <span class="number">0</span>;                 <span class="comment">//静态变量</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">MAX_SIZE</span> <span class="operator">=</span> <span class="number">100</span>;      <span class="comment">// 使用大写蛇形命名法 常量</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line">MyClass.count = <span class="number">10</span>; <span class="comment">// 通过类名访问</span></span><br><span class="line"><span class="type">MyClass</span> <span class="variable">obj</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">MyClass</span>();</span><br><span class="line">obj.count = <span class="number">20</span>; <span class="comment">// 通过实例名访问</span></span><br></pre></td></tr></table></figure><p><strong>final 属性</strong> 声明变量时可以不赋值，而且一旦赋值就不能被修改了,用来new的那个对象里有final修饰的属性那个属性必须赋值</p><p><strong>final 方法</strong> 可以被子类继承，但是不能被子类重写。声明 final 方法的主要目的是防止该方法的内容被修改</p><p><strong>final 类</strong> 不能被继承</p><h4 id="abstract抽象类"><a class="markdownIt-Anchor" href="#abstract抽象类"></a> abstract（抽象类）</h4><p>抽象类不能用来实例化对象</p><p>一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法，那么该类一定要声明为抽象类，否则将出现编译错误</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">Caravan</span>&#123;  <span class="comment">//被abstract修饰就是抽象类</span></span><br><span class="line">   <span class="keyword">private</span> <span class="type">double</span> price;</span><br><span class="line">   <span class="keyword">private</span> String model;</span><br><span class="line">   <span class="keyword">private</span> String year;</span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">goFast</span><span class="params">()</span>; <span class="comment">//抽象方法</span></span><br><span class="line">   <span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">changeColor</span><span class="params">()</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>抽象方法是一种没有任何实现的方法，该方法的具体实现由子类提供</p><p>抽象方法不能被声明成 final 和 static</p><p>如果一个类包含抽象方法，那么该类必须声明为抽象类。抽象类可以不包含抽象方法</p><p>继承抽象类的子类必须实现父类的所有抽象方法，除非该子类也必须声明为抽象类</p><p>构造方法，类方法（用 static 修饰的方法）不能声明为抽象方法</p><p>抽象方法的声明以分号结尾，例如：<strong>public abstract sample();</strong></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">abstract</span> <span class="keyword">class</span> <span class="title class_">SuperClass</span>&#123;</span><br><span class="line">    <span class="keyword">abstract</span> <span class="keyword">void</span> <span class="title function_">m</span><span class="params">()</span>; <span class="comment">//抽象方法</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SubClass</span> <span class="keyword">extends</span> <span class="title class_">SuperClass</span>&#123;</span><br><span class="line">     <span class="comment">//实现抽象方法</span></span><br><span class="line">      <span class="keyword">void</span> <span class="title function_">m</span><span class="params">()</span>&#123;</span><br><span class="line">          .........</span><br><span class="line">      &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="synchronized"><a class="markdownIt-Anchor" href="#synchronized"></a> synchronized</h4><p>synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title function_">showDetails</span><span class="params">()</span>&#123;</span><br><span class="line">.......</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="枚举类"><a class="markdownIt-Anchor" href="#枚举类"></a> 枚举类</h4><p>枚举是一个特殊的类，一般表示一组常量，比如一年的 4 个季节，一年的 12 个月份，一个星期的 7 天，方向有东南西北等—&gt;场景：颜色（红黄蓝绿…）、星期、反射做多个oss桶时候</p><p>常量类是指一组声明为静态的、不可改变的常量变量，它们通常用于定义一些全局性的常量，如数学常数π、还有一些不变的值，项目中必定有一个常量类，final关键字，表示这些变量不能被修改—&gt; 场景：分页的当前页、限制页数、返回的数据成功、失败…</p><p>Java 枚举类使用 enum 关键字来定义，各个常量使用逗号 <strong>,</strong> 来分割</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">Color</span> &#123;</span><br><span class="line">    RED, GREEN, BLUE;</span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">Color</span><span class="params">()</span>    <span class="comment">// 构造函数只能使用 private 访问修饰符，所以外部无法调用</span></span><br><span class="line">    &#123;</span><br><span class="line">        System.out.println(<span class="string">&quot;Constructor called for : &quot;</span> + <span class="built_in">this</span>.toString());</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">colorInfo</span><span class="params">()</span> &#123;<span class="comment">//枚举既可以包含具体方法，也可以包含抽象方法。 如果枚举类具有抽象方法，则枚举类的每个实例都必须实现它</span></span><br><span class="line">        System.out.println(<span class="string">&quot;枚举的方法&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>每个枚举都是通过 Class 在内部实现的，且所有的枚举值都是 public static final 的，所以可以 类名.名称</p><ul><li>values() 返回枚举类中所有的值。</li><li>ordinal()方法可以找到每个枚举常量的索引，就像数组索引一样。</li><li>valueOf()方法返回指定字符串值的枚举常量。</li></ul><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Color</span> <span class="variable">c1</span> <span class="operator">=</span> Color.RED;</span><br><span class="line">        System.out.println(c1);</span><br><span class="line">        <span class="keyword">for</span> (Color myVar : Color.values()) &#123;</span><br><span class="line">            System.out.println(myVar);</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// ------------------------------------------------</span></span><br><span class="line">        <span class="type">Color</span> <span class="variable">myVar</span> <span class="operator">=</span> Color.BLUE;</span><br><span class="line">        <span class="keyword">switch</span> (myVar) &#123;</span><br><span class="line">            <span class="keyword">case</span> RED:</span><br><span class="line">                System.out.println(<span class="string">&quot;红色&quot;</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> GREEN:</span><br><span class="line">                System.out.println(<span class="string">&quot;绿色&quot;</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            <span class="keyword">case</span> BLUE:</span><br><span class="line">                System.out.println(<span class="string">&quot;蓝色&quot;</span>);</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// ------------------------------------------------</span></span><br><span class="line">        Color[] arr = Color.values();</span><br><span class="line">        <span class="comment">// 迭代枚举</span></span><br><span class="line">        <span class="keyword">for</span> (Color col : arr) &#123;</span><br><span class="line">            <span class="comment">// 查看索引</span></span><br><span class="line">            System.out.println(col + <span class="string">&quot; at index &quot;</span> + col.ordinal());</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 使用 valueOf() 返回枚举常量，不存在的会报错 IllegalArgumentException</span></span><br><span class="line">        System.out.println(Color.valueOf(<span class="string">&quot;RED&quot;</span>));</span><br><span class="line">        <span class="comment">// ------------------------------------------------</span></span><br><span class="line">        <span class="type">Color</span> <span class="variable">green</span> <span class="operator">=</span> Color.GREEN;<span class="comment">//下面2个结果一样</span></span><br><span class="line">        green.colorInfo();</span><br><span class="line">        <span class="type">Color</span> <span class="variable">red</span> <span class="operator">=</span> Color.RED;</span><br><span class="line">        red.colorInfo();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>工作中的写法1</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><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">ErrorCode</span> &#123;</span><br><span class="line">    OK(<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">public</span> String <span class="title function_">getDescription</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;成功&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    ERROR_A(<span class="number">100</span>) &#123;</span><br><span class="line">        <span class="keyword">public</span> String <span class="title function_">getDescription</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;错误A&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    ERROR_B(<span class="number">200</span>) &#123;</span><br><span class="line">        <span class="keyword">public</span> String <span class="title function_">getDescription</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;错误B&quot;</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;                            <span class="comment">//分号</span></span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> code;</span><br><span class="line">    <span class="comment">// 构造方法：enum的构造方法只能被声明为private权限或不声明权限</span></span><br><span class="line">    <span class="keyword">private</span> <span class="title function_">ErrorCode</span><span class="params">(<span class="type">int</span> number)</span> &#123; <span class="comment">// 构造方法</span></span><br><span class="line">        <span class="built_in">this</span>.code = number;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getCode</span><span class="params">()</span> &#123; <span class="comment">// 普通方法</span></span><br><span class="line">        <span class="keyword">return</span> code;</span><br><span class="line">    &#125; <span class="comment">// 普通方法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">abstract</span> String <span class="title function_">getDescription</span><span class="params">()</span>; <span class="comment">// 抽象方法</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>写法2 效果和调用一样</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> <span class="title class_">ErrorCodeEn</span> &#123;</span><br><span class="line">    OK(<span class="number">0</span>, <span class="string">&quot;成功&quot;</span>),</span><br><span class="line">    ERROR_A(<span class="number">100</span>, <span class="string">&quot;错误A&quot;</span>),</span><br><span class="line">    ERROR_B(<span class="number">200</span>, <span class="string">&quot;错误B&quot;</span>);</span><br><span class="line">    ErrorCodeEn(<span class="type">int</span> number, String description) &#123;</span><br><span class="line">        <span class="built_in">this</span>.code = number;</span><br><span class="line">        <span class="built_in">this</span>.description = description;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> code;</span><br><span class="line">    <span class="keyword">private</span> String description;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getCode</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> code;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getDescription</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> description;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="comment">// 获取枚举常量的值</span></span><br><span class="line">        System.out.println(ErrorCodeEn.OK.getCode()); <span class="comment">// 输出: 0</span></span><br><span class="line">        System.out.println(ErrorCodeEn.ERROR_A.getCode()); <span class="comment">// 输出: 100</span></span><br><span class="line">        System.out.println(ErrorCodeEn.ERROR_B.getCode()); <span class="comment">// 输出: 200</span></span><br><span class="line">        <span class="comment">// 获取枚举常量的描述</span></span><br><span class="line">        System.out.println(ErrorCodeEn.OK.getDescription()); <span class="comment">// 输出: 成功</span></span><br><span class="line">        System.out.println(ErrorCodeEn.ERROR_A.getDescription()); <span class="comment">// 输出: 错误A</span></span><br><span class="line">        System.out.println(ErrorCodeEn.ERROR_B.getDescription()); <span class="comment">// 输出: 错误B</span></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="补充"><a class="markdownIt-Anchor" href="#补充"></a> 补充</h3><p><strong>面向对象与面向过程区别</strong></p><p>面向过程：只关注事情本身的完成，不关注谁去做，就像大象塞进冰箱，不管是谁把冰箱打开，谁把大象弄进去</p><p>面向对象：更多关注 谁去做事情 各有各的好处</p><p><strong>对象的生命周期</strong></p><p>对象的出生：一旦被声明被赋值之后 对象即出现</p><p>对象的销毁：当该对象没有被指向 就会被自动销毁</p><p>String a；这是空，没有对象，所以没有出生和销毁</p><h2 id="io流"><a class="markdownIt-Anchor" href="#io流"></a> IO流</h2><p>IO 流：按照流动的方向，以内存为基准，分为输入 input 和输出 output ，即流向内存是输入流，流出内存的输出流</p><p>（1）明确要操作的数据是数据源还是数据目的(也就是要读还是要写)<br />（2）明确要操作的设备上的数据是字节还是文本<br />（3）明确数据所在的具体设备<br />（4）明确是否需要额外功能（比如是否需要转换流、高效流等）</p><p>输入流（读数据 硬盘----&gt;内存）、输出流（写数据 内存—&gt;硬盘）</p><p>分类：</p><p>1.字节流：字节流又分为字节输入流、字节输出流 2.字符流：字符流由分为字符输入流、字符输出流</p><p>字符流的由来：因为数据编码的不同，字节流直接读中文会乱码 字符流 = 字节流 + 编码表</p><p>数据流向内存就是输入流，流出内存就是输出流，根据数据的类型分为</p><p>字节流和字符流，如名字的为单位</p><p>字节流对应的输入流 InputStream 输出流 OutputStream</p><p>字符流对应的输入流 Reader 输出流 Writer</p><p>超类（父类）以这四个名称结尾都是它的子类</p><p>比如常见的 FileInputStream 文件输入流</p><p>1 个字符=2 个字节</p><p>字节流适合读取视频、音乐、图片等二进制文件，字符流比较适合读取纯文本文件</p><p>字节流可以传输任意文件数据。在操作流的时候，我们要时刻明确，无论使用什么样的流对象，底层传输的始终为二进制数据</p><h3 id="file-类"><a class="markdownIt-Anchor" href="#file-类"></a> File 类</h3><p>java.io.File 类是专门对文件进行操作的类，只能对文件本身进行操作，不能对文件进行读和写也就是输入和输出</p><p>File 类构造方法不会给你检验这个文件或文件夹是否真实存在，因此无论该路径下是否存在文件或者目录，都不影响 File 对象的创建。</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/10 -10:34</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FileDemo</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">f</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;C:\\Users\\FF\\Desktop\\1.txt&quot;</span>);  <span class="comment">//就算文件1.txt不存在也不影响file对象的创建</span></span><br><span class="line">        <span class="keyword">if</span> (!f.exists()) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;是否创建:&quot;</span>+f.createNewFile()); <span class="comment">// true 如果没有文件则创建并返回true</span></span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;是否创建:&quot;</span>+f.createNewFile());  <span class="comment">//已经存在，所以就false了</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件绝对路径:&quot;</span>+f.getAbsolutePath());<span class="comment">//文件绝对路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件构造路径:&quot;</span>+f.getPath());        <span class="comment">//文件构造路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件名称:&quot;</span>+f.getName());          <span class="comment">//文件名称:1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件长度:&quot;</span>+f.length()+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        <span class="comment">// 判断是文件还是目录</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件:&quot;</span>+f.isFile());</span><br><span class="line">        System.out.println(<span class="string">&quot;目录:&quot;</span>+f.isDirectory());</span><br><span class="line">        <span class="comment">//一个路径下全部文件名,先将字符串转目录</span></span><br><span class="line"><span class="comment">//        String path = &quot;D:\\workspace&quot;;</span></span><br><span class="line"><span class="comment">//        File file = new File(path);</span></span><br><span class="line"><span class="comment">//        printFile(file);</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//结果1   传进的file不一样结果不一样，如果是绝对位置那么构造啥的都是绝对的</span></span><br><span class="line"><span class="comment">//    是否创建:false</span></span><br><span class="line"><span class="comment">//    文件绝对路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line"><span class="comment">//    文件构造路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line"><span class="comment">//    文件名称:1.txt</span></span><br><span class="line"><span class="comment">//    文件长度:0字节</span></span><br><span class="line"><span class="comment">//    文件:true</span></span><br><span class="line"><span class="comment">//    目录:false</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//结果2 如果是直接1.txt则会相对这个项目来创建这个文件</span></span><br><span class="line"><span class="comment">//    是否创建:true</span></span><br><span class="line"><span class="comment">//    是否创建:false</span></span><br><span class="line"><span class="comment">//    文件绝对路径:E:\LuckyWorckSpace\lucky_api\1.txt</span></span><br><span class="line"><span class="comment">//    文件构造路径:1.txt</span></span><br><span class="line"><span class="comment">//    文件名称:1.txt</span></span><br><span class="line"><span class="comment">//    文件长度:0字节</span></span><br><span class="line"><span class="comment">//    文件:true</span></span><br><span class="line"><span class="comment">//    目录:false</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDemo2</span><span class="params">()</span> &#123;   <span class="comment">//目录的创建等,使用相对这个项目下的目录来测试了</span></span><br><span class="line">        <span class="comment">// 目录的创建</span></span><br><span class="line">        File f2= <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira&quot;</span>);</span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否存在:&quot;+f2.exists());// false</span></span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否创建:&quot;+f2.mkdir());    //  这个是创建的意思，并返回true</span></span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否存在:&quot;+f2.exists());// true</span></span><br><span class="line">        <span class="comment">// 创建多级目录</span></span><br><span class="line"><span class="comment">//        File f3= new File(&quot;newDira\\newDirb&quot;);</span></span><br><span class="line"><span class="comment">//        System.out.println(f3.mkdir());// false，没有加s指南创建单层的目录</span></span><br><span class="line">        File f4= <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira\\newDirb&quot;</span>);</span><br><span class="line">  <span class="comment">//      System.out.println(f4.mkdirs());// true,可以创建多级别的目录</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 文件和目录的删除  delete方法，如果此File表示目录，则目录必须为空才能删除。</span></span><br><span class="line">      <span class="comment">//  System.out.println(f2.delete());// true</span></span><br><span class="line">   <span class="comment">//     System.out.println(f4.delete());// false如果是删除多层目录只能删除最底层的比如这个的newDirb目录，外newDira没有删掉</span></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">public</span> <span class="keyword">void</span> <span class="title function_">demo3</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\other\\study\\学习sp\\实用篇&quot;</span>);</span><br><span class="line">        printFile(file);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span>  <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">printFile</span><span class="params">(File file)</span> &#123;</span><br><span class="line"><span class="comment">//        //获取当前目录下的文件以及文件夹的名称。</span></span><br><span class="line"><span class="comment">//        File[] files = file.listFiles();</span></span><br><span class="line"><span class="comment">//        for (File a:files) &#123;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//            if (a.isFile()) &#123;</span></span><br><span class="line"><span class="comment">//                System.out.println( a.getName());</span></span><br><span class="line"><span class="comment">//            &#125;else &#123;</span></span><br><span class="line"><span class="comment">//                printFile(a);</span></span><br><span class="line"><span class="comment">//            &#125;</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        //下面的只获取一层，上面是里面全部获取</span></span><br><span class="line"><span class="comment">//        String[] names = file.list();</span></span><br><span class="line"><span class="comment">//        for(String name : names)&#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(name);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"><span class="comment">//        //获取当前目录下的文件以及文件夹对象，只要拿到了文件对象，那么就可以获取更多信息</span></span><br><span class="line"><span class="comment">//        File[] files = file.listFiles(); //listFiles指定的必须是目录。否则容易引发返回数组为null，出现NullPointerException异常</span></span><br><span class="line"><span class="comment">//        for (File fi : files) &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(fi);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        递归全部</span></span><br><span class="line">        <span class="comment">//1、判断传入的是否是目录</span></span><br><span class="line">        <span class="keyword">if</span>(!file.isDirectory())&#123;</span><br><span class="line">            <span class="comment">//不是目录直接退出</span></span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//已经确保了传入的file是目录</span></span><br><span class="line">        File[] files = file.listFiles();</span><br><span class="line">        <span class="comment">//遍历files</span></span><br><span class="line">        <span class="keyword">for</span> (File f: files) &#123;</span><br><span class="line">            <span class="comment">//如果该目录下文件还是个文件夹就再进行递归遍历其子目录</span></span><br><span class="line">            <span class="keyword">if</span>(f.isDirectory())&#123;</span><br><span class="line">                <span class="comment">//递归</span></span><br><span class="line">                printFile(f);</span><br><span class="line">            &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">//如果该目录下文件是个文件，则打印对应的名字</span></span><br><span class="line">                System.out.println(f.getName());</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">demo2</span><span class="params">()</span>&#123;</span><br><span class="line">         <span class="comment">//从d盘下的a.txt文件拷贝到另个盘下</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">File</span> <span class="variable">file1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\a.txt&quot;</span>);<span class="comment">//这是源文件</span></span><br><span class="line">            <span class="type">long</span> flen=file1.length();</span><br><span class="line">            System.out.println(<span class="string">&quot;源文件的大小是&quot;</span>+flen+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">            <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file1);</span><br><span class="line">            <span class="type">File</span> <span class="variable">file2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\b.txt&quot;</span>);<span class="comment">//这是复制到的地方</span></span><br><span class="line">            <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(file2);</span><br><span class="line">            <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>]; <span class="comment">//这是1兆1兆传</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="type">long</span> readSize=<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;<span class="comment">//-1就是最后一个结束</span></span><br><span class="line">                fos.write(bytes,<span class="number">0</span>,len); <span class="comment">//比如一个文件是1024*8+244，那么len就是244</span></span><br><span class="line">                fos.flush();<span class="comment">//强制输出，推送数据</span></span><br><span class="line">                readSize+=len;</span><br><span class="line">                <span class="keyword">if</span> (readSize== flen) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;读的大小&quot;</span>+readSize+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">demo1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\1.txt&quot;</span>);</span><br><span class="line">        <span class="type">File</span> <span class="variable">file1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\222.txt&quot;</span>);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file);</span><br><span class="line">            <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(file1);</span><br><span class="line">            <span class="type">BufferedInputStream</span> <span class="variable">bis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedInputStream</span>(fis);</span><br><span class="line">            <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">            <span class="keyword">while</span> (bis.read(bytes) != -<span class="number">1</span>) &#123;</span><br><span class="line">                fos.write(bytes);</span><br><span class="line">                fos.flush();</span><br><span class="line">                System.out.println(<span class="string">&quot;aaaa&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="fileoutputstream"><a class="markdownIt-Anchor" href="#fileoutputstream"></a> FileOutputStream</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">FileOutputStream</span> <span class="variable">outputStream</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;abc.txt&quot;</span>);</span><br></pre></td></tr></table></figure><p>这行代码做了下面的事情<br />1、调用系统功能去创建文件【输出流对象才会自动创建】<br />2、创建outputStream对象<br />3、把foutputStream对象指向这个文件</p><p>创建输出流对象的时候，系统会自动去对应位置创建对应文件，而创建输出流对象的时候，文件不存在则会报 FileNotFoundException 异常，也就是系统找不到指定的文件异常。</p><p>当你创建一个流对象时，必须直接或者间接传入一个文件路径。比如现在我们创建一个 FileOutputStream 流对象，在该路径下，如果没有这个文件，会创建该文件。如果有这个文件，会清空这个文件的数据</p><p><strong>为什么是输入流呢</strong></p><p>1、因为流是相对于内存来说的，现在 abc.txt 就是要保存到磁盘里面的文本，就是说从内存----&gt;磁盘，那必须是输出流，用 FileWrite 和 FileOutputStream 都可以</p><p>2、传入路径时候是它的一种构造方法，不会继续写到文本中，所以用它的另外的构造函数即可解决这个问题。</p><ul><li><p>public FileOutputStream(File file, boolean append) 一般不需要用这个，因为文件创建，输出流自动会帮我们生成，没必要多此一举暂时</p></li><li><p>public FileOutputStream(String name, boolean append) true 表示追加数据</p></li></ul><p>Windows 系统里，每行结尾是 回车+换行 ，即\r\n；<br />Unix 系统里，每行结尾只有 换行 ，即\n；<br />Mac 系统里，每行结尾是 回车 ，即\r。从 Mac OS X 开始与 Linux 统一。</p><h3 id="fileinputstream"><a class="markdownIt-Anchor" href="#fileinputstream"></a> FileInputStream</h3><p>流进内存的，输入流</p><p>1、 <strong>FileInputStream(File file)</strong>： 通过打开与实际文件的连接来创建一个 FileInputStream ，该文件由文件系统中的 File 对象 file 命名。<br />2、 <strong>FileInputStream(String name)</strong>： 通过打开与实际文件的连接来创建一个 FileInputStream ，该文件由文件系统中的路径名 name 命名。</p><p>当你创建一个输入流对象时，必须传一个文件路径。该路径下，如果没有该文件,会抛出 FileNotFoundException</p><p>使用字节数组读取：read(byte[] b) 效率更高</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></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">0</span> ;</span><br><span class="line"><span class="type">byte</span>[] bys = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line"><span class="keyword">while</span> ((len = inputStream.read(bys)) != -<span class="number">1</span>) &#123;</span><br><span class="line">    System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(bys,<span class="number">0</span>,len));<span class="comment">//len输出有效的字节数</span></span><br></pre></td></tr></table></figure><h3 id="reader"><a class="markdownIt-Anchor" href="#reader"></a> Reader</h3><p>字符输入流的所有类的超类 输入流</p><h3 id="filewriter"><a class="markdownIt-Anchor" href="#filewriter"></a> FileWriter</h3><p>写出字符到文件的便利类 输出流</p><p>//关闭资源时,与 FileOutputStream 不同。 如果不关闭,数据只是保存到缓冲区，并未保存到文件。</p><p>// fw.close();</p><p>关闭 close 和刷新 flush<br />因为内置缓冲区的原因，如果不关闭输出流，无法写出字符到文件中。但是关闭的流对象，是无法继续写出数据的。如果我们既想写出数据，又想继续使用流，就需要 flush 方法了。</p><p>flush ：刷新缓冲区，流对象可以继续使用。清空缓冲区的数据流<br />close:先刷新缓冲区，然后通知系统释放资源。流对象不可以再被使用了。</p><h3 id="缓冲流"><a class="markdownIt-Anchor" href="#缓冲流"></a> 缓冲流</h3><p>1、使用了底层流对象从具体设备上获取数据，并将数据存储到缓冲区的数组内。<br />2、通过缓冲区的 read()方法从缓冲区获取具体的字符数据，这样就提高了效率。<br />3、如果用 read 方法读取字符数据，并存储到另一个容器中，直到读取到了换行符时，将另一个容器临时存储的数据转成字符串返回，就形成了 readLine()功能。</p><p>也就是说在创建流对象时，会创建一个内置的默认大小的缓冲区数组，通过缓冲区读写，减少系统 IO 次数，从而提高读写的效率。</p><p>缓冲书写格式为 BufferedXxx，按照数据类型分类：</p><p><strong>字节缓冲流</strong>：BufferedInputStream，BufferedOutputStream<br /><strong>字符缓冲流</strong>：BufferedReader，BufferedWriter<br />构造方法<br /><strong>public BufferedInputStream(InputStream in)</strong> ：创建一个新的缓冲输入流，注意参数类型为 InputStream。<br /><strong>public BufferedOutputStream(OutputStream out)</strong>： 创建一个新的缓冲输出流，注意参数类型为 OutputStream。</p><p><strong>BufferedReader：public String readLine()</strong>: 读一行数据。 读取到最后返回 null,就这个特别一点，判断条件都需要修改了<br /><strong>BufferedWriter：public void newLine()</strong>: 换行,由系统属性定义符号。</p><h3 id="转换流"><a class="markdownIt-Anchor" href="#转换流"></a> 转换流</h3><p>简单一点的说就是：</p><p>编码:字符(能看懂的)–字节(看不懂的)</p><p>解码:字节(看不懂的)–&gt;字符(能看懂的)</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></pre></td><td class="code"><pre><span class="line">String(<span class="type">byte</span>[] bytes, String charsetName):通过指定的字符集解码字节数组</span><br><span class="line"><span class="type">byte</span>[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组</span><br><span class="line"></span><br><span class="line">编码:把看得懂的变成看不懂的</span><br><span class="line">String -- <span class="type">byte</span>[]</span><br><span class="line"></span><br><span class="line">解码:把看不懂的变成看得懂的</span><br><span class="line"><span class="type">byte</span>[] -- String</span><br></pre></td></tr></table></figure><p>字符集 Charset：也叫编码表。是一个系统支持的所有字符的集合，包括各国家文字、标点符号、图形符号、数字等。</p><p>在 java 开发工具 IDEA 中，使用 FileReader 读取项目中的文本文件。由于 IDEA 的设置，都是默认的 UTF-8 编码，所以没有任何问题。但是，当读取 Windows 系统中创建的文本文件时，由于 Windows 系统的默认是 GBK 编码，就会出现乱码。</p><p>转换流 java.io.InputStreamReader，是 Reader 的子类，从字面意思可以看出它是从字节流到字符流的桥梁。它读取字节，并使用指定的字符集将其解码为字符。它的字符集可以由名称指定，也可以接受平台的默认字符集。</p><p>构造方法<br /><strong>InputStreamReader(InputStream in)</strong>: 创建一个使用默认字符集的字符流。<br /><strong>InputStreamReader(InputStream in, String charsetName)</strong>: 创建一个指定字符集的字符流。</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></pre></td><td class="code"><pre><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;in.txt&quot;</span>));</span><br><span class="line"><span class="type">InputStreamReader</span> <span class="variable">isr2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;in.txt&quot;</span>) , <span class="string">&quot;GBK&quot;</span>);</span><br></pre></td></tr></table></figure><p><strong>OutputStreamWriter</strong>同理</p><h4 id="案例-1"><a class="markdownIt-Anchor" href="#案例-1"></a> 案例 1</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/10 -10:34</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">FileDemo</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">fun1</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">f</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;C:\\Users\\FF\\Desktop\\1.txt&quot;</span>);  <span class="comment">//就算文件1.txt不存在也不影响file对象的创建</span></span><br><span class="line">        <span class="keyword">if</span> (!f.exists()) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;是否创建:&quot;</span>+f.createNewFile()); <span class="comment">// true 如果没有文件则创建并返回true</span></span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;是否创建:&quot;</span>+f.createNewFile());  <span class="comment">//已经存在，所以就false了</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件绝对路径:&quot;</span>+f.getAbsolutePath());<span class="comment">//文件绝对路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件构造路径:&quot;</span>+f.getPath());        <span class="comment">//文件构造路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件名称:&quot;</span>+f.getName());          <span class="comment">//文件名称:1.txt</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件长度:&quot;</span>+f.length()+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        <span class="comment">// 判断是文件还是目录</span></span><br><span class="line">        System.out.println(<span class="string">&quot;文件:&quot;</span>+f.isFile());</span><br><span class="line">        System.out.println(<span class="string">&quot;目录:&quot;</span>+f.isDirectory());</span><br><span class="line">        <span class="comment">//一个路径下全部文件名,先将字符串转目录</span></span><br><span class="line"><span class="comment">//        String path = &quot;D:\\workspace&quot;;</span></span><br><span class="line"><span class="comment">//        File file = new File(path);</span></span><br><span class="line"><span class="comment">//        printFile(file);</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="comment">//结果1   传进的file不一样结果不一样，如果是绝对位置那么构造啥的都是绝对的</span></span><br><span class="line"><span class="comment">//    是否创建:false</span></span><br><span class="line"><span class="comment">//    文件绝对路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line"><span class="comment">//    文件构造路径:C:\Users\FF\Desktop\1.txt</span></span><br><span class="line"><span class="comment">//    文件名称:1.txt</span></span><br><span class="line"><span class="comment">//    文件长度:0字节</span></span><br><span class="line"><span class="comment">//    文件:true</span></span><br><span class="line"><span class="comment">//    目录:false</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//结果2 如果是直接1.txt则会相对这个项目来创建这个文件</span></span><br><span class="line"><span class="comment">//    是否创建:true</span></span><br><span class="line"><span class="comment">//    是否创建:false</span></span><br><span class="line"><span class="comment">//    文件绝对路径:E:\LuckyWorckSpace\lucky_api\1.txt</span></span><br><span class="line"><span class="comment">//    文件构造路径:1.txt</span></span><br><span class="line"><span class="comment">//    文件名称:1.txt</span></span><br><span class="line"><span class="comment">//    文件长度:0字节</span></span><br><span class="line"><span class="comment">//    文件:true</span></span><br><span class="line"><span class="comment">//    目录:false</span></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">testDemo2</span><span class="params">()</span> &#123;   <span class="comment">//目录的创建等,使用相对这个项目下的目录来测试了</span></span><br><span class="line">        <span class="comment">// 目录的创建</span></span><br><span class="line">        File f2= <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira&quot;</span>);</span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否存在:&quot;+f2.exists());// false</span></span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否创建:&quot;+f2.mkdir());    //  这个是创建的意思，并返回true</span></span><br><span class="line"><span class="comment">//        System.out.println(&quot;是否存在:&quot;+f2.exists());// true</span></span><br><span class="line">        <span class="comment">// 创建多级目录</span></span><br><span class="line"><span class="comment">//        File f3= new File(&quot;newDira\\newDirb&quot;);</span></span><br><span class="line"><span class="comment">//        System.out.println(f3.mkdir());// false，没有加s指南创建单层的目录</span></span><br><span class="line">        File f4= <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;newDira\\newDirb&quot;</span>);</span><br><span class="line">  <span class="comment">//      System.out.println(f4.mkdirs());// true,可以创建多级别的目录</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">// 文件和目录的删除  delete方法，如果此File表示目录，则目录必须为空才能删除。</span></span><br><span class="line">      <span class="comment">//  System.out.println(f2.delete());// true</span></span><br><span class="line">   <span class="comment">//     System.out.println(f4.delete());// false如果是删除多层目录只能删除最底层的比如这个的newDirb目录，外newDira没有删掉</span></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">public</span> <span class="keyword">void</span> <span class="title function_">demo3</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\other\\study\\学习sp\\实用篇&quot;</span>);</span><br><span class="line">        printFile(file);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span>  <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">printFile</span><span class="params">(File file)</span> &#123;</span><br><span class="line"><span class="comment">//        //获取当前目录下的文件以及文件夹的名称。</span></span><br><span class="line"><span class="comment">//        File[] files = file.listFiles();</span></span><br><span class="line"><span class="comment">//        for (File a:files) &#123;</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//            if (a.isFile()) &#123;</span></span><br><span class="line"><span class="comment">//                System.out.println( a.getName());</span></span><br><span class="line"><span class="comment">//            &#125;else &#123;</span></span><br><span class="line"><span class="comment">//                printFile(a);</span></span><br><span class="line"><span class="comment">//            &#125;</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        //下面的只获取一层，上面是里面全部获取</span></span><br><span class="line"><span class="comment">//        String[] names = file.list();</span></span><br><span class="line"><span class="comment">//        for(String name : names)&#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(name);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"><span class="comment">//        //获取当前目录下的文件以及文件夹对象，只要拿到了文件对象，那么就可以获取更多信息</span></span><br><span class="line"><span class="comment">//        File[] files = file.listFiles(); //listFiles指定的必须是目录。否则容易引发返回数组为null，出现NullPointerException异常</span></span><br><span class="line"><span class="comment">//        for (File fi : files) &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(fi);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        递归全部</span></span><br><span class="line">        <span class="comment">//1、判断传入的是否是目录</span></span><br><span class="line">        <span class="keyword">if</span>(!file.isDirectory())&#123;</span><br><span class="line">            <span class="comment">//不是目录直接退出</span></span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//已经确保了传入的file是目录</span></span><br><span class="line">        File[] files = file.listFiles();</span><br><span class="line">        <span class="comment">//遍历files</span></span><br><span class="line">        <span class="keyword">for</span> (File f: files) &#123;</span><br><span class="line">            <span class="comment">//如果该目录下文件还是个文件夹就再进行递归遍历其子目录</span></span><br><span class="line">            <span class="keyword">if</span>(f.isDirectory())&#123;</span><br><span class="line">                <span class="comment">//递归</span></span><br><span class="line">                printFile(f);</span><br><span class="line">            &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">//如果该目录下文件是个文件，则打印对应的名字</span></span><br><span class="line">                System.out.println(f.getName());</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">demo2</span><span class="params">()</span>&#123;</span><br><span class="line">         <span class="comment">//从d盘下的a.txt文件拷贝到另个盘下</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">File</span> <span class="variable">file1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\a.txt&quot;</span>);<span class="comment">//这是源文件</span></span><br><span class="line">            <span class="type">long</span> flen=file1.length();</span><br><span class="line">            System.out.println(<span class="string">&quot;源文件的大小是&quot;</span>+flen+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">            <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file1);</span><br><span class="line">            <span class="type">File</span> <span class="variable">file2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;D:\\workspace\\b.txt&quot;</span>);<span class="comment">//这是复制到的地方</span></span><br><span class="line">            <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(file2);</span><br><span class="line">            <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>]; <span class="comment">//这是1兆1兆传</span></span><br><span class="line">            <span class="type">int</span> <span class="variable">len</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">            <span class="type">long</span> readSize=<span class="number">0</span>;</span><br><span class="line">            <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;<span class="comment">//-1就是最后一个结束</span></span><br><span class="line">                fos.write(bytes,<span class="number">0</span>,len); <span class="comment">//比如一个文件是1024*8+244，那么len就是244</span></span><br><span class="line">                fos.flush();<span class="comment">//强制输出，推送数据</span></span><br><span class="line">                readSize+=len;</span><br><span class="line">                <span class="keyword">if</span> (readSize== flen) &#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            System.out.println(<span class="string">&quot;读的大小&quot;</span>+readSize+<span class="string">&quot;字节&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">demo1</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\1.txt&quot;</span>);</span><br><span class="line">        <span class="type">File</span> <span class="variable">file1</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;E:\\222.txt&quot;</span>);</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file);</span><br><span class="line">            <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(file1);</span><br><span class="line">            <span class="type">BufferedInputStream</span> <span class="variable">bis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedInputStream</span>(fis);</span><br><span class="line">            <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">            <span class="keyword">while</span> (bis.read(bytes) != -<span class="number">1</span>) &#123;</span><br><span class="line">                fos.write(bytes);</span><br><span class="line">                fos.flush();</span><br><span class="line">                System.out.println(<span class="string">&quot;aaaa&quot;</span>);</span><br><span class="line">            &#125;</span><br><span class="line"></span><br><span class="line">        &#125; <span class="keyword">catch</span> (Exception e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="案例-2"><a class="markdownIt-Anchor" href="#案例-2"></a> 案例 2</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><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><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.nwa;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.omg.CORBA.PUBLIC_MEMBER;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@Date</span> 2023/8/10 -14:14</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">IoDemo</span> &#123;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">demo1</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">//public void write(int b)</span></span><br><span class="line">        <span class="comment">//public void write(byte[] b)</span></span><br><span class="line">        <span class="comment">//public void write(byte[] b,int off,int len)  //从`off`索引开始，`len`个字节</span></span><br><span class="line">        <span class="comment">//构造方法中加入true即可追加数据，否则就是清空了</span></span><br><span class="line">        <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;a.txt&quot;</span>, <span class="literal">true</span>);<span class="comment">//输出流，如果没有文件则帮忙创，有的话清空里面数据</span></span><br><span class="line">        fos.write(<span class="number">97</span>);<span class="comment">//对于内存里流向本地磁盘，所以是输出流，而且会帮忙创建文件，并写入数据,所以才会清空</span></span><br><span class="line">        fos.write((<span class="string">&quot;我要吃汉堡&quot;</span>).getBytes());</span><br><span class="line">        fos.close();</span><br><span class="line">        <span class="comment">//a我要吃汉堡    97字节对于的是小写的a，字符串这个是转字节了</span></span><br><span class="line">        <span class="type">FileWriter</span> <span class="variable">fileWriter</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileWriter</span>(<span class="string">&quot;b.txt&quot;</span>);</span><br><span class="line">        fileWriter.write(<span class="string">&quot;ss&quot;</span>);<span class="comment">//这个可以直接写入</span></span><br><span class="line">        fileWriter.close();</span><br><span class="line"></span><br><span class="line">        <span class="comment">//写出指定长度字节数组：write(byte[] b, int off, int len) ,每次写出从off索引开始，len个字节</span></span><br><span class="line">        <span class="comment">// 使用文件名称创建流对象</span></span><br><span class="line">        <span class="type">FileOutputStream</span> <span class="variable">fos2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;a2.txt&quot;</span>);</span><br><span class="line">        <span class="comment">// 字符串转换为字节数组</span></span><br><span class="line">        <span class="type">byte</span>[] b = <span class="string">&quot;abcde&quot;</span>.getBytes();</span><br><span class="line">        <span class="comment">// 写出从索引2开始，2个字节。索引2是c，两个字节，也就是cd。</span></span><br><span class="line">        fos2.write(b, <span class="number">2</span>, <span class="number">2</span>);</span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        fos2.close();</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">public</span> <span class="keyword">void</span> <span class="title function_">delTxt</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;a.txt&quot;</span>).delete();</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">public</span> <span class="keyword">void</span> <span class="title function_">arrDemo</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">// 使用文件名称创建流对象</span></span><br><span class="line">        <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;fos.txt&quot;</span>);</span><br><span class="line">        <span class="comment">// 定义字节数组</span></span><br><span class="line">        <span class="type">byte</span>[] words = &#123;<span class="number">97</span>, <span class="number">98</span>, <span class="number">99</span>, <span class="number">100</span>, <span class="number">101</span>&#125;;</span><br><span class="line">        <span class="comment">// 遍历数组</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; words.length; i++) &#123;</span><br><span class="line">            <span class="comment">// 写出一个字节</span></span><br><span class="line">            fos.write(words[i]);</span><br><span class="line">            <span class="comment">// 写出一个换行, 换行符号转成数组写出</span></span><br><span class="line">            fos.write(<span class="string">&quot;\r\n&quot;</span>.getBytes());</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        fos.close();</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">public</span> <span class="keyword">void</span> <span class="title function_">inputS</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="comment">// 使用File对象创建流对象</span></span><br><span class="line">        <span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">&quot;a2.txt&quot;</span>);<span class="comment">//这个文本中只有cd2个字符</span></span><br><span class="line">        <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(file);<span class="comment">//我把a.txt删了它就找不到了报错</span></span><br><span class="line"><span class="comment">//        int read = fis.read();</span></span><br><span class="line"><span class="comment">//        System.out.println((char)read);//不加char的话会转数字那种99---c</span></span><br><span class="line"><span class="comment">//        int read1 = fis.read();//继续读取下一个字符</span></span><br><span class="line"><span class="comment">//        System.out.println((char)read1);</span></span><br><span class="line"><span class="comment">//        int read2 = fis.read();//如果是最后一个字符，它会返回-1,通过-1知道到底了</span></span><br><span class="line"><span class="comment">//        System.out.println(read2);</span></span><br><span class="line"><span class="comment">//        fis.close();</span></span><br><span class="line">        <span class="comment">//改进版1</span></span><br><span class="line"><span class="comment">//        int b;</span></span><br><span class="line"><span class="comment">//        while ((b = fis.read()) != -1) &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println((char)b);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"><span class="comment">//        fis.close();</span></span><br><span class="line">        <span class="comment">//改进版2将文本里的值变成的abced，一次读取2个，结果出现了abcded</span></span><br><span class="line">        <span class="comment">//1 a  b  2  c  d  3e  d  因为没替换就流着了，要解决一下改进3</span></span><br><span class="line">        <span class="comment">// 定义变量，作为有效个数</span></span><br><span class="line"><span class="comment">//        int len;</span></span><br><span class="line"><span class="comment">//        // 定义字节数组，作为装字节数据的容器</span></span><br><span class="line"><span class="comment">//        byte[] b = new byte[2];</span></span><br><span class="line"><span class="comment">//        // 循环读取</span></span><br><span class="line"><span class="comment">//        while (( len= fis.read(b))!=-1) &#123;</span></span><br><span class="line"><span class="comment">//            // 每次读取后,把数组变成字符串打印</span></span><br><span class="line"><span class="comment">//            System.out.println(new String(b));</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        <span class="comment">//  fis.close();</span></span><br><span class="line"><span class="comment">//        改进3</span></span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="comment">// 定义字节数组，作为装字节数据的容器</span></span><br><span class="line">        <span class="type">byte</span>[] b = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">2</span>];</span><br><span class="line">        <span class="comment">// 循环读取</span></span><br><span class="line">        <span class="keyword">while</span> ((len = fis.read(b)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="comment">// 每次读取后,把数组变成字符串打印</span></span><br><span class="line">            System.out.println(<span class="keyword">new</span> <span class="title class_">String</span>(b, <span class="number">0</span>, len));<span class="comment">//len是每次读取有效的个数</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// 关闭资源</span></span><br><span class="line">        fis.close();</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">public</span> <span class="keyword">void</span> <span class="title function_">copyPic</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;<span class="comment">//将本地图片复制到项目下面</span></span><br><span class="line">        <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;C:\\Users\\FF\\Desktop\\6.png&quot;</span>);<span class="comment">//输入流到内存</span></span><br><span class="line">        <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;1.png&quot;</span>);<span class="comment">//内存输出到项目下面</span></span><br><span class="line">        <span class="type">byte</span>[] b = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="keyword">while</span> ((len = fis.read(b)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            fos.write(b, <span class="number">0</span>, len);</span><br><span class="line">        &#125;</span><br><span class="line">        fos.close();</span><br><span class="line">        fis.close();</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">public</span> <span class="keyword">void</span> <span class="title function_">readI</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;1.txt&quot;</span>);<span class="comment">//输入流。文本中是中文你是大聪明，正常字节流去解析会乱码</span></span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">        <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            System.out.println((<span class="type">char</span>) len);  <span class="comment">//乱码</span></span><br><span class="line">            System.out.print(<span class="keyword">new</span> <span class="title class_">String</span>(bytes, <span class="number">0</span>, len));<span class="comment">//String里自带了utf8解码所以可以。不过比较麻烦直接字符流解决</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//下面用字符流</span></span><br><span class="line">        <span class="type">FileReader</span> <span class="variable">fr</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;1.txt&quot;</span>);</span><br><span class="line">        <span class="type">int</span> len2;</span><br><span class="line">        <span class="keyword">while</span> ((len2 = fr.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">            System.out.print((<span class="type">char</span>) len2);</span><br><span class="line">        &#125;</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">public</span> <span class="keyword">void</span> <span class="title function_">copyText</span><span class="params">()</span> <span class="keyword">throws</span>  IOException&#123;</span><br><span class="line">        <span class="type">FileWriter</span> <span class="variable">fileWriter</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileWriter</span>(<span class="string">&quot;66.md&quot;</span>);</span><br><span class="line">        <span class="type">FileReader</span> <span class="variable">fileReader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;E:\\后端代码接收解析.md&quot;</span>);</span><br><span class="line">        <span class="type">char</span>[] c=<span class="keyword">new</span> <span class="title class_">char</span>[<span class="number">1024</span>];</span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="keyword">while</span> ((len = fileReader.read(c)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            fileWriter.write(c, <span class="number">0</span>, len);</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">        fileWriter.flush();<span class="comment">//清空缓冲区的数据流</span></span><br><span class="line">        fileWriter.close();</span><br><span class="line">        fileReader.close();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//下面开始测试缓存流的速度效率,1是正常，2是加入缓存</span></span><br><span class="line"></span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">Buff1</span><span class="params">()</span> <span class="keyword">throws</span>  IOException&#123;</span><br><span class="line">        <span class="type">long</span> <span class="variable">start</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line">        <span class="type">FileOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;ps2015.zip&quot;</span>);</span><br><span class="line">        <span class="type">FileInputStream</span> <span class="variable">fis</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;E:\\other\\装机必备软件\\必备软件\\ps2015.zip&quot;</span>);</span><br><span class="line">        <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            fos.write(bytes, <span class="number">0</span>, len);</span><br><span class="line">        &#125;</span><br><span class="line">        fis.close();</span><br><span class="line">        fos.close();</span><br><span class="line">        <span class="comment">// 记录结束时间</span></span><br><span class="line">        <span class="type">long</span> <span class="variable">end</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line">        System.out.println(<span class="string">&quot;普通流复制时间:&quot;</span>+(end - start)+<span class="string">&quot; 毫秒&quot;</span>);<span class="comment">//33000</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@Test</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">Buff2</span><span class="params">()</span> <span class="keyword">throws</span>  IOException&#123;</span><br><span class="line">        <span class="type">long</span> <span class="variable">start</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line">        <span class="type">BufferedOutputStream</span> <span class="variable">fos</span> <span class="operator">=</span><span class="keyword">new</span>   <span class="title class_">BufferedOutputStream</span>(<span class="keyword">new</span> <span class="title class_">FileOutputStream</span>(<span class="string">&quot;ps2015.zip&quot;</span>)) ;</span><br><span class="line">        <span class="type">BufferedInputStream</span> <span class="variable">fis</span> <span class="operator">=</span><span class="keyword">new</span> <span class="title class_">BufferedInputStream</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(<span class="string">&quot;E:\\other\\装机必备软件\\必备软件\\ps2015.zip&quot;</span>)) ;</span><br><span class="line">        <span class="type">byte</span>[] bytes = <span class="keyword">new</span> <span class="title class_">byte</span>[<span class="number">1024</span>];</span><br><span class="line">        <span class="type">int</span> len;</span><br><span class="line">        <span class="keyword">while</span> ((len = fis.read(bytes)) != -<span class="number">1</span>) &#123;</span><br><span class="line">            fos.write(bytes, <span class="number">0</span>, len);</span><br><span class="line">        &#125;</span><br><span class="line">        fis.close();</span><br><span class="line">        fos.close();</span><br><span class="line">        <span class="comment">// 记录结束时间</span></span><br><span class="line">        <span class="type">long</span> <span class="variable">end</span> <span class="operator">=</span> System.currentTimeMillis();</span><br><span class="line">        System.out.println(<span class="string">&quot;缓冲流复制时间:&quot;</span>+(end - start)+<span class="string">&quot; 毫秒&quot;</span>);<span class="comment">//缓冲流复制时间:4314 毫秒</span></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">public</span> <span class="keyword">void</span> <span class="title function_">BuffRead</span><span class="params">()</span> <span class="keyword">throws</span> IOException &#123;</span><br><span class="line">        <span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;b.txt&quot;</span>));<span class="comment">//       两个黄鹂鸣翠柳，一行白鹭上青天。 窗含西岭千秋雪，门泊东吴万里船。</span></span><br><span class="line">        System.out.println(br.readLine()); <span class="comment">// 读取一行的</span></span><br><span class="line">        String len=<span class="literal">null</span>;</span><br><span class="line">        <span class="keyword">while</span> ((len = br.readLine()) != <span class="literal">null</span>) &#123;</span><br><span class="line">            System.out.println((len));</span><br><span class="line">        &#125;</span><br><span class="line">        br.close();</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">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">()</span> <span class="keyword">throws</span> IOException&#123;</span><br><span class="line">        <span class="comment">// 定义文件路径,文件为gbk编码</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">FileName</span> <span class="operator">=</span> <span class="string">&quot;C:\\Users\\FF\\Desktop\\1.txt&quot;</span>;</span><br><span class="line">        <span class="comment">// 创建流对象,默认UTF8编码</span></span><br><span class="line">        <span class="type">InputStreamReader</span> <span class="variable">isr</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(FileName));</span><br><span class="line">        <span class="comment">// 创建流对象,指定GBK编码</span></span><br><span class="line">        <span class="type">InputStreamReader</span> <span class="variable">isr2</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(<span class="keyword">new</span> <span class="title class_">FileInputStream</span>(FileName) , <span class="string">&quot;GBK&quot;</span>);</span><br><span class="line">        <span class="comment">// 定义变量,保存字符</span></span><br><span class="line">        <span class="type">int</span> read;</span><br><span class="line">        <span class="comment">// 使用默认编码字符流读取,乱码</span></span><br><span class="line">        <span class="keyword">while</span> ((read = isr.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">            System.out.print((<span class="type">char</span>)read);</span><br><span class="line">        &#125;</span><br><span class="line">        isr.close();</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 使用指定编码字符流读取,正常解析</span></span><br><span class="line">        <span class="keyword">while</span> ((read = isr2.read()) != -<span class="number">1</span>) &#123;</span><br><span class="line">            System.out.print((<span class="type">char</span>)read); <span class="comment">//如果这个txt默认是ANSI编码就需要GBK就不会乱码，如果本身就utf就不需要编码了</span></span><br><span class="line">        &#125;</span><br><span class="line">        isr2.close();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="异常处理"><a class="markdownIt-Anchor" href="#异常处理"></a> 异常处理</h2><p>异常处理是一种重要的编程概念，用于处理程序执行过程中可能出现的错误或异常情况</p><p>必须捕获的异常，包括<code>Exception</code>及其子类，但不包括<code>RuntimeException</code>及其子类，这种类型的异常称为Checked Exception</p><p>不需要捕获的异常，包括<code>Error</code>及其子类，<code>RuntimeException</code>及其子类</p><ul><li>数值类型的格式错误------------NumberFormatException</li><li>要打开的文件不存在------------FileNotFoundException</li><li>空指针------------NullPointerException------------对某个<code>null</code>的对象调用方法或字段</li><li>数组索引越界------------ArrayIndexOutOfBoundsException</li><li>数据库表不存在</li><li>向方法传递了一个不合法或不正确的参数</li><li>无法加载某个Class------------NoClassDefFoundError</li><li>栈溢出------------StackOverflowError</li></ul><p><strong>错误：</strong> 错误不是异常，而是脱离程序员控制的问题，错误在代码中通常被忽略。例如，当栈溢出时，一个错误就发生了，它们在编译也检查不到的</p><p>所有的异常类是从 java.lang.Exception 类继承的子类。</p><p>Exception 类是 Throwable 类的子类。除了Exception类外，Throwable还有一个子类Error</p><p>异常类有两个主要的子类：IOException 类和 RuntimeException 类</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java7.png" alt="" /></p><h3 id="捕获异常"><a class="markdownIt-Anchor" href="#捕获异常"></a> 捕获异常</h3><p>如果不捕获异常，就需要抛出异常，直到有人捕获或者最高一级</p><p>使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。ctrl+alt+t</p><p>throws 是写在类那里--------------------throw 是直接在方法里面抛出</p><p>try/catch代码块中的代码称为保护代码，使用 try/catch 的语法如下：</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span></span><br><span class="line">&#123;</span><br><span class="line">   <span class="comment">// 程序代码</span></span><br><span class="line">&#125;<span class="keyword">catch</span>(ExceptionName e1)</span><br><span class="line">&#123;</span><br><span class="line">   <span class="comment">//Catch 块</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>throw</strong> 关键字用于在代码中抛出异常，而 <strong>throws</strong> 关键字用于在方法声明中指定可能会抛出的异常类型</p><p>当方法内部throws抛出指定类型的异常时，该异常会被传递给调用该方法的代码，并在该代码中处理异常。</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line"><span class="comment">//        Scanner scanner = new Scanner(System.in);</span></span><br><span class="line"><span class="comment">//        scanner = null;</span></span><br><span class="line"><span class="comment">//        scanner.next();                                               //空指针java.lang.NullPointerException</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        int[] a = new int[]&#123;1, 2&#125;;</span></span><br><span class="line"><span class="comment">//        System.out.println(a[2]);                                     //数组索引越界java.lang.ArrayIndexOutOfBoundsException</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        try &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(11 / 0);                               //0不能为除数java.lang.ArithmeticException异常</span></span><br><span class="line"><span class="comment">//        &#125; catch (ArithmeticException e) &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(&quot;捕获到了0不能为除数的异常&quot;);//这里抛出了运行时异常</span></span><br><span class="line"><span class="comment">//        &#125; catch (Exception e) &#123;//最大异常,上面捕获了下面就捕获了</span></span><br><span class="line"><span class="comment">//            throw new RuntimeException(e); //这里抛出了运行时异常</span></span><br><span class="line"><span class="comment">//        &#125; finally &#123;</span></span><br><span class="line"><span class="comment">//            System.out.println(&quot;这里必运行,一般用来关闭&quot;);</span></span><br><span class="line"><span class="comment">//        &#125;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//        checkNumber(-1);//非法参数异常IllegalArgumentException</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//  readFile(&quot;D:\\1.txt&quot;);//去d盘新建1.txt,内容随便写点</span></span><br><span class="line">            readFile(<span class="string">&quot;D:\\1.txt&quot;</span>);<span class="comment">//没找到就会有异常</span></span><br><span class="line">            System.out.println(<span class="string">&quot;找到了&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">RuntimeException</span>(e);</span><br><span class="line">        &#125;</span><br><span class="line"></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> <span class="keyword">void</span> <span class="title function_">checkNumber</span><span class="params">(<span class="type">int</span> num)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (num &lt; <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="title class_">IllegalArgumentException</span>(<span class="string">&quot;Number must be positive&quot;</span>);<span class="comment">//当代码执行到某个条件下无法继续正常执行时，可以使用 throw 关键字抛出异常，以告知调用者当前代码的执行状态</span></span><br><span class="line">        &#125;</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> <span class="keyword">void</span> <span class="title function_">readFile</span><span class="params">(String filePath)</span> <span class="keyword">throws</span> IOException &#123;<span class="comment">// 包含了文件没找到异常，如果还有其他异常,隔开继续写</span></span><br><span class="line">        <span class="type">BufferedReader</span> <span class="variable">reader</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">FileReader</span>(filePath));</span><br><span class="line">        <span class="type">String</span> <span class="variable">line</span> <span class="operator">=</span> reader.readLine();</span><br><span class="line">        <span class="keyword">while</span> (line != <span class="literal">null</span>) &#123;</span><br><span class="line">            System.out.println(line);</span><br><span class="line">            line = reader.readLine();</span><br><span class="line">        &#125;</span><br><span class="line">        reader.close();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>JDK7 之后，Java 新增的 <strong>try-with-resource</strong> 语法结构，旨在自动管理资源，确保资源在使用后能够及时关闭，避免资源泄露 。</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> (resource declaration) &#123;</span><br><span class="line">  <span class="comment">// 使用的资源</span></span><br><span class="line">&#125; <span class="keyword">catch</span> (ExceptionType e1) &#123;</span><br><span class="line">  <span class="comment">// 异常块</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        String line;</span><br><span class="line">        <span class="keyword">try</span> (<span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;test.txt&quot;</span>))) &#123;<span class="comment">//如果多个;隔开继续new</span></span><br><span class="line">            <span class="keyword">while</span> ((line = br.readLine()) != <span class="literal">null</span>) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;Line =&gt;&quot;</span> + line);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;IOException in try block =&gt;&quot;</span> + e.getMessage());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>结果：IOException in try block =&gt;test.txt (系统找不到指定的文件。)</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><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line">        String line;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;Entering try block&quot;</span>);</span><br><span class="line">            br = <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">FileReader</span>(<span class="string">&quot;test.txt&quot;</span>));</span><br><span class="line">            <span class="keyword">while</span> ((line = br.readLine()) != <span class="literal">null</span>) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;Line =&gt;&quot;</span> + line);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;IOException in try block =&gt;&quot;</span> + e.getMessage());</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;<span class="comment">//比较繁琐</span></span><br><span class="line">            System.out.println(<span class="string">&quot;Entering finally block&quot;</span>);</span><br><span class="line">            <span class="keyword">try</span> &#123;</span><br><span class="line">                <span class="keyword">if</span> (br != <span class="literal">null</span>) &#123;</span><br><span class="line">                    br.close();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">                System.out.println(<span class="string">&quot;IOException in finally block =&gt;&quot;</span> + e.getMessage());</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="全局异常处理器"><a class="markdownIt-Anchor" href="#全局异常处理器"></a> 全局异常处理器</h3><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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">@RestControllerAdvice</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RRExceptionHandler</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">Logger</span> <span class="variable">logger</span> <span class="operator">=</span> LoggerFactory.getLogger(getClass());</span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 处理自定义异常</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="meta">@ExceptionHandler(RRException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleRRException</span><span class="params">(RRException e)</span>&#123;</span><br><span class="line">        <span class="type">R</span> <span class="variable">r</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">R</span>();</span><br><span class="line">        r.put(<span class="string">&quot;code&quot;</span>, e.getCode());</span><br><span class="line">        r.put(<span class="string">&quot;msg&quot;</span>, e.getMessage());</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> r;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@ExceptionHandler(NoHandlerFoundException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handlerNoFoundException</span><span class="params">(Exception e)</span> &#123;</span><br><span class="line">        logger.error(e.getMessage(), e);</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="number">404</span>, <span class="string">&quot;路径不存在，请检查路径是否正确&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@ExceptionHandler(DuplicateKeyException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleDuplicateKeyException</span><span class="params">(DuplicateKeyException e)</span>&#123;</span><br><span class="line">        logger.error(e.getMessage(), e);</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="string">&quot;数据库中已存在该记录&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@ExceptionHandler(AuthorizationException.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleAuthorizationException</span><span class="params">(AuthorizationException e)</span>&#123;</span><br><span class="line">        logger.error(e.getMessage(), e);</span><br><span class="line">        <span class="keyword">return</span> R.error(<span class="string">&quot;没有权限，请联系管理员授权&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="meta">@ExceptionHandler(Exception.class)</span></span><br><span class="line">    <span class="keyword">public</span> R <span class="title function_">handleException</span><span class="params">(Exception e)</span>&#123;</span><br><span class="line">        logger.error(e.getMessage(), e);</span><br><span class="line">        <span class="keyword">return</span> R.error();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">RRException</span> <span class="keyword">extends</span> <span class="title class_">RuntimeException</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="type">long</span> <span class="variable">serialVersionUID</span> <span class="operator">=</span> <span class="number">1L</span>;</span><br><span class="line">    <span class="keyword">private</span> String msg;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> <span class="variable">code</span> <span class="operator">=</span> <span class="number">500</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">RRException</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">RRException</span><span class="params">(String msg, Throwable e)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg, e);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">RRException</span><span class="params">(String msg, <span class="type">int</span> code)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">RRException</span><span class="params">(String msg, <span class="type">int</span> code, Throwable e)</span> &#123;</span><br><span class="line">        <span class="built_in">super</span>(msg, e);</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> String <span class="title function_">getMsg</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> msg;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setMsg</span><span class="params">(String msg)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.msg = msg;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getCode</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> code;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setCode</span><span class="params">(<span class="type">int</span> code)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.code = code;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="api"><a class="markdownIt-Anchor" href="#api"></a> API</h2><h3 id="random常用"><a class="markdownIt-Anchor" href="#random常用"></a> Random（常用）</h3><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>(); <span class="comment">//new出这个对象</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">randomValue1</span> <span class="operator">=</span> random.nextInt(<span class="number">2</span>);  <span class="comment">//调用这个对象的方法 范围是0~1的整数</span></span><br><span class="line">        System.out.println(randomValue1);</span><br><span class="line">        <span class="type">int</span> <span class="variable">randomValue2</span> <span class="operator">=</span> random.nextInt(<span class="number">90</span>) + <span class="number">10</span>;<span class="comment">//范围是10-99的整数</span></span><br><span class="line">        System.out.println(randomValue2);</span><br><span class="line">        <span class="type">int</span> <span class="variable">randomValue3</span> <span class="operator">=</span> random.nextInt(<span class="number">1000</span>) - <span class="number">500</span>;<span class="comment">//范围-500~500,500取不到</span></span><br><span class="line">        System.out.println(randomValue3);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="scanner"><a class="markdownIt-Anchor" href="#scanner"></a> Scanner</h3><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><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="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Scanner</span> <span class="variable">scanner</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Scanner</span>(System.in);</span><br><span class="line">        System.out.println(<span class="string">&quot;请输入名称:&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">name</span> <span class="operator">=</span> scanner.nextLine();</span><br><span class="line">        System.out.println(<span class="string">&quot;请输入密码:&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">pwd</span> <span class="operator">=</span> scanner.nextLine();</span><br><span class="line">        System.out.println(name + <span class="string">&quot;--左名称右密码--&quot;</span> + pwd);</span><br><span class="line">        System.out.println(<span class="string">&quot;请输入整数n:&quot;</span>);</span><br><span class="line">        <span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">if</span> (scanner.hasNextInt()) &#123;                        <span class="comment">//加个判断防止异常，还有hasNextDouble等</span></span><br><span class="line">            i = scanner.nextInt();                         <span class="comment">// 判断输入的是否是整数</span></span><br><span class="line">            System.out.println(<span class="string">&quot;整数数据：&quot;</span> + i);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;输入的不是整数！&quot;</span>);           <span class="comment">// 输入错误的信息</span></span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;i为&quot;</span> + i);</span><br><span class="line">        scanner.close();                                   <span class="comment">//用完就关闭</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="date"><a class="markdownIt-Anchor" href="#date"></a> Date</h3><p>java.util 包提供了 Date 类来封装当前的日期和时间。 Date 类提供两个构造函数来实例化 Date 对象</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">Date</span> <span class="variable">date</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Date</span>();</span><br><span class="line">        <span class="comment">// 参考https://www.runoob.com/java/java-date-time.html</span></span><br><span class="line">        System.out.printf(<span class="string">&quot;全部日期和时间信息：%tc%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;年-月-日格式：%tF%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;月/日/年格式：%tD%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;HH:MM:SS PM格式（12时制）：%tr%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;HH:MM:SS格式（24时制）：%tT%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;HH:MM格式（24时制）：%tR%n&quot;</span>, date);</span><br><span class="line">        System.out.printf(<span class="string">&quot;%tY-%tm-%td %tH:%tM:%tS %tZ%n&quot;</span>, date, date, date, date, date, date, date);</span><br><span class="line">        System.out.println(<span class="string">&quot;-----------------------------------&quot;</span>);</span><br><span class="line">        <span class="type">Date</span> <span class="variable">dNow</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Date</span>();</span><br><span class="line">        <span class="comment">//yyyy 是完整的公元年，MM 是月份，dd 是日期HH:mm:ss 是时、分、秒 SSS毫秒</span></span><br><span class="line">        <span class="type">SimpleDateFormat</span> <span class="variable">ft</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">SimpleDateFormat</span>(<span class="string">&quot;yyyy-MM-dd hh:mm:ss:SSS&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">format</span> <span class="operator">=</span> ft.format(dNow);</span><br><span class="line">        System.out.println(<span class="string">&quot;当前时间为: &quot;</span> + format);<span class="comment">//当前时间为: 2024-06-12 04:59:08:803</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="calendar"><a class="markdownIt-Anchor" href="#calendar"></a> Calendar</h3><p>Calendar类是一个抽象类，在实际使用时实现特定的子类的对象，创建对象的过程对程序员来说是透明的，只需要使用getInstance方法创建即可</p><p>我们如何才能设置和获取日期数据的特定部分呢，比如说小时，日，或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类</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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        String months[] = &#123;</span><br><span class="line">                <span class="string">&quot;Jan&quot;</span>, <span class="string">&quot;Feb&quot;</span>, <span class="string">&quot;Mar&quot;</span>, <span class="string">&quot;Apr&quot;</span>,</span><br><span class="line">                <span class="string">&quot;May&quot;</span>, <span class="string">&quot;Jun&quot;</span>, <span class="string">&quot;Jul&quot;</span>, <span class="string">&quot;Aug&quot;</span>,</span><br><span class="line">                <span class="string">&quot;Sep&quot;</span>, <span class="string">&quot;Oct&quot;</span>, <span class="string">&quot;Nov&quot;</span>, <span class="string">&quot;Dec&quot;</span>&#125;;</span><br><span class="line"></span><br><span class="line">        <span class="type">int</span> year;</span><br><span class="line">        <span class="comment">// 初始化 Gregorian 日历</span></span><br><span class="line">        <span class="comment">// 使用当前时间和日期</span></span><br><span class="line">        <span class="comment">// 默认为本地时间和时区</span></span><br><span class="line">        <span class="type">GregorianCalendar</span> <span class="variable">gcalendar</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">GregorianCalendar</span>();</span><br><span class="line">        <span class="comment">// 显示当前时间和日期信息</span></span><br><span class="line">        System.out.print(<span class="string">&quot;Date: &quot;</span>);</span><br><span class="line">        System.out.print(months[gcalendar.get(Calendar.MONTH)]);</span><br><span class="line">        System.out.print(<span class="string">&quot; &quot;</span> + gcalendar.get(Calendar.DATE) + <span class="string">&quot; &quot;</span>);</span><br><span class="line">        System.out.println(year = gcalendar.get(Calendar.YEAR));</span><br><span class="line">        System.out.print(<span class="string">&quot;Time: &quot;</span>);</span><br><span class="line">        System.out.print(gcalendar.get(Calendar.HOUR) + <span class="string">&quot;:&quot;</span>);</span><br><span class="line">        System.out.print(gcalendar.get(Calendar.MINUTE) + <span class="string">&quot;:&quot;</span>);</span><br><span class="line">        System.out.println(gcalendar.get(Calendar.SECOND));</span><br><span class="line"></span><br><span class="line">        <span class="comment">// 测试当前年份是否为闰年</span></span><br><span class="line">        <span class="keyword">if</span> (gcalendar.isLeapYear(year)) &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;当前年份是闰年&quot;</span>);</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;当前年份不是闰年&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="math"><a class="markdownIt-Anchor" href="#math"></a> Math</h3><p>Java 的 Math 包含了用于执行基本数学运算的属性和方法，如初等指数、对数、平方根和三角函数</p><p>Math 的方法都被定义为 static 形式，通过 Math 类可以在主函数中直接调用</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span> <span class="params">(String []args)</span></span><br><span class="line">    &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;返回两个参数中的最大值：&quot;</span> + Math.max(<span class="number">1</span>, <span class="number">2</span>));</span><br><span class="line">            System.out.println(<span class="string">&quot;返回两个参数中的最小值：&quot;</span> + Math.min(<span class="number">0</span>, <span class="number">3</span>));</span><br><span class="line">            System.out.println(<span class="string">&quot;60度的正切值：&quot;</span> + Math.tan(Math.PI / <span class="number">3</span>));</span><br><span class="line">            System.out.println(<span class="string">&quot;1的反正切值： &quot;</span> + Math.atan(<span class="number">1</span>));</span><br><span class="line">            System.out.println(<span class="string">&quot;π/2的角度值：&quot;</span> + Math.toDegrees(Math.PI / <span class="number">2</span>));</span><br><span class="line">            System.out.println(Math.PI);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="string"><a class="markdownIt-Anchor" href="#string"></a> String</h3><p>String 类是不可改变的final修饰，所以你一旦创建了 String 对象，那它的值就无法改变</p><p>如果需要对字符串做很多修改，那么应该选择使用 StringBuffer &amp; StringBuilder 类</p><p>String 创建的字符串存储在公共池中，而 new 创建的字符串对象在堆上</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">s1</span> <span class="operator">=</span> <span class="string">&quot;Runoob&quot;</span>;                       <span class="comment">// String 直接创建</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s2</span> <span class="operator">=</span> <span class="string">&quot;Runoob&quot;</span>;                       <span class="comment">// String 直接创建</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s3</span> <span class="operator">=</span> s1;                             <span class="comment">// 相同引用</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s4</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;Runoob&quot;</span>);    <span class="comment">// String 对象创建</span></span><br><span class="line">        <span class="type">String</span> <span class="variable">s5</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">String</span>(<span class="string">&quot;Runoob&quot;</span>);    <span class="comment">// String 对象创建</span></span><br><span class="line">        System.out.println(s1 == s2);</span><br><span class="line">        System.out.println(s1 == s3);           <span class="comment">//s1、s2、s3都是直接创建，都指向同一个公共池里的值和对象</span></span><br><span class="line">        System.out.println(s1.equals(s3));      <span class="comment">//true    值肯定相等、并且都在公共池中</span></span><br><span class="line">        System.out.println(s4 == s5);           <span class="comment">//false   这个比较是对象引用，2个不同对象在不同堆中，值相同</span></span><br><span class="line">        System.out.println(s4.equals(s5));      <span class="comment">//true    这个比较的是值</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/java4.png" alt="" /></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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        <span class="type">String</span> <span class="variable">str</span> <span class="operator">=</span> <span class="string">&quot;Hello World&quot;</span>;</span><br><span class="line">        System.out.println(str.length());                          <span class="comment">//结果11，返回字符串的长度空格和！都算，用于不确定字符串长度时候</span></span><br><span class="line">        System.out.println(str.charAt(<span class="number">1</span>));                         <span class="comment">//e，返回字符串1的位置，从0开始，长度是str的长度-1，可用于验证码的实现</span></span><br><span class="line">        System.out.println(str.indexOf(<span class="string">&quot;h&quot;</span>));                      <span class="comment">//-1，查找这个字符，没查到则返回-1</span></span><br><span class="line">        System.out.println(str.indexOf(<span class="string">&quot;o&quot;</span>));                      <span class="comment">//4，查找第一个，并返回索引值</span></span><br><span class="line">        System.out.println(str.substring(<span class="number">4</span>));            <span class="comment">//o World,字符串的截取 从下标4开始</span></span><br><span class="line">        System.out.println(str.substring(<span class="number">4</span>, str.length() - <span class="number">2</span>));    <span class="comment">//o Wor,[4,9)参数1是开始位置 参数2是结束，左闭右开</span></span><br><span class="line">        System.out.println(str.toLowerCase());                     <span class="comment">//全部转小写</span></span><br><span class="line">        System.out.println(str.toUpperCase());                     <span class="comment">//全部转大写</span></span><br><span class="line">        String[] split = str.split(<span class="string">&quot; &quot;</span>);</span><br><span class="line">        <span class="comment">//Hello</span></span><br><span class="line">        <span class="comment">//World</span></span><br><span class="line">        <span class="comment">//根据空格切割</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; split.length; i++) &#123;</span><br><span class="line">            System.out.println(split[i]);</span><br><span class="line">        &#125;</span><br><span class="line">        System.out.println(<span class="string">&quot;-----------------------------------&quot;</span>);</span><br><span class="line">        <span class="type">String</span> <span class="variable">str1</span> <span class="operator">=</span> <span class="string">&quot;Hello1 World2&quot;</span>;</span><br><span class="line">        System.out.println(str1.indexOf(<span class="string">&quot;1&quot;</span>, <span class="number">4</span>));    <span class="comment">//5，查的必须是字符串类型，第二次参数是开始位置，这是正向搜、4，5刚好就是1返回5</span></span><br><span class="line">        System.out.println(str1.lastIndexOf(<span class="string">&quot;l&quot;</span>));            <span class="comment">//10,查找最后一个l，并返回它的索引值</span></span><br><span class="line">        System.out.println(str1.lastIndexOf(<span class="string">&quot;l&quot;</span>, <span class="number">11</span>));<span class="comment">//10,11是d，然后开始反向搜到l直接返回索引</span></span><br><span class="line">        System.out.println(<span class="string">&quot;-----------------------------------&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.compareTo(<span class="string">&quot;abcde&quot;</span>));              <span class="comment">//-2，返回整型，比较对应字符的大小(ASCII码顺序)</span></span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.compareTo(<span class="string">&quot;abc&quot;</span>));                <span class="comment">//0，相同返回0</span></span><br><span class="line">        System.out.println(<span class="string">&quot;12789&quot;</span>.compareTo(<span class="string">&quot;123&quot;</span>));              <span class="comment">//4,回字符串长度,比较7和3返回4</span></span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.equals(<span class="string">&quot;a&quot;</span>));                     <span class="comment">//false，判断2个字符串是否相等，需要完全一样</span></span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.equals(<span class="string">&quot;abc&quot;</span>));                   <span class="comment">//True</span></span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.equalsIgnoreCase(<span class="string">&quot;ABC&quot;</span>));   <span class="comment">//true,忽略大小写</span></span><br><span class="line">        System.out.println(<span class="string">&quot;abc&quot;</span>.concat(<span class="string">&quot;derfg&quot;</span>));                   <span class="comment">//abcderfg 字符串拼接，用+也可以</span></span><br><span class="line">        System.out.println(<span class="string">&quot;nnnwa&quot;</span>.replace(<span class="string">&quot;n&quot;</span>, <span class="string">&quot;g&quot;</span>));  <span class="comment">//gggwa,替换所有n，第一个参数是需要被替换的，第二个是替换的</span></span><br><span class="line">        System.out.printf(<span class="string">&quot;浮点型变量的值为 &quot;</span> +</span><br><span class="line">                <span class="string">&quot;%f, 整型变量的值为 &quot;</span> +</span><br><span class="line">                <span class="string">&quot; %d, 字符串变量的值为 &quot;</span> +</span><br><span class="line">                <span class="string">&quot;is %s&quot;</span>, <span class="number">1.12f</span>, <span class="number">16</span>, <span class="string">&quot;LuckyNwa&quot;</span>);</span><br><span class="line">        System.out.println(<span class="string">&quot;nwa&quot;</span>.contains(<span class="string">&quot;nw&quot;</span>));                        <span class="comment">//true，包含它返回布尔值，顺序有影响</span></span><br><span class="line">        System.out.println(<span class="string">&quot;nwa&quot;</span>.endsWith(<span class="string">&quot;a&quot;</span>));                         <span class="comment">//true，包含它返回布尔值，测试是否以字符a结尾</span></span><br><span class="line">        System.out.println(<span class="string">&quot;  hello world  &quot;</span>.trim());                    <span class="comment">//hello world,去除前后空格，不去中间</span></span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><a href="https://www.runoob.com/java/java-string.html">https://www.runoob.com/java/java-string.html</a> 参考这</p><p><strong>总结</strong></p><p>length方法使用地方特别多，比如数组遍历时候就需要，字符串同，不知道长度可以直接用这方法获取</p><p>s=“aascsaxaca”;它的下标就是0到s.length()-1</p><p>indexOf可以用来查询是否存在，返回值为-1则不存在，也可以查询这个字符串第一次出现的地方</p><p>charAt方法可用于验证码的实现，把验证码需要的字符串存在一个变量里，通过charAt(new Random().nextInt(codeBox.length()))来获取随机字符</p><p>trim方法去首尾空格，用于登录时候输入有空格的把空格直接去掉，用的范围也挺广 以及split用的很多,可以根据空格，-等分割</p><p>isEmpty判断是否为空</p><h3 id="stringbuffer-和-stringbuilder"><a class="markdownIt-Anchor" href="#stringbuffer-和-stringbuilder"></a> StringBuffer 和 StringBuilder</h3><p>和 String 类不同的是，StringBuffer 和 StringBuilder 类的对象能够被多次的修改，并且不产生新的未使用对象</p><p>StringBuilder 类在 Java 5 中被提出，StringBuilder不是线程安全，StringBuffer 线程安全</p><p>由于 StringBuilder 相较于 StringBuffer 有速度优势，所以多数情况下建议使用 StringBuilder 类</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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Demo1</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> &#123;</span><br><span class="line">        StringBuilder sb;</span><br><span class="line">        sb = <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(<span class="number">10</span>);</span><br><span class="line">        sb.append(<span class="string">&quot;Runoob..&quot;</span>);</span><br><span class="line">        System.out.println(sb);</span><br><span class="line">        sb.append(<span class="string">&quot;!&quot;</span>);</span><br><span class="line">        System.out.println(sb);</span><br><span class="line">        sb.insert(<span class="number">8</span>, <span class="string">&quot;Java&quot;</span>);</span><br><span class="line">        System.out.println(sb);</span><br><span class="line">        sb.delete(<span class="number">5</span>, <span class="number">8</span>);</span><br><span class="line">        System.out.println(sb);</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">luckyNwa</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>(<span class="string">&quot;LuckyNwa&quot;</span>);</span><br><span class="line">        luckyNwa.append(<span class="string">&quot;你好啊&quot;</span>);</span><br><span class="line">        System.out.println(luckyNwa);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><img src="https://cloud.luckynwa.top/profile/mdS/java5.png" alt="" /></p><h2 id="其他"><a class="markdownIt-Anchor" href="#其他"></a> 其他</h2><h3 id="转义序列"><a class="markdownIt-Anchor" href="#转义序列"></a> 转义序列</h3><p>前面有反斜杠（\）的字符代表转义字符，它对编译器来说是有特殊含义的</p><p>列表展示了Java的转义序列：</p><p><img src="https://cloud.luckynwa.top/profile/mdS/java3.png" alt="" /></p>]]></content>
    
    
    <summary type="html">绳锯木断，水滴石穿</summary>
    
    
    
    <category term="后端" scheme="https://luckynwa.top/categories/%E5%90%8E%E7%AB%AF/"/>
    
    
    <category term="Java" scheme="https://luckynwa.top/tags/Java/"/>
    
  </entry>
  
  <entry>
    <title>Java 环境</title>
    <link href="https://luckynwa.top/posts/tool4/"/>
    <id>https://luckynwa.top/posts/tool4/</id>
    <published>2023-07-22T02:21:57.000Z</published>
    <updated>2026-07-07T16:19:34.062Z</updated>
    
    <content type="html"><![CDATA[<h1 id="jdk-8"><a class="markdownIt-Anchor" href="#jdk-8"></a> JDK 8</h1><h2 id="安装与环境变量"><a class="markdownIt-Anchor" href="#安装与环境变量"></a> 安装与环境变量</h2><ol><li>先装 JDK，默认安装即可</li><li>配置环境变量：<code>此电脑</code> 右键 → 属性 → 高级系统设置 → 环境变量</li></ol><p><strong>新建 <code>JAVA_HOME</code>：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">C:\Program Files\Java\jdk1.8.0_271</span><br></pre></td></tr></table></figure><p><strong>新建 <code>CLASSPATH</code>：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar</span><br></pre></td></tr></table></figure><p><strong>编辑 <code>Path</code>，新增：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%JAVA_HOME%\bin</span><br></pre></td></tr></table></figure><h2 id="验证"><a class="markdownIt-Anchor" href="#验证"></a> 验证</h2><figure class="highlight shell"><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">java -version        # java version &quot;1.8.0_271&quot;</span><br><span class="line">javac</span><br></pre></td></tr></table></figure><h1 id="jdk-11"><a class="markdownIt-Anchor" href="#jdk-11"></a> JDK 11</h1><h2 id="安装"><a class="markdownIt-Anchor" href="#安装"></a> 安装</h2><p>直接安装 <code>jdk-11.0.22_windows-x64_bin.exe</code>，默认装即可。如果是 zip 也解压到 <code>C:\Program Files\Java</code> 下。</p><p>此时有 3 个文件夹：<code>jdk-11</code>、<code>jdk1.8.0_271</code>、<code>jre1.8.0_271</code></p><h2 id="环境变量配置"><a class="markdownIt-Anchor" href="#环境变量配置"></a> 环境变量配置</h2><p><code>此电脑</code> → 属性 → 高级系统设置 → 环境变量</p><p><strong>新建变量（严格按下面）：</strong></p><figure class="highlight plaintext"><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">JAVA11_HOME    C:\Program Files\Java\jdk-11</span><br><span class="line">JAVA8_HOME     C:\Program Files\Java\jdk1.8.0_271</span><br></pre></td></tr></table></figure><p><strong>修改 <code>JAVA_HOME</code> 变量值：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%JAVA11_HOME%      # 想要哪个改哪个</span><br></pre></td></tr></table></figure><p><strong><code>CLASSPATH</code> 没有则新建：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib;</span><br></pre></td></tr></table></figure><p><strong>编辑 <code>Path</code>，将 <code>%JAVA_HOME%\bin</code> 移动到最前面。</strong></p><h2 id="验证-2"><a class="markdownIt-Anchor" href="#验证-2"></a> 验证</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -version</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">读书破万卷，下笔如有神</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Doc" scheme="https://luckynwa.top/tags/Doc/"/>
    
  </entry>
  
  <entry>
    <title>JMeter</title>
    <link href="https://luckynwa.top/posts/tool3/"/>
    <id>https://luckynwa.top/posts/tool3/</id>
    <published>2023-07-15T01:37:29.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a class="markdownIt-Anchor" href="#简介"></a> 简介</h1><p>Apache JMeter 是一款开源的压力测试工具，主要用于对 Web 应用、API 接口进行性能测试和负载测试。通过模拟大量并发用户访问，可以测量系统的吞吐量、响应时间、错误率等关键指标。</p><h1 id="使用步骤"><a class="markdownIt-Anchor" href="#使用步骤"></a> 使用步骤</h1><ol><li>进入 <code>bin</code> → 点击 <code>jmeter.bat</code>（本版本自带汉化）</li><li>测试计划右键 → 添加线程 → 线程组</li><li>线程组右键 → 取样器 → HTTP 请求<ul><li>协议：<code>http</code> 或 <code>https</code></li><li>IP：<code>localhost</code> 或其他</li><li>端口：对应端口</li><li>路径：接口路径</li></ul></li><li>测试计划右键 → 添加 → 监听器 → 查看结果树 / 汇总报告</li></ol><h1 id="详细步骤"><a class="markdownIt-Anchor" href="#详细步骤"></a> 详细步骤</h1><ol><li>添加线程组：测试计划 → 右键 → Add → Thread → 线程组</li><li>线程数 1000，Ramp-Up 启动时间 10s，循环 10 = 访问 1w 次</li><li>右键线程组 → 添加 Sampler（取样器）→ HTTP 请求</li><li>填写协议（http）、IP、端口、路径、编码 UTF-8，有参数填参数</li><li>右键 HTTP 请求 → 添加监听器 → 查看结果树和汇总报告，<code>ThroughPut</code> 是吞吐量（每秒请求次数）</li><li>点击绿色运行按钮</li></ol>]]></content>
    
    
    <summary type="html">少年辛苦终身事，莫向光阴惰寸功</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>IDEA 配置</title>
    <link href="https://luckynwa.top/posts/tool2/"/>
    <id>https://luckynwa.top/posts/tool2/</id>
    <published>2023-07-07T21:41:22.000Z</published>
    <updated>2026-07-07T16:19:34.175Z</updated>
    
    <content type="html"><![CDATA[<h1 id="安装与激活"><a class="markdownIt-Anchor" href="#安装与激活"></a> 安装与激活</h1><p><strong>安装路径：</strong> <code>D:\soft\IntelliJ IDEA 2023.2.1</code></p><ol><li>将 <code>jetbra</code> 里面的文件复制到安装目录下</li><li>正常安装 IDEA，选择同样的目录</li><li>勾选必要选项，文件夹右键那个记得勾，<strong>别重启</strong></li><li>右键管理员运行 <code>D:\soft\IntelliJ IDEA 2023.2.1\jetbra\scripts\install-all-users.vbs</code>，出现 <code>done</code> 即成功</li><li>验证环境变量：</li></ol><figure class="highlight shell"><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">echo %IDEA_VM_OPTIONS%</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">结果：D:\soft\IntelliJ IDEA 2023.2.1\jetbra\vmoptions\idea.vmoptions</span></span><br></pre></td></tr></table></figure><ol start="6"><li>打开 IDEA，选择 <strong>Activation code</strong> 激活</li></ol><details><summary>激活码（点击展开）</summary><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">6G5NXCPJZB-eyJsaWNlbnNlSWQiOiI2RzVOWENQSlpCIiwibGljZW5zZWVOYW1lIjoic2lnbnVwIHNjb290ZXIiLCJhc3NpZ25lZU5hbWUiOiIiLCJhc3NpZ25lZUVtYWlsIjoiIiwibGljZW5zZVJlc3RyaWN0aW9uIjoiIiwiY2hlY2tDb25jdXJyZW50VXNlIjpmYWxzZSwicHJvZHVjdHMiOlt7ImNvZGUiOiJQU0kiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBEQiIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiSUkiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOmZhbHNlfSx7ImNvZGUiOiJQUEMiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBHTyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFNXIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQV1MiLCJmYWxsYmFja0RhdGUiOiIyMDI1LTA4LTAxIiwicGFpZFVwVG8iOiIyMDI1LTA4LTAxIiwiZXh0ZW5kZWQiOnRydWV9LHsiY29kZSI6IlBQUyIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX0seyJjb2RlIjoiUFJCIiwiZmFsbGJhY2tEYXRlIjoiMjAyNS0wOC0wMSIsInBhaWRVcFRvIjoiMjAyNS0wOC0wMSIsImV4dGVuZGVkIjp0cnVlfSx7ImNvZGUiOiJQQ1dNUCIsImZhbGxiYWNrRGF0ZSI6IjIwMjUtMDgtMDEiLCJwYWlkVXBUbyI6IjIwMjUtMDgtMDEiLCJleHRlbmRlZCI6dHJ1ZX1dLCJtZXRhZGF0YSI6IjAxMjAyMjA5MDJQU0FOMDAwMDA1IiwiaGFzaCI6IlRSSUFMOi0xMDc4MzkwNTY4IiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlLCJpc0F1dG9Qcm9sb25nYXRlZCI6ZmFsc2V9-SnRVlQQR1/9nxZ2AXsQ0seYwU5OjaiUMXrnQIIdNRvykzqQ0Q+vjXlmO7iAUwhwlsyfoMrLuvmLYwoD7fV8Mpz9Gs2gsTR8DfSHuAdvZlFENlIuFoIqyO8BneM9paD0yLxiqxy/WWuOqW6c1v9ubbfdT6z9UnzSUjPKlsjXfq9J2gcDALrv9E0RPTOZqKfnsg7PF0wNQ0/d00dy1k3zI+zJyTRpDxkCaGgijlY/LZ/wqd/kRfcbQuRzdJ/JXa3nj26rACqykKXaBH5thuvkTyySOpZwZMJVJyW7B7ro/hkFCljZug3K+bTw5VwySzJtDcQ9tDYuu0zSAeXrcv2qrOg==-MIIETDCCAjSgAwIBAgIBDTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTIwMTAxOTA5MDU1M1oXDTIyMTAyMTA5MDU1M1owHzEdMBsGA1UEAwwUcHJvZDJ5LWZyb20tMjAyMDEwMTkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCUlaUFc1wf+CfY9wzFWEL2euKQ5nswqb57V8QZG7d7RoR6rwYUIXseTOAFq210oMEe++LCjzKDuqwDfsyhgDNTgZBPAaC4vUU2oy+XR+Fq8nBixWIsH668HeOnRK6RRhsr0rJzRB95aZ3EAPzBuQ2qPaNGm17pAX0Rd6MPRgjp75IWwI9eA6aMEdPQEVN7uyOtM5zSsjoj79Lbu1fjShOnQZuJcsV8tqnayeFkNzv2LTOlofU/Tbx502Ro073gGjoeRzNvrynAP03pL486P3KCAyiNPhDs2z8/COMrxRlZW5mfzo0xsK0dQGNH3UoG/9RVwHG4eS8LFpMTR9oetHZBAgMBAAGjgZkwgZYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUJNoRIpb1hUHAk0foMSNM9MCEAv8wSAYDVR0jBEEwP4AUo562SGdCEjZBvW3gubSgUouX8bOhHKQaMBgxFjAUBgNVBAMMDUpldFByb2ZpbGUgQ0GCCQDSbLGDsoN54TATBgNVHSUEDDAKBggrBgEFBQcDATALBgNVHQ8EBAMCBaAwDQYJKoZIhvcNAQELBQADggIBABqRoNGxAQct9dQUFK8xqhiZaYPd30TlmCmSAaGJ0eBpvkVeqA2jGYhAQRqFiAlFC63JKvWvRZO1iRuWCEfUMkdqQ9VQPXziE/BlsOIgrL6RlJfuFcEZ8TK3syIfIGQZNCxYhLLUuet2HE6LJYPQ5c0jH4kDooRpcVZ4rBxNwddpctUO2te9UU5/FjhioZQsPvd92qOTsV+8Cyl2fvNhNKD1Uu9ff5AkVIQn4JU23ozdB/R5oUlebwaTE6WZNBs+TA/qPj+5/we9NH71WRB0hqUoLI2AKKyiPw++FtN4Su1vsdDlrAzDj9ILjpjJKA1ImuVcG329/WTYIKysZ1CWK3zATg9BeCUPAV1pQy8ToXOq+RSYen6winZ2OO93eyHv2Iw5kbn1dqfBw1BuTE29V2FJKicJSu8iEOpfoafwJISXmz1wnnWL3V/0NxTulfWsXugOoLfv0ZIBP1xH9kmf22jjQ2JiHhQZP7ZDsreRrOeIQ/c4yR8IQvMLfC0WKQqrHu5ZzXTH4NO3CwGWSlTY74kE91zXB5mwWAx1jig+UXYc2w4RkVhy0//lOmVya/PEepuuTTI4+UJwC7qbVlh5zfhj8oTNUXgN0AOc+Q0/WFPl1aw5VV/VrO8FCoB15lFVlpKaQ1Yh+DVU8ke+rt9Th0BCHXe0uZOEmH0nOnH/0onD</span><br></pre></td></tr></table></figure></details><h1 id="插件配置"><a class="markdownIt-Anchor" href="#插件配置"></a> 插件配置</h1><p>新版自带很多插件，看着关闭，留下数据库、Maven、Spring 相关等。</p><ul><li><strong>UI 风格：</strong> UI Options 里第一列全部勾选，第二列勾选前和后</li></ul><h1 id="保存并自动格式化代码"><a class="markdownIt-Anchor" href="#保存并自动格式化代码"></a> 保存并自动格式化代码</h1><p><code>Settings</code> → <code>Save Actions</code> → 勾选 <strong>Reformat code</strong> 和 <strong>Optimize imports</strong></p><h1 id="自动编译与热部署"><a class="markdownIt-Anchor" href="#自动编译与热部署"></a> 自动编译与热部署</h1><ol><li><code>Settings</code> → <code>Compiler</code> → 勾选图中 2 个选项</li><li>勾选 <code>Allow auto-make to start even if developed application is currently running</code></li><li>2023 版 IDEA 再引入依赖即可热部署：</li></ol><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></pre></td><td class="code"><pre><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-devtools<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>runtime<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>切换到别的软件，就开始热部署了 🙂</p><p><img src="http://imgs.luckynwa.top/profile/mdS/2fc4d2d3139d44cd9e9d4dbed7477d55.png" alt="热部署配置" /></p><h1 id="设置头文件自动生成"><a class="markdownIt-Anchor" href="#设置头文件自动生成"></a> 设置头文件自动生成</h1><p><code>Settings</code> → <code>Editor</code> → <code>File and Code Templates</code> → 配置完新建一个类就有效果了：</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></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> <span class="doctag">@Author</span> Lucky友人a</span></span><br><span class="line"><span class="comment"> <span class="doctag">@Date</span> $&#123;DATE&#125; -$&#123;TIME&#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure><p><img src="http://imgs.luckynwa.top/profile/mdS/beb3718241de46edb65d6318bb41cc8d.png" alt="头文件配置" /></p><h1 id="滚轮设置编辑区字体大小"><a class="markdownIt-Anchor" href="#滚轮设置编辑区字体大小"></a> 滚轮设置编辑区字体大小</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → 勾选 <code>Change font size with Ctrl+Mouse Wheel</code></p><blockquote><p>⚠️ 临时生效，第二次进入会恢复默认</p></blockquote><p><img src="http://imgs.luckynwa.top/profile/mdS/716b4cb25e7846b183789a8fe9929f37.png" alt="滚轮字体设置" /></p><h1 id="自动导包"><a class="markdownIt-Anchor" href="#自动导包"></a> 自动导包</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → <code>Auto Import</code></p><ul><li>上面：自动导包</li><li>下面：自动删除无用包</li></ul><p><img src="http://imgs.luckynwa.top/profile/mdS/b6b87225fce343e581a931e8598e7fa8.png" alt="自动导包" /></p><h1 id="显示行号和方法的分隔符"><a class="markdownIt-Anchor" href="#显示行号和方法的分隔符"></a> 显示行号和方法的分隔符</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → <code>Appearance</code></p><p><img src="http://imgs.luckynwa.top/profile/mdS/901142a1dfc5430eb280aff4f1bd0ca7.png" alt="行号设置" /></p><h1 id="设置鼠标悬浮提示"><a class="markdownIt-Anchor" href="#设置鼠标悬浮提示"></a> 设置鼠标悬浮提示</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → <code>Code Completion</code> → 勾选显示标题功能</p><p><img src="http://imgs.luckynwa.top/profile/mdS/0fe541133367443db67f435fa38b4f09.png" alt="悬浮提示" /></p><h1 id="忽略字母大小写的提示"><a class="markdownIt-Anchor" href="#忽略字母大小写的提示"></a> 忽略字母大小写的提示</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → <code>Code Completion</code> → 取消勾选 <code>Match case</code></p><p><img src="http://imgs.luckynwa.top/profile/mdS/e6c08d5733cd4b65ab0678fdebf07a07.png" alt="忽略大小写" /></p><h1 id="设置编码"><a class="markdownIt-Anchor" href="#设置编码"></a> 设置编码</h1><p><code>Settings</code> → <code>Editor</code> → <code>File Encodings</code> → 全部设置为 <code>UTF-8</code>，影响 i18n 里中文，必配，BOM 勾选也记得。</p><p><img src="http://imgs.luckynwa.top/profile/mdS/63b5b37ebdec4731b6c8378569275851.png" alt="编码设置" /></p><h1 id="取消-tab-页单行显示"><a class="markdownIt-Anchor" href="#取消-tab-页单行显示"></a> 取消 Tab 页单行显示</h1><p><code>Settings</code> → <code>Editor</code> → <code>General</code> → <code>Editor Tabs</code></p><p>2023 版 IDEA 选择单选 <strong>Multiple rows</strong></p><p><img src="http://imgs.luckynwa.top/profile/mdS/5fe98091ba9246ee8f48156bfcc16687.png" alt="Tab设置" /></p><h1 id="设置字体-字体大小-行间距"><a class="markdownIt-Anchor" href="#设置字体-字体大小-行间距"></a> 设置字体、字体大小、行间距</h1><p><code>Settings</code> → <code>Editor</code> → <code>Font</code></p><p><img src="http://imgs.luckynwa.top/profile/mdS/85de093acf034b0da65581b18c330e06.png" alt="字体设置" /></p><h1 id="推荐插件"><a class="markdownIt-Anchor" href="#推荐插件"></a> 推荐插件</h1><table><thead><tr><th>插件名</th><th>说明</th></tr></thead><tbody><tr><td><strong>Lombok</strong></td><td><code>@Data</code> 注解插件</td></tr><tr><td><strong>MybatisX</strong></td><td>快速定位实现类以及方法在 XML 的位置</td></tr><tr><td><strong>Rainbow Brackets</strong></td><td>不同颜色 <code>&#123;&#125;</code>，设置里搜 <code>disable when</code> 取消掉 1000 那个；Round Brackets 中 5 颜色：<code>E8BA36</code> <code>46A97B</code> <code>E594D2</code> <code>8F8BFF</code> <code>A938D7</code></td></tr><tr><td><strong>Dark Purple Theme</strong></td><td>主题，<code>Appearance</code> + <code>Color Scheme</code> 里导入 <code>luckyColor.icls</code> 样式；不满意在 <code>Language Defaults</code> 中修改，其中 <code>Semantic Highlighting</code> 是参数颜色</td></tr><tr><td><strong>Translation</strong></td><td>3.5.6 翻译，选择百度，5w 字符内免费</td></tr><tr><td><strong>GenerateAllSetter</strong></td><td><code>A a = new A();</code> 右键 <code>a</code> → <code>Alt+Enter</code> → 选 set</td></tr><tr><td><strong>Mybatis Log Free</strong></td><td>恢复 MyBatis SQL 日志到可执行 SQL，Tools 里打开；需开启日志：<code>log-impl: org.apache.ibatis.logging.stdout.StdOutImpl</code></td></tr><tr><td><strong>JUnit4 Parallel Runner</strong></td><td>不然测试类不能运行</td></tr><tr><td><strong>Compiler</strong></td><td>相关插件记得开</td></tr><tr><td><strong>CamelCase</strong></td><td><code>Shift+Alt+U</code> 大小写转换，支持驼峰与下划线</td></tr><tr><td><strong>Get Emoji / Yet Another Emoji Support</strong></td><td>MD 文件输入 <code>:</code> + 图标名，emoji 参考 <a href="https://gitmoji.dev/">https://gitmoji.dev/</a></td></tr><tr><td><strong>Background Image Plus</strong></td><td>给代码加背景图，<code>Appearance</code> → <code>Background Image</code> → <code>Opacity</code> 透明度</td></tr><tr><td><strong>Easy Javadoc</strong></td><td>生成代码注释，<code>Ctrl+/</code>，设置快捷键 <code>Alt+/</code></td></tr><tr><td><strong>SonarLint</strong></td><td>代码规范检查</td></tr><tr><td><strong>TONGYI Lingma</strong></td><td>代码 AI 助手，批量注释，提示功能 Tab 键输入</td></tr><tr><td><strong>Chinese</strong></td><td>中文包必装</td></tr><tr><td><strong>Nyan Progress Bar</strong></td><td>进度条变成彩虹猫</td></tr><tr><td><strong>Grep Console</strong></td><td>改变控制台日志颜色</td></tr><tr><td><strong>Batch Scripts Support</strong></td><td><code>.bat</code> 脚本支持</td></tr></tbody></table><blockquote><p>💡 禁用 GitHub 插件只留一个 Git 插件；插件网络要是用代理记得开启。</p></blockquote><h1 id="新项目设置"><a class="markdownIt-Anchor" href="#新项目设置"></a> 新项目设置</h1><p><code>File</code> → <code>New Projects Setup</code> → <code>Settings for New Projects</code></p><ul><li>Maven 路径配置一下</li><li>保存自动格式化配置</li></ul>]]></content>
    
    
    <summary type="html">仰天大笑出门去，我辈岂是蓬蒿人</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Tool" scheme="https://luckynwa.top/tags/Tool/"/>
    
  </entry>
  
  <entry>
    <title>Git 实战笔记</title>
    <link href="https://luckynwa.top/posts/tool1/"/>
    <id>https://luckynwa.top/posts/tool1/</id>
    <published>2023-06-30T23:30:33.000Z</published>
    <updated>2026-07-07T16:19:34.352Z</updated>
    
    <content type="html"><![CDATA[<h1 id="git-基础概念"><a class="markdownIt-Anchor" href="#git-基础概念"></a> Git 基础概念</h1><h2 id="工作区域"><a class="markdownIt-Anchor" href="#工作区域"></a> 工作区域</h2><p>Git 管理的三个核心区域（<code>.git</code> 文件夹内是暂存区和仓库）：</p><figure class="highlight plaintext"><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">工作区  ──git add──▶  暂存区  ──git commit──▶  Git 仓库</span><br><span class="line">(编写代码)            (临时存放)                (最终提交)</span><br></pre></td></tr></table></figure><table><thead><tr><th>区域</th><th>说明</th></tr></thead><tbody><tr><td><strong>工作区</strong></td><td>项目文件夹，日常编写代码的地方</td></tr><tr><td><strong>暂存区</strong></td><td>已完成工作的临时存放区域，等待提交</td></tr><tr><td><strong>Git 仓库</strong></td><td>最终提交的区域，记录所有版本历史</td></tr></tbody></table><h2 id="文件状态"><a class="markdownIt-Anchor" href="#文件状态"></a> 文件状态</h2><p>工作区文件的四种状态：</p><table><thead><tr><th>状态</th><th>说明</th><th>标识</th></tr></thead><tbody><tr><td>未跟踪</td><td>未被 Git 管理</td><td>红色 <code>??</code></td></tr><tr><td>未修改</td><td>已被管理，无改动</td><td>-</td></tr><tr><td>已修改</td><td>工作区和仓库不一样</td><td>红色 <code>M</code>，<code>git add</code> 后变绿色 <code>M</code></td></tr><tr><td>已暂存</td><td>已执行 <code>git add</code></td><td>绿色 <code>M</code></td></tr></tbody></table><h1 id="环境配置"><a class="markdownIt-Anchor" href="#环境配置"></a> 环境配置</h1><h2 id="基础配置"><a class="markdownIt-Anchor" href="#基础配置"></a> 基础配置</h2><p>安装 Git 后，桌面空白处右键打开 Git Bash：</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 class="meta prompt_"># </span><span class="language-bash">设置默认主分支为 main（默认是 master）</span></span><br><span class="line">git config --global init.defaultBranch main</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">设置用户信息（按需选择）</span></span><br><span class="line">git config --global user.name &quot;luckyNwa&quot;</span><br><span class="line">git config --global user.email &quot;1656213092@qq.com&quot;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">查看配置</span></span><br><span class="line">git config user.name</span><br><span class="line">git config user.email</span><br></pre></td></tr></table></figure><h2 id="ssh-配置"><a class="markdownIt-Anchor" href="#ssh-配置"></a> SSH 配置</h2><p>SSH 方式无需每次输入密码，推荐使用。</p><h3 id="步骤一生成密钥"><a class="markdownIt-Anchor" href="#步骤一生成密钥"></a> 步骤一：生成密钥</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ssh-keygen -t rsa -b 4096 -C &quot;你的邮箱@qq.com&quot;</span><br><span class="line">ssh-keygen -t rsa -b 4096 -C &quot;1656213092@qq.com&quot;</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">连续回车 3 次，密钥生成在 C:\Users\Administrator\.ssh 目录，打开 id_rsa.pub 复制里面内容</span></span><br></pre></td></tr></table></figure><h3 id="步骤二添加公钥到-github"><a class="markdownIt-Anchor" href="#步骤二添加公钥到-github"></a> 步骤二：添加公钥到 GitHub</h3><ol><li>登录 GitHub → 头像 → Settings → SSH and GPG keys → New SSH key</li><li>粘贴公钥，Title 随意填写</li></ol><h3 id="步骤三验证连接"><a class="markdownIt-Anchor" href="#步骤三验证连接"></a> 步骤三：验证连接</h3><figure class="highlight shell"><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">ssh -T git@github.com</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">输入 <span class="built_in">yes</span>，看到欢迎信息即成功</span></span><br></pre></td></tr></table></figure><h3 id="同时配置-gitee-和-github"><a class="markdownIt-Anchor" href="#同时配置-gitee-和-github"></a> 同时配置 Gitee 和 GitHub</h3><p>删除 <code>.ssh</code> 目录后重新生成密钥，然后：</p><ol><li><p>将 <code>id_rsa.pub</code> 内容分别添加到：</p><ul><li>Gitee: <a href="https://gitee.com/profile/sshkeys">https://gitee.com/profile/sshkeys</a></li><li>GitHub: <a href="https://github.com/settings/keys">https://github.com/settings/keys</a></li></ul></li><li><p>验证两个平台：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ssh -T git@gitee.com</span><br><span class="line">ssh -T git@github.com</span><br></pre></td></tr></table></figure></li></ol><h1 id="常用指令"><a class="markdownIt-Anchor" href="#常用指令"></a> 常用指令</h1><h2 id="初始化项目"><a class="markdownIt-Anchor" href="#初始化项目"></a> 初始化项目</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git init                              # 初始化 Git 仓库</span><br><span class="line">git remote add origin git@github.com:用户名/仓库名.git  # 关联远程仓库</span><br><span class="line">git push -u origin main               # 首次推送并关联分支</span><br></pre></td></tr></table></figure><h2 id="文件操作"><a class="markdownIt-Anchor" href="#文件操作"></a> 文件操作</h2><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></pre></td><td class="code"><pre><span class="line">git status                            # 查看状态</span><br><span class="line">git status -s                         # 简洁模式查看状态</span><br><span class="line">git add 文件名.后缀                    # 添加指定文件到暂存区</span><br><span class="line">git add .                             # 添加所有文件到暂存区</span><br><span class="line">git commit -m &quot;备注信息&quot;               # 提交到本地仓库</span><br><span class="line">git commit -a -m &quot;备注信息&quot;            # 跳过暂存区，直接提交（已跟踪文件）</span><br></pre></td></tr></table></figure><h2 id="文件删除"><a class="markdownIt-Anchor" href="#文件删除"></a> 文件删除</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git rm 文件名                          # 从仓库和工作区同时删除</span><br><span class="line">git rm --cached 文件名                 # 只从仓库移除，保留工作区文件</span><br><span class="line">git rm --cached components.d.ts       # 移除已追踪的文件（配合 .gitignore 使用）</span><br></pre></td></tr></table></figure><h2 id="分支管理"><a class="markdownIt-Anchor" href="#分支管理"></a> 分支管理</h2><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></pre></td><td class="code"><pre><span class="line">git branch                            # 查看所有分支（* 标记当前分支）</span><br><span class="line">git branch 新分支名                    # 创建新分支（基于当前分支）</span><br><span class="line">git checkout 分支名                    # 切换分支</span><br><span class="line">git checkout -b 分支名                 # 创建并切换到新分支</span><br><span class="line">git checkout master                   # 切换到主分支</span><br><span class="line">git merge 分支名                       # 合并指定分支到当前分支</span><br><span class="line">git branch -d 分支名                   # 删除本地分支（需先切换到其他分支）</span><br></pre></td></tr></table></figure><h2 id="远程仓库"><a class="markdownIt-Anchor" href="#远程仓库"></a> 远程仓库</h2><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></pre></td><td class="code"><pre><span class="line">git remote show origin                # 查看远程仓库信息</span><br><span class="line">git remote update origin --prune      # 同步远程分支（删除已不存在的分支）</span><br><span class="line">git clone 地址                         # 克隆仓库</span><br><span class="line">git clone -b 分支名 地址               # 克隆指定分支</span><br><span class="line">git pull                              # 拉取远程最新代码</span><br><span class="line">git push                              # 推送到远程</span><br><span class="line">git push origin --delete 远程分支名    # 删除远程分支（-D 强制删除）</span><br><span class="line">git checkout 远程分支名                # 将远程分支检出到本地</span><br></pre></td></tr></table></figure><h2 id="版本回退"><a class="markdownIt-Anchor" href="#版本回退"></a> 版本回退</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">git log                               # 查看提交历史</span><br><span class="line">git reset --mixed 版本号               # 默认：回退 commit 和 index，保留源码</span><br><span class="line">git reset --soft 版本号                # 仅回退 commit，保留 index 和源码</span><br><span class="line">git reset --hard 版本号                # 彻底回退，源码也恢复到指定版本</span><br></pre></td></tr></table></figure><h1 id="工作流程"><a class="markdownIt-Anchor" href="#工作流程"></a> 工作流程</h1><h2 id="日常开发流程"><a class="markdownIt-Anchor" href="#日常开发流程"></a> 日常开发流程</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_"># </span><span class="language-bash">1. 修改代码后</span></span><br><span class="line">git add .</span><br><span class="line">git commit -m &quot;feat: 新增功能描述&quot;</span><br><span class="line">git push</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">2. 切换分支开发</span></span><br><span class="line">git checkout -b feature/新功能</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">... 开发完成 ...</span></span><br><span class="line">git checkout main</span><br><span class="line">git merge feature/新功能</span><br><span class="line">git push</span><br></pre></td></tr></table></figure><h2 id="关联已有远程仓库"><a class="markdownIt-Anchor" href="#关联已有远程仓库"></a> 关联已有远程仓库</h2><p>当远程仓库已有内容（如 <a href="http://README.md">README.md</a>）时：</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></pre></td><td class="code"><pre><span class="line">git init</span><br><span class="line">git remote add origin git@github.com:用户名/仓库名.git</span><br><span class="line">git add .</span><br><span class="line">git commit -m &quot;feat: 初始提交&quot;</span><br><span class="line">git pull origin main --allow-unrelated-histories</span><br><span class="line">git push -u origin main</span><br></pre></td></tr></table></figure><h1 id="常见问题"><a class="markdownIt-Anchor" href="#常见问题"></a> 常见问题</h1><h2 id="github-443-连接超时"><a class="markdownIt-Anchor" href="#github-443-连接超时"></a> GitHub 443 连接超时</h2><p><strong>报错：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Failed to connect to github.com port 443 after 21104 ms: Timed out</span><br></pre></td></tr></table></figure><p><strong>原因：</strong> 使用了代理，但 Git 未配置代理</p><p><strong>解决：</strong></p><figure class="highlight shell"><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">git config --global http.proxy 127.0.0.1:7890</span><br><span class="line">git config --global https.proxy 127.0.0.1:7890</span><br></pre></td></tr></table></figure><h2 id="ssh-连接-github-报-connection-closed"><a class="markdownIt-Anchor" href="#ssh-连接-github-报-connection-closed"></a> SSH 连接 GitHub 报 Connection closed</h2><p><strong>报错：</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Connection closed by 127.0.0.1 port 22</span><br></pre></td></tr></table></figure><p><strong>原因：</strong> 代理封禁了 GitHub 端口 22 的连接</p><p><strong>解决：</strong></p><ol><li><p>重新生成 SSH 密钥</p><figure class="highlight shell"><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">git config user.email  # 确认邮箱正确</span><br><span class="line">ssh-keygen -t rsa -b 4096 -C &quot;你的邮箱@qq.com&quot;</span><br></pre></td></tr></table></figure></li><li><p>将新公钥添加到 GitHub</p></li><li><p>在 <code>C:\Users\Administrator\.ssh</code> 目录下创建 <code>config</code> 文件（无后缀），内容：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Host github.com</span><br><span class="line">Hostname ssh.github.com</span><br><span class="line">Port 443</span><br></pre></td></tr></table></figure></li><li><p>验证连接：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -T git@github.com</span><br></pre></td></tr></table></figure></li></ol><h1 id="开发工具推荐"><a class="markdownIt-Anchor" href="#开发工具推荐"></a> 开发工具推荐</h1><h2 id="vscode-插件"><a class="markdownIt-Anchor" href="#vscode-插件"></a> VSCode 插件</h2><ul><li><strong>Git Blame</strong> - 查看每行代码的最后修改者</li><li><strong>Git History</strong> - 查看文件修改历史</li><li><strong>Git Graph</strong> - 可视化分支图</li></ul><h2 id="intellij-idea"><a class="markdownIt-Anchor" href="#intellij-idea"></a> IntelliJ IDEA</h2><p>2023.2.1 版本自带 Git 插件，只需保留 Git 相关插件即可。</p><blockquote><p>⚠️ <strong>注意：</strong> 遇到过保留 GitHub 插件导致无法推送的问题</p></blockquote><h1 id="注意事项"><a class="markdownIt-Anchor" href="#注意事项"></a> 注意事项</h1><ol><li><strong>Gitee 使用</strong> - 注意区分主分支名称（master/main）和远程源（origin）</li><li><strong>远程仓库已有内容</strong> - 使用 <code>--allow-unrelated-histories</code> 拉取后再推送</li><li><strong>删除已追踪文件</strong> - 仅修改 <code>.gitignore</code> 不够，需执行 <code>git rm --cached</code> 移除追踪</li></ol>]]></content>
    
    
    <summary type="html">俱怀逸兴壮思飞，欲上青天揽明月</summary>
    
    
    
    <category term="工具" scheme="https://luckynwa.top/categories/%E5%B7%A5%E5%85%B7/"/>
    
    
    <category term="Git" scheme="https://luckynwa.top/tags/Git/"/>
    
  </entry>
  
</feed>
