<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>实战 on 老张开工了</title>
    <link>/%E5%AE%9E%E6%88%98/</link>
    <description>Recent content in 实战 on 老张开工了</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Mon, 27 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="/%E5%AE%9E%E6%88%98/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>实战五：AI 测试与 CI 集成</title>
      <link>/posts/2026/07/ai-ci-integration/</link>
      <pubDate>Mon, 27 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/ai-ci-integration/</guid>
      <description>前 28 章你的 AI 工作都是&amp;quot;我自己在 OpenCode 里跑跑&amp;quot;。第 29 章把这一摊 x fail + AI action 流搬到 CI/CD pipeline 上：每个 PR 一来，就触发一组&amp;quot;AI 验证 + AI 改进建议 + 安全扫描&amp;quot;jobs，让 review 之前先帮 reviewer 把关。&#xA;29.1 任务范围 把 5 个 AI-augmented jobs 加到 .github/workflows/pr-review.yml：&#xA;┌─ on: pull_request │ ├─ Job 1: digest (1 min, $0.01) 摘要 + AI 一句话 review │ ├─ Job 2: sanity (2 min, $0.05) 安全 / 私有 / license 扫 │ ├─ Job 3: unit (10 min, $0) 跑测试 │ ├─ Job 4: skill-check (3 min, $0.</description>
    </item>
    <item>
      <title>实战四：用 Graph 重构大型项目</title>
      <link>/posts/2026/07/practice-graph-refactor/</link>
      <pubDate>Sat, 25 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/practice-graph-refactor/</guid>
      <description>第四个实战最 hairy：用 Graph 工作流引导 Agent 重构一个多模块（≥30 文件、≥5000 行）的中型项目。这种任务单 ReAct loop 撑不下来——决定要做什么、做哪部分、什么时候跳、什么时候熔断，全靠 Graph。&#xA;28.1 任务定义 一个老 Python 项目：&#xA;30+ 文件，5000+ LOC 没有类型注解，没有 unit test 覆盖（5%） pyproject.toml 里没 ruff 三个 orchestrator 文件 (main, cli.py, web_server.py) 错综耦合 重构目标（一季）：&#xA;引入类型注解 + basedpyright 严格 单测覆盖率 70%+ 三 orchestrator 拆出公共 lib 28.2 为什么单 Agent Loop 不行 一次 Claude Code session 用 ReAct loop 跑：&#xA;Step 1: 想想 - &amp;#34;拆 main 和 cli&amp;#34; 大致步骤 Step 2-30: 边读边改文件 30 个 → context soon 80k+ → 压缩 Step 31-50: 压缩了早期 notes, 起初约束忘 Step 51: refactor 30 文件已混乱,report &amp;#34;DONE but lots of TODO&amp;#34; Step 80-200: 又迭代一次,实际上模型忘了第 3 步的架构 budget 到,模型默认 &amp;#34;DONE&amp;#34;, 实际未完成 80% Graph + Looper 优势：把项目拆成 30 个 node, 每个 node 限 scope, progressive cap, 不烧枚举上下文。</description>
    </item>
    <item>
      <title>实战三：多 Agent 工作流搭建</title>
      <link>/posts/2026/07/practice-multi-agent/</link>
      <pubDate>Thu, 23 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/practice-multi-agent/</guid>
      <description>第三个实战是把 13 章 Subagent 派发的理论变成一个可跑的多 Agent workflow：实情场景——&amp;ldquo;每周定期给团队新生 PR 做 triage / 分配 reviewer / 跑测试 brief&amp;rdquo;。&#xA;27.1 任务定义 每个周一早上 9 点，主 Agent 启动：&#xA;拉 open PRs（用 GitHub MCP） 按 PR 文件路径推理 owner（explore agent 5 个并行） 给每个 owner 生成 review brief（build agent, 5 个并行） 把 5 份 brief 拼成周报发给 Slack（slack MCP） 周一 9:00 Planner ─拉 PRs ──┐ │ 5 explore ─并行─→ owner map │ 5 build ─并行─→ review brief │ Slack send ─→ 单条最终消息 │ └ DONE 9:08 27.</description>
    </item>
    <item>
      <title>实战二：开发 MCP Server 集成内部工具</title>
      <link>/posts/2026/07/practice-mcp-server/</link>
      <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/practice-mcp-server/</guid>
      <description>第二个实战把第 15-19 章的 MCP 理论组装起来——开发一个能上生产的 mcp-internal-ops，让团队所有 Agent 都能查公司内部 dashboard、读 CI 历史、触发预部署。&#xA;26.1 任务边界 先限定范围，否则内部 MCP 容易变成&amp;quot;什么都包&amp;quot;。我们的 server 提供：&#xA;Tool 名 作用 副作用 ops.query 查询内部 SQL dashboard (readonly) 无 ops.ci_runs 最近 10 次 CI 状态 无 ops.preflight 触发预部署 sandbox（不 prod） 有 ops.slo 90 天 SLO 指标 无 不提供：&#xA;写数据的接口 触发 prod 部署 任何跟客户数据 / 法规 / 安全相关的查询 写操作只有一个 preflight，且只在 sandbox。&#xA;26.2 技术选型 Python + uv 环境 + mcp[cli] httpx 调内部 dashboard API pydantic 校验 启动方式：stdio（harness 启子进程） 26.</description>
    </item>
    <item>
      <title>实战一：构建一个 Docs Skill</title>
      <link>/posts/2026/07/practice-docs-skill/</link>
      <pubDate>Sun, 19 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/practice-docs-skill/</guid>
      <description>进入实战篇。第一个练习是写一个让你团队所有项目共享的 docs-update Skill——专治&amp;quot;AI 帮我改完代码但文档没同步&amp;quot;。一个实战把第 20-24 章 Skill 五篇理论全部跑一遍。&#xA;25.1 任务定义 场景：AI 改了代码 → 你 review 通过 → 但 docs 没动 → 几天后用户文档跟现实不符。&#xA;目标 Skill：在每次代码改动 review 完成后，主动让 Agent 检查、必要时改 docs：&#xA;触发：commit / PR 阶段 不要触发：debug session、解释性问题 DONE：所有公开 API、命令行参数、配置文件均与现有 docs 一致 / 已提出 docs 改动建议 失败模式：找不到 docs/、docs 在另一个 repo、docs 仅图片形式 25.2 写 SKILL.md .opencode/skills/docs-update/SKILL.md：&#xA;--- name: docs-update version: 0.1.0 description: | After code changes are staged or committed, check whether the related docs are still accurate.</description>
    </item>
    <item>
      <title>编写你的第一个 Skill</title>
      <link>/posts/2026/07/first-skill/</link>
      <pubDate>Mon, 13 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/first-skill/</guid>
      <description>理论 21 篇讲完了，本章从零写一个真实 Skill，让你看一遍从想法 → 写 SKILL.md → references 拆解 → 测试 → 装入 OpenCode → 上调用的全过程。我们要写的 Skill 叫 tdd-reminder：让主 Agent 在写新代码前先提示用户走 TDD。&#xA;22.1 Skill 想法从哪里来 三步法挖掘想法：&#xA;找你过去 7 天的 OpenCode session log&#xA;grep 模式 &amp;ldquo;你忘了 / 你没做 / 应该先&amp;rdquo;&#xA;rg &amp;#34;忘了\|应该\|未做\|先\|要是之前&amp;#34; .opencode/log/ | head -20 凡是出现 3 次以上的模式，就是候选 Skill&#xA;我自己日志里有一条：&amp;ldquo;每次写完 Python 函数才发现没写测试，又往回加 test_test_xxx，凑合跑&amp;rdquo;——这就是 tdd-reminder 要解决的：让 Agent 在写实现代码前主动说一句&amp;quot;咱们先写 test 行吗&amp;quot;。&#xA;22.2 拆解 Skill 行为需求 维度 spec Trigger 主 Agent 即将写 Python / TS / Go / Rust 代码,且函数 / class 存在 不要触发 1）用户问解释性问题 2）改一行小 bug 3）已有现成测试 行为 提醒想先写 unit test；提供一次 brainstorm 机会,而非强制 DONE 用户明确说 &amp;ldquo;不用 test&amp;rdquo; 或 用户已提供 test 或 单元 test 跑通 失败模式 1）用户说&amp;quot;快点别叨叨&amp;quot; → 跳过加 [tdd-reminder skipped] 自报\n2）该语言无 pytest 等价物 → 改用最简化 shell test 22.</description>
    </item>
    <item>
      <title>开发你的第一个 MCP Server</title>
      <link>/posts/2026/07/mcp-server-dev/</link>
      <pubDate>Fri, 03 Jul 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/07/mcp-server-dev/</guid>
      <description>读完生态速览，你大概发现 30% 的需求是现成 server 满足不了的——尤其是自家业务 API和团队内部数据。本章手把手写一个：把公司内部 admin API 暴露成 MCP，让所有 harness 都能调用。&#xA;17.1 任务范围 做一个 MCP server 叫 mcp-tickets，让 Agent 能：&#xA;列出内部工单系统里的 ticket（按状态） 取一条 ticket 详情 给 ticket 加一条 internal comment 只读为主，写操作需要确认 我们用 Python 写（生态成熟，团队好上手）；TypeScript 版结构近似，章末给一行对比。&#xA;17.2 起手装环境 uv init mcp-tickets cd mcp-tickets uv add &amp;#34;mcp[cli]&amp;#34; uv add httpx pydantic mcp[cli] 是官方 Python SDK，含 stdio server 与 cli 工具。httpx 是要调内部 API，pydantic 做参数校验。&#xA;17.3 项目骨架 mcp-tickets/ ├── pyproject.toml ├── src/ │ └── mcp_tickets/ │ ├── __init__.</description>
    </item>
    <item>
      <title>Prompt 工程入门：与 LLM 有效沟通</title>
      <link>/posts/2026/06/prompt-engineering/</link>
      <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/06/prompt-engineering/</guid>
      <description>Prompt 工程不是&amp;quot;魔法咒语学&amp;quot;。它是一种把任务讲清楚的能力——本质和你跟同事讲需求时讲得清楚不清楚没差别，只不过对面这个&amp;quot;同事&amp;quot;在某些维度更敏感（对结构、对示例、对上下文），在另一些维度更迟钝（不会自己反问、对领域黑话毫无知觉）。本章让你不是去背 100 句&amp;quot;完美 prompt 模板&amp;quot;，而是建立一套底层心法。&#xA;3.1 一个反直觉：把模型当实习生，而不是当神 坏 prompt：写一个爬虫 好 prompt： 目标：爬取 https://example.com 上分页列表的标题。 输入：起始 URL（list 页第 1 页）。 输出：写入 items.jsonl，每行一个 {url, title}。 约束：使用 httpx + selectolax，遵守 robots.txt，限速 1 req/s。 错误处理：403 跳过该页，其他状态码重试 3 次。 差别不在字数，而在让模型知道边界。模型是个&amp;quot;特别想被使用的实习生&amp;quot;——你给的信息越具体，它越不会瞎发挥。&#xA;3.2 五元素清单 每次写 prompt 默念一遍：&#xA;元素 作用 常被漏掉导致 目标（Goal） 一句话说清产出是什么 跑题、答非所问 输入（Input） 模型能拿到什么数据 自己编数据幻觉 输出（Output） 形式、格式、字段名 你要 csv 它给你 md 约束（Constraints） 不能做什么、用什么库 库不一致、风格漂移 示例（Examples） 1-2 条&amp;quot;输入→输出&amp;quot;样板 边界情况误判 后两个最容易被偷懒省掉，也是新手与熟手 prompt 之间最大的差距来源。&#xA;3.3 三种情境，三种写法 3.3.1 一次性任务（最常见） 任务：把下面 SQL 解释给非技术同事听。 SQL: EXPLAIN ANALYZE SELECT region, sum(revenue) FROM orders WHERE created_at &amp;gt; &amp;#39;2026-01-01&amp;#39; GROUP BY region; 输出要求： - 一句话主旨 - 三到五条要点 - 最后一句给一个最关键的&amp;#34;为什么慢&amp;#34;的提醒 - 不超过 150 字 要点：明确形式 + 字数上限 + 受众。能压字数比讲道理有用。</description>
    </item>
    <item>
      <title>综合实战：构建命令行工具</title>
      <link>/posts/2026/05/cli-project/</link>
      <pubDate>Sat, 30 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/05/cli-project/</guid>
      <description>欢迎来到本系列的最后一个项目！经过前面 29 篇文章的学习，你已经掌握了 Python 的方方面面。现在是时候把所有知识串联起来，从零构建一个完整的命令行工具了。&#xA;项目概览：任务管理器 CLI 我们将构建一个&amp;quot;任务管理器&amp;quot;（Task Manager）CLI 工具，它具备以下功能：&#xA;task-cli add &amp;#34;学习 Python 装饰器&amp;#34; --priority high # 添加任务 task-cli list # 列出所有任务 task-cli list --status pending # 按状态筛选 task-cli done 1 # 完成任务 #1 task-cli delete 1 # 删除任务 #1 task-cli show 1 # 查看任务详情 技术栈：纯 Python 标准库 + argparse + dataclasses + JSON 文件持久化。不需要任何第三方依赖。&#xA;第 1 步：项目结构 task-cli/ ├── src/ │ └── task_cli/ │ ├── __init__.py │ ├── __main__.</description>
    </item>
    <item>
      <title>网络请求与 API 调用</title>
      <link>/posts/2026/05/network-requests/</link>
      <pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/05/network-requests/</guid>
      <description>当今的软件世界是互联的。你的程序需要获取天气数据、调用 ChatGPT API、从 GitHub 拉取仓库信息、向飞书群发送通知……所有这些都离不开网络请求。&#xA;Python 的标准库提供了 urllib.request，但社区几乎都选择更人性化的 requests 库。本章从基础到实战，带你掌握 Python 中的 HTTP 通信。&#xA;HTTP 基础回顾 在你写代码之前，了解 HTTP 的基本概念会很有帮助：&#xA;概念 说明 URL 统一资源定位符，标识资源的位置 HTTP 方法 GET（获取）、POST（创建）、PUT（全量更新）、PATCH（部分更新）、DELETE（删除） 请求头 携带元信息，如认证 Token、内容类型 请求体 POST/PUT 时发送的数据 状态码 200（成功）、201（创建成功）、400（请求错误）、401（未认证）、404（未找到）、500（服务器错误） 响应体 服务器返回的数据，通常为 JSON 格式 urllib.request：内置方案 Python 标准库自带的 HTTP 客户端，无需安装：&#xA;from urllib.request import Request, urlopen from urllib.parse import urlencode import json # GET 请求 response = urlopen(&amp;#34;https://httpbin.org/get&amp;#34;) print(response.status) # 200 print(response.read().decode()) # JSON 格式的响应内容 # POST 请求 data = urlencode({&amp;#34;name&amp;#34;: &amp;#34;Alice&amp;#34;, &amp;#34;age&amp;#34;: 30}).</description>
    </item>
    <item>
      <title>虚拟环境与依赖管理</title>
      <link>/posts/2026/05/virtualenv-dependencies/</link>
      <pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/05/virtualenv-dependencies/</guid>
      <description>想象一下：你在项目 A 里用 Django 4.2，项目 B 因为遗留代码只能用 Django 3.2。如果全局只装一个版本的 Django，你只能在两个项目之间反复卸载重装——这简直是噩梦。&#xA;虚拟环境（Virtual Environment）就是来解决这个问题的：它为每个项目创建独立的 Python 环境，每个环境有自己的一套包，互不干扰。&#xA;为什么需要虚拟环境？ 依赖冲突问题 没有虚拟环境时，你的全局 Python 环境是这样的：&#xA;# 全局安装的包（所有项目共享） pip list # Django 4.2 # requests 2.31 # numpy 1.26 这对不同项目的需求造成了冲突：&#xA;项目 需要的版本 问题 项目 A Django 4.2 ✅ 项目 B Django 3.2 ❌ 全局装了 4.2 项目 C requests 2.20 ❌ 全局装了 2.31 虚拟环境的解决方案 系统 Python ├── 虚拟环境 A → Django 4.2, requests 2.31 ├── 虚拟环境 B → Django 3.</description>
    </item>
    <item>
      <title>测试入门：unittest 与 pytest</title>
      <link>/posts/2026/05/testing/</link>
      <pubDate>Wed, 27 May 2026 00:00:00 +0000</pubDate>
      <guid>/posts/2026/05/testing/</guid>
      <description>当项目从几十行代码膨胀到几千行时，你会面临一个残酷的现实：改了一处逻辑，不知道哪里会碎。手动测试一遍所有功能越来越耗时，而且人总会漏掉东西。这就是自动化测试登场的地方——用代码来验证代码。&#xA;Python 的标准库内置了 unittest 模块，社区则更青睐简洁的 pytest。本章从零开始，带你建立测试思维，掌握两种测试框架，最终写出可维护的测试。&#xA;为什么需要测试？ 没有测试的项目就像走在钢丝上：&#xA;# 假设这是你的核心函数 def calculate_discount(price: float, member_level: str) -&amp;gt; float: &amp;#34;&amp;#34;&amp;#34;根据会员等级计算折扣价&amp;#34;&amp;#34;&amp;#34; discounts = {&amp;#34;normal&amp;#34;: 0.95, &amp;#34;silver&amp;#34;: 0.9, &amp;#34;gold&amp;#34;: 0.8} return price * discounts.get(member_level, 1.0) # 改了一行代码——有人把 silver 的折扣改成了 0.85 # 没有测试的话，你可能永远不会发现这个&amp;#34;优化&amp;#34;改变了行为 测试带来的好处：&#xA;好处 说明 回归防护 修改代码后立即知道是否有东西被破坏 活的文档 测试代码展示了函数在各种情况下的预期行为 设计反馈 如果函数很难写测试，通常意味着它的设计需要改进 信心 重构时不怕改出问题，测试网络会兜住你 unittest：标准库自带 unittest 是 Python 标准库的一部分，灵感来自 Java 的 JUnit。不需要额外安装，开箱即用。&#xA;基本结构 import unittest # 被测函数 def add(a, b): return a + b class TestMathOperations(unittest.</description>
    </item>
    <item>
      <title>实战项目：电商数据库设计</title>
      <link>/posts/2025/03/ecommerce-database-project/</link>
      <pubDate>Wed, 05 Mar 2025 10:00:00 +0800</pubDate>
      <guid>/posts/2025/03/ecommerce-database-project/</guid>
      <description>本章将综合运用本系列所学的全部知识，设计一个完整的电商数据库系统——从需求分析、表结构设计、到高级查询和性能优化。&#xA;项目需求概述 构建一个支持多用户、多商品的电商平台后台数据库，主要功能包括：&#xA;用户注册与登录 商品浏览与搜索 购物车与下单 订单管理与支付 商品评价 后台数据分析 E-R 图 ┌──────────┐ ┌──────────────┐ ┌────────────┐ │ 用户 │──────→│ 购物车 │──────→│ 商品 │ └──────────┘ └──────────────┘ └────────────┘ ↓ ↑ ┌──────────┐ ┌──────────────┐ ┌──────────────┐ │ 地址 │ │ 订单 │──────→│ 订单明细 │ └──────────┘ └──────────────┘ └──────────────┘ ↓ ┌──────────────┐ ┌──────────────┐ │ 支付记录 │ │ 商品评价 │ └──────────────┘ └──────────────┘ 数据库设计与建表 -- 创建数据库 CREATE DATABASE ecommerce; \c ecommerce -- ============================ -- 1. 用户模块 -- ============================ CREATE TABLE es_users ( user_id SERIAL PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, email VARCHAR(200) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, phone VARCHAR(20), avatar_url TEXT, member_level VARCHAR(10) DEFAULT &amp;#39;普通&amp;#39; CHECK (member_level IN (&amp;#39;普通&amp;#39;, &amp;#39;银卡&amp;#39;, &amp;#39;金卡&amp;#39;, &amp;#39;钻石&amp;#39;)), status VARCHAR(10) DEFAULT &amp;#39;active&amp;#39; CHECK (status IN (&amp;#39;active&amp;#39;, &amp;#39;locked&amp;#39;, &amp;#39;deleted&amp;#39;)), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- 用户地址表 CREATE TABLE es_user_addresses ( address_id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES es_users(user_id), receiver_name VARCHAR(50) NOT NULL, receiver_phone VARCHAR(20) NOT NULL, province VARCHAR(50), city VARCHAR(50), district VARCHAR(50), detail_address TEXT NOT NULL, is_default BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW() ); -- ============================ -- 2.</description>
    </item>
    <item>
      <title>持续学习路径</title>
      <link>/posts/2025/01/learning-path/</link>
      <pubDate>Fri, 24 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/learning-path/</guid>
      <description>旅程回顾 欢迎来到本系列的最后一篇文章。在过去 24 篇文章中，我们一起走过了从零基础到能够独立完成数据项目的完整旅程。&#xA;基础篇（第 1-6 篇） 你学会了 Python 基础、NumPy、Pandas 和 Matplotlib。这些是数据分析的&amp;quot;手脚&amp;quot;，让你能动手操作数据。&#xA;进阶篇（第 7-12 篇） 你掌握了数据清洗、探索性分析、统计学基础和可视化进阶。你开始能从数据中发现故事。&#xA;高级篇（第 13-18 篇） 你学会了 A/B 测试、机器学习建模、特征工程和模型评估。你具备了用数据预测未来的能力。&#xA;实战篇（第 19-24 篇） 你用完整的项目把前面的知识串联起来：电商分析、用户行为分析、数据管道、大数据、数据产品化，以及本篇的学习路径。&#xA;# 本系列核心技能一览 skills_covered = { &amp;#34;编程基础&amp;#34;: [&amp;#34;Python&amp;#34;, &amp;#34;NumPy&amp;#34;, &amp;#34;Pandas&amp;#34;, &amp;#34;Jupyter&amp;#34;], &amp;#34;数据操作&amp;#34;: [&amp;#34;加载&amp;#34;, &amp;#34;清洗&amp;#34;, &amp;#34;转换&amp;#34;, &amp;#34;合并&amp;#34;, &amp;#34;分组聚合&amp;#34;], &amp;#34;可视化&amp;#34;: [&amp;#34;Matplotlib&amp;#34;, &amp;#34;Seaborn&amp;#34;, &amp;#34;Plotly&amp;#34;, &amp;#34;Streamlit&amp;#34;], &amp;#34;统计分析&amp;#34;: [&amp;#34;描述统计&amp;#34;, &amp;#34;假设检验&amp;#34;, &amp;#34;AB测试&amp;#34;, &amp;#34;回归分析&amp;#34;], &amp;#34;机器学习&amp;#34;: [&amp;#34;Scikit-learn&amp;#34;, &amp;#34;特征工程&amp;#34;, &amp;#34;模型评估&amp;#34;, &amp;#34;调参&amp;#34;], &amp;#34;工程化&amp;#34;: [&amp;#34;ETL管道&amp;#34;, &amp;#34;Airflow&amp;#34;, &amp;#34;PySpark&amp;#34;, &amp;#34;FastAPI&amp;#34;], &amp;#34;产品化&amp;#34;: [&amp;#34;Streamlit仪表盘&amp;#34;, &amp;#34;模型API&amp;#34;, &amp;#34;自动化报告&amp;#34;, &amp;#34;MLOps&amp;#34;], } for category, skills in skills_covered.</description>
    </item>
    <item>
      <title>数据产品化</title>
      <link>/posts/2025/01/data-productization/</link>
      <pubDate>Thu, 23 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/data-productization/</guid>
      <description>从分析到产品 在前面的文章中，我们做了大量分析工作：清洗数据、可视化趋势、建立模型、挖掘洞察。但这些分析的产出大多是 Jupyter Notebook 或 PDF 报告，业务团队无法直接交互使用。&#xA;数据产品化就是把分析成果转化为可交互、可复用、可部署的工具。典型的数据产品包括：&#xA;交互式仪表盘：业务人员可以自助查看指标 API 服务：其他系统可以调用模型预测 自动化报告：定时生成并分发 数据目录：帮助团队理解和发现数据 用 Streamlit 构建交互式仪表盘 Streamlit 是 Python 生态中最流行的数据应用框架。它让你用纯 Python 写出漂亮的 Web 应用，不需要 HTML/CSS/JS。&#xA;安装 pip install streamlit pandas matplotlib plotly 基础仪表盘示例 # dashboard.py import streamlit as st import pandas as pd import plotly.express as px import plotly.graph_objects as go from datetime import datetime, timedelta # 页面配置 st.set_page_config( page_title=&amp;#34;电商销售仪表盘&amp;#34;, page_icon=&amp;#34;📊&amp;#34;, layout=&amp;#34;wide&amp;#34; ) st.title(&amp;#34;📊 电商销售实时仪表盘&amp;#34;) st.markdown(&amp;#34;---&amp;#34;) # 缓存数据加载（避免每次交互都重读） @st.cache_data def load_data(): df = pd.</description>
    </item>
    <item>
      <title>大数据入门</title>
      <link>/posts/2025/01/big-data-intro/</link>
      <pubDate>Wed, 22 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/big-data-intro/</guid>
      <description>什么时候需要大数据？ 在前面的文章中，我们一直用 Pandas 处理数据。对于百万级的数据集，Pandas 表现良好。但当数据量达到千万、亿级时，你会遇到以下问题：&#xA;内存不足：Pandas 需要把所有数据加载到内存中。10GB 的 CSV 文件需要至少 10GB 内存来进行处理。 计算时间过长：groupby 或 join 操作可能需要几分钟甚至几小时。 单机资源瓶颈：一台机器的 CPU 核心数有限，无法并行处理大量数据。 这就是大数据技术介入的时刻。&#xA;大数据 4V 特征 特征 英文 说明 体量 Volume 数据量巨大，TB 甚至 PB 级别 速度 Velocity 数据生产和处理速度快，实时流数据 多样 Variety 数据类型多样：结构化、半结构化、非结构化 真实 Veracity 数据质量和真实性不一致，需要验证 分布式计算基础 大数据的核心理念是分布式计算：把大任务拆成小块，在多台机器上并行执行。&#xA;MapReduce 思想 MapReduce 是分布式计算的经典范式，包含两个阶段：&#xA;Map（映射）：把数据分片，每个分片独立处理，产生键值对 Reduce（归约）：将相同键的结果聚合起来 输入: [A, B, C, D, E, F] | | | | | | Map Map Map Map Map Map (并行处理) | | | | | | \ / \ / \ / Reduce Reduce Reduce (聚合结果) | | | [结果1] [结果2] [结果3] Apache Spark 概述 Spark 是目前最流行的大数据处理框架。它比传统的 Hadoop MapReduce 快 10-100 倍，因为它利用内存计算，避免了频繁的磁盘读写。</description>
    </item>
    <item>
      <title>数据管道与自动化</title>
      <link>/posts/2025/01/data-pipeline/</link>
      <pubDate>Tue, 21 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/data-pipeline/</guid>
      <description>为什么要构建数据管道？ 在前两篇文章中，我们手动加载数据、做清洗、分析、可视化。但如果这个过程需要每天重复做一次呢？比如每天早上都要给业务团队发一份昨天的销售报告。&#xA;手动做几件事很麻烦：&#xA;每天从不同系统导出数据 重复执行相同的清洗和分析代码 把结果发给不同的人 一旦某个环节出错，整个流程中断 数据管道（Data Pipeline）就是为了解决这些问题。它把数据处理流程自动化、标准化、可重复化。&#xA;ETL 与 ELT 架构 在构建数据管道前，需要了解两种主流架构。&#xA;ETL（Extract, Transform, Load） 数据先提取到中间层做转换，再加载到目标系统。&#xA;数据源 → 提取 → 转换 → 加载 → 数据仓库 适合场景：&#xA;目标系统对数据格式有严格要求 需要在加载前清洗和标准化数据 传统数据仓库场景 ELT（Extract, Load, Transform） 数据先原始加载到目标系统，在目标系统内做转换。&#xA;数据源 → 提取 → 加载 → 数据湖/仓库 → 按需转换 适合场景：&#xA;目标系统计算能力强（如云数据仓库） 需要保留原始数据以备后续重新处理 分析需求经常变化 # ETL 示例：提取 → 转换 → 加载 # Extract def extract_from_csv(filepath): return pd.read_csv(filepath) def extract_from_api(api_url, api_key): import requests headers = {&amp;#39;Authorization&amp;#39;: f&amp;#39;Bearer {api_key}&amp;#39;} response = requests.</description>
    </item>
    <item>
      <title>用户行为分析实战</title>
      <link>/posts/2025/01/user-behavior-analysis/</link>
      <pubDate>Mon, 20 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/user-behavior-analysis/</guid>
      <description>项目背景 上一篇文章我们分析了电商订单数据，得到了&amp;quot;是什么&amp;quot;的答案。但订单只是用户行为的终点。要真正理解用户，我们需要追踪和分析用户的完整行为路径：他们从哪来，在站内做了什么，为什么最终选择购买或离开。&#xA;本实战项目使用用户事件日志数据，涵盖页面浏览、点击、加购、支付等行为。我们将围绕以下几个核心问题展开分析：&#xA;用户的留存情况如何？不同渠道获取的用户留存有无差异？ 从访看到购买的转化漏斗中，哪个环节流失最严重？ 用户的日活跃度、使用深度如何？ 如何用 AARRR 框架系统评估用户生命周期？ 不同用户群体的行为模式有何差异？ 用户的终身价值该如何估算？ 数据加载与预处理 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datetime import datetime, timedelta import warnings warnings.filterwarnings(&amp;#39;ignore&amp;#39;) plt.rcParams[&amp;#39;font.sans-serif&amp;#39;] = [&amp;#39;SimHei&amp;#39;] plt.rcParams[&amp;#39;axes.unicode_minus&amp;#39;] = False # 事件日志数据 events = pd.read_csv(&amp;#39;user_events.csv&amp;#39;) print(f&amp;#39;事件总数: {len(events):,}&amp;#39;) print(f&amp;#39;唯一用户数: {events[&amp;#34;user_id&amp;#34;].nunique():,}&amp;#39;) events.head() 事件日志数据通常包含以下字段：&#xA;字段 含义 示例 event_id 事件编号 唯一标识 user_id 用户编号 匿名字段 event_type 事件类型 page_view, click, add_to_cart, purchase page_url 页面地址 /products/123 timestamp 事件时间 2025-01-15 14:30:00 session_id 会话编号 区分不同访问会话 channel 来源渠道 organic, paid, referral, social device 设备类型 mobile, desktop, tablet # 时间字段处理 events[&amp;#39;timestamp&amp;#39;] = pd.</description>
    </item>
    <item>
      <title>电商销售分析实战</title>
      <link>/posts/2025/01/ecommerce-analysis/</link>
      <pubDate>Sun, 19 Jan 2025 00:00:00 +0000</pubDate>
      <guid>/posts/2025/01/ecommerce-analysis/</guid>
      <description>项目背景 电商销售数据是数据分析入门最经典的真实场景之一。每一笔订单背后都藏着用户行为、市场趋势和运营机会。在这个实战项目中，我们将扮演一家电商公司的数据分析师，从原始订单数据出发，完成一个完整的数据分析闭环。&#xA;业务问题定义 分析开始之前，我们要先明确业务方关心的问题：&#xA;销售额的整体趋势如何？有没有季节性规律？ 哪些产品和品类贡献了主要收入？ 客户的地域分布是怎样的？ 哪些客户是高价值用户？如何区分不同价值的客户群体？ 未来一个月销售额大概会是多少？ 这些问题将指导我们后续的每一步分析。&#xA;数据加载与初始探索 我们先加载数据并了解基本情况。&#xA;import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from datetime import datetime import warnings warnings.filterwarnings(&amp;#39;ignore&amp;#39;) plt.rcParams[&amp;#39;font.sans-serif&amp;#39;] = [&amp;#39;SimHei&amp;#39;] plt.rcParams[&amp;#39;axes.unicode_minus&amp;#39;] = False df = pd.read_csv(&amp;#39;ecommerce_orders.csv&amp;#39;) print(f&amp;#39;数据集大小: {df.shape}&amp;#39;) print(f&amp;#39;列名: {df.columns.tolist()}&amp;#39;) df.head() 假设我们的数据包含以下字段：&#xA;字段 含义 类型 order_id 订单编号 字符串 customer_id 客户编号 字符串 product_id 产品编号 字符串 category 产品类别 字符串 price 单价 浮点数 quantity 数量 整数 order_date 订单日期 日期 shipping_address 收货地址 字符串 payment_method 支付方式 字符串 status 订单状态 字符串 df.</description>
    </item>
  </channel>
</rss>
