<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Neo 桃花源</title><description>Kano_Blog</description><link>https://kano.lzink.icu/</link><language>zh_CN</language><item><title>Linux——从入门到放弃 #1</title><link>https://kano.lzink.icu/dist/posts/2026-05-11-linux%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E5%9C%9F1/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2026-05-11-linux%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E5%9C%9F1/</guid><description>Liunx系统目录介绍</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;一、Linux 目录结构&lt;/h1&gt;
&lt;p&gt;在 Windows 系统中，所有文件通过&lt;strong&gt;分区&lt;/strong&gt;来管理，每个分区都有独立的目录树，彼此之间没有紧密联系。与 Windows 不同，Linux 系统的目录结构是一棵&lt;strong&gt;倒状树&lt;/strong&gt;——所有目录和文件都从唯一的根目录 &lt;code&gt;/&lt;/code&gt; 出发，层层嵌套。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/
├── bin/      # 常用命令（二进制可执行文件）
├── boot/     # 系统内核及启动文件
├── dev/      # 设备文件
├── etc/      # 系统配置文件
├── home/     # 普通用户的家目录
├── lib/      # 库文件
├── mnt/      # 临时挂载点
├── root/     # 管理员用户的家目录
├── tmp/      # 临时文件
└── usr/      # 系统应用程序及文档
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;常见目录速查&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;目录&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/bin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放常用命令（二进制可执行文件）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/etc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放系统配置文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/home&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;所有普通用户的家目录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/root&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;管理员（root）用户的家目录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/usr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放系统应用程序及文档&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/lib&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放库文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放设备文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/mnt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;临时挂载点&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/boot&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放系统内核及各种启动文件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/tmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存放各种临时文件&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;二、绝对路径与相对路径&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;绝对路径&lt;/strong&gt;：从系统根目录 &lt;code&gt;/&lt;/code&gt; 开始到指定位置的完整路径。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;相对路径&lt;/strong&gt;：从当前目录开始到指定位置的路径。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以 &lt;code&gt;main.c&lt;/code&gt; 文件为例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;绝对路径：&lt;code&gt;/home/kaishen/project/main.c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;相对路径：&lt;code&gt;./main.c&lt;/code&gt; 或 &lt;code&gt;../kaishen/project/main.c&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;提示&lt;/strong&gt;：&lt;code&gt;.&lt;/code&gt; 表示当前目录，&lt;code&gt;..&lt;/code&gt; 表示当前目录的上一层目录。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;三、家目录的概念&lt;/h2&gt;
&lt;p&gt;所有普通用户都在 &lt;code&gt;/home&lt;/code&gt; 下以该用户名创建一个专属目录，这个目录就是用户的&lt;strong&gt;家目录&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;每个用户只能在自己的家目录下创建文件、操作文件，&lt;strong&gt;不能访问其他用户的家目录&lt;/strong&gt;，这是 Linux 多用户隔离的安全基础。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;四、文件类型与权限&lt;/h2&gt;
&lt;h3&gt;4.1 文件类型&lt;/h3&gt;
&lt;p&gt;与 Windows 不同，Linux 中&lt;strong&gt;一切皆文件&lt;/strong&gt;（文件夹也是一种特殊文件）。Linux 将文件分为以下几类：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;普通文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;常规数据文件（文本、二进制等）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;目录文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文件夹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;管道文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用于进程间通信&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;链接文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;软链接（类似 Windows 快捷方式）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;块设备文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;硬盘、U盘等块设备&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;字符设备文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;键盘、鼠标等字符设备&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;套接字文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;网络通信套接字&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Linux &lt;strong&gt;不以文件扩展名&lt;/strong&gt;来区分文件类型，而是在文件属性中专门有一列来标识文件类型。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4.2 理解文件权限&lt;/h3&gt;
&lt;p&gt;以 &lt;code&gt;main.c&lt;/code&gt; 为例，使用 &lt;code&gt;ls -l&lt;/code&gt; 查看：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-rw-rw-r--  1  kaishen  kaishen  93  May 11 10:00  main.c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;各字段含义拆解如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文件类型（&lt;code&gt;-&lt;/code&gt; 表示普通文件）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rw-rw-r--&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;权限位（详见下方）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;硬链接数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kaishen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文件属主（User）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kaishen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;所属组（Group）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;93&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文件大小（字节）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;May 11 10:00&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;最后修改时间&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;main.c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;文件名&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;4.3 权限位详解&lt;/h3&gt;
&lt;p&gt;权限字符串 &lt;code&gt;rw-rw-r--&lt;/code&gt; 可分为三组，每组三个字符：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  rw-      rw-      r--
   ↓        ↓        ↓
  User     Group    Other
  (属主)   (同组)   (其他)
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字符&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;数值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;读权限（Read）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;写权限（Write）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;执行权限（eXecute）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;无权限&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;原理&lt;/strong&gt;：Linux 内核用二进制掩码来存储 9 个权限位，配合位运算判断权限，比字符串比对高效得多。例如 &lt;code&gt;rw-rw-r--&lt;/code&gt; 的二进制表示为 &lt;code&gt;110 110 100&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;五、修改文件权限：&lt;code&gt;chmod&lt;/code&gt;&lt;/h2&gt;
&lt;h3&gt;5.1 文字设定法&lt;/h3&gt;
&lt;p&gt;通过 &lt;code&gt;u&lt;/code&gt;（属主）、&lt;code&gt;g&lt;/code&gt;（同组）、&lt;code&gt;o&lt;/code&gt;（其他）配合 &lt;code&gt;+&lt;/code&gt;/&lt;code&gt;-&lt;/code&gt;/&lt;code&gt;=&lt;/code&gt; 来增减权限：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 减去属主的写权限
chmod u-w 1

# 加上属主的写权限
chmod u+w 1

# 同时设置属主读写执行、同组读写、其他只读
chmod u=rwx,g=rw,o=r 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5.2 数字设定法&lt;/h3&gt;
&lt;p&gt;每位数字 = 对应角色的权限数值之和：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  7        7        5
  ↓        ↓        ↓
 User     Group   Other
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例如 &lt;code&gt;rwxrwxr-x&lt;/code&gt; = &lt;strong&gt;775&lt;/strong&gt;：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;权限&lt;/th&gt;
&lt;th&gt;计算&lt;/th&gt;
&lt;th&gt;值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4+2+1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Group&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rwx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4+2+1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Other&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r-x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4+0+1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;# 设置为 rwxrwxr-x
chmod 775 main.c

