<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Miya Liu - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Miya Liu - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 13 Jun 2026 19:46:40 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/author/miyaliu/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ 使用 Python 和多进程构建简历筛选系统 ]]>
                </title>
                <description>
                    <![CDATA[ 招聘合适的人选，往往从一项耗时的工作开始：筛选简历。如果你发布过职位招聘，一定体会过收件箱里有数百份申请，而你得花数小时手动审阅每份简历的烦恼。 本文将带你用纯 Python 搭建一个简历筛选系统，重点讲解核心编程概念和多进程的运用。你会创建一个自定义系统，通过将非结构化的简历文档转化为排名榜单，实现评估流程的自动化。 阅读完本指南后，你将能够：  * 解析文档：使用 Python 从 PDF 和 DOCX 简历中提取文本  * 提取信息：从简历内容中识别技能与关键词  * 设计评分算法：用加权逻辑客观地为候选人排序  * 构建 Web 界面：使用 Streamlit 完成  * 部署应用：在 Streamlit Cloud 上部署应用，供公众访问 按照本教程操作，你将构建一个能在几秒内处理数百份简历的工具。 源代码见 GitHub 仓库 [https://github.com/abdultalha0862/Resume_Parser_Project] 目录  * 前置要求  * 项目概览  * 系统如何工作  * ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/python-resume-screening-system/</link>
                <guid isPermaLink="false">69904195be64e2045fddd24a</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Sat, 14 Feb 2026 10:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2026/02/----_20260214181319_13_235.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/python-resume-screening-system/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Build a Résumé Screening System Using Python and Multiprocessing</a>
      </p><!--kg-card-begin: markdown--><p>招聘合适的人选，往往从一项耗时的工作开始：筛选简历。如果你发布过职位招聘，一定体会过收件箱里有数百份申请，而你得花数小时手动审阅每份简历的烦恼。</p>
<p>本文将带你用纯 Python 搭建一个简历筛选系统，重点讲解核心编程概念和多进程的运用。你会创建一个自定义系统，通过将非结构化的简历文档转化为排名榜单，实现评估流程的自动化。</p>
<p>阅读完本指南后，你将能够：</p>
<ul>
<li>解析文档：使用 Python 从 PDF 和 DOCX 简历中提取文本</li>
<li>提取信息：从简历内容中识别技能与关键词</li>
<li>设计评分算法：用加权逻辑客观地为候选人排序</li>
<li>构建 Web 界面：使用 Streamlit 完成</li>
<li>部署应用：在 Streamlit Cloud 上部署应用，供公众访问</li>
</ul>
<p>按照本教程操作，你将构建一个能在几秒内处理数百份简历的工具。</p>
<p>源代码见 <a href="https://github.com/abdultalha0862/Resume_Parser_Project">GitHub 仓库</a></p>
<h2 id="">目录</h2>
<ul>
<li>前置要求</li>
<li>项目概览</li>
<li>系统如何工作</li>
<li>系统架构</li>
<li>项目结构</li>
<li>步骤 1：搭建项目</li>
<li>步骤 2：构建简历解析器</li>
<li>步骤 3：构建关键词提取器</li>
<li>步骤 4：实现评分引擎</li>
<li>步骤 5：构建 Web 界面</li>
<li>步骤 6：测试系统</li>
<li>步骤 7：部署应用</li>
<li>总结</li>
</ul>
<h2 id="">前置要求</h2>
<p>要学习本教程，你需要具备：</p>
<ul>
<li>Python 基础知识（函数、循环、字典）</li>
<li>已安装 Python 3.8 或更高版本</li>
<li>会用 <code>pip</code> 安装包</li>
<li>代码编辑器（如 VS Code、PyCharm 或任意你喜欢的编辑器）</li>
</ul>
<h2 id="">项目概览</h2>
<p>本指南将开发一个系统：输入一个简历文件夹和一份职位描述（JD），系统会处理每份简历、提取相关信息，并根据候选人与职位要求的匹配程度计算得分。</p>
<h2 id="">系统如何工作</h2>
<p>项目包含四个核心组件：</p>
<ul>
<li><strong>简历解析器</strong>：读取 PDF 和 DOCX 文件并提取文本</li>
<li><strong>职位描述解析器</strong>：分析职位描述以识别所需技能</li>
<li><strong>关键词提取器</strong>：将简历内容与技能分类体系进行匹配</li>
<li><strong>评分引擎</strong>：使用加权算法对候选人排序</li>
</ul>
<h3 id="">评分公式</h3>
<p>使用的评分公式如下：</p>
<pre><code>总分 =
（必备技能 × 50%）+
（优先技能 × 25%）+
（经验 × 15%）+
（关键词 × 10%）
</code></pre>
<p>这样设计可以确保核心技能比次要关键词权重更高。</p>
<h3 id="">这种方法如何有助于减少偏见</h3>
<p>本系统基于预定义标准评估简历，而不是主观判断。每份简历都根据同一套必备技能、优先技能、经验指标和关键词进行打分。</p>
<p>由于所有候选人都使用同一套加权公式评估，写作风格、排版或个人偏好等主观因素不会影响排名。评分逻辑只关注简历与职位要求的匹配程度。</p>
<p>通过将评估过程标准化，系统促进了更一致、更客观的筛选，有助于在简历初筛阶段减少偏见。</p>
<h2 id="">系统架构</h2>
<pre><code>输入                    处理                       输出
─────                   ──────────                  ─────

简历 ──► 简历解析器 ──► 关键词提取器 ──┐
(PDF/DOCX)                             │
                                        ├──► 评分引擎 ──► 排名结果
职位描述 ──► 职位描述解析器 ────────────┘
(TXT/PDF)
</code></pre>
<p>系统遵循简单的“输入—处理—输出”流程。</p>
<p>简历和职位描述作为输入。简历解析器从每份简历中提取文本，职位描述解析器从职位描述中识别必备技能和优先技能。</p>
<p>提取出的简历文本随后传给关键词提取器，该模块根据预定义的技能分类体系匹配技能和关键词。</p>
<p>最后，评分引擎应用加权公式为每位候选人计算得分，并输出一份按分数排序的简历列表。</p>
<h2 id="">项目结构</h2>
<pre><code>resume_screening_system/
├── app.py                    # Streamlit Web 界面
├── main.py                   # 命令行界面
├── parsers/
│   ├── resume_parser.py      # PDF/DOCX 文本提取
│   └── jd_parser.py          # 职位描述解析
├── extractors/
│   └── keyword_extractor.py  # 技能与经验提取
├── matcher/
│   └── scorer.py             # 评分算法
├── data/
│   ├── config.json           # 评分权重配置
│   └── skills_taxonomy.json  # 技能数据库
└── requirements.txt          # 依赖
</code></pre>
<p>项目按清晰的模块化目录组织。解析逻辑、关键词提取和评分分别放在各自文件夹中，配置文件与数据单独存放，便于浏览、维护和扩展。</p>
<h2 id="1">步骤 1：搭建项目</h2>
<p>创建目录结构并设置虚拟环境：</p>
<pre><code class="language-bash">mkdir resume_screening_system
cd resume_screening_system
mkdir parsers extractors matcher data input output
python -m venv venv
</code></pre>
<p>然后激活虚拟环境：</p>
<pre><code class="language-bash"># Windows
source venv/Scripts/activate

# macOS / Linux
source venv/bin/activate
</code></pre>
<p>安装所需依赖：</p>
<pre><code class="language-bash">pip install PyPDF2 python-docx streamlit pandas
</code></pre>
<h2 id="2">步骤 2：构建简历解析器</h2>
<p>简历解析器针对不同文件格式使用不同的提取方法。</p>
<p>对于 PDF，解析器逐页打开文档，用 PDF 阅读器从每页提取文本，再合并成单个字符串供后续处理。</p>
<p>对于 DOCX，解析器读取文档中的每个段落，将段落文本拼接成一块。这样无论简历格式如何，都能得到一致的文本输出。</p>
<p>将简历统一转为纯文本后，关键词提取和评分等组件就能高效工作。</p>
<p><strong>文件：</strong> <code>parsers/resume_parser.py</code></p>
<pre><code class="language-python">def _extract_pdf(self, file_path: Path) -&gt; str:
    text = ""
    with open(file_path, "rb") as file:
        pdf_reader = PyPDF2.PdfReader(file)
        for page in pdf_reader.pages:
            page_text = page.extract_text()
            if page_text:
                text += page_text + "\n"
    return text.strip()

def _extract_docx(self, file_path: Path) -&gt; str:
    from docx import Document
    doc = Document(file_path)
    return "\n".join(
        para.text for para in doc.paragraphs
    ).strip()
</code></pre>
<h2 id="3">步骤 3：构建关键词提取器</h2>
<p>本项目使用 <a href="https://www.kaggle.com/datasets/snehaanbhawal/resume-dataset">Kaggle</a> 上的简历数据集，确保逻辑在真实职业数据上可用。关键词提取器通过扫描简历文本来识别技能。</p>
<p>简历文本先转为小写，以便不区分大小写地匹配。预定义的技能分类体系存储每个技能及其可能变体，提取器用这些变体与简历文本比对。</p>
<p>匹配时使用词边界，避免部分匹配（例如在 “JavaScript” 里匹配到 “Java”）。匹配到的技能存入集合以避免重复。</p>
<p>这种方式能在所有简历上实现一致、可控的技能识别。</p>
<p><strong>文件：</strong> <code>extractors/keyword_extractor.py</code></p>
<pre><code class="language-python">def extract_skills(self, text: str) -&gt; Set[str]:
    text_lower = text.lower()
    found_skills = set()

    for category, skills_dict in self.skills_taxonomy.items():
        for skill_name, variations in skills_dict.items():
            for variation in variations:
                # 防止 "Java" 匹配到 "JavaScript"
                pattern = r"\b" + re.escape(variation) + r"\b"
                if re.search(pattern, text_lower):
                    found_skills.add(skill_name)
                    break

    return found_skills
</code></pre>
<h2 id="4">步骤 4：实现评分引擎</h2>
<p>为得到客观排名，系统使用加权评分公式。</p>
<table>
<thead>
<tr>
<th>组件</th>
<th>权重</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>必备技能</td>
<td>50%</td>
<td>核心技术需求</td>
</tr>
<tr>
<td>优先技能</td>
<td>25%</td>
<td>差异化竞争力</td>
</tr>
<tr>
<td>经验</td>
<td>15%</td>
<td>专业深度</td>
</tr>
<tr>
<td>关键词</td>
<td>10%</td>
<td>领域熟悉度</td>
</tr>
</tbody>
</table>
<pre><code>总分 =
(S_req × 0.50) +
(S_pref × 0.25) +
(E_exp × 0.15) +
(K_key × 0.10)
</code></pre>
<p>评分引擎用上述权重为每份简历计算最终得分。</p>
<p>它统计简历中出现的必备技能、优先技能、经验指标和关键词数量，每个数量乘以其对应权重（必备技能权重最高），加权值相加得到单一分数，再按该分数对简历排序，生成候选人排名列表。</p>
<h2 id="5web">步骤 5：构建 Web 界面</h2>
<p>Streamlit 为简历筛选系统提供了简单的 Web 界面。</p>
<p>文本区域用于输入职位描述，文件上传器用于上传多份简历。点击按钮后，Streamlit 触发后端逻辑解析简历、提取数据并计算得分，结果在浏览器中展示，用户无需使用命令行即可完成筛选。</p>
<p><strong>文件：</strong> <code>app.py</code></p>
<pre><code class="language-python">import streamlit as st

jd_text = st.text_area(
    "在此粘贴职位描述：",
    height=300
)

uploaded_files = st.file_uploader(
    "上传简历文件：",
    type=["pdf", "docx", "txt"],
    accept_multiple_files=True
)

if st.button("筛选简历", type="primary"):
    st.success("正在处理简历...")
</code></pre>
<p>运行应用：</p>
<pre><code class="language-bash">streamlit run app.py
</code></pre>
<p>应用将运行在 <a href="http://localhost:8500">http://localhost:8500</a>。</p>
<h2 id="6">步骤 6：测试系统</h2>
<h3 id="">示例职位描述输入</h3>
<p>下面是一份可用于测试的示例职位描述：</p>
<pre><code>我们正在寻找一名具有扎实后端开发经验的高级 Python 开发工程师。

必备技能：
- Python
- Django
- REST API
- SQL

优先技能：
- PostgreSQL
- Docker
- AWS

经验要求：
- 3 年以上 Python 专业开发经验
- 有构建 Web 应用的经验
</code></pre>
<p>该输入帮助系统识别必备技能、优先技能和经验关键词，供评分引擎对简历排序。</p>
<pre><code class="language-bash">python main.py
</code></pre>
<h3 id="">示例输出</h3>
<pre><code>============================================================
筛选结果
============================================================
第 1 名：Alice Johnson | 得分：85.42/100 | 匹配：python、django、postgresql
第 2 名：Carol Davis   | 得分：72.50/100 | 匹配：python、django
</code></pre>
<h2 id="7">步骤 7：部署应用</h2>
<p>若要让系统对外可访问：</p>
<ol>
<li>将代码推送到 GitHub</li>
<li>打开 share.streamlit.io</li>
<li>选择你的 <code>app.py</code> 文件</li>
<li>部署应用</li>
</ol>
<p>应用将发布在：</p>
<pre><code>https://your-app-name.streamlit.app
</code></pre>
<h2 id="">总结</h2>
<p>在本教程中，你使用 Python 从零搭建了一个完整的简历筛选系统。通过结合文本处理、结构化评分和自动化，该项目展示了如何将手动简历筛选转变为高效、客观的流程。</p>
<p>该系统有助于减少偏见、节省时间，并更一致地评估候选人。Happy coding!</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何成为 AI 辅助编程专家 - 开发者手册 ]]>
                </title>
                <description>
                    <![CDATA[ 在过去的七年里，我一直负责 freeCodeCamp 的基础设施。现在我确信，经验丰富的开发者可以在保持代码质量的同时提升 3-4 倍的编码速度。这就是 AI 辅助开发能够提供的优势。简单来说，使用像 GitHub Copilot 这样的 AI 工具作为你的编码伙伴可以提高效率。它们可以建议代码、帮助你调试以及加快处理重复性任务。 为什么这很重要 传统编码时，你需要自己编写每一行代码、查找文档、弄清语法。有了 AI，你可以：  * 专注于解决问题，而不是记住语法          * 通过实时看到优秀的代码示例更快地学习          * 快速构建项目而不牺牲质量         对于有经验的开发者来说，在 AI ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-become-an-expert-in-ai-assisted-coding-a-handbook-for-developers/</link>
                <guid isPermaLink="false">6953dfe138384c0457be01cb</guid>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Fri, 09 Jan 2026 11:16:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2026/01/----_20260110202949_190_113.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/how-to-become-an-expert-in-ai-assisted-coding-a-handbook-for-developers/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Become an Expert in AI-Assisted Coding – A Handbook for Developers</a>
      </p><!--kg-card-begin: markdown--><p>在过去的七年里，我一直负责 freeCodeCamp 的基础设施。现在我确信，经验丰富的开发者可以在保持代码质量的同时提升 3-4 倍的编码速度。这就是 AI 辅助开发能够提供的优势。简单来说，使用像 GitHub Copilot 这样的 AI 工具作为你的编码伙伴可以提高效率。它们可以建议代码、帮助你调试以及加快处理重复性任务。</p>
<h3 id="">为什么这很重要</h3>
<p>传统编码时，你需要自己编写每一行代码、查找文档、弄清语法。有了 AI，你可以：</p>
<ul>
<li>
<p>专注于解决问题，而不是记住语法</p>
</li>
<li>
<p>通过实时看到优秀的代码示例更快地学习</p>
</li>
<li>
<p>快速构建项目而不牺牲质量</p>
</li>
</ul>
<p>对于有经验的开发者来说，在 AI 帮助下可以更快地完成任务。但关键是：<strong>你需要了解如何有效使用这些工具</strong>。你也需要有编程背景来做到这一点。</p>
<p>感兴趣吗？让我们深入了解这些已经风靡全球的 AI 编码工具。</p>
<h2 id="">目录</h2>
<ul>
<li>
<p><a href="#essential-ai-terminology">基础 AI 术语</a></p>
</li>
<li>
<p><a href="#when-to-use-ai-vs-when-to-code-yourself">何时使用 AI 以及何时自己编码</a></p>
</li>
<li>
<p><a href="#prerequisites">前提条件</a></p>
</li>
<li>
<p><a href="#your-complete-learning-journey">你的完整学习旅程</a></p>
</li>
<li>
<p><a href="#how-to-generate-your-first-ai-assisted-code">如何生成你的第一个 AI 辅助代码（快速入门）</a></p>
</li>
<li>
<p><a href="#stage-1">阶段 1：基础 – 开始 AI 编码</a></p>
</li>
<li>
<p><a href="#stage-2">阶段 2：高级 GitHub Copilot 功能</a></p>
</li>
<li>
<p><a href="#stage-3">阶段 3：基于 CLI 的 AI 代理（Claude Code &amp; Gemini）</a></p>
</li>
<li>
<p><a href="#stage-4">阶段 4：掌握 – 结合工具和高级工作流程</a></p>
</li>
<li>
<p><a href="#common-ai-issues">常见 AI 问题</a></p>
</li>
<li>
<p><a href="#whats-next-after-completing-all-stages">完成所有阶段后接下来做什么？</a></p>
</li>
<li>
<p><a href="#conclusion">结语</a></p>
</li>
</ul>
<h2 id="essential-ai-terminology">基础 AI 术语</h2>
<p>在开始之前，确保你了解以下关键术语：</p>
<ul>
<li>
<p><strong>Tokens（令牌）：</strong> 把令牌想象成“词片”——AI 阅读你的代码和文本的方式。每个字符、单词或符号都会使用令牌。免费版本会限制你可以使用的令牌数量。</p>
</li>
<li>
<p><strong>Context Window（上下文窗口）：</strong> AI 能一次性“记住”多少代码/对话。就像短期记忆，更大的窗口意味着对项目的更好理解。</p>
</li>
<li>
<p><strong>Hallucinations（幻觉）：</strong> AI 自信地建议错误信息——例如，捏造不存在的函数。务必验证 AI 的建议！</p>
</li>
<li>
<p><strong>Prompt（提示）：</strong> 你给 AI 的指令——评论、问题或请求，用以指导其生成的代码。</p>
</li>
</ul>
<h2 id="when-to-use-ai-vs-when-to-code-yourself">何时使用 AI 以及何时自己编码</h2>
<p><strong>使用 AI 的场合：</strong></p>
<ul>
<li>
<p>编写模板代码（getters、setters、基本的 CRUD）</p>
</li>
<li>
<p>学习新的框架或语法</p>
</li>
<li>
<p>编写测试和文档</p>
</li>
<li>
<p>重构重复模式</p>
</li>
<li>
<p>在语法错误上解开困境</p>
</li>
</ul>
<p><strong>自己编码的场合：</strong></p>
<ul>
<li>
<p>设计系统架构</p>
</li>
<li>
<p>做出关键的安全决策</p>
</li>
<li>
<p>编写复杂的业务逻辑</p>
</li>
<li>
<p>学习新概念（首次）</p>
</li>
<li>
<p>进行关键的性能优化</p>
</li>
</ul>
<p><strong>黄金法则：</strong> 使用 AI 加速实施，但自己做架构决策。AI 擅长“如何”，但你决定“什么”和“为什么”。</p>
<h2 id="prerequisites">前提条件</h2>
<p>在开始本教程之前，你应该具备：</p>
<ul>
<li>
<p><strong>基本编程经验</strong> – 你可以用某种语言编写简单程序</p>
</li>
<li>
<p><strong>安装有代码编辑器</strong> – 推荐使用 VS Code（从 <a href="http://code.visualstudio.com/">code.visualstudio.com</a> 免费获取）</p>
</li>
<li>
<p><strong>基本 Git 知识</strong> – 你知道如何提交和推送代码</p>
</li>
<li>
<p><strong>免费起步</strong> – 许多工具现在都有慷慨的免费版本，付费计划最低大约每月 10-20 美元</p>
</li>
</ul>
<h2 id="your-complete-learning-journey">你的完整学习旅程</h2>
<p>这篇全面的教程提供了一个循序渐进的计划，旨在助你成为 AI 辅助开发的专家：</p>
<p>注意：为了保持教程的易用性，我们将只关注一些核心工具。但你应该研究和探索更多适合你特定需求的工具，超出我们在此使用的工具。</p>
<h3 id="">学习路径</h3>
<p>你将经过 4 个阶段：掌握 GitHub Copilot 基础、解锁高级功能如聊天模式和代理、探索 CLI 工具（Claude Code 和 Gemini），最终战略性地结合多个工具实现完整的项目工作流程。</p>
<p>首先，让我们快速看看如何生成你的第一个 AI 代码片段。</p>
<h2 id="how-to-generate-your-first-ai-assisted-code">如何生成你的第一个 AI 辅助代码（快速入门）</h2>
<p>让我们从最基础的开始。别担心选择“完美”的工具——你总可以后续切换。以下是开始的方法：</p>
<h3 id="githubcopilot">GitHub Copilot（推荐初学者使用）</h3>
<p>你可以通过以下步骤安装 GitHub Copilot：</p>
<ol>
<li>
<p>打开 VS Code</p>
</li>
<li>
<p>点击扩展图标（或按 Ctrl+Shift+X）</p>
</li>
<li>
<p>搜索“GitHub Copilot”</p>
</li>
<li>
<p>点击“安装”</p>
</li>
<li>
<p>使用你的 GitHub 账户登录</p>
</li>
</ol>
<p><strong>提示：</strong> 学生、教师和开源软件维护者<a href="https://docs.github.com/en/copilot/how-tos/manage-your-account/getting-free-access-to-copilot-pro-as-a-student-teacher-or-maintainer">可以免费获得 Pro 计划</a>，这可以提供无限制的使用，而不是免费的使用限制。</p>
<h3 id="ai">你的第一个 AI 建议</h3>
<p>安装后，创建一个名为 <code>test.js</code> 的新文件，并输入：</p>
<pre><code>// function to calculate the area of a circle
</code></pre>
<p>按下 Enter 键等待。你会看到灰色文本出现——这是您的 AI 建议！按 Tab 键接受它。</p>
<p>就这样！您刚刚获得了第一个 AI 建议！是不是很酷？</p>
<h2 id="stage-1">阶段 1：基础 – 开始使用 AI 编码</h2>
<h3 id="1">第 1 步：了解您的选项</h3>
<p>将 AI 编码助手想象成不同类型的有帮助的朋友和同事。让我们来浏览几个：</p>
<p><strong>基于 IDE 的：</strong> 一些工具设计为可以与熟悉的代码编辑器一起工作，或作为编辑器如 VS Code 的独立分支。例如：</p>
<ul>
<li>
<p><strong>GitHub Copilot (VS Code 扩展)</strong> – 来自 GitHub 的 AI 编码助手，直接在 VS Code 中工作，提供 Tab 补全和聊天功能</p>
</li>
<li>
<p><strong>Cursor (独立)</strong> – VS Code 分支，具有增强的代理模式、更快的自主编码和更好的大代码库重构处理</p>
</li>
<li>
<p><strong>Windsurf (独立或 VS Code 扩展)</strong> – 专注于实时建议和团队功能的协作 AI 开发</p>
</li>
<li>
<p><strong>Zed</strong> – 高性能编辑器，内置 AI 辅助功能和快速渲染</p>
</li>
</ul>
<p><strong>基于 CLI 的：</strong> 一些工具是基于 CLI 的，您可以在终端应用中启动：</p>
<ul>
<li>
<p><strong>Claude Code</strong> – Anthropic 的终端 AI，用于自主开发会话和复杂推理</p>
</li>
<li>
<p><strong>Gemini</strong> – Google 的 CLI 工具，具有大上下文窗口和多模态功能（图像、文档）</p>
</li>
<li>
<p><strong>OpenCode</strong> – 开源替代方案，具有可自定义模型和本地处理选项</p>
</li>
<li>
<p><strong>Cursor CLI</strong> – Cursor 的终端版本，用于命令行 AI 辅助</p>
</li>
</ul>
<p><strong>基于 UI 和后台代理的工具：</strong> 除此之外，还有一些后台代理和工具可以完全在后台运行，例如执行拉取请求审查等。</p>
<p>例如，如果您设置了它们，ChatGPT 和 Claude 的桌面应用程序都可以编辑本地文件系统上的文件。同样，一些基于云的代理可以“在后台运行”以完成您的指令。我们将在本指南范围内排除这些。</p>
<h3 id="2tab">第 2 步：做出选择并学习自动建议（Tab 补全）</h3>
<p>对于您的第一阶段，我建议从 GitHub Copilot 开始。您可以在学习完基础知识后随时切换到适合您需求的工具。</p>
<h3 id="3">第 3 步：逐步设置</h3>
<h4 id="githubcopilot">如何设置 GitHub Copilot（如果您之前已经遵循过快速入门，可以跳过此步骤）</h4>
<ol>
<li>
<p><strong>打开 VS Code。</strong> 如果您没有，请从 <a href="https://code.visualstudio.com/">code.visualstudio.com</a> 下载。</p>
</li>
<li>
<p><strong>安装扩展</strong></p>
<ul>
<li>
<p>按 <code>Ctrl+Shift+X</code>（Windows/Linux）或 <code>Cmd+Shift+X</code>（Mac）</p>
</li>
<li>
<p>在搜索框中输入“GitHub Copilot”</p>
</li>
<li>
<p>点击蓝色的“安装”按钮</p>
</li>
<li>
<p>您会看到一个弹出窗口要求您登录</p>
</li>
</ul>
</li>
<li>
<p><strong>登录</strong></p>
<ul>
<li>
<p>点击“登录 GitHub”</p>
</li>
<li>
<p>您的浏览器会打开</p>
</li>
<li>
<p>使用您的 GitHub 帐户登录（如果需要，可以在 <a href="http://github.com/">github.com</a> 免费创建一个）</p>
</li>
<li>
<p>点击“授权 GitHub Copilot”</p>
</li>
</ul>
</li>
<li>
<p><strong>开始使用 Copilot</strong></p>
<ul>
<li>返回 VS Code，您会看到“GitHub Copilot 已准备好使用”</li>
</ul>
</li>
</ol>
<h3 id="4tab">第 4 步：掌握 Tab 补全</h3>
<p>让我们确保它正常工作。创建一个新文件：<code>hello.py</code>。输入此注释并按 Enter：</p>
<pre><code># function to greet a user by name
</code></pre>
<p>等待 1-2 秒。您应该会看到灰色文本出现。只需按 <code>Tab</code> 接受建议。</p>
<p><strong>您应该看到的内容：</strong></p>
<pre><code># function to greet a user by name
def greet_user(name):
    return f"Hello, {name}!"
</code></pre>
<p>如果您看到了这个，恭喜您！您现在正在使用 AI 帮助您编写代码。</p>
<p>如果您遇到设置问题，可以查看 <a href="http://localhost:3333/#troubleshooting-quick-reference">疑难解答快速参考</a> 寻求解决方案。</p>
<h3 id="5">第 5 步：基本键盘快捷键和第一次练习</h3>
<p>以下是您第一周需要的唯一快捷键：</p>
<p><strong>基础：</strong></p>
<ul>
<li>
<p><code>Tab</code> – 接受 AI 建议（这个用得最多！）</p>
</li>
<li>
<p><code>Esc</code> – 拒绝建议（当您不需要时）</p>
</li>
</ul>
<p>当您准备好了解更多时，尝试这些：</p>
<p><strong>Windows/Linux：</strong></p>
<ul>
<li>
<p><code>Alt+]</code> – 查看下一个建议</p>
</li>
<li>
<p><code>Alt+[</code> – 查看上一个建议</p>
</li>
<li>
<p><code>Ctrl+Enter</code> – 在面板中查看所有建议</p>
</li>
</ul>
<p><strong>macOS：</strong></p>
<ul>
<li>
<p><code>Option+]</code> （或 <code>Alt+]</code>） – 查看下一个建议</p>
</li>
<li>
<p><code>Option+[</code> （或 <code>Alt+[</code>) – 查看上一个建议</p>
</li>
<li>
<p><code>Ctrl+Enter</code> – 在面板中查看所有建议</p>
</li>
</ul>
<h3 id="1">阶段 1 实践练习</h3>
<h4 id="">练习：构建一个简单的待办事项应用</h4>
<ol>
<li>
<p>创建一个名为 <code>todo.js</code> 的新文件</p>
</li>
<li>
<p>以此注释开始：<code>// TODO app with add, remove, and list functions</code></p>
</li>
<li>
<p>添加此注释并等待 AI 建议：<code>// function to add a new todo item</code></p>
</li>
<li>
<p>如果建议看起来不错，按 Tab 键接受</p>
</li>
<li>
<p>继续为移除和列出函数添加注释</p>
</li>
<li>
<p>测试您的函数以确保它们工作正常</p>
</li>
</ol>
<p><strong>目标：</strong> 学习通过清晰的注释与 AI “对话”，并建立接受/拒绝建议的信心。</p>
<h3 id="">准备好进入下一阶段了吗？在继续之前，请确保您能够：</h3>
<pre><code>- [ ] 通过输入注释获取 AI 建议
- [ ] 使用 Tab 接受建议，使用 Esc 拒绝建议
- [ ] 使用 Alt+] 和 Alt+[ 查看不同的建议
- [ ] 在 AI 帮助下编写基本函数
</code></pre>
<p>如果您对这些基本内容感到满意，就可以学习更强大的 Copilot 功能了。</p>
<h2 id="stage-2">阶段 2：高级 GitHub Copilot 功能</h2>
<h3 id="6ai">第 6 步：获取更好的 AI 建议</h3>
<p>现在您已经了解了基础知识，让我们学习如何从您的 AI 那里得到_更好_的建议。诀窍在于了解您的 AI 能看到什么。</p>
<h4 id="ai">您的 AI 助手能看到什么</h4>
<p>想象您的 AI 助手就像一个站在你肩头、随时提供帮助的朋友。它能看到：</p>
<ol>
<li>
<p><strong>您当前正在输入的内容</strong>——您的当前文件</p>
</li>
<li>
<p><strong>其他打开的标签页</strong>——您打开的文件（这很重要！）</p>
</li>
<li>
<p><strong>您的项目结构</strong>——文件夹和文件名</p>
</li>
<li>
<p><strong>您的注释</strong>——这是您与 AI “对话” 的方式</p>
</li>
</ol>
<h4 id="">“相邻标签页”技巧</h4>
<p>这是一个能为您节省数小时的专业提示：<strong>在标签页中打开相关文件</strong>。</p>
<p><strong>示例：</strong> 如果您在编写一个 React 组件：</p>
<ul>
<li>
<p>打开您的组件文件 (<code>Button.jsx</code>)</p>
</li>
<li>
<p>还要打开 CSS 文件 (<code>Button.css</code>)</p>
</li>
<li>
<p>同时也让测试文件可见 (<code>Button.test.js</code>)</p>
</li>
</ul>
<p>然后，您可以通过几种方式与 AI 共享这些额外文件的上下文：</p>
<ul>
<li>
<p><strong>@提及文件：</strong> 在聊天中键入 <code>@filename.js</code> 以引用特定文件</p>
</li>
<li>
<p><strong>使用 @workspace：</strong> 这个聊天参与者可以看到您项目中的所有文件</p>
</li>
<li>
<p><strong>拖放：</strong> 只需将文件从资源管理器窗口拖动到聊天窗口</p>
</li>
<li>
<p><strong>选择代码：</strong> 高亮代码并右键单击 “Ask Copilot” 以将其包括在上下文中</p>
</li>
</ul>
<p>AI 使用这些打开的文件来理解您的项目结构，并建议更相关的代码以匹配您现有的模式。</p>
<h3 id="7">第 7 步：质量控制与最佳实践</h3>
<h4 id="ai">了解 AI 的局限性</h4>
<p>AI 功能强大，但并不完美。以下是需要注意的关键事项。</p>
<p><strong>常见的 AI 错误：</strong></p>
<ol>
<li>
<p>虚构的函数：例如，<code>const result = array.superSort();</code> 并不存在！</p>
</li>
<li>
<p>错误的参数：例如，当函数期望 <code>greetUser(name)</code> 时，<code>greetUser("John", "Doe");</code></p>
</li>
<li>
<p>过于复杂的解决方案：例如，<code>const isEven = (num) =&gt; num.toString(2).slice(-1) === "0";</code> - 只需使用 <code>num % 2 === 0</code></p>
</li>
</ol>
<p>快速质量检查清单：</p>
<pre><code>- [ ] 测试代码 - 它真的有效吗？
- [ ] 阅读 - 逻辑上是否合理？
- [ ] 检查基础 - 所有函数/变量是否已定义？
- [ ] 信任直觉 - 如果感觉不对，进行调查
</code></pre>
<h4 id="">安全要点</h4>
<p>在接受 AI 建议之前，请确保检查这些安全问题：</p>
<pre><code>- [ ] 没有硬编码的密码或 API 密钥
- [ ] 用户输入已验证
- [ ] 没有对用户数据使用 eval()
- [ ] 错误消息不暴露敏感信息
</code></pre>
<h4 id="">更好的提示写作</h4>
<p>这里有一个编写可靠提示的公式：是什么 + 如何 + 返回类型。</p>
<pre><code>// ❌ 含糊： "make function"
// ✅ 清晰： "function to validate email format using regex, returns boolean"
</code></pre>
<h4 id="copilot">使用 Copilot 指令进行仓库级自定义</h4>
<p>GitHub Copilot 现在支持通过 <code>.github/copilot-instructions.md</code> 文件进行仓库级别的自定义。此功能帮助 Copilot 理解您项目的特定模式和约定。</p>
<p>以下是设置 Copilot 指令的方法：</p>
<pre><code># 如果不存在，创建 GitHub 目录
mkdir -p .github
touch .github/copilot-instructions.md
</code></pre>
<p>示例 <a href="http://copilot-instructions.md/">copilot-instructions.md</a> 文件：</p>
<pre><code># Copilot 指令

## 代码风格

- 使用具有 hooks 的 React 函数组件
- 为新文件更偏好使用 TypeScript 而不是 JavaScript
- 使用 Tailwind CSS 进行样式设计
- 遵循 `/src/components` 中的现有文件结构

## 测试

- 使用 React Testing Library 编写测试
- 将测试文件放在 `__tests__` 目录中
- 使用描述性测试名称来解释行为

## API 模式

- 使用自定义钩子进行 API 调用
- 一致地处理加载和错误状态
- 使用 React Query 进行数据提取

## 命名约定

- 组件：PascalCase（例如，`UserProfile.tsx`）
- 钩子：以“use”开头的 camelCase（例如，`useUserData.ts`）
- 工具：camelCase（例如，`formatDate.ts`）
</code></pre>
<p><strong>这项功能实现了：</strong></p>
<ul>
<li>
<p>Copilot 建议符合您项目模式的代码</p>
</li>
<li>
<p>自动遵循您的命名约定</p>
</li>
<li>
<p>建议合适的测试方法</p>
</li>
<li>
<p>理解您偏好的库和框架</p>
</li>
</ul>
<p><strong>最佳实践：</strong></p>
<ul>
<li>
<p>保持指令清晰和具体</p>
</li>
<li>
<p>随着项目标准的发展及时更新</p>
</li>
<li>
<p>包括首选模式的示例</p>
</li>
<li>
<p>提到您使用的库和框架</p>
</li>
</ul>
<h3 id="8copilot">第 8 步：解锁高级 Copilot 功能</h3>
<h4 id="">了解您的选择</h4>
<p>GitHub Copilot 提供多种方式来获得 AI 帮助：</p>
<ol>
<li>
<p><strong>Tab 补全</strong>（您一直在使用的）——在输入时提供建议</p>
</li>
<li>
<p><strong>聊天模式</strong>——与 AI 就您的代码进行对话</p>
</li>
<li>
<p><strong>编辑模式</strong>——请求 AI 对现有代码进行修改</p>
</li>
<li>
<p><strong>代理模式</strong>——让 AI 自主完成大型任务</p>
</li>
</ol>
<h4 id="">模型选择</h4>
<p>Copilot 现在提供不同的 AI 模型以满足不同需求：</p>
<p>订阅免费：</p>
<ul>
<li>
<p><strong>GPT-4.1</strong> – 默认模型，综合性能强大</p>
</li>
<li>
<p><strong>GPT-4</strong> – 对大多数编码任务来说可靠</p>
</li>
</ul>
<p>高级模型（有限的每月使用量）：</p>
<ul>
<li>
<p><strong>Claude 3.5 Sonnet</strong> – 适合复杂逻辑</p>
</li>
<li>
<p><strong>GPT-5</strong> – 最新且最强大</p>
</li>
<li>
<p><strong>Gemini 2.0 Flash</strong> – 响应非常快速</p>
</li>
</ul>
<p><strong>如何切换模型：</strong> 点击聊天视图中的模型下拉菜单</p>
<p><strong>提示：</strong> 学习时从免费模型（GPT-4.1）开始，对于复杂问题保留高级模型使用。</p>
<h4 id="githubcopilot">GitHub Copilot 的局限性</h4>
<p>以下是在使用 AI 来帮助您进行编码时需要考虑的一些重要事项：</p>
<ul>
<li>
<p><strong>互联网依赖性</strong> – 需要稳定的连接以获得建议</p>
</li>
<li>
<p><strong>上下文限制</strong> – 只能看到打开的文件，而不是整个项目结构</p>
</li>
<li>
<p><strong>免费账号限制</strong> – 每月 2,000 次补全和 50 次聊天请求</p>
</li>
<li>
<p><strong>代码质量参差不齐</strong> – 始终审查建议，特别是涉及安全性敏感的代码时</p>
</li>
<li>
<p><strong>学习曲线</strong> – 编写有效的提示需要时间，特别是对于复杂任务</p>
</li>
<li>
<p><strong>隐私考虑</strong> – 您的代码会被发送到 GitHub 的服务器（请检查您的组织的政策）</p>
</li>
</ul>
<h4 id="">基础聊天与建议</h4>
<p>您可能想知道 - 什么时候应该使用 Tab 补全，什么时候应该使用聊天？最好是用 Tab 补全来编写新函数、快速的语法帮助和模式补全。可以使用聊天来解释现有代码、获取错误帮助和规划解决问题的方法。</p>
<p><strong>尝试一下：</strong> 打开聊天（Ctrl+Shift+I）并询问：“这个函数有什么作用？”同时选择代码。</p>
<h3 id="9">第9步：掌握聊天和代理模式</h3>
<h4 id="">三种聊天模式</h4>
<ol>
<li><strong>询问模式（默认）</strong> – 用于问题和解释：</li>
</ol>
<pre><code>“这个函数有什么作用？”
“如何优化这段代码？”
“解释此错误消息”
</code></pre>
<ol start="2">
<li><strong>编辑模式</strong> – 用于对现有代码进行更改：</li>
</ol>
<pre><code>“重构这段代码以使用 async/await”
“为所有 API 调用添加错误处理”
“将其转换为 TypeScript”
</code></pre>
<ul>
<li>
<p>显示内联差异后应用更改</p>
</li>
<li>
<p>可跨多个文件工作</p>
</li>
<li>
<p>适合系统化重构</p>
</li>
</ul>
<ol start="3">
<li><strong>代理模式</strong> – 用于自主开发：</li>
</ol>
<pre><code>“创建一个带身份验证的 REST API”
“使用React和测试构建一个待办应用”
“将此代码库从Vue 2迁移到Vue 3”
</code></pre>
<ul>
<li>
<p>按 <code>Cmd+Shift+I</code> （Mac）或 <code>Ctrl+Shift+Alt+I</code>（Linux）或 <code>Ctrl+Shift+I</code>（Windows）</p>
</li>
<li>
<p>可独立工作数小时</p>
</li>
<li>
<p>自动安装包、创建文件、运行测试</p>
</li>
</ul>
<h4 id="">何时使用各模式</h4>
<p>每种模式都有特定的使用场景。当您学习新概念时，希望理解现有代码、获取解释和去计划方法时，使用询问模式。</p>
<p>当您正在重构现有代码、应用一致的更改、为现有功能添加特性或进行样式/模式更新时，使用编辑模式。</p>
<p>代理模式在构建完整特性（30分钟以上的工作）、设置新项目、大规模重构时有用，并且在您希望在 AI 编码时处理其他事情时使用。</p>
<h4 id="">代理模式示例</h4>
<p>小型代理任务（15分钟）：</p>
<pre><code>“为我的 Express 应用添加用户身份验证”
</code></pre>
<p>代理生成的内容：</p>
<pre><code>// middleware/auth.js
const jwt = require('jsonwebtoken');

const authenticateToken = (req, res, next) =&gt; {
  const authHeader = req.headers['authorization'];
  const token = authHeader &amp;&amp; authHeader.split(' ')[1];

  if (!token) return res.sendStatus(401);

  jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) =&gt; {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

// routes/auth.js
router.post('/login', async (req, res) =&gt; {
  // 使用 bcrypt 进行身份验证的逻辑
  const accessToken = jwt.sign({username: user.username}, process.env.ACCESS_TOKEN_SECRET);
  res.json({accessToken: accessToken});
});
</code></pre>
<p><strong>我发现的关键问题：</strong> 代理最初忘记对密码进行哈希处理，并且没有包括刷新令牌。这需要一次迭代来修复安全漏洞并添加适当的错误处理。</p>
<p>大型代理任务（4小时以上）：</p>
<pre><code>“将此基于类的 React 应用更新为使用 TypeScript 的 hooks”
</code></pre>
<p>代理生成的内容：</p>
<pre><code>// 之前（类组件）
class UserProfile extends React.Component {
  constructor(props) {
    this.state = { user: null, loading: true };
  }
  // ... 生命周期方法
}

// 之后（Hooks + TypeScript）
interface User {
  id: number;
  name: string;
  email: string;
}

const UserProfile: React.FC = () =&gt; {
  const [user, setUser] = useState&lt;User | null&gt;(null);
  const [loading, setLoading] = useState(true);

  useEffect(() =&gt; {
    fetchUser().then(setUser).finally(() =&gt; setLoading(false));
  }, []);

  return &lt;div&gt;{loading ? 'Loading...' : user?.name}&lt;/div&gt;;
};
</code></pre>
<p>**我发现的关键问题：**代理成功更新了47个文件，但最初在事件处理程序中存在类型问题，并且需要改进泛型类型。自动化测试还需要人工检查以确保适当的 TypeScript 覆盖。</p>
<p>Chat 参与者是专门的 AI 助手，可以访问您的开发环境中的特定部分。可以将它们视为不同领域的专家，能够帮助完成有针对性的任务。</p>
<p>它们基本上是以 <code>@</code> 作为前缀的 AI 助手，具有特殊的知识和能力：</p>
<ul>
<li>
<p><strong>@workspace</strong> 可以访问您整个项目的结构，可以搜索文件并理解组件之间的关系。当您需要项目范围的分析时，请使用 <code>@workspace</code>："找出此项目中的所有 API 端点" 或 "显示用户身份验证是在哪里实现的。"</p>
</li>
<li>
<p><strong>@terminal</strong> 了解命令行操作，可以建议 shell 命令并解释终端输出。对于命令行帮助，请使用 <code>@terminal</code>："哪个命令可以运行测试？" 或 "如何为生产构建此项目？"</p>
</li>
<li>
<p><strong>@vscode</strong> 是 VS Code 功能方面的专家，可以帮助进行设置、调试和编辑器配置。对于编辑器帮助，请使用 <code>@vscode</code>："为 Node.js 设置调试" 或 "为此项目配置自动格式化。"</p>
</li>
</ul>
<p><strong>示例用法:</strong></p>
<pre><code>@workspace 你能找到这个项目中的所有数据库模型吗？
@terminal 安装依赖项并启动开发服务器的命令是什么？
@vscode 如何设置断点以调试这个 Express 应用？
</code></pre>
<h3 id="10">步骤 10：高级用户功能和高级工作流程</h3>
<p>除了您已经了解的 Copilot 核心功能外，还有一些专门的工具和命令可以极大地提高您的生产力。这些功能超越基本的聊天模式和模型选择，专注于复杂的多文件操作和高级自动化。</p>
<h4 id="">高级斜线命令</h4>
<pre><code>/doc - 生成文档
/explain - 详细的代码说明
/fix - 修复选定代码中的错误
/tests - 生成单元测试
/new - 创建新的项目结构
</code></pre>
<h4 id="">多文件操作</h4>
<p><strong>使用 # 引用：</strong></p>
<p><code>#</code> 符号创建特定的引用，告诉 Copilot 精确关注哪里。这些引用就像是指向项目不同部分的精准指针：</p>
<ul>
<li>
<p><strong>#file:filename</strong>: 引用特定文件：<code>#file:UserModel.js</code></p>
</li>
<li>
<p><strong>#codebase</strong>: 引用整个项目代码库以进行搜索</p>
</li>
<li>
<p><strong>#selection</strong>: 引用当前选定的代码</p>
</li>
<li>
<p><strong>#editor</strong>: 引用当前活动文件</p>
</li>
</ul>
<pre><code>"更新 #file:UserModel.js 以包含时间戳"
"在 #codebase 中搜索所有数据库查询"  
"将 #selection 重构为现代 JavaScript 语法"
"为所有 API 调用添加错误处理到 #editor"
</code></pre>
<p>这些引用帮助 Copilot 准确理解要查看和更改的位置，使多文件操作更加精确。</p>
<p><strong>拖放操作：</strong></p>
<p>拖放是提供给 Copilot 的最直观的上下文方式之一。您可以将文件从 VS Code 浏览器中直接拖入聊天窗口，Copilot 会立即了解其内容和结构。</p>
<p>当您处理相关组件并需要 AI 理解不同文件如何相互连接时，此功能特别有用。Copilot 会在整个对话中记住这些文件关系，因此在继续相同的讨论时无需再次上传文件。</p>
<p>这种上下文保留在多个聊天会话中有效，使您可以轻松在复杂的多文件项目中继续之前的工作。</p>
<h3 id="2">阶段 2 实践练习</h3>
<h4 id="1">练习 1：聊天模式实践</h4>
<ol>
<li>
<p>使用提问模式理解一个复杂的函数</p>
</li>
<li>
<p>切换到编辑模式进行重构</p>
</li>
<li>
<p>比较不同的方法</p>
</li>
</ol>
<h4 id="2">练习 2：代理模式项目</h4>
<ol>
<li>
<p>启动代理模式 (<code>Shift+Cmd+I</code>)</p>
</li>
<li>
<p>请求："创建一个带测试的简单待办应用"</p>
</li>
<li>
<p>观察自主开发过程</p>
</li>
<li>
<p>查看生成的代码</p>
</li>
</ol>
<h4 id="3">练习 3：高级功能</h4>
<ol>
<li>
<p>使用 @ 参与者进行项目问题</p>
</li>
<li>
<p>试验斜线命令</p>
</li>
<li>
<p>练习多文件操作</p>
</li>
</ol>
<h3 id="cli">准备好使用 CLI 工具了吗？</h3>
<p>您现在已经学习了在 VS Code 中使用 GitHub Copilot 的基础知识！像 Claude Code 和 Gemini 这样的 CLI 工具为基于终端的开发提供了更强大的功能。</p>
<p>如果你对终端 AI 感兴趣，可以继续学习下方的第三阶段。如果你更愿意继续使用 VS Code，请跳到第四阶段以获取高级工作流程。</p>
<h2 id="stage-3">阶段 3：基于 CLI 的 AI 代理（Claude Code &amp; Gemini）</h2>
<h3 id="11claudecodeai">步骤 11：认识 Claude Code——您的终端 AI 助手</h3>
<h4 id="claudecode">什么是 Claude Code？</h4>
<p>还记得 GitHub Copilot 如何在 VS Code 中帮助你吗？Claude Code 在终端中为你提供相同的帮助。</p>
<p>不用在 VS Code 中键入和获取建议，你可以在终端中键入并与 AI 对话。这就像在命令行上有一个编程伙伴。</p>
<h4 id="">简单例子：</h4>
<p>在 VS Code 中使用 Copilot：</p>
<pre><code>// 创建一个函数来验证电子邮件
[AI 提供建议代码]
</code></pre>
<p>在终端中使用 Claude Code：</p>
<pre><code>claude
&gt; 创造一个函数来验证电子邮件地址
[AI 为你编写代码]
</code></pre>
<p>那么，什么时候应该使用 VS Code/Copilot，什么时候应该使用 Claude Code 呢？</p>
<p><strong>如果你：</strong></p>
<ul>
<li>
<p>喜欢在终端工作</p>
</li>
<li>
<p>想要与 AI 进行关于代码的对话</p>
</li>
<li>
<p>需要有关命令行任务的帮助</p>
</li>
<li>
<p>想要更多控制 AI 互动</p>
</li>
</ul>
<p>Claude Code 非常适合你。</p>
<ul>
<li>
<p>偏好可视化编辑器</p>
</li>
<li>
<p>对当前的工作流程感到满意</p>
</li>
<li>
<p>不花太多时间在终端</p>
</li>
</ul>
<h4 id="">定价</h4>
<p>Claude Code 需要 Claude Pro（每月 20 美元）或 ClaudeMax（每月 100 美元）订阅，或使用 API 积分按使用量付费。</p>
<h4 id="claudecode">Claude Code 限制</h4>
<p>如果您计划使用 Claude Code，请考虑以下重要事项：</p>
<ul>
<li>
<p><strong>仅付费</strong> – 没有免费版本，需要 Claude Pro 订阅或 API 积分</p>
</li>
<li>
<p><strong>基于终端</strong> – 不如 IDE 集成工具可视化</p>
</li>
<li>
<p><strong>学习曲线</strong> – 需要熟悉命令行界面</p>
</li>
<li>
<p><strong>上下文管理</strong> – 需要手动管理对话上下文</p>
</li>
<li>
<p><strong>依赖互联网</strong> – 所有操作都需要稳定的连接</p>
</li>
<li>
<p><strong>会话限制</strong> – 长时间的自主会话会消耗大量 API 积分</p>
</li>
</ul>
<h4 id="">安装</h4>
<p>推荐（所有平台）：</p>
<pre><code>npm install -g @anthropic-ai/claude-code
</code></pre>
<p>其他安装方式：</p>
<ul>
<li>
<p><strong>macOS/Linux</strong>: <code>curl -fsSL https://claude.ai/install.sh | bash</code></p>
</li>
<li>
<p><strong>Windows</strong>: <code>irm https://claude.ai/install.ps1 | iex</code></p>
</li>
</ul>
<h4 id="">基本用法</h4>
<p><strong>交互模式（推荐）：</strong></p>
<p>交互模式是 Claude Code 的主要界面，您可以与 AI 实时对话。不同于一次性命令，交互模式创建了一个持久的会话，您可以提出后续问题、迭代解决方案，并随着时间的推移构建复杂的项目。</p>
<p>推荐使用交互模式，因为：</p>
<ul>
<li>
<p><strong>上下文持久性</strong>：Claude 会记住整个对话和项目上下文</p>
</li>
<li>
<p><strong>迭代开发</strong>：您可以优化请求，并基于先前的回应进行改进</p>
</li>
<li>
<p><strong>实时协作</strong>：在工作时提问、获取解释并修改方法</p>
</li>
<li>
<p><strong>会话恢复</strong>：使用 <code>claude --resume</code> 继续之前的对话</p>
</li>
</ul>
<p><strong>其他可用模式：</strong></p>
<ul>
<li>
<p><strong>一次性模式</strong>：单个命令执行（下文说明）</p>
</li>
<li>
<p><strong>代理模式</strong>：可独立工作数小时的自主开发会话</p>
</li>
</ul>
<ol>
<li>导航到您的项目：</li>
</ol>
<pre><code>cd your-project
claude
</code></pre>
<ol start="2">
<li>自然地开始对话：</li>
</ol>
<pre><code>Claude Code &gt; 分析这个代码库并提出改进建议

Claude Code &gt; 现在帮我重构用户认证

Claude Code &gt; 为支付模块添加单元测试
</code></pre>
<ol start="3">
<li>继续之前的会话：</li>
</ol>
<pre><code>claude --resume
</code></pre>
<p><strong>一次性命令（用于快速任务）：</strong></p>
<p>一次性命令是执行特定任务后即退出的单次执行命令。与交互模式不同，这些命令不保留对话上下文 —— 非常适合快速、独立的任务。</p>
<p><strong>什么是一次性命令？</strong></p>
<p>这些是在您的终端中直接运行带有特定指令的命令，而不进入交互会话。Claude 将执行请求并立即提供结果。</p>
<p><strong>何时使用一次性命令：</strong></p>
<ul>
<li>
<p>快速分析或代码审查</p>
</li>
<li>
<p>简单文件修改</p>
</li>
<li>
<p>自动化脚本和 CI/CD 集成</p>
</li>
<li>
<p>需要单一特定答案时</p>
</li>
</ul>
<p><strong>示例：</strong></p>
<pre><code>claude "分析这个代码库并提出改进建议"
claude "修复 src/ 中的所有 TypeScript 错误"
claude "为 utils.js 生成单元测试"
claude "解释这个函数的作用" --file src/auth.js
</code></pre>
<p>关键区别在于一次性命令在运行之间不记住上下文，而交互模式保持完整的对话历史记录和项目理解。</p>
<p><strong>交互式 vs 自主会话：</strong></p>
<p>在交互模式内，您可以选择协作和自主的方法：</p>
<p><strong>交互式会话（协作）：</strong></p>
<pre><code>Claude Code &gt; 我正在构建用户认证。我们应该采用什么方法？

你：使用 JWT 令牌和刷新令牌轮换

Claude Code &gt; 实现带刷新令牌的 JWT 认证
[逐步向您展示实现方案]

Claude Code &gt; 我还需要添加密码重置功能吗？

你：是的，使用基于邮件的重置
</code></pre>
<p><strong>自主会话（免动手开发）：</strong></p>
<pre><code>Claude Code &gt; 构建一个完整的用户管理系统，包括认证、个人资料、偏好设置和管理功能。使用安全和测试的最佳实践。

[Claude 自主工作数小时，定期提供更新]
[最终结果：完整的用户管理系统，准备投入生产]
</code></pre>
<p><strong>何时使用每种模式：</strong> 在学习时或希望对决策进行控制时使用交互式会话。对于定义明确的任务，在您信任 Claude 能够独立做出良好选择时使用自主会话。</p>
<h4 id="">关键特性</h4>
<p><strong>思维模式（在交互式会话中使用）：</strong></p>
<p>思维模式是特定的命令，可以告诉 Claude 在响应前要进行多深的分析。您可以根据问题的复杂程度手动选择这些模式。</p>
<p><strong>何时使用每种模式：</strong></p>
<ul>
<li>
<p><code>think</code> – 对简单任务进行快速分析："think: review this function for bugs"</p>
</li>
<li>
<p><code>think hard</code> – 对复杂逻辑进行深入推理："think hard: optimize this algorithm"</p>
</li>
<li>
<p><code>think harder</code> – 复杂问题解决，考虑多重因素："think harder: design a scalable database schema"</p>
</li>
<li>
<p><code>ultrathink</code> – 对架构决策进行最大深度分析："ultrathink: evaluate microservices vs monolith for this project"</p>
</li>
</ul>
<p>Claude展示其通过较长的思考模式进行推理的过程。您将在得出最终答案之前看到逐步分析。更高的思考模式花费更多时间，但会提供更全面的解决方案。</p>
<p><strong>选择正确的模式：</strong></p>
<p>使用<code>think</code>进行快速代码审查，使用<code>think hard</code>调试复杂问题，使用<code>think harder</code>处理系统设计问题，使用<code>ultrathink</code>进行影响整个项目的重大架构决策。</p>
<h4 id="claudemd">使用Claude.md进行项目级定制</h4>
<p>Claude Code最强大的功能之一是使用<code>.claude/CLAUDE.md</code>文件进行项目级定制。这让你可以为Claude提供有关特定项目、编码标准和偏好的上下文。</p>
<p>像这样设置CLAUDE.md：</p>
<pre><code># 创建项目级配置
mkdir -p .claude
touch .claude/CLAUDE.md
</code></pre>
<p>以下是一个CLAUDE.md文件的示例：</p>
<pre><code># 项目上下文

这是一个使用Express和PostgreSQL的Node.js REST API。

## 编码标准

- 使用async/await，绝不使用回调
- 所有数据库查询使用Prisma ORM
- 为所有新功能使用Jest编写测试
- 遵循RESTful约定

## 项目结构

- `/src/routes` - API端点
- `/src/models` - 数据库模型
- `/src/middleware` - Express中间件
- `/tests` - 单元和集成测试

## 偏好

- 为所有新文件使用TypeScript
- 更喜欢函数式编程模式
- 为所有函数包含JSDoc注释
</code></pre>
<p>这有助于Claude自动理解您的项目结构。还帮助Claude遵循您的特定编码标准，为您的技术栈建议合适的模式，并在多次会话中记住您的偏好。</p>
<p><strong>专业提示：</strong> 随着项目的发展更新你的CLAUDE.md，以保持Claude的建议相关和准确。</p>
<h4 id="claudecode">Claude Code自主开发会话</h4>
<p>这是一个多小时的自主开发会话示例：</p>
<pre><code>cd your-project
claude
</code></pre>
<p><strong>你的提示：</strong>“构建一个可扩展的具有实时订阅、身份验证、速率限制和全面测试的GraphQL API”</p>
<p>Claude的6小时自主过程：</p>
<pre><code>Claude Code &gt; ultrathink: 分析需求并设计架构

[创建详细的技术规格和开发计划]

Claude Code &gt; 实现核心GraphQL服务器与Apollo
[运行：npm install apollo-server-express graphql]
[创建：server.js, schema/typeDefs.js, resolvers/index.js]

Claude Code &gt; 添加身份验证和授权中间件
[创建：middleware/auth.js, utils/jwt.js, models/User.js]
[实现具有适当错误处理的JWT策略]

Claude Code &gt; 设置具有Redis的实时订阅
[运行：npm install graphql-redis-subscriptions]
[配置WebSocket连接，创建订阅解析器]

Claude Code &gt; 实施速率限制和安全措施
[添加helmet, express-rate-limit, 查询复杂度分析]

Claude Code &gt; 编写全面的测试套件
[创建单元测试、集成测试、负载测试]
[运行：npm test - 看到8个失败的测试]

Claude Code &gt; 自动修复测试失败
[识别异步时间问题，修复解析器逻辑]
[反复重新运行测试直到94/94个测试通过]

Claude Code &gt; 性能优化和缓存
[实现Redis缓存，优化数据库查询]
[添加性能监控和日志记录]

Claude Code &gt; 生成全面的文档
[创建带示例的API文档，README，部署指南]

Claude Code &gt; 最终验证和清理
[运行完整的测试套件，检查代码覆盖率：96%]
[创建生产构建和部署脚本]
</code></pre>
<p>这代表了6小时的自主工作（在此期间你可以处理其他项目）。结果是一个生产就绪的GraphQL API，具有身份验证、实时功能和全面的测试。</p>
<p>为什么这有效：</p>
<ul>
<li>
<p><strong>自主反馈循环：</strong> Claude运行测试，看到失败，自动修复</p>
</li>
<li>
<p><strong>上下文感知：</strong> 保持对整个项目结构的理解</p>
</li>
<li>
<p><strong>自我纠正：</strong> 反复迭代解决方案直至正确工作</p>
</li>
<li>
<p><strong>工具集成：</strong> 无缝使用git, npm, 测试框架</p>
</li>
</ul>
<p><strong>网络搜索集成：</strong></p>
<p>Claude Code可以搜索网络以获取当前信息，这对于AI训练数据有截断日期特别有用。该功能帮助您保持与最新文档、最佳实践和解决方案的同步。</p>
<pre><code>Claude Code &gt; 搜索最新的React 19功能并更新我的组件

[Claude搜索网络，然后以发现继续对话]

Claude Code &gt; 现在将这些新功能应用于UserProfile组件
</code></pre>
<p><strong>网络搜索何时有帮助：</strong></p>
<ul>
<li>
<p>获取新库版本的当前文档</p>
</li>
<li>
<p>找到最近错误消息或漏洞的解决方案</p>
</li>
<li>
<p>研究最新的最佳实践和模式</p>
</li>
<li>
<p>比较当前问题的解决方案</p>
</li>
</ul>
<p>当Claude检测到需要当前信息时，网络搜索会自动发生，或者你可以通过在提示中提到“搜索”或“最新”来显式请求。</p>
<h4 id="claudecode">Claude Code键盘快捷键</h4>
<p>你可以使用这些键盘快捷键提高工作效率：</p>
<ul>
<li>
<p><code>Ctrl+C</code> – 取消当前输入或生成</p>
</li>
<li>
<p><code>Ctrl+D</code> – 退出 Claude Code 会话</p>
</li>
<li>
<p><code>Ctrl+L</code> – 清除终端屏幕</p>
</li>
<li>
<p><code>Up/Down arrows</code> – 导航命令历史</p>
</li>
<li>
<p><code>Esc</code> + <code>Esc</code> – 编辑上一条消息</p>
</li>
</ul>
<p><strong>多行输入：</strong></p>
<ul>
<li>
<p><code>\</code> + <code>Enter</code> – 快速转义以创建新行（适用于所有终端）</p>
</li>
<li>
<p><code>Option+Enter</code> (Mac) / <code>Shift+Enter</code> (已配置) – 插入新行</p>
</li>
</ul>
<h3 id="12googlegemini">步骤12：Google Gemini 命令行界面</h3>
<h4 id="geminiclaudecode">何时使用 Gemini 与 Claude Code：</h4>
<p>Gemini 是另一种基于命令行界面的 AI 工具，它与 Claude Code 相辅相成，而不是竞争。尽管 Claude Code 擅长深度推理和复杂的开发任务，但 Gemini 提供了独特的优势：大规模上下文窗口（超过100万个标记）、慷慨的免费限制以及强大的多模态能力。</p>
<p><strong>使用 Gemini，当您：</strong></p>
<ul>
<li>
<p>需要一次分析整个大型代码库</p>
</li>
<li>
<p>希望处理图像、图表或草图</p>
</li>
<li>
<p>在预算限制内工作（慷慨的免费套餐）</p>
</li>
<li>
<p>需要极大的上下文窗口来处理复杂项目</p>
</li>
</ul>
<p><strong>使用 Claude Code，当您：</strong></p>
<ul>
<li>
<p>需要复杂的推理和问题解决</p>
</li>
<li>
<p>希望进行自主开发会话</p>
</li>
<li>
<p>偏爱用于复杂分析的高级思维模式</p>
</li>
<li>
<p>正在构建需要详细规划的生产系统</p>
</li>
</ul>
<p><strong>最佳方法：</strong> 许多开发人员策略性地使用这两种工具——Gemini用于分析和视觉输入，Claude Code用于复杂的开发任务。</p>
<p>Gemini 将 Google 的 AI 带到您的终端，并提供慷慨的免费限制。</p>
<h4 id="">安装</h4>
<p>使用 npx (推荐试用)：</p>
<pre><code>npx @google/gemini-cli
</code></pre>
<p>全局安装：</p>
<pre><code>npm install -g @google/gemini-cli
gemini  # 开始交互式会话
</code></pre>
<h4 id="">认证</h4>
<ol>
<li>使用 Google 登录：</li>
</ol>
<pre><code>gemini auth login
</code></pre>
<ol start="2">
<li>检查状态：</li>
</ol>
<pre><code>gemini auth status
</code></pre>
<p>免费限制：</p>
<ul>
<li>
<p>60 次请求/分钟</p>
</li>
<li>
<p>使用 Google 帐户每日 1,000 次请求</p>
</li>
</ul>
<p>内置工具：</p>
<ul>
<li>
<p><code>/memory</code> – 管理对话记忆</p>
</li>
<li>
<p><code>/stats</code> – 查看使用统计</p>
</li>
<li>
<p><code>/tools</code> – 列出可用工具</p>
</li>
<li>
<p><code>/mcp</code> – 配置模型上下文协议服务器</p>
</li>
</ul>
<h4 id="geminicli">Gemini CLI 的限制</h4>
<p>如果您计划使用 Gemini，请考虑以下重要事项：</p>
<ul>
<li>
<p><strong>速率限制</strong> – 免费套餐 60 次请求/分钟，1,000次/天</p>
</li>
<li>
<p><strong>Google 依赖性</strong> – 需要 Google 帐户和互联网连接</p>
</li>
<li>
<p><strong>较新的工具</strong> – 相较于 GitHub Copilot，社区较小，资源较少</p>
</li>
<li>
<p><strong>面向终端</strong> – 与流行的 IDE 整合较少</p>
</li>
<li>
<p><strong>多模态处理</strong> – 图像上传有大小限制 (20MB)</p>
</li>
<li>
<p><strong>测试版功能</strong> – 某些高级功能可能不稳定</p>
</li>
</ul>
<h4 id="gemini">独特的 Gemini 特性</h4>
<p><strong>庞大的上下文窗口：</strong><br>
Gemini 可以在单个会话中处理超过 100 万个标记，这意味着它可以同时分析整个大型代码库。这对于理解复杂系统架构和多个文件之间的关系特别有用。</p>
<p><strong>多模态能力：</strong><br>
Gemini 能够处理和理解各种类型的视觉内容以及代码，使其在设计到代码的工作流程和视觉调试中具有独特的优势。</p>
<h4 id="">将您的草图转化为代码</h4>
<p>这真的很酷：您可以在纸上绘制一些东西，然后 Gemini 将其转化为可工作的代码！</p>
<p>操作方法如下：</p>
<ol>
<li>
<p><strong>创建您的草图：</strong> 在纸上、白板或数位板上绘制您的想法</p>
</li>
<li>
<p><strong>拍照或截图：</strong> 使用手机拍摄或截图，将草图数字化</p>
</li>
<li>
<p><strong>保存图像：</strong> 保存为 JPG、PNG 或 WebP 格式（小于 20MB）</p>
</li>
<li>
<p><strong>通过命令行将其展示给 Gemini：</strong></p>
</li>
</ol>
<pre><code>gemini -p "将此草图转化为具有良好样式的 React 组件" sketch.jpg
</code></pre>
<p><strong>替代方法：</strong></p>
<pre><code># 如果您处于交互会话中，您可以引用文件：
gemini
&gt; 分析此UI草图并创建HTML/CSS：@sketch.jpg

# 或在支持的终端中拖放
gemini
&gt; 将此设计实现为 Vue 组件
[将 sketch.jpg 拖入终端]
</code></pre>
<p>然后，Gemini 会查看您的图纸并生成：</p>
<ul>
<li>
<p>与您的草图匹配的工作 React 组件</p>
</li>
<li>
<p>使其看起来不错的精美 CSS 样式</p>
</li>
<li>
<p>如果您绘制了表单则提供表单验证</p>
</li>
<li>
<p>使其工作的所有代码</p>
</li>
</ul>
<p>这就像拥有一个能读懂您心思的设计师和开发人员！</p>
<h4 id="gemini">通过展示图像来修复 Gemini 中的错误</h4>
<p>UI 出现了 Bug？您可以向 Gemini 展示视觉信息以帮助调试：</p>
<pre><code>gemini -p "该 UI 看起来有问题。有什么问题，我该如何解决？" image.png
</code></pre>
<p>Gemini 可以分析视觉信息并告诉您：</p>
<ul>
<li>
<p>问题的原因是什么</p>
</li>
<li>
<p>需要修改哪些代码</p>
</li>
<li>
<p>有时还有更好的解决方法</p>
</li>
</ul>
<h4 id="">将架构图转化为代码</h4>
<p>画出系统架构图，Gemini 可以构建它：</p>
<pre><code>gemini -p "使用 Docker 和数据库构建此系统架构" diagram.jpg
</code></pre>
<p>Gemini 将：</p>
<ul>
<li>
<p>理解您的图示</p>
</li>
<li>
<p>创建您所需的所有 Docker 文件</p>
</li>
<li>
<p>设置数据库和连接</p>
</li>
<li>
<p>根据您的设计提供一个可工作的系统</p>
</li>
</ul>
<p>将设计翻译成代码不再需要耗费数小时，您可以：</p>
<ol>
<li>
<p>向 Gemini 展示您的草图或设计</p>
</li>
<li>
<p>让 Gemini 构建它</p>
</li>
<li>
<p>在几分钟内获得工作代码，而不是几个小时，只需根据需要进行细化</p>
</li>
</ol>
<p>大多数情况下，Gemini 初次尝试就能很接近您的期望。即使它并不完美，它也为您提供了一个很好的起点，节省了大量时间。</p>
<h3 id="13cli">第13步：比较 CLI 工具</h3>
<p>这里有一个简易表格来帮助您比较 Claude Code 和 Gemini CLI 的功能：</p>
<table>
<thead>
<tr>
<th><strong>功能</strong></th>
<th><strong>Claude Code</strong></th>
<th><strong>Gemini CLI</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>上下文窗口</strong></td>
<td>大</td>
<td>1M+ 令牌</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>4 个等级</td>
<td>ReAct 循环</td>
</tr>
<tr>
<td><strong>IDE 集成</strong></td>
<td>VS Code 快捷键</td>
<td>终端优先</td>
</tr>
<tr>
<td><strong>免费层</strong></td>
<td>有限</td>
<td>慷慨 (1000/天)</td>
</tr>
<tr>
<td><strong>开源</strong></td>
<td>否</td>
<td>是</td>
</tr>
<tr>
<td><strong>多模态</strong></td>
<td>否</td>
<td>是 (图像, PDF)</td>
</tr>
</tbody>
</table>
<h3 id="14cli">第14步：高级 CLI 工作流程</h3>
<h4 id="1claudecode">工作流程1：Claude Code 的互动代码审查</h4>
<pre><code>Claude Code &gt; review my recent git changes

[Claude 分析差异]

Claude Code &gt; fix the security issue you found in the login function

Claude Code &gt; now create a pull request with a good description
</code></pre>
<h4 id="2gemini">工作流程2：Gemini 的对话式架构分析</h4>
<pre><code>Gemini &gt; analyze this codebase architecture and identify technical debt

[Gemini 提供全面的分析]

Gemini &gt; create a migration plan for the database issues you found

Gemini &gt; generate API documentation for the endpoints
</code></pre>
<h4 id="3">工作流程3：互动测试驱动开发</h4>
<pre><code>Claude Code &gt; I need to add payment processing. Start by writing comprehensive tests

[Claude 创建测试套件]

Claude Code &gt; now implement the payment service to pass these tests

Claude Code &gt; add error handling and edge cases
</code></pre>
<h3 id="vscodecli">结合 VS Code 和 CLI 工具</h3>
<h4 id="">混合工作流程的力量：</h4>
<p>最具生产力的开发者通常不会只选择一个 AI 工具——他们策略性地将 VS Code 扩展与 CLI 工具结合起来，以最大化效率。每个工具都有独特的优势，结合它们会创造出一个大于其各部分总和的工作流程。</p>
<p><strong>结合工具的好处：</strong></p>
<ul>
<li>
<p><strong>无缝的上下文切换：</strong> 从 Copilot 开始快速开发，然后无缝移动到 Claude Code 进行复杂的分析，而不失去动力</p>
</li>
<li>
<p><strong>互补的优势：</strong> 利用每个工具的最佳功能，如 Copilot 的实时建议 + Claude 的深入推理 + Gemini 的视觉处理</p>
</li>
<li>
<p><strong>持续的工作流：</strong> 无需在工具之间复制/粘贴代码—在项目中直接工作，并根据需要获得不同的 AI 支持</p>
</li>
<li>
<p><strong>减少心理负担：</strong> 工具处理不同的认知任务，让您专注于创造性的问题解决</p>
</li>
</ul>
<h4 id="">如何实际组合工具：</h4>
<p>示例工作流程——构建用户仪表板：</p>
<ol>
<li>
<p><strong>在 VS Code 中使用 Copilot 开始：</strong> 使用制表符补全快速构建基本组件结构</p>
</li>
<li>
<p><strong>保持 VS Code 打开，启动 Claude Code：</strong> 获取架构建议和重构建议，同时保持编辑器上下文</p>
</li>
<li>
<p><strong>切换到 Gemini 以获取视觉元素：</strong> 上传 UI 模型以生成匹配的样式</p>
</li>
<li>
<p><strong>返回到 VS Code：</strong> 应用所有建议，同时有 Copilot 协助实现细节</p>
</li>
</ol>
<p><strong>关键集成点：</strong></p>
<ul>
<li>
<p><strong>共享项目上下文：</strong> 所有工具在同一个目录中工作，了解您的项目结构</p>
</li>
<li>
<p><strong>文件系统协调：</strong> CLI 工具进行的更改会立即在 VS Code 中可见</p>
</li>
<li>
<p><strong>版本控制集成：</strong> 使用 CLI 工具进行 git 操作，而 VS Code 显示视觉差异</p>
</li>
</ul>
<h3 id="">快速切换设置</h3>
<h4 id="">什么是快速切换？</h4>
<p>快速切换设置指的是配置你的开发环境，让你可以快速在不同的 AI 工具之间切换，而不产生摩擦。通过创建快捷方式，而不是输入长命令或通过多个设置步骤进行导航，您可以立即访问当前任务所需的 AI 工具。</p>
<p>在您的 shell 配置文件中添加（<code>.zshrc</code> 或 <code>.bashrc</code>）：</p>
<pre><code># 快速 AI 命令用于交互模式
alias cc="claude"
alias gc="gemini"

# 在需要时进行快速单次命令
alias think="claude 'think hard:'"
alias analyze="gemini -p 'analyze:'"
</code></pre>
<h3 id="3">阶段3实践练习</h3>
<h4 id="1claudecode">练习1：互动 Claude Code 项目设置</h4>
<ol>
<li>
<p>创建一个新项目目录</p>
</li>
<li>
<p>启动：<code>claude</code></p>
</li>
<li>
<p>开始对话："set up a Node.js Express API with PostgreSQL"</p>
</li>
<li>
<p>继续聊天："add authentication middleware"</p>
</li>
<li>
<p>继续："now add comprehensive error handling"</p>
</li>
<li>
<p>查看生成的代码并提问</p>
</li>
</ol>
<h4 id="2gemini">练习2：互动 Gemini 代码分析</h4>
<ol>
<li>
<p>导航到现有项目</p>
</li>
<li>
<p>启动：<code>gemini</code></p>
</li>
<li>
<p>从以下内容开始："analyze this codebase and identify potential security vulnerabilities"</p>
</li>
<li>
<p>后续："explain the most critical issue in detail"</p>
</li>
<li>
<p>继续："create a fix for the authentication vulnerability"</p>
</li>
<li>
<p>询问："what other improvements should I prioritize?"</p>
</li>
<li>
<p>在 VS Code 中使用 Copilot 开始初始开发</p>
</li>
<li>
<p>切换到交互式 Claude Code 会话进行复杂的代码重构</p>
</li>
<li>
<p>使用交互式 Gemini 会话进行代码库分析和文档撰写</p>
</li>
<li>
<p>熟练地在工具之间无缝切换</p>
</li>
</ol>
<p>需要 CLI 工具的帮助吗？请参阅<a href="http://localhost:3333/#troubleshooting-quick-reference">故障排除快速参考</a>以了解设置和常见问题。</p>
<h2 id="stage-4">阶段 4：掌握 - 工具与高级工作流程的结合</h2>
<h3 id="15">第 15 步：工具选择策略</h3>
<h4 id="">何时使用每种工具</h4>
<p>那么，在你的工作流程中，什么时候应该使用每个工具呢？</p>
<p>当速度至关重要时，你可以将 GitHub Copilot 作为一名在线的结对程序员使用。它可以帮助你快速编写新函数、在输入时获得实时建议，并即时掌握不熟悉的 API 或框架。它也方便于在不中断你的工作流程的情况下快速查找文档。</p>
<p>然后，你可以转而使用 Claude Code 来处理更大、更复杂的任务：复杂的多文件重构、起草全面的测试以及“大声思考”关于架构和权衡的问题。在这里，它还可以帮助完成 Git 任务，比如指导你进行操作和组装拉取请求。</p>
<p>最后，当需要端到端分析大型代码库或将视觉输入（如截图/图表）整合到工作流程中时，可以从终端调用 Gemini CLI。由于可以免费使用，所以适合大量运行的场景，并且它适用于需要可定制、脚本友好的设置的场合。</p>
<h3 id="16mcpai">第 16 步：理解 MCP —— 让 AI 工具协同工作</h3>
<h4 id="mcp">什么是 MCP？</h4>
<p>MCP（模型上下文协议）是一种让你的 AI 工具增强能力的简单方法。可以把它想象成给你的手机增添应用程序——每个 MCP 服务器都会为你的 AI 增加新的功能。</p>
<h4 id="mcp">为什么初学者需要关注 MCP？</h4>
<p>没有 MCP 会遇到的问题是：你的 AI 只能处理它所知道的和你告诉它的内容。它无法：</p>
<ul>
<li>
<p>搜索网络上的当前信息</p>
</li>
<li>
<p>自动测试你的网站</p>
</li>
<li>
<p>在会话之间记住你的项目细节</p>
</li>
<li>
<p>连接到你的数据库或 API</p>
</li>
</ul>
<p>但有了 MCP 服务器，你的 AI 就能突然：</p>
<ul>
<li>
<p><strong>获取当前信息</strong> —— 从 Google 搜索最新的文档和解决方案</p>
</li>
<li>
<p><strong>测试你的代码</strong> —— 自动检查你的网站是否正常工作</p>
</li>
<li>
<p><strong>记住你的项目</strong> —— 跟踪你的架构和决策</p>
</li>
<li>
<p><strong>连接到工具</strong> —— 使用 GitHub、数据库等</p>
</li>
</ul>
<p>所以，相比于手动重复劳动，你的 AI 可以自动处理这些任务。这意味着你将花更少的时间去谷歌搜索错误消息、手动测试代码，以及在每个会话中向 AI 解释你的项目，而是花更多时间实际构建东西。</p>
<h4 id="mcp">初学者简单的 MCP 示例</h4>
<p>以下是 MCP 能为你做的一些初学者友好的示例：</p>
<p><strong>示例 1：无需谷歌搜索的帮助</strong></p>
<pre><code>你：“这个 CSS 不工作。找出原因并修复它”

没有 MCP：你需要谷歌搜索错误，阅读文档，尝试解决方案
有了 MCP：AI 搜索当前的 CSS 文档，找出问题，并自动修复
</code></pre>
<p><strong>示例 2：自动测试你的网站</strong></p>
<pre><code>你：“检查我的联系表单是否正常工作”

没有 MCP：你需要手动填写表单，检查邮件，测试边缘案例
有了 MCP：AI 填写表单，确认邮件已发送，测试不同的输入
</code></pre>
<p><strong>示例 3：AI 记住你的项目</strong></p>
<pre><code>你：“为我的待办事项应用程序添加一项新功能”

没有 MCP：你需要解释数据库结构、API 路线、前端框架
有了 MCP：AI 已记住一切并直接构建功能
</code></pre>
<h4 id="mcp">准备尝试 MCP 吗？</h4>
<p>如果这看起来很复杂，不用担心！你可以从一个简单的 MCP 服务开始，在适应后再添加更多。</p>
<h4 id="mcp">初学者简单的 MCP 设置</h4>
<p>我们将从 VS Code 开始（因为这是最简单的选项）：</p>
<ol>
<li>
<p>打开 VS Code</p>
</li>
<li>
<p>转到扩展（Ctrl+Shift+X）</p>
</li>
<li>
<p>搜索“GitHub Copilot MCP”或类似的 MCP 扩展</p>
</li>
<li>
<p>点击“安装”</p>
</li>
</ol>
<p>这样就完成了！扩展会自动处理一切。</p>
<p>通过这样做，你可以为你的 AI 获取网络搜索功能、基本项目记忆力和简单的自动化功能。</p>
<p>要测试它，试着让你的 AI：“搜索最新的 React 最佳实践并给我一个示例”。 如果它能搜索并返回当前的信息，MCP 就正常工作了！</p>
<h4 id="mcp">想要更多的 MCP 功能吗？</h4>
<p>一旦你适应了基本的 MCP，可以探索下面更高级的设置：</p>
<ul>
<li>
<p>自定义 MCP 服务器安装</p>
</li>
<li>
<p>高级配置选项</p>
</li>
<li>
<p>构建自己的 MCP 集成</p>
</li>
</ul>
<p>目前，上述的 VS Code 扩展方法将为你提供充足的 AI 超能力以便入门！</p>
<p>**这就是 MCP 的精要！**从上面的简单 VS Code 扩展方法开始，你将迅速看到你的 AI 变得多么强大。</p>
<h4 id="">下一步</h4>
<ul>
<li>
<p>尝试基础的 VS Code MCP 扩展</p>
</li>
<li>
<p>使用简单的请求进行测试，比如“搜索 X 并实现它”</p>
</li>
<li>
<p>熟悉后，探索更多的第 4 阶段 MCP 服务器</p>
</li>
</ul>
<p>MCP 将你的 AI 从代码建议工具转变为真正的开发伙伴。最好的部分是？一旦你用一个工具设置好，它就会与所有工具协同工作！</p>
<p>如果 AI 提示无法搜索网络，可以尝试以下几种方法。</p>
<p>首先，检查 MCP 扩展是否确实安装在 VS Code 中。然后尝试重启 VS Code。最后，要确保你的提问方式是 AI 能理解的，比如：“搜索 X 并展示 Y”。</p>
<p>如果 VS Code 扩展无法安装，尝试检查你的网络连接或将 VS Code 更新到最新版本。你也可以尝试使用不同名称搜索“MCP”或“Model Context Protocol”扩展。</p>
<p>如果仍然遇到问题，我们将在下文中介绍高级故障排除方法。或者你也可以询问你的 AI：“帮助我排查 MCP 设置故障”。</p>
<h3 id="mcp">高级 MCP 设置与集成</h3>
<h4 id="mcp">手动 MCP 服务器安装</h4>
<p>对于希望完全控制其 MCP 设置的高级用户：</p>
<p><strong>步骤 1：安装 MCP 服务器</strong></p>
<p>大多数 MCP 服务器可以通过 npm 安装：</p>
<pre><code># 用于网络自动化和测试
npm install -g @modelcontextprotocol/server-puppeteer

# 用于无需 API 密钥的网络搜索
npm install -g @mcp-servers/duckduckgo

# 用于数据库访问
npm install -g @modelcontextprotocol/server-postgres
</code></pre>
<p>某些服务器（如 GitHub）则使用 Docker：</p>
<pre><code>docker pull ghcr.io/github/github-mcp-server
</code></pre>
<p><strong>步骤 2：配置你的工具</strong></p>
<p><strong>理解层次化配置：</strong></p>
<p>每个 AI 工具在多个位置检查 MCP 配置，更具体的设置优先级高于一般设置。这意味着你可以有全局默认值，但可以针对特定项目进行覆盖。这就像 CSS——更具体的规则覆盖一般规则。</p>
<p><strong>Claude Code 具有最灵活的设置：</strong></p>
<p>Claude Code 配置层次结构（按顺序检查）：</p>
<ol>
<li>
<p><strong>项目级别</strong>：<code>.claude/mcp.json</code>（最高优先级）</p>
</li>
<li>
<p><strong>本地设置</strong>：<code>.claude/settings.local.json</code></p>
</li>
<li>
<p><strong>全局配置</strong>：<code>~/.claude/mcp.json</code>（后备）</p>
</li>
</ol>
<p>其他工具：</p>
<ul>
<li>
<p><strong>VS Code</strong>：<code>.vscode/mcp.json</code>（仅项目级别）</p>
</li>
<li>
<p><strong>Cursor</strong>：<code>.cursor/mcp.json</code>（仅项目级别）</p>
</li>
<li>
<p><strong>Windsurf</strong>：使用 VS Code 的配置格式</p>
</li>
</ul>
<p>以下是一个示例配置（适用于任何工具，只需调整文件位置）：</p>
<pre><code>{
  "mcpServers": {
    "puppeteer": {
      "command": "npx",
      "args": ["@modelcontextprotocol/server-puppeteer"]
    },
    "duckduckgo": {
      "command": "npx",
      "args": ["@mcp-servers/duckduckgo"]
    },
    "github": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e",
        "GITHUB_PERSONAL_ACCESS_TOKEN",
        "ghcr.io/github/github-mcp-server"
      ],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "your_token_here"
      }
    }
  }
}
</code></pre>
<h4 id="mcp">生产环境 MCP 服务器</h4>
<p><strong>1. 颠覆性认知工具：</strong></p>
<p><strong>序列思维服务器：</strong><br>
该服务器通过将复杂问题分解为逻辑步骤来改变 AI 处理复杂问题的方式。当你要求实现一个大型功能时，AI 不会直接跳到代码实施，而是首先创建一个详细的计划，其中包含阶段、依赖关系和决策点。</p>
<p>这对于重构遗留系统或构建新功能来说是无价的，尤其是在操作顺序很重要的情况下。服务器在整个开发会话期间保持这种规划上下文，确保决策的一致性。</p>
<p><strong>记忆库服务器：</strong><br>
消除了每次会话都需要重新解释项目结构的烦恼。该服务器会创建有关你的架构选择、编码标准、团队偏好和项目目标的持久性记忆。当你几天后返回工作时，AI 可以立即知道你的数据库架构、API 模式，甚至为什么做出某些决策。它就像一个随着你的开发工作完美同步的项目文档系统。</p>
<p><strong>知识图谱服务器：</strong><br>
创建代码库关系的动态地图——不仅仅是文件依赖，还有功能、共享工具和架构模式之间的概念连接。当你修改一个组件时，AI 可以立即识别出可能需要更新的所有相关区域。这可以防止由于遗漏相关更改而导致的错误，并有助于重构期间的影响分析。</p>
<p><strong>2. 网页自动化与测试服务器：</strong></p>
<p><strong>Puppeteer Server：</strong><br>
提供无头浏览器的控制，用于综合测试工作流。AI 可以自动浏览你的 Web 应用程序，填写表单、点击按钮，并验证预期行为。</p>
<p>这在回归测试中特别强大——AI 可以重播用户工作流并在部署前捕获更改。此外，它还启用基于截图的测试和性能监控自动化。</p>
<p><strong>Playwright Server：</strong><br>
同时扩展 Chrome、Firefox 和 Safari 浏览器的自动化功能。该服务器对于跨浏览器兼容性测试至关重要，并允许 AI 在开发初期捕获特定浏览器的问题。</p>
<p>与手动测试不同，AI 可以在所有浏览器上并行运行相同的测试场景，生成关于功能和性能差异的比较报告。</p>
<p><strong>3. 开发集成服务器：</strong></p>
<p><strong>GitHub Server：</strong><br>
将终端转变为具有 AI 智能的完整 GitHub 界面。AI 可以自动创建分支、管理拉取请求、分析代码审查评论，甚至根据代码更改生成 PR 描述。它还可以根据内容分析分配标签，并通过理解问题与实际代码更改之间的关系来维护项目板。</p>
<p><strong>PostgreSQL 服务器：</strong><br>
支持直接的数据库分析和优化。人工智能可以检查查询性能、建议索引优化、分析数据模式，甚至生成迁移脚本。此服务器在调试生产问题时特别有价值，因为人工智能需要理解实际的数据分布和查询执行模式，而不仅仅是理论上的数据库设计。</p>
<p><strong>4. 辅助工具：</strong></p>
<p><strong>MCP Compass</strong><br>
帮助您为任何任务找到合适的 MCP 服务器。</p>
<p>这些服务器将您的人工智能从代码建议者转变为能够测试、搜索、记忆和自动化的真正开发合作伙伴！</p>
<h3 id="17">步骤 17：高级提示工程</h3>
<h4 id="">上下文提示</h4>
<p>提供示例：</p>
<pre><code>// 替代用语："创建一个验证函数"
// 使用："创建一个类似这样的验证函数但用于电子邮件：
// function validatePhone(phone) { return /^\d{10}$/.test(phone); }"
</code></pre>
<p>指定约束条件：</p>
<pre><code>claude "将此代码重构为使用函数式编程，不使用循环，使用 map/filter/reduce"
</code></pre>
<p>包括边缘案例：</p>
<pre><code>gemini -p "实现用户认证，处理以下情况：过期令牌、并发登录、速率限制"
</code></pre>
<h3 id="18ai">步骤 18：构建 AI 辅助开发流水线</h3>
<h4 id="">自动化代码审查流水线</h4>
<ol>
<li>使用 Copilot 进行预提交检查：</li>
</ol>
<pre><code>// .copilot-instructions
"审核所有更改以发现：安全问题、性能问题、代码风格"
</code></pre>
<ol start="2">
<li>使用 Claude 进行 PR 审查：</li>
</ol>
<pre><code>claude "审查此 PR：git diff main..feature-branch"
</code></pre>
<ol start="3">
<li>使用 Gemini 完成文档：</li>
</ol>
<pre><code>gemini -p "为这些更改生成更新日志并更新 README"
</code></pre>
<h4 id="ai">测试驱动的 AI 开发</h4>
<ol>
<li>编写测试规范：</li>
</ol>
<pre><code>claude "为支付处理系统编写全面的测试规范"
</code></pre>
<ol start="2">
<li>生成测试代码：</li>
</ol>
<pre><code>gemini -p "使用 Jest 实现这些测试规范"
</code></pre>
<ol start="3">
<li>
<p>使用 Copilot 实现：</p>
<ul>
<li>
<p>使用代理模式实现功能</p>
</li>
<li>
<p>测试指导实现过程</p>
</li>
</ul>
</li>
</ol>
<h3 id="19ai">步骤 19：创建您的个人 AI 工作流</h3>
<h4 id="">设置您的环境</h4>
<p>1. VS Code 设置（<code>settings.json</code>）：</p>
<pre><code>{
  "github.copilot.enable": {
    "*": true
  },
  "github.copilot.advanced": {
    "inlineCompletions.enable": true,
    "chat.enabled": true
  }
}
</code></pre>
<p>2. Claude 代码配置（<code>~/.claude/settings.json</code>）：</p>
<pre><code>{
  "cleanupPeriodDays": 7,
  "permissions": {
    "allow": [
      "Bash(fd:*)",
      "Bash(rg:*)",
      "Bash(ls:*)",
      "WebFetch(domain:github.com)",
      "WebFetch(domain:stackoverflow.com)"
    ],
    "deny": ["WebFetch(domain:medium.com)"]
  }
}
</code></pre>
<p>3. Gemini 设置（<code>~/.gemini/config.json</code>）：</p>
<pre><code>{
  "defaultModel": "gemini-2.5-pro",
  "contextWindow": "large",
  "safetyMode": "interactive"
}
</code></pre>
<h4 id="">自定义命令和别名</h4>
<p>为常见任务设置 Shell 别名：</p>
<pre><code># 启动互动会话
alias cc='claude'
alias gc='gemini'

# 快速一次性命令（在需要时）
alias aicommit='claude "创建一个带有描述性信息的 git 提交"'
alias aireview='claude "审查我的未提交更改"'
alias complexity='gemini -p "分析代码复杂性并建议简化"'
alias security='claude "更深入思考：检查安全漏洞"'
alias aidocs='gemini -p "生成全面的文档"'
</code></pre>
<h3 id="ai">最终项目：构建一个完整的应用程序与 AI</h3>
<h4 id="">项目要求</h4>
<p>构建一个任务管理 API，具备：</p>
<ul>
<li>
<p>用户认证</p>
</li>
<li>
<p>CRUD 操作</p>
</li>
<li>
<p>实时更新</p>
</li>
<li>
<p>测试套件</p>
</li>
<li>
<p>文档</p>
</li>
</ul>
<h4 id="">建议工作流程</h4>
<p>阶段 1：互动规划</p>
<pre><code># 启动 Claude 代码会话
claude

Claude Code &gt; 超级思考：设计一个可扩展的任务管理 API 架构

[Claude 提供详细分析]

Claude Code &gt; 现在将其分解为实施阶段

# 切换到 Gemini 进行规格说明
gemini

Gemini &gt; 为此任务管理 API 创建详细的技术规格

Gemini &gt; 包括数据库架构和 API 端点规格
</code></pre>
<p>阶段 2：互动实现</p>
<ol>
<li>
<p>使用 Copilot 代理模式进行初始设置</p>
</li>
<li>
<p>使用内联 Copilot 实现功能</p>
</li>
<li>
<p>切换到互动 Claude 代码会话处理复杂逻辑：</p>
</li>
</ol>
<pre><code>Claude Code &gt; 实施我们计划的用户认证系统

Claude Code &gt; 现在添加任务 CRUD 操作

Claude Code &gt; 用 WebSockets 集成实时更新
</code></pre>
<p>阶段 3：互动测试与文档</p>
<pre><code># Claude 代码会话用于测试
claude

Claude Code &gt; 为所有 API 端点编写全面测试

Claude Code &gt; 为身份验证流程添加集成测试

Claude Code &gt; 为高负载场景创建性能测试

# Gemini 生成文档
gemini

Gemini &gt; 生成包含示例的全面 API 文档

Gemini &gt; 创建开发者入职指南
</code></pre>
<p>阶段 4：互动优化</p>
<pre><code># Claude 代码进行性能优化
claude

Claude Code &gt; 分析并优化我们的数据库查询

Claude Code &gt; 为经常访问的数据实现缓存

Claude Code &gt; 添加监控和日志

# Gemini 进行最终审查
gemini

Gemini &gt; 审查整个代码库以进行改进
</code></pre>
<h3 id="">衡量你的进展</h3>
<h4 id="1">阶段 1 里程碑</h4>
<ul>
<li>
<p>熟悉标签补全</p>
</li>
<li>
<p>可以编写有效的提示语</p>
</li>
<li>
<p>理解 AI 的局限性</p>
</li>
</ul>
<h4 id="2">阶段 2 里程碑</h4>
<ul>
<li>
<p>有效使用多个模型</p>
</li>
<li>
<p>掌握聊天模式和代理</p>
</li>
<li>
<p>使用高级聊天功能</p>
</li>
</ul>
<h4 id="3">阶段 3 里程碑</h4>
<ul>
<li>
<p>熟练使用 CLI 工具</p>
</li>
<li>
<p>可以将 VS Code 和终端工作流结合起来</p>
</li>
<li>
<p>了解工具的优势</p>
</li>
</ul>
<h4 id="4">阶段 4 里程碑</h4>
<ul>
<li>
<p>创建自定义 AI 工作流</p>
</li>
<li>
<p>使用 AI 构建完整应用程序</p>
</li>
<li>
<p>可以教别人 AI 辅助开发</p>
</li>
</ul>
<h3 id="4">阶段 4 练习</h3>
<h4 id="1">练习 1：掌握工具选择</h4>
<ol>
<li>
<p>选择一个中等复杂的编码任务（例如，“构建一个 URL 缩短服务 API”）</p>
</li>
<li>
<p>计划每个阶段使用的工具（设计、编码、测试、部署）</p>
</li>
<li>
<p>按照你选择的工作流程执行</p>
</li>
<li>
<p>记录哪些工作顺利，哪些需要改进</p>
</li>
</ol>
<h4 id="2">练习 2：创建自定义工作流</h4>
<ol>
<li>
<p>识别工作中的重复性开发任务</p>
</li>
<li>
<p>设计一个使用多个工具的 AI 辅助工作流</p>
</li>
<li>
<p>测试并改进该工作流</p>
</li>
<li>
<p>为团队同事创建相关文档</p>
</li>
</ol>
<h4 id="3">练习 3：完整项目构建</h4>
<ol>
<li>
<p>使用 AI 辅助构建一个小型但完整的应用程序</p>
</li>
<li>
<p>战略性地使用至少两种不同 AI 工具</p>
</li>
<li>
<p>包括测试、文档和部署</p>
</li>
<li>
<p>反思比起传统开发的效率提升</p>
</li>
</ol>
<h3 id="">继续你的旅程</h3>
<h4 id="">持续更新</h4>
<ul>
<li>
<p>关注工具的更新说明</p>
</li>
<li>
<p>加入 AI 编码社区</p>
</li>
<li>
<p>试验新功能</p>
</li>
</ul>
<h4 id="">探索高级主题</h4>
<ul>
<li>
<p>自定义 MCP 服务器开发</p>
</li>
<li>
<p>AI 模型微调</p>
</li>
<li>
<p>企业部署策略</p>
</li>
<li>
<p>团队协作模式</p>
</li>
</ul>
<h4 id="">持续学习资源</h4>
<ul>
<li>
<p>每个工具的官方文档</p>
</li>
<li>
<p>社区论坛和 Discord 服务器</p>
</li>
<li>
<p>开源 AI 编码项目</p>
</li>
<li>
<p>会议演讲和教程</p>
</li>
</ul>
<h2 id="common-ai-issues">常见 AI 问题</h2>
<p>即便使用最好的 AI 工具，你仍会遇到挑战。一旦你了解模式，这些问题是正常且可管理的。以下是开发者面临的最常见问题以及实际可行的解决方案。</p>
<h3 id="ai">“我的 AI 建议很糟！”</h3>
<p><strong>问题：</strong> AI 给出的建议无关或错误</p>
<p><strong>解决方案：</strong></p>
<ul>
<li>
<p>写更清晰的注释</p>
</li>
<li>
<p>打开相关文件以提供上下文</p>
</li>
<li>
<p>从简单任务开始</p>
</li>
<li>
<p>确保你在正确的文件类型中</p>
</li>
</ul>
<p><strong>示例修正：</strong></p>
<pre><code>// 原先: "make function"
// 尝试: "create function to validate US phone number format (xxx) xxx-xxxx"
</code></pre>
<h3 id="ai">“AI 太慢”</h3>
<p><strong>问题：</strong> 等待建议时间过长</p>
<p><strong>解决方案：</strong></p>
<ul>
<li>
<p>检查你的网络连接</p>
</li>
<li>
<p>关闭不必要的程序</p>
</li>
<li>
<p>尝试较轻量级的 AI 工具</p>
</li>
<li>
<p>要有耐心 —— 复杂建议需要时间</p>
</li>
</ul>
<h3 id="ai">“我害怕过于依赖 AI”</h3>
<p><strong>问题：</strong> 担心丧失编码能力</p>
<p><strong>解决方案：</strong></p>
<ul>
<li>
<p>将 AI 作为学习工具，而非依赖的工具</p>
</li>
<li>
<p>在接受之前务必理解代码</p>
</li>
<li>
<p>定期练习不使用 AI 编码</p>
</li>
<li>
<p>专注于解决问题，而非语法</p>
</li>
</ul>
<h3 id="">“它建议使用过时代码”</h3>
<p><strong>问题：</strong> AI 建议的模式老旧或使用了废弃的方法</p>
<p><strong>解决方案：</strong></p>
<ul>
<li>
<p>在注释中指定版本</p>
</li>
<li>
<p>保持工具的更新</p>
</li>
<li>
<p>学会识别过时的模式</p>
</li>
</ul>
<p><strong>示例：</strong></p>
<pre><code>// create React functional component using hooks (not class component)
</code></pre>
<h3 id="">故障排除快速参考</h3>
<h4 id="">常见问题（所有工具）</h4>
<table>
<thead>
<tr>
<th><strong>问题</strong></th>
<th><strong>快捷修复</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>没有 AI 建议</td>
<td>检查网络连接，重启编辑器，验证登录</td>
</tr>
<tr>
<td>“需要付款”消息</td>
<td>检查免费层限制，验证账户状态</td>
</tr>
<tr>
<td>建议效果差</td>
<td>使用更清晰的注释，打开相关文件提供上下文</td>
</tr>
<tr>
<td>工具无法安装</td>
<td>更新编辑器，检查网络，尝试不同安装方法</td>
</tr>
</tbody>
</table>
<h4 id="githubcopilot">GitHub Copilot 问题</h4>
<table>
<thead>
<tr>
<th><strong>问题</strong></th>
<th><strong>解决方案</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>VS Code 无建议</td>
<td>检查右下角“GitHub Copilot”状态</td>
</tr>
<tr>
<td>免费层过期</td>
<td>查看 <a href="https://docs.github.com/en/copilot/how-tos/manage-your-account/getting-free-access-to-copilot-pro-as-a-student-teacher-or-maintainer">学生/维护者免费访问</a></td>
</tr>
<tr>
<td>代理模式不起作用</td>
<td>尝试 <code>Shift+Cmd+I</code>（Mac）或 <code>Ctrl+Shift+I</code>（Windows/Linux）</td>
</tr>
<tr>
<td>聊天无响应</td>
<td>尝试重启 VS Code，检查网络连接</td>
</tr>
</tbody>
</table>
<h4 id="claudecode">Claude Code 问题</h4>
<table>
<thead>
<tr>
<th><strong>问题</strong></th>
<th><strong>解决方案</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>“命令未找到”</td>
<td>重新安装：<code>npm uninstall -g @anthropic-ai/claude-code &amp;&amp; npm install -g @anthropic-ai/claude-code</code></td>
</tr>
<tr>
<td>认证失败</td>
<td>运行 <code>claude auth login</code>，检查剩余 API 信用额度</td>
</tr>
<tr>
<td>响应缓慢</td>
<td>网络检查：<code>ping api.anthropic.com</code>，尝试轻量模型：<code>--model claude-3-haiku</code></td>
</tr>
<tr>
<td>MCP 服务器不起作用</td>
<td>检查 <code>~/.claude/mcp.json</code> 语法，测试服务器：<code>npx @mcp/server-github --help</code></td>
</tr>
<tr>
<td>命令挂起/卡住</td>
<td>按 <code>Ctrl+C</code> 取消，重启终端，检查后台进程</td>
</tr>
</tbody>
</table>
<h4 id="geminicli">Gemini CLI 问题</h4>
<table>
<thead>
<tr>
<th><strong>问题</strong></th>
<th><strong>解决方案</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>需要认证</td>
<td>运行 <code>gemini auth login</code>，检查 Google 账户权限</td>
</tr>
<tr>
<td>超过速率限制</td>
<td>检查使用情况：<code>gemini /stats</code>，等待 1 分钟或升级计划</td>
</tr>
<tr>
<td>无法安装</td>
<td>尝试 <code>npx @google/gemini-cli</code>，检查 Node.js 16+</td>
</tr>
<tr>
<td>图片上传失败</td>
<td>检查格式（JPG/PNG/WebP），大小小于 20MB，验证文件路径</td>
</tr>
<tr>
<td>上下文窗口错误</td>
<td>将大请求分割成小部分，清除历史记录</td>
</tr>
</tbody>
</table>
<p>如果一切无效，请按顺序尝试以下方法：</p>
<ol>
<li>
<p>重启你的编辑器/终端</p>
</li>
<li>
<p>检查互联网连接</p>
</li>
<li>
<p>确认你已登录到正确的账户</p>
</li>
<li>
<p>更新工具至最新版本</p>
</li>
<li>
<p>尝试不同的工具（如果一个失败了，通常其他的会有效）</p>
</li>
<li>
<p>询问 AI 自己：“帮助我排查 troubleshoottool_tool_setup”</p>
</li>
</ol>
<h2 id="whats-next-after-completing-all-stages">完成所有阶段后有哪些后续步骤？</h2>
<p>一旦你掌握了基础知识，这里有一些简单的后续步骤：</p>
<h3 id="">与团队合作</h3>
<h4 id="ai">团队 AI 工作流基础</h4>
<p><strong>共享提示库：</strong></p>
<p>构建团队提示库可以改变你整个团队使用 AI 的方式。首先创建一个共享的仓库，让开发者记录适用于你特定领域和代码库的有效提示。</p>
<p>例如，如果你正在构建电子商务软件，为常见任务创建标准化提示，如“生成符合我们 REST 约定的产品目录 API 端点”或“使用我们的标准模式创建支付处理错误处理”。</p>
<p>记录成功的代理模式工作流供团队成员重复使用。某位开发者可能会发现 Claude Code 在给定有关模式演化实践的特定上下文时，特别适合数据库迁移。通过共享这些工作流，你可以避免每个团队成员独立地发现有效的方法。</p>
<p><strong>工具标准化：</strong></p>
<p>当每个人都使用兼容的 AI 工具时，团队生产力会倍增。根据团队的需要确定主要工具——例如，所有开发者都使用 GitHub Copilot，以确保一致的内联支持，再加上 Claude Code 以处理需要深入推理的复杂架构任务。制定清晰的指南，规定何时使用自主的代理模式与协作会话，以防止冲突并确保代码质量。</p>
<p>配置共享的 MCP 服务器设置，以便所有团队成员都能访问相同的增强型 AI 功能。这可能包括内部 API 的团队专用服务器、共享数据库访问或了解你的部署管道的定制工具。当每个人都拥有相同的 AI 功能时，协作就会变得顺畅无比。</p>
<p><strong>AI 生成的代码审查：</strong></p>
<p>将你的代码审查过程转变为与 AI 生成的代码有效协作。为在拉取请求中标记 AI 生成的部分建立惯例——这有助于审查者将注意力集中在适当的地方。审查者可以专注于架构决策、业务逻辑正确性和需要人工判断的集成模式，而不是挑剔 AI 通常处理得很好的语法。</p>
<p>对 AI 生成的代码实施严格的测试，因为自动化测试比手动审查更可靠地捕捉 AI 错误。为测试 AI 输出创建团队标准，包括 AI 可能遗漏的边缘案例和集成场景。这样你就能在享受 AI 带来的速度的同时，通过系统的验证保持质量。</p>
<p><strong>在提交信息中记录 AI 工具决策。</strong></p>
<h4 id="">简单的团队设置</h4>
<p>从小处着手，逐步建立：</p>
<ul>
<li>
<p>首先让每个人使用相同的 AI 工具</p>
</li>
<li>
<p>创建一个适合你项目的提示共享文档</p>
</li>
<li>
<p>找出团队何时应该使用代理模式与常规协助模式</p>
</li>
<li>
<p>为你最重要的团队工具设置 MCP 服务器</p>
</li>
</ul>
<h3 id="">对于更大的项目</h3>
<p>随着项目的发展，你可能会想要：</p>
<ul>
<li>
<p>为不同的任务尝试不同的 AI 模型（简单代码用快速的，复杂问题用强大的）</p>
</li>
<li>
<p>为你经常执行的任务创建快捷方式</p>
</li>
<li>
<p>将 AI 工具与现有开发工作流连接</p>
</li>
</ul>
<h3 id="">持续学习</h3>
<p>AI 编码工具每个月都在进步！通过以下方式保持最新：</p>
<ul>
<li>
<p>关注工具的发行说明（他们会发送更新邮件）</p>
</li>
<li>
<p>加入 AI 编码的 Discord 社区</p>
</li>
<li>
<p>尝试新功能，因为它们不断出现</p>
</li>
</ul>
<h2 id="conclusion">结语</h2>
<p>恭喜你！你现在已经拥有了开启 AI 辅助编码之旅的所有必需品。记住，每个专家都曾是初学者，而有 AI 作为你的编码伙伴，你可以比以往更快地学习和成长。</p>
<p><strong>记住：</strong></p>
<ul>
<li>
<p>AI 不会取代你的创造力——它会放大创造力</p>
</li>
<li>
<p>每个建议都是一次学习的机会</p>
</li>
<li>
<p>错误是旅程的一部分</p>
</li>
<li>
<p>社区在这里帮助你</p>
</li>
</ul>
<p>你不仅仅是在学习用 AI 编码——你是在了解软件开发的未来。几个月后，你会想知道自己过去是如何在没有它的情况下编码的。今天拥抱 AI 辅助的开发者将成为明日的领袖。</p>
<p>Happy coding! 🚀</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 来自 freeCodeCamp 社区的圣诞礼物：学习 Python、SQL、西班牙语等课程 ]]>
                </title>
                <description>
                    <![CDATA[ 2025 年对全球 freeCodeCamp 社区来说是精彩纷呈的一年。我们非常激动地以一系列圣诞礼物为这一年画上圆满句号：  1. freeCodeCamp Python 认证  2. freeCodeCamp JavaScript 认证（第 10 版）  3. freeCodeCamp 响应式 Web 设计认证（第 10 版）  4. freeCodeCamp 关系型数据库 + SQL 认证  5. 我们的 A2 级开发者英语认证  6. 我们的 B1 级开发者英语认证  7. 我们的 A1 级西班牙语课程（测试版）  8. 我们的 A1 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/christmas-gifts-freecodecamp-community-2025/</link>
                <guid isPermaLink="false">694b60661acf9a04cd95df3e</guid>
                
                    <category>
                        <![CDATA[ 社区 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Wed, 24 Dec 2025 05:29:57 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/12/----_20251224114011_141_113.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/christmas-gifts-freecodecamp-community-2025/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Christmas gifts for you from the freeCodeCamp community: Learn Python, SQL, Spanish, and more</a>
      </p><p>2025 年对全球 freeCodeCamp 社区来说是精彩纷呈的一年。我们非常激动地以一系列圣诞礼物为这一年画上圆满句号：</p><ol><li>freeCodeCamp Python 认证</li><li>freeCodeCamp JavaScript 认证（第 10 版）</li><li>freeCodeCamp 响应式 Web 设计认证（第 10 版）</li><li>freeCodeCamp 关系型数据库 + SQL 认证</li><li>我们的 A2 级开发者英语认证</li><li>我们的 B1 级开发者英语认证</li><li>我们的 A1 级西班牙语课程（测试版）</li><li>我们的 A1 级中文课程（测试版）</li></ol><p>如此丰厚的礼物，我们开始拆封吧！</p><h2 id="-10-">编程认证与全栈开发课程第 10 版</h2><p>在过去的 11 年里，freeCodeCamp 社区对核心编程课程体系进行了多次构建与重构。</p><p>如今我们终于实现编程课程兼具全面性与互动性的愿景。</p><p>第 10 版课程包含 6 项认证，每项认证都包含十余个实践项目，帮助你扎实掌握核心技能。</p><!--kg-card-begin: markdown--><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766529240482/d07520b2-ba51-427d-a053-403381c4d185.webp" alt="我们刚刚发布的 Python 课程的截图" class="image--center mx-auto" width="1654" height="1446" loading="lazy"><!--kg-card-end: markdown--><p>在每项认证结束时，你将参加一次期末考试。如果你能通过考试，将获得一份免费的认证证书。你可以将此证书加入 LinkedIn 个人资料，或添加到你的简历、履历或个人作品集网站中。</p><p>截至目前，已有 4 项认证正式上线：</p><ul><li><a href="https://www.freecodecamp.org/news/freecodecamps-new-responsive-web-design-certification-is-now-live/">响应式 Web 设计认证发布</a></li><li><a href="https://www.freecodecamp.org/news/freecodecamps-new-javascript-certification-is-now-live/">JavaScript 认证发布</a></li><li><a href="https://www.freecodecamp.org/news/freecodecamps-new-python-certification-is-now-live/">Python 认证发布</a></li><li><a href="https://www.freecodecamp.org/news/freecodecamps-new-relational-databases-certification-is-now-live/">关系型数据库认证发布</a></li></ul><p>我们将在 2026 年发布前端库认证与后端开发认证。</p><p>在获得全部 6 项认证后，你可以构建一个最终的毕业项目，该项目将由经验丰富的开发者进行代码审查。随后你将参加综合期末考试，通过后即可获得我们最终的全栈开发工程师认证。</p><p>如果你现在就开始学习前四项认证，那么在你学完之前，后两项认证也会发布了。毕竟，每项认证都涵盖了数百小时的理论计算机科学知识和动手编程实践。</p><h2 id="-">语言课程</h2><p>你可能会问：freeCodeCamp 是从何时开始教授世界语言的？</p><p>实际上，我们从 2022 年就开始设计“开发者英语”课程体系。在过去的几年间，我们对其进行了大幅扩展。</p><p>该课程通过手绘动画角色进行互动教学。在学习过程中，你将进行大量的阅读、写作、听力练习，口语练习功能也将在 2026 年上线。</p><!--kg-card-begin: markdown--><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766527685142/e1cc58c5-a245-4777-b2cf-b97dd7790d27.webp" alt="语言学习的 6 个 CEFR 级别图表" class="image--center mx-auto" width="1024" height="768" loading="lazy"><!--kg-card-end: markdown--><p>这是一套以故事驱动的课程体系。你将化身为一位刚抵达加利福尼亚、即将加入科技初创企业的开发者，在新生活的日常互动中，你将逐步掌握语法、词汇、技术术语乃至地道俚语。</p><!--kg-card-begin: markdown--><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766527748381/abc33dff-e9bf-4efb-bd4c-46362e42f288.webp" alt="开发者英语课程的截图" class="image--center mx-auto" width="856" height="656" loading="lazy"><!--kg-card-end: markdown--><p>截至目前，已有两项语言认证正式上线：</p><ul><li><a href="https://www.freecodecamp.org/news/freecodecamps-a2-english-for-developers-certification-is-now-live/">A2 级别英语认证发布</a></li><li><a href="https://www.freecodecamp.org/news/freecodecamps-b1-english-for-developers-certification-is-now-live/">B1 级别英语认证发布</a></li></ul><p>我们正在开发 A1、B2、C1 和 C2 级别的课程，计划在未来几年陆续发布（是的，以年为单位。每个级别的开发都是庞大的工程）。</p><p>freeCodeCamp 社区不仅设计了数千节英语课程，还开发了大量定制软件工具来实现这些课程体系。因此在 2024 年，我们提出设想：能否用同样的工具来教授西班牙语和中文普通话？</p><p>如今，这项努力的成果已进入公开测试阶段。我们从这两种语言的 A1 级别课程起步，其余级别将在未来几年逐步推出。</p><ul><li><a href="https://www.freecodecamp.org/news/freecodecamps-a1-professional-spanish-curriculum-beta-is-now-live/">A1 级别西班牙语课程发布</a></li><li><a href="https://www.freecodecamp.org/news/freecodecamps-a1-professional-chinese-curriculum-beta-is-now-live/">A1 级别中文课程发布</a></li></ul><h2 id="--1">为何教授西班牙语和中文？</h2><p>除英语外，西班牙语和中文（普通话）是全球使用最广泛的两种语言。掌握这些语言可帮助你参与众多网络社区、探访主要城市，甚至获得新的工作机会。</p><p>学习外语对大脑神经可塑性大有裨益，并且可以与编程等其他技能学习同步开展。</p><p>现在你可以通过我们完整的端到端课程体系免费学习这些语言，所有课程均由教师、译者和母语者共同设计。</p><h2 id="-freecodecamp-">关于将 freeCodeCamp 课程翻译为世界主要语言的进展</h2><p>你可能知道，freeCodeCamp 自 2020 年起已支持多种世界主要语言。但每当我们发布新课程时，全部内容的翻译仍需数月时间。</p><p>值得欣慰的是，机器翻译技术在过去几年持续进步。</p><p>社区仍在人工翻译教程和书籍，但对于 freeCodeCamp 编程课程这类更新迅速的内容，我们需要加速这一进程。</p><p>我们已试点将全部新课程翻译为西班牙语和葡萄牙语。</p><ul><li>首先运用前沿大语言模型，结合大量术语表和风格指南，处理编程课程中数十万词的原始内容，</li><li>随后由母语者随机抽样审校以保证质量。</li><li>当我们确认翻译质量达标后，便开始建立数据管道，通过开源代码贡献实现英文原文更新时的自动翻译同步。</li></ul><p>这些工作的经济成本并不高昂，因此我们应该能在此基础上，进一步将 freeCodeCamp 编程课程拓展到此前未能支持的其他语言，例如阿拉伯语和法语。</p><!--kg-card-begin: markdown--><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766528132885/06da1977-85b8-438e-8e80-1818f3dba7e7.webp" alt="freeCodeCamp 的编程课程被翻译为葡萄牙语的截图" class="image--center mx-auto" width="1017" height="918" loading="lazy"><!--kg-card-end: markdown--><p>如果你是多年来参与过 freeCodeCamp 翻译的数百位贡献者之一，我们依然非常欢迎你帮助翻译书籍和教程，这些内容在首次发布后通常不会有太大改动。</p><p>毕竟，文档本地化的最高标准是由一位译者完整阅读并理解原文后再进行翻译。</p><h2 id="--2">我们的社区才刚刚启航。</h2><p>今年，freeCodeCamp 社区还实现了：</p><ul><li>在 freeCodeCamp YouTube 频道上发布 129 个免费视频课程</li><li>在 freeCodeCamp 专栏上发布 45 本免费完整书籍和手册</li><li>452 篇关于数学、编程和计算机科学的教程和文章</li><li>50 集 freeCodeCamp 播客节目，我采访了许多开发者，其中许多人都是 freeCodeCamp 开源项目的贡献者</li></ul><p>我们还向 freeCodeCamp 开源学习平台合并了 4,279 次代码提交，这些更新大幅提升了用户体验与可访问性。同时我们发布了安全的考试环境，让 campers 能够参加认证考试。</p><p>你可以查看我们的 <strong><a href="https://www.freecodecamp.org/chinese/news/freecodecamp-2025-top-contributors/">2025 年度的顶级开源贡献者榜单</a></strong>。</p><p>作为一个社区，我们才刚刚起步。免费的开源教育在当今时代的意义前所未有地重大。</p><h2 id="--3">我们也邀请你更深入地参与社区。</h2><p>我要感谢每月支持我们的慈善事业与使命的 10,221 位热心人士。请考虑加入这个行列：<a href="https://www.freecodecamp.org/donate/">捐赠支持 freeCodeCamp.org</a>。</p><p>这里有其他几种<a href="https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/">可抵扣美国税款的年终捐赠方式</a>。</p><p>freeCodeCamp 拥有一个充满活力的全球社区，聚集了众多积极进取的学习者，他们正在掌握新技能并为职业发展的下一阶段做准备。我鼓励你<a href="https://discord.com/servers/freecodecamp-692816967895220344">加入 freeCodeCamp Discord 与我们交流互动</a>。</p><p>同时，请参与 <a href="https://forms.nhcarrigan.com/o/docs/forms/7LNb8jFoN4SPBvP7vRxDi2/4">Naomi 的 freeCodeCamp 社区调查</a>，帮助我们了解你喜爱 freeCodeCamp 的哪些方面，以及我们的社区可以在哪些方面做得更好。</p><p>我谨代表全球 freeCodeCamp 社区，祝愿你和家人在 2025 年收官之际一切圆满。也让我们共同举杯，迎接充满乐趣与雄心壮志的 2026 年。</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp A1 专业中文课程（测试版）上线 ]]>
                </title>
                <description>
                    <![CDATA[ freeCodeCamp 社区刚刚发布了我们新的 A1 专业中文课程的前几个章节。你现在可以利用这些内容开始学习中文。 每一章都包含数百个互动任务，旨在帮助你自信地迈出学习中文的第一步。 新的 A1 专业中文课程是怎样的？ 在这个 A1 专业中文课程中，你将学习中文的基础知识。这将遵循欧洲共同语言参考标准（CEFR）的 A1 要求。我们专注于在专业环境中特别有用的词汇。 课程包含多个模块，包括热身、学习、练习、复习和测验，以确保你真正理解了一个模块再进入下一个。 热身是准备部分，为模块的主要内容提供背景。 热身中的任务将向你介绍新词汇，或复习你已经学习过并将在当前模块中使用的内容。 下面是在课程中你将会遇到的一个示例。 每个任务都有一个相应的问题，帮助你练习内容。如果你不知道如何回答问题或需要更多细节，你可以查看解释部分。 在热身之后，你将进入学习 部分。在这里，你会看到你新学的单词在实际中的应用！你将聆听短片段的独白或对话，并回答关于它们的问题，以确保你理解它们的含义以及它们在真实对话中的使用方式。在必要时，你还将在这里学习一些理论。 课程中还包含填 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/freecodecamps-a1-professional-chinese-curriculum-beta-is-now-live/</link>
                <guid isPermaLink="false">694a9c8c1acf9a04cd95df2a</guid>
                
                    <category>
                        <![CDATA[ 社区 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 23 Dec 2025 05:55:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/12/----_20251224135437_142_113.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/freecodecamps-a1-professional-chinese-curriculum-beta-is-now-live/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">freeCodeCamp's A1 Professional Chinese Curriculum (Beta) is Now Live</a>
      </p><!--kg-card-begin: markdown--><p>freeCodeCamp 社区刚刚发布了我们新的 A1 专业中文课程的前几个章节。你现在可以利用这些内容开始学习中文。</p>
<p>每一章都包含数百个互动任务，旨在帮助你自信地迈出学习中文的第一步。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766158559146/126837fd-0786-476d-b643-1eed59e87814.png" alt="A1 专业中文课程大纲。章节包括欢迎、拼音课程，如简单韵母和鼻音韵母，以及问候和介绍。每个章节的完成状态均有显示。" width="848" height="595" loading="lazy"></p>
<h2 id="a1">新的 A1 专业中文课程是怎样的？</h2>
<p>在这个 A1 专业中文课程中，你将学习中文的基础知识。这将遵循欧洲共同语言参考标准（CEFR）的 A1 要求。我们专注于在专业环境中特别有用的词汇。</p>
<p>课程包含多个模块，包括热身、学习、练习、复习和测验，以确保你真正理解了一个模块再进入下一个。</p>
<p><strong>热身</strong>是准备部分，为模块的主要内容提供背景。</p>
<p>热身中的任务将向你介绍新词汇，或复习你已经学习过并将在当前模块中使用的内容。</p>
<p>下面是在课程中你将会遇到的一个示例。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766158665243/cb5a3d23-3626-4b12-aae0-829a3db7b7cf.png" alt="一个穿条纹毛衣的人在一个现代办公室设置的虚拟教室中。文字写道，“还记得一个音节有三个部分：声母、韵母和声调吗？这些部分的任何变化都可能表示完全不同的字符。”对话框显示“你好”的拼音和汉字。" width="960" height="647" loading="lazy"></p>
<p>每个任务都有一个相应的问题，帮助你练习内容。如果你不知道如何回答问题或需要更多细节，你可以查看解释部分。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1764863508777/7e6f988c-9bf7-454c-afaa-091920ff5a02.png" alt="7e6f988c-9bf7-454c-afaa-091920ff5a02" width="940" height="725" loading="lazy"></p>
<p>在<strong>热身</strong>之后，你将进入<strong>学习</strong>部分。在这里，你会看到你新学的单词在实际中的应用！你将聆听短片段的独白或对话，并回答关于它们的问题，以确保你理解它们的含义以及它们在真实对话中的使用方式。在必要时，你还将在这里学习一些理论。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766158808549/5a1b2945-149a-433b-a840-cff49224908c.png" alt="在一个有大窗的城市景观的办公室房间里站立的动画角色。上方文字解释如何用中文介绍国籍，“wǒ shì + 国籍”，下方字幕显示角色用拼音和简体中文字符说“我是中国人”。" width="835" height="654" loading="lazy"></p>
<p>课程中还包含填空题，帮助你练习使用拼音和汉字。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766158976101/208a38c7-850d-4d43-8794-c6c51fc92962.png" alt="一个背着背包的动画角色站在有绿色植物墙和电脑的办公室里。显示中文文本和拼音，内容为：“我是新加坡人。”下方有与句子相关的填空题目。" width="816" height="770" loading="lazy"></p>
<p>在<strong>学习</strong>之后，你将继续进入<strong>练习</strong>部分，在这里你将完成更多开放式任务，以测试你是否理解以及使用拼音和汉字写作的能力。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766159066500/9b4b962d-dcd8-4782-9526-07a4cc5e0219.png" alt="一个语言练习的截图，包含中文文本和拼音，指示用户将“我是、开发者、中国人、你好”按正确顺序放到相应位置。“wǒ shì” 意思是“我是”。这些短语需要放置在“wáng huá”和其他提示旁边的空白处。" width="805" height="444" loading="lazy"></p>
<p>在模块的末尾，有一个<strong>复习</strong>部分，包含语法要点、主要词汇和概念。你可以使用这些复习页面帮助你准备测验。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766097053581/bc30af81-4d64-42b2-84d5-624d9c3f87db.png" alt="这幅图片包含一个题为“语法要点”的文本，讨论中文中的问候类型。它介绍了三个短语：“你好” (nǐ hǎo) 用于随意的场合，“您好” (nín hǎo) 用于礼貌互动，“你们好” (nǐ men hǎo) 用于与多人打招呼。" width="1570" height="1042" loading="lazy"></p>
<p>模块的最后部分是<strong>测验</strong>，旨在检验你对模块中所涵盖材料的理解。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766162326716/7f0a788e-5f9b-4b3b-8499-1cd39eca1d37.png" alt="名为“问候与介绍测验”的页面检测你对基础中文问候的理解。要通过，必须正确回答至少 10 道题中的 9 道。第一个问题询问在向一群人问候时应该使用哪个短语，选项包括“nǐ men hǎo” (你们好)、“nín hǎo” (您好)、“wǒ shì” (我是) 和“nǐ hǎo” (你好)。" width="856" height="695" loading="lazy"></p>
<p>认证考试将作为该认证的最后一项发布。我们目前发布了前三章，后续章节将由我们的教学设计团队开发后逐步发布。当所有章节上线后，我们将发布认证考试。</p>
<h2 id="">致谢贡献者</h2>
<p>感谢以下贡献者在课程开发中提供帮助：</p>
<ul>
<li>
<p><a href="https://github.com/gikf">Krzysztof G.</a></p>
</li>
<li>
<p><a href="https://github.com/mrchenguozheng">Chen Guo Zheng</a></p>
</li>
<li>
<p><a href="https://github.com/stevending1st">Steven Ding</a></p>
</li>
</ul>
<p>我们特别感谢 <a href="https://github.com/s1ngs1ng">S1ng S1ng</a>，他录制了独白和对话音频，还录制了生动展示拼音发音的教学视频。这些拼音视频将在明年陆续添加到课程中。</p>
<h2 id="">常见问题</h2>
<h3 id="">这些内容真的全部免费吗？</h3>
<p>是的。freeCodeCamp 一直以来都是免费的，并且我们已经提供免费的认证超过十年。</p>
<h3 id="">我可以用除英语以外的语言学习中文课程吗？</h3>
<p>我们的目标是让 freeCodeCamp 支持的语言课程都能以各种语言提供。查看你的账户设置，看看你正在学习的课程是否已经提供你偏好的语言版本。</p>
<h3 id="">中文课程涵盖哪些语言技能？</h3>
<p>语言课程目前涵盖听力、阅读和写作。我们计划稍后添加口语部分。</p>
<h3 id="">语言课程和考试中的音频是由母语者录制的吗？</h3>
<p>是的。语言课程中的所有音频均由该语言的母语者录制。</p>
<h3 id="">我是聋人或听力不佳者。我还可以学习语言课程吗？</h3>
<p>可以！所有音频课程都提供字幕和可阅读的文本。</p>
<h3 id="">我是盲人或视力有限，并使用屏幕阅读器。我还可以学习语言课程吗？</h3>
<p>可以！freeCodeCamp 课程设计为无障碍，你可以使用屏幕阅读器学习语言课程。如果遇到任何无障碍问题，你可以在我们的 GitHub 仓库上反馈，以便社区解决。</p>
<h3 id="a1a2b1">课程名称旁边的字母和数字有什么意义？（例如：A1、A2、B1）</h3>
<p>这些标记指的是 CEFR（欧洲共同语言参考标准）等级，这是一种用于描述语言熟练程度的国际框架。A1 和 A2 代表初级水平，B1 和 B2 代表中级水平，C1 和 C2 代表高级水平。每个等级指示你在语言学习阶段所预期具备的技能和知识。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765475620837/6822cf7c-d05f-4a5c-8e8a-994c540ed369.png" alt="一张标题为“CEFR 等级详解”的图表展示了从 A1 到 C2 的六个 CEFR 语言能力等级。A1 等级描述为“在倾听者的帮助下进行交流”。A2 等级涉及“在有限范围内进行交流”。B1 等级重点在于“在熟悉的情境中交流核心要点”。B2 等级能够在“多种情境中较流畅地交流”。C1 等级强调“在多数情境中灵活流畅地沟通”。C2 等级代表“在绝大多数情境中实现精准细腻的交流”。freeCodeCamp 标识位于图表底部。" width="1024" height="768" loading="lazy"></p>
<h2 id="">其他</h2>
<p>祝你在 freeCodeCamp 的语言课程学习中好运。</p>
<p>祝学习愉快！</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp 开源社区 2025 年度 Top Contributors ]]>
                </title>
                <description>
                    <![CDATA[ 2025 年对于全球 freeCodeCamp 社区来说是非常富有成效的一年。作为一个已经走过 12 个年头的社区，我们在各个方面都全速前进，比以往更加稳步推进。 今年，我们对新的全栈开发者课程进行了重大改进。这是 freeCodeCamp 课程的第 10 个版本，包含 7 个认证。在学习过程中，学习者将完成超过 100 个实践项目，并通过计算机科学理论的考试。 此外，在过去的一年里，freeCodeCamp 社区实现了：  * 在 freeCodeCamp YouTube 频道上发布 129 个免费视频课程          * 在 freeCodeCamp 专栏上发布 45 本免费完整书籍和手册          * ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/freecodecamp-2025-top-contributors/</link>
                <guid isPermaLink="false">6947ed6d1acf9a04cd95ded6</guid>
                
                    <category>
                        <![CDATA[ 社区 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ freeCodeCamp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Mon, 22 Dec 2025 11:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/12/----_20251222205523_138_113.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/freecodecamp-top-open-source-contributors-2025/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">freeCodeCamp's Top Open Source Contributors of 2025</a>
      </p><!--kg-card-begin: markdown--><p>2025 年对于全球 freeCodeCamp 社区来说是非常富有成效的一年。作为一个已经走过 12 个年头的社区，我们在各个方面都全速前进，比以往更加稳步推进。</p>
<p>今年，我们对新的全栈开发者课程进行了重大改进。这是 freeCodeCamp 课程的第 10 个版本，包含 7 个认证。在学习过程中，学习者将完成超过 100 个实践项目，并通过计算机科学理论的考试。</p>
<p>此外，在过去的一年里，freeCodeCamp 社区实现了：</p>
<ul>
<li>
<p>在 freeCodeCamp YouTube 频道上发布 129 个免费视频课程</p>
</li>
<li>
<p>在 freeCodeCamp 专栏上发布 45 本免费完整书籍和手册</p>
</li>
<li>
<p>452 篇关于数学、编程和计算机科学的教程和文章</p>
</li>
<li>
<p>50 集 freeCodeCamp 播客节目，我采访了许多开发者，其中许多人都是 freeCodeCamp 开源项目的贡献者</p>
</li>
</ul>
<p>我们还合并了 4,279 个提交到 freeCodeCamp 的开源学习平台，进行了大量用户体验和无障碍访问的改进。此外，我们还发布了安全的考试环境，供学习者参加认证考试。</p>
<p>最后，我们在开发者英语课程上取得了相当大的进展，并开始制作即将上线的西班牙语和中文课程。</p>
<p>我们才刚刚开始。我们已经在规划关于数学、数据科学、机器学习和其他深度、技能密集型课程的附加课程。</p>
<p>这一切都要感谢 10,342 名善良的人们<a href="https://donate.freecodecamp.org">捐助支持我们的慈善事业和使命</a>，以及那些投入时间和才华给社区的人们。</p>
<p>以下是 2025 年我们社区的 611 位最活跃的开源贡献者名单：</p>
<h2 id="githubtopcontributor">GitHub Top Contributor</h2>
<ul>
<li>
<p><a href="https://github.com/clarencepenz">Clarence Bakosi</a></p>
</li>
<li>
<p><a href="https://github.com/Supravisor">Supravisor</a></p>
</li>
<li>
<p><a href="https://github.com/Giftea">Giftea ☕</a></p>
</li>
<li>
<p><a href="https://github.com/pdtrang">Diem-Trang Pham</a></p>
</li>
<li>
<p><a href="https://github.com/a2937">Anna</a></p>
</li>
<li>
<p><a href="https://github.com/c0d1ng-ma5ter">c0d1ng_ma5ter</a></p>
</li>
<li>
<p><a href="https://github.com/JungLee-Dev">JungLee-Dev</a></p>
</li>
<li>
<p><a href="https://github.com/hbar1st">hbar1st</a></p>
</li>
<li>
<p><a href="https://github.com/dev-kamil">dev-kamil</a></p>
</li>
<li>
<p><a href="https://github.com/arizfaiyaz">Ariz Faiyaz</a></p>
</li>
<li>
<p><a href="https://github.com/agilan11">agilan11</a></p>
</li>
<li>
<p><a href="https://github.com/cuongpham24">Vinson Pham</a></p>
</li>
<li>
<p><a href="https://github.com/StuartMosquera">Stuart Mosquera</a></p>
</li>
<li>
<p><a href="https://github.com/StephenMuya">Stephen Mutheu Muya</a></p>
</li>
<li>
<p><a href="https://github.com/MohamadSalman11">Mohamad Salman</a></p>
</li>
<li>
<p><a href="https://github.com/alexgoldsmith">Alex Goldsmith</a></p>
</li>
<li>
<p><a href="https://github.com/vishnudt2004">Vishnu D</a></p>
</li>
<li>
<p><a href="https://github.com/kannan-ravi">Kannan</a></p>
</li>
<li>
<p><a href="https://github.com/tanmaygautam11">Tanmay Gautam</a></p>
</li>
<li>
<p><a href="https://github.com/l3onhard">l3onhard</a></p>
</li>
<li>
<p><a href="https://github.com/prabhakaryadav2003">Prabhakar Yadav</a></p>
</li>
<li>
<p><a href="https://github.com/errantpianist">Ezoh Zhang</a></p>
</li>
<li>
<p><a href="https://github.com/Ajay-2005">Ajay A</a></p>
</li>
<li>
<p><a href="https://github.com/dragon-slayer27">Vivaan Teotia</a></p>
</li>
<li>
<p><a href="https://github.com/hassanwaqa">Hassan Waqar</a></p>
</li>
<li>
<p><a href="https://github.com/gikf">Krzysztof G.</a></p>
</li>
<li>
<p><a href="https://github.com/roberiacono">Roberto Iacono</a></p>
</li>
<li>
<p><a href="https://github.com/MelvinManni">Melvin Kosisochukwu</a></p>
</li>
<li>
<p><a href="https://github.com/lasjorg">Lasse Jørgensen</a></p>
</li>
<li>
<p><a href="https://github.com/dennmar">dennmar</a></p>
</li>
<li>
<p><a href="https://github.com/Arif-Khalid">Arif Khalid</a></p>
</li>
<li>
<p><a href="https://github.com/soryaek">Sorya Ek</a></p>
</li>
<li>
<p><a href="https://github.com/RaymondLiu777">Raymond Liu</a></p>
</li>
<li>
<p><a href="https://github.com/AyushSharma72">Ayush Sharma</a></p>
</li>
<li>
<p><a href="https://github.com/yusufasur">Yusuf Can Aşur</a></p>
</li>
<li>
<p><a href="https://github.com/kb42">Karthik Bagavathy</a></p>
</li>
<li>
<p><a href="https://github.com/Sky-walkerX">Naman Khandelwal</a></p>
</li>
<li>
<p><a href="https://github.com/vkalakota18">Varshith Kalakota</a></p>
</li>
<li>
<p><a href="https://github.com/omarraf">Omar Rafiq</a></p>
</li>
<li>
<p><a href="https://github.com/raahthor">Prashant Rathore</a></p>
</li>
<li>
<p><a href="https://github.com/Agung1606">Agung Saputra</a></p>
</li>
<li>
<p><a href="https://github.com/sanchitkhthpalia">Sanchit Kathpalia</a></p>
</li>
<li>
<p><a href="https://github.com/shashankdangi">Shashank Dangi</a></p>
</li>
<li>
<p><a href="https://github.com/garyeung">Gary Yeung</a></p>
</li>
<li>
<p><a href="https://github.com/ppl-call-me-tima">Amit Upadhyay</a></p>
</li>
<li>
<p><a href="https://github.com/pkdvalis">pkdvalis</a></p>
</li>
<li>
<p><a href="https://github.com/sinha21Soumya">sinha21Soumya</a></p>
</li>
<li>
<p><a href="https://github.com/VishalTelukula">Telukula Vishal</a></p>
</li>
<li>
<p><a href="https://github.com/sskiragu">sskiragu</a></p>
</li>
<li>
<p><a href="https://github.com/AishwaryaRajput09">Aishwarya</a></p>
</li>
<li>
<p><a href="https://github.com/TrevorBrowning">Trevor Browning</a></p>
</li>
<li>
<p><a href="https://github.com/AilaLu">AilaLu</a></p>
</li>
<li>
<p><a href="https://github.com/zxc-w">zxc-w</a></p>
</li>
<li>
<p><a href="https://github.com/anishlukk123">Anish Lukkireddy</a></p>
</li>
<li>
<p><a href="https://github.com/josue-igiraneza">Josue Igiraneza</a></p>
</li>
<li>
<p><a href="https://github.com/adityaravichandran6">Aditya Ravichandran</a></p>
</li>
<li>
<p><a href="https://github.com/skyewm">Skye Mickens</a></p>
</li>
<li>
<p><a href="https://github.com/gagan-bhullar-tech">Gagan Bhullar</a></p>
</li>
<li>
<p><a href="https://github.com/asr1325">Aditya</a></p>
</li>
</ul>
<h2 id="topcontributor">论坛 Top Contributor</h2>
<ul>
<li>
<p><a href="https://forum.freecodecamp.org/u/Teller">Teller</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/pkdvalis">pkdvalis</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/hasanzaib1389">Hassan Zaib</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/a1legalfreelance">A1legalfreelance</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/igorgetmeabrain">Doug Badger</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/JeremyLT">Jeremy</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/fcc4b6d10c4-b540-4e2">fcc4b6d10c4-b540-4e2</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/JuniorQ">Arakhsh Q</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Ray13">Raymond</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/hbar1st">Hanaa B.</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/lasjorg">Lasse</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/sanity">sanity or not</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/MostafaElbadry">MostafaElbadry</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/a2937">Anna</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/seopostexpert">Muhammad Subhan</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/stephenmutheu">Stephen Mutheu</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/zs_akkaya">Zeynep Serra Akkaya</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/bappyasif">A.Bappy</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/PauloRodrigues">Paulo</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/StaySilent">StaySilent</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Klexvier">Klexvier</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/robheyays">Robert H.</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/BlindVisionMan">Marvin Hunkin</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/tracy.chacon.00">Tracy Chacon</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/bochard">bochard</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Cody_Biggs">CODY BIGGS</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/be_happy"><em>Infinity</em></a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/ShadyHBedda">Shady H. Bedda</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/booleanmethod9">Boolean Method</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/ArielLeslie">Ariel Leslie</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/DanielHuebschmann">Head in Cloud</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Dovb1ek">Dovb1ek</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/c0d1ng_ma5ter">c0d1ng_ma5ter</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/evaristoc">evaristoc</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/ahraitch">ahr aitch</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/jwhoisfondofit">Jay</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/AlexK">AlexanderTheDev</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Malcolm-Harrison">Malcolm Harrison</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Ethan1">Ethan1</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/vikramvi">Vikram Ingleshwar</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/constantcode9909">Amine (Mike)</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/nickrg">Nicolas Greenwood</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/Amunyelet-Ojala">Amunyelet-Ojala</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/anon75571083">anon75571083</a></p>
</li>
<li>
<p><a href="https://forum.freecodecamp.org/u/brendenhowlett96">Brenden Howlett</a></p>
</li>
</ul>
<h2 id="topcontributor">翻译 Top Contributor</h2>
<ul>
<li>
<p>Afonso Branco (AfonsoBranco)</p>
</li>
<li>
<p>Michael Qu (qubycn)</p>
</li>
<li>
<p>Alan Luo (iLtc)</p>
</li>
<li>
<p>Nadja Sellinat (biebricherin)</p>
</li>
<li>
<p>David Almeida (david.miguel.almeida)</p>
</li>
<li>
<p>jeigux</p>
</li>
<li>
<p>Nairobi (fanqie)</p>
</li>
<li>
<p>Ivan Forcati (IvanF)</p>
</li>
<li>
<p>Quang Nguyen (nguyendangquang126)</p>
</li>
<li>
<p>Ganebas</p>
</li>
<li>
<p>Kentaro Nareswara (K3N7)</p>
</li>
<li>
<p>Alana Maia (nicegrrrl)</p>
</li>
<li>
<p>Gustavo Birman (Gustavuspqr)</p>
</li>
<li>
<p>Nataliia Hrytsyk (nataliia.hrytsyk)</p>
</li>
<li>
<p>Filipe Oliveira (FilipeOliveira)</p>
</li>
<li>
<p>Діана Маркута (dianamarkuta)</p>
</li>
<li>
<p>Kostiantyn Krysenko (barkode)</p>
</li>
<li>
<p>v4n31aa</p>
</li>
<li>
<p>janni1288</p>
</li>
<li>
<p>Nastasia Milosev (nastasia.milosev)</p>
</li>
<li>
<p>Juan Diaz (JuanPabloDiaz)</p>
</li>
<li>
<p>Stas Kinash (stasKinash)</p>
</li>
<li>
<p>ToteM</p>
</li>
<li>
<p>Tihomir Manushev (haraGADygyl)</p>
</li>
<li>
<p>Maximo Sanchez (maxysanchez.06)</p>
</li>
<li>
<p>Сервило Галина (servilogalina)</p>
</li>
<li>
<p>Laureline Paris (LaurelineP)</p>
</li>
<li>
<p>mubinabegimxayrullayeva</p>
</li>
<li>
<p>mitegab</p>
</li>
<li>
<p>Berke Volkan (kzlpndx)</p>
</li>
<li>
<p>Dana Volovelsky (danavolovelsky)</p>
</li>
<li>
<p>Isauro Rodriguez (icaro5)</p>
</li>
<li>
<p>Yuliia Lishchuk (yuli)</p>
</li>
<li>
<p>Palak (palakkhan2002)</p>
</li>
<li>
<p>bahtiyorjonq777</p>
</li>
<li>
<p>Olha Boretska (olha.boretskaa)</p>
</li>
<li>
<p>yidev27</p>
</li>
<li>
<p>Ilona Sheremeta (lonasheremeta78)</p>
</li>
<li>
<p>Anna Shram (annashram53)</p>
</li>
<li>
<p>Anastasiia Perchyshyn (anastasijp2004)</p>
</li>
<li>
<p>Mariia Soloshenko (Mariia_S)</p>
</li>
<li>
<p>erickk (lucerile435)</p>
</li>
<li>
<p>Fran Sanabria (fransanabria)</p>
</li>
<li>
<p>Богдана Онищук (bohdanaon9001)</p>
</li>
<li>
<p>Shogo SENSUI (1000ch)</p>
</li>
<li>
<p>maysa42snow</p>
</li>
<li>
<p>Halia Senkiv (haliasenkiv)</p>
</li>
<li>
<p>Jiyoung Suh (JiyoungSuh)</p>
</li>
<li>
<p>Anairis Carballea (acarballea)</p>
</li>
<li>
<p>Johan Javier Gonzalez Perez (javiergonzalez045)</p>
</li>
<li>
<p>yosrmaalej47</p>
</li>
<li>
<p>Akram Dhib (akramdhib999)</p>
</li>
<li>
<p>Bảo Nam Trần Hoàng (kipi91212)</p>
</li>
<li>
<p>Eduarda Groehs (egroehs)</p>
</li>
<li>
<p>FlameC (anonymHe)</p>
</li>
<li>
<p>sohyun</p>
</li>
<li>
<p>Xiaoyan Zhang (Drwhooooo)</p>
</li>
<li>
<p>Gabriela Silva (gabrielaquintilho.s)</p>
</li>
<li>
<p>Fausto Chiacchietta (faustooch)</p>
</li>
<li>
<p>Seif-03</p>
</li>
<li>
<p>オメロ (homero304)</p>
</li>
<li>
<p>Msam</p>
</li>
<li>
<p>Eya (eyaaba)</p>
</li>
<li>
<p>mohamed ben haj salah (mohamedbhs7)</p>
</li>
<li>
<p>abdallah djarraya (abdallahswimmer)</p>
</li>
<li>
<p>Aylin Gümüş (aylingumus)</p>
</li>
<li>
<p>aminezribi03</p>
</li>
<li>
<p>Eloy Gutiérrez (eloy.alumnes)</p>
</li>
<li>
<p>Ameeri22</p>
</li>
<li>
<p>youssef1607</p>
</li>
<li>
<p>Pablo J Lebed (pjl1978)</p>
</li>
<li>
<p>Mergen N (mn)</p>
</li>
<li>
<p>Yuki Shibata (kyubashi)</p>
</li>
<li>
<p>ggfly666</p>
</li>
<li>
<p>Amine (ersu.amine)</p>
</li>
<li>
<p>WaifuXv</p>
</li>
<li>
<p>Jawnex</p>
</li>
<li>
<p>mamaruo</p>
</li>
<li>
<p>Eric Gigondan (Itsatsu)</p>
</li>
<li>
<p>Hamzalakoud</p>
</li>
<li>
<p>c.marget</p>
</li>
<li>
<p>Saki Basken (sbasken)</p>
</li>
<li>
<p>hashim rashid (hhashbrown)</p>
</li>
<li>
<p>yuan-minglongze</p>
</li>
<li>
<p>OKmimech</p>
</li>
<li>
<p>J.G. P.C. (kaiserpc)</p>
</li>
<li>
<p>Fatma Ajroud (faty_aj)</p>
</li>
<li>
<p>Yuna_707</p>
</li>
<li>
<p>Franklin Solar Navarrete (fsolarnavarrete)</p>
</li>
<li>
<p>zeinebBenRayana</p>
</li>
<li>
<p>Mark P. (Futuraura)</p>
</li>
<li>
<p>Ahmad Hassan (sUfi)</p>
</li>
<li>
<p>Ivrin Ivrin (Ivrin)</p>
</li>
<li>
<p>parapara0919</p>
</li>
<li>
<p>Panah (panah)</p>
</li>
<li>
<p>Mario Turtoi (MarioDev)</p>
</li>
<li>
<p>Edenilson Ulises Aguilar Diaz (UlisesDiaz0)</p>
</li>
<li>
<p>rustamdocstranslator</p>
</li>
<li>
<p>Cristian Salazar (Cristian-27)</p>
</li>
<li>
<p>IsabelaMB</p>
</li>
<li>
<p>Khalil Sassi (khalilsassi67)</p>
</li>
<li>
<p>Sorayadc</p>
</li>
<li>
<p>Franco Casafus (francocasafus22)</p>
</li>
<li>
<p>miwamiwamiwa (miwalaa)</p>
</li>
<li>
<p>franciscomelov</p>
</li>
<li>
<p>Juan Taroni (juanribeiro.taroni)</p>
</li>
<li>
<p>Alexander Liu Gao (aleliu)</p>
</li>
<li>
<p>YC liou (iop52896)</p>
</li>
<li>
<p>David Oliveira (EngDavidOlivr)</p>
</li>
<li>
<p>Campoz _ (campozzz)</p>
</li>
<li>
<p>Roberta Meyrelles (rmftelier)</p>
</li>
<li>
<p>Polina (minlaux)</p>
</li>
<li>
<p>Matheus G. Oliveira (PomboObeso)</p>
</li>
<li>
<p>Hou Bowei (houbowei)</p>
</li>
<li>
<p>Paul (ptijero)</p>
</li>
<li>
<p>Danilo Parada Garcés (dparada.sistemas)</p>
</li>
<li>
<p>Ana_Writer</p>
</li>
<li>
<p>Nathalia Oliveira (royalpython)</p>
</li>
<li>
<p>Amir (Amir_lvx)</p>
</li>
<li>
<p>Eltaj Mammadzada (eltajmammadzada)</p>
</li>
<li>
<p>Oliver Loza (THE_G3NES1S)</p>
</li>
<li>
<p>Jakhongir Murtazaev (jakhongir.murtazayev)</p>
</li>
<li>
<p>Siyana Zdravkova (BlueButterflies)</p>
</li>
<li>
<p>Vindishel (vindishel)</p>
</li>
<li>
<p>Daniel Jimenez (danjim82)</p>
</li>
<li>
<p>hk7math</p>
</li>
<li>
<p>KAWPHUNMAN</p>
</li>
<li>
<p>wdthor</p>
</li>
<li>
<p>Snow sita2 (EnmanuelTorres)</p>
</li>
<li>
<p>Aldo Vanegas (AldoLara)</p>
</li>
<li>
<p>nmo-genio</p>
</li>
<li>
<p>Pedro Daniel (pedrodanielgomes)</p>
</li>
<li>
<p>sadnessasha</p>
</li>
<li>
<p>Aby Prastya Palgunadi (arcanaxvi)</p>
</li>
<li>
<p>Halifolium</p>
</li>
<li>
<p>juan jose (Juanx64)</p>
</li>
<li>
<p>Henry Richard Flores Bazurto (hflores10)</p>
</li>
<li>
<p>Leah</p>
</li>
<li>
<p>Emma (emmaa5)</p>
</li>
<li>
<p>ANVAR ZIYODOV (ziyodovanvar1999)</p>
</li>
<li>
<p>dharris296</p>
</li>
<li>
<p>Juan Esteban Montoya Marín (montoyajuanes11)</p>
</li>
<li>
<p>Yiming Sun (sunyiming008)</p>
</li>
<li>
<p>Fauzi Kurniawan (kurniawan26)</p>
</li>
<li>
<p>Royyan Ahmad Zaydan (Kasehito)</p>
</li>
<li>
<p>Mikadifo</p>
</li>
<li>
<p>thelooter</p>
</li>
<li>
<p>Berkcan Gümüşışık (berkcangumusisik)</p>
</li>
<li>
<p>Stephen Mutheu (stephenmutheu)</p>
</li>
<li>
<p>athen</p>
</li>
<li>
<p>Wajahat (syedmuhammadwajahathusain)</p>
</li>
<li>
<p>Tanish Chauhan (tanishc4444)</p>
</li>
<li>
<p>Satya900</p>
</li>
<li>
<p>Luis V. (lvalderramavergara)</p>
</li>
<li>
<p>Sharvio</p>
</li>
<li>
<p>HibouDev</p>
</li>
<li>
<p>dTM99</p>
</li>
<li>
<p>wuzzjohn</p>
</li>
<li>
<p>Gavin Xu (gavinxu2)</p>
</li>
<li>
<p>ProjektMing</p>
</li>
<li>
<p>Saidkamol Saidjamolov (saidkamolxon)</p>
</li>
<li>
<p>beta filip (betafilip)</p>
</li>
<li>
<p>Deborah Porchia (deborah98)</p>
</li>
<li>
<p>teddy_ye</p>
</li>
<li>
<p>Rommel Hindap (rommel.b.hindap)</p>
</li>
<li>
<p>Jesús Lautaro Careglio Albornoz (JLCareglio)</p>
</li>
<li>
<p>SergioBlancoFtns</p>
</li>
<li>
<p>Nathalie Bour (nathalie.bour)</p>
</li>
<li>
<p>Qingfeng Huang (darrenhqf)</p>
</li>
<li>
<p>Omar (omar.fanzeres)</p>
</li>
<li>
<p>Atsushi Hatakeyama (atsushi729)</p>
</li>
<li>
<p>Diego Fierro (diegoefierro)</p>
</li>
<li>
<p>IsaRO (IsaR0d)</p>
</li>
<li>
<p>Abdulbosit Tuychiev (abdulbosit19980204)</p>
</li>
<li>
<p>NG KA YEE (hkscsheph)</p>
</li>
<li>
<p>Floman Dizwit (Hockman)</p>
</li>
<li>
<p>Karel Vanhelden (karelvanhelden)</p>
</li>
<li>
<p>khay56</p>
</li>
<li>
<p>Dostonbek Matyakubov (doston12)</p>
</li>
<li>
<p>MarcoGeldenhuis</p>
</li>
<li>
<p>immeteor2</p>
</li>
<li>
<p>Freedom Fighter (1543431a)</p>
</li>
<li>
<p>Ibn Hosain (ibnhosain014)</p>
</li>
<li>
<p>Vairus (e-oannis)</p>
</li>
<li>
<p>Elio Fang</p>
</li>
<li>
<p><a href="https://x.com/0x99Ethan3">YiWei</a></p>
</li>
<li>
<p><a href="https://x.com/TsukistarCN">Tsukistar</a></p>
</li>
<li>
<p>luojiyin</p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.linkedin.com/in/qingfeng-huang">Qingfeng Huang</a></p>
</li>
<li>
<p>wendy chen</p>
</li>
<li>
<p>zhizhan</p>
</li>
<li>
<p>HeZean</p>
</li>
<li>
<p>Ivan Forcati</p>
</li>
<li>
<p>Andrea Sisti</p>
</li>
<li>
<p><a href="https://x.com/Xuemei525">彭雪梅</a></p>
</li>
</ul>
<h2 id="youtubetopcontributor">YouTube Top Contributor</h2>
<ul>
<li>
<p><a href="https://github.com/s1ngs1ng">S1ng S1ng</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.linkedin.com/in/leoncarlo/">Carlos León</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@LuisCanary">Luis Canary</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@programacaocomramon">Ramon Rodrigues</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/github.com/jamesgpearce">James Pearce</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@officialtatevaslanyan">Tatev Aslanyan</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@EricWTech">Eric Tech</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@RivaanRanawat">Rivaan Ranawat</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@KhanamCoding">Khaiser Khanam</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@vincibits">Paulo Dichone</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@HiteshCodeLab">Hitesh Choudhary</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@EamonnCottrell">Eamonn Cottrell</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@harshbhatt7585">Harsh Bhatt</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@radu">Radu Mariescu-Istodor</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@3CodeCampers">Imad Saddik</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@EmbarkX">Faisal Memon</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@JSLegendDev">JSLegendDev</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@ExamProChannel">Andrew Brown</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@DaveGrayTeachesCode">Dave Gray</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@asabretech">Ebenezer Asabre</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@the-lisper">Alberto Lerda</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@deeplearningexplained">Yacine Mahdid</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@codeafuture">Alen Omeri</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@tungabayrak9765">Tunga Bayrak</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@CodingCleverly">Haris Iftikhar</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/rdali.github.io/">Rola Dali</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@OmarMAtef">Omar M. Atef</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/github.com/stevenGarciaDev">Steven Garcia</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@TrickSumo">Rishi Kumar Tiwari</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@coleblender">Cole Blender</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@AlterYourEnglish">Borys Cherednychenko</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@haidermalik3402">Haider Malik</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@excel.withgrant">Grant Huang</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@vukrosic">Vuk Rosić</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@LearnQtGuide">Daniel Gakwaya</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/github.com/BrijenMakwana">Brijen Makwana</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@TheCodeholic">Zura Sekhniashvili</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@turingtimemachine">Vladimirs Hisamutdinovs</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@tapasadhikary">Tapas Adhikary</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@richardtopchii">Richard Topchii</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@code-with-abel">Abel Gideon</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@MatkatMusic">Chuck Schiemeyer</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@programmingwithalex.585">Alexandru Cristian</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@masterspanishacademy">Virginia Ocana</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.linkedin.com/in/vaibhav-mehra-main/">Vaibhav Mehra</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/optimusprime09012004@gmail.com">Kshitij Sharma</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.dotnetmastery.com">Bhrugen Patel</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@programmingoceanacademy">Mohammad Fahd Abrah</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@ThePyCoach">Frank Andrade</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@ChadsPrep">Chad McAllister</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@ErikYuzwa">Erik Yuzwa</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@dswithbappy">Bappy Ahmed</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@Programming-Fluency">Noor Fakhry</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@AyushSinghSh">Ayush Singh</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@ever-greg">Gregory Kirchoff</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@algo.monster">Sheldon Chi</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@GlitchyDevs">Muhammad Omar Al Najjar</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@talltalksfromashortlady2798">Chumki Biswas</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/c/AlvinTheProgrammer">Alvin Zablan</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@structuredcs">Qiang Hao</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@datasciencewithmarco">Marco Peix</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@logicBaseLabs">Sumit Saha</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.linkedin.com/in/yilmazalaca">Yılmaz Alaca</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@robotbobby9">Bobby Roe</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/x.com/wagslane">Lane Wagner</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/%E2%80%AA@mobidevtalk">Shad Rayhan Mazumder</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@DotNetHow">Ervis Trupja</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/github.com/vivekkalyanarangan30">Vivek Kalyanarangan</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@cs50">David J. Malan</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.linkedin.com/in/leoncarlo/">Carlos Leon</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@BlossomBuild">Carlos Valentin</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@DestinationFAANG">Parth Vyas</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@codewithmuhammadabdullah">Muhammad Abdullah</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@andrewwoan">Andrew Woan</a></p>
</li>
<li>
<p><a href="https://chinese.freecodecamp.org/news/freecodecamp-2025-top-contributors/www.youtube.com/@AlexGordonHiFi">Alex Gordon</a></p>
</li>
<li>
<p><a href="http://youtube.com/@TwoWaysMath">Karol Kurek</a></p>
</li>
</ul>
<h2 id="topcontributor">专栏 Top Contributor</h2>
<ul>
<li>
<p><a href="https://freecodecamp.org/news/author/manishshivanandhan">Manish Shivanandhan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/nsavant">Nikheel Vishwas Savant</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/appinisurya">Surya Teja Appini</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tayo4christ">OMOTAYO OMOYEMI</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Casmir">Casmir Onyekani</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Chukwudinweze">Chukwudi Nweze</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/GerCocca">German Cocca</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Shejan-Mahamud">Shejan Mahamud</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/hew">Hew Hahn</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/curiousmoshe">Moshe Siegel</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/markm208">Mark Mahoney</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/atuoha">Atuoha Anthony</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/balapriyac">Bala Priya C</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ashutoshkrris">Ashutosh Krishna</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/hiteshchauhan2023">Hitesh Chauhan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tiredmahnoor">Mah Noor</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/andrewbaisden">Andrew Baisden</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/trayalex812">Alex Tray</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/gkoos">Gabor Koos</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Abhidave">Abhijeet Dave</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sumitsaha">Sumit Saha</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Tech-On-Diapers">Opaluwa Emidowojo</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/oluwatobiss">Oluwatobi Sofela</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sholajegede">Shola Jegede</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/michaelyuan">Michael Yuan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ChisomUma123">Chisom Uma</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/heywisdom">Wisdom Usa</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/kuriko">Kuriko Iwai</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ceddlyburge">Cedd Burge</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/CaesarSage">Destiny Erhabor</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/leomofthings">Ayodele Aransiola</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Koded001">Temitope Oyedele</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/emdadulislam">Emdadul Islam</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Tioluwani">Oyedele Tioluwani</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mehtasoham">Soham Mehta</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Agnes28">Agnes Olorundare</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/atapas">Tapas Adhikary</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/chiragagrawal">Chirag Agrawal</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ATechAjay">Ajay Yadav</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mayur9210">Mayur Vekariya</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Sharvin26">Sharvin Shah</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/adejumo">Adejumo Ridwan Suleiman</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sravankaruturi">Sravan Karuturi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/wagslane">Lane Wagner</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/nitheeshp">Nitheesh Poojary</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/almamohapatra">Alma Mohapatra</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/orimdominic">Orim Dominic Adah</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/arunachalamb">Arunachalam B</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ayush01Mishra">AYUSH MISHRA</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/shricodev">Shrijal Acharya</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Oliverkrane">Ikegah Oliver</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Jongbo">Olaleye Blessing</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ifycodes99">Ifeoma Udu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Tobilyn77">Oluwatobi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/oluwaseunoladeji">Oladeji Oluwaseun</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tarunsinghofficial">Tarun Singh</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/grantdotdev">Grant Riordan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/asfakahmed">Asfak Ahmed</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/LeeRenJie">Tech With RJ</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/timkleier">Tim Kleier</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/CodeHemaa">Ophy Boamah</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ezinnecodes">EZINNE ANNE EMILIA</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Codinghappiness">Happiness Omale</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/bertao">Pedro</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Lonercode">Amanda Ene Adoyi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/arunshanmugamkumar">Arun Shanmugam Kumar</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/andrewezeani">Andrew Ezeani</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ajay074">Ajay Kalal</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ijay">Ijeoma Igboagu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/prankurpandeyy">Prankur Pandey</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/augustinealul">Augustine Alul</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sanjayxr">Sanjay R</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/adiatiayu">Ayu Adiati</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/cardstdani">Daniel García Solla</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Clifftech">Isaiah Clifford Opoku</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ryan-michael-kay">Ryan Michael Kay</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/olanetsoft">Idris Olubisi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/wittycircuitry">Aditya Vikram Kashyap</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/brkln">brooklyn</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/TemiTope1">Tope Fasasi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ilknureren">Ilknur Eren</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sohamstars">Soham Banerjee</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/vaheaslanyan">Vahe Aslanyan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tatevaslanyan">Tatev Aslanyan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/henrywinnerman">Henry Adepegba</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ThatCoolGuy">Oluwadamilola Oshungboye</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/shrutikapoor">Shruti Kapoor</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/theladybella">Mfonobong Umondia</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Spruce">Spruce Emmanuel</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Derekvibe">Okoro Emmanuel Nzube</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/rajumanoj">Raju Manoj</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/udemezue">Udemezue John</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/lulunwenyi">Oluchi Nwenyi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/toobaj">Tooba Jamal</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/nwanduka">Victoria Nduka</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Nene23">Nneoma Uche</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/michaelikoko">Michael Ikoko</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Jude-Olowo">Olowo Jude</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ateev">Ateev Duggal</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Oluwadamisi">Oluwadamisi Samuel</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/menghnani">Mohit Menghnani</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/scriptedBytes">Brandon Wozniewicz</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/huhuhang">Hang Hu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mrufai">Rufai Mustapha</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/LolaVictoria">Damilola Oniyide</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/HijabiCoder">Fatuma Abdullahi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/montasser1988">Montasser Mossallem</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/gatwirival">valentine Gatwiri</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/SmoothTech">Timothy Olanrewaju</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/gitgithan">Han Qi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Omah">Eti Ijeoma</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Yazdun">Yazdun</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/desoga">deji adesoga</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/the_BrianB">Brian Barrow</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/chidiadi01">Chidiadi Anyanwu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/codelikeandrew">Andrew Maksimchenko</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mcasari">Mario Casari</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Balajeeasish">Balajee Asish Brahmandam</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/woai3c">Gordan Tan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tildaudufo">Tilda Udufo</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/rahulgupta32">Rahul gupta</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/edae">Eda Eren</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/josiahadesola">Josiah Adesola</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/smarttester">Venkata Sai Sandeep</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tiagomonteiro">Tiago Capelo Monteiro</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Preston56">Preston Osoro</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/TheAnkurTyagi">Ankur Tyagi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/justanothertechlead">Ben</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/askvikram">Vikram Aruchamy</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/dhruv-007">Dhruv Prajapati</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/onukwilip">Prince Onukwili</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/AdeboyeDN">Daniel Adeboye</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/kanand">Kumar Anand</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/lucasgarcez">Lucas</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ec001">evaristo.c</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/officialrajdeepsingh">Rajdeep Singh</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/chaitanyarahalkar">Chaitanya Rahalkar</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/MahamCodes">Maham Codes</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/divyasaratchandran">Divya Valsala Saratchandran</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/joanayebola">Joan Ayebola</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/omerros">Omer Rosenbaum</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Nazneen758">Nazneen Ahmad</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/KunalN25">Kunal Nalawade</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/sdranju">Shamsuddoha Ranju</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/anamol-rajbhandari">Anamol Rajbhandari</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/suleolanrewaju">Sule-Balogun Olanrewaju</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Eccentric-">Sara Jadhav</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/LifeofDan-EL">Daniel Anomfueme</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Michael-para">Michael Para</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ellabee">Elabonga Atuo</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/azubuikeduru">Azubuike Duru</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/AdalbertPungu">Adalbert Pungu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/gunkev">Kevine Nzapdi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/hamdaan">Hamdaan Ali</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/AbdullahInBytes">Abdullah Salaudeen</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/RAHULISM">Rahul</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Ayobami6">Alaran Ayobami</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/omoladeekpeni">Omolade Ekpeni</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/rwalters">Rob Walters</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/viv1">Vivek Sahu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Xtephen">oghenekparobo Stephen</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/psmohammedali">P S Mohammed Ali</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/gursimar">Gursimar Singh</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Olabisi09">Olabisi Olaoye</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/de">David Asaolu</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/initialcommit">Jacob Stopak</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Yoma">Emore Ogheneyoma Lawrence</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/hunor">Hunor Márton Borbély</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/techwithpraisejames">Praise James</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/pltvs">Alex Pliutau</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/tanishkamakode">Tanishka Makode</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/SonyaMoisset">Sonya Moisset</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/vkweb">Vivek Agrawal</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/syedamahamfahim">Syeda Maham Fahim</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/chiderahumphrey">Chidera Humphrey</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/DoableDanny">Danny</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/stefanmuzyka">Stefan Muzyka</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/samhitharamaprasad">Samhitha Rama Prasad</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/nitinfab">Nitin Sharma</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/codewithshahan">Programming with Shahan</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/jpromanonet">Juan P. Romano</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/anjanbaradwaj">Anjan Baradwaj</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/manocormen">Manoel</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mkbadeniyi">Kayode Adeniyi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/MuhToyyib">Akande Olalekan Toheeb</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/dbclinton">David Clinton</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/josevnz">Jose Vicente Nunez</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/joeattardi">Joe Attardi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/mihailgaberov">Mihail Gaberov</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/ashimi0x">Ashimi0x</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Zubs">Zubair Idris Aweda</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/IbrahimOgunbiyi">Ibrahim Ogunbiyi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/svlorman">Svitlana Lorman</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/timmy471">Ayantunji Timilehin</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/imkrishnasarathi">Krishna Sarathi Ghosh</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/Daiveed">David Jaja</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/francisihe">Francis Ihejirika</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/marco-venturi">Marco Venturi</a></p>
</li>
<li>
<p><a href="https://freecodecamp.org/news/author/nyayicfanny">Fanny Nyayic</a></p>
</li>
</ul>
<h2 id="discordtopcontributor">Discord Top Contributor</h2>
<ul>
<li>
<p>hana-banana</p>
</li>
<li>
<p>Science99</p>
</li>
<li>
<p>Razzle Dazzle</p>
</li>
<li>
<p>jeremylt (他/他们)</p>
</li>
<li>
<p>Makka Pakka jOoJ</p>
</li>
<li>
<p>bradtaniguchi</p>
</li>
<li>
<p>ʇɹǝqɯoɥɹ</p>
</li>
<li>
<p>Versailles</p>
</li>
<li>
<p>CapslockHero 🎃</p>
</li>
<li>
<p>plamoni</p>
</li>
<li>
<p>xCoffeeMan</p>
</li>
<li>
<p>Dylan</p>
</li>
<li>
<p>QC Failed (Brandon)</p>
</li>
<li>
<p>minjo70</p>
</li>
<li>
<p>tgrtim</p>
</li>
<li>
<p>Yu14</p>
</li>
<li>
<p>localhost</p>
</li>
<li>
<p>ArielLeslie</p>
</li>
<li>
<p>Wayloe</p>
</li>
<li>
<p>Hordian</p>
</li>
<li>
<p>Anna</p>
</li>
<li>
<p>Starbreeze</p>
</li>
<li>
<p>supertanno</p>
</li>
<li>
<p>Hermit</p>
</li>
<li>
<p>Aakash</p>
</li>
<li>
<p>Ganesh</p>
</li>
<li>
<p>Zino</p>
</li>
<li>
<p>Cristina</p>
</li>
<li>
<p>Pantalonians</p>
</li>
<li>
<p>Cy4er</p>
</li>
<li>
<p>himonshuuu</p>
</li>
<li>
<p>Dumb ninja</p>
</li>
<li>
<p>Kiseki 奇跡</p>
</li>
<li>
<p>Sebastian</p>
</li>
<li>
<p>alpox</p>
</li>
<li>
<p>BasCat</p>
</li>
</ul>
<p>再次说明，这些只是参与 freeCodeCamp 社区的成千上万的人中最活跃的一些。</p>
<p>如果你有兴趣以开源贡献者的身份参与 freeCodeCamp 社区，我建议你<a href="https://contribute.freecodecamp.org/#/">阅读我们的贡献者指南</a>，并加入我们的<a href="https://discord.gg/KVUmVXA">贡献者 Discord 聊天室</a>。</p>
<p>再次感谢，祝编码愉快。🏕️</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 介绍 freeCodeCamp 每日 Python 和 JavaScript 挑战 – 每天解决一个新的编程难题 ]]>
                </title>
                <description>
                    <![CDATA[ freeCodeCamp 社区很高兴地宣布，我们新的每日编程挑战已经为你准备好了。🎊 持续练习是提升编程技能最有效的方法之一。因此，除了核心编程课程外，你现在可以通过每天解决一个有趣的新编程挑战来保持编程熟练度。 每个午夜（美国中部时间） ，一道新的编程题目将在 freecodecamp.org [https://freecodecamp.org] 和 freeCodeCamp 移动应用上解锁，你可以使用 JavaScript 和 Python 来解决。 如何开始解决每日编程挑战 在 freeCodeCamp 移动应用上：  1. 从 Google Play Store 或 Apple App Store 下载 freeCodeCamp 移动应用并打开。            2. 如果你想要保存你的进度，别忘了登录。然后在顶部找到今天的挑战并点击“开始挑战”：       ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/introducing-freecodecamp-daily-python-and-javascript-challenges-solve-a-new-programming-puzzle-every-day/</link>
                <guid isPermaLink="false">68dca7a6ea47500467bc736e</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Wed, 01 Oct 2025 10:19:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/10/66cb1d9b-b2e1-4911-bea5-ca1f1308ca35.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/introducing-freecodecamp-daily-python-and-javascript-challenges-solve-a-new-programming-puzzle-every-day/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Introducing freeCodeCamp Daily Python and JavaScript Challenges – Solve a New Programming Puzzle Every Day</a>
      </p><!--kg-card-begin: markdown--><p>freeCodeCamp 社区很高兴地宣布，我们新的每日编程挑战已经为你准备好了。🎊</p>
<p>持续练习是提升编程技能最有效的方法之一。因此，除了核心编程课程外，你现在可以通过每天解决一个有趣的新编程挑战来保持编程熟练度。</p>
<p>每个午夜（美国中部时间） ，一道新的编程题目将在 <a href="https://freecodecamp.org">freecodecamp.org</a> 和 freeCodeCamp 移动应用上解锁，你可以使用 JavaScript 和 Python 来解决。</p>
<h2 id="">如何开始解决每日编程挑战</h2>
<h3 id="freecodecamp">在 freeCodeCamp 移动应用上：</h3>
<ol>
<li>
<p>从 Google Play Store 或 Apple App Store 下载 freeCodeCamp 移动应用并打开。</p>
</li>
<li>
<p>如果你想要保存你的进度，别忘了登录。然后在顶部找到今天的挑战并点击“开始挑战”：</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757013682796/383439a2-12d5-4054-88d5-e0e6a6f052f0.png" alt="383439a2-12d5-4054-88d5-e0e6a6f052f0" width="281" height="609" loading="lazy"></p>
<ol start="3">
<li>选择你喜欢的语言：</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757013721085/873f1d66-93c5-47ac-805c-aa8ef99d058c.png" alt="873f1d66-93c5-47ac-805c-aa8ef99d058c" width="281" height="609" loading="lazy"></p>
<ol start="4">
<li>阅读挑战指令：</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757013769135/ff7d0843-1566-4349-8559-9626264bb87a.png" alt="ff7d0843-1566-4349-8559-9626264bb87a" width="281" height="609" loading="lazy"></p>
<ol start="5">
<li>编写代码：</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757013821639/a049756c-b873-4b6b-a7a9-ab020db48933.png" alt="a049756c-b873-4b6b-a7a9-ab020db48933" width="281" height="609" loading="lazy"></p>
<ol start="6">
<li>通过测试：</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757014651276/28dff232-0c54-41b3-ac2f-0ddbfa0d913c.png" alt="28dff232-0c54-41b3-ac2f-0ddbfa0d913c" width="281" height="609" loading="lazy"></p>
<p>这样你就完成了这项挑战。</p>
<h3 id="">在网站上：</h3>
<ol>
<li>访问 <a href="https://freecodecamp.org">freecodecamp.org</a> 并确保你已登录，以保存进度。然后向下滚动找到当天的编程挑战并点击“开始”：</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757014100541/aaf37fe9-d06e-4198-834c-6cd6ea37d330.png" alt="aaf37fe9-d06e-4198-834c-6cd6ea37d330" width="487" height="130" loading="lazy"></p>
<ol start="2">
<li>
<p>在顶部选择你喜欢的语言</p>
</li>
<li>
<p>阅读挑战指令，编写代码并通过测试：</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757014412721/ee3a6ed9-0628-41fe-acf0-fc10e5772ee8.png" alt="ee3a6ed9-0628-41fe-acf0-fc10e5772ee8" width="2094" height="1560" loading="lazy"></p>
<h2 id="">如果我错过了一天怎么办？</h2>
<p>如果你错过了一项挑战，不必担心。移动应用和网站都包含一个<strong>归档页面</strong>，你可以根据自己的节奏浏览和完成之前的挑战：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757015163098/3bdf35b5-d76c-49de-bb50-35f262716059.png" alt="3bdf35b5-d76c-49de-bb50-35f262716059" width="2094" height="1560" loading="lazy"></p>
<h2 id="">今天开始你的首个挑战</h2>
<p>今天的挑战正在等待你。打开 freeCodeCamp 应用或访问 <a href="https://freecodecamp.org">freecodecamp.org</a> 完成它吧。🚀</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 在你的浏览器中学习 React - freeCodeCamp 全栈课程 2025 年中更新 ]]>
                </title>
                <description>
                    <![CDATA[ Hey campers！freeCodeCamp 社区仍在全力开发我们的全栈课程 [https://www.freecodecamp.org/chinese/learn/full-stack-developer/]的剩余部分。 虽然才过去几个月，但已经有许多学员全力投入这些新课程和编程挑战中。 我很兴奋能与大家分享下一批更新。 新课程内容 我们刚刚发布了三个新的课程部分：React Hooks 和 State、性能、测试。 这些新课程包含：  * 50 个讲座视频  * 十几个工作坊和实验室  * 3 个新的复习模块  * 以及大量课程内容，帮助你保持学习进度（同时我们正在完成全栈课程的剩余部分） 你将构建的一些项目包括：  * 井字棋游戏  * 颜色选择器  * 超级英雄申请表 考试 我们知道许多人热切期待每个模块末尾的考试。这些考试快要准备好了。 我们还在构建一个自定义的考试环境，供你参加这些考试。这将平衡隐私保护和学术诚信。 下一步计划 社区现在正专注于 CSS 库和 TypeScript 模块。我们还在构建 Python 模块。 未来几个月我们将有很多 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/learn-react-in-your-browser-freecodecamp-full-stack-curriculum-mid-2025-update/</link>
                <guid isPermaLink="false">68527f0aeb98e40467ef9ab5</guid>
                
                    <category>
                        <![CDATA[ freeCodeCamp ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Wed, 18 Jun 2025 09:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/06/----_20250618171556.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/learn-react-in-your-browser-freecodecamp-full-stack-curriculum-mid-2025-update/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Learn React in your Browser – freeCodeCamp Full Stack Curriculum Mid-2025 Update</a>
      </p><!--kg-card-begin: markdown--><p>Hey campers！freeCodeCamp 社区仍在全力开发我们的<a href="https://www.freecodecamp.org/chinese/learn/full-stack-developer/">全栈课程</a>的剩余部分。</p>
<p>虽然才过去几个月，但已经有许多学员全力投入这些新课程和编程挑战中。</p>
<p>我很兴奋能与大家分享下一批更新。</p>
<h2 id="">新课程内容</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750152183453/6e973e4a-4b7e-4294-b056-95a5f6155e77.png" alt="课程页面截图" width="717" height="766" loading="lazy"></p>
<p>我们刚刚发布了三个新的课程部分：React Hooks 和 State、性能、测试。</p>
<p>这些新课程包含：</p>
<ul>
<li>50 个讲座视频</li>
<li>十几个工作坊和实验室</li>
<li>3 个新的复习模块</li>
<li>以及大量课程内容，帮助你保持学习进度（同时我们正在完成全栈课程的剩余部分）</li>
</ul>
<p>你将构建的一些项目包括：</p>
<ul>
<li>井字棋游戏</li>
<li>颜色选择器</li>
<li>超级英雄申请表</li>
</ul>
<h2 id="">考试</h2>
<p>我们知道许多人热切期待每个模块末尾的考试。这些考试快要准备好了。</p>
<p>我们还在构建一个自定义的考试环境，供你参加这些考试。这将平衡隐私保护和学术诚信。</p>
<h2 id="">下一步计划</h2>
<p>社区现在正专注于 CSS 库和 TypeScript 模块。我们还在构建 Python 模块。</p>
<p>未来几个月我们将有很多内容发布。</p>
<p>一些即将上线的项目包括：</p>
<ul>
<li>构建你自己的 RPG 角色</li>
<li>交易卡牌游戏</li>
<li>医疗数据验证器</li>
<li>以及更多🏕️</li>
</ul>
<h2 id="">参与进来</h2>
<p>你有兴趣帮助我们开发这些全栈课程吗？欢迎你贡献，你可以在我们的 GitHub 仓库查看所有开放的<a href="https://github.com/freecodecamp/freecodecamp/issues">议题</a>。</p>
<p>请先阅读我们的<a href="https://contribute.freecodecamp.org/intro/">贡献指南</a>，然后加入我们的 <a href="https://discord.gg/KVUmVXA">Discord 社区</a>，你可以提出任何问题。</p>
<p>我们很兴奋看到大家学习所有这些新课程。保持动力，继续提升技能，Happy coding！💜</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 旅行者面临的网络安全风险及应对策略 ]]>
                </title>
                <description>
                    <![CDATA[ 旅行是人生最大乐趣之一，但也让你成为网络罪犯的重点目标。 游客常常行色匆匆、注意力分散或不熟悉当地服务商，而这正是黑客所希望看到的。 从虚假 Wi-Fi 网络到可疑 SIM 卡骗局，以下是出国旅行时可能遇到的五大常见数字威胁及防范措施。 虚假 Wi-Fi 网络 在繁忙车站或温馨咖啡馆看到名为 “Free_Public_WiFi” 的网络时，人们常会不假思索地连接。 问题在于：这可能是伪基站。 黑客会架设名称逼真的恶意热点诱骗旅客连接，随后就能监控流量、窃取登录凭证、短信甚至信用卡信息。这种“中间人攻击 [https://www.techtarget.com/iotagenda/definition/man-in-the-middle-attack-MitM] ”在公共场所出人意料地容易得手。 安全指南： • 避免用公共 Wi-Fi 进行敏感操作（特别是网银和网购） • 在设备设置中关闭自动连接开放网络功能 • 使用 VPN 加密网络流量，增加黑客窃密难度 公共 Wi-Fi 虽便利但风险极高。保持警惕、关闭自动连接并启用 VPN，方能在保持联网时守护安全。 虚假预订/签证 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-attackers-target-travelers-and-how-to-defend-yourself/</link>
                <guid isPermaLink="false">683e6fd6aeeaf6047bb88d6a</guid>
                
                    <category>
                        <![CDATA[ 安全 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 03 Jun 2025 04:00:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/06/----_20250603122250.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/how-attackers-target-travelers-and-how-to-defend-yourself/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How Attackers Target Travelers – and How to Defend Yourself</a>
      </p><p>旅行是人生最大乐趣之一，但也让你成为网络罪犯的重点目标。</p><p>游客常常行色匆匆、注意力分散或不熟悉当地服务商，而这正是黑客所希望看到的。</p><p>从虚假 Wi-Fi 网络到可疑 SIM 卡骗局，以下是出国旅行时可能遇到的五大常见数字威胁及防范措施。</p><h2 id="-wi-fi-">虚假 Wi-Fi 网络</h2><p>在繁忙车站或温馨咖啡馆看到名为 “Free_Public_WiFi” 的网络时，人们常会不假思索地连接。</p><p>问题在于：这可能是伪基站。</p><p>黑客会架设名称逼真的恶意热点诱骗旅客连接，随后就能监控流量、窃取登录凭证、短信甚至信用卡信息。这种“<a href="https://www.techtarget.com/iotagenda/definition/man-in-the-middle-attack-MitM">中间人攻击</a>”在公共场所出人意料地容易得手。</p><p>安全指南：<br>• 避免用公共 Wi-Fi 进行敏感操作（特别是网银和网购）<br>• 在设备设置中关闭自动连接开放网络功能<br>• 使用 VPN 加密网络流量，增加黑客窃密难度</p><p>公共 Wi-Fi 虽便利但风险极高。保持警惕、关闭自动连接并启用 VPN，方能在保持联网时守护安全。</p><h2 id="-">虚假预订/签证网站</h2><p>在线规划行程很方便——有时过于方便了。</p><p>诈骗者能伪造与真实网站几乎一模一样的假的预订页面。当你以为在预订酒店或申请签证时，实则将信用卡和护照信息送给了骗子。</p><p>常见手法是微调知名域名，如将 expedia.com 改为 expeida.com，并辅以令人难以置信的优惠。警告：这些都是陷阱！</p><p>应对策略：<br>• 手动输入网址而非点击邮件/广告链接<br>• 认准知名平台或直接访问航空/酒店官网<br>• 仔细检查 URL 拼写，确认以 “https://” 开头<br>• 通过可信搜索引擎或旅行咨询页查找政府签证官网</p><p>这类骗局不仅造成不便，更可能让你损失大量金钱并延误行程。</p><h2 id="sim-">SIM 卡调包与可疑商家</h2><p>许多国家会建议游客抵达后购买当地 SIM 卡，机场柜台就出售预付费套餐。</p><p>但交出护照并让他人安装 SIM 卡风险极大。</p><p>SIM 卡调包指他人获取你的 SIM 凭证后，将号码转移至新卡并接收双重验证码，继而轻松入侵银行账户或邮箱。</p><p>防范措施：<br>• 避免在街头随机摊位购买 SIM 卡（尤其是那种索要额外的个人信息的）<br>• 通过手机设置启用 SIM 卡 PIN 码锁<br>• 关闭重要账户的短信验证，改用 Google 身份验证器等 APP</p><p>出发前配置国际旅行 eSIM 更加安全，这比实体 SIM 更难被劫持。</p><h2 id="atm-">ATM 侧录与信用卡克隆</h2><p>当你在现金不足时在 ATM 取款，可能没注意到卡槽上的侧录装置或键盘上方的微型摄像头。这些设备能复制卡片数据，配合 PIN 码即可克隆卡片清空账户。餐厅和商店的便携读卡器同样可能暗藏玄机。</p><p>防护建议：<br>• 优先使用银行内或酒店大堂等监控区域的 ATM<br>• 轻拉卡槽检查是否松动异常<br>• 输入 PIN 码时遮挡键盘，即使当下只有你一个人<br>• 尽量使用信用卡，它比借记卡有更完善的防诈保护</p><p>设置交易实时提醒，旅行期间密切监控账户。</p><h2 id="--1">钓鱼邮件与社会工程学</h2><p>“检测到 Airbnb 账户异常活动，点击验证”——这类使用企业标识的逼真邮件实为陷阱。</p><p>诈骗者伪装成可信机构诱导泄露凭证，旅客因身处陌生环境且期待行程更新更易中招。</p><p>线下场景同样存在：穿制服者以“验证”为由索要护照，或谎称酒店预订异常。这类心理操控称为社会工程学。</p><p>应对方法：<br>• 核实邮件发件人，正规企业通常不会通过邮件索要敏感信息<br>• 勿点击可疑链接，直接登录官网查看<br>• 对索要证件者保持礼貌但谨慎，先核实其身份<br>• 为每个账户设置高强度唯一密码，并启用 APP 双重验证（非短信）</p><p>当你察觉异常时，应该相信直觉，宁可多问也别事后懊悔。</p><h2 id="--2">保持警惕，安全出行</h2><p>只要你不给机会，网络诈骗就毁不了你的旅程。简单准备就能事半功倍：始终使用 VPN 隐藏网络活动、认准安全网站、非必要不使用公共 Wi-Fi、设置强密码并保持设备更新。</p><p>旅行本该充满乐趣而非焦虑。掌握正确工具并养成安全习惯，你就能安心探索世界，在保持联网的同时守护信息安全。</p><p>希望你喜欢这篇文章。欢迎订阅 <a href="https://newsletter.stealthsecurity.sh/">Stealth Security newsletter</a>，获取更多网络安全的相关文章。想学习进攻性网络安全基础知识？不妨试试我们的 <a href="https://start.stealthsecurity.sh/">Security Starter</a> 课程。</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 结合代码示例解析递归的工作原理 ]]>
                </title>
                <description>
                    <![CDATA[ 在本文中，你将学习递归的工作原理。 在学习递归之前，你需要很好地理解函数的工作原理。我在本文中使用了 Python 代码作为示例，因为它的语法简单，但递归的概念对于每种编程语言都是一样的。 什么是递归？ 在大多数编程语言中，一个函数可以调用另一个函数。但一个函数也可以调用自身。递归是一种函数调用自身的技术。 这是一个例子： def call_me():     call_me() 在这里，函数调用自身，这就是所谓的递归。 但是“调用自身”只是递归的程序定义。递归涉及将一个问题分解为更小的部分，直到无法进一步分解为止。你解决小问题并将它们组合起来以解决整个问题。 用真实生活中的例子类比递归 让我们通过一个例子来理解递归如何真正工作。 想象一下，你在迪士尼乐园排队等候，你不知道前面有多少人。 为了找出答案，你问你前面的人。 试图找出排在你前面的人数 那个人也不知道，所以她们询问她们前面的那个人。 这个过程继续进行，直到问题到达队伍最前面的人，他们看到前面没有人，回答说前面有零人。 然后队伍开始将回复传递回去。每个人在将信息传递回去之前，都会在他们被告知的数字 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/what-is-recursion/</link>
                <guid isPermaLink="false">67c06d188d004904442ab80a</guid>
                
                    <category>
                        <![CDATA[ 递归 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Thu, 27 Feb 2025 12:50:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/02/Frame-1--6-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/what-is-recursion/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How Does Recursion Work? Explained with Code Examples</a>
      </p><!--kg-card-begin: markdown--><p>在本文中，你将学习递归的工作原理。</p>
<p>在学习递归之前，你需要很好地理解函数的工作原理。我在本文中使用了 Python 代码作为示例，因为它的语法简单，但递归的概念对于每种编程语言都是一样的。</p>
<h2 id="">什么是递归？</h2>
<p>在大多数编程语言中，一个函数可以调用另一个函数。但一个函数也可以调用自身。递归是一种函数调用自身的技术。</p>
<p>这是一个例子：</p>
<pre><code>def call_me():
    call_me()
</code></pre>
<p>在这里，函数调用自身，这就是所谓的递归。</p>
<p>但是“调用自身”只是递归的程序定义。递归涉及将一个问题分解为更小的部分，直到无法进一步分解为止。你解决小问题并将它们组合起来以解决整个问题。</p>
<h2 id="">用真实生活中的例子类比递归</h2>
<p>让我们通过一个例子来理解递归如何真正工作。</p>
<p>想象一下，你在迪士尼乐园排队等候，你不知道前面有多少人。</p>
<p>为了找出答案，你问你前面的人。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/How-many--4-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>试图找出排在你前面的人数</em></p>
<p>那个人也不知道，所以她们询问她们前面的那个人。</p>
<p>这个过程继续进行，直到问题到达队伍最前面的人，他们看到前面没有人，回答说前面有零人。</p>
<p>然后队伍开始将回复传递回去。每个人在将信息传递回去之前，都会在他们被告知的数字上加 1。</p>
<p>当排在最前面的人回答，<strong>“前面有 0 人”<strong>时，下一个人加 1 然后回答，</strong>“前面有 1 人”</strong>，依此类推。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/How-many--5-.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>每个人都知道他们前面有多少人</em></p>
<p>当回复到达直接在你前面的人时，他们再加上 1 并告诉你。通过这种方式，你可以通过将前面的人给的数字添加 <strong>1</strong>，来确定你在队伍中的位置。</p>
<p>这个例子说明了递归如何将问题分解为更小的子问题，然后结合它们的解决方案以解决原始问题。</p>
<p>队伍中的每个人代表同一问题的一个较小实例：确定前面的人数。通过解决这些较小的实例并结合它们的结果，整个问题得到了解决。这正是递归的工作原理。</p>
<h2 id="">递归的技术细节</h2>
<p>在编码递归时最重要的是要找出：</p>
<ul>
<li>
<p><strong>递归情况</strong>：我们可以做的最小工作。在上面的例子中，询问你前面的人他们前面有多少人是我们可以做的最小工作。</p>
</li>
<li>
<p><strong>基本情况</strong>：无需工作的条件。在上面的例子中，队伍最前面的人没有必要问任何问题，因此这是无需工作的条件。</p>
</li>
</ul>
<h2 id="">递归的简单例子</h2>
<p>计算阶乘是递归的最简单例子，它将真正帮助你理解其工作原理。</p>
<p>有很多方法可以计算一个数的阶乘。但在这里，我们将看到递归的方式来找到它。</p>
<p>在思考我们如何做到这一点之前，我们需要知道一个数的阶乘是什么。</p>
<p>一个数的阶乘是从 <strong>1</strong> 到该数的所有数字的乘积。</p>
<p>例如，<strong>5</strong> 的阶乘是 <strong>120</strong> —— 即 <strong>5</strong>×<strong>4</strong>×<strong>3</strong>×<strong>2</strong>×<strong>1</strong>。</p>
<p>我们还可以用数学方式表示如下：</p>
<p><code>5×(5−1)!</code></p>
<p>这意味着如果我们知道 <code>(5−1)!</code> 的值，我们就可以通过简单地将 <strong>5</strong> 乘以它来轻松得到阶乘。</p>
<p>这就是我们如何找到 <strong>4</strong>、<strong>3</strong>、<strong>2</strong>、<strong>1</strong> 和 <strong>0</strong> 的阶乘：</p>
<pre><code>Factorial of 4 = 4×(4−1)!
Factorial of 3 = 3×(3−1)!
Factorial of 2 = 2×(2−1)!
Factorial of 1 = 1
Factorial of 0 = 1
</code></pre>
<p>通过观察这些，很明显要找到 <strong>5</strong> 的阶乘，我们必须将 <strong>5</strong> 乘以 <code>4!</code>。</p>
<h3 id="">更普遍的例子</h3>
<p>要找到 <code>n</code> 的阶乘，我们需要将 <code>n</code> 乘以 <code>(n−1)!</code>。这就是你需要递归执行的过程。</p>
<p>现在，必须为递归设置一个停止条件。停止条件是我们不再执行其他操作的地方。当 <code>n</code> 是 <strong>1</strong> 或 <strong>0</strong> 时，我们可以简单地停止递归，因为这些值的阶乘是已知的。我们可以简单地说 <strong>1</strong> 的阶乘是 <strong>1</strong>，对于 <strong>0</strong> 也是如此。</p>
<p>因此，分解下来，要找到 n 的阶乘，所需做的最小工作量是 <code>n×(n−1)!</code>。当我们找到 <strong>1</strong> 或 <strong>0</strong> 的阶乘时，我们可以停止对它进行操作。</p>
<p>让我们看看代码是怎样的：</p>
<pre><code># 计算 n 的阶乘
def fact(n):
</code></pre>
<pre><code class="language-markdown"># 最少工作量
return n * fact(n - 1)

n = 5

# 计算阶乘
factorial = fact(n)
print(factorial)
</code></pre>
<p><strong>输出:</strong></p>
<pre><code>120
</code></pre>
<p>让我们看看它是如何工作的：</p>
<p>在第一次函数调用中，计算了 <strong>5</strong> 的阶乘。接着在第二次调用中，计算了 <strong>4</strong> 的阶乘，以此类推，直到计算 <strong>2</strong> 的阶乘。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-1--5-.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>递归计算 5 的阶乘</em></p>
<p>在调用 <strong>2</strong> 的阶乘时，我们有<code>2×fact(2−1)</code>，即<code>2×fact(1)</code>。</p>
<p>这达到了我们的基本条件。因此，递归停止，<code>2×fact(1)</code>返回<code>2×1</code>给前一个函数调用，并且结果从堆栈中弹出。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-3.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>第四次函数调用返回 2 给前一个函数调用并从堆栈中弹出</em></p>
<p>类似地，这里是其他内容的计算方式：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-4.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>第三次函数调用返回 6 给前一个函数调用并从堆栈中弹出</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-5.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>第二次函数调用返回 24 给前一个函数调用并从堆栈中弹出</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-6.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>第一次函数调用返回 120 给初始函数调用并从堆栈中弹出</em></p>
<p>所以函数最终将值 <strong>120</strong> 返回给初始函数调用。</p>
<h3 id="">为什么我们需要一个基本条件？</h3>
<p>在上面的例子中，我们为代码使用了停止条件。但是如果我们不添加停止条件，或者我们编写的函数永远不满足停止条件呢？</p>
<p>代码会永远运行吗？</p>
<p>不会 – 即使你不终止，代码也不会永远运行。让我们通过一个例子来理解为什么会这样。</p>
<pre><code>def print_five():
    print(5)

    # 调用自身
    print_five()

# 函数调用
print_five()
</code></pre>
<p><strong>输出:</strong></p>
<pre><code>5
5
5
...

RecursionError: maximum recursion depth exceeded
</code></pre>
<p>如果运行上面的代码，你会看到函数不会永远运行，并以消息 <code>RecursionError: maximum recursion depth exceeded</code> 结束。</p>
<p>当一个函数被调用时，它会被存储在一个调用堆栈中。下面是函数<code>print_five()</code>第一次被调用时在调用堆栈中的存储方式。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/How-many--6-.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>第一次函数调用时的调用堆栈</em></p>
<p>函数一次又一次地调用自身，并且每次调用时，函数被存储在调用堆栈中。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/How-many--8-.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>n 次函数调用后的调用堆栈</em></p>
<p>但是调用堆栈的大小是有限的，不能存储无限数量的函数。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/How-many--7-.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>调用堆栈空间不足导致栈溢出</em></p>
<p>当堆栈已满时，它无法再容纳更多调用，导致栈溢出错误。</p>
<p>因此，基本条件对于防止此类错误并确保递归正确终止是必不可少的。</p>
<p>现在让我们看看另一个例子，以便更深入地理解递归。</p>
<h2 id="">如何检查一个单词是否是回文</h2>
<p>在深入代码之前，你应当知道什么是回文。回文是指正向和反向读取都相同的单词。</p>
<p>例如，<code>racecar</code>正向和反向读取都是相同的。</p>
<p>要检查一个单词是否是回文，我们需要检查第一个和最后一个字母是否相同。如果相同，我们接着检查第二个和倒数第二个字母是否相同。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-7.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>检查 racecar 的第一个和最后一个字符是否相同</em></p>
<p>在<code>racecar</code>这一例子中，第一个和最后一个字母是相同的，所以我们检查第二个和倒数第二个字母是否相同。它们相同，所以现在我们检查第三个和倒数第三个字母是否相同。现在只剩下一个字母需要检查。一个单一字母始终是回文，因为它正反读都是相同的。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-8.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>如何检查 racecar 是否是回文</em></p>
<p>所以，现在让我们尝试以递归的方式思考，包括最少的工作量以及确定何时不需要工作。</p>
<h3 id="">最少工作量</h3>
<p>检查第一个和最后一个字母是否相同，如果相同，则移除单词中的第一个和最后一个字母。</p>
<h3 id="">不需要工作</h3>
<p>当只剩下一个或没有字母时，我们可以简单地说它是一个回文。</p>
<p>现在，让我们看看代码是什么样子的：</p>
<pre><code># 检查回文
def check_palindrome(text):

    # 停止条件
    # 如果文本长度是 1 或 0，返回真
    if len(text) == 0 or len(text) == 1:
        return True

    # 最少工作量
    # 检查第一个和最后一个字符是否相同
    # 如果相同，移除字符串中的第一个和最后一个字符
    if(text[0]==text[-1]):
        return(check_palindrome(text[1:-1]))
</code></pre>
<pre><code class="language-markdown"># 检查字符串是否为回文
text = "racecar"
is_palindrome = check_palindrome(text)
print(is_palindrome)
</code></pre>
<p>以下是上述代码的工作原理：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/Frame-9.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>检查 racecar 是否为回文</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/checkpalindrome.png" alt="图像" width="600" height="400" loading="lazy"></p>
<p><em>检查 racecar 是否为回文</em></p>
<h2 id="">何时使用递归</h2>
<p>递归看似优雅且简单，但由于反复向堆栈添加方法带来的 CPU 开销，即便是简单问题常也需经过多个步骤方能解决。因此，在使用之前，请确保仔细考虑它是否为解决问题的正确方案。</p>
<p>当代码需要多个循环且显得混乱时，递归可以提供更清晰的解决方案。然而，是否使用递归取决于具体的代码以及所涉及的数据类型或数据结构。对于树和图这类数据结构，递归尤其有用。</p>
<p>尽管递归表面简单，但可能难以理解，即使处理简单问题也可能需要多个步骤。因此，再次提醒，一定要根据具体情况考虑使用。</p>
<h2 id="">总结</h2>
<p>这只是递归的入门介绍。递归的应用场景很多，你可能对其工作原理感到困惑。我将在下一篇文章中讨论更多递归的高级示例。</p>
<p>顺便说一下，以下是我在学习递归过程中找到的简单且有用的资源：</p>
<ul>
<li>
<p><a href="https://www.youtube.com/watch?v=IJDJ0kBx2LM&amp;t=657s">freeCodeCamp 的递归视频</a>：我必须感谢 freeCodeCamp，他们优秀的递归视频课程在我写这篇文章时给我了极大的启发。</p>
</li>
<li>
<p><a href="https://programiz.pro/course/learn-recursion-with-python">Programiz Pro 的递归课程</a>：另一个好资源是 Programiz 的递归课程。这是一个高级课程，需付费，但它经过精心设计。而且，你可以直接在他们的平台上进行练习，真的是很值得。</p>
</li>
</ul>
<p>无论你从哪里学习，都不要花太多时间寻找完美的资源。掌握概念并开始练习——这是你唯一能真正学会的方法。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 什么是进程 ID？如何使用 PID 进行进程管理 ]]>
                </title>
                <description>
                    <![CDATA[ 你是否曾经想过，当多个程序同时运行时，计算机如何知道显示哪个程序的输出？这一切都归功于进程 ID (PID)。 PID 是一个唯一标识符，帮助操作系统跟踪和管理运行中的程序。 在本文中，我们将探讨什么是进程 ID (PID)、它为何重要，以及如何使用它来管理进程，包括在必要时终止程序。 理解 PID：计算机如何识别正在运行的程序 让我们考虑两个 Python 脚本：  * hello_maham.py → print("Hello Maham")          * hello_amna.py → print("Hello Amna")         计算机如何知道 hello_maham.py 应该显示输出 "Hello Maham" 而不是来自 hello_amna.py 的 "Hello ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/what-is-a-process-id-process-management-tutorial/</link>
                <guid isPermaLink="false">67a3664c413508045ddca14f</guid>
                
                    <category>
                        <![CDATA[ 系统管理 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2025 11:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2025/02/1738762164263.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/what-is-a-process-id-process-management-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is a Process ID? How to Use PIDs for Process Management</a>
      </p><!--kg-card-begin: markdown--><p>你是否曾经想过，当多个程序同时运行时，计算机如何知道显示哪个程序的输出？这一切都归功于进程 ID (PID)。</p>
<p>PID 是一个唯一标识符，帮助操作系统跟踪和管理运行中的程序。</p>
<p>在本文中，我们将探讨什么是进程 ID (PID)、它为何重要，以及如何使用它来管理进程，包括在必要时终止程序。</p>
<h2 id="pid">理解 PID：计算机如何识别正在运行的程序</h2>
<p>让我们考虑两个 Python 脚本：</p>
<ul>
<li>
<p><code>hello_maham.py</code> → <code>print("Hello Maham")</code></p>
</li>
<li>
<p><code>hello_amna.py</code> → <code>print("Hello Amna")</code></p>
</li>
</ul>
<p>计算机如何知道 <code>hello_maham.py</code> 应该显示输出 "Hello Maham" 而不是来自 <code>hello_amna.py</code> 的 "Hello Amna"？</p>
<p>如果你认为这只是魔法般地发生，那就再想想吧！这都要归功于一个叫做 <strong>进程 ID (PID)</strong> 的东西。</p>
<p>在任何操作系统中，进程都在后台不停地运行以执行任务。无论是你手动启动的程序还是自动运行的系统任务，这些进程都被分配了一个唯一的 PID。</p>
<p>让我们进一步解析这个过程。</p>
<h2 id="idpid">什么是进程 ID（PID）</h2>
<p>简单来说，</p>
<blockquote>
<p><em>一个</em> <strong><em>进程 ID (PID)</em></strong> <em>是分配给操作系统中每个运行进程的唯一标识符。</em></p>
</blockquote>
<p>让我们来了解后台发生了什么。</p>
<p>每当一个程序运行时，无论是什么语言，它都需要内存和时间来执行。因此，当你运行一个程序时，操作系统会为它创建一个新的进程。为了识别这个程序，计算机会为它分配一个独特的标识符——<strong>进程 ID</strong>——然后开始执行。</p>
<p>让我们再看看之前的例子：</p>
<ul>
<li>
<p>当你运行 <code>hello_maham.py</code> 时，系统为它分配一个唯一的 PID。</p>
</li>
<li>
<p>同样，当你运行 <code>hello_amna.py</code> 时，它也会有自己独特的 PID。</p>
</li>
</ul>
<p>这就是为什么两个脚本的输出不会重叠！</p>
<p>现在明白了吗？每当创建一个新进程时，系统会确保每个进程获得不同的 PID。系统使用这个 PID 来管理和与进程交互。这就叫做 <strong>PID 的唯一性</strong>。</p>
<h3 id="id">计算机如何处理这个 ID</h3>
<p>你可能会想，计算机是否拥有数百万个 PID？毕竟，我们可能同时运行很多程序。</p>
<p>答案是<strong>否</strong>。一旦一个进程结束，它的 PID 就可以被再次使用。这意味着 PID 是可重复使用的，并且不会短缺。</p>
<h3 id="pid">但为什么以及何时需要 PID</h3>
<p>现在你知道了 PID 是什么，你可能会想：<strong>我为什么需要这个？</strong></p>
<p>实际上，PID 对于系统管理员和开发人员非常有用。它们有助于：</p>
<p><strong>系统管理员和开发人员管理进程</strong>。例如，如果某个东西不正常工作，你需要能够找到并停止引起问题的具体进程，对吧？</p>
<p>PID 对于<strong>资源管理</strong>也很重要。操作系统使用它们来为每个进程分配内存和 CPU 时间，以确保没有一个程序占用所有资源。</p>
<h2 id="pid">如何查找正在运行程序的 PID</h2>
<p>到目前为止，我们已经讲解了理论概念。现在，你可能会想：我如何在计算机上找到一个程序的 PID？</p>
<p>以下是一些使用终端中各种命令查找正在运行程序的 <strong>PID</strong> 的简单方法。</p>
<p>注意，我使用的是 Bash 来执行 PID 命令，并附上了一个截图。但对于其他终端如 CMD 和 PowerShell，相关命令将在最后提到。</p>
<p>其中一些方法包括：</p>
<h3 id="1ps">1. 使用 <code>ps</code> 命令</h3>
<p><code>ps</code> 命令显示当前正在运行的进程及其 PID 的快照。</p>
<pre><code>ps aux | grep &lt;program_name&gt;
</code></pre>
<p>这里是一个例子：</p>
<pre><code>ps aux | grep python
</code></pre>
<p>此命令将显示系统上所有正在运行的 Python 进程及其 PID。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737914130884/686568b8-77d5-439d-a08b-61e18d4e5d56.png" alt="运行的 Python 进程及其 PID" width="600" height="400" loading="lazy"></p>
<h3 id="2top">2. 使用 <code>top</code> 命令</h3>
<p><code>top</code> 命令显示系统上正在运行的进程的实时信息，包括它们的 PID。</p>
<pre><code>top
</code></pre>
<p>在 <strong>PID</strong> 列下查看你感兴趣的进程。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737914189672/43f93890-2e06-42a8-b61b-9103227cf912.png" alt="运行 top 命令的结果" width="600" height="400" loading="lazy"></p>
<h2 id="pid">如何使用 PID 终止进程</h2>
<p>如果你想<strong>终止</strong>程序怎么办？无论是 cron 作业还是行为异常或运行时间过长的程序，如何使用 PID 停止它？</p>
<p>让我们了解一下如何做到这一点：</p>
<h3 id="1kill">1. 使用 <code>kill</code> 命令</h3>
<p>要终止进程，请使用 <code>kill</code> 命令和 PID：</p>
<pre><code>kill &lt;PID&gt;
</code></pre>
<p>这里是一个例子：</p>
<pre><code>kill 1234
</code></pre>
<h3 id="2kill9">2. 使用 <code>kill -9</code> 命令（强制终止）</h3>
<p>如果在使用常规 <code>kill</code> 命令之后进程仍未停止，可以使用 <code>kill -9</code> 命令强制终止它：</p>
<pre><code>kill -9 &lt;PID&gt;
</code></pre>
<p>这是一个例子：</p>
<pre><code>kill -9 1234
</code></pre>
<p>这会强制终止进程并绕过其可能有的任何关闭程序，因此请务必谨慎使用。</p>
<h2 id="pidcron">如何使用 PID 停止 cron 作业——实际示例</h2>
<p>假设你有一个 cron 作业正在运行，并且出现了问题。你该如何停止它？</p>
<p>cron 作业是指按特定时间间隔自动运行的计划任务。</p>
<p>如果你需要停止正在运行的 cron 作业，可以使用运行该 cron 作业的进程的 PID。</p>
<h3 id="cron">停止正在运行的 cron 作业</h3>
<p>如果你需要停止正在运行的 cron 作业，可以使用运行该 cron 作业的进程的 PID。</p>
<p>以下是终止 cron 作业的方法：</p>
<ol>
<li>
<p><strong>查找 PID</strong>：使用 <code>ps</code> 或 <code>pgrep</code> 命令查找 cron 作业的 PID。例子：</p>
<pre><code>ps aux | grep cron
</code></pre>
</li>
<li>
<p><strong>终止 Cron 作业</strong>：找到 cron 作业的 PID 后，使用 <code>kill</code> 或 <code>kill -9</code> 命令停止它。</p>
</li>
</ol>
<h2 id="">其他终端的命令</h2>
<p>以下是在不同终端中管理进程的方法：</p>
<table>
<thead>
<tr>
<th>操作</th>
<th>CMD 命令</th>
<th>PowerShell 命令</th>
<th>Bash 命令</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>列出所有进程</strong></td>
<td><code>tasklist</code></td>
<td><code>Get-Process</code></td>
<td><code>ps aux</code></td>
</tr>
<tr>
<td><strong>按名称查找进程</strong></td>
<td><code>tasklist</code></td>
<td><code>findstr &lt;name&gt;</code></td>
<td><code>Get-Process</code></td>
</tr>
<tr>
<td><strong>通过 PID 终止进程</strong></td>
<td><code>taskkill /PID &lt;PID&gt;</code></td>
<td><code>Stop-Process -Id &lt;PID&gt;</code></td>
<td><code>kill &lt;PID&gt;</code></td>
</tr>
<tr>
<td><strong>强制终止进程</strong></td>
<td><code>taskkill /F /PID &lt;PID&gt;</code></td>
<td><code>Stop-Process -Id &lt;PID&gt; -Force</code></td>
<td><code>kill -9 &lt;PID&gt;</code></td>
</tr>
</tbody>
</table>
<h2 id="">小结</h2>
<p>理解<strong>进程 ID</strong> 是管理计算机上进程的关键。通过简单的命令，你可以轻松找到并停止有问题的进程，确保系统顺畅运行。</p>
<p>通过使用 PID 来控制你的系统吧！</p>
<p><strong>保持联系 — @syedamahamfahim 🐬</strong></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 子网检查单 - 24 子网掩码、30、26、27、29 和其他 IP 地址 CIDR 网络参考资料 ]]>
                </title>
                <description>
                    <![CDATA[ 作为开发人员或网络工程师，你可能需要时不时查阅子网掩码值并弄清其含义。 为了让你的生活更轻松，freeCodeCamp 社区制作了这个简单的备忘单。只需滚动或使用 Ctrl/Cmd + F 查找你要查找的值即可。 CIDR子网掩码通配符掩码IP 地址数量可用 IP 地址数量/32255.255.255.2550.0.0.011/31255.255.255.254 0.0.0.122*/30255.255.255.2520.0.0.342/29255.255.255.2480.0.0.786/28 255.255.255.2400.0.0.151614/27255.255.255.2240.0.0.313230/26255.255.255.192 0.0.0.636462/25255.255.255.1280.0.0.127128126/24255.255.255.00.0.0.255256254/23 255.255.254.00.0.1.255512510/22255.255.252.00.0.3.2551,0241,022/21255.255.248.0 0.0.7.2552, ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/</link>
                <guid isPermaLink="false">66835c6d9100b5049d88a6f8</guid>
                
                    <category>
                        <![CDATA[ 计算机网络 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Mon, 13 Jan 2025 08:59:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/10/5f9c9647740569d1a4ca10a9.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/subnet-cheat-sheet-24-subnet-mask-30-26-27-29-and-other-ip-address-cidr-network-references/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Subnet Cheat Sheet – 24 Subnet Mask, 30, 26, 27, 29, and other IP Address CIDR Network References</a>
      </p><!--kg-card-begin: markdown--><p>作为开发人员或网络工程师，你可能需要时不时查阅子网掩码值并弄清其含义。</p>
<p>为了让你的生活更轻松，freeCodeCamp 社区制作了这个简单的备忘单。只需滚动或使用 Ctrl/Cmd + F 查找你要查找的值即可。</p>
<table>
<thead>
<tr>
<th>CIDR</th>
<th>子网掩码</th>
<th>通配符掩码</th>
<th>IP 地址数量</th>
<th>可用 IP 地址数量</th>
</tr>
</thead>
<tbody>
<tr>
<td>/32</td>
<td>255.255.255.255</td>
<td>0.0.0.0</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>/31</td>
<td>255.255.255.254</td>
<td>0.0.0.1</td>
<td>2</td>
<td>2*</td>
</tr>
<tr>
<td>/30</td>
<td>255.255.255.252</td>
<td>0.0.0.3</td>
<td>4</td>
<td>2</td>
</tr>
<tr>
<td>/29</td>
<td>255.255.255.248</td>
<td>0.0.0.7</td>
<td>8</td>
<td>6</td>
</tr>
<tr>
<td>/28</td>
<td>255.255.255.240</td>
<td>0.0.0.15</td>
<td>16</td>
<td>14</td>
</tr>
<tr>
<td>/27</td>
<td>255.255.255.224</td>
<td>0.0.0.31</td>
<td>32</td>
<td>30</td>
</tr>
<tr>
<td>/26</td>
<td>255.255.255.192</td>
<td>0.0.0.63</td>
<td>64</td>
<td>62</td>
</tr>
<tr>
<td>/25</td>
<td>255.255.255.128</td>
<td>0.0.0.127</td>
<td>128</td>
<td>126</td>
</tr>
<tr>
<td>/24</td>
<td>255.255.255.0</td>
<td>0.0.0.255</td>
<td>256</td>
<td>254</td>
</tr>
<tr>
<td>/23</td>
<td>255.255.254.0</td>
<td>0.0.1.255</td>
<td>512</td>
<td>510</td>
</tr>
<tr>
<td>/22</td>
<td>255.255.252.0</td>
<td>0.0.3.255</td>
<td>1,024</td>
<td>1,022</td>
</tr>
<tr>
<td>/21</td>
<td>255.255.248.0</td>
<td>0.0.7.255</td>
<td>2,048</td>
<td>2,046</td>
</tr>
<tr>
<td>/20</td>
<td>255.255.240.0</td>
<td>0.0.15.255</td>
<td>4,096</td>
<td>4,094</td>
</tr>
<tr>
<td>/19</td>
<td>255.255.224.0</td>
<td>0.0.31.255</td>
<td>8,192</td>
<td>8,190</td>
</tr>
<tr>
<td>/18</td>
<td>255.255.192.0</td>
<td>0.0.63.255</td>
<td>16,384</td>
<td>16,382</td>
</tr>
<tr>
<td>/17</td>
<td>255.255.128.0</td>
<td>0.0.127.255</td>
<td>32,768</td>
<td>32,766</td>
</tr>
<tr>
<td>/16</td>
<td>255.255.0.0</td>
<td>0.0.255.255</td>
<td>65,536</td>
<td>65,534</td>
</tr>
<tr>
<td>/15</td>
<td>255.254.0.0</td>
<td>0.1.255.255</td>
<td>131,072</td>
<td>131,070</td>
</tr>
<tr>
<td>/14</td>
<td>255.252.0.0</td>
<td>0.3.255.255</td>
<td>262,144</td>
<td>262,142</td>
</tr>
<tr>
<td>/13</td>
<td>255.248.0.0</td>
<td>0.7.255.255</td>
<td>524,288</td>
<td>524,286</td>
</tr>
<tr>
<td>/12</td>
<td>255.240.0.0</td>
<td>0.15.255.255</td>
<td>1,048,576</td>
<td>1,048,574</td>
</tr>
<tr>
<td>/11</td>
<td>255.224.0.0</td>
<td>0.31.255.255</td>
<td>2,097,152</td>
<td>2,097,150</td>
</tr>
<tr>
<td>/10</td>
<td>255.192.0.0</td>
<td>0.63.255.255</td>
<td>4,194,304</td>
<td>4,194,302</td>
</tr>
<tr>
<td>/9</td>
<td>255.128.0.0</td>
<td>0.127.255.255</td>
<td>8,388,608</td>
<td>8,388,606</td>
</tr>
<tr>
<td>/8</td>
<td>255.0.0.0</td>
<td>0.255.255.255</td>
<td>16,777,216</td>
<td>16,777,214</td>
</tr>
<tr>
<td>/7</td>
<td>254.0.0.0</td>
<td>1.255.255.255</td>
<td>33,554,432</td>
<td>33,554,430</td>
</tr>
<tr>
<td>/6</td>
<td>252.0.0.0</td>
<td>3.255.255.255</td>
<td>67,108,864</td>
<td>67,108,862</td>
</tr>
<tr>
<td>/5</td>
<td>248.0.0.0</td>
<td>7.255.255.255</td>
<td>134,217,728</td>
<td>134,217,726</td>
</tr>
<tr>
<td>/4</td>
<td>240.0.0.0</td>
<td>15.255.255.255</td>
<td>268,435,456</td>
<td>268,435,454</td>
</tr>
<tr>
<td>/3</td>
<td>224.0.0.0</td>
<td>31.255.255.255</td>
<td>536,870,912</td>
<td>536,870,910</td>
</tr>
<tr>
<td>/2</td>
<td>192.0.0.0</td>
<td>63.255.255.255</td>
<td>1,073,741,824</td>
<td>1,073,741,822</td>
</tr>
<tr>
<td>/1</td>
<td>128.0.0.0</td>
<td>127.255.255.255</td>
<td>2,147,483,648</td>
<td>2,147,483,646</td>
</tr>
<tr>
<td>/0</td>
<td>0.0.0.0</td>
<td>255.255.255.255</td>
<td>4,294,967,296</td>
<td>4,294,967,294</td>
</tr>
</tbody>
</table>
<ul>
<li>/31 是 <a href="https://datatracker.ietf.org/doc/html/rfc3021">RFC 3021</a> 中详细说明的一种特殊情况，这种子网掩码类型的网络可以分配两个 IP 地址作为点对点链路。</li>
</ul>
<p>以下是子网掩码和通配符的十进制到二进制的转换表：</p>
<table>
<thead>
<tr>
<th></th>
<th>子网掩码</th>
<th></th>
<th>通配符</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>00000000</td>
<td>255</td>
<td>11111111</td>
</tr>
<tr>
<td>128</td>
<td>10000000</td>
<td>127</td>
<td>01111111</td>
</tr>
<tr>
<td>192</td>
<td>11000000</td>
<td>63</td>
<td>00111111</td>
</tr>
<tr>
<td>224</td>
<td>11100000</td>
<td>31</td>
<td>00011111</td>
</tr>
<tr>
<td>240</td>
<td>11110000</td>
<td>15</td>
<td>00001111</td>
</tr>
<tr>
<td>248</td>
<td>11111000</td>
<td>7</td>
<td>00000111</td>
</tr>
<tr>
<td>252</td>
<td>11111100</td>
<td>3</td>
<td>00000011</td>
</tr>
<tr>
<td>254</td>
<td>11111110</td>
<td>1</td>
<td>00000001</td>
</tr>
<tr>
<td>255</td>
<td>11111111</td>
<td>0</td>
<td>00000000</td>
</tr>
</tbody>
</table>
<p>注意，通配符只是子网掩码的反码。</p>
<p>如果你是网络工程的新手，你可以<a href="https://www.freecodecamp.org/news/computer-networks-and-how-to-actually-understand-them-c1401908172d/">在这里更好地了解计算机网络的工作原理</a>。</p>
<p>最后，这张速查表和本文的其余部分重点介绍的是 IPv4 地址，而不是较新的 IPv6 协议。如果你想了解更多关于 IPv6 的信息，请查看上面关于计算机网络的文章。</p>
<h2 id="ip">IP 地址块如何工作？</h2>
<p>像 <code>192.168.0.1</code> 这样的 IPv4 地址实际上只是四个二进制块的十进制表示。</p>
<p>每个块是 8 位，表示从 0-255 的数字。由于这些块是 8 位的组，每个块被称为一个<strong>八位</strong>。由于有四个 8 位的块，每个 IPv4 地址共有 32 位。</p>
<p>例如，以下是 IP 地址 <code>172.16.254.1</code> 的二进制格式：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/1125px-Ipv4_address.png" alt="1125px-Ipv4_address" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.wikiwand.com/en/articles/IPv4">IPv4</a></p>
<p>要将 IP 地址在十进制和二进制形式之间转换，可以使用下图：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</tbody>
</table>
<p>上图表示一个 8 位的八位字节。</p>
<p>现在假设你要转换 IP 地址 <code>168.210.225.206</code>。你只需要将地址分成四块（<code>168</code>、<code>210</code>、<code>225</code> 和 <code>206</code>），并且使用上图将每一块转换为二进制。</p>
<p>记住在二进制中，1 等同于“开”，0 等同于“关”。所以要将第一个块 <code>168</code> 转换为二进制，只需从图表的开头开始，在单元格中放置 1 或 0，直到总和为 <code>168</code>。</p>
<p>例如：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</tbody>
</table>
<p>128 + 32 + 8 = 168，在二进制中是 <code>10101000</code>。</p>
<p>如果对其余的块进行同样的操作，你会得到 <code>10101000.11010010.11100001.11001110</code>。</p>
<p>如果你看上面的表格，可能会觉得 IP 地址的数量几乎是无限的。毕竟，IPv4 地址有将近42亿个可用地址。</p>
<p>但是，考虑到互联网的发展，以及如今有多少设备连接到网络，当你听到已经存在 <a href="https://whatismyipaddress.com/ipv4-shortage">IPv4 地址短缺</a>，可能也不会感到惊讶。</p>
<p>因为开发人员多年前就已经意识到了短缺问题，他们想出了一个方法，将一个 IP 地址拆分成更小的网络，叫作“子网”。</p>
<p>这个过程叫作“子网划分”，使用 IP 地址的主机部分将其分解成更小的网络或子网。</p>
<p>通常，IP 地址由网络位和主机位组成：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/network-and-host-bits.png" alt="network-and-host-bits" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://support.huawei.com/enterprise/en/doc/EDOC1100145159">什么是 IPv4</a></p>
<p>所以，一般来说，子网划分有两个作用：它为我们提供了一种将网络拆分成子网的方法，并允许设备确定另一个设备/IP 地址是否在同一个本地网络上。</p>
<p>在没有子网划分的情况下，每个连接到互联网的设备都需要一个独特的 IP 地址。</p>
<p>但由于你有一个无线路由器，你只需要一个为你的路由器分配的 IP 地址。这个公共或外部 IP 地址通常是自动处理的，并由你的互联网服务提供商（ISP）分配。</p>
<p>然后每个连接到该路由器的设备都有其自己的私有或内部 IP 地址：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/home-network-diagram.png" alt="home-network-diagram" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.popularmechanics.com/technology/a32729384/how-to-find-ip-address/">我的 IP 地址是什么？</a></p>
<p>现在如果内部 IP 地址为 <code>192.168.1.101</code> 的设备想要与另一台设备通信，它将使用另一台设备的 IP 地址和子网掩码。</p>
<p>IP 地址和子网掩码的组合使得 <code>192.168.1.101</code> 设备能够判断其他设备是否在同一个网络中（例如 <code>192.168.1.103</code> 设备），或者是在互联网上其他地方的完全不同的网络中。</p>
<p>有趣的是，你的 ISP 为你的路由器分配的外部 IP 地址可能是某个子网的一部分，该子网可能包括附近家庭或企业的许多其他 IP 地址。和内部 IP 地址一样，它也需要一个子网掩码才能工作。</p>
<p>子网掩码可以被视为 IP 地址的一种过滤器。通过子网掩码，设备可以查看 IP 地址，并弄清楚哪些部分是网络位，哪些部分是主机位。</p>
<p>然后利用这些信息，设备可以确定最佳的通信方式。</p>
<p>如果你曾浏览过路由器或计算机上的网络设置，你可能见过这个数字：<code>255.255.255.0</code>。</p>
<p>如果见过，你已经看到了一个非常常见的适用于简单家庭网络的子网掩码。</p>
<p>像 IPv4 地址一样，子网掩码也是 32 位。就像将 IP 地址转换为二进制一样，你也可以对子网掩码进行相同的转换。</p>
<p>例如，这里是我们之前的图表：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
</tbody>
</table>
<p>现在让我们转换第一个八比特，255：</p>
<table>
<thead>
<tr>
<th>128</th>
<th>64</th>
<th>32</th>
<th>16</th>
<th>8</th>
<th>4</th>
<th>2</th>
<th>1</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>很简单，对吧？所以任何一个八比特中的 <code>255</code> 在二进制中就是 <code>11111111</code>。这意味着 <code>255.255.255.0</code> 在二进制中实际上是 <code>11111111.11111111.11111111.00000000</code>。</p>
<p>以下是这两者的十进制和二进制表示：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>192.168.0.101</td>
<td>11000000.10101000.00000000.01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>这样排列后，很容易将 <code>192.168.0.101</code> 分成网络位和主机位。</p>
<p>只要二进制子网掩码中的某位为 1，二进制 IP 地址中的相同位就是网络的一部分，而不是主机的一部分。</p>
<p>由于八比特 <code>255</code> 的二进制形式是 <code>11111111</code>，所以 IP 地址中的整个八比特都是网络的一部分。因此，前三个八比特 <code>192.168.0</code> 是 IP 地址的网络部分，而 <code>101</code> 是主机部分。</p>
<p>换句话说，如果设备 <code>192.168.0.101</code> 想与另一个设备进行通信，使用子网掩码它知道任何IP地址为 <code>192.168.0.xxx</code> 的设备都在同一个本地网络上。</p>
<p>另一种表达方式是使用网络ID，它只是IP地址的网络部分。所以IP地址 <code>192.168.0.101</code> 的网络ID，子网掩码为 <code>255.255.255.0</code>，即 <code>192.168.0.0</code>。</p>
<h3 id="cidrcidr">CIDR 是什么及 CIDR 表示法？</h3>
<p><strong>CIDR</strong> 是无类域间路由的缩写，使用于 IPv4，最近也用于 IPv6 路由。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/1920px-IP_Address_Match.svg.png" alt="1920px-IP_Address_Match.svg" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://www.wikiwand.com/zh/articles/%E6%97%A0%E7%B1%BB%E5%88%AB%E5%9F%9F%E9%97%B4%E8%B7%AF%E7%94%B1">无类别域间路由</a></p>
<p>CIDR 于 1993 年引入，作为缓解 IPv4 地址消耗的一种方式。在此之前，互联网使用的是旧有的分类 IP 地址系统，该系统导致 IPv4 地址迅速枯竭。</p>
<p>CIDR 涵盖了几个主要概念。</p>
<p>第一个是可变长度子网掩码（VLSM），这基本上允许网络工程师在子网内创建子网。那些子网可以有不同的大小，从而减少了未使用的 IP 地址数量。</p>
<p>CIDR 引入的第二个主要概念是 CIDR 表示法。</p>
<p>CIDR 表示法实际上只是子网掩码的简写，表示 IP 地址可用的位数。例如，<code>192.168.0.101/24</code> 中的 <code>/24</code> 相当于 IP 地址 <code>192.168.0.101</code> 和子网掩码 <code>255.255.255.0</code>。</p>
<h3 id="cidr">CIDR 的计算方法</h3>
<p>要计算子网掩码的 CIDR 表示法，只需将子网掩码转换为二进制，然后计算其中的 1 的数量即可。例如：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>由于有三个八比特是 1，所以有 24 个 "on" 位，这意味着 CIDR 表示法为 <code>/24</code>。</p>
<p>你可以用任何一种方式书写，但我相信你会同意用 <code>/24</code> 比写 <code>255.255.255.0</code> 要简单很多。</p>
<p>这通常是在使用 IP 地址时进行的，所以让我们看看带有 IP 地址的相同子网掩码：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>192.168.0.101</td>
<td>11000000.10101000.00000000.01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>255.255.255.0</td>
<td>11111111.11111111.11111111.00000000</td>
</tr>
</tbody>
</table>
<p>子网掩码的前三个八比特全是 "on" 位，这意味着 IP 地址的前三个八比特全是网络位。</p>
<p>让我们更详细地看看最后的第四个八比特：</p>
<table>
<thead>
<tr>
<th>类型</th>
<th>十进制</th>
<th>二进制</th>
</tr>
</thead>
<tbody>
<tr>
<td>IP 地址</td>
<td>101</td>
<td>01100101</td>
</tr>
<tr>
<td>子网掩码</td>
<td>0</td>
<td>00000000</td>
</tr>
</tbody>
</table>
<p>在这种情况下，由于子网掩码中这个八比特的所有比特都是 “off”，我们可以确定 IP 地址中这个八比特的所有相应比特都是主机的一部分。</p>
<p>当你使用 CIDR 表示法时，通常会使用网络 ID。因此，IP 地址 <code>192.168.0.101</code> 和子网掩码 <code>255.255.255.0</code> 的 CIDR 表示法是 <code>192.168.0.0/24</code>。</p>
<p>若要查看更多关于如何计算给定 IP 地址和子网掩码的 CIDR 表示法和网络 ID 的示例，请观看以下视频：</p>
<figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/XQ3T14SIlV4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" name="fitvid0"></iframe>
          </div>
        </div>
      </figure>
<h2 id="ip">IP 地址分类</h2>
<p>现在我们已经了解了一些子网划分和 CIDR 的基本示例，让我们放大来看一下所谓的“分类网络”。</p>
<p>在开发子网划分之前，所有的 IP 地址都属于特定的类别：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/subnetting.png" alt="subnetting" width="600" height="400" loading="lazy"></p>
<p>来源：<a href="https://community.spiceworks.com/t/subnetting-for-dummies/970210">简单子网划分教程</a></p>
<p>注意，这里还有 D 类和 E 类 IP 地址，但我们将在稍后详细介绍这些内容。</p>
<p>分类 IP 地址为网络工程师提供了一种为不同组织提供一系列有效 IP 地址的方法。</p>
<p>这个方法有很多问题，最终导致了子网划分的出现。但在我们深入探讨这些问题之前，让我们先仔细看看不同的 IP 地址类别。</p>
<h3 id="aip">A 类 IP 地址</h3>
<p>对于 A 类 IP 地址，前八位（8 位 / 1 字节）表示网络 ID，其余三段（24 位 / 3 字节）表示主机 ID。</p>
<p>A 类 IP 地址范围从 <code>1.0.0.0</code> 到 <code>127.255.255.255</code>，默认子网掩码为 <code>255.0.0.0</code>（或 CIDR 的 <code>/8</code>）。</p>
<p>这意味着 A 类地址可以有 128（2^7）个网络，每个网络有 16,777,214（2^24-2）个可用地址。</p>
<p>另外，请注意，在 A 类地址范围内，<code>127.0.0.0</code> 到 <code>127.255.255.255</code> 这一范围被保留用于主机循环地址（参见 <a href="https://datatracker.ietf.org/doc/html/rfc5735">RFC5735</a>）。</p>
<h3 id="bip">B 类 IP 地址</h3>
<p>对于 B 类 IP 地址，前两段（16 位 / 2 字节）表示网络 ID，其余两段（16 位 / 2 字节）表示主机 ID。</p>
<p>B 类 IP 地址范围从 <code>128.0.0.0</code> 到 <code>191.255.255.255</code>，默认子网掩码为 <code>255.255.0.0</code>（或 CIDR 的 <code>/16</code>）。</p>
<p>B 类寻址每个网络可有 16,384（2^14）个网络地址和 65,534（2^16）个可用地址。</p>
<h3 id="cip">C 类 IP 地址</h3>
<p>对于 C 类 IP 地址，前三个八位字节（24 位 / 3 字节）代表网络 ID，最后一个八位字节（8 位 / 1 字节）是主机 ID。</p>
<p>C 类 IP 地址的范围是从 <code>192.0.0.0</code> 到 <code>223.255.255.255</code>，默认子网掩码为 <code>255.255.255.0</code>（或 CIDR 记法中的 <code>/24</code>）。</p>
<p>C 类 IP 地址对应 2,097,152（2^21）个网络，每个网络有 254（2^8 - 2）个可用地址。</p>
<h3 id="deip">D 类和 E 类 IP 地址</h3>
<p>最后两类是 D 类和 E 类。</p>
<p>D 类 IP 地址保留用于多播。它们的范围是从 <code>224.0.0.0</code> 到 <code>239.255.255.255</code>。</p>
<p>E 类 IP 地址是实验性的，范围是 <code>240.0.0.0</code> 以上。</p>
<h3 id="ip">类划分 IP 地址的问题</h3>
<p>类划分 IP 地址的主要问题是不高效，会导致大量 IP 地址的浪费。</p>
<p>例如，设想你当时是一个大型组织的一部分。你的公司有 1,000 名员工，这意味着它属于 B 类。</p>
<p>但如果你往上看，你会发现 B 类网络可以支持多达 65,534 个可用地址。这远远超过了你的组织可能需要的数量，即使每个员工有多个带唯一地址的设备。</p>
<p>并且你的组织不可能退回到 C 类，因为没有足够的可用 IP 地址。</p>
<p>因此，当 IPv4 地址变得普及时，使用类 IP 地址的那段时间里，人们很快就意识到需要一个更好的系统来确保我们不会用光所有约 42 亿个可用地址。</p>
<p>自从类 IP 地址在 1993 年被 CIDR 取代后，就不再使用了，现在主要被研究用来理解早期互联网架构，以及为什么子网划分很重要。</p>
<h2 id="">希望这个速查表对你有所帮助</h2>
<p>如果你觉得这有帮助，请与朋友分享，让更多人从中受益。</p>
<p>此外，欢迎在 <a href="https://x.com/kriskoishigawa">Twitter</a> 上联系我，告诉我你的想法。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ freeCodeCamp 课程重大更新在圣诞节上线 ]]>
                </title>
                <description>
                    <![CDATA[ 圣诞快乐，campers！🎄 freeCodeCamp 刚刚发布了大量免费的学习工具，方便大家在假期里体验： 🏗️ 新的认证全栈开发者课程上线啦！ 🗨️ 新的开发者英语 CEFR B1 级别课程 🤳 我们的移动应用程序进行了重大更新 freeCodeCamp 认证全栈开发者路径 以下是全新的认证全栈开发者路径的完整内容，非常丰富： 🛠️ 64 个工作坊 – 涵盖从 HTML 到 SQL 到 Python 的互动式分步骤编程课程（现已上线 42 个） 🏛️ 513 堂讲座 – 涵盖计算机科学概念的短视频，包含测试你是否理解的选择题（现已上线 313 个） ⚗️ 83 个实验室 – 从空白编辑器和测试套件开始，你需要构建项目以通过所有测试（现已上线 60 个） 📰 62 份复习材料 – 每个模块的综合主题列表，帮助你复习并准备测验和考试（现已上线 46 份） 🔬 ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/christmas-2025-freecodecamp-curriculum-updates/</link>
                <guid isPermaLink="false">676a4d346b2a470461e6e4f3</guid>
                
                    <category>
                        <![CDATA[ 开源 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 社区 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 24 Dec 2024 05:19:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/12/19f1c48b-0d23-4bdf-882b-9f008e288719.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/christmas-2025-freecodecamp-curriculum-updates/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Major freeCodeCamp Curriculum Updates Now Live in 2025</a>
      </p><!--kg-card-begin: markdown--><p>圣诞快乐，campers！🎄 freeCodeCamp 刚刚发布了大量免费的学习工具，方便大家在假期里体验：</p>
<p>🏗️ 新的认证全栈开发者课程上线啦！</p>
<p>🗨️ 新的开发者英语 CEFR B1 级别课程</p>
<p>🤳 我们的移动应用程序进行了重大更新</p>
<h2 id="freecodecamp">freeCodeCamp 认证全栈开发者路径</h2>
<p>以下是全新的认证全栈开发者路径的完整内容，非常丰富：</p>
<p>🛠️ 64 个工作坊 – 涵盖从 HTML 到 SQL 到 Python 的互动式分步骤编程课程（现已上线 42 个）</p>
<p>🏛️ 513 堂讲座 – 涵盖计算机科学概念的短视频，包含测试你是否理解的选择题（现已上线 313 个）</p>
<p>⚗️ 83 个实验室 – 从空白编辑器和测试套件开始，你需要构建项目以通过所有测试（现已上线 60 个）</p>
<p>📰 62 份复习材料 – 每个模块的综合主题列表，帮助你复习并准备测验和考试（现已上线 46 份）</p>
<p>🔬 66 个测验 – 确认你掌握全栈开发概念和工具（现已上线 46 个）</p>
<p>🏔️ 1 个终极项目 – 你将为自己的作品集构建一个大型独特的项目，此项目将由 freeCodeCamp 社区的教师进行评审（2025 年上线）</p>
<p>🤺 1 次期末考试 – 全面的监考式认证考试，共 90 个问题，将在 freeCodeCamp 的新开源考试环境中进行（2025 年上线）</p>
<p>即使你以前已经学习过其中的一些主题，我还是建议你从头开始学习。</p>
<p>你可以立即开始学习<a href="https://www.freecodecamp.org/learn/full-stack-developer/">新的认证全栈开发者课程</a>。</p>
<h2 id="cefrb1">开发者英语课程 CEFR B1 级别</h2>
<p>去年圣诞节，我们发布了 CEFR A2 级别的英语课程。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735002125376/5eec4303-900b-4423-980a-cfa68a2962a0.png" alt="5eec4303-900b-4423-980a-cfa68a2962a0" width="600" height="400" loading="lazy"></p>
<p>经过一年的努力，我很高兴地告诉大家，我们不仅上线了所有内容，还推出了相当一部分 B1 级别课程。</p>
<p>认证考试也将在 2025 年上线。</p>
<p>你可以尝试我们的 <a href="https://www.freecodecamp.org/learn/b1-english-for-developers/">CEFR B1 级别开发者英语认证课程</a>。</p>
<h2 id="freecodecampiphoneandroid">freeCodeCamp iPhone 和 Android 应用程序</h2>
<p>freeCodeCamp 移动应用程序比之前更加出色。我们的 Flutter 代码库刚刚收到 1,000 个 commits！</p>
<p>你现在可以：</p>
<p>📺 观看我们的课程</p>
<p>📚 阅读我们的书籍</p>
<p>🤳 直接在手机上快速学习课程</p>
<p>在 iPhone/Android 上下载并留下五星好评。⭐️⭐️⭐️⭐️⭐️ 😉</p>
<p><a href="https://play.google.com/store/apps/details?id=org.freecodecamp&amp;hl=zh_CN">获取 Android 应用</a></p>
<p><a href="https://apps.apple.com/cn/app/freecodecamp/id6446908151">获取 iPhone 应用</a></p>
<h2 id="2025">2025 年将会很精彩。</h2>
<p>再次感谢所有为 freeCodeCamp 课程和我们的众多开源项目做出贡献的人们。</p>
<p>任何人都可以随时在论坛和 Discord 上获得 camper 们的帮助，这太棒了。</p>
<p>鼓励你的朋友参与进来。大家可以从<a href="https://contribute.freecodecamp.org">我们的开源贡献文档</a>开始。</p>
<p>最后，感谢所有捐款支持 freeCodeCamp 使命的人们。我们才刚刚开始。🥞</p>
<p>请鼓励你的朋友也来支持我们的慈善事业。我们共同努力，让每个人都能获得免费的世界级教育。你可以和全球 11,043 位慷慨的人们一起成为我们的<a href="https://www.freecodecamp.org/donate">支持者</a>。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Bash 脚本教程——Linux Shell 脚本和命令行入门教程 ]]>
                </title>
                <description>
                    <![CDATA[ 在 Linux 中，流程自动化在很大程度上依赖于 shell 脚本。这涉及到创建一个包含一系列命令的文件，这些命令可以一起执行。 在本文中，我们将从 bash 脚本编写的基础知识开始，包括变量、命令、输入/输出和调试。我们还会通过示例来学习每个知识点。 让我们开始吧。🚀 目录  1. 前提条件  2. 简介  * Bash 脚本的定义  * Bash 脚本的优点  * Bash Shell 和命令行界面的概述  3. 如何开始 Bash 脚本编写  * 如何从命令行运行 Bash 命令  * 如何创建和执行 Bash 脚本  4. Bash 脚本基础知识  * ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/bash-scripting-tutorial-linux-shell-script-and-command-line-for-beginners/</link>
                <guid isPermaLink="false">66b22ce179db950405c05254</guid>
                
                    <category>
                        <![CDATA[ Bash ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Thu, 19 Dec 2024 11:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/08/Copy-of-Cast-a-Function-in-SQL---Convert-Char-to-Int-SQL-Server-Example.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/bash-scripting-tutorial-linux-shell-script-and-command-line-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Bash Scripting Tutorial – Linux Shell Script and Command Line for Beginners</a>
      </p><!--kg-card-begin: markdown--><p>在 Linux 中，流程自动化在很大程度上依赖于 shell 脚本。这涉及到创建一个包含一系列命令的文件，这些命令可以一起执行。</p>
<p>在本文中，我们将从 bash 脚本编写的基础知识开始，包括变量、命令、输入/输出和调试。我们还会通过示例来学习每个知识点。</p>
<p>让我们开始吧。🚀</p>
<h2 id="">目录</h2>
<ol>
<li><a href="#pre-requisites">前提条件</a></li>
<li><a href="#introduction">简介</a></li>
</ol>
<ul>
<li><a href="#definition-of-bash-scripting">Bash 脚本的定义</a></li>
<li><a href="#advantages-of-bash-scripting">Bash 脚本的优点</a></li>
<li><a href="#overview-of-bash-shell-and-command-line-interface">Bash Shell 和命令行界面的概述</a></li>
</ul>
<ol start="3">
<li><a href="#how-to-get-started-with-bash-scripting">如何开始 Bash 脚本编写</a></li>
</ol>
<ul>
<li><a href="#how-to-run-bash-commands-from-the-command-line">如何从命令行运行 Bash 命令</a></li>
<li><a href="#how-to-create-and-execute-bash-scripts">如何创建和执行 Bash 脚本</a></li>
</ul>
<ol start="4">
<li><a href="#bash-scripting-basics">Bash 脚本基础知识</a></li>
</ol>
<ul>
<li><a href="#comments-in-bash-scripting">Bash 脚本中的注释</a></li>
<li><a href="#variables-and-data-types-in-bash">Bash 中的变量和数据类型</a></li>
<li><a href="#input-and-output-in-bash-scripts">Bash 脚本中的输入和输出</a></li>
<li><a href="#basic-bash-commands-echo-read-etc-">基本的 Bash 命令（echo、read 等）</a></li>
<li><a href="#conditional-statements-if-else-">条件语句（if/else）</a></li>
</ul>
<ol start="5">
<li><a href="#looping-and-branching-in-bash">Bash 中的循环和分支</a></li>
</ol>
<ul>
<li><a href="#while-loop">while 循环</a></li>
<li><a href="#for-loop">for 循环</a></li>
<li><a href="#case-statements">case 语句</a></li>
</ul>
<ol start="6">
<li><a href="#how-to-schedule-scripts-using-cron">如何使用 cron 调度脚本</a></li>
<li><a href="#how-to-debug-and-troubleshoot-bash-scripts">如何调试和排除 Bash 脚本的故障</a></li>
<li><a href="#conclusion">总结</a></li>
</ol>
<ul>
<li><a href="#resources-for-learning-more-about-bash-scripting">学习更多关于 Bash 脚本的资源</a></li>
</ul>
<h2 id="pre-requisites">前提条件</h2>
<p>为了跟随本教程的进度，你应具备以下条件：</p>
<ul>
<li>可以访问命令行的 Linux 运行版本。</li>
</ul>
<p>如果你没有安装 Linux 或者你是初学者，你可以通过 <a href="https://replit.com/~">Replit</a> 很容易访问 Linux 命令行。Replit 是一个基于浏览器的 IDE，你可以在几分钟内访问 bash shell。</p>
<p>你也可以通过 WSL（Windows Subsystem for Linux）在你的 Windows 系统上安装 Linux。<a href="https://www.freecodecamp.org/news/how-to-install-wsl2-windows-subsystem-for-linux-2-on-windows-10/">这里</a> 有一个相关教程。</p>
<h2 id="introduction">简介</h2>
<h3 id="definition-of-bash-scripting">Bash 脚本的定义</h3>
<p>Bash 脚本是一个包含一系列命令的文件，这些命令由 bash 程序逐行执行。它允许你通过命令行执行一系列操作，如导航到特定目录、创建文件夹和启动进程。</p>
<p>通过将这些命令保存在脚本中，你可以多次重复相同的操作，并通过运行脚本执行它们。</p>
<h3 id="advantages-of-bash-scripting">Bash 脚本的优点</h3>
<p>Bash 脚本是一种强大且灵活的工具，可以用于自动化系统管理任务、管理系统资源以及在 Unix/Linux 系统中执行其他例行任务。Shell 脚本的一些优点包括：</p>
<ul>
<li><strong>自动化</strong>：Shell 脚本允许你自动化重复性任务和过程，节省时间并减少手动执行时可能出现的错误。</li>
<li><strong>可移植性</strong>：Shell 脚本可以在各种平台和操作系统上运行，包括 Unix、Linux、macOS，甚至通过使用模拟器或虚拟机在 Windows 上运行。</li>
<li><strong>灵活性</strong>：Shell 脚本高度可定制，可以轻松修改以满足特定需求。它们还可以与其他编程语言或实用程序结合，创建更强大的脚本。</li>
<li><strong>易访问性</strong>：Shell 脚本易于编写，不需要任何特殊工具或软件。它们可以使用任何文本编辑器进行编辑，并且大多数操作系统都有内置的 shell 解释器。</li>
<li><strong>集成</strong>：Shell 脚本可以与其他工具和应用程序集成，如数据库、Web 服务器和云服务，从而实现更复杂的自动化和系统管理任务。</li>
<li><strong>调试</strong>：Shell 脚本易于调试，大多数 shell 都内置调试和错误报告工具，可以帮助快速识别和修复问题。</li>
</ul>
<h3 id="overview-of-bash-shell-and-command-line-interface">Bash Shell 和命令行界面的概述</h3>
<p>"Shell" 和 "bash" 这两个术语可以互换使用。但两者之间有细微的区别。</p>
<p>"Shell" 这个术语是指提供命令行界面以与操作系统交互的程序。Bash（Bourne-Again SHell）是最常用的 Unix/Linux shell 之一，并且是许多 Linux 发行版中的默认 shell。</p>
<p>Shell 或命令行界面看起来是这样的：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-135.png" alt="image-135" width="600" height="400" loading="lazy"></p>
<p>Shell 接收用户的命令并显示输出。</p>
<p>在上述输出中，<code>zaira@Zaira</code> 是 shell 提示符。当 shell 以交互方式使用时，在等待用户命令时会显示一个 <code>$</code>。</p>
<p>如果 shell 以 root（具有管理权的用户）身份运行，提示符会变为 <code>#</code>。超级用户 shell 提示符看起来是这样的：</p>
<pre><code class="language-bash">[root@host ~]#
</code></pre>
<p>Bash 是 shell 的一种，还有其他 shell 可供使用，如 Korn shell（ksh）、C shell（csh）和 Z shell（zsh）。每种 shell 都有自己的语法和功能，但它们都有一个共同的目的，那就是提供一个命令行界面来与操作系统交互。</p>
<pre><code class="language-bash">ps
</code></pre>
<p>这是我的输出结果：</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2023/03/image-134.png" alt="检查 shell 类型，我使用的是 bash shell" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>检查 shell 类型，我使用的是 bash shell</figcaption>
</figure>
<p>总结一下，“shell” 是指任何提供命令行界面的程序的一个广泛术语，“Bash” 是一种特定类型的 shell，在 Unix/Linux 系统中广泛使用。</p>
<p>注意：在本教程中，我们将使用 “bash" shell。</p>
<h2 id="how-to-get-started-with-bash-scripting">如何开始编写 Bash 脚本</h2>
<h3 id="how-to-run-bash-commands-from-the-command-line">从命令行运行 Bash 命令</h3>
<p>如前所述，shell 提示符看起来像这样：</p>
<pre><code class="language-bash">[username@host ~]$
</code></pre>
<p>你可以在 <code>$</code> 符号后输入任何命令，并在终端上看到输出。</p>
<p>通常，命令遵循以下语法：</p>
<pre><code>command [选项] 参数
</code></pre>
<p>让我们讨论一些基本的 bash 命令并查看它们的输出。确保跟着做哦 :)</p>
<ul>
<li><code>date</code>：显示当前日期</li>
</ul>
<pre><code class="language-bash">zaira@Zaira:~/shell-tutorial$ date
Tue Mar 14 13:08:57 PKT 2023
</code></pre>
<ul>
<li><code>pwd</code>：显示当前工作目录。</li>
</ul>
<pre><code class="language-bash">zaira@Zaira:~/shell-tutorial$ pwd
/home/zaira/shell-tutorial
</code></pre>
<ul>
<li><code>ls</code>：列出当前目录的内容。</li>
</ul>
<pre><code class="language-bash">zaira@Zaira:~/shell-tutorial$ ls
check_plaindrome.sh  count_odd.sh  env  log  temp
</code></pre>
<ul>
<li><code>echo</code>：打印一段文本或变量的值到终端。</li>
</ul>
<pre><code class="language-bash">zaira@Zaira:~/shell-tutorial$ echo "Hello bash"
Hello bash
</code></pre>
<p>你可以始终使用 <code>man</code> 命令查看命令手册。</p>
<p>例如，<code>ls</code> 的手册看起来像这样：</p>
<figure class="kg-card kg-card-image kg-card-hascaption">
    <img src="https://www.freecodecamp.org/news/content/images/2023/03/image-138.png" alt="你可以使用 `man` 命令详细查看命令的选项" class="kg-image" width="600" height="400" loading="lazy">
    <figcaption>你可以使用 `man` 命令详细查看命令的选项</figcaption>
</figure>
<h3 id="how-to-create-and-execute-bash-scripts">如何创建和执行 Bash 脚本</h3>
<h4 id="">脚本命名约定</h4>
<p>按照惯例，bash 脚本以 <code>.sh</code> 结尾。然而，即使没有 <code>sh</code> 扩展名，bash 脚本也可以正常运行。</p>
<h4 id="shebang">添加 Shebang</h4>
<p>Bash 脚本以 <code>shebang</code> 开头。Shebang 是 <code>bash #</code> 和 <code>bang !</code> 的组合，后跟 bash shell 路径。这是脚本的第一行。Shebang 告诉 shell 通过 bash shell 执行它。Shebang 指向 bash 解释器的绝对路径。</p>
<p>以下是 shebang 语句的示例。</p>
<pre><code class="language-bash">#!/bin/bash
</code></pre>
<p>你可以使用以下命令找到你的 bash shell 路径（可能与上述路径不同）：</p>
<pre><code class="language-bash">which bash
</code></pre>
<h4 id="bash">创建我们的第一个 bash 脚本</h4>
<p>我们的第一个脚本提示用户输入路径。然后，它将列出路径的内容。</p>
<p>使用 <code>vi</code> 命令创建一个名为 <code>run_all.sh</code> 的文件。您可以使用任何您喜欢的编辑器。</p>
<pre><code class="language-bash">vi run_all.sh
</code></pre>
<p>在文件中添加以下命令并保存：</p>
<pre><code class="language-bash">#!/bin/bash
echo "今天是 " `date`

echo -e "\n请输入目录路径"
read the_path

echo -e "\n 你的路径包含以下文件和文件夹："
ls $the_path
</code></pre>
<p>打印用户提供的目录内容的脚本</p>
<p>让我们逐行仔细看看脚本。我将再次显示相同的脚本，但这次带有行号。</p>
<pre><code class="language-bash">  1 #!/bin/bash
  2 echo "今天是 " `date`
  3
  4 echo -e "\n请输入目录路径"
  5 read the_path
  6
  7 echo -e "\n 你的路径包含以下文件和文件夹："
  8 ls $the_path
</code></pre>
<ul>
<li>第 1 行：Shebang (<code>#!/bin/bash</code>) 指向 bash shell 路径。</li>
<li>第 2 行：<code>echo</code> 命令在终端显示当前日期和时间。注意 <code>date</code> 在反引号中。</li>
<li>第 4 行：我们希望用户输入一个有效的路径。</li>
<li>第 5 行：<code>read</code> 命令读取输入并将其存储在变量 <code>the_path</code> 中。</li>
<li>第 8 行：<code>ls</code> 命令使用存储路径的变量并显示当前的文件和文件夹。</li>
</ul>
<h4 id="bash">执行 bash 脚本</h4>
<p>为了使脚本可执行，请使用以下命令为您的用户分配执行权限：</p>
<pre><code class="language-bash">chmod u+x run_all.sh
</code></pre>
<p>这里，</p>
<ul>
<li><code>chmod</code> 修改文件的所有权以供当前用户使用：<code>u</code>。</li>
<li><code>+x</code> 将执行权限添加到当前用户。这意味着作为所有者的用户现在可以运行该脚本。</li>
<li><code>run_all.sh</code> 是我们希望运行的文件。</li>
</ul>
<p>您可以使用下列任何方法运行脚本：</p>
<ul>
<li><code>sh run_all.sh</code></li>
<li><code>bash run_all.sh</code></li>
<li><code>./run_all.sh</code></li>
</ul>
<p>让我们看看它在运行中的样子 🚀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/run-script-bash-2.gif" alt="run-script-bash-2" width="600" height="400" loading="lazy"></p>
<h2 id="bash-scripting-basics">Bash 脚本基础</h2>
<h3 id="comments-in-bash-scripting">Bash 脚本中的注释</h3>
<p>Bash 脚本中的注释以 <code>#</code> 开头。这意味着任何以 <code>#</code> 开头的行都是注释，将被解释器忽略。</p>
<p>注释对于文档编写非常有帮助，并且是帮助他人理解代码的一个好习惯。</p>
<p>以下是注释的示例：</p>
<pre><code class="language-bash"># 这是一个示例注释
# 这两行将被解释器忽略
</code></pre>
<h3 id="variables-and-data-types-in-bash">Bash 中的变量和数据类型</h3>
<p>变量让您存储数据。您可以在脚本中使用变量读取、访问和操作数据。</p>
<p>Bash 中没有数据类型。在 Bash 中，变量能够存储数值、单个字符或字符串。</p>
<p>在 Bash 中，您可以通过以下方式使用和设置变量值：</p>
<pre><code>
```bash
country=Pakistan
</code></pre>
<p>2. &nbsp;根据从程序或命令获取的输出，使用命令替换赋值。请注意，$ 是访问现有变量值所需的。</p>
<pre><code class="language-bash">same_country=$country
</code></pre>
<p>这会将 <code>country</code> 的值赋给新变量 <code>same_country</code></p>
<p>要访问变量值，请在变量名称后附加 <code>$</code>。</p>
<pre><code class="language-bash">zaira@Zaira:~$ country=Pakistan
zaira@Zaira:~$ echo $country
Pakistan
zaira@Zaira:~$ new_country=$country
zaira@Zaira:~$ echo $new_country
Pakistan
</code></pre>
<p>赋值和打印变量值</p>
<h3 id="">变量命名规范</h3>
<p>在 Bash 脚本中，以下是变量命名规范：</p>
<ol>
<li>变量名称应以字母或下划线 (<code>_</code>) 开头。</li>
<li>变量名称可以包含字母、数字和下划线 (<code>_</code>)。</li>
<li>变量名称区分大小写。</li>
<li>变量名称不应包含空格或特殊字符。</li>
<li>使用能反映变量用途的描述性名称。</li>
<li>避免使用保留关键字（如 <code>if</code>, <code>then</code>, <code>else</code>, <code>fi</code> 等）作为变量名称。</li>
</ol>
<p>以下是一些合法变量名称的示例：</p>
<pre><code class="language-bash">name
count
_var
myVar
MY_VAR
</code></pre>
<p>以下是一些非法变量名称的示例：</p>
<pre><code class="language-bash">2ndvar (变量名称以数字开头)
my var (变量名称包含空格)
my-var (变量名称包含连字符)
</code></pre>
<p>遵循这些命名规范有助于使 Bash 脚本更具可读性和易于维护。</p>
<h3 id="input-and-output-in-bash-scripts">Bash 脚本中的输入和输出</h3>
<h4 id="">收集输入</h4>
<p>在本节中，我们将讨论一些为脚本提供输入的方法。</p>
<ol>
<li>读取用户输入并将其存储在变量中</li>
</ol>
<p>我们可以使用 <code>read</code> 命令读取用户输入。</p>
<pre><code class="language-bash">#!/bin/bash 

echo "What's your name?" 

read entered_name 

echo -e "\nWelcome to bash tutorial" $entered_name
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/name-sh.gif" alt="name-sh" width="600" height="400" loading="lazy"></p>
<p>2. &nbsp;从文件读取</p>
<p>此代码从名为 <code>input.txt</code> 的文件中读取每一行并将其打印到终端。我们将在本文稍后学习 while 循环。</p>
<pre><code class="language-bash">while read line
do
  echo $line
done &lt; input.txt
</code></pre>
<p>3. &nbsp;命令行参数</p>
<p>在 bash 脚本或函数中，<code>$1</code> 表示传递的初始参数，<code>$2</code> 表示传递的第二个参数，以此类推。</p>
<p>此脚本将名字作为命令行参数并打印个性化问候语。</p>
<pre><code class="language-bash">echo "Hello, $1!"
</code></pre>
<p>我们将 <code>Zaira</code> 作为参数提供给脚本。</p>
<pre><code class="language-bash">#!/bin/bash
echo "Hello, $1!"
</code></pre>
<p>脚本代码：<code>greeting.sh</code></p>
<p><strong>输出：</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/name-sh-1.gif" alt="name-sh-1" width="600" height="400" loading="lazy"></p>
<h4 id="">显示输出</h4>
<p>这里我们将讨论一些从脚本接收输出的方法。</p>
<ol>
<li>打印到终端：</li>
</ol>
<pre><code class="language-bash">echo "Hello, World!"
</code></pre>
<p>这会将文本 “Hello, World!” 打印到终端。</p>
<p>2. &nbsp;写入文件：</p>
<pre><code class="language-bash">echo "This is some text." &gt; output.txt
</code></pre>
<p>这会将文本 "This is some text." 写入名为 <code>output.txt</code> 的文件。请注意，<code>&gt;</code> 操作符会覆盖文件内容（如果文件已存在）。</p>
<p>3. &nbsp;追加到文件：</p>
<pre><code class="language-bash">echo "More text." &gt;&gt; output.txt
</code></pre>
<p>这会将文本 "More text." 追加到 <code>output.txt</code> 文件的末尾。</p>
<p>4. &nbsp;重定向输出：</p>
<pre><code class="language-bash">ls &gt; files.txt
</code></pre>
<p>这会列出当前目录中的文件并将输出写入名为 <code>files.txt</code> 的文件。您可以通过这种方式将任何命令的输出重定向到文件。</p>
<h3 id="basic-bash-commands-echo-read-etc-">基本 Bash 命令（echo、read 等）</h3>
<p>以下是一些最常用的 bash 命令列表：</p>
<ol>
<li><code>cd</code>: 切换到不同目录。</li>
<li><code>ls</code>: 列出当前目录的内容。</li>
<li><code>mkdir</code>: 创建新目录。</li>
<li><code>touch</code>: 创建新文件。</li>
<li><code>rm</code>: 删除文件或目录。</li>
<li><code>cp</code>: 复制文件或目录。</li>
<li><code>mv</code>: 移动或重命名文件或目录。</li>
<li><code>echo</code>: 将文本打印到终端。</li>
<li><code>cat</code>: 连接并打印文件内容。</li>
<li><code>grep</code>: 在文件中搜索模式。</li>
<li><code>chmod</code>: 更改文件或目录的权限。</li>
<li><code>sudo</code>: 以管理权限运行命令。</li>
<li><code>df</code>: 显示可用磁盘空间。</li>
<li><code>history</code>: 显示先前执行的命令列表。</li>
<li><code>ps</code>: 显示有关正在运行的进程的信息。</li>
</ol>
<h3 id="conditional-statements-if-else-">条件语句（if/else）</h3>
<p>产生布尔结果（真或假）的表达式称为条件。有多种方法来评估条件，包括 <code>if</code>、<code>if-else</code>、<code>if-elif-else</code> 和嵌套条件。</p>
<p><strong><strong>语法</strong></strong>：</p>
<pre><code class="language-bash">if [[ condition ]];
then
	statement
elif [[ condition ]]; then
	statement 
else
	do this by default
fi
</code></pre>
<p>Bash 条件语句的语法</p>
<p>我们可以使用逻辑运算符（如 AND <code>-a</code> 和 OR <code>-o</code>）进行更具意义的比较。</p>
<pre><code class="language-bash">if [ $a -gt 60 -a $b -lt 100 ]
</code></pre>
<p>此语句检查两个条件是否都为真：a 大于 60 且 b 小于 100。</p>
<p>让我们看一个使用 <code>if</code>、<code>if-else</code> 和 <code>if-elif-else</code> 语句的 Bash 脚本示例，以确定用户输入的数字是正数、负数还是零：</p>
<pre><code class="language-bash">#!/bin/bash

echo "Please enter a number: "
read num
</code></pre>
<p>确定数字是正数、负数还是零的脚本</p>
<p>该脚本首先提示用户输入一个数字。然后，它使用一个 <code>if</code> 语句检查该数字是否大于 0。如果是的话，脚本输出该数字是正数。如果该数字不大于 0，脚本进入下一个语句，即 <code>if-elif</code> 语句。在这里，脚本检查该数字是否小于 0。如果是的话，脚本输出该数字是负数。最后，如果该数字既不大于 0 也不小于 0，脚本使用 <code>else</code> 语句输出该数字是零。</p>
<p>来看一下它的运行情况 🚀</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/test-odd.gif" alt="test-odd" width="600" height="400" loading="lazy"></p>
<h2 id="looping-and-branching-in-bash">在 Bash 中的循环和分支</h2>
<h3 id="while-loop">While 循环</h3>
<p>While 循环检查一个条件，并且在条件为 <code>true</code> 时持续循环。我们需要提供一个计数器语句来增加计数器以控制循环的执行。</p>
<p>在下面的例子中，<code>(( i += 1 ))</code> 是增加 <code>i</code> 值的计数器语句。该循环将恰好运行 10 次。</p>
<pre><code class="language-bash">#!/bin/bash
i=1
while [[ $i -le 10 ]] ; do
   echo "$i"
  (( i += 1 ))
done
</code></pre>
<p>While 循环迭代 10 次。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-187.png" alt="image-187" width="600" height="400" loading="lazy"></p>
<h3 id="for-loop">For 循环</h3>
<p><code>for</code> 循环，就像 <code>while</code> 循环一样，允许你执行特定次数的语句。每个循环在语法和用法上有所不同。</p>
<p>在下面的例子中，该循环将迭代 5 次。</p>
<pre><code class="language-bash">#!/bin/bash

for i in {1..5}
do
    echo $i
done
</code></pre>
<p>For 循环迭代 5 次。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/03/image-186.png" alt="image-186" width="600" height="400" loading="lazy"></p>
<h3 id="case-statements">Case 语句</h3>
<p>在 Bash 中，case 语句用于将给定值与一系列模式进行比较，并根据第一个匹配的模式执行一段代码。Bash 中 case 语句的语法如下：</p>
<pre><code class="language-bash">case expression in
    pattern1)
        # code to execute if expression matches pattern1
        ;;
    pattern2)
        # code to execute if expression matches pattern2
        ;;
    pattern3)
        # code to execute if expression matches pattern3
        ;;
    *)
        # code to execute if none of the above patterns match expression
        ;;
esac
</code></pre>
<p>Case 语句语法</p>
<p>这里，“expression” 是我们想要比较的值，“pattern1”、“pattern2”、“pattern3”等是我们想要进行比较的模式。</p>
<p>双分号 “;;” 将要为每个模式执行的代码块分隔开来。星号 “*” 代表默认情况，当没有一个指定的模式匹配该表达式时执行。</p>
<p>让我们看一个例子。</p>
<pre><code class="language-bash">fruit="apple"

case $fruit in
    "apple")
        echo "This is a red fruit."
        ;;
    "banana")
        echo "This is a yellow fruit."
        ;;
    "orange")
        echo "This is an orange fruit."
        ;;
    *)
        echo "Unknown fruit."
        ;;
esac
</code></pre>
<p>Case 语句示例</p>
<p>在这个例子中，由于 “fruit” 的值是 “apple”，第一个模式匹配，并且执行 echo “This is a red fruit.” 的代码块。如果 “fruit” 的值是 “banana”，第二个模式将匹配并执行 echo “This is a yellow fruit.” 的代码块，依此类推。如果 “fruit” 的值不匹配任何指定的模式，则执行默认情况，输出 “Unknown fruit.”。</p>
<h2 id="how-to-schedule-scripts-using-cron">如何使用 cron 安排脚本</h2>
<p>Cron 是 Unix-like 操作系统中用于作业调度的强大工具。通过配置 cron，你可以设置自动作业在每日、每周、每月或特定时间运行。cron 提供的自动化能力在 Linux 系统管理中起到了至关重要的作用。</p>
<p>以下是调度 crons 的语法：</p>
<pre><code class="language-bash"># Cron job example
* * * * * sh /path/to/script.sh
</code></pre>
<p>这里，<code>*</code> 代表分别的分钟、小时、日、月、周几。</p>
<p>以下是一些安排 cron 作业的示例。</p>
<table>
<thead>
<tr>
<th>安排</th>
<th>描述</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0 0 * * *</code></td>
<td>每天午夜运行一个脚本</td>
<td><code>0 0 * * * /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>*/5 * * * *</code></td>
<td>每 5 分钟运行一个脚本</td>
<td><code>*/5 * * * * /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 6 * * 1-5</code></td>
<td>从星期一到星期五每天早上 6 点运行一个脚本</td>
<td><code>0 6 * * 1-5 /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 0 1-7 * *</code></td>
<td>每个月的前 7 天运行一个脚本</td>
<td><code>0 0 1-7 * * /path/to/script.sh</code></td>
</tr>
<tr>
<td><code>0 12 1 * *</code></td>
<td>每个月的第一天中午 12 点运行一个脚本</td>
<td><code>0 12 1 * * /path/to/script.sh</code></td>
</tr>
</tbody>
</table>
<h4 id="crontab">使用 crontab</h4>
<p><code>crontab</code> 工具用于添加和编辑 cron 作业。</p>
<p><code>crontab -l</code> 列出特定用户已经安排好的脚本。</p>
<p>你可以通过 <code>crontab -e</code> 添加和编辑 cron。</p>
<p>你可以在我的<a href="https://www.freecodecamp.org/news/cron-jobs-in-linux/">另一篇文章</a>中阅读更多关于 cron 作业的内容。</p>
<h2 id="how-to-debug-and-troubleshoot-bash-scripts">如何调试和排除 Bash 脚本的故障</h2>
<p>调试和排除故障是任何 Bash 脚本编写者的重要技能。虽然 Bash 脚本可以非常强大，但它们也容易出现错误和意外行为。在本节中，我们将讨论一些调试和排除 Bash 脚本故障的技巧和技术。</p>
<p>调试 Bash 脚本最有用的技巧之一是在脚本的开头设置 <code>set -x</code> 选项。这个选项启用了调试模式，使得 Bash 会在终端中打印它执行的每个命令，并以 <code>+</code> 符号作为前缀。这对于识别脚本中出现错误的位置非常有帮助。</p>
<pre><code class="language-bash">#!/bin/bash

set -x

# 您的脚本放在这里
</code></pre>
<h3 id="">检查退出码</h3>
<p>当 Bash 遇到错误时，它会设置一个退出码来指示错误的性质。您可以使用 <code>$?</code> 变量检查最近命令的退出码。值为 <code>0</code> 表示成功，而任何其他值表示错误。</p>
<pre><code class="language-bash">#!/bin/bash

# 您的脚本放在这里

if [ $? -ne 0 ]; then
    echo "发生错误。"
fi
</code></pre>
<h3 id="echo">使用 <code>echo</code> 语句</h3>
<p>另一个调试 Bash 脚本的有用技巧是在代码中插入 <code>echo</code> 语句。这可以帮助您识别错误发生的位置以及变量传递的值是什么。</p>
<pre><code class="language-bash">#!/bin/bash

# 您的脚本放在这里

echo "变量 x 的值是: $x"

# 更多代码放在这里
</code></pre>
<h3 id="sete">使用 <code>set -e</code> 选项</h3>
<p>如果您希望在脚本中的任何命令失败时立即退出脚本，您可以使用 <code>set -e</code> 选项。这个选项会使 Bash 在脚本中的任何命令失败时退出并带有错误，这样可以更容易地识别和修复脚本中的错误。</p>
<pre><code class="language-bash">#!/bin/bash

set -e

# 您的脚本放在这里
</code></pre>
<h3 id="">通过验证日志来排查定时任务</h3>
<p>我们可以使用日志文件来排查定时任务。日志会记录所有的计划任务。您可以在日志中检查并验证特定任务是否按预期运行。</p>
<p>对于 Ubuntu/Debian，您可以在这里找到 <code>cron</code> 日志：</p>
<pre><code class="language-bash">/var/log/syslog
</code></pre>
<p>其他发行版的位置各不相同。</p>
<p>一个 cron 任务日志文件可能看起来像这样：</p>
<pre><code class="language-bash">2022-03-11 00:00:01 Task started
2022-03-11 00:00:02 Running script /path/to/script.sh
2022-03-11 00:00:03 Script completed successfully
2022-03-11 00:05:01 Task started
2022-03-11 00:05:02 Running script /path/to/script.sh
2022-03-11 00:05:03 Error: unable to connect to database
2022-03-11 00:05:03 Script exited with error code 1
2022-03-11 00:10:01 Task started
2022-03-11 00:10:02 Running script /path/to/script.sh
2022-03-11 00:10:03 Script completed successfully
</code></pre>
<p>Cron 日志</p>
<h2 id="conclusion">总结</h2>
<p>在本文中，我们首先介绍了如何访问终端，然后运行了一些基本的 bash 命令。我们还学习了什么是 bash shell。我们简要地了解了使用循环和条件语句实现分支代码。最后，我们讨论了使用 cron 来自动化脚本，并介绍了一些故障排除技巧。</p>
<h3 id="resources-for-learning-more-about-bash-scripting">学习更多关于 Bash 脚本的资源</h3>
<p>如果您想深入了解 bash 脚本的世界，我建议您看看 freeCodeCamp 上这门 6 小时的 Linux 课程。</p>
<figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/sWbUDq4S6Y8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Introduction to Linux – Full Course for Beginners" name="fitvid0"></iframe>
          </div>
        </div>
      </figure>
<p>在本教程中，你学到了最喜欢的内容是什么？你还可以在这些<a href="https://zaira_.bio.link/">平台</a>上与我联系。</p>
<p>让我们在下篇教程中再见，祝你编码愉快 😁</p>
<p>封面图片来源：<a href="https://www.freepik.com/free-vector/hand-drawn-flat-design-devops-illustration_25726540.htm#query=programmer%20linux&amp;position=4&amp;from_view=search&amp;track=ais">Freepik</a></p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 如何在浏览器中使用开发者工具调试 JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ console 对象是开发人员处理有问题的 JavaScript 代码时的第一选择。 但如果你仍然只是重度依赖于 console 对象来调试 JavaScript，你就错过了浏览器开发者工具的一些很棒的功能。 让我们来看看如何使用 Chrome 开发者工具调试 JavaScript。 我们要处理的问题代码 首先，我准备了一些有 bug 的代码，将四个数字相加并计算其平均值。 这是代码的 HTML 部分： <label for="num1">Number 1:</label> <input type="text" id="num1" placeholder="Enter a number" /> <label for="num2">Number 2:</label> <input type="text" id="num2" placeholder="Enter a number" /> <label for="num3">Number 3:</label> <input type="text" id="num3" placeholder="Enter a number" / ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/how-to-use-developer-tools-to-debug-javascript-in-the-browser/</link>
                <guid isPermaLink="false">6732d3dc7b243504ae537c9b</guid>
                
                    <category>
                        <![CDATA[ 调试 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Debug ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Tue, 12 Nov 2024 11:19:29 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/11/f2ead89e25e967947691c8e4a1f8f862.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/how-to-use-developer-tools-to-debug-javascript-in-the-browser/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use Developer Tools to Debug JavaScript in the Browser</a>
      </p><!--kg-card-begin: markdown--><p><code>console</code> 对象是开发人员处理有问题的 JavaScript 代码时的第一选择。</p>
<p>但如果你仍然只是重度依赖于 <code>console</code> 对象来调试 JavaScript，你就错过了浏览器开发者工具的一些很棒的功能。</p>
<p>让我们来看看如何使用 Chrome 开发者工具调试 JavaScript。</p>
<h2 id="">我们要处理的问题代码</h2>
<p>首先，我准备了一些有 bug 的代码，将四个数字相加并计算其平均值。</p>
<p>这是代码的 HTML 部分：</p>
<pre><code class="language-html">&lt;label for="num1"&gt;Number 1:&lt;/label&gt;
&lt;input type="text" id="num1" placeholder="Enter a number" /&gt;

&lt;label for="num2"&gt;Number 2:&lt;/label&gt;
&lt;input type="text" id="num2" placeholder="Enter a number" /&gt;

&lt;label for="num3"&gt;Number 3:&lt;/label&gt;
&lt;input type="text" id="num3" placeholder="Enter a number" /&gt;

&lt;label for="num4"&gt;Number 4:&lt;/label&gt;
&lt;input type="text" id="num4" placeholder="Enter a number" /&gt;

&lt;button id="calculateBtn"&gt;Calculate Sum and Average&lt;/button&gt;

&lt;p id="addition-result"&gt;&lt;/p&gt;
&lt;p id="average-result"&gt;&lt;/p&gt;

&lt;script src="script.js"&gt;&lt;/script&gt;
</code></pre>
<p>这是非常简单的 CSS，用来将标签推到各自的行，并稍微放大输入元素和按钮：</p>
<pre><code class="language-css">body {
  background: #d2d2d2;
}

label {
  display: block;
  margin-top: 0.5rem;
}

button {
  display: block;
  margin-top: 1rem;
}

input,
button {
  padding: 0.2rem;
}
</code></pre>
<p>这是 HTML 和 CSS 在浏览器中显示的样子：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767323533/db4b903d-8cfe-4d6b-85b2-2233a2a2bcd0.png" alt="Sum and Average Calculator" width="600" height="400" loading="lazy"></p>
<p>以下是有 bug 的 JavaScript：</p>
<pre><code class="language-javascript">const calculateBtn = document.getElementById('calculateBtn');
const sumText = document.getElementById('sum');
const avgText = document.getElementById('average');

function calculateTotal(a, b, c, d) {
 return a + b + c + d;
}

function calculateAverage(total, count) {
 return total / count;
}

function handleButtonClick() {
 let num1 = document.getElementById('num1').value;
 let num2 = document.getElementById('num2').value;
 let num3 = document.getElementById('num3').value;
 let num4 = document.getElementById('num4').value;

 let total = calculateTotal(num1, num2, num3, num4);
 let average = calculateAverage(total, 4);

 sumText.textContent = `The sum is ${total}`;
 avgText.textContent = `The average is: ${average}`;
}

calculateBtn.addEventListener('click', handleButtonClick);
</code></pre>
<p>如果你输入四个数字，比如 <code>3</code>、<code>4</code>、<code>2</code>、<code>1</code>，然后点击 <code>Calculate Sum and Average</code> 按钮，会发生什么：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767417791/6c5a49d1-dc6f-45db-9720-c3c6daedbeb3.png" alt="Wrong sum and average" width="600" height="400" loading="lazy"></p>
<p>不幸的是，数字只是被合并了，平均值是基于这个计算的，这意味着执行了拼接而不是加法。加法执行有问题也导致了平均值计算错误。</p>
<p>让我们用浏览器开发者工具检查一下发生了什么。</p>
<h2 id="chromejavascript">如何使用 Chrome 开发者工具调试 JavaScript 代码</h2>
<p>当出现这样的错误时，你可能会倾向于添加一堆控制台日志。</p>
<p>很多时候，控制台日志可以完成任务，但你必须花费大量时间来弄清楚事情。</p>
<p>浏览器开发者工具为你提供了更多选项，比如添加断点、监视特定表达式，甚至逐行执行代码以查看错误发生的位置。</p>
<h3 id="sources">如何打开开发者工具和源代码（Sources）标签</h3>
<p>首先，右键点击浏览器中并选择“检查”来打开 Chrome DevTools。</p>
<p>在 DevTools 中，打开源代码（Sources）标签查看程序中的文件。你也可以按下键盘上的 <code>F12</code> 键并选择源代码（Sources）标签。</p>
<p>以下是 Chrome DevTools 源代码（Sources）标签的简要结构：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767628385/30310aa1-ddb0-41d5-a3ce-9ecc84b034e3.png" alt="Anatomy of the chrome developer tools source tab" width="600" height="400" loading="lazy"></p>
<p>在调试器标签顶部有一些灰色的图标。激活它们，你可以逐步执行代码并添加或移除断点。</p>
<p>在调试器标签中还有：</p>
<ul>
<li>
<p>监视：你可以在此添加和查看监视表达式。</p>
</li>
<li>
<p>断点：你可以在此查看你添加断点的代码行。</p>
</li>
<li>
<p>作用域：包含本地和全局变量。</p>
</li>
<li>
<p>调用栈：显示导致当前位置代码执行的函数调用。</p>
</li>
</ul>
<p>要查看任何文件的内容，你可以点击它。然后，调试器标签中的一些图标将不再是灰色的。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729767971149/04f8e5c7-a08a-49b3-be7f-2854f820b94a.png" alt="Icons of the Chrome developer tools source tab" width="600" height="400" loading="lazy"></p>
<h3 id="">如何通过添加断点调试代码</h3>
<p>要开始调试代码，你可以通过点击行号添加断点。</p>
<p>断点就像你可以在开发者工具中设置的行标记，它会在该行执行之前暂停你的代码执行。这样，你就可以检查变量的值，查看函数是否按预期被调用，或者观察代码的整体流程。</p>
<p>当你添加一个断点并执行代码时，该行会出现一个蓝色图标，表示执行会在该行之前暂停。</p>
<p>或者，你可以在你想暂停执行的行添加 <code>debugger</code> 语句。不过，还是让我们坚持使用断点。</p>
<p>例如，我们在第 14 行添加一个断点，然后输入四个数字并点击 <code>Calculate Sum and Average</code> 按钮，这样代码就会运行：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768234921/8c1f0d4e-5fb2-4461-8e62-574d95a51672.png" alt="第 14 行的断点" width="600" height="400" loading="lazy"></p>
<p>此时，你会看到没有继续执行——这就是为什么在 “Local” 下所有变量显示 “value unavailable”。</p>
<p>从这里开始，你可以通过点击右上角的 step 图标逐行单步执行代码：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768323163/45fb5c6b-682d-4b90-8bec-d4ef8596c4b7.png" alt="Chrome 开发者工具源标签的 step 图标" width="600" height="400" loading="lazy"></p>
<p>一旦你点击 step 图标，你所退出的行被执行。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768411765/f2670800-c8d8-490f-8dc9-1fdfa8c8da7b.png" alt="点击 step 图标" width="600" height="400" loading="lazy"></p>
<p>你可以看到，<code>"3"</code> 是第<code>14</code>行的值。该值被一对双引号包围，这意味着它是一个字符串。你需要确保这一点，而这正是 watch 特性能让你做到的。你将很快了解这一特性。</p>
<p>如果你正处理多行代码，逐行单步执行可能会耗费时间。因此，你可能需要添加另一个断点。</p>
<p>我将继续在第 <code>23</code> 行设置一个断点并再次运行代码：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768528136/478fc837-0c16-4990-9b70-19ff1695331e.png" alt="第 23 行的断点" width="600" height="400" loading="lazy"></p>
<p>现在你可以看到，除了 <code>average</code> 外的所有变量结果似乎都是字符串。这引出了下一个 Chrome 开发者工具调试器特性——watcher。</p>
<h3 id="watch">如何使用开发者工具的监视（watch）特性</h3>
<p>开发者工具的监视特性可以让你在代码运行时监视（watch）特定的变量或表达式。</p>
<p>要确认变量的数据类型，你可以添加一个显示其值的监视（watch）表达式，或更合适地，显示其类型。</p>
<p>要添加监视（watch）表达式，点击 “监视（watch）” 旁边的加号（+）图标，并按键盘上的 <code>ENTER</code>。</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768780977/ef22ae71-068c-41a2-9a2e-509c7c6a8afb.png" alt="添加 watch 表达式" width="600" height="400" loading="lazy"></p>
<p>以下监视（watch）表达式是确认 <code>num1</code> 到 <code>num4</code> 和 <code>total</code> 为字符串——但它们应为整数：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768808497/5d7352d6-37b3-490c-9ce2-f430c2d9a0e6.png" alt="watch 表达式" width="600" height="400" loading="lazy"></p>
<p>你还可以在控制台标签中验证变量类型：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768847227/3730a133-0a5b-4eb1-a5dd-257fa0ac2293.png" alt="控制台的变量类型" width="600" height="400" loading="lazy"></p>
<p>这意味着你输入的数字被解释为字符串。这是因为在 JavaScript 中，从 HTML 元素（如输入字段）获取的值总是字符串。</p>
<p>这是因为输入元素的 <code>value</code> 属性返回一个字符串，即使你输入的是数字——这就是 bug 出现的原因。</p>
<p>记住，JavaScript 只会连接字符串，即使它们是数字。这说明 <code>"3"</code> 是字符串类型而不是整型。</p>
<p>要修复这个 bug，你应将 <code>num1</code> 到 <code>num4</code> 的类型更改为整数，以便 JavaScript 能正确地将它们的值相加。</p>
<p>然后你可以继续在 DevTools 中修复此问题，并在 Windows 上按 <code>CTRL + S</code> 或在Mac上按 <code>CMD + S</code> 保存代码。你也可以在代码编辑器中，通过在数字的变量中使用 <code>parseInt()</code> 来修复它。</p>
<p>一旦你这么做并再次运行代码，watcher 中应该显示正确的数据类型，Local 下应该显示正确的变量值：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729768941146/964cabbd-2298-4303-ac0d-2b54af070d66.png" alt="watch 中的正确变量类型" width="600" height="400" loading="lazy"></p>
<p>你也可以在代码编辑器中实现这些更改，使一切正常工作。以下是正确的代码：</p>
<pre><code class="language-javascript">const calculateBtn = document.getElementById('calculateBtn');
const sumText = document.getElementById('sum');
const avgText = document.getElementById('average');

function calculateTotal(a, b, c, d) {
  return a + b + c + d;
}

function calculateAverage(total, count) {
  return total / count;
}

function handleButtonClick() {
  let num1 = parseInt(document.getElementById('num1').value);
  let num2 = parseInt(document.getElementById('num2').value);
  let num3 = parseInt(document.getElementById('num3').value);
  let num4 = parseInt(document.getElementById('num4').value);

  let total = calculateTotal(num1, num2, num3, num4);
  let average = calculateAverage(total, 4);

  sumText.textContent = `The sum is ${total}`;
  avgText.textContent = `The average is: ${average}`;
}

calculateBtn.addEventListener('click', handleButtonClick);
</code></pre>
<p>以下是在浏览器中的结果：</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1729769063113/b7e39538-e9fe-4ce5-a4de-e98f43263235.png" alt="求和并计算平均值正常执行" width="600" height="400" loading="lazy"></p>
<h2 id="">总结</h2>
<p>这就是如何使用 Chrome 的开发者工具调试 JavaScript。断点和监视器功能以及 step 按钮是对基本控制台日志的升级。</p>
<p>请注意，每个现代浏览器都内置了这个 JavaScript 调试工具，因此你可以使用相同的方法在 Firefox 或 Edge 中调试 JavaScript。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ 祝贺 freeCodeCamp 全球开源社区 2024 Top Contributors ]]>
                </title>
                <description>
                    <![CDATA[ 对于 freeCodeCamp 社区来说，2024 年是极富成效的一年。我们为实现为所有人创建开放式学习资源的使命积蓄了巨大的动力。 在过去的 12 个月中，freeCodeCamp 社区取得了以下成就：  * 在我们的 GitHub 开源仓库合并了 2,455 个代码贡献  * 在 YouTube 上发布了 193 个免费的完整视频教程  * 通过 freeCodeCamp 出版社发布了 850 篇编程教程和 5 本免费书籍  * 翻译了 150 多万字的英文资源，让母语是其他语言的人们更容易学习我们的课程和教程 我非常感谢今年参与志愿贡献的善良的人们。我们在多个方面取得了实质性进展。 以下是按贡献类别列出的 top contributors 的完整名单。 GitHub Top Contributors  * Anna [https://github.com/a2937]  * ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/freecodecamps-top-open-source-contributors-of-2024/</link>
                <guid isPermaLink="false">67243df18c1e8204aca0b68b</guid>
                
                    <category>
                        <![CDATA[ 开源 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ 社区 ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Miya Liu ]]>
                </dc:creator>
                <pubDate>Fri, 01 Nov 2024 03:25:34 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2024/11/d8ef629c-64b8-4f80-bb57-b5f6b00bfa23.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/freecodecamps-top-open-source-contributors-of-2024/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">freeCodeCamp's Top Open Source Contributors of 2024</a>
      </p><p>对于 freeCodeCamp 社区来说，2024 年是极富成效的一年。我们为实现为所有人创建开放式学习资源的使命积蓄了巨大的动力。</p><p>在过去的 12 个月中，freeCodeCamp 社区取得了以下成就：</p><ul><li>在我们的 GitHub 开源仓库合并了 <strong>2,455<strong> 个代码贡献</strong></strong></li><li>在 YouTube 上发布了 <strong><strong>1</strong>93<strong> 个免费的完整视频教程</strong></strong></li><li>通过 freeCodeCamp 出版社发布了 <strong>850<strong> 篇编程教程</strong></strong>和 <strong>5<strong> 本免费书籍</strong></strong></li><li>翻译了 <strong>150<strong> 多万字</strong></strong>的英文资源，让母语是其他语言的人们更容易学习我们的课程和教程</li></ul><p>我非常感谢今年参与志愿贡献的善良的人们。我们在多个方面取得了实质性进展。</p><p>以下是按贡献类别列出的 top contributors 的完整名单。</p><h2 id="github-top-contributors"><strong>GitHub Top Contributors</strong></h2><ul><li><a href="https://github.com/a2937">Anna</a></li><li><a href="https://github.com/lasjorg">Lasse Jørgensen</a></li><li><a href="https://github.com/Supravisor">Supravisor</a></li><li><a href="https://github.com/gagan-bhullar-tech">Gagan Bhullar</a></li><li><a href="https://github.com/gikf">Krzysztof G.</a></li><li><a href="https://github.com/altsun">Duong The Pham</a></li><li><a href="https://github.com/Re1nGer">Re1nGer</a></li><li><a href="https://github.com/RGHANILOO">RGHANILOO</a></li><li><a href="https://github.com/mmatsumoto1026">Manabu Matsumoto</a></li><li><a href="https://github.com/Nitz2611">Nitish sharma</a></li><li><a href="https://github.com/royjohnlee">Roy John Lee</a></li><li><a href="https://github.com/1jds">James</a></li><li><a href="https://github.com/zxc-w">zxc-w</a></li><li><a href="https://github.com/jnahan">jnahan</a></li><li><a href="https://github.com/dyx9">Yixuan Dai</a></li><li><a href="https://github.com/Rabberpoli">Giovanni Ruberto</a></li><li><a href="https://github.com/shootermv">Moshe</a></li><li><a href="https://github.com/alagumuthiah">Alagu Muthiah</a></li><li><a href="https://github.com/iLtc">Alan Luo</a></li><li><a href="https://github.com/OrestSonich">Orest Sonich</a></li><li><a href="https://github.com/DeepaPrasanna">Anne Deepa Prasanna</a></li><li><a href="https://github.com/AndrewYturaldi">Andrew M. Yturaldi</a></li><li><a href="https://github.com/sanskriti2005">Sanskriti</a></li><li><a href="https://github.com/srikanth-kandi">Srikanth Kandi</a></li><li><a href="https://github.com/PedroRamos360">Pedro Ramos</a></li><li><a href="https://github.com/JBhrayn">Jose Bhrayn Colina</a></li><li><a href="https://github.com/shanmukh-sai2003">Korada Shanmukh Sai</a></li><li><a href="https://github.com/Vijaychandra-Govindapalle">Vijaychandra Govindapalle</a></li><li><a href="https://github.com/weilirs">Lawrence Li</a></li><li><a href="https://github.com/JamesCartar">Hein Htet</a></li><li><a href="https://github.com/sulaiman-dev">Sulaiman</a></li><li><a href="https://github.com/jeremylt">Jeremy L Thompson</a></li><li><a href="https://github.com/Ritesh2351235">Ritesh S Hiremath</a></li><li><a href="https://github.com/WilliamSpanfelner">William Spanfelner</a></li><li><a href="https://github.com/praizjosh">Josh</a></li><li><a href="https://github.com/Deep512">Deep Dhanuka</a></li><li><a href="https://github.com/abhinavkgrd">Abhinav Kumar</a></li><li><a href="https://github.com/Mikey-Esteban">Mikey Esteban</a></li><li><a href="https://github.com/jayAardvark">Jr Cenina</a></li><li><a href="https://github.com/iprime2">Sushil Gupta</a></li><li><a href="https://github.com/jayanth920">jayanth920</a></li><li><a href="https://github.com/LouizaMak">Louiza Mak</a></li><li><a href="https://github.com/CracktheDom">CracktheDom</a></li><li><a href="https://github.com/Lalith246">Lalith Kanakamedala</a></li><li><a href="https://github.com/kevin-wu01">Kevin</a></li><li><a href="https://github.com/sanjeevmurmu">Sanjeev Murmu</a></li><li><a href="https://github.com/devXaks">Akshat Tripathi</a></li><li><a href="https://github.com/dwrik">dwrik</a></li><li><a href="https://github.com/mcehme">Michael Ehme</a></li><li><a href="https://github.com/patrickwcode">Patrick Wauschek</a></li><li><a href="https://github.com/andrebdinis">André Barreira Dinis</a></li><li><a href="https://github.com/LuG-r">Lucas Gracia</a></li><li><a href="https://github.com/ChiaraTrt">Chiara</a></li><li><a href="https://github.com/vaibhav-ace">Vaibhav-Ace</a></li><li><a href="https://github.com/cheenu-1824">cheenu-1824</a></li><li><a href="https://github.com/vic-fb">Vicky Fernandez Busch</a></li><li><a href="https://github.com/katereverie">Jiantao (Felix)</a></li><li><a href="https://github.com/gova646">Govardhan</a></li><li><a href="https://github.com/Auxdible">Steven Primeaux</a></li><li><a href="https://github.com/JeevaRamanathan">JeevaRamanathan</a></li><li><a href="https://github.com/Lalithkumarponnambalam">Lalithkumarponnambalam</a></li><li><a href="https://github.com/bulhaa">Hammadh</a></li><li><a href="https://github.com/Arnav-2004">Arnav</a></li><li><a href="https://github.com/ajcruise007">Anugrah</a></li><li><a href="https://github.com/PrajvalaRC">Prajvala R C</a></li><li><a href="https://github.com/shivasaikrishnagadeela">Shiva Sai Krishna Gadeela</a></li><li><a href="https://github.com/developwithabhinav">developwithabhinav</a></li><li><a href="https://github.com/itsmacr8">ITS MAC</a></li><li><a href="https://github.com/mayankkamboj47">Mayank Kamboj</a></li><li><a href="https://github.com/netanelben">Nate Ben</a></li><li><a href="https://github.com/israelone">Israel Lopez</a></li><li><a href="https://github.com/jozzbruer">Joz-Bruer Quince</a></li><li><a href="https://github.com/sahilintech">Sahil Chauhan</a></li><li><a href="https://github.com/tsirianni">Tobias Sirianni Melo</a></li><li><a href="https://github.com/sohamtembhurne">Soham Tembhurne</a></li><li><a href="https://github.com/mccarreon">mccarreon</a></li><li><a href="https://github.com/anikaitprasar">Anikait Prasar</a></li><li><a href="https://github.com/edwinhung">Edwin Hung</a></li><li><a href="https://github.com/MikhailWahib">Mikhail Wahib</a></li><li><a href="https://github.com/ytrkptl">Yatrik Patel</a></li><li><a href="https://github.com/pramod74">Pramod Lumb</a></li><li><a href="https://github.com/shivam-0510">Shivam Gupta</a></li><li><a href="https://github.com/clarencepenz">Clarence</a></li><li><a href="https://github.com/olawanlejoel">Joel Olawanle</a></li><li><a href="https://github.com/yeldarx">Yeldar Kudaibergenov</a></li><li><a href="https://github.com/AxlSou">Axel Soubielle Almada</a></li><li><a href="https://github.com/Kashinathpat">Kashinath Patkar</a></li><li><a href="https://github.com/WOLFRIEND">Oleksandr Tkachenko</a></li><li><a href="https://github.com/v-i-k-a-s">v-i-k-a-s</a></li><li><a href="https://github.com/farshed">Faisal Arshed</a></li><li><a href="https://github.com/usamabasharat">Usama Basharat</a></li><li><a href="https://github.com/budblack">budblack</a></li></ul><h2 id="-top-contributors"><strong>论坛 Top Contributors</strong></h2><ul><li><a href="https://forum.freecodecamp.org/u/hbar1st">Hanaa B.</a></li><li><a href="https://forum.freecodecamp.org/u/Teller">Teller</a></li><li><a href="https://forum.freecodecamp.org/u/JeremyLT">Jeremy</a></li><li><a href="https://forum.freecodecamp.org/u/stephenmutheu">Stephen Mutheu</a></li><li><a href="https://forum.freecodecamp.org/u/lasjorg">Lasse</a></li><li><a href="https://forum.freecodecamp.org/u/pkdvalis">pkdvalis</a></li><li><a href="https://forum.freecodecamp.org/u/hasanzaib1389">Hassan Zaib</a></li><li><a href="https://forum.freecodecamp.org/u/Cody_Biggs">CODY BIGGS</a></li><li><a href="https://forum.freecodecamp.org/u/bbsmooth">Bruce B</a></li><li><a href="https://forum.freecodecamp.org/u/igorgetmeabrain">Doug Badger</a></li><li><a href="https://forum.freecodecamp.org/u/DanielHuebschmann">DanielHuebschmann</a></li><li><a href="https://forum.freecodecamp.org/u/ArielLeslie">Ariel Leslie</a></li><li><a href="https://forum.freecodecamp.org/u/zuhameer6">Zuhaira Ameer</a></li><li><a href="https://forum.freecodecamp.org/u/a2937">Anna</a></li><li><a href="https://forum.freecodecamp.org/u/Ray13">Raymond</a></li><li><a href="https://forum.freecodecamp.org/u/sanity">sanity</a></li><li><a href="https://forum.freecodecamp.org/u/toan">Toan</a></li><li><a href="https://forum.freecodecamp.org/u/opudoprince">Opudo Prince</a></li><li><a href="https://forum.freecodecamp.org/u/DobarBREND">Vladimir Jovanović</a></li><li><a href="https://forum.freecodecamp.org/u/be_happy"><em><em>Infinity</em></em></a></li><li><a href="https://forum.freecodecamp.org/u/HungryBee">HungryBee</a></li><li><a href="https://forum.freecodecamp.org/u/bappyasif">a b</a></li><li><a href="https://forum.freecodecamp.org/u/robheyays">Robert H.</a></li><li><a href="https://forum.freecodecamp.org/u/MostafaElbadry">MostafaElbadry</a></li><li><a href="https://forum.freecodecamp.org/u/GrannyIsA-Dreamer">GrannyIsA-Dreamer</a></li><li><a href="https://forum.freecodecamp.org/u/JuniorQ">Arakhsh Qanit</a></li><li><a href="https://forum.freecodecamp.org/u/ios-man">ios-man</a></li><li><a href="https://forum.freecodecamp.org/u/marcusparsons">Marcus Parsons</a></li><li><a href="https://forum.freecodecamp.org/u/ambradnum">Alan Bradnum</a></li><li><a href="https://forum.freecodecamp.org/u/constantcode9909">Mohamed Amine (Mike)</a></li><li><a href="https://forum.freecodecamp.org/u/a1legalfreelance">A1legalfreelance</a></li><li><a href="https://forum.freecodecamp.org/u/danielbailey0629">Daniel Bailey</a></li><li><a href="https://forum.freecodecamp.org/u/Jyothsna13">Jyothsna Lakshminarayanan</a></li><li><a href="https://forum.freecodecamp.org/u/albert_kucz">Albert Kucz</a></li><li><a href="https://forum.freecodecamp.org/u/MrSanyi">SanyiDiriba</a></li><li><a href="https://forum.freecodecamp.org/u/bijiyiqi2017">William Miller Jr</a></li><li><a href="https://forum.freecodecamp.org/u/aldehyde">Aldrin Sean Pereira</a></li><li><a href="https://forum.freecodecamp.org/u/SpookyBlump">SpookyBlump</a></li><li><a href="https://forum.freecodecamp.org/u/luisclaudioc">Luis Costantin</a></li><li><a href="https://forum.freecodecamp.org/u/0x74h51N">Tahsin Önemli</a></li><li><a href="https://forum.freecodecamp.org/u/CrlosZgz">Carlos Bernad</a></li><li><a href="https://forum.freecodecamp.org/u/madhavvattackattu">Madhav Mohan</a></li><li><a href="https://forum.freecodecamp.org/u/christ_harper">Christ-yvan KEMAJOU</a></li><li><a href="https://forum.freecodecamp.org/u/aaronvincent6411">Aaron P Laju</a></li><li><a href="https://forum.freecodecamp.org/u/kevinSmith">Kevin Smith</a></li><li><a href="https://forum.freecodecamp.org/u/Alabastor">Alabastor</a></li><li><a href="https://forum.freecodecamp.org/u/Answer_Alyosha">Answer</a></li><li><a href="https://forum.freecodecamp.org/u/cherry-27">⛤Cherry-27⛤</a></li><li><a href="https://forum.freecodecamp.org/u/m-stanleysk">M</a></li><li><a href="https://forum.freecodecamp.org/u/ablairmorris">ablairmorris</a></li><li><a href="https://forum.freecodecamp.org/u/franciscomelov">Francisco Ecatl Melo Valle</a></li><li><a href="https://forum.freecodecamp.org/u/ziggybryson">Anthony Bryson Jr.</a></li><li><a href="https://forum.freecodecamp.org/u/moT01">Tom M</a></li><li><a href="https://forum.freecodecamp.org/u/Losarig">Alex</a></li><li><a href="https://forum.freecodecamp.org/u/ibrahim_aq">Ibrahim Aq</a></li><li><a href="https://forum.freecodecamp.org/u/admit8490">Andrey D</a></li><li><a href="https://forum.freecodecamp.org/u/mailforworkon">mailforworkon</a></li><li><a href="https://forum.freecodecamp.org/u/AbbyGTech">AbbyGTech</a></li><li><a href="https://forum.freecodecamp.org/u/OpeRichards">Opeyemi Richard</a></li><li><a href="https://forum.freecodecamp.org/u/stroudy91">Stroudy91</a></li><li><a href="https://forum.freecodecamp.org/u/miketandy">Mike</a></li><li><a href="https://forum.freecodecamp.org/u/Blman">Tadesse Agegnehu</a></li><li><a href="https://forum.freecodecamp.org/u/Samuel-54">Samuel Diriba</a></li><li><a href="https://forum.freecodecamp.org/u/Cryptic_X">Cryptic</a></li><li><a href="https://forum.freecodecamp.org/u/hiekamara1">Easside MJ. Kamara</a></li><li><a href="https://forum.freecodecamp.org/u/KoduFCC">KoduFCC</a></li><li><a href="https://forum.freecodecamp.org/u/shy_away">shy_away</a></li><li><a href="https://forum.freecodecamp.org/u/Sebastian_W">Sebastian Włodarczyk</a></li><li><a href="https://forum.freecodecamp.org/u/surelyalice">Kesa Elizabeth Stallman</a></li><li><a href="https://forum.freecodecamp.org/u/KTO">Kyle O'Leary</a></li><li><a href="https://forum.freecodecamp.org/u/Glory1">💜💜purpleglow🌟🌟</a></li><li><a href="https://forum.freecodecamp.org/u/mohamedelmir">mohamed elmir</a></li><li><a href="https://forum.freecodecamp.org/u/KaiG">Kai G</a></li><li><a href="https://forum.freecodecamp.org/u/jpccdirect">jpccdirect</a></li><li><a href="https://forum.freecodecamp.org/u/lucatardi">Luca Tardito</a></li><li><a href="https://forum.freecodecamp.org/u/CodingCoding">Logan Drake Cody</a></li><li><a href="https://forum.freecodecamp.org/u/millicentbowers">Millie Bowers</a></li><li><a href="https://forum.freecodecamp.org/u/MilesWeb">MilesWeb</a></li><li><a href="https://forum.freecodecamp.org/u/sulemankhalil44">suleman khalil</a></li><li><a href="https://forum.freecodecamp.org/u/ghulamshabirbaloch">ghulamshabirbaloch</a></li><li><a href="https://forum.freecodecamp.org/u/diegog">Diego</a></li><li><a href="https://forum.freecodecamp.org/u/fourleagues">Maestro Goldring</a></li></ul><h2 id="-top-contributors-1"><strong>翻译 Top Contributors</strong></h2><ul><li>Afonso Branco</li><li>rustamdocstranslator</li><li>Madlen</li><li>Alan Luo</li><li>LisaGo</li><li>majidah</li><li>Karel Vanhelden</li><li>SeunghyunKim</li><li>Nadja Sellinat</li><li>Kevin Matthew</li><li>Siyana Zdravkova</li><li>Ricardo Cuauro</li><li>Liu dakang</li><li>Álvaro Dávila</li><li>Ira Bohach</li><li>Laureline</li><li>Nils Goeke</li><li>ViktoriaKushnir0-</li><li>ピンク人</li><li>sohyun</li><li>kimploo</li><li>franciscomelov</li><li>Andriana Cabrera</li><li>Kostiantyn Melnyk</li><li>athen</li><li>JulianLobonAguilar</li><li>moonki kim</li><li>Suzie</li><li>Kasia</li><li>mamaruo</li><li>VL</li><li>Solomiia Karpachova</li><li>Diana Kolosovska (Діана Колосовська)</li><li>steven ding</li><li>Elias Pereyra</li><li>nin3lee</li><li>Juanma</li><li>Naelko</li><li>Álvaro Dávila</li><li>Tamiris</li><li>Devan</li><li>Leslie Suh</li><li>Dario</li><li>mix bo</li><li>Eduardo Lima</li><li>isaura-ribeiro</li><li>nighttheduck</li><li>Caroline Andrade</li><li>salvatore luciano</li><li>Nikolai</li><li>Frankline Were</li><li>Mikadifo</li><li>MaxiNZ</li><li>SleepyGogo</li><li>Brendo Arruda</li><li>rkang13</li><li>TikaZ</li><li>shaudvetis</li><li>Minh Tuấn Nguyễn</li><li>wdthor</li><li>BeGeosDev</li><li>Kristian Pavic</li><li>Dalton Cuenca</li><li>jonathanq</li><li>Erick</li><li>Sreya Satheesh</li><li>Freddy R</li><li>Wilmer Gulcochía Sánchez</li><li>Shannon</li><li>André Garcia</li><li>Saikrishna Anumula</li><li>Sharvio</li><li>David Gómez Redondo</li><li>Jimmy Yem</li><li>Lucy Macartney</li><li>vLeov</li><li>Sunce</li><li>1615_P._Enrique</li><li>Ener Octavio Buitrago Camelo</li><li>ProjektMing</li><li>nrached</li><li>Camila</li><li>Maria Luz Davico</li><li>EricF</li><li>Bobby M</li><li>lime</li><li>irabucha</li><li>Filippo Crespi</li><li>MrTL3</li><li>Li Chuan (李川)</li><li>Rodrigo Lajas</li><li>Jarvis Hack</li><li>invoker</li><li>claudiomavi</li><li>Kato Tsune (加藤恒)</li><li>yk1537</li><li>Jose Zambrano</li><li>Takkapi</li><li>BlackAndRed.eth</li><li>leopard355</li><li>DariaShu</li><li>Daniel R. da Silva</li><li>Adham Muhammadjonov</li><li>Davi Stadlinger</li><li>w w</li><li>KenGan</li><li>cezin17</li><li>Dylan Gabriel Diroché</li><li>luluhwenceslau</li><li>Chinchu Ori</li><li>albasantalo</li><li>Dira R P</li><li>William Hincapié</li><li>aldid95</li><li>Fran Martinez</li><li>Yao990815</li><li>Miracle</li><li>Julian Andres Lasso Figueroa</li><li>pame.gon</li><li>watanaki</li><li>Faisal Hanafi</li><li>Jiwon</li><li>Abo_AbdelSalam</li><li>Vé</li><li>Lu Mu (辂木)</li><li>martinvostatek</li><li>Patrick Hähnel</li><li>Stanley S</li><li>Alexia Javadd</li><li>peperluiz</li><li>Lina Guio</li><li>adnen rebai</li><li>Pasan Hewavitharana</li><li>Monir Adam</li><li>Adi Nugroho</li><li>YumiClmpn</li><li>Daniel Garcia Sanchez</li><li>bugrahankaramollaoglu</li><li>Hannibal_TN</li><li>Ucky Deni Ulinnuha</li><li>David Beyer</li><li>Nicolás Folli</li><li>IM Grigore</li><li>Bill Gao</li><li>Baris</li><li>Simón San Juan Gallardo</li><li>Eralpozcan</li><li>Maria Fernanda Rios</li><li>Tsukistar (月落星河)</li><li>Tao</li><li>Gabriel Kraemer</li><li>mementog</li><li>petyaDeveloper</li><li>TrueJackWu</li><li>Nicolvs</li><li>Juan Diego Jaimes</li><li>Cássio Barth</li><li>Aekkapob Pangtan</li><li>Sergitxin</li><li>Bettina Neuwirth</li><li>juanalbglz</li><li>Marta Escriche</li><li>adrianna</li><li>pcaballero</li><li>Nico Van Pletzen</li><li>Rafael Quintero</li><li>Ozat21</li><li>Dinto</li><li>orikes</li><li>fanqie</li><li>Kamil Kliczbor</li><li>Francisco Mancuello</li><li>Roberto Perez</li><li>Luis Aguilar</li><li>kersen</li><li>miller-danilo</li><li>castrovca</li><li>ChristianMoya</li><li>Felipe Navarro</li><li>Felipe Hernández</li><li>DongHyeon</li><li>Denisse Lemos</li><li>Meer Sajib</li><li>AR Dhrubo</li><li><a href="https://www.freecodecamp.org/italian/news/author/paola/">Paola Rosati</a></li><li><a href="https://www.freecodecamp.org/italian/news/author/andrea-sisti/">Andrea Sisti</a></li><li><a href="https://www.freecodecamp.org/japanese/news/author/charlotte-stone/">Charlotte Stone</a></li><li><a href="https://www.freecodecamp.org/japanese/news/author/saki/">Saki Basken</a></li><li><a href="https://www.freecodecamp.org/japanese/news/author/yuki/">Yuki Shibata</a></li><li><a href="https://www.freecodecamp.org/japanese/news/author/yuusuke/">YUUSUKE OKAMOTO</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/cotyar/">Constanza Areal</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/elias-pereyra/">Elias Ezequiel Pereyra Gomez</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/diego-lopez/">Diego Lopez</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/cristian-fernando-villca-gutierrez/">Cristian Fernando Villca Gutierrez</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/franciscomelov/">Francisco Melo V.</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/hezean/">HeZean</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/mingxun/">Mingxun Liu</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/tsukistar/">Tsukistar</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/james/">James Z. Zhang</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/hu-qi/">huqi</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/junowei/">JunoWei</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/yiwei/">YiWei</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/luojiyin/">luojiyin</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/herosql/">herosql</a></li><li><a href="https://www.freecodecamp.org/chinese/news/author/nin3/">李小宁</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/afonso">Afonso Branco</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/krislagerstrom">Kris Lagerström</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/filipe-torres">Filipe Barbosa</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/david">David Esdras</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/joao">João Eduardo Gomes</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/luisfelipelc">Luis Felipe L. C.</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/marcelo-pena">Marcelo Pena</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/zendefta">Gabriel Balbueno</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/sabrina">Sabrina Alves</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/analaurareis">Ana Laura Reis</a></li><li><a href="https://www.freecodecamp.org/portuguese/news/author/isabel">Isabel de Souza</a></li></ul><h2 id="youtube-top-contributors"><strong>YouTube Top Contributors</strong></h2><ul><li><a href="https://youtube.com/@programacaocomramon">Ramon Rodrigues</a></li><li><a href="https://www.youtube.com/@_LeoDev">Leosbel Poll Sotomayor</a></li><li><a href="https://www.youtube.com/@CodingTube">David Ruiz</a></li><li><a href="https://www.youtube.com/@programacion-es">Pedro Plasencia</a></li><li><a href="https://www.youtube.com/channel/UCCPJTSHMeae1Ll9uuG-zlkA">David Choi</a></li><li><a href="https://www.youtube.com/channel/UCrvxjsSrcpInnd4NIGDHt2g">Sergie Code</a></li><li><a href="https://www.youtube.com/leonardocastillo79">Leonardo Jose Castillo Lacruz</a></li><li><a href="https://www.youtube.com/@carpicoder">Carpi Coder</a></li><li><a href="https://www.youtube.com/@AlexCGDesign">Jordan Alexander Cruz Garcia</a></li><li><a href="https://www.youtube.com/channel/UC_XaEmy0Rz49GkrhtpzqWlw">Luis Canary</a></li><li><a href="https://youtube.com/@1littlecoder">Abdul M</a></li><li><a href="https://youtube.com/@analyst_adithya">Vyas Adithya</a></li><li><a href="https://youtube.com/@anthonygg_">AnthonyGG</a></li><li><a href="https://youtube.com/@BoualiAli">Ali Bouali</a></li><li><a href="https://youtube.com/@codeafuture">Alen Omeri</a></li><li><a href="https://youtube.com/@codeddesign">Matthew Hlazo</a></li><li><a href="https://youtube.com/@codegenix">Code Genix</a></li><li><a href="https://youtube.com/@codeheadq">Amini</a></li><li><a href="https://youtube.com/@CodeLab98">Code Lab</a></li><li><a href="https://youtube.com/@CodingCleverly">Haris Iftikhar</a></li><li><a href="https://youtube.com/@CodingMoney">Mukhtar Mukhtar</a></li><li><a href="https://youtube.com/@CoffeeNCode">Aba Codes</a></li><li><a href="https://youtube.com/@CounterSyntax">Dauda Kolo</a></li><li><a href="https://youtube.com/@dailycodework">Simpson Alfred</a></li><li><a href="https://youtube.com/@DanVega">Dan Vega</a></li><li><a href="https://youtube.com/@DivRhino">Div Rhino</a></li><li><a href="https://youtube.com/@hayk.simonyan">Hayk Simonyan</a></li><li><a href="https://youtube.com/@hnasr">Hussein Nasser</a></li><li><a href="https://youtube.com/@itsdineshvaryani">Dinesh Varyani</a></li><li><a href="https://youtube.com/@kantancoding">Georgio Tunson</a></li><li><a href="https://youtube.com/@kerolloz">Kerollos Magdy</a></li><li><a href="https://youtube.com/@krishnaik06">Krish Naik</a></li><li><a href="https://youtube.com/@Kulkarniankita">Ankita Kulkarni</a></li><li><a href="https://youtube.com/@pattvira">Patt Vira</a></li><li><a href="https://youtube.com/@ProgrammingwithUmair321">Umair Jameel</a></li><li><a href="https://youtube.com/@quantum-soar">Michael Minaca</a></li><li><a href="https://youtube.com/@reactwithutkarsh">Utkarsh Seth</a></li><li><a href="https://youtube.com/@RobertsTech139">Aleksa Robavs</a></li><li><a href="https://youtube.com/@robotbobby9">Bobby Roe</a></li><li><a href="https://youtube.com/@sangammukherjee">Sangam Mukherjee</a></li><li><a href="https://youtube.com/@shandilyacodes">Ramendu</a></li><li><a href="https://youtube.com/@StevenCodeCraft">Steven Garcia</a></li><li><a href="https://youtube.com/@the_rings_of_saturn">Emilian Kasemi</a></li><li><a href="https://youtube.com/@TheCodeAngle">Deji Adesoga</a></li><li><a href="https://youtube.com/@TheCodeDealer">Wilson Mucheke</a></li><li><a href="https://youtube.com/@TheQuackLearner">Henry Ly</a></li><li><a href="https://youtube.com/@tommys_codebase">Thomas Burns</a></li><li><a href="https://youtube.com/@tweakdesigns">Ashokkumar Chavada</a></li><li><a href="https://youtube.com/@vincibits">Paulo Dichone</a></li><li><a href="https://youtube.com/@vladdata741">Vlad Gheorghe</a></li><li><a href="https://youtube.com/@vukrosic">Vuk Rosić</a></li><li>Anthony Aragues</li><li>Andrew Brown</li><li><a href="https://www.youtube.com/@1stcode">Zak Ali</a></li><li><a href="https://www.youtube.com/@asaprogrammer_">Burak Orkmez</a></li><li><a href="https://www.youtube.com/@AyushSinghSh">Ayush Singh</a></li><li><a href="https://www.youtube.com/@bootdotdev">Lane Wagner</a></li><li><a href="https://www.youtube.com/@CodeBucks">Code Bucks</a></li><li><a href="https://www.youtube.com/@CodingAddict">John Smilga</a></li><li><a href="https://www.youtube.com/@CodingQuests">Omar Zaki</a></li><li><a href="https://www.youtube.com/@CybernaticoByNishant">Nishant Singh</a></li><li><a href="https://www.youtube.com/@DestinationFAANG">Parth Vyas</a></li><li><a href="https://www.youtube.com/@doabledanny">Dan Adams</a></li><li><a href="https://www.youtube.com/@elliotarledge">Elliot Arledge</a></li><li><a href="https://www.youtube.com/@haidermalik3402">Haider Malik</a></li><li><a href="https://www.youtube.com/@HiteshChoudharydotcom">Hitesh Choudhary</a></li><li><a href="https://www.youtube.com/@JSLegendDev">JSLegendDev</a></li><li><a href="https://www.youtube.com/@KeertiPurswani">Keerti Purswani</a></li><li><a href="https://www.youtube.com/@mdalmamunit427">Md Al Mamun</a></li><li><a href="https://www.youtube.com/@NiklasZiermann">Niklas Ziermann</a></li><li><a href="https://www.youtube.com/@Radu">Dr. Radu Mariescu-Istodor</a></li><li><a href="https://www.youtube.com/@SMDS_Studio">Rohan from Self Made Data Scientist</a></li><li><a href="https://www.youtube.com/@Smoljames">James McArthur</a></li><li><a href="https://www.youtube.com/c/CodeWithStein">Stein Helset</a></li><li><a href="https://www.youtube.com/c/RexJonesII">Rex Jones</a></li><li><a href="https://www.youtube.com/channel/UCvFsd8VBn5WZTJLEM-vZwkg">Piyush Itankar</a></li><li><a href="https://youtube.com/@codewithlari">Alaribe Bright</a></li><li>Brijen Makwana</li><li>Dr. Chuck</li><li>Dr. Immanuel Trummer</li><li>Dr. Lance Martin</li><li>Fatos Morina</li><li>Kshitij Sharma</li><li>Tatev from LunarTech</li><li>Tristan Willcox</li><li>Zubin Pratap</li></ul><h2 id="-top-contributors-2"><strong>专栏 Top Contributors</strong></h2><ul><li><a href="https://freecodecamp.org/news/author/joanayebola">Joan Ayebola</a></li><li><a href="https://freecodecamp.org/news/author/dotslashbit">Sahil Mahapatra</a></li><li><a href="https://freecodecamp.org/news/author/manishshivanandhan">Manish Shivanandhan</a></li><li><a href="http://xn--matu-dpa.sh/">Matéu.sh</a></li><li><a href="https://freecodecamp.org/news/author/tiagomonteiro">Tiago Capelo Monteiro</a></li><li><a href="https://freecodecamp.org/news/author/vaheaslanyan">Vahe Aslanyan</a></li><li><a href="https://freecodecamp.org/news/author/Tobilyn77">Oluwatobi</a></li><li><a href="https://freecodecamp.org/news/author/Daiveed">David Jaja</a></li><li><a href="https://freecodecamp.org/news/author/tomerpacific">Tomer</a></li><li><a href="https://freecodecamp.org/news/author/KunalN25">Kunal Nalawade</a></li><li><a href="https://freecodecamp.org/news/author/samyakjainblog">Samyak Jain</a></li><li><a href="https://freecodecamp.org/news/author/nathansebhastian">Nathan Sebhastian</a></li><li><a href="https://freecodecamp.org/news/author/pltvs">Alex Pliutau</a></li><li><a href="https://freecodecamp.org/news/author/Oluwadamisi">Oluwadamisi Samuel</a></li><li><a href="https://freecodecamp.org/news/author/CodeHemaa">Ophy Boamah</a></li><li><a href="https://freecodecamp.org/news/author/reedbarger">Reed</a></li><li><a href="https://freecodecamp.org/news/author/anjanbaradwaj">Anjan Baradwaj</a></li><li><a href="https://freecodecamp.org/news/author/officialrajdeepsingh">Rajdeep Singh</a></li><li><a href="https://freecodecamp.org/news/author/SmoothTech">Timothy Olanrewaju</a></li><li><a href="https://freecodecamp.org/news/author/dbclinton">David Clinton</a></li><li><a href="https://freecodecamp.org/news/author/FahimFBA">Md. Fahim Bin Amin</a></li><li><a href="https://freecodecamp.org/news/author/TheAnkurTyagi">Ankur Tyagi</a></li><li><a href="https://freecodecamp.org/news/author/ashutoshkrris">Ashutosh Krishna</a></li><li><a href="https://freecodecamp.org/news/author/Ijay">Ijeoma Igboagu</a></li><li><a href="https://freecodecamp.org/news/author/grantdotdev">Grant Riordan</a></li><li><a href="https://freecodecamp.org/news/author/elizabethmeshioye">Elizabeth Lola</a></li><li><a href="https://freecodecamp.org/news/author/atapas">Tapas Adhikary</a></li><li><a href="https://freecodecamp.org/news/author/anshulsanghi">Anshul Sanghi</a></li><li><a href="https://freecodecamp.org/news/author/Clifftech">Isaiah Clifford Opoku</a></li><li><a href="https://freecodecamp.org/news/author/CaesarSage">Destiny Erhabor</a></li><li><a href="https://freecodecamp.org/news/author/danieltunj">Daniel Adetunji</a></li><li><a href="https://freecodecamp.org/news/author/hunor">Hunor Márton Borbély</a></li><li><a href="https://freecodecamp.org/news/author/Tioluwani">Oyedele Tioluwani</a></li><li><a href="https://freecodecamp.org/news/author/nyayicfanny">Fanny Nyayic</a></li><li><a href="https://freecodecamp.org/news/author/jcubic">Jakub T. Jankiewicz</a></li><li><a href="https://freecodecamp.org/news/author/DanielKehoe">Daniel Kehoe</a></li><li><a href="https://freecodecamp.org/news/author/Kamaldeen">Kamaldeen Lawal</a></li><li><a href="https://freecodecamp.org/news/author/josevnz">Jose Vicente Nunez</a></li><li><a href="https://freecodecamp.org/news/author/prankurpandeyy">Prankur Pandey</a></li><li><a href="https://freecodecamp.org/news/author/asfakahmed">Asfak Ahmed</a></li><li><a href="https://freecodecamp.org/news/author/obumnwabude">Obum</a></li><li><a href="https://freecodecamp.org/news/author/Spruce">Spruce Emmanuel</a></li><li><a href="https://freecodecamp.org/news/author/Koded001">Temitope Oyedele</a></li><li><a href="https://freecodecamp.org/news/author/marco-venturi">Marco Venturi</a></li><li><a href="https://freecodecamp.org/news/author/sleekcodes">Austin Asoluka</a></li><li><a href="https://freecodecamp.org/news/author/askvikram">Vikram Aruchamy</a></li><li><a href="https://freecodecamp.org/news/author/DanielAsaboro">Daniel Asaboro</a></li><li><a href="https://freecodecamp.org/news/author/huericnan">Eric Hu</a></li><li><a href="https://freecodecamp.org/news/author/Toria">Victoria Burabari Poromon</a></li><li><a href="https://freecodecamp.org/news/author/anantchowdhary">Anant Chowdhary</a></li><li><a href="https://freecodecamp.org/news/author/kealanparr">Kealan Parr</a></li><li><a href="https://freecodecamp.org/news/author/OlehRomanyuk">Oleh Romanyuk</a></li><li><a href="https://freecodecamp.org/news/author/Okosaleo">Okosa Leonard</a></li><li><a href="https://freecodecamp.org/news/author/HijabiCoder">Fatuma Abdullahi</a></li><li><a href="https://freecodecamp.org/news/author/boolfalse">San B</a></li><li><a href="https://freecodecamp.org/news/author/developeraspire">Franklin Okolie</a></li><li><a href="https://freecodecamp.org/news/author/chrisblakely01">Chris Blakely</a></li><li><a href="https://freecodecamp.org/news/author/codenil">Niladri S. Jyoti</a></li><li><a href="https://freecodecamp.org/news/author/kerneldevgr">Nikolaos Panagopoulos</a></li><li><a href="https://freecodecamp.org/news/author/Xtephen">oghenekparobo Stephen</a></li><li><a href="https://freecodecamp.org/news/author/keyurparalkar">Keyur Paralkar</a></li><li><a href="https://freecodecamp.org/news/author/AyaNabilOthman">Aya Nabil Othman</a></li><li><a href="https://freecodecamp.org/news/author/TantoluwaAlabiHerita">Tantoluwa Heritage Alabi NB</a></li><li><a href="https://freecodecamp.org/news/author/ashutoshbw">Ashutosh Biswas</a></li><li><a href="https://freecodecamp.org/news/author/MuhToyyib">Akande Olalekan Toheeb</a></li><li><a href="https://freecodecamp.org/news/author/GhoulKingR">Oduah Chigozie</a></li><li><a href="https://freecodecamp.org/news/author/codewithshahan">Programming with Shahan</a></li><li><a href="https://freecodecamp.org/news/author/bhav09">Bhavishya Pandit</a></li><li><a href="https://freecodecamp.org/news/author/Dotcodes">Abimbola Adedotun Samuel</a></li><li><a href="https://freecodecamp.org/news/author/REXTECH">Ifeanyi Otuonye</a></li><li><a href="https://freecodecamp.org/news/author/gor8808">Gor Grigoryan</a></li><li><a href="https://freecodecamp.org/news/author/trayalex812">Alex Tray</a></li><li><a href="https://freecodecamp.org/news/author/andrico1234">Andrico Karoulla</a></li><li><a href="https://freecodecamp.org/news/author/gatwirival">valentine Gatwiri</a></li><li><a href="https://freecodecamp.org/news/author/bajcmartinez">Juan Cruz Martinez</a></li><li><a href="https://freecodecamp.org/news/author/sieis">Eamonn Cottrell</a></li><li><a href="https://freecodecamp.org/news/author/dera10">Chidera Humphrey</a></li><li><a href="https://freecodecamp.org/news/author/toobaj">Tooba Jamal</a></li><li><a href="https://freecodecamp.org/news/author/balapriyac">Bala Priya C</a></li><li><a href="https://freecodecamp.org/news/author/snowolohijere">Faith Olohijere</a></li><li><a href="https://freecodecamp.org/news/author/Musab19">Musab Habeeb</a></li><li><a href="https://freecodecamp.org/news/author/oluwatobiss">Oluwatobi Sofela</a></li><li><a href="https://freecodecamp.org/news/author/THEJOHNCALEB">John Caleb</a></li><li><a href="https://freecodecamp.org/news/author/AmrDeveloper">Amr Hesham</a></li><li><a href="https://freecodecamp.org/news/author/andrewbaisden">Andrew Baisden</a></li><li><a href="https://freecodecamp.org/news/author/Hyemiie">Yemi Ojedapo</a></li><li><a href="https://freecodecamp.org/news/author/kaushal-joshi">Kaushal Joshi</a></li><li><a href="https://freecodecamp.org/news/author/chelmerrox">Losalini Rokocakau</a></li><li><a href="https://freecodecamp.org/news/author/irorochad">Iroro Chadere</a></li><li><a href="https://freecodecamp.org/news/author/Olabisi09">Olabisi Olaoye</a></li><li><a href="https://freecodecamp.org/news/author/hamdaanaliquatil">Hamdaan Ali</a></li><li><a href="https://freecodecamp.org/news/author/suleolanrewaju">Sule-Balogun Olanrewaju</a></li><li><a href="https://freecodecamp.org/news/author/Derekvibe">Okoro Emmanuel Nzube Derek</a></li><li><a href="https://freecodecamp.org/news/author/kdk">Nibesh Khadka</a></li><li><a href="https://freecodecamp.org/news/author/doroh">Chepkirui Dorothy</a></li><li><a href="https://freecodecamp.org/news/author/alex-anie">Alex Anie</a></li><li><a href="https://freecodecamp.org/news/author/jpromanonet">Juan P. Romano</a></li><li><a href="https://freecodecamp.org/news/author/Zubs">Zubair Idris Aweda</a></li><li><a href="https://www.freecodecamp.org/espanol/news/author/leonardo/">Leonardo José Castillo Lacruz</a></li></ul><h2 id="discord-top-contributors"><strong>Discord Top Contributors</strong></h2><ul><li>plamoni</li><li>jeremylt</li><li>Versailles</li><li>Science99</li><li>rhombert</li><li>localhost</li><li>goks563</li><li>Razzle Dazzle</li><li>hana</li><li>SaintPeter</li><li>Maestro</li><li>xCoffeeMan</li><li>Tex</li><li>Jim</li><li>bradtaniguchi</li><li>Mohammed_malleck</li><li>andrewdmitriev39r</li><li>ilenia</li><li>ArialLeslie</li><li>Chara</li><li>SaintElGandoSmokio</li><li>CapslockHero</li><li>g0vX</li><li>tgrtim</li><li>alpox</li><li>AlexG</li><li>dark</li><li>Lycelia</li><li>WangGang</li><li>Saburo</li><li>Bordin</li><li>Dylan</li><li>bulhaa</li><li>bro keeps whining</li><li>Tek</li></ul><p>freeCodeCamp 社区中有成千上万的参与者，这里我只是列出其中贡献最多的一些人们。</p><p>如果你有兴趣作为 freeCodeCamp 社区的开源贡献者，我建议你<a href="https://contribute.freecodecamp.org/#/">阅读我们的贡献者指南</a>，并加入我们的<a href="https://discord.gg/KVUmVXA">贡献者 Discord</a>。</p><p>再次感谢大家，happy coding。🏕️</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
