<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>zhengcookie</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://zhengcookie.github.io/</id>
  <link href="https://zhengcookie.github.io/" rel="alternate"/>
  <link href="https://zhengcookie.github.io/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, zhengcookie</rights>
  <subtitle>欢迎来到zhengcookie的博客！</subtitle>
  <title>zhengcookie</title>
  <updated>2026-08-16T14:30:00.000Z</updated>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="AI大模型" scheme="https://zhengcookie.github.io/categories/AI%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    <category term="DeepSeek" scheme="https://zhengcookie.github.io/tags/DeepSeek/"/>
    <category term="AI" scheme="https://zhengcookie.github.io/tags/AI/"/>
    <category term="agent" scheme="https://zhengcookie.github.io/tags/agent/"/>
    <category term="大模型" scheme="https://zhengcookie.github.io/tags/%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    <content>
      <![CDATA[<blockquote><p>本文基于 DeepSeek Harness（<code>dsh</code>）当前开发者预览版整理，命令与配置以官方文档为准。它正处于快速迭代阶段，未来会出现破坏兼容性的变更。</p></blockquote><h2 id="DeepSeek-Harness-是什么？"><a href="#DeepSeek-Harness-是什么？" class="headerlink" title="DeepSeek Harness 是什么？"></a>DeepSeek Harness 是什么？</h2><p><strong>DeepSeek Harness（简称 <code>dsh</code>）</strong> 是由 <a href="https://deepseek.com/">DeepSeek AI</a> 开发的开源 <strong>agent harness（智能体框架）</strong>。</p><p>它不是又一个大模型，而是一套”让大模型动起来干活”的运行时：给它一个工作区、一段目标、一组工具，它就能自主地读文件、写代码、跑命令、委派子任务、维护计划，直到完成目标。</p><p>它的几个关键特点：</p><ul><li><strong>一切皆插件</strong>：核心能力（LLM 接入、工具、Web UI、headless、持久化……）都拆成插件，通过组合包自由拼装。</li><li><strong>由 Cordis 驱动</strong>：底层用 <a href="https://github.com/cordiverse/cordis">Cordis</a> 插件容器实现插件生命周期与组合，设计思想见论文 <em>A Programming Paradigm for Spatiotemporal Composability</em>。</li><li><strong>多形态入口</strong>：网页端（Web UI）、命令行（CLI &#x2F; headless）、Python SDK 都能用。</li><li><strong>配置分层叠加</strong>：内置组合包 → 配置文件 → 用户覆盖层，逐层叠加出最终行为。</li></ul><h2 id="快速开始"><a href="#快速开始" class="headerlink" title="快速开始"></a>快速开始</h2><h3 id="1-环境要求"><a href="#1-环境要求" class="headerlink" title="1. 环境要求"></a>1. 环境要求</h3><ul><li><strong>Node.js</strong>（<code>npx</code> 需要）。从源码跑时要求 <code>node ^22.19.0 || &gt;=24.0.0</code>，且用 <code>pnpm@11.7.0</code>。</li><li>一个 <strong>DeepSeek API Key</strong>（或任意 OpenAI 兼容端点 &#x2F; 其他提供方密钥）。</li><li>一个<strong>隔离的工作区目录</strong>（agent 会在上面读写文件、跑命令）。</li></ul><h3 id="2-一行启动-Web-UI"><a href="#2-一行启动-Web-UI" class="headerlink" title="2. 一行启动 Web UI"></a>2. 一行启动 Web UI</h3><p>无需克隆源码，Node.js 装好后直接：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sh">npx @deepseek-ai/dsh web<br></code></pre></td></tr></table></figure><p>启动后访问 <strong><code>http://127.0.0.1:3080</code></strong> 即可。</p><h3 id="3-从源码运行（推荐给想深入-开发的用户）"><a href="#3-从源码运行（推荐给想深入-开发的用户）" class="headerlink" title="3. 从源码运行（推荐给想深入&#x2F;开发的用户）"></a>3. 从源码运行（推荐给想深入&#x2F;开发的用户）</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sh">git <span class="hljs-built_in">clone</span> https://github.com/deepseek-ai/deepseek-harness.git<br><span class="hljs-built_in">cd</span> deepseek-harness<br>pnpm install<br>pnpm run build<br>pnpm dsh web<br></code></pre></td></tr></table></figure><h2 id="使用-Web-UI-跑通第一个任务"><a href="#使用-Web-UI-跑通第一个任务" class="headerlink" title="使用 Web UI 跑通第一个任务"></a>使用 Web UI 跑通第一个任务</h2><h3 id="第一步：配置模型"><a href="#第一步：配置模型" class="headerlink" title="第一步：配置模型"></a>第一步：配置模型</h3><p>打开 <strong>设置 → 模型</strong>：</p><ul><li><strong>DeepSeek 卡片</strong>：直接填入你的 DeepSeek API 密钥并保存，模型路由立即可用，<strong>不需要重启服务器</strong>。</li><li><strong>其他提供方</strong>（Anthropic &#x2F; OpenAI 等）：点”添加提供方”输入密钥。</li><li><strong>自定义端点 &#x2F; 公司网关</strong>：点”添加自定义提供方”，填 Provider ID、基础 URL、API 协议、凭据和至少一个模型。</li></ul><p>几点说明：</p><ul><li>密钥是<strong>只写</strong>的：保存后页面只显示脱敏描述符，明文密钥存在 <code>$DSH_HOME/.credentials.yaml</code>。</li><li>Provider ID 一旦创建就是永久的（请求、会话、凭据引用都用它），重命名就走”新建+删除”。</li><li>模型变更在<strong>下一次请求</strong>生效，无需重启。</li></ul><h3 id="第二步：选择工作区"><a href="#第二步：选择工作区" class="headerlink" title="第二步：选择工作区"></a>第二步：选择工作区</h3><p>点击<strong>选择工作区</strong>，添加你启动 <code>dsh</code> 时的项目目录并选中。<strong>选中工作区前，会话输入框不可用。</strong></p><h3 id="第三步：发任务"><a href="#第三步：发任务" class="headerlink" title="第三步：发任务"></a>第三步：发任务</h3><p>启动一个会话，发送一句话，例如：</p><blockquote><p>Summarize this repository and identify its main packages.</p></blockquote><p>agent 会读取&#x2F;编辑工作区文件、运行命令、委派子任务并维护计划；当操作超出当前权限策略需要审批时，Web UI 会先询问你，而不是擅自执行。</p><h3 id="常见排错"><a href="#常见排错" class="headerlink" title="常见排错"></a>常见排错</h3><ul><li><strong><code>MISSING_CREDENTIAL</code></strong>：去模型页存密钥，或提供被引用的环境变量。</li><li><strong><code>UNKNOWN_MODEL</code></strong>：在模型选择器里选一个已配置的模型。</li><li><strong><code>获取可用模型</code> 返回 401</strong>：检查密钥；该功能调用 OpenAI 兼容的 <code>GET /models</code>，不提供该端点的服务请手动输入模型。</li></ul><h2 id="其他调用方式"><a href="#其他调用方式" class="headerlink" title="其他调用方式"></a>其他调用方式</h2><h3 id="CLI-headless-模式"><a href="#CLI-headless-模式" class="headerlink" title="CLI &#x2F; headless 模式"></a>CLI &#x2F; headless 模式</h3><p><code>dsh</code> 是启动 profile 用的命令，不同 profile 对应不同形态：</p><table><thead><tr><th>命令</th><th>用途</th></tr></thead><tbody><tr><td><code>dsh web</code></td><td>启动 Web UI（<code>--profile web</code> 的别名）</td></tr><tr><td><code>dsh --profile headless &quot;job&quot;</code></td><td>运行一个全新的持久化会话，打印最终答案并退出</td></tr><tr><td><code>dsh --profile &lt;name&gt;</code></td><td>启动指定 profile</td></tr><tr><td><code>dsh plugin --profile &lt;name&gt; &lt;pnpm args&gt;</code></td><td>通过 pnpm 管理该 profile 的插件</td></tr></tbody></table><p><strong>运行命令时的当前目录</strong>就是默认 workspace 根目录。头尾部 flag 约定：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs sh">dsh --profile web --port 8080        <span class="hljs-comment"># --port 是 web app 的参数</span><br>dsh --profile headless <span class="hljs-string">&quot;run the tests&quot;</span>   <span class="hljs-comment"># 引号里是任务</span><br>dsh --<span class="hljs-built_in">help</span>                           <span class="hljs-comment"># 启动器自身的帮助</span><br></code></pre></td></tr></table></figure><h3 id="Python-SDK"><a href="#Python-SDK" class="headerlink" title="Python SDK"></a>Python SDK</h3><p>装 SDK：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs sh">git <span class="hljs-built_in">clone</span> https://github.com/deepseek-ai/deepseek-harness.git<br><span class="hljs-built_in">cd</span> deepseek-harness<br>python -m venv .venv<br>. .venv/bin/activate<br>python -m pip install deepseek-harness-sdk<br></code></pre></td></tr></table></figure><p>设置凭据后跑一个任务：</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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><code class="hljs sh"><span class="hljs-built_in">export</span> DEEPSEEK_API_KEY=sk-your-key-here<br><br>python examples/jsonrpc-agent/minimal.py \<br>  --workspace /absolute/path/to/workspace \<br>  --session-root /absolute/path/to/sessions \<br>  --session-id example-001 \<br>  <span class="hljs-string">&quot;Inspect the repository and fix the failing tests.&quot;</span><br></code></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><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> pathlib <span class="hljs-keyword">import</span> Path<br><span class="hljs-keyword">from</span> deepseek_harness <span class="hljs-keyword">import</span> DeepSeekHarness<br><br>config = Path(<span class="hljs-string">&quot;examples/jsonrpc-agent/minimal.cordis.yml&quot;</span>).resolve()<br>workspace = Path(<span class="hljs-string">&quot;/absolute/path/to/workspace&quot;</span>).resolve()<br>sessions = Path(<span class="hljs-string">&quot;/absolute/path/to/sessions&quot;</span>).resolve()<br><br><span class="hljs-keyword">with</span> DeepSeekHarness(<br>    provider=<span class="hljs-string">&quot;deepseek-official&quot;</span>,<br>    model=<span class="hljs-string">&quot;deepseek-v4-flash&quot;</span>,<br>    max_tokens=<span class="hljs-number">49_152</span>,<br>    cwd=<span class="hljs-built_in">str</span>(workspace),<br>    session_root=<span class="hljs-built_in">str</span>(sessions),<br>    cordis=<span class="hljs-built_in">str</span>(config),<br>) <span class="hljs-keyword">as</span> harness:<br>    result = harness.run(<br>        <span class="hljs-string">&quot;Inspect the repository and fix the failing tests.&quot;</span>,<br>        session_id=<span class="hljs-string">&quot;example-001&quot;</span>,<br>    )<br><br><span class="hljs-built_in">print</span>(result.final_response)<br></code></pre></td></tr></table></figure><p><strong>用好 session id 的两条经验</strong>：</p><ul><li>复用同一个 harness + session id 会<strong>保留该会话的 Bash 进程</strong>（工作目录、已导出的变量、shell 函数都在）。</li><li><strong>独立任务用新的 session id</strong>；只有下次调用需要延续同一段对话时才复用旧 id。</li></ul><blockquote><p>SDK 组合默认是 <code>danger-full-access</code>，agent 能改运行时进程有权访问的任何路径。<strong>请只在可丢弃的 checkout 或容器内运行</strong>，别在重要目录上跑。</p></blockquote><h2 id="插件开发：扩展-dsh"><a href="#插件开发：扩展-dsh" class="headerlink" title="插件开发：扩展 dsh"></a>插件开发：扩展 dsh</h2><p><code>dsh</code> 的核心能力几乎都是插件。文档里把插件开发分成两块：</p><h3 id="基础插件（basic）"><a href="#基础插件（basic）" class="headerlink" title="基础插件（basic）"></a>基础插件（basic）</h3><ul><li><strong>config</strong>：声明自己的配置项，暴露给用户覆盖。</li><li><strong>tool</strong>：给 agent 新增工具（比如自定义的查询接口）。</li><li><strong>publish</strong>：把你的插件作为 npm 包发布，供他人 <code>dsh plugin</code> 安装；为你的插件仓库加上 <strong><code>dsh-plugin</code></strong> topic 便于被发现。</li></ul><h3 id="框架机制（framework）"><a href="#框架机制（framework）" class="headerlink" title="框架机制（framework）"></a>框架机制（framework）</h3><ul><li><strong>service</strong>：定义可注入的服务。</li><li><strong>events</strong>：订阅&#x2F;发布事件。</li><li>组合语法基于 Cordis，入门可看 <a href="docs/cordis-primer.md">Cordis primer</a>。</li></ul><h2 id="配置与目录结构速览"><a href="#配置与目录结构速览" class="headerlink" title="配置与目录结构速览"></a>配置与目录结构速览</h2><ul><li><strong><code>$DSH_HOME</code></strong>：用户级配置与凭据目录，密钥、settings 都在这里。</li><li><strong>profile 目录</strong>：包含 <code>package.json</code>（插件依赖）、<code>dsh.profile</code>（metadata 清单 + bundles）、<code>cordis.patch.yml</code>（用户 patch 层）。</li><li><strong>配置叠加顺序</strong>：内置组合包 patch → profile 的 <code>cordis.patch.yml</code> → home 级 <code>$DSH_HOME/cordis.patch.yml</code> → <code>--patch</code> 覆盖层。</li><li>用 <code>--dump-default-config</code> &#x2F; <code>--dump-config</code> 可以在不启动的情况下查看组合后的配置树。</li></ul><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2><p>DeepSeek Harness 把”让大模型真正干活”这件事拆成了可插拔、可自由组合的运行时。对普通用户来说，<strong><code>npx @deepseek-ai/dsh web</code> + 填一个 API Key + 选一个工作区 + 发一句话</strong> 就能跑通第一个 agent；对开发者而言，CLI、Python SDK 和插件体系提供了更深的扩展空间。</p><p>需要踩稳的三件事：</p><ol><li><strong>工作区要隔离</strong>：别在重要目录上让 agent 全权读写。</li><li><strong>API Key 只写不读</strong>：存好后看不到明文。</li><li><strong>预览版变化快</strong>：跟随官方 <a href="https://github.com/deepseek-ai/deepseek-harness">README</a> 与 <a href="https://github.com/deepseek-ai/deepseek-harness/discussions">Discussions</a> 迭代。</li></ol><hr><p><strong>参考资料</strong></p><ul><li><a href="https://github.com/deepseek-ai/deepseek-harness">DeepSeek Harness 官方仓库</a></li><li><a href="https://github.com/deepseek-ai/deepseek-harness/tree/main/docs/user/guide">使用 Web UI 指南</a></li><li><a href="https://github.com/deepseek-ai/deepseek-harness/tree/main/docs/user/guide/providers.md">配置模型 &#x2F; Providers</a></li><li><a href="https://github.com/deepseek-ai/deepseek-harness/tree/main/docs/user/guide/python-sdk.md">Python SDK 快速上手</a></li><li><a href="https://github.com/deepseek-ai/deepseek-harness/tree/main/apps/cli/README.md">CLI 说明</a></li></ul>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/DeepSeek-Harness%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/DeepSeek-Harness%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97/"/>
    <published>2026-01-20T09:39:06.000Z</published>
    <summary>DeepSeek Harness（dsh）是 DeepSeek AI 开源的 agent harness 框架，采用&quot;一切皆插件&quot;架构。本文从安装、Web UI 配置模型与工作区、运行任务，到 headless / CLI / Python SDK 等多种调用方式，再到插件开发，带你一步步跑通自己的第一个 agent。</summary>
    <title>DeepSeek Harness 使用指南：从安装到跑通你的第一个 agent</title>
    <updated>2026-08-16T14:30:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <content>
      <![CDATA[<h3 id="一、核心观点概述"><a href="#一、核心观点概述" class="headerlink" title="一、核心观点概述"></a><a href="#%E4%B8%80%E3%80%81%E6%A0%B8%E5%BF%83%E8%A7%82%E7%82%B9%E6%A6%82%E8%BF%B0"></a>一、核心观点概述</h3><p>模型优化不仅依赖提示工程，更取决于模型本身的知识储备与训练数据。若模型本身能力不足，仅优化提示词效果有限。因此，实际生产中常采用以下三种方式提升模型表现：</p><ol><li><strong>提示词工程</strong></li><li><strong>检索增强生成（RAG）</strong></li><li><strong>模型微调（Fine-Tuning）</strong></li></ol><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260112020848114.png" alt="image-20260112020848114"></p><p>我们把 AI 模型想象成一个“智能助手”，它要帮你回答问题。<br>想让它的回答更准、更有用，一般有三种办法：</p><hr><h3 id="1-给它更清楚的“提问指南”（提示词工程）"><a href="#1-给它更清楚的“提问指南”（提示词工程）" class="headerlink" title="1. 给它更清楚的“提问指南”（提示词工程）"></a><a href="#1-%E7%BB%99%E5%AE%83%E6%9B%B4%E6%B8%85%E6%A5%9A%E7%9A%84%E2%80%9C%E6%8F%90%E9%97%AE%E6%8C%87%E5%8D%97%E2%80%9D%EF%BC%88%E6%8F%90%E7%A4%BA%E8%AF%8D%E5%B7%A5%E7%A8%8B%EF%BC%89"></a>1. <strong>给它更清楚的“提问指南”（提示词工程）</strong></h3><p>就像你教别人怎么做事，要步骤清楚、要求明确。</p><ul><li><strong>优点</strong>：简单直接，不需要动模型本身。</li><li><strong>缺点</strong>：如果助手自己知识不够，再怎么教它步骤，它也可能答不上来。</li></ul><hr><h3 id="2-让它先“查资料”再回答（检索增强生成-RAG）"><a href="#2-让它先“查资料”再回答（检索增强生成-RAG）" class="headerlink" title="2. 让它先“查资料”再回答（检索增强生成 &#x2F; RAG）"></a><a href="#2-%E8%AE%A9%E5%AE%83%E5%85%88%E2%80%9C%E6%9F%A5%E8%B5%84%E6%96%99%E2%80%9D%E5%86%8D%E5%9B%9E%E7%AD%94%EF%BC%88%E6%A3%80%E7%B4%A2%E5%A2%9E%E5%BC%BA%E7%94%9F%E6%88%90-RAG%EF%BC%89"></a>2. <strong>让它先“查资料”再回答（检索增强生成 &#x2F; RAG）</strong></h3><p>这就是 RAG 的核心思想。<br><strong>步骤很简单</strong>：</p><ol><li><strong>存资料</strong>：把公司的文件、数据等，变成“数字指纹”，存进一个专门的数据库。</li><li><strong>问问题</strong>：当你提问时，系统也会把你的问题变成“数字指纹”，然后去数据库里找和它最相似的“资料指纹”。</li><li><strong>组合回答</strong>：把找到的相关资料和你的问题一起交给 AI，让它根据资料来组织答案。</li></ol><p><strong>好处</strong>：</p><ul><li>答案有依据，不容易瞎编。</li><li>可以随时更新资料库，保持信息及时。</li></ul><p><strong>注意</strong>：</p><ul><li>资料库大了之后，检索速度可能变慢，要不断优化。</li><li>上手容易，但做好不容易，需要持续调整。</li></ul><hr><h3 id="3-专门“培训”它（微调）"><a href="#3-专门“培训”它（微调）" class="headerlink" title="3. 专门“培训”它（微调）"></a><a href="#3-%E4%B8%93%E9%97%A8%E2%80%9C%E5%9F%B9%E8%AE%AD%E2%80%9D%E5%AE%83%EF%BC%88%E5%BE%AE%E8%B0%83%EF%BC%89"></a>3. <strong>专门“培训”它（微调）</strong></h3><p>相当于请一个“通用智能助手”来公司做专业培训，让它更懂你们行业的话术和知识。</p><ul><li>适合需要它从根本上改变回答风格或深入掌握专业知识的场景。</li><li>成本较高，但效果也更彻底。</li></ul><hr><h3 id="怎么选？"><a href="#怎么选？" class="headerlink" title="怎么选？"></a><a href="#%E6%80%8E%E4%B9%88%E9%80%89%EF%BC%9F"></a>怎么选？</h3><table><thead><tr><th>方法</th><th>适用情况</th><th>特点</th></tr></thead><tbody><tr><td><strong>提示词优化</strong></td><td>模型本身不错，只需明确指令</td><td>快、简单，但不解决知识短板</td></tr><tr><td><strong>RAG</strong></td><td>想让模型能用到最新或内部资料</td><td>不用改模型，可随资料库更新，答案更靠谱</td></tr><tr><td><strong>微调</strong></td><td>有大量行业数据，希望模型从根本上更专业</td><td>效果持久，但需要训练成本</td></tr></tbody></table><hr><h3 id="打个比方"><a href="#打个比方" class="headerlink" title="打个比方"></a><a href="#%E6%89%93%E4%B8%AA%E6%AF%94%E6%96%B9"></a>打个比方</h3><ul><li><strong>提示词优化</strong> → 你告诉助手：“回答请分三点，用简单语言。”</li><li><strong>RAG</strong> → 助手接到问题，先去查公司手册，再结合手册内容回答你。</li><li><strong>微调</strong> → 你送助手去参加你们行业的培训，回来后它就成了半个专家。</li></ul><h3 id="二、RAG-流程详解"><a href="#二、RAG-流程详解" class="headerlink" title="二、RAG 流程详解"></a><a href="#%E4%BA%8C%E3%80%81RAG-%E6%B5%81%E7%A8%8B%E8%AF%A6%E8%A7%A3"></a>二、RAG 流程详解</h3><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260112021753679.png" alt="image-20260112021753679"></p><ol><li><strong>数据向量化</strong><br>使用 Embedding 模型将文本（可以处理很多文档格式）转为高维向量（可理解为 N 维空间中的点）。</li><li><strong>相似度检索</strong><br>将查询问题同样转为向量，在向量空间中查找距离最近的向量点（即语义最相似的文档）。</li><li><strong>生成答案</strong><br>将检索到的文档与问题组合，输入大模型进行归纳、总结并生成最终答案。</li></ol><hr><h3 id="三、为什么需要-RAG？"><a href="#三、为什么需要-RAG？" class="headerlink" title="三、为什么需要 RAG？"></a><a href="#%E4%B8%89%E3%80%81%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-RAG%EF%BC%9F"></a>三、为什么需要 RAG？</h3><ul><li><strong>传统方式缺点</strong>：<br>直接提问模型，无法获取最新或私有数据，易产生不准确或虚构内容。</li><li><strong>RAG 解决思路</strong>：<br>先“检索”相关证据，再“生成”答案，使输出基于实际资料，提升可信度与实时性。</li></ul><hr><h3 id="五、总结"><a href="#五、总结" class="headerlink" title="五、总结"></a><a href="#%E4%BA%94%E3%80%81%E6%80%BB%E7%BB%93"></a>五、总结</h3><ul><li>提示词工程适用于模型本身较强时的细节优化。</li><li>RAG 是实现数据与模型结合的高效路径，尤其适合企业私有知识库应用。</li><li>微调适用于对模型行为有深度定制需求的场景。</li><li>RAG 系统易入门难精通，需在索引、检索、性能等多方面持续优化才能实现长期稳定落地。</li></ul>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BC%81%E4%B8%9A%E7%BA%A7%E4%B8%9A%E5%8A%A1%E5%9C%BA%E6%99%AF%E8%90%BD%E5%9C%B0%E6%96%B9%E6%A1%88%E5%AE%9E%E8%B7%B5/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%BC%81%E4%B8%9A%E7%BA%A7%E4%B8%9A%E5%8A%A1%E5%9C%BA%E6%99%AF%E8%90%BD%E5%9C%B0%E6%96%B9%E6%A1%88%E5%AE%9E%E8%B7%B5/"/>
    <published>2026-01-11T18:40:23.000Z</published>
    <summary>.video-container { position: relative; width: 100%; padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */*/ } .video-container iframe { position: absolute;</summary>
    <title>大模型企业级业务场景落地方案实践</title>
    <updated>2026-01-12T17:07:12.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <content>
      <![CDATA[<p>.video-container {<br>    position: relative;<br>    width: 100%;<br>    padding-top: 56.25%; &#x2F;* 16:9 aspect ratio (height&#x2F;width &#x3D; 9&#x2F;16 * 100%) *&#x2F;<br>}<br>.video-container iframe {<br>    position: absolute;<br>    top: 0;<br>    left: 0;<br>    width: 100%;<br>    height: 100%;<br>}</p><p>大模型全套资料→夸克网盘文件链接：<a href="https://pan.quark.cn/s/ef4f66a5ec0a">https://pan.quark.cn/s/ef4f66a5ec0a</a><br>大模型全套资料→百度网盘文件链接：<a href="https://pan.baidu.com/s/1Bbnw5tsK1b50oo2QfUiDqg?pwd=izg3">https://pan.baidu.com/s/1Bbnw5tsK1b50oo2QfUiDqg?pwd=izg3</a></p><p><a href="https://pan.baidu.com/s/1XHTPipTFct8BJi7NAhV_3Q?dp-logid=78821300141927410002&pwd=itns#/home/%2F%E5%A4%A7%E6%A8%A1%E5%9E%8B%2F3%E3%80%81B%E7%AB%99%E3%80%81%E8%A7%86%E9%A2%91%E5%8F%B7%E7%AD%89%E8%B5%84%E6%96%99/%2F%E8%87%AA%E5%AD%A6%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BF%85%E7%9C%8B%E7%9A%846%E6%9C%AC%E4%B9%A6%E7%B1%8DPDF">https://pan.baidu.com/s/1XHTPipTFct8BJi7NAhV_3Q?dp-logid&#x3D;78821300141927410002&amp;pwd&#x3D;itns#&#x2F;home&#x2F;%2F%E5%A4%A7%E6%A8%A1%E5%9E%8B%2F3%E3%80%81B%E7%AB%99%E3%80%81%E8%A7%86%E9%A2%91%E5%8F%B7%E7%AD%89%E8%B5%84%E6%96%99&#x2F;%2F%E8%87%AA%E5%AD%A6%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BF%85%E7%9C%8B%E7%9A%846%E6%9C%AC%E4%B9%A6%E7%B1%8DPDF</a></p><p>学习路线</p><p><a href="https://blog.csdn.net/u014106644/article/details/145965064">大模型学习路线以及资料—更新中_大模型教程 b站-CSDN博客</a></p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/ai%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%94%B5%E5%AD%90%E4%B9%A6/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/ai%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%94%B5%E5%AD%90%E4%B9%A6/"/>
    <published>2026-01-09T09:16:03.000Z</published>
    <summary>.video-container { position: relative; width: 100%; padding-top: 56.25%; / 16:9 aspect ratio (height/width = 9/16 100%) */}.video-container iframe { position: absolute; top: 0; ...</summary>
    <title>ai大模型电子书</title>
    <updated>2026-01-11T18:36:47.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <content>
      <![CDATA[<h1 id="入门篇"><a href="#入门篇" class="headerlink" title="入门篇"></a><a href="#%E5%85%A5%E9%97%A8%E7%AF%87"></a>入门篇</h1><h2 id="从函数到神经网络"><a href="#从函数到神经网络" class="headerlink" title="从函数到神经网络"></a><a href="#%E4%BB%8E%E5%87%BD%E6%95%B0%E5%88%B0%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C"></a>从函数到神经网络</h2><h3 id="函数"><a href="#函数" class="headerlink" title="函数"></a><a href="#%E5%87%BD%E6%95%B0"></a>函数</h3><h4 id="定义"><a href="#定义" class="headerlink" title="定义"></a><a href="#%E5%AE%9A%E4%B9%89"></a>定义</h4><p>在早期的人工智能研究中，有一种观点认为可以通过找到一个精确的数学函数来表达和解决所有问题。这种想法基于一种信念：即世界上的每一种现象或规律都可以通过某种形式的函数关系来描述。然而，随着研究的深入，人们逐渐认识到现实世界的复杂性远超最初的想象。</p><h4 id="符号主义"><a href="#符号主义" class="headerlink" title="符号主义"></a><a href="#%E7%AC%A6%E5%8F%B7%E4%B8%BB%E4%B9%89"></a>符号主义</h4><p>符号主义是早期人工智能的一个重要流派，它试图通过逻辑推理、规则匹配等方法来模拟人类的思维过程。这种方法的核心在于寻找并利用那些能够准确描述问题本质的“规律”。然而，在面对极其复杂的现实情况时，符号主义遇到了难以克服的挑战——即如何全面而准确地捕捉到这些规律。</p><h4 id="转向近似解"><a href="#转向近似解" class="headerlink" title="转向近似解"></a><a href="#%E8%BD%AC%E5%90%91%E8%BF%91%E4%BC%BC%E8%A7%A3"></a>转向近似解</h4><p>由于直接找到完美匹配所有情况下的通用法则变得几乎不可能，研究人员开始转向另一种思路：即使不能得到完全正确的答案，但至少可以尝试获得一个足够接近真实结果的近似解。这种方法更加灵活，并且能够在一定程度上缓解了对绝对精度的要求。</p><h4 id="联结主义"><a href="#联结主义" class="headerlink" title="联结主义"></a><a href="#%E8%81%94%E7%BB%93%E4%B8%BB%E4%B9%89"></a>联结主义</h4><p>当传统的方法无法有效解决问题时，联结主义提供了一种全新的视角。联结主义主张模仿大脑神经元之间的连接方式来构建模型，通过训练让系统自动学习数据中的模式。这实际上是一种“猜测”加“简化”的策略，其中关键在于如何有效地估计权重（w）和偏置（b）参数值。</p><ul><li><strong>线性模型</strong>：最简单的形式就是线性方程 f(x) &#x3D; wx + b，其中 w 表示输入 x 对输出的影响程度，b 则是一个常数项。</li><li><strong>激活函数</strong>：为了使模型能够处理非线性的关系，引入了激活函数 g()。例如，sigmoid 或 ReLU 等函数可以将线性组合的结果转换为更复杂的非线性映射。</li></ul><h4 id="通过组合构建复杂关系"><a href="#通过组合构建复杂关系" class="headerlink" title="通过组合构建复杂关系"></a><a href="#%E9%80%9A%E8%BF%87%E7%BB%84%E5%90%88%E6%9E%84%E5%BB%BA%E5%A4%8D%E6%9D%82%E5%85%B3%E7%B3%BB"></a>通过组合构建复杂关系</h4><p>通过不断地将线性和非线性激活函数相结合，可以创建出非常强大的模型来表示极为复杂的关系。尽管这种方式极大地增强了模型的表现力，但也带来了计算上的难度以及理解上的挑战。</p><h4 id="神经网络"><a href="#神经网络" class="headerlink" title="神经网络"></a><a href="#%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C"></a>神经网络</h4><p>神经网络是上述思想的具体实现之一。它由多个层次组成，每个层次包含若干个节点（类似于神经元），这些节点之间通过权重相连。整个网络的工作原理可以用公式 f(x) &#x3D; g(wx+b) 来概括，其中 g() 是激活函数，wx+b 则是对输入进行线性变换后的结果。通过调整各层之间的权重和偏置，神经网络能够学习到从输入到输出之间复杂的映射关系，从而实现诸如图像识别、自然语言处理等多种任务。<br>总之，从最初的追求精确到后来接受近似，再到采用更加直观且灵活的联结主义方法，人工智能的发展历程体现了科学研究不断适应新挑战的过程。</p><p>输入层  输出层</p><p>x              y</p><p>复杂一点像下图这样 ↓</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766046923044-43b4b7f9-649d-4450-97d9-02ac0c46ca7f.png" alt="img"></p><h2 id="计算神经网络的参数"><a href="#计算神经网络的参数" class="headerlink" title="计算神经网络的参数"></a><a href="#%E8%AE%A1%E7%AE%97%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E7%9A%84%E5%8F%82%E6%95%B0"></a>计算神经网络的参数</h2><h3 id="损失函数"><a href="#损失函数" class="headerlink" title="损失函数"></a><a href="#%E6%8D%9F%E5%A4%B1%E5%87%BD%E6%95%B0"></a>损失函数</h3><p>如图</p><p>y为真实数据 y^为预测数据</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766048463141-dca6f4c9-66ba-4b3e-9c20-42d904dfa3c7.png" alt="img"></p><p>用于真实值与预测值的误差</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766048597312-7b3fde0d-4483-4d79-9b07-f7a5da1d3347.png" alt="img"></p><p>我们可以把所有真实值和预测值加起来，这样可以得到预测数据和真实数据之间的总的误差（拟合度）</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766048764193-ee7a1f24-ce5a-4692-a68b-0197fcea4314.png" alt="img"></p><h4 id="均方误差-MSE"><a href="#均方误差-MSE" class="headerlink" title="均方误差 (MSE)"></a><a href="#%E5%9D%87%E6%96%B9%E8%AF%AF%E5%B7%AE-MSE"></a>均方误差 (MSE)</h4><p>因为绝对值不平滑，我们用平方来代替，一来解决绝对值的误差，二来放大误差较大的值的影响，我们再根据样本的数量平均一下，消除样本数量大小的影响，我们把损失函数记成L，就得到下面的公式</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049113577-b909e089-68c0-4a60-9cff-6f119032dfcf.png" alt="img"></p><p>参数视角则为</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049190107-11cac79e-12f2-4cd5-8269-120a1ad236f2.png" alt="img"></p><h5 id="简单的线性函数"><a href="#简单的线性函数" class="headerlink" title="简单的线性函数"></a><a href="#%E7%AE%80%E5%8D%95%E7%9A%84%E7%BA%BF%E6%80%A7%E5%87%BD%E6%95%B0"></a>简单的线性函数</h5><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049287600-270b12ad-c73d-423b-93b9-9a9a708dab2f.png" alt="img"></p><h6 id="演化过程"><a href="#演化过程" class="headerlink" title="演化过程"></a><a href="#%E6%BC%94%E5%8C%96%E8%BF%87%E7%A8%8B"></a>演化过程</h6><p>展开损失函数</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049356850-8b1bb26b-e2dc-4a85-a6f4-41bf318e7928.png" alt="img"></p><p>把y^代入</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224194539575.png" alt="image-20251224194539575"></p><p>求和符号展开</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049425818-05035746-d163-49e0-9929-8f9d76f5a228.png" alt="img"></p><p>把上面这组数据带进来（视频里给的最后一个3-4w，大概率是写错了）</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049579943-2a76f1a7-80d7-4310-a4f2-c8b61bc94177.png" alt="img"></p><p>平方展开,代入公式是a^2 - 2ab +b^2</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049597461-db478700-4ca6-4be5-a3bd-dd573c4a1cd1.png" alt="img"></p><p>化简结果</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049618819-1b094465-59cb-4383-be26-d3914a812c5d.png" alt="img"></p><p>求导，怎么求呢</p><p>图一</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766051072389-10c9e01c-51b0-41bd-b8da-2303603eb12a.png" alt="img"></p><p><strong>计算 w^x &#x3D; x个 w</strong><br><strong>原题中</strong></p><p><strong>常数项为0，因为他不随w变化</strong></p><p><strong>一次项w 一个w在变 -&gt;变化算一次 所以乘以1</strong></p><p><strong>两次项 俩个w在变 → 变化算两次 → 乘 2</strong></p><p>所以：d&#x2F;dw(7.5w^2) &#x3D; 7.5 · 2w &#x3D; 15</p><p>结果</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766049670250-5fc5a388-1cc2-4d39-9548-26769128fca8.png" alt="img"></p><p>要求最小值，带入进来就是</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766051756268-eb0d6c13-174d-4876-ab89-5b3c9e2e498b.png" alt="img"></p><p>导数等于0，就可以得到</p><p>带入为原直线函数，</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766051846313-8a1dec09-39b2-4728-846c-de0a958fb822.png" alt="img"></p><p>y 是模型的输出（预测值 ）这个 y 预测损失多少</p><p>此时y&#x3D;x就是让损失函数最小，也就是最拟合真实数据的那条直线</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195437775.png" alt="image-20251224195437775"></p><p>所以它（损失函数）实际上就是一条开口向上的抛物线，我们刚刚就在寻找最低点，采用的办法就是导数&#x3D;0</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766052825703-c42aaade-94d0-4656-97e6-b2a5c6ba1261.png" alt="img"></p><h5 id="复杂的线性函数"><a href="#复杂的线性函数" class="headerlink" title="复杂的线性函数"></a><a href="#%E5%A4%8D%E6%9D%82%E7%9A%84%E7%BA%BF%E6%80%A7%E5%87%BD%E6%95%B0"></a>复杂的线性函数</h5><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766053239598-a3a57817-f3ea-450d-bd56-5ee9f94a7606.png" alt="img"></p><p>图像来解释就是一个三维图像，一个开口向上的网状形状</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766053278114-96774c5b-499e-4249-87fd-cd3d8ce12213.png" alt="img"></p><p>我们要找到的就是这个二元函数最小值对应的w和b</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766053324153-f1563548-104f-45fb-b64d-010d3c9d15fb.png" alt="img"></p><p>那么就不再是计算导数，而是偏导数来求解</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766053390008-230d0d7f-30b5-4ca1-b0b0-5266148cc257.png" alt="img"></p><p>对w求偏导，就是把b当作常数，在三维图像就是这样的，相当于只看到这个切面</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054063306-184912ac-02cb-436a-8c3b-945fb2dc09f4.png" alt="img"></p><p>对于b也是如此，对b求偏导，就是把w当作常数，在三维图像就是这样的，相当于只看到这个切面</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054169528-bf94fd5c-cb96-4077-bf19-4224f582ec77.png" alt="img"></p><h6 id="线性回归"><a href="#线性回归" class="headerlink" title="线性回归"></a><a href="#%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92"></a>线性回归</h6><p>通过寻找一个线性函数，来拟合x和y之间的关系，也就是机器学习中最基本的一种分析方法，我们叫他线性回归</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766053480429-1bf6184b-a68f-40e4-9c84-13910b9c2b4e.png" alt="img"></p><p>往往呢，我们不能通过像刚刚那样将导数&#x3D;0来计算出最小值</p><p>解决办法呢，简单除暴一点就是一点点试</p><p>假如w为5，b为5，损失函数计算结果为10</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054347400-9463e8cc-2921-4e93-8176-281d26611ecb.png" alt="img"></p><p>我们调整了w为6，损失函数为9，这说明w增加让损失函数的值变小了。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054454849-dfbee1f9-cc72-40f0-bfac-f979a9b4655b.png" alt="img"></p><p>再尝试b增加1，结果为11.损失函数增加2，说明b增加让损失函数的值变大了，误差变大了。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054507666-6c5d1b49-36cd-4f40-b6c4-c6818468408f.png" alt="img"></p><p>我们就反过来对b进行减少，让损失函数继续变小</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195618519.png" alt="image-20251224195618519"></p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195719092.png" alt="image-20251224195719092"></p><p>w变化一点点，使得损失函数也发生变化。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195732171.png" alt="image-20251224195732171"></p><p>这其实是损失函数对w的偏导数</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054674741-e873d4ed-3659-45f5-93f0-4a1d8beeca6b.png" alt="img"></p><p>对b也是如此</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195744652.png" alt="image-20251224195744652"></p><p>我们要做的其实就是w和b不断网偏导数的反方向去变化</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195839067.png" alt="image-20251224195839067"></p><p>具体的变化快慢呢，我们用一个系数n来表示，我们叫他学习率</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224195856760.png" alt="image-20251224195856760"></p><h6 id="梯度"><a href="#梯度" class="headerlink" title="梯度"></a><a href="#%E6%A2%AF%E5%BA%A6"></a>梯度</h6><p>这些导数所构成的向量，我们就叫他梯度</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766054957460-4da50ce0-5e47-4c11-a4ab-dea821468a15.png" alt="img"></p><h6 id="梯度下降"><a href="#梯度下降" class="headerlink" title="梯度下降"></a><a href="#%E6%A2%AF%E5%BA%A6%E4%B8%8B%E9%99%8D"></a>梯度下降</h6><p>不断变化w和b，让损失函数逐渐变小的一个过程，进而求出最终的w和b，这个过程我们叫他梯度下降。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224200007284.png" alt="image-20251224200007284"></p><p>偏导数如何求？</p><p>神经网络中，虽然函数本身是一个复杂到变态的非线性函数，直接求导不好求。</p><p>但是，层与层之间的关系，确实非常简单的，我们就用前面的这个神经网络结构来举例</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224200029670.png" alt="image-20251224200029670"></p><p>只有一个输入和输出，而且中间只有一个隐藏层。</p><p>我们通过x来计算出隐藏层a的值，这个g就是随便一个激活函数，比如sigmod<img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766055493403-4624d8d5-13e5-4195-b003-a917a0657965.png" alt="img"></p><p>再根据a的值计算出y^的值，然后根据y^的值以及真实值y计算出损失函数L，损失函数就用均方误差了。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766055170364-d52495e0-98ea-4dd7-ac99-ef55660728e4.png" alt="img"></p><p>由于只有一个输出数据，所以把求符号省略掉了</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251224021425633.png" alt="image-20251224021425633"></p><h6 id="链式法则"><a href="#链式法则" class="headerlink" title="链式法则"></a><a href="#%E9%93%BE%E5%BC%8F%E6%B3%95%E5%88%99"></a>链式法则</h6><p>这个神经网络中共有4个参数，w1和w2，b1和b2要通过梯度下降的方式逐渐求解。</p><p>w1变化多少，会让L变化多少。</p><p>我们就看w1变化一个单位，a变化多少</p><p>再看a变化一个单位，会让y^变化多少</p><p>最后看y^变化一个单位，会对L变化多少</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766056428445-950f35bb-a739-4536-a9ff-31cdd7866b69.png" alt="img"></p><p>把三者相乘，就知道w变化一个单位，会使得L变化多少了</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766056479480-94de5713-01c1-4d26-a397-ece20d91c8ff.png" alt="img"></p><p>也就是微积分中的复合函数求导，在这里也叫做链式法则。</p><h6 id="反向传播"><a href="#反向传播" class="headerlink" title="反向传播"></a><a href="#%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD"></a>反向传播</h6><p>因为我们可以从右向左计算求导公式，逐步更新每一层的参数，直到把所有的神经网络的参数，都计算一遍，所以前面计算用到的偏导数的值后面也会用到，所以不必计算太多，而是让这些值从右向左一点点传播过来，这个过程就叫做反向传播。</p><p><strong>训练</strong></p><p>我们通过前向传播输入x计算输出y，通过反向传播计算出损失函数个参数的梯度，每个参数都向着梯度的反方向变化，这就构成了神经网络的训练。当神经网络进行足够多的训练，直到让损失函数足够小，也就是找到了我们需要的那个函数。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1766057555821-4fcadbc3-0fa3-4678-b7af-a8f1c4ace229.png" alt="img"></p><h2 id="调教神经网络的方法"><a href="#调教神经网络的方法" class="headerlink" title="调教神经网络的方法"></a><a href="#%E8%B0%83%E6%95%99%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E7%9A%84%E6%96%B9%E6%B3%95"></a>调教神经网络的方法</h2><p>我们知道神经网络的本质就是线性变换，套上一个激活函数，不断组合而成的一个非常复杂的非线性函数，并且巧妙地通过梯度下降，</p><p>我们可以从肉眼看出下面哪个好，一点点计算出神经网络中的一组合适的参数，那这样看起来只要神经网络足够大，岂不是什么问题都能解决了，理论上确实是这样，但是理想很丰满，现实很骨感，令人头疼的问题很快就接踵而至。</p><p>上个视频中我们说过，我们的目标是让数据拟合的好，比如左边这个就拟合的挺好，右边这个就不太好</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260108235638803.png" alt="image-20260108235638803"></p><h3 id="过拟合"><a href="#过拟合" class="headerlink" title="过拟合"></a><a href="#%E8%BF%87%E6%8B%9F%E5%90%88"></a><strong>过拟合</strong></h3><p>那再来一组图，这回你认为是左边好还是右边好呢？</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109000320243.png" alt="image-20260109000320243"></p><p>纯从预测值与真实值误差来看，也就是损失值最小化这个目标来看的话，显然右边这个更好但直觉似乎告诉我们，右边这个好像有点好的太过了，结果可能是只适合训练数据，对新数据的预测反而不如左边的准，那这种在训练数据上表现的很完美，但是在没见过的数据上表现的很糟糕的现象，就叫做过拟合。而在没见过的数据上的表现能力我们叫<code>泛化能力</code>。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109000615421.png" alt="image-20260109000615421"></p><p>那为什么会过拟合呢。看看刚刚这个图。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109000819688.png" alt="image-20260109000819688"></p><p>其实就是训练数据本身是个很简单的规律，但模型太复杂了，把那些噪声和随机波动也给学会了，那这该怎么办呢？</p><p>自然就是简化一下模型的复杂度</p><p>比如说这个案例中</p><p>你用一个非常复杂的神经网络模型来训练</p><p>效果甚至不如一个线性模型好</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109000910123.png" alt="image-20260109000910123"></p><p>这就告诉我们</p><p>神经网络不是越大越好</p><p>那简化模型复杂度有效果</p><p>与之相对的就是增加训练数据的量</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109000957748.png" alt="image-20260109000957748"></p><p>数据量足够充足</p><p>那原本复杂的模型也就相对变得简单了</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001032605.png" alt="image-20260109001032605"></p><h3 id="数据增强"><a href="#数据增强" class="headerlink" title="数据增强"></a><a href="#%E6%95%B0%E6%8D%AE%E5%A2%9E%E5%BC%BA"></a><strong>数据增强</strong></h3><p>但有的时候我们确实无法收集</p><p>或者懒得收集更多的数据</p><p>怎么办呢</p><p>那就在原有的数据中创造更多的数据</p><p>比如说在图像处理中</p><p>我们可以对图像进行旋转翻转</p><p>裁剪加噪声等操作</p><p>创造出更多新的训练样本</p><p>这就叫做数据增强。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001229637.png" alt="image-20260109001229637"></p><h3 id="鲁棒性（Robostness）"><a href="#鲁棒性（Robostness）" class="headerlink" title="鲁棒性（Robostness）"></a><a href="#%E9%B2%81%E6%A3%92%E6%80%A7%EF%BC%88Robostness%EF%BC%89"></a>鲁棒性（Robostness）</h3><p>这样不仅仅能够产生更多的数据</p><p>还刚好训练了一个让模型不因</p><p>输入的一点点小的变化</p><p>而对结果产生很大的波动</p><p>这就是增强了模型的鲁棒性。</p><p>提前终止训练过程</p><p>好刚刚是从数据和模型本身入手来防止过拟合</p><p>那有没有可能从训练过程入手</p><p>阻止过拟合的发生呢</p><p>其实训练过程就是不断调整参数的过程吧</p><p>那其实只要不让参数继续过分的</p><p>向着过拟合的方向发展就可以了</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001525265.png" alt="image-20260109001525265"></p><p>所以有个简单到你都不敢相信的办法</p><p>就是提前终止训练过程</p><p>意思就是差不多就行了</p><p>不用追求那么完美</p><p>不过这种办法还是太粗糙了</p><p>像咱们这种精致的人</p><p>肯定还得追求一些更精细的办法</p><p>也就是说有没有什么办法</p><p>能够直接抑制参数的野蛮增长呢</p><p>非常简单</p><p>你想想看参数是怎么被训练出来的</p><p>是不是通过让参数往让损失函数变小的方向</p><p>不断调整</p><p>也就是梯度下降</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001711006.png" alt="image-20260109001711006"></p><p>那我们可以在损失函数中</p><p>把参数本身的值加上去</p><p>这样在参数往大了调整时</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001748033.png" alt="image-20260109001748033"></p><p>如果让损失函数减小的没有那么多</p><p>导致新的损失函数反而是变大的</p><p>那么此时调整就是不合适的</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20260109001813263.png" alt="image-20260109001813263"></p><h2 id="神经网络训练优化与高级架构"><a href="#神经网络训练优化与高级架构" class="headerlink" title="神经网络训练优化与高级架构"></a><a href="#%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E8%AE%AD%E7%BB%83%E4%BC%98%E5%8C%96%E4%B8%8E%E9%AB%98%E7%BA%A7%E6%9E%B6%E6%9E%84"></a><strong>神经网络训练优化与高级架构</strong></h2><h3 id="一、-对抗过拟合"><a href="#一、-对抗过拟合" class="headerlink" title="一、 对抗过拟合"></a><a href="#%E4%B8%80%E3%80%81-%E5%AF%B9%E6%8A%97%E8%BF%87%E6%8B%9F%E5%90%88"></a><strong>一、 对抗过拟合</strong></h3><p>为了防止模型在训练集上表现太好（过拟合），而在未知数据上表现糟糕，我们使用多种方法：</p><ol><li><strong>正则化</strong><br><strong>核心思想</strong>：在损失函数中加入“惩罚项”，抑制模型参数过大或过于复杂。</li><li><strong>L1 正则化</strong>：惩罚项为所有权重参数的绝对值之和。倾向于产生<strong>稀疏权重</strong>（部分权重为0）。</li><li><strong>L2 正则化</strong>：惩罚项为所有权重参数的平方和。倾向于让权重<strong>均匀地变小</strong>。</li><li><strong>正则化系数</strong>：控制惩罚力度的超参数。</li><li><strong>Dropout（丢弃）</strong><br><strong>核心思想</strong>：在训练过程中，随机“关闭”（置零）网络中的一部分神经元。</li><li><strong>效果</strong>：迫使网络不依赖任何单个神经元或少数路径，从而增强模型的<strong>鲁棒性</strong>和泛化能力。</li><li><strong>特点</strong>：由 Geoffrey Hinton 提出，方法简单但效果显著，有点“玄学”但有效。</li><li><strong>其他方法</strong><br>增加训练数据量。</li><li>降低模型复杂度（减少层数或神经元数）。</li><li>提前终止训练。</li></ol><h3 id="二、-神经网络基础架构演进"><a href="#二、-神经网络基础架构演进" class="headerlink" title="二、 神经网络基础架构演进"></a><a href="#%E4%BA%8C%E3%80%81-%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84%E6%BC%94%E8%BF%9B"></a><strong>二、 神经网络基础架构演进</strong></h3><h4 id="1-矩阵表示"><a href="#1-矩阵表示" class="headerlink" title="1. 矩阵表示"></a><a href="#1-%E7%9F%A9%E9%98%B5%E8%A1%A8%E7%A4%BA"></a><strong>1. 矩阵表示</strong></h4><p>将繁琐的神经元计算改写为矩阵运算，不仅公式简洁，更能利用 <strong>GPU 并行计算</strong> 加速训练和推理。</p><h4 id="2-从全连接到卷积网络"><a href="#2-从全连接到卷积网络" class="headerlink" title="2. 从全连接到卷积网络"></a><a href="#2-%E4%BB%8E%E5%85%A8%E8%BF%9E%E6%8E%A5%E5%88%B0%E5%8D%B7%E7%A7%AF%E7%BD%91%E7%BB%9C"></a><strong>2. 从全连接到卷积网络</strong></h4><ul><li><strong>全连接层</strong>：每一层的每个神经元都与上一层的所有神经元相连。处理图像时参数巨大，且无法有效捕捉空间局部特征。</li><li><strong>卷积神经网络（CNN）</strong>：<br><strong>核心创新</strong>：用<strong>卷积层</strong>替代全连接层，进行<strong>卷积运算</strong>。</li><li><strong>卷积核</strong>：一个小的权重矩阵，在输入图像上滑动，计算局部区域的加权和，提取局部特征（如边缘、纹理）。</li><li><strong>优点</strong>：<strong>参数共享</strong>极大减少了参数量；能有效捕捉图像的<strong>空间层次信息</strong>。</li><li><strong>典型结构</strong>：卷积层 + 池化层（用于降维）+ 全连接层。</li></ul><h3 id="三、-处理序列数据：从词嵌入到-RNN"><a href="#三、-处理序列数据：从词嵌入到-RNN" class="headerlink" title="三、 处理序列数据：从词嵌入到 RNN"></a><a href="#%E4%B8%89%E3%80%81-%E5%A4%84%E7%90%86%E5%BA%8F%E5%88%97%E6%95%B0%E6%8D%AE%EF%BC%9A%E4%BB%8E%E8%AF%8D%E5%B5%8C%E5%85%A5%E5%88%B0-RNN"></a><strong>三、 处理序列数据：从词嵌入到 RNN</strong></h3><h4 id="1-词嵌入"><a href="#1-词嵌入" class="headerlink" title="1. 词嵌入"></a><a href="#1-%E8%AF%8D%E5%B5%8C%E5%85%A5"></a><strong>1. 词嵌入</strong></h4><ul><li><strong>目的</strong>：将词语转化为计算机可处理的数值向量。</li><li><strong>独热编码（One-Hot）</strong>：维度极高且稀疏，无法表示词义相关性。</li><li><strong>词嵌入（Word Embedding）</strong>：将词映射到<strong>低维、稠密</strong>的连续向量空间（潜空间）。语义相近的词，其向量在空间中的距离也相近。</li><li><strong>嵌入矩阵</strong>：所有词向量的集合，通常通过训练（如 Word2Vec）得到。</li></ul><h4 id="2-循环神经网络（RNN）"><a href="#2-循环神经网络（RNN）" class="headerlink" title="2. 循环神经网络（RNN）"></a><a href="#2-%E5%BE%AA%E7%8E%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%EF%BC%88RNN%EF%BC%89"></a><strong>2. 循环神经网络（RNN）</strong></h4><ul><li><strong>核心思想</strong>：为网络引入“记忆”。每个时间步（处理一个词）的输出不仅取决于当前输入，还取决于上一个时间步的“隐藏状态”。</li><li><strong>结构</strong>：具有循环连接，能将历史信息逐步向后传递。</li><li><strong>用途</strong>：处理文本、语音、时间序列等有顺序关系的数据。</li><li><strong>缺陷</strong>：<br><strong>长程依赖问题</strong>：信息随步长增加而衰减或爆炸。</li><li><strong>串行计算</strong>，训练效率低。</li></ul><h3 id="四、-Transformer：突破性的架构"><a href="#四、-Transformer：突破性的架构" class="headerlink" title="四、 Transformer：突破性的架构"></a><a href="#%E5%9B%9B%E3%80%81-Transformer%EF%BC%9A%E7%AA%81%E7%A0%B4%E6%80%A7%E7%9A%84%E6%9E%B6%E6%9E%84"></a><strong>四、 Transformer：突破性的架构</strong></h3><h4 id="1-核心：自注意力机制"><a href="#1-核心：自注意力机制" class="headerlink" title="1. 核心：自注意力机制"></a><a href="#1-%E6%A0%B8%E5%BF%83%EF%BC%9A%E8%87%AA%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6"></a><strong>1. 核心：自注意力机制</strong></h4><ul><li><strong>目标</strong>：让模型在处理一个词时，能同时“注意”到句子中所有其他词的信息，且能衡量它们的重要性。</li><li><strong>过程</strong>：<br>为每个输入词向量生成三个向量：<strong>查询（Q）、键（K）、值（V）</strong>。</li><li>用当前词的 <strong>Q</strong> 与所有词的 <strong>K</strong> 计算相似度（得分）。</li><li>用 <strong>Softmax</strong> 将得分归一化为权重。</li><li>用权重对所有的 <strong>V</strong> 进行加权求和，得到当前词的<strong>新表示</strong>，它融合了全局上下文信息。</li><li><strong>多头注意力</strong>：并行运行多个自注意力机制（多个“头”），让模型从不同角度关注信息，最后将结果合并。这是 Transformer 的<strong>核心创新</strong>。</li></ul><h4 id="2-Transformer-整体架构"><a href="#2-Transformer-整体架构" class="headerlink" title="2. Transformer 整体架构"></a><a href="#2-Transformer-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84"></a><strong>2. Transformer 整体架构</strong></h4><ul><li><strong>编码器</strong>：负责理解输入序列。包含多头注意力层和前馈神经网络层，层间有残差连接和层归一化。</li><li><strong>解码器</strong>：负责生成输出序列。比编码器多一个“编码器-解码器注意力层”，用于关注编码器的输出。</li><li><strong>位置编码</strong>：因为自注意力本身没有顺序信息，需要额外加入位置编码向量来告诉模型词的顺序。</li><li><strong>意义</strong>：彻底抛弃了 RNN 的串行结构，支持<strong>高度并行化训练</strong>，效果好且可扩展性强，成为现代大语言模型的<strong>基石</strong>。GPT 系列模型主要基于 Transformer 的解码器部分构建。</li></ul><h3 id="五、-大模型关键术语速览"><a href="#五、-大模型关键术语速览" class="headerlink" title="五、 大模型关键术语速览"></a><a href="#%E4%BA%94%E3%80%81-%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%85%B3%E9%94%AE%E6%9C%AF%E8%AF%AD%E9%80%9F%E8%A7%88"></a><strong>五、 大模型关键术语速览</strong></h3><table><thead><tr><th>概念</th><th>简要说明</th></tr></thead><tbody><tr><td><strong>大模型 &#x2F; 大语言模型</strong></td><td>参数量巨大的模型，用于处理自然语言。</td></tr><tr><td><strong>预训练 &#x2F; 微调</strong></td><td>先在海量通用数据上训练基础模型，再用特定任务数据精细调整。</td></tr><tr><td><strong>推理</strong></td><td>使用训练好的模型根据输入生成输出的过程。</td></tr><tr><td><strong>涌现</strong></td><td>当模型规模达到一定程度时，突然展现出的小规模模型不具备的能力。</td></tr><tr><td><strong>开源 &#x2F; 闭源模型</strong></td><td>是否公开模型权重和训练代码。</td></tr><tr><td><strong>私有化部署</strong></td><td>将模型部署在本地服务器或个人设备上。</td></tr><tr><td><strong>生成式 AI</strong></td><td>能够生成新内容（文本、图像等）的 AI 系统。</td></tr><tr><td><strong>上下文 &#x2F; Prompt</strong></td><td>输入给模型的所有信息，即“提示词”。</td></tr><tr><td><strong>温度 &#x2F; Top-k</strong></td><td>控制生成内容随机性的参数。</td></tr><tr><td><strong>幻觉</strong></td><td>模型生成看似合理但不符合事实或逻辑的内容。</td></tr><tr><td><strong>检索增强生成（RAG）</strong></td><td>先从外部知识库检索相关信息，再结合信息生成答案，减少幻觉。</td></tr><tr><td><strong>向量数据库</strong></td><td>专门用于存储和检索向量化数据（如词向量）的数据库。</td></tr><tr><td><strong>智能体（Agent）</strong></td><td>能感知环境、规划、调用工具以完成复杂任务的 AI 程序。</td></tr><tr><td><strong>模型压缩</strong></td><td>使模型变小、变快的方法，如<strong>量化、蒸馏、剪枝</strong>。</td></tr><tr><td><strong>思维链</strong></td><td>引导模型通过逐步推理（“让我们一步步思考…”）来提升复杂问题回答的准确性。</td></tr></tbody></table><hr>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/AI%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%AD%A6%E4%B9%A0/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/AI%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%AD%A6%E4%B9%A0/"/>
    <published>2025-12-23T17:52:26.000Z</published>
    <summary>[] .video-container { position: relative; width: 100%; padding-top: 56.25%; /* 16:9 aspect ratio (height/width = 9/16 * 100%) */ } .video-container iframe { position: absolute;</summary>
    <title>AI大模型学习</title>
    <updated>2026-01-17T14:33:42.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <content>
      <![CDATA[<h4 id="一、python基础语法-08-47"><a href="#一、python基础语法-08-47" class="headerlink" title="一、python基础语法 ﻿08:47"></a><a href="#%E4%B8%80%E3%80%81python%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95-08-47"></a>一、python基础语法 ﻿08:47</h4><h5 id="1-Python基础语法的主要知识点-11-23"><a href="#1-Python基础语法的主要知识点-11-23" class="headerlink" title="1. Python基础语法的主要知识点 ﻿11:23"></a><a href="#1-Python%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95%E7%9A%84%E4%B8%BB%E8%A6%81%E7%9F%A5%E8%AF%86%E7%82%B9-11-23"></a>1. Python基础语法的主要知识点 ﻿11:23</h5><ul><li><p><img src="https://yqcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-1?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-xTdHOZrZcnEt1Wd6ZfcSSdy9EIs=&to=119&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Yangquan,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-e3e5470fe45c8510415775d4a4624afdb1e7417b4a6f05197495cc9b68998ce66b17aca0140eacf991dc906f7f27748f68117fd9c21a49ca305a5e1275657320&expires=8h&r=574195163&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-1&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-1&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=718800a01e5121ca8395a30becffee929b0c4e2d279992da&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></p></li><li><p>数据类型：包括int、float、string等基本数据类型及其对应方法，如字符串的切割、切片等操作</p></li><li><p>函数：函数的定义、调用和使用方法，学到递归即可</p></li><li><p>面向对象编程：类的概念和使用</p></li><li><p>进阶内容：<br>异常处理</p></li><li><p>内置模块的使用（如OS模块）</p></li><li><p>模块化编程</p></li><li><p>基础部分（数据类型和函数）必须掌握</p></li><li><p>面向对象编程建议学习</p></li><li><p>更高级内容可根据兴趣选择性学习</p></li><li><p>推荐B站等平台上的Python基础教程</p></li></ul><h5 id="2-环境配置与工具使用-13-54"><a href="#2-环境配置与工具使用-13-54" class="headerlink" title="2. 环境配置与工具使用 ﻿13:54"></a><a href="#2-%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E4%B8%8E%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8-13-54"></a>2. 环境配置与工具使用 ﻿13:54</h5><h6 id="1）Python安装与版本管理-14-50"><a href="#1）Python安装与版本管理-14-50" class="headerlink" title="1）Python安装与版本管理 ﻿14:50"></a><a href="#1%EF%BC%89Python%E5%AE%89%E8%A3%85%E4%B8%8E%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86-14-50"></a>1）Python安装与版本管理 ﻿14:50</h6><ul><li><p><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-2?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-7g6X5BFksW332LvHn5eNIrh54XE=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-1bf45a877f6df9ec30190b61c96eb17486b583ce90e62f985e1eeafec1f63c073f45f83b9114f2f947732e05893d05f18747416aa91b6114305a5e1275657320&expires=8h&r=771730252&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-2&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-2&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=a7e1f23860a769ab07a05bfe2a8de2d58deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></p></li><li><p>版本选择：<br>推荐Python 3.10或3.11版本</p></li><li><p>Mac电脑内置Python 3.8，可覆盖安装</p></li><li><p>Windows避免安装在C盘</p></li><li><p>Mac无盘符限制</p></li><li><p>Windows使用where python命令</p></li><li><p>Mac使用where python3命令</p></li><li><p>注意：C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps\python.exe不是真正的安装路径</p></li></ul><h6 id="2）Jupyter-Notebook使用-14-25"><a href="#2）Jupyter-Notebook使用-14-25" class="headerlink" title="2）Jupyter Notebook使用 ﻿14:25"></a><a href="#2%EF%BC%89Jupyter-Notebook%E4%BD%BF%E7%94%A8-14-25"></a>2）Jupyter Notebook使用 ﻿14:25</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-3?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-EeASQkafxLuSE/2tfpJ2dsYoBZI=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-9d394fde795b531d2580561bc0a16c4e7e346fb5c0f7eb0f9b103e80a63da57b1a0bda9eebd39e4e3971fa51154e0fbe31ff62bef839560d305a5e1275657320&expires=8h&r=489872292&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-3&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-3&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=718800a01e5121ca44342240fa99746f4c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>安装方法：</li><li>启动方式：</li></ul><p>在目标目录下打开终端输入jupyter notebook</p><ul><li>启动后会在当前目录打开</li></ul><p>浏览器配置</p><p>：</p><ul><li>推荐使用Chrome浏览器</li><li>可复制带token的URL在其他浏览器打开</li></ul><p>基本操作</p><p>：</p><ul><li>代码单元格与Markdown单元格切换</li><li>运行快捷键：Shift+Enter或Ctrl+Enter</li><li>保存快捷键：Ctrl+S</li></ul><p>优势</p><p>：</p><ul><li>支持分段执行代码</li><li>适合教学演示和实验性编程</li></ul><h6 id="3）PyCharm与VS-Code选择"><a href="#3）PyCharm与VS-Code选择" class="headerlink" title="3）PyCharm与VS Code选择"></a><a href="#3%EF%BC%89PyCharm%E4%B8%8EVS-Code%E9%80%89%E6%8B%A9"></a>3）PyCharm与VS Code选择</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-4?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-JZTl6SMvm1aFLPnDfMJLuNNe7Rk=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-1773fed66c0f1d0a1a4cf0128c3249422f18a92631a23ce8fc325850cb1df3bdc46b92fa6b1c915bfca643d8db9ffd4d726695a774e29a57305a5e1275657320&expires=8h&r=145751520&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-4&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-4&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=3612dd02eb4608ab5d190a3cea8128ca8deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>PyCharm<br>：</li></ul><p>推荐社区版，无需专业版</p><ul><li>启动较慢，需耐心等待</li><li>Mac用户直接使用社区版</li></ul><p>VS Code</p><p>：</p><ul><li>轻量级替代方案</li><li>适合配置较低的电脑</li></ul><p>选择建议</p><p>：</p><ul><li>根据个人习惯选择工具</li><li>不要纠结于工具版本</li><li>电脑性能较差时推荐VS Code</li></ul><h6 id="4）环境变量配置-32-05"><a href="#4）环境变量配置-32-05" class="headerlink" title="4）环境变量配置 ﻿32:05"></a><a href="#4%EF%BC%89%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE-32-05"></a>4）环境变量配置 ﻿32:05</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-5?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-UucxegEjTz5pM2w5nCJdVbEUGrA=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-f3b166f2b9ec8bb0b9454d6f41cc9f6d2c78e82a018cb6096c2a6eccfe8e2a378949d2ace53e61cc1fa0f8867a009f4bc79aaf275d1df5fc305a5e1275657320&expires=8h&r=740056837&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-5&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-5&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=718800a01e5121ca56afef5411c6cb254c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>.env文件<br>：</li></ul><p>用于存储敏感信息如API KEY</p><ul><li>格式：OPENAI_API_KEY&#x3D;”your_key_here”</li></ul><p>代理设置：</p><p>加载方法：</p><h6 id="5）常用命令"><a href="#5）常用命令" class="headerlink" title="5）常用命令"></a><a href="#5%EF%BC%89%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4"></a>5）常用命令</h6><ul><li>目录操作<br>：</li></ul><p>cd：切换目录</p><ul><li>ls(Mac)&#x2F;dir(Windows)：列出当前目录内容</li></ul><p>Python相关</p><p>：</p><ul><li>python —version：查看Python版本</li><li>pip install package_name：安装Python包</li></ul><p>Jupyter相关</p><p>：</p><ul><li>jupyter notebook：启动Notebook</li><li>!pip install package_name：在Notebook中安装包</li></ul><h4 id="二、大模型的认知"><a href="#二、大模型的认知" class="headerlink" title="二、大模型的认知"></a><a href="#%E4%BA%8C%E3%80%81%E5%A4%A7%E6%A8%A1%E5%9E%8B%E7%9A%84%E8%AE%A4%E7%9F%A5"></a>二、大模型的认知</h4><h5 id="1-env文件问题-32-16"><a href="#1-env文件问题-32-16" class="headerlink" title="1. env文件问题 ﻿32:16"></a><a href="#1-env%E6%96%87%E4%BB%B6%E9%97%AE%E9%A2%98-32-16"></a>1. env文件问题 ﻿32:16</h5><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-6?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-u/MDYpThTS0wBOL3x4YWWc6sBUc=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-be110507975da4f7f1c40f44e19794dfda0916cfe9015510c9ebce8be8d45d67f1371b4e7ba41e94af41a6f0ed55359096c4741ad92e9bcd305a5e1275657320&expires=8h&r=511869968&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-6&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-6&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=3612dd02eb4608abcbc79c52d488987e8deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>创建步骤<br>：</li></ul><p>Windows系统需先显示文件扩展名</p><ul><li>右键新建文本文件后删除前缀，只保留”.env”后缀</li><li>内容必须使用英文引号，格式为：</li></ul><p>注意事项</p><p>：</p><ul><li>禁止将变量放入系统环境变量</li><li>Jupyter用户需重启内核才能识别新建的env文件</li><li>建议直接复制课件内容避免格式错误</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-7?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-j9ArjIPJCdYi5xtqGQMj+X3wT6g=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-6397271a13347297cda92d3430c620c2aa50b59cfae5ef13d04f63cf1b2cabba6c4fe1960f5d014e1c5b4feb25962f92369c695392e1c972305a5e1275657320&expires=8h&r=965441738&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-7&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-7&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=718800a01e5121cabf9c9f5b8bcce4519b0c4e2d279992da&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li></ul><p>内容规范</p><p>：</p><ul><li>仅包含API_KEY和BASE_URL两个变量</li><li>所有符号必须为英文半角（包括引号、等号）</li><li>变量名严格区分大小写</li></ul><h5 id="2-mac问题-36-38"><a href="#2-mac问题-36-38" class="headerlink" title="2. mac问题 ﻿36:38"></a><a href="#2-mac%E9%97%AE%E9%A2%98-36-38"></a>2. mac问题 ﻿36:38</h5><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-8?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-b128ju0B/rSzZV4RMXTBJ6UUd5E=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-636ad972efc2446118e7ffda020c04fd9f259a8d13af7e0a264a2522afeed634ee8e9aefa9153c27b3086499dce020a7d41643a96f2cf498305a5e1275657320&expires=8h&r=944619035&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-8&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-8&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=2a0349c66f068e0f07c7abd6ae653f448deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>特殊处理<br>：</li></ul><p>通过PyCharm&#x2F;VSCode图形界面创建.env文件</p><ul><li>在IDE中右键项目目录选择”New File”创建</li><li>注意.env是隐藏文件，在Finder中默认不可见</li></ul><p>验证方法</p><p>：</p><ul><li>使用代码编辑器确认文件内容</li><li>确保没有多余空格或换行符</li></ul><h5 id="3-全局环境和虚拟环境问题-40-13"><a href="#3-全局环境和虚拟环境问题-40-13" class="headerlink" title="3. 全局环境和虚拟环境问题 ﻿40:13"></a><a href="#3-%E5%85%A8%E5%B1%80%E7%8E%AF%E5%A2%83%E5%92%8C%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E9%97%AE%E9%A2%98-40-13"></a>3. 全局环境和虚拟环境问题 ﻿40:13</h5><h6 id="1）全局环境和虚拟环境的概念"><a href="#1）全局环境和虚拟环境的概念" class="headerlink" title="1）全局环境和虚拟环境的概念"></a><a href="#1%EF%BC%89%E5%85%A8%E5%B1%80%E7%8E%AF%E5%A2%83%E5%92%8C%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E7%9A%84%E6%A6%82%E5%BF%B5"></a>1）全局环境和虚拟环境的概念</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-9?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-2Jgn+YPz7F4IhPScAgyhlQdiRXQ=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-4a8ebd782ad3246f6a58b81b4005d8a3194fd6a08e34315eeb23f1b04e102d1139a4b9b92747c8d12fffeb0f6072f9e2b5d956feccdedf5e305a5e1275657320&expires=8h&r=665301168&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-9&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-9&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=12146e4ffd7df3c9b7d6c8393faaedc69b0c4e2d279992da&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>核心区别<br>：</li></ul><p>全局环境：通过pip install直接安装到系统Python</p><ul><li>虚拟环境：为每个项目创建隔离的Python运行环境</li></ul><p>典型场景</p><p>：</p><ul><li>当不同项目需要同一库的不同版本时（如A库需0.1.0和0.1.1）</li><li>避免卸载重装导致的版本冲突</li></ul><p>优势对比</p><p>：</p><ul><li>虚拟环境允许并行存在多个依赖版本</li><li>项目迁移时可通过requirements.txt重建环境</li></ul><h6 id="2）GitHub示例操作-44-18"><a href="#2）GitHub示例操作-44-18" class="headerlink" title="2）GitHub示例操作 ﻿44:18"></a><a href="#2%EF%BC%89GitHub%E7%A4%BA%E4%BE%8B%E6%93%8D%E4%BD%9C-44-18"></a>2）GitHub示例操作 ﻿44:18</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-10?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-aUsGhjRvYTMq+RbwbzvSBmIfKJQ=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-432f4f7334996d2cf245d23dabea1856bd4385eae007dd999244da7d6ccd6e79b957df9b05c3919840840249a3b7a07c8064367bb72d4cc2305a5e1275657320&expires=8h&r=207792599&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-10&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-10&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=738aa28698fb94aa61061f9ec8ddb82f8deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>行业实践<br>：</li></ul><p>项目根目录通常包含requirements.txt或Pipfile</p><ul><li>示例：Dify项目使用Dockerfile管理环境</li></ul><p>依赖导出</p><p>：</p><ul><li>使用pip freeze &gt; requirements.txt命令</li><li>该文件记录所有依赖包及其精确版本号</li></ul><p>环境重建：</p><h4 id="三、Python环境使用详解-45-21"><a href="#三、Python环境使用详解-45-21" class="headerlink" title="三、Python环境使用详解 ﻿45:21"></a><a href="#%E4%B8%89%E3%80%81Python%E7%8E%AF%E5%A2%83%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3-45-21"></a>三、Python环境使用详解 ﻿45:21</h4><h5 id="1-搜索Python相关资源"><a href="#1-搜索Python相关资源" class="headerlink" title="1. 搜索Python相关资源"></a><a href="#1-%E6%90%9C%E7%B4%A2Python%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90"></a>1. 搜索Python相关资源</h5><h6 id="1）GitHub上的RAG项目"><a href="#1）GitHub上的RAG项目" class="headerlink" title="1）GitHub上的RAG项目"></a><a href="#1%EF%BC%89GitHub%E4%B8%8A%E7%9A%84RAG%E9%A1%B9%E7%9B%AE"></a>1）GitHub上的RAG项目</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-11?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-4NqRqJSCdSAnIv187EqthjjYdM0=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-2cb95e11025319ea3ec639378ce37491407b8ed91348359972e56181ee7bd17ed8532f626452a98f57e8e9ba6023109a6b6c70a447bf9ad2305a5e1275657320&expires=8h&r=352258822&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-11&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-11&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=12146e4ffd7df3c9bc45b0a9363017654c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>RAGFlow项目：开源RAG（检索增强生成）引擎，基于深度文档理解技术，支持Python语言开发（49.1%代码占比）</li><li>项目特点<br>：</li></ul><p>包含79.8k个相关仓库结果</p><ul><li>支持多语言开发（TypeScript 47.0%，JavaScript 14%）</li><li>最新更新时间为1小时前，活跃度较高</li></ul><h6 id="2）项目依赖管理方式"><a href="#2）项目依赖管理方式" class="headerlink" title="2）项目依赖管理方式"></a><a href="#2%EF%BC%89%E9%A1%B9%E7%9B%AE%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86%E6%96%B9%E5%BC%8F"></a>2）项目依赖管理方式</h6><ul><li><img src="https://yqcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-12?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-wFNwvBe3pMcqs0BbjnH4MPGb0Io=&to=119&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Yangquan,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-60248f215d1402855bcad063fce751838566b3e1e9d43a7bccd151a0d9e977e07ef9f4a213721dd03f3aeb8f5fba3f786e2984ef74575615305a5e1275657320&expires=8h&r=160719341&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-12&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-12&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=4d291be9b94219595d190a3cea8128ca8deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>依赖管理<br>：</li></ul><p>现代Python项目普遍采用Docker容器化部署</p><ul><li>通过Dockerfile配置环境依赖（如Python 3.8+、JDK等）</li><li>包含NLTK数据、Tika服务器等专业组件</li></ul><p>典型依赖项</p><p>：</p><ul><li>基础库：libglib2.0、libgdiplus</li><li>Python包：python-pptx、selenium</li><li>工具链：docker-ce、apt-cacher-ng</li></ul><h6 id="3）环境配置要点"><a href="#3）环境配置要点" class="headerlink" title="3）环境配置要点"></a><a href="#3%EF%BC%89%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E8%A6%81%E7%82%B9"></a>3）环境配置要点</h6><ul><li><img src="https://yqcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-13?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-69oYdj7U5mNyrNbdxCqPZgU+E5I=&to=119&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Yangquan,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-161d5ac282b590dbcc7b2e3de76b0d2757ef43dfd97f67482dcda0c11b0a0584b0e9c37d63b3b7481a7bcee0689c82e8f568de92f9f03fda305a5e1275657320&expires=8h&r=359147062&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-13&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-13&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=83f2b583554fba159c9dcc2c5a4d86874c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>关键配置<br>：</li></ul><p>使用虚拟环境隔离项目依赖</p><ul><li>避免使用系统默认Python路径（如WindowsApps下的python.exe）</li><li>通过.env文件管理API密钥等敏感信息</li></ul><p>注意事项</p><p>：</p><ul><li>环境变量引号必须使用英文格式</li><li>不建议将密钥存入系统环境变量</li><li>典型项目结构包含requirements.txt文件管理Python依赖</li></ul><h5 id="2-requirements-txt文件-46-00"><a href="#2-requirements-txt文件-46-00" class="headerlink" title="2. requirements.txt文件 ﻿46:00"></a><a href="#2-requirements-txt%E6%96%87%E4%BB%B6-46-00"></a>2. requirements.txt文件 ﻿46:00</h5><ul><li><img src="https://xacu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-14?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-OxX2/q9ctdB9vzLCy8JsS5na2Z0=&to=128&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Xian,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-77324a899d9c08ffc7f6cb094d76a1ae398c251980b4b54fc5c50b1986244f0ce55f44b23b8be4e004a0b5e6672185e6327f40277348f836305a5e1275657320&expires=8h&r=371058402&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-14&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-14&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=cf87eda222dfadb79bb24ef744090da98deec605ca7b091f&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>项目依赖管理：在非Docker项目中，requirements.txt是Python项目常见的依赖配置文件</li><li>文件内容：记录了项目所需的所有Python模块及其精确版本号</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-15?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-QeKQgjMpjdVdfFUqUGbSwr17LV0=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-4bd5b43e650416e720d517871603c9e154259dbc58180a71b375e48e5360be028eaa8e93073929836b7c2af1730d78758637e564a2999e13305a5e1275657320&expires=8h&r=719367820&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-15&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-15&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=875e0ff32ac7bd89ec8b61f085efb7e49b0c4e2d279992da&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>典型示例：</li></ul><h6 id="1）文件作用"><a href="#1）文件作用" class="headerlink" title="1）文件作用"></a><a href="#1%EF%BC%89%E6%96%87%E4%BB%B6%E4%BD%9C%E7%94%A8"></a>1）文件作用</h6><ul><li>环境重建：通过该文件可以在新环境中快速安装相同版本的依赖</li><li>版本控制：确保不同开发者使用完全一致的依赖版本，避免兼容性问题</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-16?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-15kEX4qsbFSJ26SBMGpr/Pfd5pY=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-357d63f8d50e15b99bc9b7eaa39d56d0cf6651dfa62028d6376648d428c21e1b5079668402f7abe3675cf63f622d02108795719c726f8ad2305a5e1275657320&expires=8h&r=778508889&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-16&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-16&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=66239664855e80686faf624695b8f8f85d769a06a6f8ff993639323619ab123a&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>使用方法<br>：</li></ul><p>创建虚拟环境后执行pip install -r requirements.txt</p><ul><li>全局环境安装需谨慎，建议使用虚拟环境</li></ul><h6 id="2）导出依赖"><a href="#2）导出依赖" class="headerlink" title="2）导出依赖"></a><a href="#2%EF%BC%89%E5%AF%BC%E5%87%BA%E4%BE%9D%E8%B5%96"></a>2）导出依赖</h6><ul><li>导出方法：使用pip freeze &gt; requirements.txt命令可将当前环境所有安装包导出</li><li>注意事项<br>：</li></ul><p>仅导出项目必要的依赖，避免包含无关包</p><ul><li>导出版本号确保精确匹配</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-17?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-nKwF7LceyjwaEeQfGPLTImcir+o=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-5e7a02a14ef07ea227116e28969fc72dad9ab82a7323bc512ae858d64a1440849b08ea25ca0d8942d6281632f9e60f1950e0db9d9a2702d0305a5e1275657320&expires=8h&r=751366413&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-17&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-17&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=875e0ff32ac7bd8947990d12e1e064b74c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li></ul><p>版本管理技巧</p><p>：</p><ul><li>全局环境与虚拟环境可以安装不同版本</li><li>项目开发时应固定主要依赖版本</li></ul><h6 id="3）与Docker的区别"><a href="#3）与Docker的区别" class="headerlink" title="3）与Docker的区别"></a><a href="#3%EF%BC%89%E4%B8%8EDocker%E7%9A%84%E5%8C%BA%E5%88%AB"></a>3）与Docker的区别</h6><ul><li>轻量级方案：相比Docker容器化，requirements.txt提供更轻量的环境配置方案</li><li>适用场景<br>：</li></ul><p>快速分享Python项目依赖配置</p><ul><li>不需要完整系统环境复现的场景</li><li>开发初期快速搭建环境</li></ul><h5 id="3-问题答疑-47-34"><a href="#3-问题答疑-47-34" class="headerlink" title="3. 问题答疑 ﻿47:34"></a><a href="#3-%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91-47-34"></a>3. 问题答疑 ﻿47:34</h5><h6 id="1）全局环境与虚拟环境-47-51"><a href="#1）全局环境与虚拟环境-47-51" class="headerlink" title="1）全局环境与虚拟环境 ﻿47:51"></a><a href="#1%EF%BC%89%E5%85%A8%E5%B1%80%E7%8E%AF%E5%A2%83%E4%B8%8E%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83-47-51"></a>1）全局环境与虚拟环境 ﻿47:51</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-18?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-x/dW36NOD4zol8W+MDMcJqMfrOo=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-41826015bf2fb90f42a26b8d22fffaf4ed1d2b2e3a3c0308ed65ec21f3542a3798b9699fde12fbb7654ca539a1885b5b4d1efe65067b8260305a5e1275657320&expires=8h&r=148477954&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-18&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-18&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=66239664855e8068173f2ae99a7b5b754c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>环境区别<br>:</li></ul><p>全局环境：通过pip install a&#x3D;1.1.1安装的包对所有项目生效</p><ul><li>虚拟环境：每个项目独立环境（如a&#x3D;0.1.0），避免包版本冲突</li></ul><p>项目实践：建议每个项目创建独立虚拟环境，防止不同项目间的依赖冲突</p><h6 id="2）设置Python环境-48-27"><a href="#2）设置Python环境-48-27" class="headerlink" title="2）设置Python环境 ﻿48:27"></a><a href="#2%EF%BC%89%E8%AE%BE%E7%BD%AEPython%E7%8E%AF%E5%A2%83-48-27"></a>2）设置Python环境 ﻿48:27</h6><ul><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-19?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-6dFLNc9oS5bymWiy45Qxhiow69Q=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-aed8cf7f410ac1216ca84a29f0d0b2ace81a895a46b6bf0bb5e1edaae0df7b15261aa6fcf703c0939e12f4011da1440937df430708a6bc16305a5e1275657320&expires=8h&r=960790681&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-19&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-19&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=b3434a369726e9249598d5fd593929895d769a06a6f8ff993639323619ab123a&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>环境查询<br>：</li></ul><p>使用where python命令查看当前使用的Python解释器路径</p><ul><li>第一个显示的路径即为当前激活环境</li></ul><p>环境切换</p><p>：</p><ul><li>在PyCharm中通过Settings &gt; Project &gt; Python Interpreter修改</li><li>可添加系统环境（System）或指定虚拟环境路径</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-20?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-4nCJW3Ign3Rjiq6yFMCBKdB8Oo8=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-98c4fd0a2739a159d33133f8b6eb0deab6ce9b8bfde1be0f4d83ea9a969d4385635d1a5ce8141ccbbd645daa2ad559895f6bb07b709c5aaa305a5e1275657320&expires=8h&r=537284088&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-20&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-20&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=66239664855e8068c32f23017ea016b05d769a06a6f8ff993639323619ab123a&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li></ul><p>配置选项</p><p>：</p><ul><li>System：全局Python环境</li><li>Virtualenv：虚拟环境</li><li>Conda：Anaconda环境</li><li>Pipenv：Pipenv管理环境</li></ul><p>操作步骤</p><p>：</p><ul><li>点击”Add Interpreter”</li><li>选择环境类型</li><li>指定解释器路径（如D:\Python310\python.exe）</li></ul><h6 id="3）虚拟环境的使用-49-12"><a href="#3）虚拟环境的使用-49-12" class="headerlink" title="3）虚拟环境的使用 ﻿49:12"></a><a href="#3%EF%BC%89%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E7%9A%84%E4%BD%BF%E7%94%A8-49-12"></a>3）虚拟环境的使用 ﻿49:12</h6><ul><li><img src="https://yqcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-21?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-7jLFkxB6FxeU08+5uhpxsgn8Yeg=&to=119&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Yangquan,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-8e9c442e1d87f4f47e0e8a5f8301dab4878bcedf577c0be0875b21f332c2b8b66ca3420c05c8026f60b279b4c5632935f2fac3c06a1329fc305a5e1275657320&expires=8h&r=143797820&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-21&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-21&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=1524a5cd531d02e5ccc7bc964f060af44c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li><li>存储位置<br>：</li></ul><p>默认路径：C:\Users\Administrator\llm_agent</p><ul><li>包含不同项目的独立环境（如langchain、RAG等）</li></ul><p>创建原则</p><p>：</p><ul><li>PyCharm一般使用全局环境</li><li>项目开发时需创建专属虚拟环境</li><li>通过venv或virtualenv工具创建</li><li><img src="https://bdcu01.baidupcs.com/file/p-f26333f5f50c2d48e13625874f318371-40-2025042100-22?bkt=en-3de6f374fcad9f514a94920d227b7f50&fid=282335-250528-&time=1765207027&sign=FDTAXUVGEQlBHSKfWqij-GBWOGYTBgG0KqHy7wNbwoLTVMyJyK6xE-muVY0OJdpEoghIsywItzHJu5L6c=&to=136&size=10&sta_dx=10&sta_cs=0&sta_ft=&sta_ct=7&sta_mt=7&fm2=MH,Baoding,Anywhere,,%E5%B9%BF%E4%B8%9C,cnc&ctime=0&mtime=0&dt3=0&resv0=-1&resv1=0&resv2=rlim&resv3=5&resv4=10&vuk=0&iv=2&vl=0&htype=&randtype=&newver=1&newfm=1&secfm=1&flow_ver=3&pkey=en-3a757c683469977b6ecbb793adf48e76cba8bdacf7adf1ed36cfd28cceaf1a85029dafb1c2f9b31479aab4e4414aada59f2cb109bba34fad305a5e1275657320&expires=8h&r=988533937&vbdid=-&fin=p-f26333f5f50c2d48e13625874f318371-40-2025042100-22&fn=p-f26333f5f50c2d48e13625874f318371-40-2025042100-22&rtype=1&dp-logid=9084176436728216142&dp-callid=0.1&hps=1&tsl=0&csl=0&fsl=-1&csign=dmayhhcqdS1jXSxjkf6DN1P7N8o=&so=0&ut=1&uter=1&serv=-1&uc=741949868&ti=66239664855e80684cf9f0f2313dbfba4c88d07557ce4a43305a5e1275657320&hflag=30&from_type=&adg=n&reqlabel=250528_n_6b9a84f07cc8d87d9fb3f04e181a8479_0_6e9ee3c1076923df6c6b82e025aca87e&chkv=5&bid=250528&by=themis" alt="img"></li></ul><p>管理技巧</p><p>：</p><ul><li>环境命名建议与项目名称关联（如langchain_env）</li><li>路径中应包含Scripts\python.exe可执行文件</li><li>激活后终端提示符会显示环境名称</li></ul><p>最佳实践</p><p>：</p><ul><li>开发时：使用项目专属虚拟环境</li><li>测试时：可切换至全局环境验证兼容性</li><li>部署时：通过requirements.txt固化依赖版本</li></ul><h5 id="4-VScode-51-24"><a href="#4-VScode-51-24" class="headerlink" title="4. VScode ﻿51:24"></a><a href="#4-VScode-51-24"></a>4. VScode ﻿51:24</h5><ul><li>主要用途：常被当作记事本使用，但实际是功能强大的代码编辑器</li><li>汉化设置<br>：</li></ul><p>搜索安装”Chinese”插件实现汉化</p><ul><li>默认英文界面，汉化后更易理解但可能影响准确性</li></ul><p>插件推荐</p><p>：</p><ul><li>Code Runner：用于运行代码</li><li>Python扩展：支持Python开发</li><li>Jupyter支持：可运行.ipynb文件（但老师个人不推荐）</li></ul><p>优势特点</p><p>：</p><ul><li>插件生态丰富，支持多种语言</li><li>内存占用小，适合配置较低的设备</li><li>支持文件夹项目管理</li></ul><p>使用建议</p><p>：</p><ul><li>初学者可先汉化后逐步过渡到英文</li><li>虚拟环境设置需自行搜索配置</li></ul><h5 id="5-PyCharm-55-17"><a href="#5-PyCharm-55-17" class="headerlink" title="5. PyCharm ﻿55:17"></a><a href="#5-PyCharm-55-17"></a>5. PyCharm ﻿55:17</h5><ul><li>使用习惯：老师主要开发工具，已习惯英文界面</li><li>对比优势<br>：</li></ul><p>专业Python IDE，功能更全面</p><ul><li>但内存占用较大</li></ul><p>汉化说明：支持汉化但不推荐，可能影响功能理解</p><h5 id="6-Anaconda-55-38"><a href="#6-Anaconda-55-38" class="headerlink" title="6. Anaconda ﻿55:38"></a><a href="#6-Anaconda-55-38"></a>6. Anaconda ﻿55:38</h5><ul><li>适用人群：不推荐零基础学习者使用</li><li>主要问题<br>：</li></ul><p>虚拟环境概念对新手较复杂</p><ul><li>环境配置容易造成混淆</li></ul><p>替代方案：建议初学者使用PyCharm或VS Code</p><h5 id="7-应用案例-59-01"><a href="#7-应用案例-59-01" class="headerlink" title="7. 应用案例 ﻿59:01"></a><a href="#7-%E5%BA%94%E7%94%A8%E6%A1%88%E4%BE%8B-59-01"></a>7. 应用案例 ﻿59:01</h5><h6 id="1）例题-打印问题"><a href="#1）例题-打印问题" class="headerlink" title="1）例题:打印问题"></a><a href="#1%EF%BC%89%E4%BE%8B%E9%A2%98-%E6%89%93%E5%8D%B0%E9%97%AE%E9%A2%98"></a>1）例题:打印问题</h6><ul><li><p>题目解析<br>换行实现对比：<br>单引号&#x2F;双引号需手动添加转义字符\n</p></li><li><p>三引号自动支持多行文本</p></li><li><p>都是字符串类型（str）</p></li><li><p>语法形式不同但功能等价</p></li><li><p>多行文本处理时三引号更便捷</p></li><li><p>简单字符串可使用单&#x2F;双引号</p></li></ul><h6 id="2）例题-三引号作用-59-12"><a href="#2）例题-三引号作用-59-12" class="headerlink" title="2）例题:三引号作用 ﻿59:12"></a><a href="#2%EF%BC%89%E4%BE%8B%E9%A2%98-%E4%B8%89%E5%BC%95%E5%8F%B7%E4%BD%9C%E7%94%A8-59-12"></a>2）例题:三引号作用 ﻿59:12</h6><ul><li><p>题目解析<br>核心功能：<br>实现多行字符串定义</p></li><li><p>避免频繁使用转义字符</p></li><li><p>使用type()检查均为str类型</p></li><li><p>长文本处理</p></li><li><p>文档字符串(Docstring)</p></li></ul><p>需要保留原始格式的文本</p><ul><li>注：本笔记已按照康奈尔笔记法结构化整理，保留了所有关键知识点、使用建议和对比分析，并确保与课程内容完全对应。对于代码运行环境配置等实操性内容，建议结合具体开发环境进行实践验证。</li></ul><h5 id="8-在线编译器-01-00-34"><a href="#8-在线编译器-01-00-34" class="headerlink" title="8. 在线编译器 ﻿01:00:34"></a><a href="#8-%E5%9C%A8%E7%BA%BF%E7%BC%96%E8%AF%91%E5%99%A8-01-00-34"></a>8. 在线编译器 ﻿01:00:34</h5><h6 id="1）MasterCode工具介绍"><a href="#1）MasterCode工具介绍" class="headerlink" title="1）MasterCode工具介绍"></a><a href="#1%EF%BC%89MasterCode%E5%B7%A5%E5%85%B7%E4%BB%8B%E7%BB%8D"></a>1）MasterCode工具介绍</h6><ul><li>核心功能：提供在线Python代码编写和运行环境，无需本地安装</li><li>适用场景：适合初学者快速验证基础语法，解决环境配置问题</li><li>访问方式：通过网页直接体验，老师推荐的学习工具</li><li>版本信息：默认使用Python 3.9.x版本环境</li></ul><h6 id="2）基础操作指南"><a href="#2）基础操作指南" class="headerlink" title="2）基础操作指南"></a><a href="#2%EF%BC%89%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97"></a>2）基础操作指南</h6><ul><li>项目创建<br>：</li></ul><p>新建项目时可自定义项目名称（如P007）</p><ul><li>详情设置保持默认即可</li></ul><p>文件管理</p><p>：</p><ul><li>可删除默认生成的文件</li><li>支持新建.py文件（如demo.py）</li></ul><p>代码执行</p><p>：</p><ul><li>右键选择”Run”运行当前文件</li><li>支持通过顶部按钮运行主程序</li></ul><h6 id="3）AI辅助功能"><a href="#3）AI辅助功能" class="headerlink" title="3）AI辅助功能"></a><a href="#3%EF%BC%89AI%E8%BE%85%E5%8A%A9%E5%8A%9F%E8%83%BD"></a>3）AI辅助功能</h6><ul><li>代码解释<br>：</li></ul><p>选中代码后点击”解释”获取AI分析</p><ul><li>支持整段代码的逐行解释（如环境变量加载、实例化过程等）</li></ul><p>注释生成</p><p>：</p><ul><li>自动为方法添加功能说明文档</li><li>包含参数说明和返回值描述</li><li>用户可选择接受(Y)或拒绝(N)生成的注释</li></ul><p>代码对话</p><p>：</p><ul><li>可询问方法调用方式等具体问题</li><li>提供使用示例和返回结果说明</li></ul><h6 id="4）环境配置"><a href="#4）环境配置" class="headerlink" title="4）环境配置"></a><a href="#4%EF%BC%89%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE"></a>4）环境配置</h6><ul><li>模块安装<br>：</li></ul><p>支持通过pip install安装第三方库</p><ul><li>安装速度快（如openai 1.59.6版本）</li></ul><p>系统限制</p><p>：</p><ul><li>内存上限4GB</li><li>硬盘空间有限制</li><li>不适合运行大型项目</li></ul><h5 id="9-问题答疑-01-12-05"><a href="#9-问题答疑-01-12-05" class="headerlink" title="9. 问题答疑 ﻿01:12:05"></a><a href="#9-%E9%97%AE%E9%A2%98%E7%AD%94%E7%96%91-01-12-05"></a>9. 问题答疑 ﻿01:12:05</h5><h6 id="1）虚拟环境问题"><a href="#1）虚拟环境问题" class="headerlink" title="1）虚拟环境问题"></a><a href="#1%EF%BC%89%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E9%97%AE%E9%A2%98"></a>1）虚拟环境问题</h6><ul><li>处理方案：将在正式课程中详细讲解虚拟环境创建和使用</li><li>应用场景：后续项目开发时会实际应用</li></ul><h6 id="2）程序员工作方式"><a href="#2）程序员工作方式" class="headerlink" title="2）程序员工作方式"></a><a href="#2%EF%BC%89%E7%A8%8B%E5%BA%8F%E5%91%98%E5%B7%A5%E4%BD%9C%E6%96%B9%E5%BC%8F"></a>2）程序员工作方式</h6><ul><li>开发流程<br>：</li></ul><p>项目前期进行技术评审和框架选定</p><ul><li>在确定的技术框架基础上实现需求</li></ul><p>代码编写</p><p>：</p><ul><li>传统开发以手写代码为主</li><li>固定代码段可采用复制粘贴</li><li>现代开发可结合AI辅助</li></ul><p>岗位区分</p><p>：</p><ul><li>开发、运维、设计等不同岗位工作内容差异大</li><li>不同编程语言有对应的专用框架</li></ul><h6 id="3）网页运行原理"><a href="#3）网页运行原理" class="headerlink" title="3）网页运行原理"></a><a href="#3%EF%BC%89%E7%BD%91%E9%A1%B5%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86"></a>3）网页运行原理</h6><ul><li>课程关联：已在前期课程中多次讲解网页运行机制</li><li>框架学习：后续将学习LangChain等专业框架的使用</li></ul><h4 id="四、Streamlit使用指南-01-15-23"><a href="#四、Streamlit使用指南-01-15-23" class="headerlink" title="四、Streamlit使用指南 ﻿01:15:23"></a><a href="#%E5%9B%9B%E3%80%81Streamlit%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97-01-15-23"></a>四、Streamlit使用指南 ﻿01:15:23</h4><h5 id="1-运行方法"><a href="#1-运行方法" class="headerlink" title="1. 运行方法"></a><a href="#1-%E8%BF%90%E8%A1%8C%E6%96%B9%E6%B3%95"></a>1. 运行方法</h5><ul><li>运行命令: 使用streamlit run命令运行项目，需先定位到项目目录</li><li>目录定位方法<br>:</li></ul><p>在文件资源管理器中打开项目文件夹</p><ul><li>通过cmd或终端进入项目目录</li><li>在PyCharm等IDE中，终端默认打开当前项目目录</li></ul><h5 id="2-运行机制"><a href="#2-运行机制" class="headerlink" title="2. 运行机制"></a><a href="#2-%E8%BF%90%E8%A1%8C%E6%9C%BA%E5%88%B6"></a>2. 运行机制</h5><ul><li>自动启动: 运行后会默认打开浏览器显示界面</li><li>网络配置<br>:</li></ul><p>使用本机IP地址</p><ul><li>端口号由Streamlit自动分配</li><li>首次运行直接敲回车即可</li></ul><h5 id="3-环境注意事项"><a href="#3-环境注意事项" class="headerlink" title="3. 环境注意事项"></a><a href="#3-%E7%8E%AF%E5%A2%83%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9"></a>3. 环境注意事项</h5><ul><li>Windows系统<br>:</li></ul><p>用户名路径不要使用中文</p><ul><li>项目路径避免包含中文字符</li></ul><p>目录结构</p><p>:</p><ul><li>项目应组织在单一文件夹内</li><li>打开最上层文件夹即可访问整个项目</li></ul><h5 id="4-Streamlit优势探究"><a href="#4-Streamlit优势探究" class="headerlink" title="4. Streamlit优势探究"></a><a href="#4-Streamlit%E4%BC%98%E5%8A%BF%E6%8E%A2%E7%A9%B6"></a>4. Streamlit优势探究</h5><ul><li>作业要求<br>:</li></ul><p>对比Streamlit与其他框架的区别</p><ul><li>分析Streamlit的独特优势</li><li>研究为何选择Streamlit开发界面</li></ul><h5 id="5-开发建议"><a href="#5-开发建议" class="headerlink" title="5. 开发建议"></a><a href="#5-%E5%BC%80%E5%8F%91%E5%BB%BA%E8%AE%AE"></a>5. 开发建议</h5><ul><li>调试技巧<br>:</li></ul><p>通过与大模型对话解决编码问题</p><ul><li>遇到问题时先分析错误信息</li></ul><p>教学目的</p><p>:</p><ul><li>重点掌握实际应用方法</li><li>理解问题解决思路比直接看结果更重要</li></ul><h4 id="五、知识小结"><a href="#五、知识小结" class="headerlink" title="五、知识小结"></a><a href="#%E4%BA%94%E3%80%81%E7%9F%A5%E8%AF%86%E5%B0%8F%E7%BB%93"></a>五、知识小结</h4><table><thead><tr><th>知识点</th><th>核心内容</th><th>考试重点&#x2F;易混淆点</th><th>难度系数</th></tr></thead><tbody><tr><td>Python环境配置</td><td>全局环境与虚拟环境区别、jupyter notebook使用技巧</td><td>虚拟环境路径设置、不同系统命令差异(Win&#x2F;mac)</td><td>⭐⭐⭐</td></tr><tr><td>代码调试方法</td><td>VS Code&#x2F;PyCharm调试配置、在线编译器(MasterCode)使用</td><td>环境变量(.env)加载机制、浏览器兼容性问题</td><td>⭐⭐</td></tr><tr><td>Python基础语法</td><td>数据类型&#x2F;函数&#x2F;面向对象三大知识模块</td><td>三引号字符串特性、递归函数理解</td><td>⭐⭐⭐⭐</td></tr><tr><td>大模型开发基础</td><td>API密钥管理、Streamlit框架应用</td><td>代理设置、端点URL配置</td><td>⭐⭐⭐⭐</td></tr><tr><td>学习资源推荐</td><td>B站基础教程、AI代码解释工具</td><td>官方文档与第三方资源取舍</td><td>⭐</td></tr><tr><td>项目部署实践</td><td>requirements.txt文件作用、Docker基础概念</td><td>依赖版本冲突解决</td><td>⭐⭐⭐⭐</td></tr><tr><td>开发工具对比</td><td>PyCharm社区版&#x2F;专业版差异、Jupyter分段执行优势</td><td>内存占用优化、快捷键配置</td><td>⭐⭐</td></tr><tr><td>代码理解技巧</td><td>AI辅助注释生成、多行代码解释方法</td><td>上下文关联分析</td><td>⭐</td></tr></tbody></table>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/agi%E5%A4%A7%E6%A8%A1%E5%9E%8B/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/agi%E5%A4%A7%E6%A8%A1%E5%9E%8B/"/>
    <published>2025-12-05T20:11:45.000Z</published>
    <summary>一、python基础语法 ﻿08:47﻿1. Python基础语法的主要知识点 ﻿11:23﻿ 数据类型：包括int、float、string等基本数据类型及其对应方法，如字符串的切割、切片等操作 函数：函数的定义、调用和使用方法，学到递归即可 面向对象编程：类的概念和使用 进阶内容： 异常处理 内置模块的使用（如OS模块） 模块化编程 学习建议： 基...</summary>
    <title>agi大模型</title>
    <updated>2025-12-26T12:11:21.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="区块链" scheme="https://zhengcookie.github.io/categories/%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
    <category term="区块链智能合约语法" scheme="https://zhengcookie.github.io/tags/%E5%8C%BA%E5%9D%97%E9%93%BE%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E8%AF%AD%E6%B3%95/"/>
    <content>
      <![CDATA[<h2 id="Solidity基础语法"><a href="#Solidity基础语法" class="headerlink" title="Solidity基础语法"></a><a href="#Solidity%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95"></a>Solidity基础语法</h2><h3 id="引言"><a href="#引言" class="headerlink" title="引言"></a><a href="#%E5%BC%95%E8%A8%80"></a>引言</h3><p>Solidity是一种合约导向编程语言，用于编写智能合约，运行在Ethereum虚拟机（EVM）上。本文档将为您介绍Solidity的基本语法和概念，帮助您快速上手智能合约开发。</p><h3 id="合约结构"><a href="#合约结构" class="headerlink" title="合约结构"></a><a href="#%E5%90%88%E7%BA%A6%E7%BB%93%E6%9E%84"></a>合约结构</h3><p>在 Solidity 中，合约类似于面向对象编程语言中的类。 每个合约中可以包含 <a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-state-variables">状态变量</a>、 <a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-functions">函数</a>、 <a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-function-modifiers">函数修饰器</a>、<a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-events">事件</a>、 <a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-struct-types">结构类型</a>、 和 <a href="https://solidity-cn.readthedocs.io/zh/develop/structure-of-a-contract.html#structure-enum-types">枚举类型</a> 的声明，且合约可以从其他合约继承。</p><h4 id="状态变量"><a href="#状态变量" class="headerlink" title="状态变量"></a><a href="#%E7%8A%B6%E6%80%81%E5%8F%98%E9%87%8F"></a>状态变量</h4><p>状态变量是永久地存储在合约存储中的值。</p><figure class="highlight d"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><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><code class="hljs d"><span class="hljs-keyword">pragma</span> solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.0</span>;<br><br>contract SimpleStorage &#123;<br>    <span class="hljs-built_in">uint</span> storedData; <span class="hljs-comment">// 状态变量</span><br>    <span class="hljs-comment">// ...</span><br>&#125;<br></code></pre></td></tr></table></figure><p>有效的状态变量类型参阅 <a href="https://solidity-cn.readthedocs.io/zh/develop/types.html#types">类型</a> 章节， 对状态变量可见性有可能的选择参阅 <a href="https://solidity-cn.readthedocs.io/zh/develop/contracts.html#visibility-and-getters">可见性和 getter 函数</a> 。</p><h4 id="函数"><a href="#函数" class="headerlink" title="函数"></a><a href="#%E5%87%BD%E6%95%B0"></a>函数</h4><p>函数是合约中代码的可执行单元。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><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><code class="hljs csharp">pragma solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.0</span>;<br><br>contract SimpleAuction &#123;<br>    <span class="hljs-function">function <span class="hljs-title">bid</span>() <span class="hljs-keyword">public</span> payable</span> &#123; <span class="hljs-comment">// 函数</span><br>        <span class="hljs-comment">// ...</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p><a href="https://solidity-cn.readthedocs.io/zh/develop/control-structures.html#function-calls">函数调用</a> 可发生在合约内部或外部，且函数对其他合约有不同程度的可见性（ <a href="https://solidity-cn.readthedocs.io/zh/develop/contracts.html#visibility-and-getters">可见性和 getter 函数</a>）。</p><h4 id="函数修饰器"><a href="#函数修饰器" class="headerlink" title="函数修饰器"></a><a href="#%E5%87%BD%E6%95%B0%E4%BF%AE%E9%A5%B0%E5%99%A8"></a>函数修饰器</h4><p>函数修饰器可以用来以声明的方式改良函数语义（参阅合约章节中 <a href="https://solidity-cn.readthedocs.io/zh/develop/contracts.html#modifiers">函数</a>）。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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><code class="hljs csharp">pragma solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.22</span>;<br><br>contract Purchase &#123;<br>    address <span class="hljs-keyword">public</span> seller;<br><br>    <span class="hljs-function">modifier <span class="hljs-title">onlySeller</span>()</span> &#123; <span class="hljs-comment">// 修饰器</span><br>        require(<br>            msg.sender == seller,<br>            <span class="hljs-string">&quot;Only seller can call this.&quot;</span><br>        );<br>        _;<br>    &#125;<br><br>    <span class="hljs-function">function <span class="hljs-title">abort</span>() <span class="hljs-keyword">public</span> onlySeller</span> &#123; <span class="hljs-comment">// Modifier usage</span><br>        <span class="hljs-comment">// ...</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="事件"><a href="#事件" class="headerlink" title="事件"></a><a href="#%E4%BA%8B%E4%BB%B6"></a>事件</h4><p>事件是能方便地调用以太坊虚拟机日志功能的接口。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><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><code class="hljs csharp">pragma solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.21</span>;<br>contract SimpleAuction &#123;<br>    <span class="hljs-function"><span class="hljs-keyword">event</span> <span class="hljs-title">HighestBidIncreased</span>(<span class="hljs-params">address bidder, <span class="hljs-built_in">uint</span> amount</span>)</span>; <span class="hljs-comment">// 事件</span><br><br>    <span class="hljs-function">function <span class="hljs-title">bid</span>() <span class="hljs-keyword">public</span> payable</span> &#123;<br>        <span class="hljs-comment">// ...</span><br>        <span class="hljs-function">emit <span class="hljs-title">HighestBidIncreased</span>(<span class="hljs-params">msg.sender, msg.<span class="hljs-keyword">value</span></span>)</span>; <span class="hljs-comment">// 触发事件</span><br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>有关如何声明事件和如何在 dapp 中使用事件的信息，参阅合约章节中的 <a href="https://solidity-cn.readthedocs.io/zh/develop/contracts.html#events">事件</a>。</p><h4 id="结构类型"><a href="#结构类型" class="headerlink" title="结构类型"></a><a href="#%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B"></a>结构类型</h4><p>结构是可以将几个变量分组的自定义类型（参阅类型章节中的 <a href="https://solidity-cn.readthedocs.io/zh/develop/types.html#structs">结构体</a>）。</p><figure class="highlight d"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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><code class="hljs d"><span class="hljs-keyword">pragma</span> solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.0</span>;<br><br>contract Ballot &#123;<br>    <span class="hljs-keyword">struct</span> Voter &#123; <span class="hljs-comment">// 结构</span><br>        <span class="hljs-built_in">uint</span> weight;<br>        <span class="hljs-built_in">bool</span> voted;<br>        address <span class="hljs-built_in">delegate</span>;<br>        <span class="hljs-built_in">uint</span> vote;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="枚举类型"><a href="#枚举类型" class="headerlink" title="枚举类型"></a><a href="#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B"></a>枚举类型</h4><p>枚举可用来创建由一定数量的“常量值”构成的自定义类型（参阅类型章节中的 <a href="https://solidity-cn.readthedocs.io/zh/develop/types.html#enums">枚举类型</a>）。</p><figure class="highlight d"><table><tr><td class="gutter"><pre><span class="line">1</span><br><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><code class="hljs d"><span class="hljs-keyword">pragma</span> solidity ^<span class="hljs-number">0.4</span><span class="hljs-number">.0</span>;<br><br>contract Purchase &#123;<br>    <span class="hljs-keyword">enum</span> State &#123; Created, Locked, Inactive &#125; <span class="hljs-comment">// 枚举</span><br>&#125;<br></code></pre></td></tr></table></figure><h3 id="类型"><a href="#类型" class="headerlink" title="类型"></a><a href="#%E7%B1%BB%E5%9E%8B"></a>类型</h3><p>Solidity 是一种静态类型语言，这意味着每个变量（状态变量和局部变量）都需要被指定类型。 Solidity 提供了几种基本类型，可以用来组合出复杂类型。</p><h4 id="值类型"><a href="#值类型" class="headerlink" title="值类型"></a><a href="#%E5%80%BC%E7%B1%BB%E5%9E%8B"></a>值类型</h4><p>以下类型之所以被称为值类型，是因为它们的变量总是通过值传递， 即在用作函数参数或赋值时总是被复制。</p><h5 id="布尔类型"><a href="#布尔类型" class="headerlink" title="布尔类型"></a><a href="#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B"></a>布尔类型</h5><p><code>bool</code> ：可能的取值为常数值 <code>true</code> 和 <code>false</code>。</p><p>运算符：</p><ul><li><code>!</code> (逻辑非)</li><li><code>&amp;&amp;</code> (逻辑与, “and”)</li><li><code>||</code> (逻辑或, “or”)</li><li><code>==</code> (等于)</li><li><code>!=</code> (不等于)</li></ul><p>运算符 <code>||</code> 和 <code>&amp;&amp;</code> 都遵循同样的短路（ short-circuiting ）规则。 就是说在表达式 <code>f(x) || g(y)</code> 中， 如果 <code>f(x)</code> 的值为 <code>true</code> &#x2F; <code>false</code> ， 那么 <code>g(y)</code> 就不会被执行，即使会出现一些副作用。</p><h5 id="整型"><a href="#整型" class="headerlink" title="整型"></a><a href="#%E6%95%B4%E5%9E%8B"></a>整型</h5><p><code>int</code> &#x2F; <code>uint</code>: 分别表示有符号和无符号的不同位数的整型变量。 关键字 <code>uint8</code> 到 <code>uint256</code> （无符号整型，从 8 位到 256 位）以及 <code>int8</code> 到 <code>int256</code>， 以 8 位为步长递增。 <code>uint</code> 和 <code>int</code> 分别是 <code>uint256</code> 和 <code>int256</code> 的别名。</p><p>运算符：</p><ul><li>比较运算符： <code>=</code>， <code>&gt;</code> （返回布尔值）</li><li>位运算符： <code>&amp;</code>， <code>|</code>， <code>^</code> (异或)， <code>~</code> (位取反)</li><li>移位运算符： <code>&gt;</code> （右移）</li><li>算数运算符： <code>+</code>， <code>-</code>， 一元运算 <code>-</code> （只适用于有符号的整数）， <code>*</code>， <code>/</code>， <code>%</code> (取余)， <code>**</code> (幂)</li></ul><p>对于一个整数类型 <code>X</code>，您可以使用 <code>type(X).min</code> 和 <code>type(X).max</code> 来访问该类型代表的最小值和最大值。</p><h5 id="定长浮点型"><a href="#定长浮点型" class="headerlink" title="定长浮点型"></a><a href="#%E5%AE%9A%E9%95%BF%E6%B5%AE%E7%82%B9%E5%9E%8B"></a>定长浮点型</h5><blockquote><p>警告. Solidity 还没有完全支持定长浮点型。可以声明定长浮点型的变量， 但不能给它们赋值或把它们赋值给其他变量。<a href="#reffn_%E8%AD%A6%E5%91%8A">↩</a></p></blockquote><p><code>fixed</code> &#x2F; <code>ufixed</code>：表示各种大小的有符号和无符号的定长浮点型。 在关键字 <code>ufixedMxN</code> 和 <code>fixedMxN</code> 中， <code>M</code> 表示该类型占用的位数， <code>N</code> 表示可用的小数位数。 <code>M</code> 必须能整除 8，即 8 到 256 位。 <code>N</code> 则可以是从 0 到 80 之间的任意数。 <code>ufixed</code> 和 <code>fixed</code> 分别是 <code>ufixed128x18</code> 和 <code>fixed128x18</code> 的别名。</p><figure class="highlight abnf"><table><tr><td class="gutter"><pre><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><code class="hljs abnf">fixed constant PI <span class="hljs-operator">=</span> <span class="hljs-number">3.14159265</span><span class="hljs-comment">;</span><br>fixed a <span class="hljs-operator">=</span> <span class="hljs-number">1.2</span><span class="hljs-comment">;</span><br>ufixed constant PI <span class="hljs-operator">=</span> <span class="hljs-number">3.14159265</span><span class="hljs-comment">;</span><br>ufixed a <span class="hljs-operator">=</span> <span class="hljs-number">1.2</span><span class="hljs-comment">;</span><br></code></pre></td></tr></table></figure><p>运算符：</p><ul><li>比较运算符： <code>=</code>， <code>&gt;</code> （返回值是布尔型）</li><li>算术运算符： <code>+</code>， <code>-</code>， 一元运算 <code>-</code>， <code>*</code>， <code>/</code>， <code>%</code> (取余数)</li></ul><h5 id="地址类型"><a href="#地址类型" class="headerlink" title="地址类型"></a><a href="#%E5%9C%B0%E5%9D%80%E7%B1%BB%E5%9E%8B"></a>地址类型</h5><p>地址类型有两种大致相同的类型：</p><ul><li><code>address</code>: 保存一个20字节的值（一个以太坊地址的大小）。</li><li><code>address payable</code>: 与 <code>address</code> 类型相同，但有额外的方法 <code>transfer</code> 和 <code>send</code>。</li></ul><p>这种区别背后的想法是， <code>address payable</code> 是一个您可以发送以太币的地址， 而您不应该发送以太币给一个普通的 <code>address</code>，例如，因为它可能是一个智能合约， 而这个合约不是为接受以太币而建立的。</p><figure class="highlight abnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs abnf">address addr <span class="hljs-operator">=</span> <span class="hljs-number">0</span>x690B9A9E9aa1C9dB991C7721a92d351Db4FaC990<span class="hljs-comment">;</span><br>address payable addr_pay <span class="hljs-operator">=</span> payable(<span class="hljs-number">0</span>x8306300ffd616049FD7e4b0354a64Da835c1A81C)<span class="hljs-comment">;</span><br></code></pre></td></tr></table></figure><p>运算符：</p><ul><li><code>=</code> 和 <code>&gt;</code></li></ul><h5 id="定长字节数组"><a href="#定长字节数组" class="headerlink" title="定长字节数组"></a><a href="#%E5%AE%9A%E9%95%BF%E5%AD%97%E8%8A%82%E6%95%B0%E7%BB%84"></a>定长字节数组</h5><p>值类型 <code>bytes1</code>, <code>bytes2</code>, <code>bytes3</code>, …, <code>bytes32</code> 代表从1到32的字节序列。</p><figure class="highlight abnf"><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><code class="hljs abnf">bytes32 public _byte32 <span class="hljs-operator">=</span> <span class="hljs-string">&quot;MiniSolidity&quot;</span><span class="hljs-comment">;</span><br><br>bytes1 public _byte <span class="hljs-operator">=</span> _byte32[<span class="hljs-number">0</span>]<span class="hljs-comment">;</span><br></code></pre></td></tr></table></figure><p>运算符：</p><p>比较运算符：&lt;&#x3D;， &lt;， &#x3D;&#x3D;， !&#x3D;， &gt;&#x3D;， &gt; （返回布尔型）</p><ul><li>比较运算符： <code>=</code>， <code>&gt;</code> (返回 <code>bool</code>)</li><li>位运算符： <code>&amp;</code>， <code>|</code>， <code>^</code> （按位异或）， <code>~</code> （按位取反）</li><li>移位运算符： <code>&gt;</code> （右移位）</li><li>索引访问： 如果 <code>x</code> 是 <code>bytesI</code> 类型，那么当 <code>0 &lt;= k &lt; I</code> 时， <code>x[k]</code> 返回第 <code>k</code> 个字节（只读）。</li></ul><p>移位运算符以无符号的整数类型作为右操作数（但返回左操作数的类型）， 它表示要移位的位数。有符号类型的移位将产生一个编译错误。</p><p>成员变量：</p><ul><li><code>.length</code> 表示这个字节数组的长度（只读）.</li></ul><h5 id="枚举类型-1"><a href="#枚举类型-1" class="headerlink" title="枚举类型"></a><a href="#%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B-1"></a>枚举类型</h5><p>枚举是在 Solidity 中创建用户定义类型的一种方式。 它们可以显式地转换为所有整数类型，和从整数类型来转换，但不允许隐式转换。 从整数的显式转换在运行时检查该值是否在枚举的范围内，否则会导致 <a href="https://docs.soliditylang.org/zh-cn/latest/control-structures.html#assert-and-require">异常</a>。 枚举要求至少有一个成员，其声明时的默认值是第一个成员。 枚举不能有超过256个成员。</p><p>数据表示与 C 语言中的枚举相同。选项由后续的从 <code>0</code> 开始无符号整数值表示。</p><p>使用 <code>type(NameOfEnum).min</code> 和 <code>type(NameOfEnum).max</code> 您可以得到给定枚举的最小值和最大值。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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><code class="hljs csharp"><span class="hljs-comment">// SPDX-License-Identifier: GPL-3.0</span><br>pragma solidity ^<span class="hljs-number">0.8</span><span class="hljs-number">.8</span>;<br><br>contract test &#123;<br>    <span class="hljs-built_in">enum</span> ActionChoices &#123; GoLeft, GoRight, GoStraight, SitStill &#125;<br>    ActionChoices choice;<br>    ActionChoices constant defaultChoice = ActionChoices.GoStraight;<br><br>    <span class="hljs-function">function <span class="hljs-title">setGoStraight</span>() <span class="hljs-keyword">public</span></span> &#123;<br>        choice = ActionChoices.GoStraight;<br>    &#125;<br><br>    <span class="hljs-comment">// 由于枚举类型不属于ABI的一部分，因此对于所有来自 Solidity 外部的调用，</span><br>    <span class="hljs-comment">// &quot;getChoice&quot; 的签名会自动被改成 &quot;getChoice() returns (uint8)&quot;。</span><br>    <span class="hljs-function">function <span class="hljs-title">getChoice</span>() <span class="hljs-keyword">public</span> view <span class="hljs-title">returns</span> (<span class="hljs-params">ActionChoices</span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> choice;<br>    &#125;<br><br>    <span class="hljs-function">function <span class="hljs-title">getDefaultChoice</span>() <span class="hljs-keyword">public</span> pure <span class="hljs-title">returns</span> (<span class="hljs-params"><span class="hljs-built_in">uint</span></span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> <span class="hljs-built_in">uint</span>(defaultChoice);<br>    &#125;<br><br>    <span class="hljs-function">function <span class="hljs-title">getLargestValue</span>() <span class="hljs-keyword">public</span> pure <span class="hljs-title">returns</span> (<span class="hljs-params">ActionChoices</span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> type(ActionChoices).max;<br>    &#125;<br><br>    <span class="hljs-function">function <span class="hljs-title">getSmallestValue</span>() <span class="hljs-keyword">public</span> pure <span class="hljs-title">returns</span> (<span class="hljs-params">ActionChoices</span>)</span> &#123;<br>        <span class="hljs-keyword">return</span> type(ActionChoices).min;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h5 id="函数类型"><a href="#函数类型" class="headerlink" title="函数类型"></a><a href="#%E5%87%BD%E6%95%B0%E7%B1%BB%E5%9E%8B"></a>函数类型</h5><p>函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量， 也可以将一个函数作为参数进行传递，还能在函数调用中返回函数类型变量。</p><p>类似的格式如下</p><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql"><span class="hljs-keyword">function</span> &lt;<span class="hljs-keyword">function</span> <span class="hljs-type">name</span>&gt; (&lt;parameter <span class="hljs-keyword">types</span>&gt;) &#123;<span class="hljs-type">internal</span>|<span class="hljs-keyword">external</span>|<span class="hljs-built_in">public</span>|private&#125; &#123;modifier&#125; [pure|<span class="hljs-keyword">view</span>|payable] [<span class="hljs-keyword">returns</span> (&lt;<span class="hljs-keyword">return</span> <span class="hljs-keyword">types</span>&gt;)]<br></code></pre></td></tr></table></figure><h4 id="引用类型"><a href="#引用类型" class="headerlink" title="引用类型"></a><a href="#%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B"></a>引用类型</h4><p>在 Solidity 中，相比于值类型，引用类型更复杂，通常包括占用更多内存的数组和结构体。当处理这些复杂的引用类型时，需要谨慎考虑它们的数据位置。</p><p>所有引用类型（如数组和结构体）都具有一个 “数据位置” 属性，指明数据是存储在内存中还是存储中。大多数情况下，数据位置有默认值，但可以通过在类型名后加 <code>storage</code> 或 <code>memory</code> 来显式指定。</p><ul><li><strong>memory</strong>：用于临时存储，数据在执行完后会被销毁。</li><li><strong>storage</strong>：用于持久保存，数据会永久保存，直到被修改或删除。</li><li><strong>calldata</strong>：只读，常用于存储外部函数的参数。</li></ul><h6 id="默认数据位置："><a href="#默认数据位置：" class="headerlink" title="默认数据位置："></a><a href="#%E9%BB%98%E8%AE%A4%E6%95%B0%E6%8D%AE%E4%BD%8D%E7%BD%AE%EF%BC%9A"></a>默认数据位置：</h6><ul><li>函数参数（包括返回参数）的默认位置是 <strong>内存 (memory)</strong>。</li><li>局部变量的默认位置是 <strong>存储 (storage)</strong>。</li><li>状态变量的数据位置强制为 <strong>存储 (storage)</strong>。</li></ul><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></pre></td><td class="code"><pre><code class="hljs plaintext">// SPDX-License-Identifier: GPL-3.0<br>pragma solidity ^0.8.0;<br>contract C &#123;<br>    // 我们选择使用string类型，这里使用storage。<br>    // 需要注意的是，在该位置时默认数据为storage，这个可以忽略<br>    // 这是因为状态变量不需要指定数据位置，默认为storage<br>    string public x;<br>    // memoryArray 的数据存储位置是 memory<br>    // 我们也可以给他的数据存储位置为 calldata<br>    function f(string memory memoryString) public&#123;<br>      // memoryString = &quot;hello&quot;<br>       x = memoryString;<br>    &#125;<br>    // calldata<br>    // memory<br>    function g(string calldata ) external &#123;<br>    &#125;<br>    // storage<br>    function h(string storage ) internal  &#123;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure><h6 id="数据位置的重要性"><a href="#数据位置的重要性" class="headerlink" title="数据位置的重要性"></a><a href="#%E6%95%B0%E6%8D%AE%E4%BD%8D%E7%BD%AE%E7%9A%84%E9%87%8D%E8%A6%81%E6%80%A7"></a>数据位置的重要性</h6><p>数据位置影响赋值行为：</p><ul><li>在 <strong>存储 (storage)</strong> 和 <strong>内存 (memory)</strong> 之间赋值会创建新的拷贝。</li><li>**存储 (storage)**进行 赋值时，只会传递引用，不会创建新副本。</li><li><strong>内存 (memory)</strong> 之间的赋值通常不会创建新副本，因为它们共享相同的数据。</li></ul><h5 id="总结"><a href="#总结" class="headerlink" title="总结"></a><a href="#%E6%80%BB%E7%BB%93"></a>总结</h5><ul><li><p><strong>强制指定的数据位置</strong>：<br>外部函数,也就是<code>external</code>，形参的数据位置可以为 <code>calldata</code>，也可以为<code>memory</code>，但是绝对不是<code>storage</code>，<code>public</code>同理。</p></li><li><p>状态变量为 <code>storage</code>，也可以指定函数形参的数据位置为<code>storage</code>，不过基本上只能在内部函数<code>internal</code>执行。</p></li><li><p>函数参数（包括返回参数）为 <code>memory</code>，也可以为<code>calldata</code>。</p></li><li><p>其他局部变量为 <code>storage</code>。</p></li></ul><hr><h5 id="数组"><a href="#数组" class="headerlink" title="数组"></a><a href="#%E6%95%B0%E7%BB%84"></a>数组</h5><p>Solidity 支持两种类型的数组：固定长度数组和动态数组。</p><p>一个元素类型为 <code>T</code>，固定长度为 <code>k</code> 的数组可以声明为 <code>T[k]</code>， 而动态数组声明为 <code>T[]</code>。</p><p><strong>固定长度数组</strong>:<code>uint[5]</code>,<code>uint[2][5]</code> …</p><p><strong>动态数组</strong>:<code>uint[]</code>,<code>uint[][5]</code> …</p><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><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">uint[5] a = [1,2,3,4,5]; // 5 element array<br>uint[5] b;<br>uint[] c;<br>uint[] d = [1,2,3,4,5];<br></code></pre></td></tr></table></figure><p><strong>索引</strong>: 对元素中的一个数据进行定位，数组索引从0开始，访问一个数组中的其中一个元素，访问时的下标顺序与声明时相反。访问一个超过它的末端的数组会导致一个失败的断言。</p><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">function returnOne() public view returns (uint)&#123;<br>    return d[0];//返回第一个元素<br>&#125;<br>function returntwo() public view returns (uint)&#123;<br>    return d[1];//返回第二个元素<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>数组成员</strong>:</p><ul><li><strong>length</strong>:<br>数组有 <code>length</code> 成员变量表示当前数组的长度。一经创建， 内存memory数组的大小就是固定的（但却是动态的，也就是说，它依赖于运行时数组的参数）。<br>1<br>2<br>3<br><code>function returnLength() public view returns (uint){    return d.length;}</code></li><li><strong>push()</strong>:<br>动态存储数组和 <code>bytes</code> （不是 <code>string</code> ）有一个叫 <code>push()</code> 的成员函数， 您可以用它在数组的末尾追加一个零初始化的元素。它返回一个元素的引用， 因此可以像 <code>x.push().t = 2</code> 或 <code>x.push() = b</code> 那样使用。<br>1<br>2<br>3<br><code>function add(uint x) public{     c.push();}</code></li><li><strong>push(x)</strong>:<br>动态存储数组和 <code>bytes</code> （不是 <code>string</code> ）有一个叫 <code>push(x)</code> 的成员函数， 您可以用它在数组的末端追加一个指定的元素。该函数不返回任何东西。<br>1<br>2<br>3<br><code>function add(uint x) public{d.push(x);}</code></li><li><strong>pop()</strong>:<br>动态存储数组和 <code>bytes</code> （不是 <code>string</code> ）有一个叫 <code>pop()</code> 的成员函数， 您可以用它来从数组的末端移除一个元素。 这也隐含地在被删除的元素上调用 <a href="https://docs.soliditylang.org/zh-cn/latest/types.html#delete">delete</a>。该函数不返回任何东西。</li></ul><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><code class="hljs plaintext">function del() public&#123;<br>    d.pop(); //删除末尾<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>创建内存数组</strong>:具有动态长度的内存数组可以使用 <code>new</code> 操作符创建。 与存储数组不同的是，<strong>不可能</strong> 调整内存数组的大小（例如， <code>.push</code> 成员函数不可用）。 您必须事先计算出所需的大小，或者创建一个新的内存数组并复制每个元素。</p><p>正如Solidity中的所有变量一样，新分配的数组元素总是以 <a href="https://docs.soliditylang.org/zh-cn/latest/control-structures.html#default-value">默认值</a> 进行初始化。</p><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">function createMemoryArray(uint len) public view returns (uint[] memory)&#123;<br>       uint[] memory arr = new uint[](len); //创建长度为len的内存数组<br>       arr[0] = 1;<br>       arr[1] = 2;<br>       return arr;<br>   &#125;<br></code></pre></td></tr></table></figure><p><strong>数组切片</strong>: <code>x[start:end]</code></p><p>数组切片是对一个数组的连续部分的预览。 它们被写成 <code>x[start:end]</code>，其中 <code>start</code> 和 <code>end</code> 是表达式， 结果是uint256类型（或隐含的可转换类型）。分片的第一个元素是 <code>x[start]</code>， 最后一个元素是 <code>x[end - 1]</code>。</p><p>如果 <code>start</code> 大于 <code>end</code>，或者 <code>end</code> 大于数组的长度， 就会出现异常。</p><p><code>start</code> 和 <code>end</code> 都是可选的： <code>start</code> 默认为 <code>0</code>， <code>end</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><code class="hljs plaintext">function get(uint[] calldata arr) public view returns (uint[] calldata)&#123;<br>      return arr[:6];<br>  &#125;<br></code></pre></td></tr></table></figure><p><strong>数组元素</strong>：数组元素可以是任何类型，包括映射或结构体。 并适用于类型的一般限制，映射只能存储在 <code>storage</code> 数据位置,下面是一些特殊的数组。</p><p><strong>bytes</strong></p><p><code>bytes</code> 类似于 <code>bytes1[]</code>， 但它在 calldata 中会被“紧打包”（译者注：将元素连续地存在一起，不会按每 32 字节一单元的方式来存放）。</p><p>您应该使用 <code>bytes</code> 而不是 <code>bytes1[]</code>，因为它更便宜， 因为在 <code>memory</code> 中使用 <code>bytes1[]</code> 会在元素之间增加31个填充字节。  一般来说，对于任意长度的原始字节数据使用 <code>bytes</code>，对于任意长度的字符串（UTF-8）数据使用 <code>string</code>。 如果您能将长度限制在一定的字节数，使用 <code>bytes1</code> 到 <code>bytes32</code> 中的一种值类型，因为它们更便宜。</p><p>函数:  <code>bytes.concat</code></p><p><code>bytes.concat</code> 函数可以连接任意数量的 <code>bytes</code> 或 <code>bytes1 ... bytes32</code> 值。 该函数返回一个单一的 <code>bytes memory</code> 数组，其中包含没有填充的参数内容。 如果您想使用字符串参数或其他不能隐式转换为 <code>bytes</code> 的类型， 您需要先将它们转换为 <code>bytes</code> 或 <code>bytes1</code> &#x2F;…&#x2F; <code>bytes32</code>。</p><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract C&#123;<br>    bytes public Bytes = &quot;abc&quot;;<br>    bytes public Bytes2 = &quot;efg&quot;;<br>    string public s = &quot;Storage&quot;;<br>    string public d = &quot;Memory&quot;;<br>    bool public keccak =<br>    keccak256(abi.encodePacked(s)) == keccak256(abi.encodePacked(d));<br>    string public stringConcat = string.concat(s,d,string(Bytes),string(Bytes2));<br>    bytes public concatBytes = bytes.concat(Bytes,Bytes2,bytes(s),bytes(d));<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>string</strong></p><p><code>string</code> 与 <code>bytes</code> 相同，但不允许用长度或索引来访问。</p><p>Solidity没有字符串操作函数，但有第三方的字符串库。 可以用 <code>keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))</code> 来比较两个字符串的keccak256-hash，用 <code>string.concat(s1, s2)</code> 来连接两个字符串。</p><p>函数: <code>string.concat</code></p><p>可以使用 <code>string.concat</code> 连接任意数量的 <code>string</code> 值。 该函数返回一个单一的 <code>string memory</code> 数组，其中包含没有填充的参数内容。 如果您想使用不能隐式转换为 <code>string</code> 的其他类型的参数，您需要先将它们转换为 <code>string</code>。</p><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><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><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract C&#123;<br>    bytes public Bytes = &quot;abc&quot;;<br>    bytes public Bytes2 = &quot;efg&quot;;<br>    string public s = &quot;Storage&quot;;<br>    string public d = &quot;Memory&quot;;<br>    bool public keccak =<br>    keccak256(abi.encodePacked(s)) == keccak256(abi.encodePacked(d));<br>    string public stringConcat = string.concat(s,d,string(Bytes),string(Bytes2));<br>    bytes public concatBytes = bytes.concat(Bytes,Bytes2,bytes(s),bytes(d));<br>&#125;<br></code></pre></td></tr></table></figure><h5 id="结构体"><a href="#结构体" class="headerlink" title="结构体"></a><a href="#%E7%BB%93%E6%9E%84%E4%BD%93"></a>结构体</h5><p>Solidity 支持通过结构体定义新类型。</p><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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract Struct&#123;<br>    struct user&#123;<br>        string name;<br>        uint age;<br>        string email;<br>    &#125;<br>    // function add(string memory name, uint age, string memory email)<br>    // public view returns (user memory)&#123;<br>    //     user memory newUser = user(name, age, email);<br>    //     return newUser;<br>    // &#125;<br>    user user1;<br>    function add(string memory name, uint age, string memory email)<br>    external&#123;<br>        user storage newUser = user1;<br>        newUser.name =&quot;hello&quot;;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h6 id="结构体的赋值和访问"><a href="#结构体的赋值和访问" class="headerlink" title="结构体的赋值和访问"></a><a href="#%E7%BB%93%E6%9E%84%E4%BD%93%E7%9A%84%E8%B5%8B%E5%80%BC%E5%92%8C%E8%AE%BF%E9%97%AE"></a>结构体的赋值和访问</h6><ul><li><strong>存储结构体</strong>：当结构体赋值给局部变量时，并不会复制数据，而是传递引用。</li><li><strong>成员访问</strong>：可以直接访问结构体的成员，例如 <code>campaigns[campaignID].amount = 0;</code>。</li></ul><h4 id="映射类型"><a href="#映射类型" class="headerlink" title="映射类型"></a><a href="#%E6%98%A0%E5%B0%84%E7%B1%BB%E5%9E%8B"></a>映射类型</h4><p>在映射中，人们可以通过键（<code>Key</code>）来查询对应的值（<code>Value</code>），比如：通过一个人的<code>id</code>来查询他的钱包地址。</p><p>声明映射的格式为<code>mapping(_KeyType =&gt; _ValueType)</code>，其中<code>_KeyType</code>和<code>_ValueType</code>分别是<code>Key</code>和<code>Value</code>的变量类型。例子：</p><h5 id="映射的规则"><a href="#映射的规则" class="headerlink" title="映射的规则"></a><a href="#%E6%98%A0%E5%B0%84%E7%9A%84%E8%A7%84%E5%88%99"></a>映射的规则</h5><p><strong>规则1</strong>：映射的<code>_KeyType</code>只能选择Solidity内置的值类型，比如<code>uint</code>，<code>address</code>等，不能用自定义的结构体。而<code>_ValueType</code>可以使用自定义的类型。下面这个例子会报错，因为<code>_KeyType</code>使用了我们自定义的结构体：</p><p><strong>规则2</strong>：映射的存储位置必须是<code>storage</code>，因此可以用于合约的状态变量，函数中的<code>storage</code>变量和library函数的参数（见<a href="https://github.com/ethereum/solidity/issues/4635">例子</a>）。不能用于<code>public</code>函数的参数或返回结果中，因为<code>mapping</code>记录的是一种关系 (key - value pair)。</p><p><strong>规则3</strong>：如果映射声明为<code>public</code>，那么Solidity会自动给你创建一个<code>getter</code>函数，可以通过<code>Key</code>来查询对应的<code>Value</code>。</p><p><strong>规则4</strong>：给映射新增的键值对的语法为<code>_Var[_Key] = _Value</code>，其中<code>_Var</code>是映射变量名，<code>_Key</code>和<code>_Value</code>对应新增的键值对。例子：</p><h5 id="映射的原理"><a href="#映射的原理" class="headerlink" title="映射的原理"></a><a href="#%E6%98%A0%E5%B0%84%E7%9A%84%E5%8E%9F%E7%90%86"></a>映射的原理</h5><p><strong>原理1</strong>: 映射不储存任何键（<code>Key</code>）的资讯，也没有length的资讯。</p><p><strong>原理2</strong>: 对于映射使用<code>keccak256(h(key) . slot)</code>计算存取value的位置。<a href="https://github.com/WTFAcademy/WTF-Solidity-Internals/tree/master/tutorials/02_MappingStorage">https://github.com/WTFAcademy/WTF-Solidity-Internals/tree/master/tutorials/02_MappingStorage</a>)</p><p><strong>原理3</strong>: 因为Ethereum会定义所有未使用的空间为0，所以未赋值（<code>Value</code>）的键（<code>Key</code>）初始值都是各个type的默认值，如uint的默认值是0。</p><h5 id="在Remix上验证-以-Mapping-sol为例"><a href="#在Remix上验证-以-Mapping-sol为例" class="headerlink" title="在Remix上验证 (以 Mapping.sol为例)"></a><a href="#%E5%9C%A8Remix%E4%B8%8A%E9%AA%8C%E8%AF%81-%E4%BB%A5-Mapping-sol%E4%B8%BA%E4%BE%8B"></a>在Remix上验证 (以 <code>Mapping.sol</code>为例)</h5><p>映射示例 1 部署</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/69dd365d690ea6ed3c8368f45a16d25a.jpg" alt="img"></p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1763632090332-1f40dddf-c031-4692-8317-b15bc0d2d49e.jpeg" alt="img"></p><p>映射示例 3 key-value pair</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/1763632088903-2bf9034a-c080-4d04-a18e-5cef2ce4ae1d.jpeg" alt="img"></p><h4 id="运算符"><a href="#运算符" class="headerlink" title="运算符"></a><a href="#%E8%BF%90%E7%AE%97%E7%AC%A6"></a>运算符</h4><p>在Solidity智能合约中，以下是一些常见运算符的简要说明和示例：</p><h5 id="三元运算符"><a href="#三元运算符" class="headerlink" title="三元运算符"></a><a href="#%E4%B8%89%E5%85%83%E8%BF%90%E7%AE%97%E7%AC%A6"></a><strong>三元运算符</strong></h5><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">条件表达式</span>&gt;</span> ? <span class="hljs-tag">&lt;<span class="hljs-name">true条件表达式</span>&gt;</span> : <span class="hljs-tag">&lt;<span class="hljs-name">false条件表达式</span>&gt;</span><br></code></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></pre></td><td class="code"><pre><code class="hljs plaintext">uint public a = 10;<br>uint b = 20;<br>uint public x;<br>uint public max = a &gt; b ? a : b;<br>uint public min = a &lt; b ? a : b;<br></code></pre></td></tr></table></figure><h5 id="复合赋值运算符"><a href="#复合赋值运算符" class="headerlink" title="复合赋值运算符"></a><a href="#%E5%A4%8D%E5%90%88%E8%B5%8B%E5%80%BC%E8%BF%90%E7%AE%97%E7%AC%A6"></a><strong>复合赋值运算符</strong></h5><p><code>-=</code>，<code>+=</code>, <code>*=</code>， <code>/=</code>， <code>%=</code>， <code>|=</code>， <code>&amp;=</code>， <code>^=</code>， <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><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><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><code class="hljs plaintext">function jian(uint y) public &#123;<br>        // a = a - y;<br>        a -= y;<br>    &#125;<br>    function add(uint y) public &#123;<br>        // a = a + y;<br>        a += y;<br>    &#125;<br>    function divide(uint y) public &#123;<br>        // a = a / y;<br>        a /= y;<br>    &#125;<br>    function multiply(uint y) public &#123;<br>        // a = a * y;<br>        a *= y;<br>    &#125;<br>    function test(uint y) public &#123;<br>        // a %= y;  // a = 10 % 2 = 0<br>        // a |= y;  // a = a | y ;  10 | 2  1 0 1 0 | 0 0 1 0  = 1 0 1 0<br>        // a &amp;= y; // a = a &amp; y;  10 &amp; 2  1 0 1 0 | 0 0 1 0  = 0 0 1 0<br>        // a ^= y;  // a = a ^ y  10 ^ 2  1 0 1 0 | 0 0 1 0 = 1 0 0 0<br>        // a &lt;&lt;= y;  // a = a &lt;&lt; y  10 &lt;&lt; 2  0 0 0 0 1 0 1 0  &lt;&lt; 2 =  0 0 1 0 1 0 0 0 40<br>        a &gt;&gt;= y;  // a = a &gt;&gt; y  10 &gt;&gt; 2  0 0 0 0 1 0 1 0 &gt;&gt; 2   = 0 0 0 0 0 0 1 0<br>    &#125;<br></code></pre></td></tr></table></figure><p>用于简洁地对变量进行更新。</p><h5 id="增量-减量运算符："><a href="#增量-减量运算符：" class="headerlink" title="增量&#x2F;减量运算符："></a><a href="#%E5%A2%9E%E9%87%8F-%E5%87%8F%E9%87%8F%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%9A"></a><strong>增量&#x2F;减量运算符</strong>：</h5><p>a++<code>和</code>a—</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><code class="hljs plaintext">function add1() public &#123;<br>       a++<br>   &#125;<br></code></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><code class="hljs plaintext">function divide1() public &#123;<br>   x = a--;<br>  &#125;<br></code></pre></td></tr></table></figure><p>—a<code>和</code>++a</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><code class="hljs plaintext">function add1() public &#123;<br>        x = ++a;<br>    &#125;<br></code></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><code class="hljs plaintext">function divide1() public &#123;<br>     x = --a;<br> &#125;<br></code></pre></td></tr></table></figure><p>用于快速增加或减少变量的值。</p><h5 id="删除运算符"><a href="#删除运算符" class="headerlink" title="删除运算符"></a><a href="#%E5%88%A0%E9%99%A4%E8%BF%90%E7%AE%97%E7%AC%A6"></a>删除运算符</h5><p>在Solidity中是存在 <code>delete</code> 运算符的。使用 <code>delete</code> 可以将变量设置为其类型的默认值。对于简单类型，如 <code>uint</code> 或 <code>int</code>，默认值是 <code>0</code>；对于数组，<code>delete</code> 会使数组的所有元素被置为默认值；对于结构体，它将重置结构体中的所有成员变量为它们的默认值。<br>例如：</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></pre></td><td class="code"><pre><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract test2&#123;<br>    uint public x = 2;<br>    uint[]  array = [1,2,3,4];<br>    struct S &#123; uint a; uint b;&#125;<br>    S public s;<br>    function test() public returns(S memory)&#123;<br>        delete x;<br>        delete array[1];<br>        s.a = 5;<br>        s.b = 2;<br>        delete s;<br>        // delete s[0];<br>        return s;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>请注意，<code>delete</code> 对于动态数组只会将特定索引处的元素重置为默认值，并不会改变数组的长度。而对于静态数组，<code>delete</code> 将会重置整个数组为默认值。对于映射（mapping），<code>delete</code> 会使特定的键对应的值被移除。对于复杂类型的数组或映射，<code>delete</code> 不会递归删除内部元素，只会将它们设置为默认值。</p><h5 id="运算符优先顺序："><a href="#运算符优先顺序：" class="headerlink" title="运算符优先顺序："></a><a href="#%E8%BF%90%E7%AE%97%E7%AC%A6%E4%BC%98%E5%85%88%E9%A1%BA%E5%BA%8F%EF%BC%9A"></a><strong>运算符优先顺序</strong>：</h5><table><thead><tr><th>优先级</th><th>描述</th><th>操作符</th><th></th></tr></thead><tbody><tr><td><em>1</em></td><td>后置自增和自减</td><td><code>++</code>， <code>--</code></td><td></td></tr><tr><td></td><td>创建类型实例</td><td><code>new </code></td><td></td></tr><tr><td></td><td>数组元素</td><td><code>[]</code></td><td></td></tr><tr><td></td><td>访问成员</td><td><code>.</code></td><td></td></tr><tr><td></td><td>函数调用</td><td><code>()</code></td><td></td></tr><tr><td></td><td>小括号</td><td><code>()</code></td><td></td></tr><tr><td><em>2</em></td><td>前置自增和自减</td><td><code>++</code>， <code>--</code></td><td></td></tr><tr><td></td><td>一元运算减</td><td><code>-</code></td><td></td></tr><tr><td></td><td>一元操作符</td><td><code>delete</code></td><td></td></tr><tr><td></td><td>逻辑非</td><td><code>!</code></td><td></td></tr><tr><td></td><td>按位非</td><td><code>~</code></td><td></td></tr><tr><td><em>3</em></td><td>乘方</td><td><code>**</code></td><td></td></tr><tr><td><em>4</em></td><td>乘、除和模运算</td><td><code>*</code>， <code>/</code>， <code>%</code></td><td></td></tr><tr><td><em>5</em></td><td>算术加和减</td><td><code>+</code>， <code>-</code></td><td></td></tr><tr><td><em>6</em></td><td>移位操作符</td><td><code>&gt;</code></td><td></td></tr><tr><td><em>7</em></td><td>按位与</td><td><code>&amp;</code></td><td></td></tr><tr><td><em>8</em></td><td>按位异或</td><td><code>^</code></td><td></td></tr><tr><td><em>9</em></td><td>按位或</td><td>&#96;</td><td>&#96;</td></tr><tr><td><em>10</em></td><td>非等操作符</td><td>&#96;&#96;， <code>=</code></td><td></td></tr><tr><td><em>11</em></td><td>等于操作符</td><td><code>==</code>， <code>!=</code></td><td></td></tr><tr><td><em>12</em></td><td>逻辑与</td><td><code>&amp;&amp;</code></td><td></td></tr><tr><td><em>13</em></td><td>逻辑或</td><td><code>==</code></td><td></td></tr><tr><td><em>14</em></td><td>三元操作符</td><td><code>?  :</code></td><td></td></tr><tr><td></td><td>赋值操作符</td><td><code>=</code>， &#96;</td><td>&#x3D;<code>，</code>^&#x3D;<code>，</code>&amp;&#x3D;<code>，</code>&lt;&lt;&#x3D;<code>，</code>&gt;&gt;&#x3D;<code>，</code>+&#x3D;<code>，</code>-&#x3D;<code>，</code>*&#x3D;<code>，</code>&#x2F;&#x3D;<code>，</code>%&#x3D;&#96;</td></tr><tr><td><em>15</em></td><td>逗号</td><td><code>,</code></td><td></td></tr></tbody></table><p>运算符按照特定的优先级进行求值，例如：</p><ul><li><code>*</code>、<code>/</code>、<code>%</code>（乘、除、取余）具有高于<code>+</code>、<code>-</code>（加、减）的优先级。</li><li><code>&amp;&amp;</code>（逻辑与）的优先级高于<code>||</code>（逻辑或）。</li><li>使用括号<code>()</code>可以改变默认的优先级。<br>下面是一个运算符优先级的例子：</li></ul><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><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract test3&#123;<br>//     *、/、%（乘、除、取余）具有高于+、-（加、减）的优先级。<br>// &amp;&amp;（逻辑与）的优先级高于||（逻辑或）。<br>// 使用括号()可以改变默认的优先级。<br>    uint a = 2; uint b =3; uint c=4;<br>    // uint public result = a + b * c;<br>    // bool public result = true &amp;&amp; false || false;<br>    uint public result = (a + b) * c;<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="基本类型之间的转换"><a href="#基本类型之间的转换" class="headerlink" title="基本类型之间的转换"></a><a href="#%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E4%B9%8B%E9%97%B4%E7%9A%84%E8%BD%AC%E6%8D%A2"></a>基本类型之间的转换</h4><h5 id="隐式转换"><a href="#隐式转换" class="headerlink" title="隐式转换"></a><a href="#%E9%9A%90%E5%BC%8F%E8%BD%AC%E6%8D%A2"></a>隐式转换</h5><p>在某些情况下，在赋值过程中，在向函数传递参数和应用运算符时， 编译器会自动应用隐式类型转换。一般来说，如果在语义上有意义， 并且不会丢失信息，那么值-类型之间的隐式转换是可能的。</p><p>uint8 &#x3D;&gt; uint16, int128&#x3D;&gt;int256, int8 !&#x3D;&gt; uint256【!&#x3D;-1】</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></pre></td><td class="code"><pre><code class="hljs plaintext">uint8 y; uint16 z;<br>uint32 public x = y+z;<br>uint16 public j = y+z;<br>int128 public iy; int256 public iz;<br>int256 public ix = iy+iz;<br>int8 public io=-1;<br></code></pre></td></tr></table></figure><h5 id="显式转换"><a href="#显式转换" class="headerlink" title="显式转换"></a><a href="#%E6%98%BE%E5%BC%8F%E8%BD%AC%E6%8D%A2"></a>显式转换</h5><p>如果编译器不允许隐式转换，但您确信转换会成功， 有时可以进行显式类型转换。 这可能会导致意想不到的行为，并使您绕过编译器的一些安全特性， 所以一定要测试结果是否是您想要的和期望的!</p><p>int y&#x3D;&gt; uint(y)</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><code class="hljs plaintext">// 1 0 0 0 0 0 0 1  确定源码 2进制符号 最高位1/0 负/正<br>// 1 1 1 1 1 1 1 0  计算反码 除最高位以外取反<br>// 1 1 1 1 1 1 1 1  补码，反码加一<br>// 128+127=255      十进制结果<br>uint256 public k = uint8(io);<br>uint8 public a = 255;<br>// uint8 public b = 256;<br></code></pre></td></tr></table></figure><h4 id="字面常数和基本类型之间的转换"><a href="#字面常数和基本类型之间的转换" class="headerlink" title="字面常数和基本类型之间的转换"></a><a href="#%E5%AD%97%E9%9D%A2%E5%B8%B8%E6%95%B0%E5%92%8C%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B%E4%B9%8B%E9%97%B4%E7%9A%84%E8%BD%AC%E6%8D%A2"></a>字面常数和基本类型之间的转换</h4><h5 id="整数类型"><a href="#整数类型" class="headerlink" title="整数类型"></a><a href="#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B"></a>整数类型</h5><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></pre></td><td class="code"><pre><code class="hljs plaintext">//十进制转换<br>   uint8 public a = 255;<br>   // bytes4 b = bytes1(a); 可行<br>   // bytes4 b = a 不可行<br>   //十六进制常量<br>   bytes2 m = 0x1234;<br></code></pre></td></tr></table></figure><h5 id="固定大小的字节数组"><a href="#固定大小的字节数组" class="headerlink" title="固定大小的字节数组"></a><a href="#%E5%9B%BA%E5%AE%9A%E5%A4%A7%E5%B0%8F%E7%9A%84%E5%AD%97%E8%8A%82%E6%95%B0%E7%BB%84"></a>固定大小的字节数组</h5><p>十进制数字字面常数不能被隐含地转换为固定大小的字节数组。 十六进制数字字面常数是可以的，但只有当十六进制数字的数量正好符合字节类型的大小时才可以。 但是有一个例外，数值为0的十进制和十六进制数字字面常数都可以被转换为任何固定大小的字节类型</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><code class="hljs plaintext">// bytes2 n = 0x12; 不行<br>  // bytes2 x = 0x12345; 不行<br>  bytes2 z = 0x0;<br>  bytes2 y = 0;<br></code></pre></td></tr></table></figure><h5 id="地址类型-1"><a href="#地址类型-1" class="headerlink" title="地址类型"></a><a href="#%E5%9C%B0%E5%9D%80%E7%B1%BB%E5%9E%8B-1"></a>地址类型</h5><p>正如在 <a href="https://docs.soliditylang.org/zh-cn/latest/types.html#address-literals">地址字面量（Address Literals）</a> 中所描述的那样，正确大小并通过校验测试的十六进制字是 <code>address</code> 类型。 其他字面常数不能隐含地转换为 <code>address</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><code class="hljs plaintext">// 地址类型<br>    address user = 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4;<br>    // address a = address(0x0); 不行<br></code></pre></td></tr></table></figure><h5 id="总结-1"><a href="#总结-1" class="headerlink" title="总结:"></a><a href="#%E6%80%BB%E7%BB%93-1"></a>总结:</h5><ul><li><strong>隐式转换</strong>：只有在“范围扩大 + 不丢失信息”时才允许。</li><li><strong>显式转换</strong>：允许开发者强制转换，但可能导致意外结果 → 必须验证。</li><li><strong>字面量转换规则</strong>：</li><li>整数字面量可隐式转换（不超范围）。</li><li>十六进制字面量可用于定长字节数组（需精确字节数）。</li><li>地址必须是符合格式的十六进制字面量。</li></ul><p>参考资料 :</p><p><a href="https://docs.soliditylang.org/zh-cn/latest/index.html">Solidity — Solidity 0.8.24 文档</a></p><p><a href="https://www.wtf.academy/zh/course/solidity101">WTF Solidity课程</a></p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/Solidity%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%88%E4%BA%8C%EF%BC%89Solidity%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/Solidity%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%88%E4%BA%8C%EF%BC%89Solidity%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95/"/>
    <published>2025-11-30T09:26:22.000Z</published>
    <summary>Solidity基础语法引言Solidity是一种合约导向编程语言，用于编写智能合约，运行在Ethereum虚拟机（EVM）上。本文档将为您介绍Solidity的基本语法和概念，帮助您快速上手智能合约开发。 合约结构在 Solidity 中，合约类似于面向对象编程语言中的类。 每个合约中可以包含 状态变量、 函数、 函数修饰器、事件、 结构类型、 和 ...</summary>
    <title>Solidity智能合约零基础入门（二）Solidity基础语法</title>
    <updated>2026-01-17T14:54:19.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="后端开发" scheme="https://zhengcookie.github.io/categories/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="GoLang" scheme="https://zhengcookie.github.io/tags/GoLang/"/>
    <content>
      <![CDATA[<h2 id="常量"><a href="#常量" class="headerlink" title="常量"></a><a href="#%E5%B8%B8%E9%87%8F"></a>常量</h2><p>常量是内存中用于保存固定值的单元，在程序中常量的值不能发生改变。</p><p>在Go语言 中定义常量的方法如下：</p><p>例</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs go"><span class="hljs-keyword">const</span> CAPITAL <span class="hljs-type">string</span> = <span class="hljs-string">&quot;Guangdong&quot;</span><br></code></pre></td></tr></table></figure><h2 id="变量"><a href="#变量" class="headerlink" title="变量"></a><a href="#%E5%8F%98%E9%87%8F"></a>变量</h2><p>变量是内存中命名的存储位置，与常量不同的是变量的值可以动态变化。与常量一 样，变量也有一个名字。</p><p>在Go语言中定义变量的方法如下：</p><p>例如，下面的代码定义了一个字符串变量str。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs go"><span class="hljs-keyword">var</span> str <span class="hljs-type">string</span> = <span class="hljs-string">&quot;Hello&quot;</span>;<br></code></pre></td></tr></table></figure><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a><a href="#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"></a>数据类型</h2><ol><li><a href="#%E5%B8%83%E5%B0%94%E5%9E%8B"></a><strong>布尔型</strong></li></ol><p>Go语言的布尔型为bool，布尔型常量包括true和false。</p><p>例如，下面的代码定义了 一个布尔型变量existed。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">var</span> existed <span class="hljs-built_in">bool</span> = <span class="hljs-literal">false</span>;<br></code></pre></td></tr></table></figure><ol><li><a href="#%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B"></a><strong>数字类型</strong>Go语言的数字类型包括整型和浮点型。Go语言支持的整型数据类型如下图所示。</li></ol><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251126212023344.png" alt="image-20251126212023344"></p><p>Go语言支持的浮点型数据类型如下图所示。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251126212147032.png" alt="image-20251126212147032"></p><ol><li><a href="#%E6%B4%BE%E7%94%9F%E7%B1%BB%E5%9E%8B"></a><strong>派生类型</strong>Go语言的派生类型包括指针、结构体、枚举、数组、切片、集合、接口、通道、函数等。大多数派生类型都比较复杂，本小节只介绍其中比较简单的结构体类型和枚举类型。<br>（1）结构体类型<br>结构体是一种自定义的数据类型，即可以由一组不同的数据类型组合成一个新的数据类型。可以使用struct关键字来定义结构体类型，具体方法如下：<br>type结构体类型struct {<br>​    成员定义<br>​    成员定义<br>​    ……<br>​    成员定义<br> }<br>例如，下面的代码定义了一个Book结构体，其中包含Name（名称）、Author（作者）、Pagecount（页数）和Price（价格）等成员。<br>1<br>2<br>3<br>4<br>5<br>6<br><code>type Book struct {    Name string;     Author string;    Pagecount uint;    Price uint; }</code><br>定义结构体类型后，可以使用如下方法声明结构体变量。<br>变量：&#x3D; 结构体类型 {字段值1， 字段值2,…，字段值n}<br>上面的代码在初始化结构体变量时按照其字段定义的顺序指定字段值，也可以按照 键值对的形式初始化结构体变量，方法如下：<br>变量：&#x3D; 结构体类型 {字段名1：字段值1， 字段名2：字段值2,…，字段名n：字段值n}<br>初始化一个结构体时要指定每个成员的值。<br>例如，初始化一个Book变量b的方法如 下：<br>Book b &#x3D; Book{“ 活着”, “余华”, 350, 90}<br>可以使用b.Name来访问结构体的成员Name。<br>运行结果<br><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251127032517471.png" alt="image-20251127032517471"></li></ol><p>（2）枚举类型</p><p>枚举类型是一种有有限可选值的数据类型，每个可选值都对应一个int值。</p><p>在Go语 言中，可以使用const关键字来定义一个枚举类型，方法如下：</p><p>type &lt;枚举类型名&gt; int const (</p><p>&lt;可选值1&gt; &lt;枚举类型名&gt; &#x3D; iota&#x2F;&#x2F;值为0</p><p>&lt;可选值2&gt; &#x2F;&#x2F;值为1</p><p>&lt;可选值3&gt; &#x2F;&#x2F;值为2</p><p>&lt;可选值4&gt; &#x2F;&#x2F;值为3</p><p>)</p><p>&lt;可选值1&gt;由iota初始化后，后面的可选值会自动递增。&lt;可选值1&gt;对应整型数0,&lt; 可选值2&gt;对应整型数1,&lt;可选值3&gt;对应整型数2，以此类推。</p><p>可以使用下面的方法引用枚举类型的可选值。</p><p>&lt;枚举类型名&gt;.&lt;可选值n&gt;</p><p>参考资料:    Go语言Hyperledger区块链开发实战_(李晓黎)</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80-%E4%B8%89-%E5%B8%B8%E9%87%8F%E3%80%81%E5%8F%98%E9%87%8F%E5%92%8C%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80-%E4%B8%89-%E5%B8%B8%E9%87%8F%E3%80%81%E5%8F%98%E9%87%8F%E5%92%8C%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B/"/>
    <published>2025-11-26T13:04:56.000Z</published>
    <summary>常量常量是内存中用于保存固定值的单元，在程序中常量的值不能发生改变。 在Go语言 中定义常量的方法如下： const 常量标识符 [数据类型] = 常量值例 1const CAPITAL string = &quot;Guangdong&quot; 变量变量是内存中命名的存储位置，与常量不同的是变量的值可以动态变化。与常量一 样，变量也有一个名字。 在Go语言中定义变量的...</summary>
    <title>go语言基础(三) 常量、变量和数据类型</title>
    <updated>2025-11-26T19:41:40.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="后端开发" scheme="https://zhengcookie.github.io/categories/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="GoLang" scheme="https://zhengcookie.github.io/tags/GoLang/"/>
    <content>
      <![CDATA[<p>代码如下：</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><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><code class="hljs go"><span class="hljs-keyword">package</span> main<br><br><span class="hljs-keyword">import</span> <span class="hljs-string">&quot;fmt&quot;</span><br><br><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><br>&#123;<br><br>fmt.Println(<span class="hljs-string">&quot;Hello World!&quot;</span>)<br><br> &#125;<br></code></pre></td></tr></table></figure><p>具体说明如下。</p><p>·程序使用package关键字定义了一个名为main的包。这说明当前程序是一个可执 行程序。</p><p>·程序使用import语句导入包fmt。fmt是Go语言的内置包，其中包含格式化I&#x2F;O （Input&#x2F; Output，输入&#x2F;输出）函数。</p><p>·func关键字用于定义函数。本例中定义了一个main()函数，这是项目的主函数， 也是执行程序的入口。</p><p>·调用fmt包中的Println()函数，在终端输出字符串“Hello World!”。</p><p>这是一个非常简单的Go语言程序，但是其中包含Go语言程序的必要元素，例如包、 函数和字符串等。本章后面会详细介绍这些概念。</p><p>参考资料:    Go语言Hyperledger区块链开发实战_(李晓黎)</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80-%E4%BA%8C-%E7%AC%AC%E4%B8%80%E4%B8%AAgo%E5%BA%94%E7%94%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80-%E4%BA%8C-%E7%AC%AC%E4%B8%80%E4%B8%AAgo%E5%BA%94%E7%94%A8/"/>
    <published>2025-11-26T08:58:05.000Z</published>
    <summary>代码如下： 1234567891011package main import &quot;fmt&quot; func main(){ fmt.Println(&quot;Hello World!&quot;) } 具体说明如下。 ·程序使用package关键字定义了一个名为main的包。这说明当前程序是一个可执 行程序。 ·程序使用import语句导入包fmt。fmt</summary>
    <title>go语言基础(二) 第一个go应用</title>
    <updated>2025-11-26T19:29:24.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="后端开发" scheme="https://zhengcookie.github.io/categories/%E5%90%8E%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="GoLang" scheme="https://zhengcookie.github.io/tags/GoLang/"/>
    <content>
      <![CDATA[<p>b本内容部分参考了书籍Go语言Hyperledger区块链开发实战*(李晓黎)*</p><p>Go语言支持Windows、Linux、FreeBSD和macOS等多种操作系统。</p><p>下载官网</p><p><a href="https://golang.google.cn/">The Go Programming Language</a></p><p>这里只详细说一下windows怎么做，在windows中，下载完成之后的go默认的安装目录为C:\Program Files\Go【可以自行设置】，用户需要把C:\Program Files\Go\bin目录添加到环境变量PATH中【初次安装不需要，但也可能因人而异】，以便可以在任何目录下执行go命令。执行go version命令可以查看Go语言的版本信息，go env命令可以查看与Go语言相关的环境变量。</p><p><img src="https://cdn.jsdelivr.net/gh/zhengcookie/tuchuang@main/img/image-20251126023701181.png" alt="image-20251126023701181"></p><p>常用的与Go语言相关的环境变量如下。</p><p>·GOROOT：存储Go语言的安装目录，默认为C:\Program Files\Go。</p><p>·GOPATH：存储Go语言的项目目录，默认为C:\Users\Administrator\go。</p><p>参考资料:    Go语言Hyperledger区块链开发实战_(李晓黎)</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80(%E4%B8%80)%20%E4%B8%8B%E8%BD%BD%E5%8F%8A%E5%AE%89%E8%A3%85/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80(%E4%B8%80)%20%E4%B8%8B%E8%BD%BD%E5%8F%8A%E5%AE%89%E8%A3%85/"/>
    <published>2025-11-25T18:32:35.000Z</published>
    <summary>b本内容部分参考了书籍Go语言Hyperledger区块链开发实战(李晓黎) Go语言支持Windows、Linux、FreeBSD和macOS等多种操作系统。 下载官网 The Go Programming Language 这里只详细说一下windows怎么做，在windows中，下载完成之后的go默认的安装目录为C:\Program Files\...</summary>
    <title>go语言基础(一) 下载及安装</title>
    <updated>2025-11-26T19:29:14.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="区块链" scheme="https://zhengcookie.github.io/categories/%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
    <category term="区块链智能合约语法" scheme="https://zhengcookie.github.io/tags/%E5%8C%BA%E5%9D%97%E9%93%BE%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E8%AF%AD%E6%B3%95/"/>
    <content>
      <![CDATA[<h2 id="启程-区块链与智能合约概念"><a href="#启程-区块链与智能合约概念" class="headerlink" title="启程 - 区块链与智能合约概念"></a><a href="#%E5%90%AF%E7%A8%8B-%E5%8C%BA%E5%9D%97%E9%93%BE%E4%B8%8E%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E6%A6%82%E5%BF%B5"></a>启程 - 区块链与智能合约概念</h2><h3 id="比特币-vs-以太坊：为什么需要智能合约？"><a href="#比特币-vs-以太坊：为什么需要智能合约？" class="headerlink" title="比特币 vs 以太坊：为什么需要智能合约？"></a><a href="#%E6%AF%94%E7%89%B9%E5%B8%81-vs-%E4%BB%A5%E5%A4%AA%E5%9D%8A%EF%BC%9A%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%EF%BC%9F"></a>比特币 vs 以太坊：为什么需要智能合约？</h3><p>比特币作为区块链技术的第一个成功应用，开创了去中心化数字货币的先河。它的核心功能是提供一种安全、透明且不可篡改的价值转移方式。然而，比特币的设计初衷是专注于支付和存储价值，其脚本语言（Script）虽然具有一定的可编程性，但功能较为有限，无法支持复杂的逻辑操作。<br>相比之下，以太坊在设计上引入了一个革命性的概念——<strong>智能合约</strong>。智能合约是一种运行在区块链上的程序代码，能够根据预设条件自动执行特定的操作。它使得以太坊不仅是一个去中心化的支付系统，更是一个通用的计算平台。通过智能合约，开发者可以构建各种去中心化应用（DApps），例如去中心化金融（DeFi）、非同质化代币（NFT）、去中心化自治组织（DAO）等。这种灵活性使以太坊成为区块链生态系统的核心支柱之一。<br>那么，为什么需要智能合约？智能合约的核心优势在于<strong>自动化执行</strong>和<strong>信任最小化</strong>。传统合约需要依赖第三方（如律师或仲裁机构）来确保执行，而智能合约通过代码直接定义规则并自动执行，无需中介参与。这不仅降低了交易成本，还提高了效率，同时减少了人为干预带来的风险。此外，智能合约的透明性和不可篡改性进一步增强了信任，使其在金融、供应链管理、身份认证等领域展现出巨大的潜力。</p><h3 id="什么是Gas？什么是交易？"><a href="#什么是Gas？什么是交易？" class="headerlink" title="什么是Gas？什么是交易？"></a><a href="#%E4%BB%80%E4%B9%88%E6%98%AFGas%EF%BC%9F%E4%BB%80%E4%B9%88%E6%98%AF%E4%BA%A4%E6%98%93%EF%BC%9F"></a>什么是Gas？什么是交易？</h3><h4 id="Gas"><a href="#Gas" class="headerlink" title="Gas"></a><a href="#Gas"></a>Gas</h4><p>在以太坊网络中，<strong>Gas</strong> 是衡量执行智能合约或进行交易所需计算资源的单位。简单来说，Gas 是用户为使用以太坊网络支付的“燃料费”。每笔交易或智能合约的执行都需要消耗一定数量的 Gas，而 Gas 的价格由市场供需决定，通常以以太币（ETH）计价。<br>Gas 的存在有几个重要意义：</p><ol><li><strong>防止滥用网络资源</strong>：通过收取 Gas 费用，以太坊可以防止恶意用户发起无限循环或占用大量计算资源的操作。</li><li><strong>激励矿工&#x2F;验证者</strong>：Gas 费用作为奖励分配给矿工（在 PoW 机制下）或验证者（在 PoS 机制下），以保障网络的安全性和稳定性。</li><li><strong>动态调节网络负载</strong>：当网络拥堵时，用户可以通过提高 Gas 价格来优先处理自己的交易。</li></ol><h4 id="交易"><a href="#交易" class="headerlink" title="交易"></a><a href="#%E4%BA%A4%E6%98%93"></a>交易</h4><p>在区块链语境中，<strong>交易</strong>是指任何改变区块链状态的操作。交易可以分为两类：</p><ol><li><strong>普通转账交易</strong>：指从一个账户向另一个账户转移加密货币（如 ETH）。</li><li><strong>智能合约交互交易</strong>：指调用智能合约中的函数，可能涉及复杂的数据处理或状态更新。<br>每笔交易都需要包含以下信息：</li></ol><ul><li>发送方地址</li><li>接收方地址（如果是普通转账）或智能合约地址（如果是合约交互）</li><li>转账金额（如果是普通转账）</li><li>Gas 限制（Gas Limit）：用户愿意为该交易支付的最大 Gas 数量</li><li>Gas 价格（Gas Price）：每单位 Gas 的价格<br>如果交易执行所需的 Gas 超过了用户设置的 Gas 限制，交易将失败，但已消耗的 Gas 不会退还。</li></ul><h3 id="开发环境搭建（FISCO-BCOS-Remix-IDE）"><a href="#开发环境搭建（FISCO-BCOS-Remix-IDE）" class="headerlink" title="开发环境搭建（FISCO-BCOS, Remix IDE）"></a><a href="#%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%EF%BC%88FISCO-BCOS-Remix-IDE%EF%BC%89"></a>开发环境搭建（FISCO-BCOS, Remix IDE）</h3><p>为了在区块链上开发和部署智能合约，我们需要搭建合适的开发环境。以下是两种常用的工具：<strong>FISCO-BCOS</strong> 和 <strong>Remix IDE</strong>。</p><h4 id="FISCO-BCOS"><a href="#FISCO-BCOS" class="headerlink" title="FISCO-BCOS"></a><a href="#FISCO-BCOS"></a>FISCO-BCOS</h4><p>FISCO-BCOS 是一个国产的区块链底层平台，专注于企业级应用场景。它支持联盟链模式，适合构建私有链或联盟链项目。以下是搭建 FISCO-BCOS 的基本步骤：</p><p><a href="https://fisco-bcos-doc.readthedocs.io/zh-cn/latest/index.html">https://fisco-bcos-doc.readthedocs.io/zh-cn/latest/index.html</a></p><h4 id="Remix-IDE"><a href="#Remix-IDE" class="headerlink" title="Remix IDE"></a><a href="#Remix-IDE"></a>Remix IDE</h4><p>Remix 是一个基于浏览器的集成开发环境（IDE），专为以太坊智能合约开发设计。它的界面友好，功能强大，非常适合初学者和快速原型开发。以下是使用 Remix 的基本流程：</p><ol><li><strong>访问 Remix IDE</strong>：</li></ol><ul><li>打开浏览器，访问 <a href="https://remix.ethereum.org/">Remix 官网</a>。</li></ul><ol><li><strong>编写智能合约</strong>：</li></ol><ul><li>在 Remix 的“File Explorer”区域新建一个 <code>.sol</code> 文件，例如 <code>MyContract.sol</code>。</li><li>编写 Solidity 代码，例如：</li></ul><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><code class="hljs plaintext">// SPDX-License-Identifier: MIT<br>pragma solidity ^0.8.0;<br>contract MyContract &#123;<br>    uint public value;<br>    function setValue(uint _value) public &#123;<br>        value = _value;<br>    &#125;<br>    function getValue() public view returns (uint) &#123;<br>        return value;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><ol><li><strong>编译合约</strong>：</li></ol><ul><li>切换到“Solidity Compiler”标签页，选择适当的编译器版本并点击“Compile”。</li></ul><ol><li><strong>部署合约</strong>：</li></ol><ul><li>切换到“Deploy &amp; Run Transactions”标签页，选择 JavaScript VM（虚拟机）或其他环境（如 MetaMask）。</li><li>点击“Deploy”按钮将合约部署到测试网络。</li></ul><ol><li><strong>测试合约</strong>：</li></ol><ul><li>在“Deployed Contracts”区域，调用合约的函数（如 <code>setValue</code> 和 <code>getValue</code>）进行交互。</li></ul>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/Solidity%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%88%E4%B8%80%EF%BC%89%E5%8C%BA%E5%9D%97%E9%93%BE%E4%B8%8E%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E6%A6%82%E5%BF%B5/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/Solidity%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E9%9B%B6%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%88%E4%B8%80%EF%BC%89%E5%8C%BA%E5%9D%97%E9%93%BE%E4%B8%8E%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E6%A6%82%E5%BF%B5/"/>
    <published>2025-10-19T14:17:53.000Z</published>
    <summary>启程 - 区块链与智能合约概念比特币 vs 以太坊：为什么需要智能合约？比特币作为区块链技术的第一个成功应用，开创了去中心化数字货币的先河。它的核心功能是提供一种安全、透明且不可篡改的价值转移方式。然而，比特币的设计初衷是专注于支付和存储价值，其脚本语言（Script）虽然具有一定的可编程性，但功能较为有限，无法支持复杂的逻辑操作。相比之下，以太坊在设...</summary>
    <title>Solidity智能合约零基础入门（一）区块链与智能合约概念</title>
    <updated>2025-12-11T09:14:19.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<h2 id="一、工作内容与成果"><a href="#一、工作内容与成果" class="headerlink" title="一、工作内容与成果"></a><a href="#%E4%B8%80%E3%80%81%E5%B7%A5%E4%BD%9C%E5%86%85%E5%AE%B9%E4%B8%8E%E6%88%90%E6%9E%9C"></a>一、工作内容与成果</h2><p>本周围绕农场相关系统的优化、功能扩展及上线展开工作，具体内容与成果如下：</p><p>（一）周一：后台界面优化工作</p><ol><li><strong>本地存储数据安全优化</strong>：针对后台界面，移除了通过 storage 本地存储模拟操作数据的方式。此优化有效避免了操作数据在本地透明可见的问题，提升了数据传输与存储的安全性，降低了数据被篡改或泄露的风险。</li><li><strong>核心业务逻辑调整</strong>：重点调整了后台作物管理与日志操作的核心逻辑。优化后，系统能够精准匹配对应地块的种子信息，确保作物数据与地块信息的关联性；同时，日志信息也能与具体操作场景、地块及作物数据准确对应，提升了后台数据管理的准确性与可读性，为后续数据查询与分析奠定基础。</li></ol><p>（二）周二：作物日志功能扩展</p><ol><li><strong>操作频次管控实现</strong>：为规范作物日志记录，新增作物日志每日操作限制规则，设定每种操作每日最多记录两次。该规则有效避免了日志数据冗余，保证了日志信息的简洁性与有效性，同时也符合农场日常运营中对作物操作的合理频次需求。</li><li><strong>日志生命周期管理</strong>：完善作物日志的生命周期逻辑，实现 “收获后自动删除日志，后续重新操作时添加新日志” 的功能。此举确保了日志信息与作物生长周期的同步性，避免了过期日志对数据管理的干扰，提升了日志数据的时效性。</li><li><strong>弱网环境数据保障</strong>：采用幂等性设计实现作物日志记录功能，在弱网、网络不流畅等不稳定环境下，能够有效防止重复添加日志数据，同时确保操作数据的完整性与准确性，提升了系统在复杂网络环境下的稳定性与可靠性。</li></ol><p>（三）周三：农场后台管理系统上线</p><ol><li><strong>管家日志管理功能</strong>：上线的农场后台管理系统中，新增管家后台日志记录功能，管家可通过系统的 “作物管理” 模块与 “每周日志” 模块，实时记录、查看与管理作物相关的操作日志，便于管家全面掌握作物生长过程中的关键操作，提升管理效率。</li><li><strong>种子图鉴管理功能</strong>：系统支持管家通过 “种子管理” 模块，上传、编辑与管理种子图鉴信息，包括种子品种、生长周期、适宜环境等关键数据。该功能为管家提供了统一的种子信息管理平台，便于规范种子信息管理，同时也为后续作物种植规划提供数据支持。</li><li><strong>订单查询管理功能</strong>：上线 “订单管理” 模块，管家可通过该模块快速查询所有订单信息，包括订单编号、订单类型、下单时间、订单状态等详细内容，支持按不同条件筛选查询，提升了订单信息的查询效率，便于管家及时跟进订单进度，保障农场运营的顺畅性。</li></ol><h3 id="二、核心工作成果"><a href="#二、核心工作成果" class="headerlink" title="二、核心工作成果"></a><a href="#%E4%BA%8C%E3%80%81%E6%A0%B8%E5%BF%83%E5%B7%A5%E4%BD%9C%E6%88%90%E6%9E%9C"></a>二、核心工作成果</h3><p>本周聚焦农场相关系统完成三项关键工作：一是优化后台界面，移除 storage 本地存储模拟数据以强化安全，同时调整作物与日志逻辑，实现地块 - 种子 - 日志信息精准匹配；二是扩展作物日志功能，新增每日操作频次限制、收获后日志自动清理机制，并通过幂等设计解决弱网环境下数据重复问题；三是成功上线农场后台管理系统，为管家提供日志管理、种子图鉴上传、订单查询三大核心模块，满足日常管理需求。</p><h3 id="三、关键价值与亮点"><a href="#三、关键价值与亮点" class="headerlink" title="三、关键价值与亮点"></a><a href="#%E4%B8%89%E3%80%81%E5%85%B3%E9%94%AE%E4%BB%B7%E5%80%BC%E4%B8%8E%E4%BA%AE%E7%82%B9"></a>三、关键价值与亮点</h3><p>从安全性、实用性、稳定性三方面实现突破：安全层面，通过本地存储优化降低数据泄露风险，为系统数据安全奠定基础；实用层面，日志生命周期管理与后台系统功能模块，直接贴合农场运营场景，帮助管家提升数据管理与工作效率；稳定性层面，幂等设计的应用，有效应对复杂网络环境，保障操作数据的完整性，减少系统异常问题。</p><h3 id="四、后续行动方向"><a href="#四、后续行动方向" class="headerlink" title="四、后续行动方向"></a><a href="#%E5%9B%9B%E3%80%81%E5%90%8E%E7%BB%AD%E8%A1%8C%E5%8A%A8%E6%96%B9%E5%90%91"></a>四、后续行动方向</h3><p>后续将围绕 “优化体验、强化安全、拓展功能” 推进工作：优先收集管家使用反馈，迭代优化系统操作流程与功能漏洞；进一步完善数据安全体系，新增定期备份与恢复机制；结合农场实际需求调研新功能（如作物生长监控），同时持续监控系统性能，通过优化数据库、压缩资源等方式，确保系统长期稳定高效运行。</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%B9%9D%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%B9%9D%E5%91%A8/"/>
    <published>2025-09-13T08:16:54.000Z</published>
    <summary>一、工作内容与成果本周围绕农场相关系统的优化、功能扩展及上线展开工作，具体内容与成果如下： （一）周一：后台界面优化工作 本地存储数据安全优化：针对后台界面，移除了通过 storage 本地存储模拟操作数据的方式。此优化有效避免了操作数据在本地透明可见的问题，提升了数据传输与存储的安全性，降低了数据被篡改或泄露的风险。 核心业务逻辑调整：重点调整了后台...</summary>
    <title>广州it工作第九周</title>
    <updated>2025-12-11T09:11:10.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>本周核心目标：</strong> 实现从购买、种植、管理到收获的完整农场业务闭环，并完善后台管理功能。<br><strong>整体进展：</strong> ✅ <strong>核心闭环成功打通！</strong> 用户可完成<code>购买服务</code> -&gt; <code>播种</code> -&gt; <code>日常管理（浇水）</code> -&gt; <code>生成日志</code> -&gt; <code>收获</code> -&gt; <code>下单配送</code>的全流程。后台管理功能得到显著增强。</p><hr><h3 id="一、-每日开发详情"><a href="#一、-每日开发详情" class="headerlink" title="一、 每日开发详情"></a><a href="#%E4%B8%80%E3%80%81-%E6%AF%8F%E6%97%A5%E5%BC%80%E5%8F%91%E8%AF%A6%E6%83%85"></a>一、 每日开发详情</h3><table><thead><tr><th><strong>日期</strong></th><th><strong>核心工作</strong></th><th><strong>关键产出与细节</strong></th></tr></thead><tbody><tr><td><strong>周一</strong></td><td><strong>后端服务开发</strong></td><td>✅ <strong>下单服务</strong>：完成接收、处理、存储订单信息的后端逻辑。</td></tr><tr><td>✅ <strong>后台托管服务</strong>：实现分配管家处理任务及切换角色登录权限的功能。</td><td></td><td></td></tr><tr><td><strong>周二</strong></td><td><strong>后台管理系统开发</strong></td><td>✅ <strong>订单管理页面</strong>：</td></tr></tbody></table><ul><li>设计订单列表，可根据 <code>order_type</code> 动态展示信息。  </li><li>实现按类型、状态等条件的筛选功能。  </li><li>开发订单详情页，关联显示主表(<code>t_order</code>)与子表信息。<br>✅ <strong>托管日志集成</strong>：在作物管理界面中，可查看关联的托管服务日志。<br>✅ <strong>管家绑定</strong>：前端通过 <code>store</code> 中的用户ID查询并绑定 <code>caretaker_user_id</code>，管理作物。 |<br>| <strong>周三</strong> | <strong>前后端功能联调</strong> | ✅ <strong>日志查看</strong>：点击作物即可显示相关管家的操作日志。<br>✅ <strong>订单管理</strong>：用户可查询并修改自己的订单信息。 |<br>| <strong>周四</strong> | <strong>功能优化与扩展</strong> | ✅ <strong>修复前端显示</strong>：优化购买服务页面，为播种功能做准备。<br>✅ <strong>服务扩展</strong>：扩展下单服务，支持收获后生成配送订单的流程。<br>✅ <strong>界面优化</strong>：对订单列表的“待收获”界面进行了视觉和体验优化。 |<br>| <strong>周五</strong> | <strong>交互功能实现</strong> | ✅ <strong>确认操作</strong>：实现前端确认操作（如浇水）的功能。<br>✅ <strong>日志记录</strong>：为浇水等操作生成两种日志：  </li><li><strong>用户操作日志</strong> (用户点击触发)  </li><li><strong>管家工作日志</strong> (管家后台记录)<br>✅ <strong>通知机制</strong>：管家可在后台管理系统中获取相关操作的通知和日志。 |<br>| <strong>周六</strong> | <strong>全链路测试与BUG修复</strong> | ✅ <strong>核心闭环验证</strong>：成功测试并修复逻辑BUG，确保从购买到收获下单的全流程畅通。<br>✅ <strong>遗留问题定位</strong>：  </li><li><strong>问题一</strong>：手机端支付后可重复点击购买，需前端优化交互。  </li><li><strong>问题二</strong>：后台订单界面需集成第三方服务（如支付、物流），待确定方案。 |</li></ul><hr><h3 id="二、-核心业务流程与逻辑-本周重大进展"><a href="#二、-核心业务流程与逻辑-本周重大进展" class="headerlink" title="二、 核心业务流程与逻辑 (本周重大进展)"></a><a href="#%E4%BA%8C%E3%80%81-%E6%A0%B8%E5%BF%83%E4%B8%9A%E5%8A%A1%E6%B5%81%E7%A8%8B%E4%B8%8E%E9%80%BB%E8%BE%91-%E6%9C%AC%E5%91%A8%E9%87%8D%E5%A4%A7%E8%BF%9B%E5%B1%95"></a>二、 核心业务流程与逻辑 (本周重大进展)</h3><ol><li><strong>收获后处理逻辑（后端）</strong>：<br>当用户发起收获并成功创建配送单后，系统自动执行以下操作，确保数据状态准确：</li></ol><p><strong>清空地块</strong>：将对应地块的作物状态重置为 <code>empty</code>。<br>2. <strong>扣减权益</strong>：<br>对于<strong>次数型</strong>权益：将 <code>uses_left</code> (剩余次数) 减1。若次数用尽，则将权益状态置为 <code>consumed</code>。<br>3. 对于<strong>时长型</strong>权益：不扣减次数，仅检查有效期。<br>4. <strong>更新权益状态</strong>：重新计算该地块的 <code>owned</code> 字段。只要仍有有效的<code>active</code>权益（次数未用完或未过期），<code>owned</code> 即为 <code>true</code>，否则为 <code>false</code>。<br>5. <strong>前端支付流程优化（已解决）</strong>：<br>修复了 <code>purchaseServicePackage</code> 函数中 <code>await</code> 与 <code>success</code> 回调混用导致的逻辑问题。</p><p><strong>解决方案</strong>：重写该函数，采用纯 <code>async/await</code> 方式调用支付接口。支付成功后，<strong>立即调用后端接口刷新地块数据</strong>，并提交一个 <code>mutation</code> 来本地更新状态，确保UI显示及时、准确。</p><hr><h3 id="三、-待解决的问题与下周计划"><a href="#三、-待解决的问题与下周计划" class="headerlink" title="三、 待解决的问题与下周计划"></a><a href="#%E4%B8%89%E3%80%81-%E5%BE%85%E8%A7%A3%E5%86%B3%E7%9A%84%E9%97%AE%E9%A2%98%E4%B8%8E%E4%B8%8B%E5%91%A8%E8%AE%A1%E5%88%92"></a>三、 待解决的问题与下周计划</h3><table><thead><tr><th><strong>问题描述</strong></th><th><strong>性质</strong></th><th><strong>可能解决方案&#x2F;下一步计划</strong></th></tr></thead><tbody><tr><td><strong>1. 移动端支付后可重复点击</strong></td><td>前端交互BUG</td><td>在支付请求发起后，禁用按钮并显示加载状态，直到收到明确的成功&#x2F;失败回调。</td></tr><tr><td><strong>2. 后台需集成第三方服务</strong></td><td>技术方案调研</td><td>调研并选择可靠的第三方服务提供商（如支付宝&#x2F;微信支付官方API、聚合支付平台、物流公司API），然后编写对接代码。</td></tr></tbody></table><p><strong>下周计划：</strong></p><ul><li><strong>解决遗留问题</strong>：优先修复移动端支付交互BUG，并启动第三方服务对接的调研与开发。</li><li><strong>功能增强</strong>：基于已打通的闭环，考虑添加更多作物管理操作（如施肥、除虫）、优化日志系统、设计更完善的管家通知中心。</li><li><strong>测试与部署</strong>：进行更全面的测试，准备将新功能部署至测试或生产环境。</li></ul><hr><h3 id="四、-本周工作回顾：核心业务闭环全面打通"><a href="#四、-本周工作回顾：核心业务闭环全面打通" class="headerlink" title="四、 本周工作回顾：核心业务闭环全面打通"></a><a href="#%E5%9B%9B%E3%80%81-%E6%9C%AC%E5%91%A8%E5%B7%A5%E4%BD%9C%E5%9B%9E%E9%A1%BE%EF%BC%9A%E6%A0%B8%E5%BF%83%E4%B8%9A%E5%8A%A1%E9%97%AD%E7%8E%AF%E5%85%A8%E9%9D%A2%E6%89%93%E9%80%9A"></a><strong>四、 本周工作回顾：核心业务闭环全面打通</strong></h3><p>本周的核心工作是推动农场项目的<strong>完整业务流程实现</strong>与<strong>后台管理系统强化</strong>，并成功完成了端到端的测试验证。</p><ol><li><strong>后端服务建设</strong>：完成了<strong>下单服务</strong>与<strong>后台托管服务</strong>的开发，实现了订单的接收、处理、存储，以及管家的任务分配与权限管理。</li><li><strong>后台管理功能增强</strong>：开发了功能完善的订单管理页面（列表、筛选、详情）、托管服务日志记录模块，并实现了作物与管家的绑定管理。</li><li><strong>核心业务闭环验证</strong>：成功打通了“<strong>用户购买服务 -&gt; 播种 -&gt; 进行浇水等管理操作 -&gt; 自动生成日志 -&gt; 收获并创建配送单 -&gt; 地块状态重置</strong>”的完整业务流程，标志着项目最核心的功能链路已全部跑通。</li><li><strong>前端体验优化</strong>：修复了购买服务页面的显示问题，优化了订单界面，并重写了支付逻辑，确保了交互的准确性和数据的一致性。</li></ol><h3 id="五-、-问题与反思：技术方案与细节处理需持续打磨"><a href="#五-、-问题与反思：技术方案与细节处理需持续打磨" class="headerlink" title="五**、 问题与反思：技术方案与细节处理需持续打磨**"></a><a href="#%E4%BA%94%E3%80%81-%E9%97%AE%E9%A2%98%E4%B8%8E%E5%8F%8D%E6%80%9D%EF%BC%9A%E6%8A%80%E6%9C%AF%E6%96%B9%E6%A1%88%E4%B8%8E%E7%BB%86%E8%8A%82%E5%A4%84%E7%90%86%E9%9C%80%E6%8C%81%E7%BB%AD%E6%89%93%E7%A3%A8"></a>五**、 问题与反思：技术方案与细节处理需持续打磨**</h3><p>在开发过程中，也遇到并识别了一些亟待解决的问题，主要集中在交互细节和技术方案选型上。</p><ol><li><strong>移动端交互细节问题</strong>：手机端支付成功后，按钮状态未能及时重置，导致用户可重复点击，<strong>暴露了前端对连续请求控制的不足</strong>。这需要通过添加加载状态和按钮禁用机制来优化。</li><li><strong>外部集成技术方案待定</strong>：后台系统需要接入支付、物流等第三方服务，但目前<strong>尚未确定具体的技术选型和对接方案</strong>，这是下一步需要重点调研和决策的点。</li><li><strong>逻辑严谨性</strong>：在解决“收获后清空地块”等复杂业务逻辑时，意识到必须通过<strong>精准的后端逻辑</strong>（如扣减权益、状态更新）来保证数据一致性，而非依赖前端。</li></ol><h3 id="六、-下周计划：解决遗留问题，推进系统集成与优化"><a href="#六、-下周计划：解决遗留问题，推进系统集成与优化" class="headerlink" title="六、 下周计划：解决遗留问题，推进系统集成与优化"></a><a href="#%E5%85%AD%E3%80%81-%E4%B8%8B%E5%91%A8%E8%AE%A1%E5%88%92%EF%BC%9A%E8%A7%A3%E5%86%B3%E9%81%97%E7%95%99%E9%97%AE%E9%A2%98%EF%BC%8C%E6%8E%A8%E8%BF%9B%E7%B3%BB%E7%BB%9F%E9%9B%86%E6%88%90%E4%B8%8E%E4%BC%98%E5%8C%96"></a><strong>六、 下周计划：解决遗留问题，推进系统集成与优化</strong></h3><p>基于本周的进展和问题，下周的工作将围绕以下重点展开：</p><ol><li><strong>优先解决遗留问题</strong>：<br>修复移动端支付交互BUG，增加防重复提交机制。</li><li>启动对第三方服务（如支付、物流API）的调研，并形成初步的集成方案。</li><li><strong>功能增强与优化</strong>：<br>在现有闭环基础上，规划并开发更多的作物管理操作（如施肥、除虫）。</li><li>优化日志系统和管家通知中心，提升用户体验和管理效率。</li><li><strong>测试与部署准备</strong>：<br>对已打通的全流程进行更全面的测试，准备将稳定版本部署至测试环境。</li></ol>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%85%AB%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%85%AB%E5%91%A8/"/>
    <published>2025-09-07T12:22:49.000Z</published>
    <summary>
      <![CDATA[本周核心目标： 实现从购买、种植、管理到收获的完整农场业务闭环，并完善后台管理功能。整体进展： ✅ 核心闭环成功打通！ 用户可完成购买服务 -> 播种 -> 日常管理（浇水） -> 生成日志 -> 收获 -> 下单配送的全流程。后台管理功能得到显著增强。 一、 每日开发详情 日期 核心工作 关键产出与细节 周一 后端服务开发 ✅ 下单服务：完成接收、处]]>
    </summary>
    <title>广州it工作第八周</title>
    <updated>2025-12-11T09:11:06.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<h3 id="周一：农场服务前端界面实现"><a href="#周一：农场服务前端界面实现" class="headerlink" title="周一：农场服务前端界面实现"></a><a href="#%E5%91%A8%E4%B8%80%EF%BC%9A%E5%86%9C%E5%9C%BA%E6%9C%8D%E5%8A%A1%E5%89%8D%E7%AB%AF%E7%95%8C%E9%9D%A2%E5%AE%9E%E7%8E%B0"></a><strong>周一：农场服务前端界面实现</strong></h3><p><strong>完成工作</strong>：</p><ul><li>实现托管服务操作流程：点击托管→选择种植物→确认收获→判断收获方式。</li><li>搭建基础农场前端界面，完成用户交互逻辑。</li></ul><p><strong>遇到的问题</strong>：</p><ul><li>收获方式判断逻辑需与后端土地状态同步（未实时更新）。</li></ul><p><strong>解决方式</strong>：</p><ul><li>添加前端定时查询地块状态，确保数据一致性。</li></ul><hr><h3 id="周二：订单生成与支付界面优化"><a href="#周二：订单生成与支付界面优化" class="headerlink" title="周二：订单生成与支付界面优化"></a><a href="#%E5%91%A8%E4%BA%8C%EF%BC%9A%E8%AE%A2%E5%8D%95%E7%94%9F%E6%88%90%E4%B8%8E%E6%94%AF%E4%BB%98%E7%95%8C%E9%9D%A2%E4%BC%98%E5%8C%96"></a><strong>周二：订单生成与支付界面优化</strong></h3><p><strong>完成工作</strong>：</p><ul><li>对接托管服务订单接口（<code>/orders/service</code>），生成订单并关联用户与地块数据。</li><li>优化支付界面样式，使其更简洁清晰，支持后续扩展托管服务类型。</li><li>实现土地及托管服务数据存储，支持详细查询。</li></ul><p><strong>遇到的问题</strong>：</p><ul><li>支付界面在不同设备上显示错位（移动端适配问题）。</li></ul><p><strong>解决方式</strong>：</p><ul><li>使用响应式布局（CSS Flexbox+Media Query）快速修复。</li></ul><hr><h3 id="周三：扩展购买与播种功能"><a href="#周三：扩展购买与播种功能" class="headerlink" title="周三：扩展购买与播种功能"></a><a href="#%E5%91%A8%E4%B8%89%EF%BC%9A%E6%89%A9%E5%B1%95%E8%B4%AD%E4%B9%B0%E4%B8%8E%E6%92%AD%E7%A7%8D%E5%8A%9F%E8%83%BD"></a><strong>周三：扩展购买与播种功能</strong></h3><p><strong>完成工作</strong>：</p><ul><li>扩展托管服务购买功能（接口：<code>/farm/service/package/purchase</code>）。</li><li>实现种子播种功能（接口：<code>/farm/plant</code>）并关联地块数据（接口：<code>/farm/plots</code>）。</li><li>订单查询与支付状态联动（支付成功自动更新订单状态）。</li></ul><p><strong>遇到的问题</strong>：</p><ul><li>播种请求超时（地块数据量增大导致查询缓慢）。</li></ul><p><strong>解决方式</strong>：</p><ul><li>为<code>/farm/plots</code>接口添加缓存机制（Redis缓存地块信息）。</li></ul><hr><h3 id="周四：后台管理系统开发"><a href="#周四：后台管理系统开发" class="headerlink" title="周四：后台管理系统开发"></a><a href="#%E5%91%A8%E5%9B%9B%EF%BC%9A%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%8F%91"></a><strong>周四：后台管理系统开发</strong></h3><p><strong>完成工作</strong>：</p><ul><li>实现后台托管服务管理（增删改查）。</li><li>开发作物管理模块（支持作物信息维护）。</li><li>搭建每周日志记录功能（支持日志添加与查询）。</li><li>完成种子管理基础功能（CRUD操作）。</li></ul><p><strong>遇到的问题</strong>：</p><ul><li>管家管理模块需对接若依权限系统，但账户体系不兼容。</li></ul><p><strong>解决方式</strong>：</p><ul><li>暂独立开发管家管理模块，预留若依系统对接接口。</li></ul><hr><h3 id="周五：后台功能完善与权限隔离"><a href="#周五：后台功能完善与权限隔离" class="headerlink" title="周五：后台功能完善与权限隔离"></a><a href="#%E5%91%A8%E4%BA%94%EF%BC%9A%E5%90%8E%E5%8F%B0%E5%8A%9F%E8%83%BD%E5%AE%8C%E5%96%84%E4%B8%8E%E6%9D%83%E9%99%90%E9%9A%94%E7%A6%BB"></a><strong>周五：后台功能完善与权限隔离</strong></h3><p><strong>完成工作</strong>：</p><ul><li>完成托管服务、作物管理、每周日志、种子管理的完整增删改查功能。</li><li>优化后台数据查询效率（添加数据库索引）。</li><li>管家管理模块独立运行（暂未关联若依登录）。</li></ul><p><strong>遇到的问题</strong>：</p><ul><li>若依系统权限接口文档缺失，无法直接对接。</li></ul><p><strong>解决方式</strong>：</p><ul><li>优先保证其他后台功能上线，管家管理采用若依账号过渡。</li></ul><hr><h3 id="本周总结"><a href="#本周总结" class="headerlink" title="本周总结"></a><a href="#%E6%9C%AC%E5%91%A8%E6%80%BB%E7%BB%93"></a><strong>本周总结</strong></h3><h4 id="1-独立完成内容"><a href="#1-独立完成内容" class="headerlink" title="1. 独立完成内容"></a><a href="#1-%E7%8B%AC%E7%AB%8B%E5%AE%8C%E6%88%90%E5%86%85%E5%AE%B9"></a><strong>1. 独立完成内容</strong></h4><ul><li>前端农场服务全流程（托管→支付→播种→收获）。</li><li>订单与支付系统集成（微信支付+订单状态管理）。</li><li>后台管理核心功能（作物、日志、种子、托管服务管理）。</li></ul><h4 id="2-主要挑战"><a href="#2-主要挑战" class="headerlink" title="2. 主要挑战"></a><a href="#2-%E4%B8%BB%E8%A6%81%E6%8C%91%E6%88%98"></a><strong>2. 主要挑战</strong></h4><ul><li><strong>支付合规性</strong>：订单号长度限制（32位）、HTTPS证书配置。</li><li><strong>系统兼容性</strong>：管家模块与若依权限系统账户体系不匹配。</li><li><strong>性能问题</strong>：地块数据量增大导致查询缓慢。</li></ul><h4 id="3-成长与改进"><a href="#3-成长与改进" class="headerlink" title="3. 成长与改进"></a><a href="#3-%E6%88%90%E9%95%BF%E4%B8%8E%E6%94%B9%E8%BF%9B"></a><strong>3. 成长与改进</strong></h4><ul><li><strong>第三方集成经验</strong>：支付接口必须严格遵循字段规范（如订单号长度）。</li><li><strong>解耦设计</strong>：模块化开发（如管家管理独立）降低系统耦合风险。</li><li><strong>性能优化</strong>：引入缓存与数据库索引应对数据增长。</li></ul><h4 id="4-后续计划"><a href="#4-后续计划" class="headerlink" title="4. 后续计划"></a><a href="#4-%E5%90%8E%E7%BB%AD%E8%AE%A1%E5%88%92"></a><strong>4. 后续计划</strong></h4><ul><li>补全若依系统对接文档，完成管家权限集成。</li><li>统一接口响应格式，编写后端API文档。</li><li>增加农场操作（播种、收获）的事务回滚机制。</li></ul><p><strong>总结</strong>：本周成功交付农场系统核心功能，但支付与权限集成暴露了<strong>预研不足</strong>的问题。后续类似项目需提前验证第三方接口（支付、登录）的合规性；</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%B8%83%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%B8%83%E5%91%A8/"/>
    <published>2025-08-30T11:18:00.000Z</published>
    <summary>周一：农场服务前端界面实现完成工作： 实现托管服务操作流程：点击托管→选择种植物→确认收获→判断收获方式。 搭建基础农场前端界面，完成用户交互逻辑。 遇到的问题： 收获方式判断逻辑需与后端土地状态同步（未实时更新）。 解决方式： 添加前端定时查询地块状态，确保数据一致性。 周二：订单生成与支付界面优化完成工作： 对接托管服务订单接口（/orders/</summary>
    <title>广州it工作第七周</title>
    <updated>2025-12-11T09:11:35.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>本周核心目标：</strong> 实现小程序核心交易与农场种植闭环（支付功能 + 农场后端服务）<br><strong>整体进展：</strong> ✅ 成功打通<code>HTTPS部署</code> -&gt; <code>微信支付</code> -&gt; <code>农场种植</code>全链路，项目进入可演示阶段。</p><hr><h3 id="一、-每日工作记录"><a href="#一、-每日工作记录" class="headerlink" title="一、 每日工作记录"></a><a href="#%E4%B8%80%E3%80%81-%E6%AF%8F%E6%97%A5%E5%B7%A5%E4%BD%9C%E8%AE%B0%E5%BD%95"></a><strong>一、 每日工作记录</strong></h3><table><thead><tr><th><strong>日期</strong></th><th><strong>核心工作</strong></th><th><strong>关键产出与细节</strong></th></tr></thead><tbody><tr><td><strong>周一</strong></td><td><strong>HTTPS服务配置</strong></td><td>✅ <strong>前端</strong>：使用Nginx配置SSL证书，实现小程序前端页面的HTTPS安全访问。</td></tr><tr><td>✅ <strong>后端</strong>：在SpringBoot中配置SSL证书，使后端API支持HTTPS请求，为微信支付等安全接口打下基础。</td><td></td><td></td></tr><tr><td><strong>周二</strong></td><td><strong>微信支付集成</strong></td><td>✅ 集成<strong>微信支付V2版</strong>，完成下单、回调等核心流程开发。</td></tr><tr><td>✅ 使用<strong>内网穿透</strong>工具模拟支付环境，初步测试通过。</td><td></td><td></td></tr><tr><td>⚠️ <strong>待办</strong>：退款功能暂未实现。</td><td></td><td></td></tr><tr><td><strong>周三</strong></td><td><strong>问题修复与设计</strong></td><td>✅ <strong>修复支付Bug</strong>：深入分析并解决了官方文档中提及的“订单重复”问题，优化为首次<code>统一下单</code>、后续调用<code>jsapi</code>的稳定流程。</td></tr><tr><td>✅ <strong>数据库设计</strong>：为农场托管功能设计了<code>farms</code>（田地）、<code>crops</code>（种子）、<code>farmManagers</code>（农场管家）三张核心表，明确通过JWT鉴权来隔离用户数据。</td><td></td><td></td></tr><tr><td><strong>周四</strong></td><td><strong>农场服务开发</strong></td><td>✅ 开发并部署核心农场后端服务，提供初步可用的RESTful API：</td></tr></tbody></table><ul><li><code>POST /farm/plant</code>： <strong>种植接口</strong>  </li><li><code>POST /farm/init</code>： <strong>初始化用户田地</strong>  </li><li><code>POST /farm/listByUser</code>： <strong>获取用户田地信息</strong> |<br>| <strong>周五</strong> | <strong>联调与架构复盘</strong> | ✅ 成功完成前端与农场服务的联调，可获取并展示用户种植数据。<br>✅ <strong>架构决策</strong>：确定使用<strong>混合云开发</strong>方案（自建MySQL + 云服务），兼顾了数据灵活性与开发效率。 |</li></ul><hr><h3 id="二、-本周最大的挑战与解决方案"><a href="#二、-本周最大的挑战与解决方案" class="headerlink" title="二、 本周最大的挑战与解决方案"></a><a href="#%E4%BA%8C%E3%80%81-%E6%9C%AC%E5%91%A8%E6%9C%80%E5%A4%A7%E7%9A%84%E6%8C%91%E6%88%98%E4%B8%8E%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88"></a><strong>二、 本周最大的挑战与解决方案</strong></h3><ul><li><strong>挑战：</strong> 技术选型在<strong>数据库扩展性</strong>与<strong>开发维护效率</strong>之间的权衡。纯微信云开发无法满足复杂的MySQL业务需求，而完全自建服务器运维成本较高。</li><li><strong>解决方案：</strong> 采用<strong>混合云架构</strong>。<br><strong>核心业务数据</strong>（用户、订单、农场）：使用自建云服务器上的MySQL数据库，保证了对数据的完全控制和复杂查询能力。</li><li><strong>静态资源&#x2F;轻量功能</strong>：后续可考虑使用云开发平台的服务，提升开发速度与稳定性。</li></ul><hr><h3 id="三、-本周工作带来的成长"><a href="#三、-本周工作带来的成长" class="headerlink" title="三、 本周工作带来的成长"></a><a href="#%E4%B8%89%E3%80%81-%E6%9C%AC%E5%91%A8%E5%B7%A5%E4%BD%9C%E5%B8%A6%E6%9D%A5%E7%9A%84%E6%88%90%E9%95%BF"></a><strong>三、 本周工作带来的成长</strong></h3><ol><li><strong>全链路能力提升：</strong> 从最基础的HTTPS配置，到复杂的支付业务、数据库设计，再到后端服务开发，独立打通了核心功能的全链路，对前后端协同开发的理解更加深刻。</li><li><strong>技术方案设计能力：</strong> 不再局限于实现功能，开始从<strong>架构角度</strong>思考问题（如混合云选型），学会了在多种技术方案中权衡利弊，选择最适合当前业务阶段的方案。</li><li><strong>文档驱动开发：</strong> 通过编写设计文档来理清逻辑，再着手编码，有效减少了开发过程中的反复和错误，提升了开发效率和质量。</li></ol><hr><h3 id="四、-反思与未来优化"><a href="#四、-反思与未来优化" class="headerlink" title="四、 反思与未来优化"></a><a href="#%E5%9B%9B%E3%80%81-%E5%8F%8D%E6%80%9D%E4%B8%8E%E6%9C%AA%E6%9D%A5%E4%BC%98%E5%8C%96"></a><strong>四、 反思与未来优化</strong></h3><ul><li><strong>本周不足：</strong> 最初的方案设计对<strong>云原生</strong>和<strong>混合架构</strong>的考量不够深入，导致中途需要调整技术路线，产生了一定的学习成本。</li><li><strong>未来优化：</strong><br><strong>架构设计</strong>：在项目初期，应更系统地评估各种技术方案（自建、纯云、混合云）的优缺点，制作详细的对比表格，避免后期切换。</li><li><strong>可维护性</strong>：虽然混合方案稳定，但未来可以考虑使用<strong>Docker容器化</strong>来部署MySQL和应用，提升环境一致性和迁移效率。</li><li><strong>功能完善</strong>：下一步需补全<strong>退款流程</strong>，并开始构建基于农场数据的<strong>商城购买与订单生成</strong>功能，最终完成商业闭环。</li></ul><hr>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%85%AD%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%85%AD%E5%91%A8/"/>
    <published>2025-08-25T15:01:50.000Z</published>
    <summary>
      <![CDATA[本周核心目标： 实现小程序核心交易与农场种植闭环（支付功能 + 农场后端服务）整体进展： ✅ 成功打通HTTPS部署 -> 微信支付 -> 农场种植全链路，项目进入可演示阶段。 一、 每日工作记录 日期 核心工作 关键产出与细节 周一 HTTPS服务配置 ✅ 前端：使用Nginx配置SSL证书，实现小程序前端页面的HTTPS安全访问。✅ 后端：在Spr...]]>
    </summary>
    <title>广州it工作第六周</title>
    <updated>2025-12-11T09:11:12.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<hr><table><thead><tr><th>日期</th><th>核心工作</th><th>关键产出</th></tr></thead><tbody><tr><td><strong>周一</strong></td><td>后台系统技术选型与架构设计</td><td>✅ 选定 <strong>若依框架</strong> 搭建后台管理系统</td></tr><tr><td>✅ 完成 <strong>功能模块划分</strong> 及技术文档输出</td><td></td><td></td></tr><tr><td><strong>周二</strong></td><td>用户管理模块开发</td><td>✅ 实现用户信息 <strong>增删改查（CRUD）</strong> 全功能</td></tr><tr><td><strong>周三</strong></td><td>核心业务模块开发</td><td>✅ 完成 <strong>订单管理</strong> 业务流程设计</td></tr><tr><td>✅ 落地 <strong>土地管理</strong> CRUD 核心逻辑</td><td></td><td></td></tr><tr><td><strong>周四</strong></td><td>技术方案优化与问题修复</td><td>✅ 验证 <strong>微信云开发</strong> 替代方案可行性</td></tr><tr><td>✅ 修复 <strong>图片上传异常</strong> Bug（改用云存储+路径映射）</td><td></td><td></td></tr><tr><td><strong>周五</strong></td><td>混合架构设计与规划</td><td>✅ 制定 <strong>MySQL + 云数据库混合方案</strong></td></tr><tr><td>✅ 参与 <strong>后续原型扩展</strong> 技术讨论</td><td></td><td></td></tr></tbody></table><hr><h3 id="关键亮点说明："><a href="#关键亮点说明：" class="headerlink" title="关键亮点说明："></a><a href="#%E5%85%B3%E9%94%AE%E4%BA%AE%E7%82%B9%E8%AF%B4%E6%98%8E%EF%BC%9A"></a>关键亮点说明：</h3><ol><li><strong>技术选型</strong>：</li></ol><p>选择 <strong>若依框架</strong> → 节省60%基础模块开发时间<br>2. 放弃纯云开发 → 因 <strong>MySQL业务兼容性</strong> 不足<br>3. <strong>架构突破</strong>：<br><code>graph LR A[微信小程序] --&gt; B{云存储} A --&gt; C[自建服务器] B --&gt; D[图片/文件] C --&gt; E[MySQL业务库] </code><br><strong>混合架构价值</strong>：静态资源云化减压，核心数据自主可控</p><hr><h3 id="一、独立完成事项-挑战与成长"><a href="#一、独立完成事项-挑战与成长" class="headerlink" title="一、独立完成事项 &amp; 挑战与成长"></a><a href="#%E4%B8%80%E3%80%81%E7%8B%AC%E7%AB%8B%E5%AE%8C%E6%88%90%E4%BA%8B%E9%A1%B9-amp-%E6%8C%91%E6%88%98%E4%B8%8E%E6%88%90%E9%95%BF"></a>一、独立完成事项 &amp; 挑战与成长</h3><table><thead><tr><th><strong>工作内容</strong></th><th><strong>挑战</strong></th><th><strong>克服方式</strong></th><th><strong>成长收获</strong></th></tr></thead><tbody><tr><td><strong>1. 后台系统设计</strong></td><td></td><td></td><td></td></tr></tbody></table><ul><li>技术选型（若依框架）  </li><li>功能模块规划文档 | • 平衡开发效率与后期扩展性 | • 选择 <strong>开源后台框架若依</strong>（集成权限管理&#x2F;代码生成） | ✅ 掌握 <strong>快速搭建企业级后台</strong> 的方法论 |<br>| <strong>2. 核心模块开发</strong>  </li><li>用户管理（增删改查）  </li><li>订单&#x2F;土地管理功能 | • 数据库设计需兼容农场业务逻辑<br>• 字段关联性复杂 | • 先画 <strong>ER图梳理数据关系</strong><br>• 用若依代码生成器快速实现基础CRUD | ✅ 提升 <strong>业务模型抽象能力</strong><br>✅ 熟练 <strong>框架工具提效技巧</strong> |<br>| <strong>3. 技术方案优化</strong>  </li><li>尝试微信云开发  </li><li>图片上传BUG修复 | • 云开发与传统MySQL不兼容<br>• 图片路径存储异常 | • 改用 <strong>混合云架构</strong>：  </li><li>核心业务用云服务器+MySQL  </li><li>图片&#x2F;文件用云存储 | ✅ 理解 <strong>混合云方案设计思维</strong><br>✅ 学会 <strong>根据场景灵活选型</strong> |</li></ul><hr><h3 id="二、本周工作思考"><a href="#二、本周工作思考" class="headerlink" title="二、本周工作思考"></a><a href="#%E4%BA%8C%E3%80%81%E6%9C%AC%E5%91%A8%E5%B7%A5%E4%BD%9C%E6%80%9D%E8%80%83"></a>二、本周工作思考</h3><ol><li><strong>「快 vs 稳」的博弈</strong>：</li></ol><p>若依框架虽加速开发，但过度依赖其生成代码可能导致<strong>技术债积累</strong>（如订单扩展字段需手动调整），下次需预留20%自定义空间。<br>2. <strong>云服务的双刃剑</strong>：  </p><p>微信云开发适合轻量应用，但<strong>数据库生态封闭</strong>（不支持MySQL）成为硬伤，混合架构虽解燃眉之急，也带来运维复杂度。</p><hr><h3 id="三、若重来我会如何做？"><a href="#三、若重来我会如何做？" class="headerlink" title="三、若重来我会如何做？"></a><a href="#%E4%B8%89%E3%80%81%E8%8B%A5%E9%87%8D%E6%9D%A5%E6%88%91%E4%BC%9A%E5%A6%82%E4%BD%95%E5%81%9A%EF%BC%9F"></a>三、若重来我会如何做？</h3><ol><li><strong>技术选型更严谨</strong>：</li></ol><p>制作 <strong>方案对比表</strong>（如下），避免试错成本：<br>| 方案         | 扩展性 | 维护成本 | 适合场景       |<br>| —————— | ——— | ———— | ——————— |<br>| 自建MySQL    | ★★★★   | 中       | 复杂业务       |<br>| 纯微信云开发 | ★★     | 低       | 轻量工具类应用 |<br>| <strong>混合云</strong>   | ★★★    | <strong>中高</strong> | <strong>中庸型项目</strong> |<br>2. 非核心功能（如图片上传）<strong>彻底云化</strong>，直接用云开发SDK。<br>3. <strong>建立原型验证机制</strong>：  </p><p>重要模块（如订单状态机）先写 <strong>伪代码流程图</strong> 与产品确认，避免返工。</p><blockquote><p><strong>总结</strong>：本周深刻体会架构选型需考量 <strong>业务生命周期</strong>（短期效率 vs 长期扩展）。未来将坚持 <strong>“设计-原型-开发”三步走</strong>，让技术真正服务业务增长。</p></blockquote><hr>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%BA%94%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E4%BA%94%E5%91%A8/"/>
    <published>2025-08-16T16:04:11.000Z</published>
    <summary>日期 核心工作 关键产出 周一 后台系统技术选型与架构设计 ✅ 选定 若依框架 搭建后台管理系统✅ 完成 功能模块划分 及技术文档输出 周二 用户管理模块开发 ✅ 实现用户信息 增删改查（CRUD） 全功能 周三 核心业务模块开发 ✅ 完成 订单管理 业务流程设计✅ 落地 土地管理 CRUD 核心逻辑 周四 技术方案优化与问题修复 ✅ 验证 微信云开发...</summary>
    <title>广州it工作第五周</title>
    <updated>2025-12-11T09:11:39.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>周一：</strong></p><ul><li>完成租地功能：设计租赁信息表，JWT鉴权后创建租赁记录。</li><li><em>注意点：</em> 补充了状态字段设计。</li></ul><p><strong>周二：</strong></p><ul><li>构建订单系统：创建订单主表及详情表，实现：<br>JWT用户订单查询</li><li>多状态分类（待支付&#x2F;待发货等）</li><li>PageHelper分页（&gt;10自动分页，加载页面缓存进度）</li></ul><p><strong>周三：</strong></p><ul><li>订单详情增强：调用土地接口展示租赁地块信息。</li><li>前端隐患：<code>this.orderInfo.items[0]</code> 强耦合数据绑定。</li></ul><p><strong>周四：</strong></p><ul><li>订单状态管理：实现增删改查及状态流转（如取消订单同步释放土地）。</li><li><em>优化：</em> 采用状态模式替代if-else链。</li></ul><p><strong>周五：</strong></p><ul><li>支付功能受阻：<br><strong>致命问题：</strong> 后端未配置HTTPS（微信支付强制要求）</li><li><strong>设计缺陷：</strong> 订单号长度不符支付接口规范（20位≠32位）</li><li><em>转向：</em> 启动手机号验证方案研究。</li></ul><p><strong>周六：</strong></p><ul><li>微信验证困局：<br>手机号快速验证失败（需企业认证）</li><li><code>getUserProfile</code>仅获取基础信息（头像&#x2F;昵称）</li><li>开放数据解密流程复杂且无进展</li></ul><hr><p><strong>核心卡点：</strong></p><ol><li><strong>支付环节：</strong> HTTPS缺失 + 订单号设计缺陷</li><li><strong>微信生态：</strong> 政策收紧导致手机号获取路径封死</li></ol><h3 id="一、独立完成-挑战-成长"><a href="#一、独立完成-挑战-成长" class="headerlink" title="一、独立完成 &amp; 挑战 &amp; 成长"></a><a href="#%E4%B8%80%E3%80%81%E7%8B%AC%E7%AB%8B%E5%AE%8C%E6%88%90-amp-%E6%8C%91%E6%88%98-amp-%E6%88%90%E9%95%BF"></a><strong>一、独立完成 &amp; 挑战 &amp; 成长</strong></h3><table><thead><tr><th><strong>事项</strong></th><th><strong>独立完成</strong></th><th><strong>最大挑战</strong></th><th><strong>克服方式</strong></th><th><strong>成长</strong></th></tr></thead><tbody><tr><td><strong>租地系统</strong></td><td>租赁表设计 + JWT用户绑定</td><td>状态字段缺失</td><td>快速补字段 + 关联订单状态</td><td>意识到<strong>数据扩展性</strong>的重要性</td></tr><tr><td><strong>订单中台</strong></td><td>双表创建 + 分页&#x2F;状态筛 + 状态机</td><td>订单号长度设计不足(20位)</td><td>重构为32位 UUID</td><td><strong>关键字段需预判业务需求</strong></td></tr><tr><td><strong>支付对接</strong></td><td>调用微信支付流程开发</td><td>1. 无HTTPS</td><td></td><td></td></tr><tr><td>2. 微信政策限制</td><td>转向备用方案（手机号验证）</td><td>第三方功能<strong>必须预研环境&#x2F;政策</strong></td><td></td><td></td></tr><tr><td><strong>微信集成</strong></td><td>实现<code>getUserProfile</code>基础授权</td><td>无法获取用户准确信息（政策封锁）</td><td>明确放弃，转为人工审核流程</td><td>学会<strong>在限制中寻找替代路径</strong></td></tr></tbody></table><hr><h3 id="二、本周工作思考"><a href="#二、本周工作思考" class="headerlink" title="二、本周工作思考"></a><a href="#%E4%BA%8C%E3%80%81%E6%9C%AC%E5%91%A8%E5%B7%A5%E4%BD%9C%E6%80%9D%E8%80%83"></a><strong>二、本周工作思考</strong></h3><ol><li><strong>做得好的</strong><br>基础功能闭环：租地→订单→状态流转全链路跑通</li><li>快速响应问题：发现订单号缺陷应该立即重构</li><li><strong>待改进的</strong><br><strong>致命疏忽</strong>：支付未提前验证HTTPS&#x2F;字段规则 → 导致整块功能返工</li><li><strong>过度乐观</strong>：低估微信政策限制（开发者权限）</li><li><strong>核心认知</strong><br><strong>“能开发” ≠ “能上线”</strong><br>第三方依赖的合规性（HTTPS&#x2F;政策）比代码更重要</li></ol><hr><h3 id="三、未来同样机会的做法"><a href="#三、未来同样机会的做法" class="headerlink" title="三、未来同样机会的做法"></a><a href="#%E4%B8%89%E3%80%81%E6%9C%AA%E6%9D%A5%E5%90%8C%E6%A0%B7%E6%9C%BA%E4%BC%9A%E7%9A%84%E5%81%9A%E6%B3%95"></a><strong>三、未来同样机会的做法</strong></h3><ol><li><strong>预研四象限（首日必做）</strong><br>1<br>2<br>3<br>4<br><code>[技术]      [政策]      [环境]       [兼容性]  │          │          │            │  ├─HTTPS?   ├─微信文档? ├─测试账号?   ├─字段长度?  └─SDK兼容  └─权限范围  └─域名备案    └─数据格式  </code></li><li><strong>设计两原则</strong></li></ol><p><strong>字段设计</strong>：订单号&#x2F;金额等支付相关字段，直接对齐微信要求（32位&#x2F;UUID）<br>3. <strong>解耦开发</strong>：支付模块用模拟运行，便于替换（例：HTTPS未就绪时模拟支付）<br>4. <strong>政策应对</strong>  </p><p>项目避免强依赖微信敏感接口（如手机号）</p><blockquote><p><strong>总结一句话</strong>：<br><strong>下次先花2小时跑通支付Demo+政策验证，再动手写业务代码。</strong><br>功能开发速度 ≠ 交付速度，预研省下的就是返工浪费的。</p></blockquote>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%9B%9B%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E5%B7%9Eit%E5%B7%A5%E4%BD%9C%E7%AC%AC%E5%9B%9B%E5%91%A8/"/>
    <published>2025-08-10T05:28:04.000Z</published>
    <summary>
      <![CDATA[周一： 完成租地功能：设计租赁信息表，JWT鉴权后创建租赁记录。 注意点： 补充了状态字段设计。 周二： 构建订单系统：创建订单主表及详情表，实现： JWT用户订单查询 多状态分类（待支付/待发货等） PageHelper分页（>10自动分页，加载页面缓存进度） 遗留问题： 订单号长度仅20位（需32位）。 周三： 订单详情增强：调用土地接口展示]]>
    </summary>
    <title>广州it工作第四周</title>
    <updated>2025-12-11T09:11:29.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>核心目标：</strong> 独立搭建农场小程序的订单系统（包括后台接口、前端页面和数据库）。</p><p><strong>本周主要进展：</strong></p><ol><li><strong>项目启动与基础搭建 (周一)：</strong></li></ol><p>用开发工具创建了小程序项目框架。<br>2. <strong>首页：</strong> 实现了图片热区点击跳转（用<code>绝对定位</code>精确定位点击区域，<code>uni.switchTab</code>跳转底部菜单页）。<br>3. <strong>公告栏：</strong> 暂时留空。<br>4. <strong>我的农场：</strong> 开始设计核心玩法（比如种植收获逻辑）。<br>5. <strong>个人中心：</strong> 画好了页面布局。<br>6. 图片上传到<code>图床</code>，减小小程序安装包体积。<br>7. <strong>界面优化与农场互动 (周二)：</strong></p><p><strong>首页：</strong> 用<code>媒体查询</code>让页面在不同尺寸手机上都好看（响应式布局）。<br>8. <strong>我的农场：</strong> 用<code>Grid网格布局</code>做了9块整齐的地块。点击地块能弹出操作图片（比如选择种子）。<br>9. <strong>个人中心：</strong> 本想做微信<code>一键登录</code>（获取手机号），但个人小程序权限不够。改用方案：用户授权获取微信<code>头像和昵称</code>绑定账号，登录成功后服务器返回一个<code>token</code>（身份令牌）存起来，代表用户已登录。<br>10. <strong>新增功能模块 (周三)：</strong></p><p><strong>首页：</strong> 加了“马克农场”入口，点击后跳转新页面（用<code>uni.navigateTo</code>页面跳转）。<br>11. <strong>个人中心：</strong> 增加了“设置”页面，可以修改个人信息。<br>12. <strong>核心登录功能实现 (周四)：</strong></p><p><strong>个人中心：</strong><br>实现了完整的微信登录流程：<br>小程序获取临时登录凭证<code>code</code>。<br>13. 把<code>code</code>发给我的后台服务器。<br>14. 后台用<code>code</code>向微信服务器换取用户的<code>唯一标识(openid)</code>等信息。<br>15. 后台查数据库：如果是新用户，就创建账号；老用户则读取信息。<br>16. 后台生成<code>token</code>，连同用户信息一起返回给小程序。<br>17. 小程序把<code>token</code>和用户信息存起来（<code>storage</code>），后续操作代表该用户。</p><p><strong>用户信息保护与更新 (周五)：</strong></p><ul><li>完善登录后的安全措施：采用<code>JWT令牌</code>进行<code>鉴权</code>（验证身份）。<br><strong>为什么选JWT？</strong> 主要因为它不需要<code>Cookie</code>，避免了<code>跨域(CORS)</code>问题，更方便不同服务器间协作。而且服务器不用存储用户登录状态（<code>无状态</code>），减轻负担。</li><li><strong>怎么用？</strong> 用户登录后拿到<code>JWT token</code>（就是周四的那个token）。当用户想修改头像昵称等需要登录的操作时，小程序在请求头里带上这个token（格式：<code>Authorization: Bearer </code>）。后台收到请求后，先<code>验证token是否有效且合法</code>，验证通过了才允许修改用户信息。</li></ul><p><strong>简单来说，这周：</strong> 搭好了小程序的基础架子，重点实现了用户<code>登录注册流程</code>（包括微信授权、后台验证、生成令牌JWT），完成了个人中心的主要功能（信息展示、设置、头像昵称修改），并开始为订单系统做跳转准备。技术上解决了图片优化、布局适配、登录授权、身份验证（JWT）等关键点。</p><p>以下是对本周工作的结构化复盘总结，结合实践与成长思考：</p><hr><h3 id="一、独立完成事项-挑战与成长"><a href="#一、独立完成事项-挑战与成长" class="headerlink" title="一、独立完成事项 &amp; 挑战与成长"></a><a href="#%E4%B8%80%E3%80%81%E7%8B%AC%E7%AB%8B%E5%AE%8C%E6%88%90%E4%BA%8B%E9%A1%B9-amp-%E6%8C%91%E6%88%98%E4%B8%8E%E6%88%90%E9%95%BF"></a>一、独立完成事项 &amp; 挑战与成长</h3><table><thead><tr><th><strong>完成内容</strong></th><th><strong>挑战</strong></th><th><strong>克服方式</strong></th><th><strong>带来的成长</strong></th></tr></thead><tbody><tr><td><strong>1. 用户系统全流程搭建</strong></td><td></td><td></td><td></td></tr></tbody></table><ul><li>微信登录+JWT鉴权  </li><li>头像&#x2F;昵称修改功能 | • 个人小程序无法直接获取手机号<br>• JWT无状态鉴权首次实战 | • 改用 <strong>Code→OpenID→Token</strong> 替代方案<br>• 研读JWT机制，设计 <strong>Bearer Token</strong> 请求头鉴权逻辑 | ✅ 掌握<strong>受限条件下的灵活架构能力</strong><br>✅ 理解<strong>无状态认证</strong>的设计优势与风险 |<br>| <strong>2. 农场交互核心模块</strong>  </li><li>Grid九宫格布局  </li><li>地块点击弹窗交互 | • 动态弹窗与地块操作状态联动<br>• 多端样式适配 | • 用 <strong>CSS变量+媒体查询</strong> 控制响应式<br>• <strong>事件委托</strong> 统一管理地块点击逻辑 | ✅ 强化 <strong>复杂交互前端设计能力</strong><br>✅ 提升 <strong>CSS3实战应用水平</strong> |<br>| <strong>3. 项目基建优化</strong>  </li><li>图床节省包体积  </li><li>路由传参统一管理 | • 图标库兼容性问题<br>• 路由跳转类型混乱 | • <strong>源码调试+强制样式覆盖</strong> 解决依赖冲突<br>• 封装 <strong>路由工具函数</strong> 统一处理?type&#x3D;参数 | ✅ 学会 <strong>第三方库问题排查技巧</strong><br>✅ 养成 <strong>提前封装工具类</strong> 的习惯 |</li></ul><hr><h3 id="二、本周工作思考"><a href="#二、本周工作思考" class="headerlink" title="二、本周工作思考"></a><a href="#%E4%BA%8C%E3%80%81%E6%9C%AC%E5%91%A8%E5%B7%A5%E4%BD%9C%E6%80%9D%E8%80%83"></a>二、本周工作思考</h3><p><strong>1. 技术决策的价值</strong>：</p><blockquote><p>选择JWT不仅解决了跨域问题，更让我意识到<strong>技术选型需服务业务场景</strong>——个人小程序无法用企业级登录方案时，用Token机制快速搭建安全认证体系是最优解。</p></blockquote><p><strong>2. 限制催生创新</strong>：</p><blockquote><p>微信API权限限制反而推动设计出更通用的 <strong>「Code+OpenID+DB」用户绑定流程</strong>，未来扩展手机号&#x2F;邮箱登录只需复用该流程。</p></blockquote><p><strong>3. 技术债预警</strong>：</p><blockquote><p>临时解决CSS兼容性的“hack手段”需在迭代中重构，<strong>开发效率与代码质量必须动态平衡</strong>。</p></blockquote><hr><h3 id="三、若重来我会如何做？"><a href="#三、若重来我会如何做？" class="headerlink" title="三、若重来我会如何做？"></a><a href="#%E4%B8%89%E3%80%81%E8%8B%A5%E9%87%8D%E6%9D%A5%E6%88%91%E4%BC%9A%E5%A6%82%E4%BD%95%E5%81%9A%EF%BC%9F"></a>三、若重来我会如何做？</h3><p><strong>1. 前置设计更彻底</strong>：</p><blockquote><p>用<strong>流程图</strong>预先规划登录&#x2F;鉴权全链路（避免周四返工）<br>订单系统数据库<strong>提前预留扩展字段</strong>（如<code>order_type</code>应对跳转传参）</p></blockquote><p><strong>2. 技术方案分层验证</strong>：</p><blockquote><p>关键模块（如JWT）先写<strong>技术原型Demo</strong>再集成<br>第三方库（uView）提前做<strong>兼容性测试矩阵</strong></p></blockquote><p><strong>3. 自动化提效</strong>：</p><blockquote><p>用<strong>CI&#x2F;CD工具</strong>自动压缩图片上传图床<br>编写<strong>路由配置生成脚本</strong>避免手写跳转参数  </p><p><strong>总结</strong>：未来需更注重<strong>前瞻性设计</strong>与<strong>可持续架构</strong>，让代码既能跑得快，更能跑得远。</p></blockquote>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%B8%89%E5%91%A8/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%B8%89%E5%91%A8/"/>
    <published>2025-08-01T16:26:28.000Z</published>
    <summary>核心目标： 独立搭建农场小程序的订单系统（包括后台接口、前端页面和数据库）。 本周主要进展： 项目启动与基础搭建 (周一)： 用开发工具创建了小程序项目框架。 首页： 实现了图片热区点击跳转（用绝对定位精确定位点击区域，uni.switchTab跳转底部菜单页）。 公告栏： 暂时留空。 我的农场： 开始设计核心玩法（比如种植收获逻辑）。 个人中心： 画...</summary>
    <title>广漂码农第三周</title>
    <updated>2025-12-11T09:11:57.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>核心任务：</strong> 独立完成车位项目订单系统后端接口、前端页面及数据库设计。</p><p><strong>本周开发纪实：</strong></p><ol><li><strong>周一：</strong> 复盘上周工作，为本周冲刺蓄力。</li><li><strong>周二：</strong> 承接新需求：<br><strong>记住手机号：</strong> 提升用户体验。</li><li><strong>自定义弹窗：</strong> 实现灵活交互。</li><li><strong>价格需求：</strong> 核心业务逻辑。</li><li><strong>技术选型：</strong> 确定使用 <code>HttpSession</code> 存储 <code>手机号:验证码</code> 键值对，作为临时认证方案。</li><li><strong>周三：</strong> 功能实现日<br>完成“记住手机号” ✅</li><li>集成验证码登录 ✅ (<strong>注意点：</strong> 接口参数类型需严格匹配，<code>Session ID</code> 不一致会导致校验失败 - <em>已解决</em>)</li><li>实现协议勾选及自定义弹窗 ✅</li><li><strong>兼容性问题：</strong> 确认微信浏览器不支持 <code>datalist</code> 元素。 (<em>已找到替代方案-采用div来自定义下拉框</em>✅)</li><li><strong>周四：</strong> 优化与设计<br><strong>验证码生命周期优化：</strong> 将清除逻辑从固定5分钟 (<code>setInterval</code>)，升级为 <strong>登录成功即销毁</strong> 或 <strong>5分钟到期销毁</strong>，更贴合实际场景。</li><li><strong>数据库设计：</strong> 新增 <code>订单表 (order)</code>。<br>关键设计：通过 <code>spot_id</code> 外键关联车位表。</li><li>决策说明：未直接复用车位表 <code>user_id</code> 字段 (因车位归属逻辑与订单用户逻辑存在差异)。</li><li><strong>周五：</strong> 数据库深化<br>完善 <code>订单表</code> 结构，清晰记录交易信息。</li><li>设计 <code>优惠规则表 (discount_rule)</code>，定义车位关联的折扣类型与规则。 (<em>终于给优惠上了“户口本”</em>)</li><li><strong>周六：</strong> 逻辑实现 &amp; 性能飞跃<br>完成订单金额计算引擎，支持匹配优惠规则。</li><li><strong>接口性能重大优化：</strong><br><strong>问题：</strong> 原有设计需两个接口拉取 <strong>全量用户车位数据</strong>，效率低下。</li><li><strong>方案：</strong> 重构为单一接口，精准查询 <strong>当前用户订单信息</strong>。</li><li><strong>成果：</strong> <strong>响应速度显著提升，数据库压力大幅降低。</strong> ( <em>成功给臃肿接口“瘦身”</em> )</li></ol><p><strong>本周总结与反思：</strong></p><ol><li><strong>主要成就与挑战：</strong></li></ol><p><strong>独立完成：</strong> 成功独立完成了车位及订单模块的后端接口开发、前端订单页面设计以及相关数据库设计。<br>2. <strong>关键挑战：</strong> 如何在后端安全、有效地存储和验证用户专属的短信验证码，避免多用户共用同一验证码的风险。<br>3. <strong>解决方案：</strong> 采用基于 <code>HttpSession</code> 的存储方案：<br>Key: 用户手机号<br>4. Value: 对应的验证码<br>5. 生命周期管理：用户成功登录后或 Session 超时（设置 5 分钟）自动销毁。<br>6. <strong>成长点：</strong> 深入理解了 <code>HttpSession</code> 机制在后端数据临时存储中的应用。<br>7. <strong>反思与改进点：</strong></p><p><strong>需求理解：</strong> 未来开发前，应更深入地与客户&#x2F;产品沟通需求细节，以便更好地支持后续扩展性开发。<br>8. <strong>数据库设计：</strong> 反思当前设计是否足够精细？例如 <code>user</code> 表可考虑增加 <code>user_type</code>、<code>created_at</code>、<code>last_login_at</code> 等字段增强功能性和可追溯性。<br>9. <strong>设计文档：</strong> 意识到个人设计文档的详细度有待提高，需加强文档规范。<br>10. <strong>未来优化方向：</strong></p><p><strong>沟通：</strong> 加强沟通，确保需求理解透彻，及时同步进展。<br>11. <strong>数据库：</strong><br>精细化核心表结构（如扩展 <code>user</code> 表字段）。<br>12. 建立更清晰的表关系。<br>13. <strong>后端架构：</strong><br>进行更清晰的分层设计（Controller &#x2F; Service &#x2F; Repository &#x2F; Entity）。<br>14. 将车位管理、用户收藏等模块进行逻辑拆分，提高可维护性。<br>15. <strong>前端：</strong><br>加强浏览器兼容性测试（如已发现的微信 <code>datalist</code> 问题）。<br>16. 持续进行界面加载速度优化。<br>17. <strong>目标：</strong> 通过以上改进，全面提升开发效率、代码质量和系统健壮性，促进个人技术能力的成长。</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%BA%8C%E5%91%A8%EF%BC%9A%E6%89%8B%E6%92%95%E9%AA%8C%E8%AF%81%E7%A0%81Session%EF%BC%8C%E7%BB%99%E8%AE%A2%E5%8D%95%E7%B3%BB%E7%BB%9F%E2%80%9C%E5%AE%89%E5%AE%B6%E8%90%BD%E6%88%B7%E2%80%9D/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%BA%8C%E5%91%A8%EF%BC%9A%E6%89%8B%E6%92%95%E9%AA%8C%E8%AF%81%E7%A0%81Session%EF%BC%8C%E7%BB%99%E8%AE%A2%E5%8D%95%E7%B3%BB%E7%BB%9F%E2%80%9C%E5%AE%89%E5%AE%B6%E8%90%BD%E6%88%B7%E2%80%9D/"/>
    <published>2025-07-26T17:20:11.000Z</published>
    <summary>核心任务： 独立完成车位项目订单系统后端接口、前端页面及数据库设计。 本周开发纪实： 周一： 复盘上周工作，为本周冲刺蓄力。 周二： 承接新需求： 记住手机号： 提升用户体验。 自定义弹窗： 实现灵活交互。 价格需求： 核心业务逻辑。 技术选型： 确定使用 HttpSession 存储 手机号:验证码 键值对，作为临时认证方案。 周三： 功能实现日 完...</summary>
    <title>广漂码农第二周：手撕验证码Session，给订单系统“安家落户”</title>
    <updated>2025-12-11T09:12:00.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="工作心得" scheme="https://zhengcookie.github.io/categories/%E5%B7%A5%E4%BD%9C%E5%BF%83%E5%BE%97/"/>
    <category term="工作" scheme="https://zhengcookie.github.io/tags/%E5%B7%A5%E4%BD%9C/"/>
    <content>
      <![CDATA[<p><strong>前言：新手村报到</strong><br>广漂第一个月，终于上岸！入职第一天，抱着对职场前辈的敬畏（以及怕露怯的紧张），做足准备踏入新战场。记录下这一周，主打一个真实！</p><p><strong>Day 1: HTML星辰大海，打包是个误会？</strong><br>产品经理的原型图甩过来，先设计好文档没问题了再开干！祭出神器 <code>Cursor</code> + <code>Claude-3-Connect</code>，AI 辅助下吭哧吭哧撸完一堆纯 HTML 页面。AI 老哥贴心提示：“亲，打包上传哦~”。我信了！一头扎进打包工具的坑里折腾半天，汗流浃背。结果？<strong>发现特么的纯 HTML 直接扔服务器就能跑！</strong> 打包？打包了个寂寞！今日教训：AI 的话，也得结合上下文判断啊… (╯‵□′)╯︵┻━┻</p><p><strong>Day 2: SpringBoot 从零开始，CSDN 付费墙刺客！</strong><br>今日任务：搞后端 API 录入。第一次正经从零搭 <code>SpringBoot</code> 项目。IDEA 社区版 2023 有点坑，创建方式藏得深。CSDN 搜教程，好家伙，第一步就让装个插件，装完重启直接弹登录+<strong>付费订阅</strong>！真·知识付费刺客！果断弃坑。翻到良心文章指路：<a href="https://start.spring.io/">https://start.spring.io</a>，官方生成器真香！唯一小插曲：我 JDK 11 的“老环境”，伺候不了 SpringBoot 3 这位“新贵”，手动把版本和相关依赖<strong>降级到 2.x</strong>，世界终于清净。结论：CSDN 水文害人，官方文档&#x2F;工具永流传！</p><p><strong>Day 3: 宝塔端口玄学 &amp; “数字小孩”落户口！</strong><br>任务：把后端 API 部署上云服务器（宝塔面板）。一顿操作猛如虎：端口放行√，配置√。测试？<strong>死活连不上！</strong> CSDN 又跳出来“指点”：搞个随机域名数据库？一看还得付费固定域名？我信你个鬼！焦头烂额之际，<strong>猛然想起腾讯云还有个安全组！</strong> 火速添上端口规则，瞬间畅通！啊，这熟悉的安全感… (长舒一口气)</p><ul><li><strong>技术小悟：</strong> 跨域问题，不一定非搬 Nginx 大神。后端配个全局 <code>CORS</code>，指定好前端地址，也能愉快玩耍！省事！</li><li><strong>短信验证码插曲：</strong> 折腾半天接好了，但备案没过的号能发成功吗？心里有点虚，先当它行吧！</li></ul><p><strong>🌟 今日高光时刻 🌟</strong><br>今年我们团队的心血——<strong>“医疗健康问诊系统”</strong>，<strong>喜提国家版权局颁发的《计算机软件著作权登记证书》！</strong> 正式拥有了“<strong>数字小孩</strong>”的户口本！🎉</p><blockquote><p>感谢并肩作战的伙伴，<br>感谢每个改bug到天亮的自己。<br>——【医疗健康问诊系统】软著𝐆𝐞𝐭，未来可期！</p></blockquote><p><strong>Day 4: 切图仔の挣扎 vs 后端の从容（伪）</strong><br>实现一个“点击录入所有数据”的功能。纯 HTML + Vue 的组合，对我这个后端半吊子来说，操作 DOM 像在绣花… <strong>切图仔，属实不易！</strong> 顺带搞了车位收藏功能，数据库表设计修修补补好几回，勉强上线。<strong>结论：前端水太深，后端（的CRUD）才是俺的舒适区（暂时）！</strong></p><p><strong>Day 5: 数据库改改改，AI又救我狗命！</strong><br>搞车位收藏和抢购的多表查询。<strong>是的，我又双叒改数据库了！</strong> 最初设计图样图森破：想着一个车位记录，既能标记收藏又能记录谁买了，还绑 UserID。结果，“车位必须空闲”的规则和用户操作直接打架！卡壳半天，<strong>求助 AI 老哥</strong>，一语点醒：这设计有坑！火速重构，把状态、归属理清楚，功能终于跑通。<strong>教训：数据库设计，脑子得提前多绕几圈，少走弯路！</strong></p><p><strong>周记结尾：</strong><br>第一周，在疯狂踩坑、暴躁搜索、偶尔顿悟和一次巨大惊喜（软著！）中飞逝。从打包误会到安全组玄学，从被 CSDN 付费墙背刺到 AI 救场，从切图痛苦到改库狂魔… <strong>真实又酸爽！</strong> 见识了工具的便利与坑爹，体会了团队的温暖（和一起加班）。代码世界的大门刚推开一条缝，路还长，坑还多，但看着“数字小孩”上了户口，值了！下周，继续升级打怪！</p><hr>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%9A%E8%B8%A9%E5%9D%91%EF%BC%8C%E6%94%B9%E5%BA%93%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%96%9C%E6%8F%90-%E6%95%B0%E5%AD%97%E5%B0%8F%E5%AD%A9%E6%88%B7%E5%8F%A3/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%B9%BF%E6%BC%82%E7%A0%81%E5%86%9C%E7%AC%AC%E4%B8%80%E5%91%A8%EF%BC%9A%E8%B8%A9%E5%9D%91%EF%BC%8C%E6%94%B9%E5%BA%93%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%96%9C%E6%8F%90-%E6%95%B0%E5%AD%97%E5%B0%8F%E5%AD%A9%E6%88%B7%E5%8F%A3/"/>
    <published>2025-07-18T16:24:08.000Z</published>
    <summary>前言：新手村报到广漂第一个月，终于上岸！入职第一天，抱着对职场前辈的敬畏（以及怕露怯的紧张），做足准备踏入新战场。记录下这一周，主打一个真实！ Day 1: HTML星辰大海，打包是个误会？产品经理的原型图甩过来，先设计好文档没问题了再开干！祭出神器 Cursor + Claude-3-Connect，AI 辅助下吭哧吭哧撸完一堆纯 HTML 页面。A...</summary>
    <title>广漂码农第一周</title>
    <updated>2025-12-11T09:11:52.000Z</updated>
  </entry>
  <entry>
    <author>
      <name>zhengcookie</name>
    </author>
    <category term="区块链" scheme="https://zhengcookie.github.io/categories/%E5%8C%BA%E5%9D%97%E9%93%BE/"/>
    <category term="区块链赛题智能合约" scheme="https://zhengcookie.github.io/tags/%E5%8C%BA%E5%9D%97%E9%93%BE%E8%B5%9B%E9%A2%98%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6/"/>
    <content>
      <![CDATA[<p>源码</p><p><a href="https://zhengcookie.github.io/file/%E5%8C%BA%E5%9D%97%E9%93%BE/%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6/medical/%E5%8C%BB%E7%96%97/Main.sol">Main.sol</a></p><p>以下是智能合约代码的逐段解析，按功能模块分类说明：</p><hr><h3 id="1-患者信息管理"><a href="#1-患者信息管理" class="headerlink" title="1. 患者信息管理"></a><a href="#1-%E6%82%A3%E8%80%85%E4%BF%A1%E6%81%AF%E7%AE%A1%E7%90%86"></a><strong>1. 患者信息管理</strong></h3><h4 id="结构体定义"><a href="#结构体定义" class="headerlink" title="结构体定义"></a><a href="#%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89"></a><strong>结构体定义</strong></h4><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><code class="hljs plaintext">struct Sick &#123;<br>    address accountAddress; // 患者钱包地址<br>    string name;            // 姓名<br>    string sex;             // 性别<br>    uint256 age;            // 年龄<br>    uint256 id;             // 身份证号(主键)<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="数据存储"><a href="#数据存储" class="headerlink" title="数据存储"></a><a href="#%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8"></a><strong>数据存储</strong></h4><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><code class="hljs plaintext">mapping(uint256 =&gt; Sick) public sicks;  // 身份证号→患者信息的映射<br>uint256[] public sickIds;               // 所有患者身份证号列表<br></code></pre></td></tr></table></figure><h4 id="核心功能"><a href="#核心功能" class="headerlink" title="核心功能"></a><a href="#%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD"></a><strong>核心功能</strong></h4><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></pre></td><td class="code"><pre><code class="hljs plaintext">// 创建患者档案 (需校验参数有效性)<br>function createSick(...) public &#123;<br>    // 参数校验...<br>    sicks[identityNumber] = Sick(...);  // 存储信息<br>    sickIds.push(identityNumber);       // 记录ID<br>    emit SickCreated(...);              // 触发事件<br>&#125;<br><br>// 按身份证查询患者<br>function getSickByIdentityNumber(...) public view returns (...) &#123;<br>    require(sick.accountAddress != address(0)); // 校验存在性<br>    return (sick.accountAddress, ...);<br>&#125;<br><br>// 按钱包地址查询患者<br>function getSickByAccountAddress(...) public view returns (...) &#123;<br>    uint256 sickID = findSickIDByAccountAddress(accountAddr); // 内部遍历查找<br>    return (sick.name, ...);<br>&#125;<br><br>// 辅助函数：地址→ID映射<br>function findSickIDByAccountAddress(...) internal view returns (...) &#123;<br>    for (uint256 i = 0; i &lt; sickIds.length; i++) &#123;<br>        if (sicks[sickID].accountAddress == accountAddr) return sickID;<br>    &#125;<br>    return 0;<br>&#125;<br><br>// 检查患者是否存在<br>function isSickExist(uint256 sickID) public view returns (bool) &#123;<br>    return sicks[sickID].accountAddress != address(0);<br>&#125;<br><br>// 获取所有患者ID列表<br>function getSicksList() public view returns (uint256[] memory) &#123;<br>    return sickIds;<br>&#125;<br></code></pre></td></tr></table></figure><hr><h3 id="2-预约挂号系统"><a href="#2-预约挂号系统" class="headerlink" title="2. 预约挂号系统"></a><a href="#2-%E9%A2%84%E7%BA%A6%E6%8C%82%E5%8F%B7%E7%B3%BB%E7%BB%9F"></a><strong>2. 预约挂号系统</strong></h3><h4 id="结构体定义-1"><a href="#结构体定义-1" class="headerlink" title="结构体定义"></a><a href="#%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89-1"></a><strong>结构体定义</strong></h4><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><code class="hljs plaintext">struct Appointment &#123;<br>    string hospitalName; // 医院名称<br>    string department;   // 科室名称<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="数据存储-1"><a href="#数据存储-1" class="headerlink" title="数据存储"></a><a href="#%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8-1"></a><strong>数据存储</strong></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mapping(uint256 =&gt; Appointment) public sickAppointment; // 患者ID→预约信息<br></code></pre></td></tr></table></figure><h4 id="核心功能-1"><a href="#核心功能-1" class="headerlink" title="核心功能"></a><a href="#%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD-1"></a><strong>核心功能</strong></h4><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></pre></td><td class="code"><pre><code class="hljs plaintext">// 创建预约<br>function createAppointment(...) public &#123;<br>    require(isSickExist(sickID));          // 患者必须存在<br>    sickAppointment[sickID] = Appointment(...); // 存储预约<br>    emit AppointmentCreated(...);           // 触发事件<br>&#125;<br><br>// 查询预约<br>function getSickAppointment(...) public view returns (...) &#123;<br>    require(bytes(appointment.hospitalName).length &gt; 0); // 校验存在性<br>    return (appointment.hospitalName, ...);<br>&#125;<br><br>// 删除预约<br>function deleteSickAppointment(uint256 sickID) public &#123;<br>    delete sickAppointment[sickID];  // 清除预约记录<br>&#125;<br></code></pre></td></tr></table></figure><hr><h3 id="3-电子病历管理"><a href="#3-电子病历管理" class="headerlink" title="3. 电子病历管理"></a><a href="#3-%E7%94%B5%E5%AD%90%E7%97%85%E5%8E%86%E7%AE%A1%E7%90%86"></a><strong>3. 电子病历管理</strong></h3><h4 id="结构体定义-2"><a href="#结构体定义-2" class="headerlink" title="结构体定义"></a><a href="#%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89-2"></a><strong>结构体定义</strong></h4><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></pre></td><td class="code"><pre><code class="hljs plaintext">struct MedicalRecord &#123;<br>    uint256 sickID;               // 患者ID<br>    string hospitalName;          // 医院<br>    string department;            // 科室<br>    string doctorName;            // 医生姓名<br>    string registrationInfo;      // 挂号信息<br>    string pastMedicalHistory;    // 既往病史<br>    string currentMedicalHistory; // 现病史<br>    string isFilled;              // 是否完成(&quot;Yes&quot;/&quot;No&quot;)<br>&#125;<br></code></pre></td></tr></table></figure><h4 id="数据存储-2"><a href="#数据存储-2" class="headerlink" title="数据存储"></a><a href="#%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8-2"></a><strong>数据存储</strong></h4><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs plaintext">mapping(uint256 =&gt; MedicalRecord) public sickMedicalRecords; // 患者ID→病历<br></code></pre></td></tr></table></figure><h4 id="核心功能-2"><a href="#核心功能-2" class="headerlink" title="核心功能"></a><a href="#%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD-2"></a><strong>核心功能</strong></h4><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></pre></td><td class="code"><pre><code class="hljs plaintext">// 创建空白病历<br>function createMedicalRecord(...) public &#123;<br>    sickMedicalRecords[sickID] = MedicalRecord(...);<br>    emit MedicalRecordCreated(...);<br>&#125;<br><br>// 授权医生访问病历<br>function authorizeDoctor(...) public &#123;<br>    if (病历不存在) createMedicalRecord(...); // 自动创建空病历<br>    sickMedicalRecords[sickID].doctorName = doctorName; // 设置医生<br>&#125;<br><br>// 更新病历内容<br>function updateMedicalRecord(...) public &#123;<br>    medicalRecord.hospitalName = hospitalName;<br>    medicalRecord.pastMedicalHistory = pastMedicalHistory; // 更新病史等<br>    emit MedicalRecordUpdated(...);<br>&#125;<br><br>// 查询完整病历<br>function getMedicalRecordByIdentityNumber(...) public view returns (...) &#123;<br>    return (medicalRecord.hospitalName, ...); // 返回所有病历字段<br>&#125;<br><br>// 查询特定科室的既往病史<br>function getPastMedicalHistory(...) public view returns (...) &#123;<br>    require(keccak256(科室)==keccak256(目标科室)); // 严格科室匹配<br>    return medicalRecord.pastMedicalHistory;<br>&#125;<br><br>// 标记病历完成状态<br>function endMedicalConsultation(...) public &#123;<br>    medicalRecord.isFilled = mrtype; // 设置&quot;Yes&quot;/&quot;No&quot;<br>&#125;<br><br>// 检查病历是否完成<br>function isMedicalRecordFilled(...) public view returns (bool) &#123;<br>    return keccak256(medicalRecord.isFilled) == keccak256(&quot;Yes&quot;);<br>&#125;<br></code></pre></td></tr></table></figure><p>该合约完整实现了患者档案管理、挂号预约、电子病历三大核心功能，构建了医疗数据上链的基础框架。</p>]]>
    </content>
    <id>https://zhengcookie.github.io/zhengcookie/%E5%8C%BA%E5%9D%97%E9%93%BE%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E6%95%99%E7%A8%8B-%E5%8C%BB%E7%96%97/</id>
    <link href="https://zhengcookie.github.io/zhengcookie/%E5%8C%BA%E5%9D%97%E9%93%BE%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E6%95%99%E7%A8%8B-%E5%8C%BB%E7%96%97/"/>
    <published>2025-07-12T13:31:15.000Z</published>
    <summary>源码 Main.sol 以下是智能合约代码的逐段解析，按功能模块分类说明： 1. 患者信息管理结构体定义1234567struct Sick { address accountAddress; // 患者钱包地址 string name; // 姓名 string sex; // 性别 uint256 age;</summary>
    <title>区块链智能合约教程-医疗</title>
    <updated>2025-12-22T19:34:03.000Z</updated>
  </entry>
</feed>