# 设置为 rw-rw-r--
chmod 664 main.c
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;小结&lt;/h2&gt;
&lt;p&gt;本文带你初识了 Linux 操作系统，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;倒状树型目录结构及常见目录的作用&lt;/li&gt;
&lt;li&gt;绝对路径与相对路径的区别&lt;/li&gt;
&lt;li&gt;家目录与多用户隔离的概念&lt;/li&gt;
&lt;li&gt;文件类型、权限位的理解&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;chmod&lt;/code&gt; 命令修改文件权限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;掌握这些基础知识，你就已经迈出了 Linux 学习的第一步！&lt;/p&gt;
</content:encoded></item><item><title>多智能体协同——主Agent</title><link>https://kano.lzink.icu/dist/posts/agent_prompt/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/agent_prompt/</guid><description>通用主Agent调度提示词分享</description><pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. 项目概述&lt;/h2&gt;
&lt;p&gt;一个&lt;strong&gt;场景无关的通用主Agent调度提示词模板&lt;/strong&gt;，用于驱动多智能体（Multi-Agent）协作系统完成复杂任务的自动化开发与质量验证。经过30+轮设计评审和11项工程缺陷修复，形成了一套可复用的编排骨架。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心命题&lt;/strong&gt;：在主Agent上下文窗口有限的约束下，如何安全、可靠、可恢复地调度多个子Agent完成&quot;计划→执行→验证→修正&quot;闭环。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. 技术栈&lt;/h2&gt;
&lt;h3&gt;2.1 运行时平台&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;组件&lt;/th&gt;
&lt;th&gt;技术&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent 框架&lt;/td&gt;
&lt;td&gt;Claude Agent SDK / Claude Code&lt;/td&gt;
&lt;td&gt;多Agent启动、resume、后台运行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;语言模型&lt;/td&gt;
&lt;td&gt;DeepSeek-v4-pro / DeepSeek-v4-flash&lt;/td&gt;
&lt;td&gt;主Agent用pro做调度决策，CHECK用falsh降本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;操作系统&lt;/td&gt;
&lt;td&gt;Windows（bash 环境）&lt;/td&gt;
&lt;td&gt;Git Bash 提供 GNU 工具链&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shell&lt;/td&gt;
&lt;td&gt;GNU Bash&lt;/td&gt;
&lt;td&gt;find / sed / grep / ls / mkdir / stat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文件系统&lt;/td&gt;
&lt;td&gt;NTFS&lt;/td&gt;
&lt;td&gt;标记文件、日志、报告、产物均落盘&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.2 核心CLI依赖&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;工具&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;关键参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent ID 探测&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-newer&lt;/code&gt; 时间过滤、&lt;code&gt;-printf&lt;/code&gt; 时间排序&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;plan.md 状态标记更新（兜底）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-i&lt;/code&gt; 原地替换，捕获组保留标题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;测试报告判定提取&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pattern=&quot;^### 判定&quot;&lt;/code&gt; 只取第一行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt; / &lt;code&gt;Glob&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;标记文件扫描&lt;/td&gt;
&lt;td&gt;&lt;code&gt;status/*.done&lt;/code&gt; / &lt;code&gt;status/*.pass&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;初始化目录结构&lt;/td&gt;
&lt;td&gt;&lt;code&gt;status/&lt;/code&gt; / &lt;code&gt;reports/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.3 文件体系&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;文件&lt;/th&gt;
&lt;th&gt;生产者&lt;/th&gt;
&lt;th&gt;消费者&lt;/th&gt;
&lt;th&gt;主Agent权限&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;plan.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PLAN&lt;/td&gt;
&lt;td&gt;DO, CHECK, MASTER&lt;/td&gt;
&lt;td&gt;只读状态行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;guide.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PLAN&lt;/td&gt;
&lt;td&gt;DO, CHECK&lt;/td&gt;
&lt;td&gt;不读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lessons.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PLAN→DO&lt;/td&gt;
&lt;td&gt;DO, PLAN&lt;/td&gt;
&lt;td&gt;不读&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;log.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MASTER&lt;/td&gt;
&lt;td&gt;MASTER&lt;/td&gt;
&lt;td&gt;读写&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reports/{单元}-{维度}.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CHECK&lt;/td&gt;
&lt;td&gt;DO(全读), MASTER(判定行)&lt;/td&gt;
&lt;td&gt;Grep 判定行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;status/{单元}.done&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DO&lt;/td&gt;
&lt;td&gt;MASTER&lt;/td&gt;
&lt;td&gt;Glob 文件名&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;status/{单元}-{维度}.pass&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CHECK&lt;/td&gt;
&lt;td&gt;MASTER, DO&lt;/td&gt;
&lt;td&gt;Glob 文件名 / DO删除&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主产物&lt;/td&gt;
&lt;td&gt;DO&lt;/td&gt;
&lt;td&gt;CHECK, DO&lt;/td&gt;
&lt;td&gt;不读&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.4 角色体系&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;th&gt;引用名&lt;/th&gt;
&lt;th&gt;模型建议&lt;/th&gt;
&lt;th&gt;工具权限&lt;/th&gt;
&lt;th&gt;上下文策略&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;主调度Agent&lt;/td&gt;
&lt;td&gt;MASTER&lt;/td&gt;
&lt;td&gt;Opus&lt;/td&gt;
&lt;td&gt;Bash, Glob, Grep, Agent&lt;/td&gt;
&lt;td&gt;持久会话&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;计划Agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{PLAN}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opus/Sonnet&lt;/td&gt;
&lt;td&gt;Read, Write, Bash, Glob, Grep&lt;/td&gt;
&lt;td&gt;独立窗口，每次新建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;执行Agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{DO}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sonnet&lt;/td&gt;
&lt;td&gt;Read, Edit, Write, Bash, Glob, Grep&lt;/td&gt;
&lt;td&gt;独立窗口，同批 resume 复用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;验证Agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{CHECK}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Haiku&lt;/td&gt;
&lt;td&gt;Read, Write, Glob, Grep&lt;/td&gt;
&lt;td&gt;Phase 0新建 / Phase 2 resume&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;2.5 设计模式&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;模式&lt;/th&gt;
&lt;th&gt;应用位置&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;编排者-执行者分离&lt;/td&gt;
&lt;td&gt;MASTER vs PLAN/DO/CHECK&lt;/td&gt;
&lt;td&gt;主Agent只调不干，全权委托&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;上下文隔离&lt;/td&gt;
&lt;td&gt;绝对禁止清单&lt;/td&gt;
&lt;td&gt;主Agent不Read任何子Agent产出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;乐观批处理&lt;/td&gt;
&lt;td&gt;Phase 2 BATCH_SIZE&lt;/td&gt;
&lt;td&gt;批量开发+批量测试，减少调度轮次&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重试循环&lt;/td&gt;
&lt;td&gt;Phase 0/2 修正循环&lt;/td&gt;
&lt;td&gt;最多3轮，每轮 resume 而非新建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;检查点&lt;/td&gt;
&lt;td&gt;.done / .pass&lt;/td&gt;
&lt;td&gt;落盘标记，支撑断点续跑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;乐观并发&lt;/td&gt;
&lt;td&gt;Phase 2 CHECK修正轮&lt;/td&gt;
&lt;td&gt;已有ID后并行resume，上限由PLAN设定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;串行取号&lt;/td&gt;
&lt;td&gt;Phase 2 CHECK首轮&lt;/td&gt;
&lt;td&gt;逐个前台阻塞，防竞态&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;兜底策略&lt;/td&gt;
&lt;td&gt;Step 4 sed&lt;/td&gt;
&lt;td&gt;无DO可用时主Agent机械替换状态标记&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;3. 架构详解&lt;/h2&gt;
&lt;h3&gt;3.1 整体流程&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;INPUT_PATH
    │
    ▼
Phase 0: 计划审查（PLAN → CHECK ⇄ 修正≤3轮）
    │  ├─ PLAN: 读素材 → 出 plan.md + guide.md + 主产物骨架 + lessons.md + [PARAMS]
    │  ├─ CHECK: 审计划（任务分解/执行顺序/认知目标/格式合规/标记唯一性）
    │  └─ 修正: resume PLAN 修 plan/guide → 新建 CHECK 重审
    │
    ▼
Phase 1: 计划确认
    │  └─ MASTER 读 plan.md 状态行，使用 [PARAMS] 中的 BATCH_SIZE / 维度 / 并发上限
    │
    ▼
Phase 2: 批量开发循环（逐批）
    │  ├─ Step 1: DO(后台) → 查重→追加→写.done → MASTER Glob汇总
    │  ├─ Step 2: CHECK逐个前台(串行取ID) → 写报告+写.pass
    │  ├─ Step 3: FAIL? → resume DO修+删.pass+更新lessons → CHECK重测全批
    │  │          循环≤3轮 → 全PASS: DO改plan.md✅ / 仍FAIL: sed改⚠️
    │  └─ Step 4: 首次全PASS兜底 → sed改✅
    │
    ▼
Phase 3: 收尾统计 → log.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 中断恢复链路&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;MASTER 重启
  │
  ├─ 1. Glob status/*.done   → 哪些单元已写入主产物
  ├─ 2. Glob status/*.pass   → 哪些单元-维度已通过测试
  ├─ 3. Read plan.md 状态行  → 交叉校验
  │
  ├─ .done✅ + .pass完整  → 跳过（已完成）
  ├─ .done✅ + .pass不全  → 从缺失维度重测
  ├─ .done❌              → 从该单元重新开发
  │
  └─ DO_ID/CHECK_ID 全部失效 → 强制重启（不复用 resume）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 Agent ID 生命周期&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Step 1: 启动 DO(后台) → 等待完成 → find + 重试(2s/3s/4s) → 写入 log.md
Step 2: 启动 CHECK_1(前台) → 完成 → 取ID_1
        启动 CHECK_2(前台) → 完成 → 取ID_2
        ...
Step 3: resume DO_ID(修) → resume CHECK_ID(重测，可并发)
Step 4: resume DO_ID(改状态) 或 sed
下一批: 所有 ID 失效，重新获取
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 工程特性&lt;/h2&gt;
&lt;h3&gt;4.1 竞态保护&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;首轮CHECK逐个前台阻塞启动，完成一个取一个ID再启下一个&lt;/li&gt;
&lt;li&gt;find 使用 &lt;code&gt;-newer log.md&lt;/code&gt; 过滤其他项目历史残留&lt;/li&gt;
&lt;li&gt;find 无结果时启用3次递增间隔重试（2s/3s/4s）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2 防重复追加&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DO 追加前按 guide.md 定义的标记格式 Grep 主产物，已存在则跳过&lt;/li&gt;
&lt;li&gt;guide.md 标记格式（如 &lt;code&gt;&amp;lt;!-- UNIT_MARKER:u01 --&amp;gt;&lt;/code&gt;）由 Phase 0 作为最高优先级审查项校验&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.3 防状态污染&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Step 3 DO修正环节&lt;strong&gt;严禁修改 plan.md&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;plan.md ✅ 只在重测全部 PASS 之后才写入&lt;/li&gt;
&lt;li&gt;DO修正时删除受影响单元的 .pass 文件，确保恢复时重测&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.4 解析鲁棒性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CHECK 返回使用 &lt;code&gt;|||&lt;/code&gt; 分隔符（非逗号/换行），主Agent按分隔符切割&lt;/li&gt;
&lt;li&gt;PLAN 返回使用 &lt;code&gt;[PARAMS]&lt;/code&gt; 标记行，主Agent正则精确提取&lt;/li&gt;
&lt;li&gt;测试报告写入规定目录+规定命名（&lt;code&gt;reports/{单元}-{维度}.md&lt;/code&gt;），Grep 判定行做二次校验&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.5 上下文保护&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;主Agent永远只用 Grep/Glob/Bash，绝不用 Read 读子Agent产出&lt;/li&gt;
&lt;li&gt;后台通知只回复&quot;已确认&quot;，不复述内容&lt;/li&gt;
&lt;li&gt;Agent ID 立即写入 log，不依赖记忆&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sed&lt;/code&gt; 仅用于元数据标记替换，不加载文件进入上下文&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 性能模型&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;估算&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;主Agent单批调度开销&lt;/td&gt;
&lt;td&gt;~500-1000 tokens（路径传递+判定解析+日志写入）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CHECK 单维度测试延迟&lt;/td&gt;
&lt;td&gt;30-90s（Haiku，前台阻塞）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DO 单批开发延迟&lt;/td&gt;
&lt;td&gt;2-5min（Sonnet，后台，与单元数正比）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;修正轮额外开销&lt;/td&gt;
&lt;td&gt;DO修 ~1-2min + CHECK重测 ~30-90s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ID 获取重试上限&lt;/td&gt;
&lt;td&gt;9s（2+3+4s，3次全失败则暂停）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;中断恢复时间&lt;/td&gt;
&lt;td&gt;&amp;lt;30s（Glob扫描+.done/.pass交叉校验）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;6. 适用场景与局限&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;适用：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;复杂任务需分解为独立单元逐批开发&lt;/li&gt;
&lt;li&gt;主Agent上下文预算紧张，需要严格隔离&lt;/li&gt;
&lt;li&gt;需要N维质量验证和修正闭环&lt;/li&gt;
&lt;li&gt;运行环境不稳定，需要中断恢复&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;不适用：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单次简单任务（杀鸡用牛刀）&lt;/li&gt;
&lt;li&gt;子Agent能力边界不清晰&lt;/li&gt;
&lt;li&gt;任务间强依赖、无法批处理&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;7. 版本演进&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;版本&lt;/th&gt;
&lt;th&gt;日期&lt;/th&gt;
&lt;th&gt;核心变更&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;v1.0（通用版）&lt;/td&gt;
&lt;td&gt;2026-05-02&lt;/td&gt;
&lt;td&gt;抽离场景名词，PLAN/DO/CHECK角色槽，新增Phase 0计划审查+中断恢复，N维验证&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v1.1.0&lt;/td&gt;
&lt;td&gt;2026-05-02&lt;/td&gt;
&lt;td&gt;修复竞态/时序/解析等11项缺陷，引入.done/.pass标记文件体系，重试机制，状态更新链路优化&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;8. 已知问题&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;问题：前端生成的视觉效果不理想——说白了就是不好看。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;目前已定位到 4 个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;增量拼装与视觉设计天然冲突&lt;/strong&gt;
每个 DO 只看到自己负责的那一小块需求，从头到尾没有任何一个角色看过全貌。各自做对，拼起来不对。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CHECK 的验证维度偏机械合规&lt;/strong&gt;
当前三维度（学术规范、信息传达、视觉一致性）验的是&quot;有没有 3 条虚线&quot;&quot;中文标签是否存在&quot;&quot;颜色是不是指定色值&quot;——不是&quot;这张图放在学术论文里好不好看&quot;。一个通过全部测试的图，技术上合规，但依然可以很丑。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;缺少整体审美的验证维度&lt;/strong&gt;
学术图表真正重要的是比例、留白、层次、信息节奏。这些东西在当前体系里三处缺席：plan.md 的备注断言里没有、CHECK 的三维度里没有、guide.md 的认知目标里也没有。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;PLAN 骨架没有约束&quot;好不好看&quot;&lt;/strong&gt;
PLAN 设计了 CSS Design System（配色、字体、间距）和单元拆分，但没有定义&quot;最终组装完应该是什么样&quot;的整体蓝图。每批 DO 对着自己的验收标准做完就交差了，没人对最终视觉效果负责。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;总结：这个系统擅长&quot;做对&quot;，不擅长&quot;做好&quot;。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&quot;对&quot;是离散可测的断言，&quot;好&quot;是整体感知判断。当前 CHECK 没有审美的维度，此为根本原因&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方案待选项&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;增加Agent种类&lt;/strong&gt;
由PLAN来判断这是什么项目，前端还是后端，如果是前端就在流程中添加一个美化检查子Agent来进行修正&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修改现有子Agent&lt;/strong&gt;
CHECK的维度名就是检查方向，PLAN 在 guide.md 里定义每个维度检查什么，CHECK 照章办事&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;添加Skill&lt;/strong&gt;
前端项目给 DO 绑一个&quot;前端设计规范&quot;skill，里面写：栅格系统、配色比例、留白节奏、组件间距基准。DO 执行前三问时对照 skill 作答
后端项目给 DO 绑&quot;代码规范&quot;skill
学术图表给 CHECK 绑&quot;图表设计评审&quot;skill&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;利用lessons.md进行修正&lt;/strong&gt;
本架构里添加了lessons.md经验库，LLM会自动把项目中踩的坑或者项目经验写入lessons.md，在 DO 提示词执行前三问里加一句：&quot;读 lessons.md 后，大声说出本单元需要警惕的经验条目&quot;，强制 LLM 分配注意力&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;——THE END——&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Python-包管理工具-uv</title><link>https://kano.lzink.icu/dist/posts/uv110/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/uv110/</guid><description>第三方 Python 包管理工具讲解</description><pubDate>Wed, 29 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言——碎碎念&lt;/h1&gt;
&lt;p&gt;UV 是一个第三方 Python 包管理工具，可以替代官方的 pip。&lt;/p&gt;
&lt;p&gt;其优点是速度快、可以切换多个版本的 python、管理第三方包的虚拟环境等。更多内容可以看&lt;a href=&quot;https://docs.astral.sh/uv/#highlights&quot;&gt;官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;个人认为用起来比Conda舒服得多，速度真的快了很多&lt;/p&gt;
&lt;p&gt;要我说，uv知名度还是太低了，Ai都不认识uv，搜索引擎也不认识，不如在前面加个a : )&lt;/p&gt;
&lt;p&gt;快速复习：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装 pyproject.toml 中的依赖
uv sync
# 安装包含 dev 依赖
uv sync --dev
# 只安装生产依赖，不安装 dev 依赖
uv sync --no-dev
# 添加新依赖，会自动写入
pyproject.tomluv add requests
# 添加开发依赖
uv add --dev pytest
# 运行项目里的 Python 命令
uv run python app.py
# 运行某个工具
uv run pytest
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;安装&lt;/h1&gt;
&lt;p&gt;Windows：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;powershell -ExecutionPolicy Bypass -c &quot;irm https://github.com/astral-sh/uv/releases/download/0.9.27/uv-installer.ps1 | iex&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Linux/Mac OS：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -LsSf https://astral.sh/uv/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;uv 的运行程序安装在&lt;code&gt;C:\Users\[Your Name]\.local\bin&lt;/code&gt;，要将其添加到环境变量 path，一般来说安装时会自动添加&lt;/p&gt;
&lt;h1&gt;Python 管理&lt;/h1&gt;
&lt;p&gt;查看 uv 支持的 Python 版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv python list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会列出当前电脑安装的 Python 版本以及可以安装的 Python 版本：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以使用以下命令安装特定版本的 Python：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv python install 3.13.6
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;如果不指定版本号，将安装最新版本的 Python&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;使用uv安装的python会被安装到&lt;code&gt;.local\bin&lt;/code&gt;目录&lt;/p&gt;
&lt;p&gt;注意:不推荐用uv装Python，不会自动添加到Path里，麻烦&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-19-1024x345.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以使用&lt;code&gt;uv run&lt;/code&gt;来命令运行指定版本的 python：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; uv run -p 3.13 python   
Python 3.13.6 (main, Aug  8 2025, 17:02:53) [MSC v.1944 64 bit (AMD64)] on win32   Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接命令行运行也行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ python3.13   
Python 3.13.6 (main, Aug  8 2025, 17:02:53) [MSC v.1944 64 bit (AMD64)] on win32   Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Python脚本运行&lt;/h1&gt;
&lt;p&gt;给出一个简单的脚本，功能就是输出hello world&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;print(&apos;hello world&apos;) //脚本名:hello.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用uv run命令运行是完全可行的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv run -p .\hello.py   
hello world
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个脚本没有引用任何第三方库，自然可以正常运行&lt;/p&gt;
&lt;p&gt;现在这个脚本升级了，变成了这样&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from flask import Flask

app = Flask(__name__)

@app.route(&apos;/&apos;)
def hello_world():
    return &apos;Hello&apos;
if __name__ == &apos;__main__&apos;:
    app.run(debug = True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一个用flask写的hello world，即引用了第三方库flask&lt;/p&gt;
&lt;p&gt;直接运行肯定会报错：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; uv run .\flask.py
cannot import name &apos;Flask&apos; from partially initialized module &apos;flask&apos; (most likely due to a circular import) (D:\code\code\python\flask.py)
  File &quot;D:\code\code\python\flask.py&quot;, line 1, in &amp;lt;module&amp;gt;
    from flask import Flask
  File &quot;D:\code\code\python\flask.py&quot;, line 1, in &amp;lt;module&amp;gt;
    from flask import Flask
ImportError: cannot import name &apos;Flask&apos; from partially initialized module &apos;flask&apos; (most likely due to a circular import) (D:\code\code\python\flask.py)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为环境缺少第三方库，需要安装库后才能正常运行&lt;/p&gt;
&lt;p&gt;可以在执行 run 命令时通过参数指定脚本运行需要的第三方库，这样如果环境缺少第三方库就会安装后再执行脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ uv run --with &apos;flask&apos; .\flask.py   
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:01
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;还可以可以指定版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ uv run --with &apos;rich&amp;gt;12,&amp;lt;13&apos; .\test.py   
For example: ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:01
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一种一次性临时安装方式，不会出现依赖冲突的现象&lt;/p&gt;
&lt;p&gt;也就是说这种方式只适用于单独的脚本文件，不要对 Python 项目中的 Python 文件使用&lt;/p&gt;
&lt;h1&gt;Python依赖管理&lt;/h1&gt;
&lt;p&gt;要管理项目依赖，首先就得有个项目&lt;/p&gt;
&lt;p&gt;可以通过 uv 创建项目目录：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv init hello-world
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;如果项目目录已经存在，可以使用&lt;code&gt;uv init&lt;/code&gt;命令初始化当前目录为项目目录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;创建完成后，会出现项目目录&lt;/p&gt;
&lt;p&gt;使用 &lt;code&gt;cd .\hello-world\&lt;/code&gt;来指定该环境，输入 &lt;code&gt;ls&lt;/code&gt; 查看项目目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;cd .\hello-world\
&amp;gt;ls

      目录: D:\code\code\hello-world

Mode          LastWriteTime             Length Name
---- ------------- ------ ----
-a---- 2026/1/27 23:38 5       .python-version
-a---- 2026/1/27 23:38 89       main.py
-a---- 2026/1/27 23:38 157      pyproject.toml
-a---- 2026/1/27 23:38 0        README.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;.python-version&lt;/code&gt;这个文件记录了当前项目运行的 python 版本，这样 uv 在运行时就会以指定版本运行项目，要换版本直接修改就行&lt;/p&gt;
&lt;p&gt;有了项目框架，项目中的依赖同样可以使用 uv 进行管理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv add flask   
&amp;gt;uv add [第三方库]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;uv 会自动在项目目录下创建一个&lt;code&gt;.venv&lt;/code&gt;目录作为虚拟环境的依赖包的安装目录，并且在项目描述文件&lt;code&gt;pyproject.toml&lt;/code&gt;中添加依赖信息&lt;/p&gt;
&lt;p&gt;然后把需要运行的脚本放到hello-wrold这个环境中，直接&lt;code&gt;uv run&lt;/code&gt;运行即可，这里用上文的flask.py举例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv run flask.py
 * Serving Flask app &apos;hello&apos;
 * Debug mode: on
 * Running on http://127.0.0.1:5000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在你的项目就可以运行了&lt;/p&gt;
&lt;p&gt;如果想查看自己安装的库：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv pip list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你还想知道所有库之间的依赖关系：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv tree
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入后会打印出整个依赖树&lt;/p&gt;
&lt;p&gt;现在这个第三方库我不想用了，怎么移除依赖：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv remove flask   
&amp;gt;uv remove [第三方库]
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;安装项目/工具&lt;/h1&gt;
&lt;p&gt;在开发过程中，我们会使用很多的工具&lt;/p&gt;
&lt;p&gt;如上文使用的Flask网站框架，或是代码检查工具ruff，本文学习的uv也是一种包管理和环境管理工具&lt;/p&gt;
&lt;p&gt;要想使用工具，我们可以直接把工具像依赖一样安装&lt;/p&gt;
&lt;p&gt;添加ruff工具:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv add ruff --dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入后就能直接使用工具了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv run ruff check   
All checks passed!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;--dev的作用是防止打包的时候把ruff一起打包进来，只在开发中使用，打包下文会讲&lt;/p&gt;
&lt;p&gt;因为ruff是一种工具，不推荐直接依赖安装，--dev里应该装和代码有关的，这是笔者的个人习惯，直接放--dev里也没错&lt;/p&gt;
&lt;p&gt;第二种方法就是用uv tool，可以安装、更新项目，其用途类似于 pip&lt;/p&gt;
&lt;p&gt;比如安装已发布的项目：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv tool install ruff  
&amp;gt;uv tool install [已发布项目]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更新已安装的项目：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv tool upgrade ruff //更新ruff   
&amp;gt;uv tool upgrade --all //更新所有通过 uv 安装的项目
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看已经安装的项目:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;uv tool list   
ruff v0.14.14   
- ruff
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用&lt;code&gt;uv tool install&lt;/code&gt;安装的项目在当前用户下是全局可用的，并不会局限于某个环境&lt;/p&gt;
&lt;p&gt;uv会自动为每个项目都创建虚拟环境，换言之通过这种方式安装的包之间是互相隔离的，不需要担心库之间的冲突&lt;/p&gt;
&lt;p&gt;因为工具不依赖于任何特定的 Python 环境，所以说也就不能直接&lt;code&gt;import ruff&lt;/code&gt;导入，想要导入就用&lt;code&gt;pip install&lt;/code&gt;或者&lt;code&gt;uv add&lt;/code&gt;安装&lt;/p&gt;
&lt;p&gt;uv还有个很好用的特色命令uvx：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 临时运行某个工具，无需事先安装
uvx ruff --help

# 指定版本
uvx ruff@0.1.0 --help

# 运行任意脚本
uvx --from https://example.com/script.py

# 运行 GitHub 上的脚本
uvx --from github:astral-sh/ruff
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Python项目打包&lt;/h1&gt;
&lt;p&gt;使用 &lt;code&gt;uv build&lt;/code&gt;命令可以创建（打包） python 项目的二进制发行版本（&lt;code&gt;.whl&lt;/code&gt;文件）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ uv build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成的文件保存在&lt;code&gt;dist&lt;/code&gt;目录下&lt;/p&gt;
&lt;p&gt;然后就可以&lt;code&gt;uv add&lt;/code&gt;或者&lt;code&gt;uv tool install&lt;/code&gt;安装了&lt;/p&gt;
&lt;h1&gt;Python项目打包——拓展&lt;/h1&gt;
&lt;p&gt;在打包之前，可以打开pyproject.toml这个文件，添加：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[project.scripts]
hello = &quot;hello2:main&quot; 
//[命令名] = &quot;[包名]:[函数名]&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;在Python中，&quot;包名&quot;指的是Python包的名称。一个Python包是一个包含&lt;code&gt;__init__.py&lt;/code&gt;文件的目录，该目录下可以有多个模块（.py文件）和子包&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当你在命令行中输入命令名（hello）时&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;1.找到&lt;code&gt;hello2&lt;/code&gt;这个 Python 包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2.找到其中的 &lt;code&gt;main&lt;/code&gt; 模块&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;3.调用其中的 &lt;code&gt;main()&lt;/code&gt; 函数&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如&lt;code&gt;main&lt;/code&gt;函数里就一个&lt;code&gt;print（&apos;hello-world&apos;）&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;hello
hello-world
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>小说——星辰之前，学校之后</title><link>https://kano.lzink.icu/dist/posts/2026-04-23-%E5%B0%8F%E8%AF%B4-%E6%98%9F%E8%BE%B0%E4%B9%8B%E5%89%8D%E5%AD%A6%E6%A0%A1%E4%B9%8B%E5%90%8E/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2026-04-23-%E5%B0%8F%E8%AF%B4-%E6%98%9F%E8%BE%B0%E4%B9%8B%E5%89%8D%E5%AD%A6%E6%A0%A1%E4%B9%8B%E5%90%8E/</guid><description>我能看见所有人的未来，唯独看不见自己的罪</description><pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;01.归途与旧页&lt;/h2&gt;
&lt;p&gt;永寂星尘号航行的时候，几乎没有声音&lt;/p&gt;
&lt;p&gt;只有引擎深处极轻的低鸣，像一页时间在缓慢翻动&lt;/p&gt;
&lt;p&gt;卡诺结束了当天最后一项校准，把航线提交给舰载系统，关掉主控台上层层叠叠的光。舱室于是一下子暗下来，唯独那片遥远星云仍旧亮着，像熄不掉的旧梦&lt;/p&gt;
&lt;p&gt;永寂星尘的夜总是来得很快。或者说，在深空里根本没有夜，只有光抵达得太慢，以至于看上去像黑暗&lt;/p&gt;
&lt;p&gt;她本该回休息舱，她已经连续工作了十四个小时。明早还有一次例行检修，下午要经过一处碎陨带，晚上则要和一支补给舰队进行短距通讯。她的生活一向精确、稳定、几乎没有误差，像她亲手维护的这些仪器&lt;/p&gt;
&lt;p&gt;但她只是坐着，望了那团星云很久。久到主控台下层储物柜的自动锁在静默里发出一声极轻的回弹音，像在提醒她：里面还有一样她很久没有碰过的东西&lt;/p&gt;
&lt;p&gt;卡诺低下头，拉开储物柜&lt;/p&gt;
&lt;p&gt;最里面压着一本很旧的记录册&lt;/p&gt;
&lt;p&gt;它和永寂星尘上的一切都不相称，封皮是深灰色的，边角磨得起毛，脊背上有一道很多年前留下的划痕，像曾经被谁匆忙摔到地上，又在后来被捡起，若无其事地放回原处。册页比标准航行日志小一圈，纸张也不够平整，有些地方甚至被反复翻阅得发软&lt;/p&gt;
&lt;p&gt;那不是标准航行日志&lt;/p&gt;
&lt;p&gt;更早的时候，它只是一本普通的笔记本；再后来，它被她拿来记梦、记日期、记那些比现实先一步抵达她眼前的碎片；又过了很多年，它开始像一份迟来的供词&lt;/p&gt;
&lt;p&gt;她把它取出来，放到膝上&lt;/p&gt;
&lt;p&gt;册页一翻开，便有一张旧纸从里面滑落，轻轻掉在脚边&lt;/p&gt;
&lt;p&gt;卡诺弯腰拾起那张纸。纸面已经发黄，边缘微卷，上面的字迹因为时间太久而有些发淡，但仍能辨认出来。那是少年时的她用黑色钢笔写下的一句话，字不算漂亮，落笔却很稳，像明明在发抖，却强迫自己不要显露出来&lt;/p&gt;
&lt;p&gt;——&lt;strong&gt;预言不是用来改变未来的，是用来理解现在的，如果你试图改变未来的每一秒，你就会被预言的重量压碎&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;她看着那句话，许久没有动&lt;/p&gt;
&lt;p&gt;主舱里安静得只能听见空气循环系统规律的低鸣。舷窗外，一颗迟到太久的光点终于穿过漫长距离，落进玻璃表面，又很快随着舰体的角度偏移，悄无声息地滑走&lt;/p&gt;
&lt;p&gt;卡诺忽然想起，自己第一次真正意识到“预言”这回事的时候，才七岁&lt;/p&gt;
&lt;h2&gt;02.七岁那年的预兆&lt;/h2&gt;
&lt;p&gt;那年夏天很热。&lt;/p&gt;
&lt;p&gt;她住的地方离城中心很远，窗外没有太多能让人记住的景色，只有一条狭窄的街道，一家卖旧家电的小店，一棵总在掉叶子的树，还有楼下那户人家一年到头都晾不干的衣服。卡诺对童年的很多东西都记得不算清楚，譬如某些人的脸、一些已经搬走的邻居、还有父亲离开时到底有没有回头，但她记得那只杯子&lt;/p&gt;
&lt;p&gt;那是一只很普通的玻璃杯，透明的，杯口有一圈细小的磨损，原本放在窗台边，盛着半杯早晨剩下的凉水&lt;/p&gt;
&lt;p&gt;她那时正趴在客厅地板上写字&lt;/p&gt;
&lt;p&gt;窗开着，夏天的风从防盗栏的缝隙里挤进来，把桌上的作业纸吹得一角一角卷起。屋子里有一股晒过头的棉布味，厨房还留着午饭后没有散尽的热气。电视没开，家里安静得近乎空荡。母亲在卧室里睡午觉，邻居家的收音机隐隐约约响着，不知道是哪一台，音质很差，像隔着很远的水面传来&lt;/p&gt;
&lt;p&gt;卡诺低头写着一个字，笔尖刚落下去，耳边却先一步听见了一声极轻的脆响&lt;/p&gt;
&lt;p&gt;很清，很短&lt;/p&gt;
&lt;p&gt;像什么薄而硬的东西，已经碎了&lt;/p&gt;
&lt;p&gt;她抬起头&lt;/p&gt;
&lt;p&gt;那只玻璃杯还好好地放在窗台上，阳光照过去，杯壁上映出一圈细小的亮斑，静得像什么都没有发生&lt;/p&gt;
&lt;p&gt;卡诺愣了一下&lt;/p&gt;
&lt;p&gt;她甚至来不及想那声音是从哪里来的，就看见风又往屋里灌了一阵，吹动了窗边那块搭着的旧布。旧布的一角扫过杯底，杯子极轻地晃了一下，向外滑了半寸&lt;/p&gt;
&lt;p&gt;然后，第二声响起了&lt;/p&gt;
&lt;p&gt;这一次不是在她耳边，而是在现实里&lt;/p&gt;
&lt;p&gt;杯子坠下去，在地砖上摔成四分五裂，凉水沿着缝隙漫开，像一小块忽然长出来的、透明的地图&lt;/p&gt;
&lt;p&gt;卡诺手里的笔掉在了地上&lt;/p&gt;
&lt;p&gt;卧室门很快被拉开，母亲皱着眉走出来，先看见满地碎玻璃，又看见坐在原地一动不动的女儿&lt;/p&gt;
&lt;p&gt;“怎么回事？”&lt;/p&gt;
&lt;p&gt;卡诺张了张嘴，却没有发出声音&lt;/p&gt;
&lt;p&gt;她不知道该怎么说。她不能说自己先听见了那声碎裂。不能说在杯子真正落地之前，她已经知道它会碎。七岁的孩子会说很多奇怪的话，可大多数时候，大人只会把它们当成胡思乱想、做梦、发呆、或者为了逃避责任编出来的借口&lt;/p&gt;
&lt;p&gt;于是她只是低下头，看着自己膝盖旁那摊慢慢扩散开的水&lt;/p&gt;
&lt;p&gt;母亲叹了口气，以为是她碰倒了杯子，没有再追问，只让她别乱动，自己去拿扫帚和抹布。塑料扫帚刮过地砖的时候发出单调的声响，把碎玻璃一片一片聚到一起。阳光照在那些碎片上，亮得有些刺眼。卡诺忽然觉得喉咙发干，心口一阵一阵发紧，好像有什么东西正沿着脊背往上爬，却又说不清那究竟是什么&lt;/p&gt;
&lt;p&gt;那天傍晚，楼下卖旧家电的小店关门比平时早。店主推着卷帘门的时候，卡诺站在阳台上，忽然看见他身后晃过一个画面——不是眼前这个夏天的黄昏，而是某个灰白色的雨天，男人蹲在一间医院外的台阶上，头埋得很低，肩膀一下一下地抖&lt;/p&gt;
&lt;p&gt;那画面只持续了一瞬，短得像眨眼时进了沙&lt;/p&gt;
&lt;p&gt;卡诺下意识往前迈了一步，额头撞在防盗栏上，疼得她“嘶”了一声。再抬眼时，小店老板已经锁好门，像往常一样推着自行车走了。街道还是那条街道，树影还是那样斜，傍晚的天色甚至很温和，完全看不出任何不祥&lt;/p&gt;
&lt;p&gt;她站在那儿，盯着那扇空下来的店门，很久&lt;/p&gt;
&lt;p&gt;后来的某一天，那家店真的关了。不是临时歇业，而是彻底停掉。再后来，母亲和邻居聊天时提起，说老板的妻子病得很重，他那段时间天天往医院跑，整个人像老了十岁&lt;/p&gt;
&lt;p&gt;卡诺没问老板是什么病&lt;/p&gt;
&lt;p&gt;她已经知道了&lt;/p&gt;
&lt;p&gt;卡诺那时候已经学会不再追问这些巧合&lt;/p&gt;
&lt;p&gt;因为那不是巧合&lt;/p&gt;
&lt;p&gt;那个夏天以后，她开始不断地提前听见一些声音，看见一些还没有发生的画面。它们总是来得很突然，毫无预兆，像有一道极细的裂缝藏在世界表面，只有她会在某些时刻从那里面看到一点漏出来的东西&lt;/p&gt;
&lt;p&gt;有时是一句争吵，等到第二天果然在楼道里原封不动地响起；有时是老师转身时落在窗台上的一片粉笔灰，几周后，那位老师真的请假离开，再也没回来；有时是雨夜街角一辆翻倒的自行车，卡诺在看见它时甚至不知道骑车的人是谁，直到三天后班里一个男生手臂缠着绷带回来，抱怨自己在转弯时摔得多惨&lt;/p&gt;
&lt;p&gt;她开始偷偷记日期&lt;/p&gt;
&lt;p&gt;起先是记在作业本的背面，后来怕被人发现，又换成零散的小纸片。纸片夹在课本里，藏在抽屉最深处，或者塞进枕套下面。她把看见的、听见的、梦到的东西一条条写下来，尽量写得平静，像在替什么尚未抵达的东西提前备案&lt;/p&gt;
&lt;p&gt;可那些字越写越多，卡诺心里那种说不出的寒意也越积越深&lt;/p&gt;
&lt;p&gt;因为她很快发现，自己看见的并不总是坏事。有人会在考试里超常发挥，有人会在冬天收到期待已久的信，有人会在很久以后变得比现在更快乐。未来本身并不偏爱灾祸。真正让她感到恐惧的，是它们总会准时抵达，而她无从解释，也无处逃避&lt;/p&gt;
&lt;p&gt;她试过把自己的名字写在纸上&lt;/p&gt;
&lt;p&gt;试过对着镜子闭上眼，再慢慢睁开，试图看见几年后的自己&lt;/p&gt;
&lt;p&gt;试过把手指浸进洗脸盆的水里，盯着晃动的水面看上很久很久，直到眼睛发酸&lt;/p&gt;
&lt;p&gt;可每一次，留给她的都只有空白&lt;/p&gt;
&lt;p&gt;别人会有模糊的画面，有声音，有日期，有一闪而过的姿态，只有她自己，像是从未来里被人为地剪掉了。镜子里没有答案，水面里没有倒影，梦也拒绝把她带去任何更远的地方。仿佛所有人的命运都有去处，唯独她没有。&lt;/p&gt;
&lt;p&gt;那段时间，卡诺常常在半夜突然醒来&lt;/p&gt;
&lt;p&gt;窗外黑得很深，楼道里的感应灯偶尔亮一下，又迅速灭掉。她坐在床上，心脏跳得很快，觉得自己像站在一条没有尽头的走廊里，能透过每一扇门缝看见别人房间里的灯，却唯独找不到自己的那一扇门&lt;/p&gt;
&lt;p&gt;第二天一早，她照旧去上学，照旧把作业放上讲台，照旧在体育课上因为个子太小被排到队伍最前面，照旧在放学时跟着人群走出校门。她没有对任何人提起那些纸片、那些画面、那些先一步到来的声音。她很早就明白，人一旦说出不该被理解的话，就会立刻从“奇怪”掉进“麻烦”&lt;/p&gt;
&lt;p&gt;而她不想成为麻烦&lt;/p&gt;
&lt;p&gt;所以她学会了沉默&lt;/p&gt;
&lt;p&gt;很多年以后，卡诺独自坐在星舰主舱里，回想起那段时光，依然能清楚地记起那个七岁夏天的下午：地砖上的水、玻璃碎片的反光、母亲拿着扫帚时微微皱起的眉、还有自己垂下眼睛时嘴唇上那一点被咬出的白色&lt;/p&gt;
&lt;p&gt;她那时当然还不知道，预言会把她带去多远的地方，带去怎样的城市、怎样的航路、怎样的深空。她更不知道，许多年后，会有一个人穿过再普通不过的一所学校，站到她面前，让她第一次因为“看见未来”而感到真正的恐惧&lt;/p&gt;
&lt;p&gt;她只知道，从那只杯子开始，有些事情已经和别人不一样了&lt;/p&gt;
&lt;p&gt;主舱的待机灯在夜色里轻轻闪了一下&lt;/p&gt;
&lt;p&gt;卡诺合上眼，又把那本旧册子翻过一页。纸张摩擦时发出很轻的沙沙声，像旧日正在极远的地方缓慢逼近。&lt;/p&gt;
&lt;p&gt;下一页最上方，是另一行更晚些时候写下的字：&lt;/p&gt;
&lt;p&gt;——&lt;strong&gt;—后来我进入了一所很普通的学校&lt;/strong&gt;，&lt;strong&gt;一切的故事都是从那开始的&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;03.一所很普通的学校&lt;/h2&gt;
&lt;p&gt;后来卡诺进入了一所很普通的学校&lt;/p&gt;
&lt;p&gt;很多年以后，我仍然觉得，“普通”是一个近乎无懈可击的词。它像一层薄薄的白漆，均匀地刷过所有裂缝。只要墙面看上去还算干净，谁也不会去追问里面是不是已经返潮、发霉，或者正在一点点空下去。人们提起那所学校时，总是用很平静的语气，说它纪律不错，师资稳定，升学率也好，操场够大，宿舍不算旧，老师大多负责，学生也没有传闻里那么难管&lt;/p&gt;
&lt;p&gt;它的确没有什么特别的&lt;/p&gt;
&lt;p&gt;校门是银白色的铁栏，夏天会被太阳晒得发烫；教学楼刷着浅灰色的漆，雨天一到，墙角总有一股洗不净的潮气；走廊尽头那扇窗常年关不严，一到傍晚就会被风吹得轻轻作响。早读、上课、午休、考试、排名、家长会、国旗下讲话，所有东西都按部就班，整齐得像一张排得过分工整的课表&lt;/p&gt;
&lt;p&gt;卡诺第一次站在校门口的时候，天很亮&lt;/p&gt;
&lt;p&gt;那天是初秋，太阳悬得很高，亮得有些空。新生都在礼堂前集合，广播里不断重复年级分班和班主任名字。有人拖着行李箱，有人拎着一大袋新领的校服和练习册，家长站在树荫底下交代最后几句，神情里带着一种近乎一致的期望，好像只要孩子跨进这道门，往后的很多年就都该自然而然地朝着某个正确方向流去&lt;/p&gt;
&lt;p&gt;她背着书包站在人群里，突然听见了几句不属于当天的声音&lt;/p&gt;
&lt;p&gt;不是有人真的在她耳边说话，而是那种熟悉的、极轻的回响。像风经过很长很长的管道，带回来一点别处的残音&lt;/p&gt;
&lt;p&gt;有人会在冬天请长假&lt;br /&gt;
有人会在下一次月考后第一次失眠&lt;br /&gt;
有人会在三年后毕业照那天笑得很好看，之后很多年都再也没有那样笑过&lt;br /&gt;
还有人，会一点点活成所有人都放心的样子，然后在某一天，连自己都认不出自己&lt;/p&gt;
&lt;p&gt;那些念头擦过去的时候，卡诺只是微微低了下头，像怕别人看见她在走神&lt;/p&gt;
&lt;p&gt;她已经很懂得把异样藏起来了&lt;/p&gt;
&lt;p&gt;卡诺在开学第三周就记住了所有人的座位。&lt;/p&gt;
&lt;p&gt;不是刻意去记，只是因为那些画面总是在她毫无防备的时候涌上来。比如前排靠窗那个扎低马尾的女生，发梢扫过作业本，卡诺脑海里便忽然闪过同一个女生两年后站在另一座城市陌生的阳台上，手指夹着烟，整个人单薄得像一张被风吹皱的纸。又比如斜后方那个总是第一个举手答问的男生，卡诺看见他未来某一天坐在空荡荡的办公室里，电脑屏幕亮着，光标停了很久，而他只是盯着桌角半杯凉掉的咖啡，表情空白。&lt;/p&gt;
&lt;p&gt;她把这些都写进那本灰皮册子里。字迹很淡，像怕被人看见，也像怕惊动什么。&lt;/p&gt;
&lt;p&gt;册子里渐渐记录下各种各样的碎片：有人在三年后的某个黄昏蹲在洗衣房里哭，有人会收到一封写了很久很久的信却再也没有回音，有人会在毕业典礼那天缺席，缺席的原因永远不会被写在班级日志上，只会变成老师们私下谈起时一声很轻的叹息。她把日期记在旁边，有些已经对上了，有些还在远处等着她。&lt;/p&gt;
&lt;p&gt;这本该只属于她一个人。卡诺也一直这样以为。&lt;/p&gt;
&lt;p&gt;直到有一天体育课，她请了假，坐在操场边老旧的水泥看台上，膝头摊着那本册子。阳光把水泥地晒得发白，跑道上的脚步声很吵，有人在喊传球，有人在笑。她低头写字，铅笔划过纸面的声音细得像虫子爬。&lt;/p&gt;
&lt;p&gt;“你在记什么？”一个声音忽然从身后传来。&lt;/p&gt;
&lt;p&gt;卡诺几乎是条件反射地合上册子，抬头时手心已经微微出汗。那个叫林栖的男生正站在她侧后方，一只手插在运动服口袋里，另一只手拎着自己的水壶，脸上没有好奇过度的表情，只是很平常地看着她，像在问现在是几点。&lt;/p&gt;
&lt;p&gt;“没什么，”卡诺说，声音比自己预想中更轻，“就随便写点东西。”&lt;/p&gt;
&lt;p&gt;林栖没有追问。这本身就让卡诺有些意外。&lt;/p&gt;
&lt;p&gt;他在她旁边隔了一个位置坐下，拧开水壶盖子喝了一口，然后望着操场，像刚才那个问题只是随口一提。远处跑道上有人起跑慢了，被同伴回头喊了一声，笑声顺着风滚过来，又很快被另一阵哨声盖过去。阳光把林栖的头发照出很浅的棕色边缘，他整个人看起来安静，像一潭不会被风掀起褶皱的水。&lt;/p&gt;
&lt;p&gt;卡诺的手指还压在册子封面上。&lt;/p&gt;
&lt;p&gt;她知道林栖是谁。同班，成绩偏上但不是最显眼的那一批，在走廊里从不和人大声说话，作业交得很准时，名字有时会被老师忘记。她不是第一次注意到他；但这却是头一回，她没有在他身上看见任何画面。&lt;/p&gt;
&lt;p&gt;什么都没有。&lt;/p&gt;
&lt;p&gt;卡诺忍不住又看了他一眼。林栖感觉到她的目光，转过头来，微微挑了下眉。&lt;/p&gt;
&lt;p&gt;“你头发上沾了片叶子。”卡诺说。&lt;/p&gt;
&lt;p&gt;林栖伸手在头发上摸了一下，果然取下一小片不知什么时候落上的枯叶。他低头看了看，把它放在看台上，朝她笑了一下，说：“刚才去器材室搬垫子，大概是那时候掉的。”&lt;/p&gt;
&lt;p&gt;那笑容很短，却意外地干净。&lt;/p&gt;
&lt;p&gt;卡诺垂下眼睛，没有再接话。&lt;/p&gt;
&lt;h2&gt;04.注视与空白&lt;/h2&gt;
&lt;p&gt;此后几周，她开始不由自主地在走廊里、食堂里、上课铃响前嘈杂的教室里，注意到林栖的存在。他从最后一排靠窗的位置望出去的时候，眼神里有种很淡的空，像人没有在想任何具体的事，只是在等时间过去。他写字很慢，每一次翻页都不急不躁，好像很珍惜每一张纸。他帮忙发作业本时从不像其他人那样把本子往桌上一扔，而是会轻轻放下来，封面朝上。&lt;/p&gt;
&lt;p&gt;卡诺渐渐养成一个习惯：在没有预言可记的时候，她会随手写一些观察。林栖是唯一一个她可以反复翻看记录、却完全无法在字里行间找到“未来痕迹”的人。&lt;/p&gt;
&lt;p&gt;这让她既安心，又隐隐警觉。&lt;/p&gt;
&lt;p&gt;她太清楚自己的脆弱了。一旦被人理解，就依赖得很深。而林栖的存在，像一片没有预报的平静天气，她甚至不知道那平静底下究竟是什么。&lt;/p&gt;
&lt;p&gt;转折发生在深秋的一个傍晚。&lt;/p&gt;
&lt;p&gt;那天下了很大的雨，从下午第四节课一直下到晚自习结束。教学楼门厅堵满了没带伞的学生，地面被踩得全是水印，空气里飘着湿透的校服味道和一阵阵不耐的说话声。卡诺站在侧面走廊的尽头，背靠着墙，看着雨幕外面模糊的路灯，等雨小一些再走。&lt;/p&gt;
&lt;p&gt;她听见脚步声，很轻，很稳，不紧不慢地沿着走廊过来。&lt;/p&gt;
&lt;p&gt;林栖走到她旁边停下来，手里的伞在往下滴水。他看了看外面的雨，又看了看她。&lt;/p&gt;
&lt;p&gt;“你也没带伞？”他问。&lt;/p&gt;
&lt;p&gt;“带了。”卡诺说，“只是不喜欢挤。”&lt;/p&gt;
&lt;p&gt;林栖“嗯”了一声，没有走，反而把伞靠在墙边，自己也靠在墙上，和她并排站着。两个人之间隔了半臂的距离，刚好够让沉默不显得逼仄。走廊里的人声渐渐散去了，雨声大起来，把远处一切细碎的声音都吞掉。&lt;/p&gt;
&lt;p&gt;“其实，”林栖忽然开口，声音很平，“我早就注意到了。”&lt;/p&gt;
&lt;p&gt;卡诺没说话。&lt;/p&gt;
&lt;p&gt;“注意你总在记东西，”他说，目光没有看她，而是看着走廊尽头那扇被风吹得微微开合的气窗，“不像是做笔记，更像是怕忘了。”&lt;/p&gt;
&lt;p&gt;风夹着雨味从窗缝里灌进来，把走廊里最后半盏日光灯吹得闪了一下。卡诺握在口袋里的手指微微收紧。&lt;/p&gt;
&lt;p&gt;“而且，”林栖顿了一下，好像在琢磨措辞，然后极轻地说，“你好像总会提前知道一些事。”&lt;/p&gt;
&lt;p&gt;这句话落下来的时候，没有砸出任何声响。&lt;/p&gt;
&lt;p&gt;他没有用“预言”两个字。没有用“奇怪”。没有问“你是不是不正常”。他只是说“提前知道”，像在描述一种很自然的、可以被理解的、也许只是比别人敏锐一些的能力。&lt;/p&gt;
&lt;p&gt;卡诺偏过头看他。林栖还是望着那扇气窗，侧脸在暗光里很安静，表情里没有任何窥探或猎奇。&lt;/p&gt;
&lt;p&gt;“你为什么会这么想？”她问。&lt;/p&gt;
&lt;p&gt;林栖想了一会儿，从口袋里掏出一张折成小方块的纸，递给她。&lt;/p&gt;
&lt;p&gt;卡诺展开那张纸。纸已经被折痕磨得有些软，上面的字迹是她的——那是大约两周前她夹在课堂笔记本里的一张预言记录，写得很潦草，只记了一句：“明天下午第二节课，物理老师会在黑板上写错一个公式，然后自己愣了一下，笑着说这个错犯得太蠢了。”她在课间整理笔记时大概不小心把它掉在了地上。&lt;/p&gt;
&lt;p&gt;她抬起头，林栖正看着她，目光安静。&lt;/p&gt;
&lt;p&gt;“你掉了的那天，我捡到的，”他说，“本来想还给你，凑巧看见了。我没多想，就放回了你桌上。然后第二天——”&lt;/p&gt;
&lt;p&gt;“第二天物理课，他就真的写错了。”卡诺接过话头，语气很淡。&lt;/p&gt;
&lt;p&gt;林栖点了点头。&lt;/p&gt;
&lt;p&gt;雨声忽然变大了，像是天上又倾下了一层更厚的雨幕。走廊里的灯闪了第二下，终于彻底灭了，把两个人罩在从气窗透进来的微光里。空气的味道湿得发甜。&lt;/p&gt;
&lt;p&gt;“你信吗？”卡诺问。&lt;/p&gt;
&lt;p&gt;“信什么？”&lt;/p&gt;
&lt;p&gt;“信我不是在发疯。”&lt;/p&gt;
&lt;p&gt;林栖转过头来，在昏暗中看着她。那双眼睛的颜色很浅，此刻被雨光映得微亮，像有人在水底点了一盏很小的灯。&lt;/p&gt;
&lt;p&gt;“我不知道该信什么，”他说，“但我知道你没在胡说。你写的字很认真，还标注了时间。人只有对真事才会这么仔细。”&lt;/p&gt;
&lt;p&gt;卡诺感到喉咙口有什么堵了一下。她低下头，把那张纸重新折好，握在手心里。折痕已经太深，纸张几乎要从折叠处断开。&lt;/p&gt;
&lt;p&gt;“你说你早就注意到了，”她终于开口，声音压得很低，“那你注意到什么？”&lt;/p&gt;
&lt;p&gt;林栖想了想，说：“很多。你比别人谨慎，从不轻易发表意见；别人在讲未来的计划时你总是不参与；有几次你提前移开桌上的水杯，几秒后就有人路过碰倒了桌子。别人没发现，我刚好看到了。”&lt;/p&gt;
&lt;p&gt;“你不觉得可怕吗？”&lt;/p&gt;
&lt;p&gt;“什么可怕？”&lt;/p&gt;
&lt;p&gt;“我。”卡诺说。&lt;/p&gt;
&lt;p&gt;林栖沉默了一会儿。然后他拿起靠在墙边的伞，往她那边偏了偏伞面，尽管他们还在屋檐下。&lt;/p&gt;
&lt;p&gt;“可怕的人不会把自己藏得这么深，”他说，“也不会在体育课一个人坐在看台上，看别人跑步看到出神。”&lt;/p&gt;
&lt;p&gt;卡诺张了张嘴，什么也没说出来。雨水顺着屋檐落下来，在地上溅成细细的水雾，沾湿了她的鞋尖。她忽然觉得这整个傍晚都变得不像真的——那些她藏了很多年的东西，那些她以为自己永远不会对任何人说的话，就这样被一个安静的同龄人，用最平常的语气，一句一句说了出来。&lt;/p&gt;
&lt;p&gt;“你问过自己吗？”林栖的声音更低了，低到几乎像是说给自己听，“你看见的那些事，后来都发生了吧？”&lt;/p&gt;
&lt;p&gt;“都发生了。”卡诺说。&lt;/p&gt;
&lt;p&gt;“那你能看见自己的吗？”&lt;/p&gt;
&lt;p&gt;这一问问得太准。&lt;/p&gt;
&lt;p&gt;卡诺抬起头，雨光从侧面打在她脸上，把她眼里的某种东西照得无处可藏。林栖看到那个眼神，愣了一下。&lt;/p&gt;
&lt;p&gt;“不能，”她说，声音很轻，像一片终于落地的枯叶，“从来不能。”&lt;/p&gt;
&lt;p&gt;林栖没有再问。他只是把伞往她那边又挪了一寸，虽然那一寸没有任何实际意义。&lt;/p&gt;
&lt;p&gt;走廊外面，雨渐渐小了。远处教学楼二楼的灯一盏一盏亮起来，发出低沉的电流声。门厅里最后一个等待的人撑开伞，踩着一地积水离开。整个世界只剩下雨声、风声、和两个人之间忽然变轻的沉默。&lt;/p&gt;
&lt;p&gt;后来，卡诺把那晚记进了她的灰皮册子里。她写道：“我终于遇到一个人，他看见了我，却没有叫我怪物。他问我是否知道自己的未来，我回答不能，他的眼神就像被雨淋了一下。那一刻我想，也许这个人是可以信任的。”&lt;/p&gt;
&lt;p&gt;在这段话的下面，她又加了一小行字，墨迹压得特别轻：“可我后来也懂了，信任不是祝福。信任是把钥匙，一旦给了人，他就能走进你最不该让他走进的房间。”&lt;/p&gt;
&lt;p&gt;那时她还不知道，这把钥匙会打开怎样的门。&lt;/p&gt;
&lt;p&gt;那天之后，她和林栖开始走得近了一些。&lt;/p&gt;
&lt;p&gt;不是那种刻意结伴式的走近。他们没有约好一起上学、一起吃饭、一起去图书馆，只是在上课的时候偶尔会心照不宣地对视一眼，在午休的时候碰巧坐到同一张长桌的两端，在晚自习结束后一起走那段从教学楼到校门的路。&lt;/p&gt;
&lt;p&gt;林栖话不多，但他的沉默不是空洞，像是一间点了灯的空屋子，你知道里面有人。卡诺和他并肩走的时候，不需要费力填补空白，说出来的话也不会在半途被误解或打断。他会想很久，然后说一句很短的话，而那句话往往是她在别人那里听不到的。&lt;/p&gt;
&lt;p&gt;有一次他们在图书馆过期刊物室整理旧报纸，外面又下着雨。林栖把一摞发黄的报纸码齐，忽然问：“你最早看到的，是什么？”&lt;/p&gt;
&lt;p&gt;他没用“预言”这个词。&lt;/p&gt;
&lt;p&gt;卡诺捻着手里一张报纸的边角，那上面印着三年前某次学科竞赛的获奖名单，好多名字她都不认识。她说：“一只杯子。摔碎之前我就听见了声音。”&lt;/p&gt;
&lt;p&gt;林栖把下一摞报纸放下来，看着她。&lt;/p&gt;
&lt;p&gt;“那后来呢？”&lt;/p&gt;
&lt;p&gt;“后来就越来越多，也越来越清楚。有时候是一个画面，有时候只是一句话，有时候是梦。”她把那张旧报纸折好，接着说，“我都记下来了。日期，画面，多久以后发生。”&lt;/p&gt;
&lt;p&gt;“准吗？”&lt;/p&gt;
&lt;p&gt;“每次都准。”她顿了顿，“除了我自己。”&lt;/p&gt;
&lt;p&gt;林栖没有马上说话。他把最后一摞报纸码好，整齐地放进档案架，拍了拍手上的灰，然后在窗边那把吱嘎作响的木椅上坐下来，椅子发出一声很长的呻吟，像被压疼了。&lt;/p&gt;
&lt;p&gt;“那你能不能看见我的？”他问。不是试探，而是坦然地、安静地邀请。&lt;/p&gt;
&lt;p&gt;卡诺在那一瞬间抬起眼睛看了他很久。窗外的雨把光线打湿，落在他的肩头和颈侧，他坐在那里，像一幅没有画完的画，所有关键的笔触都被刻意留了白。&lt;/p&gt;
&lt;p&gt;“看不见，”她终于说，声音像从很深的井里提上来的水，一圈一圈荡开，“什么都看不见。”&lt;/p&gt;
&lt;p&gt;林栖的表情没有变，但他放在膝盖上的手指极轻地动了一下，像在按一个暂停键。&lt;/p&gt;
&lt;p&gt;“那是什么意思？”他问。&lt;/p&gt;
&lt;p&gt;“我也不知道，”卡诺垂下眼，“在别人那里，我至少能看见碎片。但在你这里——什么都没有。”&lt;/p&gt;
&lt;p&gt;这个事实说出来之后，两个人同时沉默了。不是尴尬的沉默，而是两个人都意识到，这或许是某种重要的东西，只是暂时还说不清。&lt;/p&gt;
&lt;p&gt;过了很久，林栖站起身，走到窗边，望着雨里模糊的操场。操场上塑胶跑道被泡成了深深的砖红色，旗杆孤零零地竖在那里，旗子在雨里湿透了，贴在上面一动不动。&lt;/p&gt;
&lt;p&gt;“那你在我面前，大概会比较轻松吧。”他说。&lt;/p&gt;
&lt;p&gt;卡诺抬起头看他。&lt;/p&gt;
&lt;p&gt;她把视线从他脸上移开，落在窗外被雨水模糊的操场上。旗杆孤零零地竖在那里，湿透的旗子黏在杆子上，纹丝不动。图书馆里只剩下翻报纸的沙沙声和管理员在远处整理书脊的闷响。&lt;/p&gt;
&lt;p&gt;“轻松？”她终于开口，声音很轻，“大概吧。至少不用提前知道你什么时候会走。”&lt;/p&gt;
&lt;p&gt;林栖看了她一眼。&lt;/p&gt;
&lt;p&gt;“那你挺亏的。”他说。&lt;/p&gt;
&lt;p&gt;卡诺一愣：“亏什么？”&lt;/p&gt;
&lt;p&gt;“你能看见别人什么时候离开，”他把报纸摞齐，语气淡淡的，“却看不见我什么时候留下来。”&lt;/p&gt;
&lt;p&gt;这句话落下去之后，窗外的雨好像忽然变大了。卡诺的手指压在旧报纸上，纸面受潮发软，微微凹陷下去。她没有接话，因为她不知道自己还能接什么。&lt;/p&gt;
&lt;p&gt;林栖也没有再说。他只是从口袋里掏出一支铅笔，从她手边抽过一张废纸，在上面画了个歪歪扭扭的圈，推到卡诺面前。&lt;/p&gt;
&lt;p&gt;“这是圈。”他说。&lt;/p&gt;
&lt;p&gt;“……我知道。”&lt;/p&gt;
&lt;p&gt;“所以被圈住了，”林栖站起身，把椅子推回原位，声音轻得像说给自己听，“不会走。”&lt;/p&gt;
&lt;p&gt;他说完就往期刊室外面走，脚步不快，军绿色的运动鞋踩在地板上几乎没有声响。卡诺盯着那张纸上歪歪扭扭的圈，直到他的背影消失在书架后面，才把纸折好，夹进了灰皮册子里&lt;/p&gt;
</content:encoded></item><item><title>LLM大模型微调——入门篇</title><link>https://kano.lzink.icu/dist/posts/2026-05-05-llm%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BE%AE%E8%B0%83-%E5%85%A5%E9%97%A8%E7%AF%87/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2026-05-05-llm%E5%A4%A7%E6%A8%A1%E5%9E%8B%E5%BE%AE%E8%B0%83-%E5%85%A5%E9%97%A8%E7%AF%87/</guid><description>想让大模型更“懂你”？其实没想象中那么难</description><pubDate>Sat, 11 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本文介绍了模型微调最基础的部分，目的是带读者体验简单微调的全过程。如果有一定基础，请移步至提高篇。&lt;/p&gt;
&lt;h2&gt;文章结构&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;#%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86llm%E5%BE%AE%E8%B0%83%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5&quot;&gt;第一部分：LLM微调的基本概念&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.1 大模型的本质是什么&lt;/li&gt;
&lt;li&gt;1.2 怎么获得优质参数&lt;/li&gt;
&lt;li&gt;1.3 什么是微调&lt;/li&gt;
&lt;li&gt;1.4 什么时候该使用微调&lt;/li&gt;
&lt;li&gt;1.5 怎么确定微调的大模型学得好不好&lt;/li&gt;
&lt;li&gt;1.6 微调的流程是什么&lt;/li&gt;
&lt;li&gt;1.7 我需要使用哪些工具&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;#%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86%E7%B3%BB%E7%BB%9F%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE&quot;&gt;第二部分：系统环境配置&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2.1 安装 CUDA&lt;/li&gt;
&lt;li&gt;2.2 安装 Ubuntu（可选）&lt;/li&gt;
&lt;li&gt;2.3 安装 LLaMA-Factory&lt;/li&gt;
&lt;li&gt;2.4 疑难杂症&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;#%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86%E4%BD%93%E9%AA%8C%E7%AE%80%E5%8D%95%E5%BE%AE%E8%B0%83%E5%85%A8%E8%BF%87%E7%A8%8B&quot;&gt;第三部分：体验简单微调全过程&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3.1 启动 Web 界面&lt;/li&gt;
&lt;li&gt;3.2 选择合适的模型&lt;/li&gt;
&lt;li&gt;3.3 准备数据集&lt;/li&gt;
&lt;li&gt;3.4 开始你的第一次微调吧！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;第一部分：LLM微调的基本概念&lt;/h2&gt;
&lt;h3&gt;1.1 大模型的本质是什么&lt;/h3&gt;
&lt;p&gt;一句话总结：&lt;strong&gt;模型的本质是函数，核心是参数，而训练是为了获得更好用的参数。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;大模型的地基是由 Transformer 这一自注意力机制神经网络架构组成。大模型每吐出一个词，都是根据当前的词计算下一个词的概率，而这个计算过程就是由函数完成的。&lt;/p&gt;
&lt;p&gt;函数里最重要的就是参数，参数决定模型算出来的结果准不准确。换而言之，模型的知识和能力都存储在参数里。模型智不智能，很重要的一点就是看参数好不好。&lt;/p&gt;
&lt;p&gt;所谓模型训练，就是一个&lt;strong&gt;寻找优质参数&lt;/strong&gt;的过程。&lt;/p&gt;
&lt;h3&gt;1.2 怎么获得优质参数&lt;/h3&gt;
&lt;p&gt;大模型的参数与我们平时解方程不一样，没有固定的公式，而是一步一步计算出来的。&lt;/p&gt;
&lt;p&gt;计算过程如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/4a1f9947619201369ba122acf9f6ba9e.png&quot; alt=&quot;训练流程&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;随机初始化参数&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用初始化的参数展开计算&lt;/strong&gt; —— 输入训练数据，模型预测下一个词的概率。比如下一个词是&quot;故事&quot;，但模型认为&quot;故事&quot;一词概率为 0，这就错了，记录下这个错误，这个错误就叫&lt;strong&gt;损失&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;使用记录下来的损失进行求导&lt;/strong&gt; —— 求导之后得到梯度（求导很复杂，不用管）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;根据梯度下降算法公式进行参数更新&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;新参数 = 旧参数 - 学习率 × 梯度
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用新参数再次输入训练数据&lt;/strong&gt;，重复执行这个过程，对参数的值不断调整&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这就是优化参数的全过程。&lt;/p&gt;
&lt;h3&gt;1.3 什么是微调&lt;/h3&gt;
&lt;p&gt;模型微调是指在&lt;strong&gt;预训练模型&lt;/strong&gt;的基础上，针对特定任务进行进一步训练的过程。&lt;/p&gt;
&lt;p&gt;预训练模型已经学习了大量通用语言知识，但在具体场景可能表现不佳。通过微调，我们可以让模型更好地理解和适应特定领域的语言特征和表达方式。&lt;/p&gt;
&lt;p&gt;打个比方：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;预训练的大模型就像一个马上参加高考的优秀学生，你给他一道高考数学题，他能很快给出答案。但如果你给出一道数学奥赛题，他就有点力不从心了。&lt;/p&gt;
&lt;p&gt;这时，微调就像在做题之前对他进行奥赛辅导，使他成为一名 MOer，再让他做奥赛题，效果就会好得多。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;总结：拿一个已经训练好的模型（预训练模型），在它的基础上继续训练，这就是微调。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;1.4 什么时候该使用微调&lt;/h3&gt;
&lt;p&gt;一般来说有两种情况：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;情况一：提示词不够用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在某些场景中，你竭尽所能地调整提示词，可模型输出结果还是不尽人意。比如工具调用场景 —— 要让模型在用户提问中准确判断要使用哪个工具，纯靠提示词需要高性能的模型，而且场景不能太复杂。再比如垂直领域提问，效果同样不好。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;情况二：计算机资源不够&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当提示词够用，但要写得很长、要给出很多案例、还要使用较大的模型时，会有两个问题：一是资源消耗巨大，二是推理速度变慢。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;补充&lt;/strong&gt;：解决这两种问题，不只有微调这一种方案，还有一种叫做 &lt;strong&gt;RAG&lt;/strong&gt;（检索增强生成）的方案。如果说微调是考试前给学生辅导，那么 RAG 就是给学生一本书让他考试时翻着看 —— 简单来说就是外挂知识库。这不是本文的重点，简单了解即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.5 怎么确定微调的大模型学得好不好&lt;/h3&gt;
&lt;p&gt;在反复训练中，当我们觉得模型学会的时候，就可以停下来了。要知道多轮学习中模型学得怎么样，最简单的方式就是监控前文提到的&lt;strong&gt;损失（Loss）&lt;/strong&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果损失没有下降，说明模型没学会，需要继续学&lt;/li&gt;
&lt;li&gt;损失下降了，不一定是学会了 —— 就像学生上完课写作业，作业会写不代表知识学懂了，要通过考试才知道&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们准备另一份&lt;strong&gt;不重复&lt;/strong&gt;的数据集，叫&lt;strong&gt;验证集&lt;/strong&gt;。把验证集丢给模型：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;训练集损失&lt;/th&gt;
&lt;th&gt;验证集损失&lt;/th&gt;
&lt;th&gt;结论&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;高&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;过拟合&lt;/strong&gt; —— 模型在照葫芦画瓢，没有真正理解&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;低&lt;/td&gt;
&lt;td&gt;学得还不错&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;判断的指标远远不止这一个，之后会讲到。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.6 微调的流程是什么&lt;/h3&gt;
&lt;p&gt;微调概括来说就是：&lt;strong&gt;基座模型 + 训练数据 + 微调方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 基座模型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;要微调模型，肯定得有个模型，选择的这个模型就是基座模型。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 训练数据&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是&lt;strong&gt;最最重要&lt;/strong&gt;的环节。你准备的数据质量决定了模型的上限，花再多心思也不过分。业界有句话：&lt;strong&gt;你输入的是垃圾，得到的也是垃圾&lt;/strong&gt;。一定要保证质量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 微调方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;微调方法总结来看分三种：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;th&gt;推荐程度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全局微调&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;对所有参数进行调整（如 10B 参数全调一遍）&lt;/td&gt;
&lt;td&gt;⭐⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;冻结微调&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;把底层参数冻结，只调整靠近输出层的那几层&lt;/td&gt;
&lt;td&gt;⭐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;LoRA 微调&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;不调整原参数，单独构建一个 LoRA 参数块并只调整它。原参数 + LoRA 参数块 = 完整参数&lt;/td&gt;
&lt;td&gt;⭐⭐⭐ 最推荐&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;推荐初学者只掌握 LoRA 微调，只需调整少量参数即可达到很好的效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;1.7 我需要使用什么工具&lt;/h3&gt;
&lt;p&gt;本文采用 &lt;strong&gt;LLaMA-Factory&lt;/strong&gt; 这个开源工具进行模型微调，自带 Web 图形化界面，好用易上手。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LLaMA-Factory 前置依赖：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PyTorch&lt;/strong&gt;：深度学习框架&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CUDA&lt;/strong&gt;：NVIDIA GPU 的并行计算平台，能让 LLaMA-Factory 调用 GPU 进行计算（纯用 CPU 太慢了）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 及相关库&lt;/strong&gt;：推荐使用 Python 3.10 版本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NVIDIA 驱动&lt;/strong&gt;：无需多言&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;本文给出本地部署方案，部分步骤需要科学上网。使用服务器跑模型放到提高篇讲。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;第二部分：系统环境配置&lt;/h2&gt;
&lt;p&gt;众所周知，搞 AI 的人 90% 的时间在配置环境，写代码的时间只占 10%。遇到问题直接去看 &lt;a href=&quot;#24-%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87&quot;&gt;疑难杂症&lt;/a&gt;，还是无法解决可以自行询问大模型。&lt;/p&gt;
&lt;h3&gt;2.1 安装 CUDA&lt;/h3&gt;
&lt;p&gt;首先需要一张 NVIDIA 的、支持 CUDA 的显卡。想知道自己的显卡是否支持，请自行询问大模型。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开 NVIDIA 官网，下载 NVIDIA APP，安装后更新驱动到最新版本&lt;/li&gt;
&lt;li&gt;在官网搜索 CUDA 并安装，推荐安装 &lt;strong&gt;CUDA 13.0&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自行下载：&lt;a href=&quot;https://developer.nvidia.com/cuda-toolkit-archive&quot;&gt;CUDA Toolkit Archive&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;2.2 安装 Ubuntu（可选）&lt;/h3&gt;
&lt;p&gt;对于本地部署，有两种方案：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows 本地部署&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;直接使用电脑自带的 Windows 系统&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WSL + Ubuntu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;使用 Windows 官方提供的 WSL 组件来运行 Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;为什么推荐 Ubuntu？&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;LLaMA-Factory 在 Linux 生态更好 —— 官方文档本身就是按 Linux 环境写的，Windows 下开启 QLoRA 需要额外装预编译的 bitsandbytes wheel，兼容性和折腾成本更高&lt;/li&gt;
&lt;li&gt;安装超级简单，不需要装虚拟机，一行命令即可&lt;/li&gt;
&lt;li&gt;WSL2 现在已经能正式使用 NVIDIA CUDA 进行 GPU 加速，不是早期那种&quot;勉强能跑&quot;的状态&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;如果只是想简单体验一下，跑最基础的推理或轻量训练，用 Windows 就够了。如果要真正开始做微调，强烈推荐 WSL + Ubuntu。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;安装 WSL + Ubuntu&lt;/strong&gt;（需科学上网）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wsl --install -d Ubuntu-22.04
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;安装完成后，使用 Windows 自带的搜索功能即可打开 Ubuntu。打开后会让你输入账号和密码，依次填写即可。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意！&lt;/strong&gt; WSL 有两个版本：WSL1 和 WSL2。WSL1 是早期版本，只有勉强能用的水平，&lt;strong&gt;一定要使用 WSL2！&lt;/strong&gt; 上面的命令默认使用 WSL2。可以用以下命令查看版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wsl --list --verbose
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看 &lt;code&gt;VERSION&lt;/code&gt; 这一列确认是 &lt;code&gt;2&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2.3 安装 LLaMA-Factory&lt;/h3&gt;
&lt;h4&gt;2.3.1 安装 LLaMA-Factory 本体&lt;/h4&gt;
&lt;p&gt;打开命令行或 PowerShell，拉取代码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://gitee.com/hiyouga/LLaMA-Factory.git
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;完笔之后听说这个 Gitee 库失效了，把 &lt;code&gt;gitee&lt;/code&gt; 换成 &lt;code&gt;github&lt;/code&gt; 即可，记得科学上网。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;2.3.2 配置虚拟环境&lt;/h4&gt;
&lt;p&gt;为了防止日后出现各种依赖报错，推荐给每一个项目都创建一个单独的虚拟环境。&lt;/p&gt;
&lt;p&gt;这里推荐使用 &lt;strong&gt;UV&lt;/strong&gt; 这个包管理工具。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安装 UV：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Windows
powershell -ExecutionPolicy Bypass -c &quot;irm https://github.com/astral-sh/uv/releases/download/0.9.27/uv-installer.ps1 | iex&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Linux
pip install uv -i https://mirrors.aliyun.com/pypi/simple
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;创建虚拟环境：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv venv finetune    # finetune 是虚拟环境的名字，可以自己改
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;进入虚拟环境：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Windows
finetune/Scripts/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# Linux
source finetune/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.3.3 安装依赖包&lt;/h4&gt;
&lt;p&gt;切换到安装目录并下载依赖：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd LLaMA-Factory
uv pip install -e &quot;.[torch,metrics]&quot; -i https://mirrors.aliyun.com/pypi/simple
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个过程大概 5-10 分钟。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;验证 GPU 是否可用&lt;/strong&gt;（应该输出 &lt;code&gt;True&lt;/code&gt;，显示 &lt;code&gt;False&lt;/code&gt; 请查看疑难杂症）：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python -c &quot;import torch;print(torch.cuda.is_available())&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.4 疑难杂症&lt;/h3&gt;
&lt;h4&gt;显示&quot;无法解析服务器的名称或地址&quot;怎么办&lt;/h4&gt;
&lt;p&gt;科学上网喵，科学上网谢谢喵。&lt;/p&gt;
&lt;h4&gt;安装依赖 &lt;code&gt;numpy==1.26.4&lt;/code&gt; 时失败怎么办&lt;/h4&gt;
&lt;p&gt;主要原因是缺少编译工具。去 VS Code 官网下载安装 Visual Studio Build Tools，安装 C++ 工具包即可。&lt;/p&gt;
&lt;h4&gt;我怎么确认有没有成功安装 LLaMA-Factory&lt;/h4&gt;
&lt;p&gt;进入虚拟环境，输入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;llamafactory-cli version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;能显示版本号就成了。&lt;/p&gt;
&lt;h4&gt;我怎么确认有没有安装 PyTorch&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;python -c &quot;import torch; print(torch.__version__)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;如果 PyTorch 已安装，会输出版本号，例如 &lt;code&gt;1.13.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果未安装，会看到 &lt;code&gt;ModuleNotFoundError: No module named &apos;torch&apos;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;验证 GPU 时显示 False 怎么办&lt;/h4&gt;
&lt;p&gt;GPU 加速需要安装兼容版本的 CUDA 和 PyTorch。&lt;/p&gt;
&lt;p&gt;可能的原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;没有安装 CUDA&lt;/li&gt;
&lt;li&gt;没有安装 GPU 驱动 / 驱动不是最新&lt;/li&gt;
&lt;li&gt;GPU 不支持 CUDA&lt;/li&gt;
&lt;li&gt;PyTorch 版本不兼容（确保安装的是 CUDA 版本）&lt;/li&gt;
&lt;li&gt;CUDA 运行时问题&lt;/li&gt;
&lt;li&gt;环境变量未正确设置（&lt;code&gt;CUDA_HOME&lt;/code&gt;、&lt;code&gt;PATH&lt;/code&gt; 等）&lt;/li&gt;
&lt;li&gt;系统权限问题&lt;/li&gt;
&lt;li&gt;CUDA 版本与 GPU 不兼容&lt;/li&gt;
&lt;li&gt;PyTorch 安装有问题&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;建议安装 CUDA 13.0 + PyTorch 2.9.1，这俩是兼容的。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 检查 CUDA 版本
nvcc --version

# 检查 GPU 是否被系统识别
nvidia-smi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;安装 PyTorch 2.9.1（Windows）：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install torch==2.9.1 torchvision==0.24.1 torchaudio==2.9.1 --index-url https://download.pytorch.org/whl/cu128
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;安装 UV 时出现 &lt;code&gt;Command &apos;pip&apos; not found&lt;/code&gt; 怎么办&lt;/h4&gt;
&lt;p&gt;Ubuntu 安装 Python 时不会自动装 pip，手动装上就行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install python3-pip
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;tyro 库报错怎么办&lt;/h4&gt;
&lt;p&gt;别用高版本 Python，用 &lt;strong&gt;3.10 版本&lt;/strong&gt;就行。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;第三部分：体验简单微调全过程&lt;/h2&gt;
&lt;h3&gt;3.1 启动 Web 界面&lt;/h3&gt;
&lt;p&gt;进入虚拟环境，输入：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;llamafactory-cli webui
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果没出问题，稍后 Web 面板会自动打开。如果没有自动打开，浏览器访问 &lt;code&gt;http://127.0.0.1:7860/&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;两个小设置：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 Language 选项处选择 &lt;strong&gt;zh&lt;/strong&gt; 切换成中文&lt;/li&gt;
&lt;li&gt;模型下载源选择 &lt;strong&gt;ModelScope&lt;/strong&gt;，下模型不用科学上网&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 选择合适的模型&lt;/h3&gt;
&lt;p&gt;推荐去&lt;strong&gt;魔搭网&lt;/strong&gt;下载模型：&lt;a href=&quot;https://www.modelscope.cn/home&quot;&gt;ModelScope 主页&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在魔搭网上方选择&quot;模型库&quot;，你会看到非常非常多的模型。选择方法如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 推荐选择千问（Qwen）系列&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;社区生态好，性能抗打。而且 Qwen 的命名方式很规范，举个例子：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;3.5qwen-7b-Thinking-base&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;→ 千问 3.5 — 70 亿参数 — 带思考功能 — 预训练模型&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一目了然。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;常见模型后缀一览：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;后缀&lt;/th&gt;
&lt;th&gt;含义&lt;/th&gt;
&lt;th&gt;通俗理解&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Base&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;仅经过大规模无监督预训练，未做指令或对话微调&lt;/td&gt;
&lt;td&gt;干不了事，要微调才能用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Instruct&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用大量&quot;指令-回答&quot;对进行了指令微调&lt;/td&gt;
&lt;td&gt;已经微调过了，直接用（也可以继续微调）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Thinking&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;经过思维链增强训练，能展示推理过程&lt;/td&gt;
&lt;td&gt;先思考，后回答&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Chat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;经过对话微调，擅长多轮对话&lt;/td&gt;
&lt;td&gt;天赋点聊天上了&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Vision / Audio / VLM&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;能同时处理文本、图像、音频等多种数据类型&lt;/td&gt;
&lt;td&gt;多模态（能识图、视频等）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Lite / Tiny / Small / Nano&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;参数量更小，速度快、资源占用低&lt;/td&gt;
&lt;td&gt;轻量化版本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Code&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在代码语料上额外训练，擅长代码生成与理解&lt;/td&gt;
&lt;td&gt;写代码很 NB 的模型&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GGUF / GPTQ / AWQ / FP16 / INT8 / INT4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;权重从高精度转换为低精度的压缩版本&lt;/td&gt;
&lt;td&gt;我显存不够&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;2. 入门推荐选择带 &lt;code&gt;-Instruct&lt;/code&gt; 的模型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;接手别人调过的模型再次微调会容易很多。Base 也行，但需要更多数据，也会更难。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. 根据硬件配置选择合适参数量的模型&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在满足应用需求的前提下，越小越好 —— 小意味着快，更省资源。&lt;/p&gt;
&lt;p&gt;选择好模型后，根据魔搭网教程下载即可。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;冷知识&lt;/strong&gt;：真正的 DeepSeek 是指 DeepSeek-671B 模型。数字比 671 小的，其实是 DeepSeek 团队制作的 Llama/Qwen 模型的改良版。严格来说，DeepSeek-32B 等模型并不是&quot;DeepSeek 模型&quot;，只是 DeepSeek 团队的作品简写成了这个名字。所以你能看见 DeepSeek 模型后面带了个 Qwen 的后缀（&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;3.3 准备数据集&lt;/h3&gt;
&lt;p&gt;还是那句话：&lt;strong&gt;你输入的是垃圾，得到的也是垃圾&lt;/strong&gt; —— 准备数据集是重中之重。&lt;/p&gt;
&lt;p&gt;三个重点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;质量 &amp;gt; 数量&lt;/strong&gt; —— 保证数据集的质量&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数量适中&lt;/strong&gt; —— 太多记不住，太少学不会。多少合适得自己测，这些都是宝贵的经验 :)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据多样性&lt;/strong&gt; —— 如果每条数据都差不多，效果依然不好&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;入门学习可以去网上找开源数据集。还是选择魔搭网，左上角选择&quot;数据集&quot;，自行选择合适的数据集下载。&lt;/p&gt;
&lt;p&gt;LLaMA-Factory 支持两种数据格式：&lt;strong&gt;Alpaca&lt;/strong&gt; 和 &lt;strong&gt;ShareGPT&lt;/strong&gt;。下载数据集时注意格式是否符合要求。&lt;/p&gt;
&lt;h4&gt;Alpaca 格式&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;instruction&quot;: &quot;雨星，我睡不着怎么办&quot;,
    &quot;input&quot;: &quot;&quot;,
    &quot;output&quot;: &quot;睡不着就和我聊聊天，聊着聊着就会睡着的啦&quot;,
    &quot;history&quot;: []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;字段说明：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;instruction&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;人类指令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;input&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;人类输入（可省略）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;模型输出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;history&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;存储上下文，提升上下文理解能力（可省略）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;实际输入 = instruction + input。以下三种写法是等价的：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 写法一
{
    &quot;instruction&quot;: &quot;雨星，我睡不着怎么办&quot;,
    &quot;input&quot;: &quot;睡不着就和我聊聊天，&quot;,
    &quot;output&quot;: &quot;聊着聊着就会睡着的啦&quot;,
    &quot;history&quot;: []
}

// 写法二
{
    &quot;instruction&quot;: &quot;雨星，我睡不着怎么办&quot;,
    &quot;input&quot;: &quot;&quot;,
    &quot;output&quot;: &quot;睡不着就和我聊聊天，聊着聊着就会睡着的啦&quot;,
    &quot;history&quot;: []
}

// 写法三
{
    &quot;instruction&quot;: &quot;雨星，我睡不着怎么办&quot;,
    &quot;input&quot;: &quot;睡不着就和我聊聊天，聊着聊着就会睡着的啦&quot;,
    &quot;output&quot;: &quot;&quot;,
    &quot;history&quot;: []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ShareGPT 格式&lt;/h4&gt;
&lt;p&gt;ShareGPT 格式包含一个 &lt;code&gt;conversations&lt;/code&gt; 列表，就像 Python 的字典一样：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;conversations&quot;: [
    {
      &quot;from&quot;: &quot;human&quot;,
      &quot;value&quot;: &quot;晚上好&quot;
    },
    {
      &quot;from&quot;: &quot;gpt&quot;,
      &quot;value&quot;: &quot;晚上好！是时候享受生活了，去洗澡、吃宵夜、和朋友聊天，还是和我聊天呢？&quot;
    },
    {
      &quot;from&quot;: &quot;human&quot;,
      &quot;value&quot;: &quot;没有朋友聊，所以选择和雨星聊天（&quot;
    },
    {
      &quot;from&quot;: &quot;gpt&quot;,
      &quot;value&quot;: &quot;看来你的朋友都很忙碌呢，没事，你还有雨星我⭐。看看今晚我们有什么话题可以聊的～&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;字段说明：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;字段&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;from&lt;/code&gt;（或 &lt;code&gt;role&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;值常为 &lt;code&gt;human&lt;/code&gt; / &lt;code&gt;gpt&lt;/code&gt;，或 &lt;code&gt;user&lt;/code&gt; / &lt;code&gt;assistant&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;value&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;对应角色的发言内容&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;3.4 开始你的第一次微调吧！&lt;/h3&gt;
&lt;p&gt;在 LLaMA-Factory 的 Web 界面中：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;选择你下载好的&lt;strong&gt;基座模型&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;加载你准备好的&lt;strong&gt;数据集&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;选择 &lt;strong&gt;LoRA 微调&lt;/strong&gt;方式&lt;/li&gt;
&lt;li&gt;设置训练参数（入门先用默认值即可）&lt;/li&gt;
&lt;li&gt;点击&lt;strong&gt;开始训练&lt;/strong&gt;！&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;训练完成后，可以在 Web 界面中直接与微调后的模型对话，看看效果如何。&lt;/p&gt;
&lt;p&gt;祝微调顺利&lt;/p&gt;
</content:encoded></item><item><title>小说——活着还行</title><link>https://kano.lzink.icu/dist/posts/2026-03-07-%E5%B0%8F%E8%AF%B4-%E5%BF%85%E9%A1%BB%E5%A5%94%E8%B7%91%E6%89%8D%E8%83%BD%E7%95%99%E5%9C%A8%E5%8E%9F%E5%9C%B0/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2026-03-07-%E5%B0%8F%E8%AF%B4-%E5%BF%85%E9%A1%BB%E5%A5%94%E8%B7%91%E6%89%8D%E8%83%BD%E7%95%99%E5%9C%A8%E5%8E%9F%E5%9C%B0/</guid><description>我有时候觉得，对于预言家而言，回忆和预知并没有什么区别</description><pubDate>Sat, 07 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;我有时候觉得，对于预言家而言，回忆和预知并没有什么区别。&lt;/p&gt;
&lt;p&gt;只不过是，一份报告里的尸体已经冰凉，而另一份里的尸体，此刻正倚在夜色的霓虹灯牌下，在寒风中，抱着一碗滚烫的、热气腾腾的关东煮。他很用力地吸了一口气，然后小心翼翼地咬下一大口鱼豆腐。豆腐吸饱了汤汁，烫得他直哈气，却又舍不得吐出来。他把脸埋在升腾的白色蒸汽里——那是萝卜和海带被煮透后的香气——脸上露出一种极其单纯的、乃至有些愚蠢的满足感。&lt;/p&gt;
&lt;p&gt;在不见天日的下层城区，这种加了很多香精的、不健康的、热腾腾的食物，是唯一能给予人片刻温暖的东西。&lt;/p&gt;
&lt;p&gt;我也买了一碗，站在候车区的阴影里看着他。&lt;/p&gt;
&lt;p&gt;少年大概十七八岁，皮肤白净，穿着一件洗得褪色的蓝色校服，袖口磨出了线头。校服左胸口的位置，原本绣校名的地方现在只剩几根断线，像是被人刻意拆掉的。他把鱼豆腐认真咽下去，动作停顿了一下，从怀里掏出一个屏幕碎裂的通讯器。&lt;/p&gt;
&lt;p&gt;紧接着，他看了一眼——大概是看到了什么令人恼火的消息，也许是老师的催促，也许是明天就要到期的房租。&lt;/p&gt;
&lt;p&gt;但他的眉头紧皱仅有一瞬间。&lt;/p&gt;
&lt;p&gt;终端的荧光照亮了他的脸，我看得见。他笑了。&lt;/p&gt;
&lt;p&gt;不是苦笑，不是自嘲，是那种真的被什么逗乐了的笑。他把通讯器收起来，又咬了一口鱼豆腐，汤汁顺着嘴角流下来一点，他用手背胡乱一抹，然后吸了吸鼻子。&lt;/p&gt;
&lt;p&gt;绞盘和缆索的摩擦声打破了沉默，垂直列车停靠在了站台。&lt;/p&gt;
&lt;p&gt;铁门吱呀作响地滑开。少年最后看了一眼这个充满油烟味的世界，把纸碗扔进垃圾桶，拎起脚边那个破旧的书包，露出一角卷边的笔记本——然后踏步走上这辆末班车。&lt;/p&gt;
&lt;p&gt;我咽下最后一口汤，把纸碗叠好，扔进同一个垃圾桶。&lt;/p&gt;
&lt;p&gt;裹紧大衣，逆着人流走进列车。&lt;/p&gt;
&lt;p&gt;去见证他的结局&lt;/p&gt;
&lt;p&gt;——————————————————————————&lt;/p&gt;
&lt;p&gt;列车启动了。&lt;/p&gt;
&lt;p&gt;车厢里人不多，这个时间点，上层的人早已入睡，下层的人还在加班。零星几个乘客都缩在角落里打盹，头顶的灯管有一半不亮，剩下的也在滋滋作响，把每个人的脸照得像褪了色的旧照片。&lt;/p&gt;
&lt;p&gt;我找了个靠窗的位置坐下，玻璃上映出我的脸——二十多岁，眼窝深陷，和车厢里任何一个疲惫的乘客没什么两样。唯一不同的是，我知道这趟列车的终点是什么。&lt;/p&gt;
&lt;p&gt;不，不只是终点。我知道这节车厢里每个人的终点。&lt;/p&gt;
&lt;p&gt;斜对面那个戴安全帽的中年男人，三个月后会死于一次缆索断裂。他的抚恤金会被侄子领走，妻子会在一年后改嫁，嫁的人恰好是他生前的工友。&lt;/p&gt;
&lt;p&gt;过道里站着的年轻女孩，正在用碎屏的手机看网课视频——屏幕上是一道物理题。她会连续考三年，第三年终于考上，然后在下层城区的某次超自然现象清扫行动中被误伤，死在距离录取通知书送达前六小时。&lt;/p&gt;
&lt;p&gt;但我没有说话，预言家的第一课就是学会闭嘴。&lt;/p&gt;
&lt;p&gt;车厢尽头飘来关东煮的味道。我转头看去，是刚才那个少年。他端着纸碗，在找座位。车厢摇晃，汤汁差点洒出来，他慌忙低头吸了一口，然后心满意足地咂咂嘴。&lt;/p&gt;
&lt;p&gt;他看见我在看他，愣了一下，然后笑了笑——和刚才看通讯器时一模一样的笑。&lt;/p&gt;
&lt;p&gt;“你也买了那家的？”他走过来，在我对面坐下，“我觉得他家比三号口的浓。”&lt;/p&gt;
&lt;p&gt;我点点头，没说话。&lt;/p&gt;
&lt;p&gt;他也不介意，自顾自地吃起来。车厢里很安静，只有列车行驶的轰隆声和他咀嚼的声音。吃到一半，他忽然抬起头：“你是去上层吧？”&lt;/p&gt;
&lt;p&gt;“怎么看出来的？”&lt;/p&gt;
&lt;p&gt;他指了指我的大衣领口——那里别着一枚很小的徽章，是出入上层城区的通行凭证。&lt;/p&gt;
&lt;p&gt;“见过几次。”他说，“你们走路的样子都不一样。”&lt;/p&gt;
&lt;p&gt;我低头看看自己的手，又看看他的手。他的手指上有茧，指甲缝里有一点洗不掉的墨水渍——那是长期握笔留下的痕迹。但更多的是细小的伤口，像是搬过什么重物后被划伤的。&lt;/p&gt;
&lt;p&gt;“你叫什么名字？”我问。&lt;/p&gt;
&lt;p&gt;“浅羽。”他说，“你呢？”&lt;/p&gt;
&lt;p&gt;“卡诺。”&lt;/p&gt;
&lt;p&gt;他点点头，把最后一口汤喝完，把纸碗叠好，放在座位旁边。动作很熟练，显然是经常坐这趟车的人。&lt;/p&gt;
&lt;p&gt;“卡诺，”他忽然叫我的名字，“你是做什么的？”&lt;/p&gt;
&lt;p&gt;我看着他的眼睛。那是一双年轻的眼睛，眼白上有几根血丝，满眼都是疲惫，但瞳孔里有一点亮光。&lt;/p&gt;
&lt;p&gt;“算是……记录者。”我说。&lt;/p&gt;
&lt;p&gt;“记录什么？”&lt;/p&gt;
&lt;p&gt;“人的结局。”&lt;/p&gt;
&lt;p&gt;他愣了一下，然后笑了：“那你这工作挺轻松的。反正每个人结局都一样。”&lt;/p&gt;
&lt;p&gt;“是吗？”&lt;/p&gt;
&lt;p&gt;“不是吗？”他往后一靠，脑袋贴着车厢的金属壁，“活着，然后死掉。有什么区别？”&lt;/p&gt;
&lt;p&gt;列车穿过隧道，窗外一片漆黑，只有偶尔掠过的维修灯，把他的脸照得明明灭灭。我想起报告上他的结局——一个小时后，七号区塌方。&lt;/p&gt;
&lt;p&gt;但我没说话。&lt;/p&gt;
&lt;p&gt;他也没等我回答，自顾自地继续说：“你知道我刚刚在看什么吗？”&lt;/p&gt;
&lt;p&gt;“催房租的消息。”&lt;/p&gt;
&lt;p&gt;“不止。”他把那个碎屏的通讯器掏出来，在我面前晃了晃，“一模成绩出来了。年级排名掉了一百多名。”&lt;/p&gt;
&lt;p&gt;我看着屏幕上那个刺眼的数字，没有说话。&lt;/p&gt;
&lt;p&gt;“老师发的。”他说，“让我加把劲，说还有三个月，来得及。”&lt;/p&gt;
&lt;p&gt;“来得及什么？”&lt;/p&gt;
&lt;p&gt;“高考。”他看着我，眼神里有一点奇怪的东西，“你不知道？哦对，你们上层的人不用考。你们有推荐名额，有保送通道，有各种我不知道的东西。”&lt;/p&gt;
&lt;p&gt;我没说话。因为他说的是真的。&lt;/p&gt;
&lt;p&gt;“我本来成绩还行。”他把通讯器收起来，声音很平静，“上学期还在年级前五十。但后来不行了。”&lt;/p&gt;
&lt;p&gt;“为什么？”&lt;/p&gt;
&lt;p&gt;他歪着头想了想，像是在组织语言：“因为我发现，不管我怎么跑，别人跑得比我更快。”&lt;/p&gt;
&lt;p&gt;他指了指窗外漆黑的隧道：“你知道吗，我们学校，晚自习到十点。熄灯是十点半。但熄灯以后，有人打手电背单词，有人去走廊刷题，有人在被窝里听网课。我试过不学，睡一觉，第二天早自习小测，人家比我多背二十个单词。”&lt;/p&gt;
&lt;p&gt;“所以你也开始学？”&lt;/p&gt;
&lt;p&gt;“对。我打手电打到十二点，一开始我假装去上厕所，回来的时候把英语书带到了床上。但其实我什么都没背进去，第二天困得要死，上课听不进去，晚上又要花更多时间补，就觉得心慌后来我发现，不是只有我在这样。所有人都在这样。我们就像——”他想了半天，没找到合适的词，“就像一群人在一个没有出口的房间里跑圈。谁都不敢停，因为一停就会被踩死。”&lt;/p&gt;
&lt;p&gt;我沉默了一会儿，然后说：“这叫内卷。”&lt;/p&gt;
&lt;p&gt;“什么？”&lt;/p&gt;
&lt;p&gt;“内卷。”我说，“一种系统性的困境。每个人都在拼命往前跑，但因为所有人都在跑，所以谁的位置都没有真正改变。消耗了所有精力，换来的只是——留在原地。”&lt;/p&gt;
&lt;p&gt;他听着，眼神里有什么东西闪了闪。&lt;/p&gt;
&lt;p&gt;“你怎么知道？”我没接他的话茬：“听过囚徒困境吗？”&lt;/p&gt;
&lt;p&gt;“什么困境？”&lt;/p&gt;
&lt;p&gt;“警察抓到两个小偷，分开审讯。如果两个人都抵赖，各判一年；一个坦白一个抵赖，坦白的释放，抵赖的判十年；两个都坦白，各判五年。你觉得他们会怎么选？”&lt;/p&gt;
&lt;p&gt;浅羽皱起眉，手指无意识地摩挲着那个碎屏终端：“你是说，我们都在互相提防？怕别人偷跑，所以自己也不敢停？”&lt;/p&gt;
&lt;p&gt;“对。”我指了指车厢里那些昏睡的乘客，“在被窝里打手电，是因为怕别人偷偷学；有人去走廊，是因为怕有人超过他。每个人都做出了对自己最‘安全’的选择，结果呢？”&lt;/p&gt;
&lt;p&gt;“结果所有人都没睡好，第二天上课全在打瞌睡。”浅羽苦笑了一声，声音里透着疲惫，“所以我们是在互相坑？明明知道这样没用，却谁也停不下来？”&lt;/p&gt;
&lt;p&gt;“你们被困在了一个游戏里。”我顿了顿，本想继续说些大道理，但看着他眼下的青黑，话到嘴边又咽了回去，“难道……你就没想过，如果不跑了会怎样？”&lt;/p&gt;
&lt;p&gt;浅羽愣了一下，随即苦笑着摇头：“卡诺，你是上层的人，你不懂。在下城区，除了考出去，我别无选择。哪怕我付出十倍努力，别人付出二十倍，我也只能像个傻瓜一样跟着跑。”&lt;/p&gt;
&lt;p&gt;沉默在车厢里蔓延。&lt;/p&gt;
&lt;p&gt;“你知道我为什么买这碗关东煮吗？”我突然问。&lt;/p&gt;
&lt;p&gt;他茫然地摇摇头：“饿了？”&lt;/p&gt;
&lt;p&gt;“不是。”我看着手里升腾的热气，“因为我今天不想吃食堂，也不想管什么排名。就这么简单。我只想要这一口热乎的。”&lt;/p&gt;
&lt;p&gt;他看着我，眼神里的光微微晃动了一下。&lt;/p&gt;
&lt;p&gt;“考试也一样，”我轻声说，“有人非要吃到最好吃的那家，熬三个小时排队，最后饿得胃疼。我只想吃一碗热的，哪家都行。你说，谁更累？”&lt;/p&gt;
&lt;p&gt;浅羽沉默了很久。列车穿过一段长长的隧道，黑暗吞没了他的表情。&lt;/p&gt;
&lt;p&gt;“你是让我……别排队了？”他的声音很轻，像是在问自己。&lt;/p&gt;
&lt;p&gt;“我是让你想清楚，”我看着窗外掠过的维修灯，“你到底是想吃饱，还是想赢。”&lt;/p&gt;
&lt;p&gt;过了很久，他开口：“你是说，我不需要跟别人比，只需要找到那个……让我觉得‘活着还行’的东西？”&lt;/p&gt;
&lt;p&gt;“我不知道。”我说，“这是你自己说的。”&lt;/p&gt;
&lt;p&gt;”卡诺，你是上层的人，你知道的东西多，你怎么知道这些的？“&lt;/p&gt;
&lt;p&gt;“听一个朋友说的，她还给我讲过一个故事”&lt;/p&gt;
&lt;p&gt;“嗯哼？”&lt;/p&gt;
&lt;p&gt;“《爱丽丝梦游仙境》里，有一位叫红皇后的角色。”我说，“她对爱丽丝说：在这个地方，你必须不停奔跑，才能留在原地。”&lt;/p&gt;
&lt;p&gt;他沉默了很久。列车继续在黑暗里穿行，轰隆轰隆，像是某种巨大的呼吸。&lt;/p&gt;
&lt;p&gt;然后他忽然笑了。&lt;/p&gt;
&lt;p&gt;“你知道吗，”他说，“我有时候会想，如果我不跑了会怎么样？”&lt;/p&gt;
&lt;p&gt;“会怎样？”&lt;/p&gt;
&lt;p&gt;“不知道。”他望向窗外，玻璃上映出他年轻的脸，“可能会被踩死吧。可能会掉队，然后被淘汰，然后——反正那些词我都听腻了。”&lt;/p&gt;
&lt;p&gt;他顿了顿，声音轻下来：“但今晚吃关东煮的时候，我忽然想，如果跑不动了，至少刚才那口鱼豆腐是真的烫，真的很香。”&lt;/p&gt;
&lt;p&gt;我愣住了。&lt;/p&gt;
&lt;p&gt;他转过头看我，又是那个笑容。&lt;/p&gt;
&lt;p&gt;“你是记录者对吧？”他说，“那你帮我记一下：某年某月某日，浅羽，十七岁，在下层城区三号口的关东煮摊，吃到了一颗很烫的鱼豆腐。那一刻他觉得，活着还行。”&lt;/p&gt;
&lt;p&gt;我看着他，忽然不知道说什么。&lt;/p&gt;
&lt;p&gt;报告上的结局还印在我脑子里——七号区，塌方，一个小时后。但那具“冰凉的尸体”，此刻正活生生地坐在我对面，眼睛里有光。&lt;/p&gt;
&lt;p&gt;列车开始减速。前方是他的那一站。&lt;/p&gt;
&lt;p&gt;他站起身，拎起那个破旧的书包。临走前，他回头看了我一眼。&lt;/p&gt;
&lt;p&gt;“卡诺，”他说，“你是记录者，那你一定见过很多人的结局吧？”&lt;/p&gt;
&lt;p&gt;我点点头。&lt;/p&gt;
&lt;p&gt;“那我问你——那些结局好的人，他们有什么共同点？”&lt;/p&gt;
&lt;p&gt;我张了张嘴，想回答。但我忽然发现，我不知道。&lt;/p&gt;
&lt;p&gt;因为我见过太多结局——好的，坏的，平淡的，惨烈的——但我从来没想过这个问题。&lt;/p&gt;
&lt;p&gt;他等了几秒，没等到答案，于是笑了笑：“没事，你慢慢想。下次再遇到我，告诉我。”&lt;/p&gt;
&lt;p&gt;门开了，冷风灌进来。&lt;/p&gt;
&lt;p&gt;他跳下站台，消失在昏暗的通道里。&lt;/p&gt;
&lt;p&gt;列车重新启动。我把脸贴在冰冷的玻璃上，看着他的背影越来越小，最终融入那片漆黑的夜色。&lt;/p&gt;
&lt;p&gt;下次再遇到他？&lt;/p&gt;
&lt;p&gt;我闭上眼睛，那份报告浮现在脑海里：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;姓名：浅羽&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;年龄：十七岁&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;身份：下层城区高三学生&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;死亡时间：一个小时后&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;死亡地点：七号居住区&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;死亡原因：塌方&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不会再有下次了。&lt;/p&gt;
&lt;p&gt;但那个笑容，那个说“活着还行”的笑容，却怎么也挥之不去。&lt;/p&gt;
&lt;p&gt;列车驶入隧道，窗外一片黑暗。玻璃上映出我的脸，还有我嘴角不知何时浮现的、一点极浅的笑意&lt;/p&gt;
&lt;p&gt;————————————————————————&lt;/p&gt;
&lt;p&gt;一个小时后。&lt;/p&gt;
&lt;p&gt;列车抵达上层城区。&lt;/p&gt;
&lt;p&gt;我走出车站，走进那片永远灯火通明、永远不缺关东煮的世界。&lt;/p&gt;
&lt;p&gt;路过一家便利店时，我停下脚步。&lt;/p&gt;
&lt;p&gt;走进去，买了一碗关东煮。&lt;/p&gt;
&lt;p&gt;鱼豆腐，萝卜，海带。&lt;/p&gt;
&lt;p&gt;我端着纸碗，站在路边，咬下一大口。&lt;/p&gt;
&lt;p&gt;烫。&lt;/p&gt;
&lt;p&gt;很烫。&lt;/p&gt;
&lt;p&gt;烫得我想哈气，但又舍不得吐出来。&lt;/p&gt;
&lt;p&gt;我把脸埋在升腾的白色蒸汽里，那是萝卜和海带被煮透后的香气&lt;/p&gt;
&lt;p&gt;我改变不了他的结局。&lt;/p&gt;
&lt;p&gt;但我可以记住他的笑容。&lt;/p&gt;
&lt;p&gt;可以记住他说“活着还行”的时候，眼睛里的光。&lt;/p&gt;
&lt;p&gt;我掏出通讯器，给那个永远不会再回复的号码，发了一条消息：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“今天鱼豆腐也很烫。”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;然后我把通讯器收起来，继续吃。&lt;/p&gt;
&lt;p&gt;汤汁顺着嘴角流下来一点，我用手背胡乱一抹。&lt;/p&gt;
&lt;p&gt;吸了吸鼻子。&lt;/p&gt;
&lt;p&gt;抬起头。&lt;/p&gt;
&lt;p&gt;夜色里，霓虹灯牌闪烁不停。&lt;/p&gt;
&lt;p&gt;我裹紧大衣，走进人群。&lt;/p&gt;
&lt;p&gt;明天，还会再买一碗&lt;/p&gt;
&lt;p&gt;哪怕只是为了证明，在这该死的世道里，至少这一刻的热度，是真的&lt;/p&gt;
&lt;p&gt;——————————————————————————————————&lt;/p&gt;
&lt;p&gt;这其实是一篇讲怎么反内卷的，看出来了吗：）&lt;/p&gt;
&lt;p&gt;人生苦短 ，自行寻乐 别想太多 ，珍惜当下&lt;/p&gt;
&lt;p&gt;——THE END——&lt;/p&gt;
</content:encoded></item><item><title>KMP算法</title><link>https://kano.lzink.icu/dist/posts/kmp/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/kmp/</guid><description>非常高效的字符串匹配算法</description><pubDate>Thu, 22 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;KMP是一种用于字符串匹配的算法，就是从一个字符串中寻找另一个子串&lt;/p&gt;
&lt;p&gt;老实说，第一次接触这个算法的时候看的那是一头雾水，代码相当简洁，但是众所周知，代码越简单就代表越难理解: (&lt;/p&gt;
&lt;p&gt;同时KMP算法的应用是非常广泛的，AC自动机就是利用KMP算法实现的，浏览器中上亿个关键字也是通过这种方式检索的，有关字符串匹配的相关问题都和KMP脱不了干系&lt;/p&gt;
&lt;p&gt;接下来让我们一起来了解一下这个精妙的算法&lt;/p&gt;
&lt;h1&gt;暴力匹配&lt;/h1&gt;
&lt;p&gt;当遇到字符串匹配问题时，第一反应是使用蛮力法来一个一个比对，一旦匹配失败就调回主串的下一个字符重新匹配，问题很明显，只要数据量过大，运行就会很慢&lt;/p&gt;
&lt;p&gt;考虑到最坏的情况，蛮力法的时间复杂度为N（n*m）&lt;/p&gt;
&lt;h1&gt;KMP王朝&lt;/h1&gt;
&lt;p&gt;因为暴力匹配实在是太慢了，于是3位大佬Knuth，Morris，Pratt（即KMP）发表了一个新的算法，把时间复杂度优化到了N（n+m），变成了线性时间复杂度，也就是说在一次遍历之中就能完成字符串的匹配&lt;/p&gt;
&lt;p&gt;KMP的本质是利用已知的信息来减少重复的运算，在暴力匹配中，只要遇到不匹配的字符就会将整个数组后移，然后重新匹配，但是我们已经知道之前遍历过的字符，那么我们怎么利用这些信息来避免暴力匹配的“回退”步骤呢&lt;/p&gt;
&lt;p&gt;换句话来说，就是让指针不后退，而让它永远向前移动&lt;/p&gt;
&lt;p&gt;这就是KMP的其中一个精妙之处了，KMP定义了一个叫做Next数组的概念，先不管Next数组怎么生成的，我们先来详细讲解一下Next数组的用处&lt;/p&gt;
&lt;h1&gt;Next数组的功能与用途&lt;/h1&gt;
&lt;p&gt;下面是一个很常见的字符数组，当运行到红色处时发现匹配错误&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当遇到匹配错误时，就会去看最后一个匹配的字符所对应的Next数值&lt;/p&gt;
&lt;p&gt;如图所示，这里使用的next数值就是2，那么我们就直接跳过前面俩个字符，也就是说next数组代表着要跳过的字符个数&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这样我们就实现了不再回退指针（重点），只需要一次遍历就能完成匹配，效率就会高得多&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-14-1024x507.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Python代码实现&lt;/p&gt;
&lt;p&gt;这里需要指出一个概念—PM表与Next表，其实上图的这种严格意义上来说是PM表（Partial Match部分匹配表），Next表指的是当匹配失败时，&lt;strong&gt;模式串指针应该回退的位置&lt;/strong&gt;，而PM表指的是&lt;strong&gt;最长相同前后缀长度&lt;/strong&gt;（后面会讲到），一定一定不要搞混了，再次重申，本文的Next数组不是真正的Next数组！！！而是PM表！！！&lt;/p&gt;
&lt;p&gt;Next的第一种写法就是整个数组向后平移一位，再在第一位补-1或者不补&lt;/p&gt;
&lt;p&gt;第二种写法是给第一种都加1，也就是前两位一直是0&lt;/p&gt;
&lt;p&gt;经过这样的改写后才是真正意义上的Next数组，可自行百度&lt;/p&gt;
&lt;h1&gt;Next数组的原理&lt;/h1&gt;
&lt;p&gt;这个才是KMP的重中之重，想一想，为什么能跳过2个字符呢，就不会漏掉字符吗&lt;/p&gt;
&lt;p&gt;其实在推导下这样是不会出现漏掉字符的问题的，注意看，主串的后缀集合与子串的前缀集合是一样的，这句话也等同于为&lt;strong&gt;子串的前缀集合与它本身后缀集合的交集&lt;/strong&gt;（重点），读者自行思考一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我们再次来看看这张图片，图中跳过了2个字符，为啥一定是2个呢，因为成功匹配的最后这俩AB，和跳过的这俩AB是完全一样的，也就是说，这4个字符，它们有着&lt;strong&gt;相同的最长前后缀AB&lt;/strong&gt;，而这个前后缀的长度刚好为2&lt;/p&gt;
&lt;p&gt;可知，我们使用的Next数组就是用来找子串的最长相同前后缀的，一定一定是最长的前后缀，且不含它本身&lt;/p&gt;
&lt;h1&gt;Next数组的构建&lt;/h1&gt;
&lt;p&gt;现在我们知道了Next数组的原理，那么算法该怎么写呢&lt;/p&gt;
&lt;p&gt;当然，可以for暴力求解，就是效率低了点（乐）&lt;/p&gt;
&lt;p&gt;我们可以用递推的方式来求解，利用已有的数据来避免重复运算&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里分为俩种情况，第一种情况就是下一个字符能构成一个更长的相同前后缀&lt;/p&gt;
&lt;p&gt;如图，当运行到第5个字符时，我们已经发现了最长前后缀为AB，即Next为2，在第6个字符时我们发现能构成一个更长的前后缀了，即ABA，那么长度就为2+1，Next就为3&lt;/p&gt;
&lt;p&gt;第二种情况就是下一个字符无法构成更长的前后缀，如图ABAC与ABAB无法匹配，那么怎么办呢，难不成又暴力匹配，从0开始数吗？&lt;/p&gt;
&lt;p&gt;我们可以发现，子串前后这俩部分完全相同（ABA与ABA），右边这部分的后缀等于左边这部分的后缀，刚好，左边部分的Next已经算过了，直接查表就能发现Next为1，然后又开始匹配，发现AB与AB又能构成相同前后缀了，Next = 1 + 1，即Next为2&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/73427a40d5c3d3bc3faa464cdcfa4b65.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Python代码实现&lt;/p&gt;
&lt;h1&gt;另一种解释&lt;/h1&gt;
&lt;p&gt;在网上查阅资料时发现了一个很有意思的说法，是通过信号波的角度来解释KMP的概念&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/661673949&quot;&gt;https://zhuanlan.zhihu.com/p/661673949&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;读者可以自行阅读学习&lt;/p&gt;
</content:encoded></item><item><title>Python项目管理杂谈</title><link>https://kano.lzink.icu/dist/posts/2025-12-24-python%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E6%9D%82%E8%B0%88/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2025-12-24-python%E9%A1%B9%E7%9B%AE%E7%AE%A1%E7%90%86%E6%9D%82%E8%B0%88/</guid><description>如果你写过Go 或者 Rust，你会发现它们的项目结构特别的规整，就跟带了强迫症一样 但是Python却恰恰相反，这玩意...</description><pubDate>Wed, 24 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;如果你写过Go 或者 Rust，你会发现它们的项目结构特别的规整，就跟带了强迫症一样&lt;/p&gt;
&lt;p&gt;但是Python却恰恰相反，这玩意从诞生之初压根就没考虑过工程结构这事&lt;/p&gt;
&lt;p&gt;所以早期的Python管理相当放飞自我，好在一方面官方的pep规范一直在努力的打补丁，另一方面许多流行的库的项目结构都长得差不多，好歹算是有个很好的参考&lt;/p&gt;
&lt;h2&gt;妙妙小工具——Conda&lt;/h2&gt;
&lt;p&gt;现在的Python工程管理分为了两大流派，第一大派则是Conda宇宙&lt;/p&gt;
&lt;p&gt;Conda本身是一个商业软件，但是大家用的最多的是它的免费版本，MiniConda和最近很火的pixi都属于这个生态&lt;/p&gt;
&lt;p&gt;但是Conda这个体系从根上来说，和官方的Python八竿子打不着一块去&lt;/p&gt;
&lt;p&gt;有着自己的配置文件，自己的软件仓库，甚至连Python解释器都是自己编译的，更关键的是Conda不止是支持Python服务，也支持GO,Rust,C++等各种各样的语言，只是Conda刚好选择了Python作为最主要的交互语言而已&lt;/p&gt;
&lt;p&gt;这样做的好处是，Conda从设计之初就想的很周全，把多语言支持，依赖管理，虚拟环境等令人头大的问题，用一套统一的方案全给解决了，相比之下官方的Python体系在早期就是一个烂摊子&lt;/p&gt;
&lt;p&gt;同时，Conda的问题也不少，Conda想成为一个跨语言的包管理器，带来的问题就是臃肿不堪，速度堪忧，主打一个大炮打蚊子&lt;/p&gt;
&lt;p&gt;频道冲突、封闭生态等问题也是层出不穷&lt;/p&gt;
&lt;p&gt;在轻量级、符合标准的现代工具如 uv 和 pixi 崛起的今天，Conda的架构显得愈发陈旧和过时&lt;/p&gt;
&lt;p&gt;不过本文章的重点并不在这，我们先点到为止，之后会单独开一篇文章来讲解Conda这一工具（会出的！）&lt;/p&gt;
&lt;h2&gt;Python官方体系&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意！以下大部分都是些过时的写法，了解一下来龙去脉就好，不推荐在真实项目中使用（重点）&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;目前管理依赖建议使用UV这个包管理工具，如果想了解这个工具可以移步至这篇文章，&lt;a href=&quot;https://neko.lzink.icu/?p=55&quot;&gt;链接跳转&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我们先从一个例子开始，假如我们手里有个项目&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from flask import Flask

app = Flask(__name__)

@app.route(&apos;/&apos;)
def hello_world():
    return &apos;Hello&apos;
if __name__ == &apos;__main__&apos;:
    app.run(debug = True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;目录里只有一个代码文件main.py（如图），这个项目非常简单，就是个用Flask写的hello world&lt;/p&gt;
&lt;p&gt;在一个新的环境里，Flask这个库通常是没有安装的，直接运行肯定会报错&lt;/p&gt;
&lt;p&gt;这好办，我们的第一反应肯定是用pip来安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip3 install flask
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行pip后：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-2-1024x439.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;好耶，程序能够成功运行力，可喜可贺&lt;/p&gt;
&lt;p&gt;但是请注意，用这种方式安装会放入一个全局环境之中&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这样在开发过程中会带来俩个很棘手的问题&lt;/p&gt;
&lt;p&gt;1.版本冲突&lt;/p&gt;
&lt;p&gt;比如main.py使用的flask是3.1.1版本，而old.py可能只兼容3.0版&lt;/p&gt;
&lt;p&gt;那么我们因为新项目而全局升级了flask库，旧项目就可能因为版本不匹配而无法运行&lt;/p&gt;
&lt;p&gt;2.复杂的依赖关系（也就是依赖地狱）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一个库通常会依赖其他几个库，其他的库又有各自的依赖，这样一层层嵌套下来，就会引发更多的版本冲突&lt;/p&gt;
&lt;p&gt;而虚拟环境就是为了解决这个问题而设计出来的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python3 -m venv .venv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入这个代码就能生成一个名叫.venv的虚拟环境&lt;/p&gt;
&lt;p&gt;执行完后 你的目录里就会多一个名为.venv的目录&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;名字是可以随便取的，但我还是推荐就叫.venv，这样你的IDE能够自动检测到这个名字&lt;/p&gt;
&lt;p&gt;如果没有使用IDE，就用以下命令来激活这个环境&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source .venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;现在我们有了虚拟环境，项目之间的依赖总算被隔离开了&lt;/p&gt;
&lt;p&gt;这样应该就没问题了………吧？&lt;/p&gt;
&lt;h2&gt;依赖管理&lt;/h2&gt;
&lt;p&gt;自己运行到是没啥问题了，那么我们要怎么把项目的依赖分享给别人呢&lt;/p&gt;
&lt;p&gt;总不能让人执行一大堆&lt;code&gt;pip install&lt;/code&gt;命令吧，太容易出错了，还不专业：（&lt;/p&gt;
&lt;p&gt;为了解决这种问题，早期最主流的做法是用&lt;code&gt;pip freeze&lt;/code&gt;命令，这样就可以列出所以已经安装好的包和版本号&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;并用重定向符把这些内容输出到一个文件里，这个文件名可以随便取，但一般我们会叫做requirements.txt&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;对方只需要在自己的虚拟环境里执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pip就会读取这个文件，并把里面的依赖全部安装一遍，这种安装方式非常直观，现在依然可以在大量开源项目中看到requirements.txt的身影&lt;/p&gt;
&lt;p&gt;这样做会有一个很大的缺陷，那就是分不清楚项目需要的直接依赖，和这些直接依赖引入的间接依赖&lt;/p&gt;
&lt;p&gt;在项目中，明明我们只有Flask这一个直接依赖，requirements.里却又7个包，如果说项目很简单，这问题不大，只要项目变得复杂，那就有得玩了&lt;/p&gt;
&lt;p&gt;更麻烦的是，在卸载包的时候，根本处理不好这种依赖关系&lt;/p&gt;
&lt;p&gt;卸载Flask：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip uninstall flask
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后再重新生成requirements文件&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;会发现pip只会移除Flask本身，Flask的依赖仍然存在，这些依赖会留在环境里面，变成没人管的孤儿依赖&lt;/p&gt;
&lt;p&gt;现代Python项目的标准解决方案是使用pyproject.toml&lt;/p&gt;
&lt;p&gt;在你的项目目录里建立一个名为pyproject.toml的文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[project]
name = &quot;hello-world&quot;
version = &quot;0.1.0&quot;
dependencies = [
    &quot;flask&amp;gt;=3.1.2&quot;,
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;dependencies&lt;/code&gt;括号中写上你所需要的依赖即可，如果依赖不想要了，直接删除就行&lt;/p&gt;
&lt;p&gt;接下来，安装依赖：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pip install .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条命令做了俩件事&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;pip会根据pyproject.toml的配置，把这个项目打包成一个Python包（.whl）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装刚刚打包好的Python包&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样，依赖就安装完成了，&lt;/p&gt;
</content:encoded></item><item><title>元宇宙怎么突然销声匿迹了？</title><link>https://kano.lzink.icu/dist/posts/2025-12-23-%E5%85%83%E5%AE%87%E5%AE%99%E6%80%8E%E4%B9%88%E7%AA%81%E7%84%B6%E9%94%80%E5%A3%B0%E5%8C%BF%E8%BF%B9%E4%BA%86/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2025-12-23-%E5%85%83%E5%AE%87%E5%AE%99%E6%80%8E%E4%B9%88%E7%AA%81%E7%84%B6%E9%94%80%E5%A3%B0%E5%8C%BF%E8%BF%B9%E4%BA%86/</guid><description>2019元宇宙那么火，怎么现在一点消息都没有了呢</description><pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在2019年，在科技高速发展的时候，突然出现了俩个有意思的概念，那就是NFT和元宇宙&lt;/p&gt;
&lt;p&gt;这俩玩意是啥呢，NFT大概算是一种虚拟资产或者虚拟货币，而元宇宙呢，听着那可就高大上了&lt;/p&gt;
&lt;p&gt;它是一个由虚拟和现实世界融合创造的、具有&lt;strong&gt;临场感&lt;/strong&gt;的、&lt;strong&gt;共享的&lt;/strong&gt;、&lt;strong&gt;持久的&lt;/strong&gt;3D虚拟空间网络，你可以在里面能够真正拥有虚拟财产，进行交易（NFT），也可以在其中与其他进行实时互动、社交、工作、娱乐，就像在现实世界中一样，并且这个世界不会因为你的退出而关闭或重置，7*24小时全天开放，听着很厉害是不是？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/0363f40ebea729a0e4039612ac69d2f0_720.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;等等，这不就是？…… VRChat吗!!!？&lt;/p&gt;
&lt;p&gt;在当时，元宇宙这个概念可是轰动全球，阿里巴巴，百度等大型厂商可是大手一挥，分分钟投资进场，主星序科技 (AR手游) 在2019年获得百万级投资，&lt;strong&gt;Unity Technologies&lt;/strong&gt; 在2019年5月完成1.25亿美元E轮融资，那么多人关注着，这么看来，元宇宙应该会发展的很好……吧？&lt;/p&gt;
&lt;p&gt;不对啊，怎么几年前这么火，现在怎么连影子都看不到哇，我的虚拟世界呢，我的虚拟房产呢？这和想象的明显不一样哇！！！&lt;/p&gt;
&lt;p&gt;其实只要是玩过一些游戏，都能够知道这东西火的有多莫名其妙，元宇宙这玩意现目前根本就不可能实现，就是用来忽悠从来没有玩过游戏老头钱的 ：）&lt;/p&gt;
&lt;p&gt;现在的网络技术又没有突飞猛进，怎么可能就出现什么质变呢&lt;/p&gt;
&lt;p&gt;玩个VRChat都能电子ed，凭什么元宇宙能让你一直沉浸其中呢？&lt;/p&gt;
&lt;p&gt;开个多人音频会议都会有卡段，凭什么网络能满足千万级人数同时社交？三体科技？&lt;/p&gt;
&lt;p&gt;VR产品价格那么昂贵，设备那么笨重，续航如此拉胯，体验如此折磨，凭什么说服这么多人一天到晚带着那玩意&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;images/7e3be53fb295c37a7d62ff22d51b0b88-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在元宇宙最火的那年，还真有人以这样的形式开会，怎么说呢…就挺乐的&lt;/p&gt;
&lt;p&gt;5G被诟病再多，它落地了，它装到手机上了&lt;/p&gt;
&lt;p&gt;新能源车诟病再多，它落地了，它可以开，还卖得挺不错&lt;/p&gt;
&lt;p&gt;元宇宙那么火，它落地了吗，他让大家感受到了吗，没有，完全没有&lt;/p&gt;
&lt;p&gt;至今唯一成功且出名的，是和元宇宙同时出生的NFT，它化为了CS饰品，然后变成了倒钩的交易场所，元宇宙更是查无此人（这俩唐比概念真是一对苦命鸳鸯啊）&lt;/p&gt;
&lt;p&gt;炒作那么久，最后发现元宇宙就是大型多人同时在线交互性网络游戏，有那资源直接做3A不香吗，做大型网游不香吗&lt;/p&gt;
&lt;p&gt;真有能力做出来的，最后都当游戏卖了&lt;/p&gt;
&lt;p&gt;扎克伯格也不知道是被谁忽悠了，脑袋抽筋成这样去All in这玩意，现在唯一留下来的痕迹就是fb公司这个mete新名字，还有扎克伯格本人的蜥蜴人avater&lt;/p&gt;
&lt;p&gt;不过好歹这个虚拟人比他本人更像人类（确信）&lt;/p&gt;
&lt;p&gt;说到底，元宇宙的失败的根本原因是技术问题，不可否认的是元宇宙它确实是未来趋势，很有可能成为下一代互联网的形态，但是目前的科技水平还远远做不到，或者说没法低成本做到，没法低成本就说明没法赚普通人米嘛，所以它现在暂时看不到了&lt;/p&gt;
&lt;p&gt;再说，全球的游戏公司全部合并，造一个虚拟世界，强制统一所有游戏ID，这种丰功伟绩得赛博秦始皇搞定大一统后才能落实下来了&lt;/p&gt;
&lt;p&gt;有生之年怕是看不着咯 ~lol~ 还想玩刀剑神域呢 老老实实玩VRC去吧：）&lt;/p&gt;
&lt;p&gt;——The End——&lt;/p&gt;
</content:encoded></item><item><title>Linux——从入门到放弃 #2</title><link>https://kano.lzink.icu/dist/posts/2026-5-28-linux%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E5%9C%9F2/</link><guid isPermaLink="true">https://kano.lzink.icu/dist/posts/2026-5-28-linux%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E5%9C%9F2/</guid><description>Linux常见命令介绍</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;在上一篇文章中，我们了解了 Linux 的目录结构、路径概念和文件权限。但要在 Linux 系统中游刃有余，光懂理论可不行，必须得和系统&quot;对话&quot;。Linux 的命令行界面（CLI）就是最高效的对话窗口&lt;/p&gt;
&lt;p&gt;如果你习惯了图形界面的鼠标点击，刚开始敲命令一定会觉得痛苦，但相信我，一旦熟悉了这些快捷指令，你就会再也回不去鼠标了。本文将带你掌握 Linux 中最常用的基础命令&lt;/p&gt;
&lt;h2&gt;一、目录操作命令&lt;/h2&gt;
&lt;p&gt;在 Linux 系统中，文件系统呈倒状树结构，通过目录操作命令可以在不同层级之间进行切换与查看&lt;/p&gt;
&lt;h3&gt;1.1 &lt;code&gt;pwd&lt;/code&gt;：显示当前路径&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pwd&lt;/code&gt;（Print Working Directory）用于输出当前工作目录的绝对路径。当不确定当前所处位置时，可使用此命令确认&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ pwd
/home/kaishen/project
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.2 &lt;code&gt;ls&lt;/code&gt;：列出目录内容&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ls&lt;/code&gt;（List）用于显示指定目录下的文件和子目录信息。不加参数时仅显示文件名，常用参数组合如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ls           # 列出当前目录下的文件名
$ ls -l        # 以长格式显示详细信息（包含权限、属主、大小等）
$ ls -a        # 显示所有文件（包括以 . 开头的隐藏文件）
$ ls -lah      # 组合参数：长格式 + 所有文件 + 人类可读的文件大小(h)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1.3 &lt;code&gt;cd&lt;/code&gt;：切换工作目录&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cd&lt;/code&gt;（Change Directory）用于切换当前工作目录，支持绝对路径与相对路径&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd /etc      # 切换至绝对路径 /etc
$ cd ..        # 返回上一级目录
$ cd ~         # 切换至当前用户的家目录
$ cd -         # 切换至上一次所在的目录
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;提示：&lt;/strong&gt; 直接执行 &lt;code&gt;cd&lt;/code&gt; 不加参数，等同于 &lt;code&gt;cd ~&lt;/code&gt;，均会返回当前用户的家目录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;二、文件与目录管理命令&lt;/h2&gt;
&lt;h3&gt;2.1 &lt;code&gt;mkdir&lt;/code&gt;：创建目录&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mkdir&lt;/code&gt;（Make Directory）用于创建新的目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir test          # 在当前目录创建 test 目录
$ mkdir -p a/b/c      # 递归创建多层目录（若父目录不存在则自动创建）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.2 &lt;code&gt;touch&lt;/code&gt;：创建空文件&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;touch&lt;/code&gt; 命令原本用于更新文件的时间戳，若目标文件不存在，则会创建一个空文件，因此常被用来新建文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ touch hello.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.3 &lt;code&gt;cp&lt;/code&gt;：复制文件或目录&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cp&lt;/code&gt;（Copy）用于复制文件或目录&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cp source.txt dest.txt    # 复制文件并重命名
$ cp -r dir1/ dir2/         # 复制目录（必须添加 -r 参数表示递归复制目录内的所有内容）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.4 &lt;code&gt;mv&lt;/code&gt;：移动与重命名&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mv&lt;/code&gt;（Move）可实现文件或目录的移动与重命名。源路径与目标路径在同一目录下时为重命名，不同目录时为移动&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mv oldname.txt newname.txt    # 将文件重命名
$ mv file.txt ../               # 将文件移动至上一级目录
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.5 &lt;code&gt;rm&lt;/code&gt;：删除文件或目录&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rm&lt;/code&gt;（Remove）用于删除文件或目录。Linux 默认不提供回收站机制，删除后难以恢复，操作需谨慎&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rm file.txt         # 删除文件
$ rm -r dir/          # 递归删除目录及其内容
$ rm -ri dir/         # 递归删除并在删除前逐一确认
$ rm -rf dir/         # 强制递归删除，无需确认
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;警告：&lt;/strong&gt; 切勿随意执行 &lt;code&gt;rm -rf /&lt;/code&gt;，该命令会强制递归删除根目录下所有文件，导致系统彻底损坏&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;三、文件内容查看命令&lt;/h2&gt;
&lt;h3&gt;3.1 &lt;code&gt;cat&lt;/code&gt;：查看完整内容&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;cat&lt;/code&gt;（Concatenate）会将文件全部内容一次性输出到屏幕，适用于内容较少的文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat main.c
#include &amp;lt;stdio.h&amp;gt;

int main() {
    printf(&quot;Hello, Linux!\n&quot;);
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2 &lt;code&gt;head&lt;/code&gt; 与 &lt;code&gt;tail&lt;/code&gt;：查看首尾内容&lt;/h3&gt;
&lt;p&gt;对于较长的文件，可使用 &lt;code&gt;head&lt;/code&gt; 或 &lt;code&gt;tail&lt;/code&gt; 仅查看文件开头或末尾的部分行数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ head -n 10 main.c     # 查看文件前 10 行
$ tail -n 10 main.c     # 查看文件最后 10 行
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tail&lt;/code&gt; 命令配合 &lt;code&gt;-f&lt;/code&gt;（follow）参数可实时追踪文件的最新追加内容，常用于查看实时日志：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tail -f /var/log/syslog   # 实时监控日志输出（按 Ctrl+C 退出）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3 &lt;code&gt;less&lt;/code&gt;：分页查看&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;less&lt;/code&gt; 命令支持分页浏览文件内容，适用于大文件查看。使用方向键上下滚动，按 &lt;code&gt;q&lt;/code&gt; 退出&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ less main.c
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;四、查找与搜索命令&lt;/h2&gt;
&lt;h3&gt;4.1 &lt;code&gt;find&lt;/code&gt;：查找文件&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;find&lt;/code&gt; 命令可根据文件名、大小、修改时间等属性在指定目录树中查找文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ find / -name &quot;main.c&quot;        # 在根目录下查找名为 main.c 的文件
$ find . -name &quot;*.txt&quot;         # 在当前目录及子目录查找所有 .txt 文件
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4.2 &lt;code&gt;grep&lt;/code&gt;：搜索文本&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;grep&lt;/code&gt; 用于在文件中搜索匹配指定模式的行，并输出该行内容，常与管道符 &lt;code&gt;|&lt;/code&gt; 结合使用&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ grep &quot;hello&quot; main.c              # 在 main.c 中搜索包含 hello 的行
$ ls -l /etc | grep &quot;conf&quot;         # 在 ls 的输出结果中筛选包含 conf 的行
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;五、获取帮助命令&lt;/h2&gt;
&lt;h3&gt;5.1 &lt;code&gt;man&lt;/code&gt;：查看手册&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;man&lt;/code&gt;（Manual）用于查阅命令、系统调用及配置文件的官方帮助手册&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ man ls
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 &lt;code&gt;man&lt;/code&gt; 页面中，可使用方向键翻阅，按 &lt;code&gt;/&lt;/code&gt; 输入关键字进行搜索，按 &lt;code&gt;q&lt;/code&gt; 退出&lt;/p&gt;
&lt;h2&gt;常见命令速查&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;全称&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;常用参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pwd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Print Working Directory&lt;/td&gt;
&lt;td&gt;显示当前路径&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ls&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List&lt;/td&gt;
&lt;td&gt;列出目录内容&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-l&lt;/code&gt; (长格式), &lt;code&gt;-a&lt;/code&gt; (所有), &lt;code&gt;-h&lt;/code&gt; (易读大小)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cd&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change Directory&lt;/td&gt;
&lt;td&gt;切换目录&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~&lt;/code&gt; (家目录), &lt;code&gt;-&lt;/code&gt; (上次目录)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mkdir&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Make Directory&lt;/td&gt;
&lt;td&gt;创建目录&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-p&lt;/code&gt; (递归创建)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;touch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;创建空文件/更新时间戳&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy&lt;/td&gt;
&lt;td&gt;复制&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-r&lt;/code&gt; (复制目录)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Move&lt;/td&gt;
&lt;td&gt;移动/重命名&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove&lt;/td&gt;
&lt;td&gt;删除&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-r&lt;/code&gt; (目录), &lt;code&gt;-f&lt;/code&gt; (强制), &lt;code&gt;-i&lt;/code&gt; (交互确认)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Concatenate&lt;/td&gt;
&lt;td&gt;查看全文&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;head&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;查看文件头部&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-n&lt;/code&gt; (指定行数)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tail&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;查看文件尾部&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-n&lt;/code&gt; (行数), &lt;code&gt;-f&lt;/code&gt; (实时追踪)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;less&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;分页查看&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;查找文件&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-name&lt;/code&gt; (按名称)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;搜索文本模式&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;man&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;查看帮助手册&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;小结&lt;/h2&gt;
&lt;p&gt;本文介绍了 Linux 系统中的常见基础命令，涵盖以下内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;pwd&lt;/code&gt;、&lt;code&gt;ls&lt;/code&gt;、&lt;code&gt;cd&lt;/code&gt; 进行目录查看与切换&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;mkdir&lt;/code&gt;、&lt;code&gt;touch&lt;/code&gt;、&lt;code&gt;cp&lt;/code&gt;、&lt;code&gt;mv&lt;/code&gt;、&lt;code&gt;rm&lt;/code&gt; 进行文件与目录的创建、复制、移动和删除&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;cat&lt;/code&gt;、&lt;code&gt;head&lt;/code&gt;、&lt;code&gt;tail&lt;/code&gt;、&lt;code&gt;less&lt;/code&gt; 查看文件内容&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;find&lt;/code&gt;、&lt;code&gt;grep&lt;/code&gt; 进行文件查找与文本搜索&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;man&lt;/code&gt; 获取命令的官方帮助信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;熟练掌握这些基础命令，即可满足 Linux 系统日常操作的大部分需求&lt;/p&gt;
</content:encoded></item></channel></rss>