news 2026/10/16 12:34:15

终端AI编程助手实践手册:从Claude Code到hooks与MCP的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
终端AI编程助手实践手册:从Claude Code到hooks与MCP的完整指南

如果你常年在IDE和网页AI之间来回搬运代码,大概率有过一种很拧巴的感觉:一边是强大的对话模型,一边是真正要维护的工程目录,两边中间隔着一层剪贴板。过去我习惯把代码复制给网页AI,再把建议半行半行地粘回来,遇到稍大的重构就是一场体力劳动。后来我改用终端里的编程助手——Claude Code,模式彻底变了:它直接在终端里启动,能自己读目录、改文件、跑命令、盯测试结果,我只需要说“哪里有问题、想改成什么样”。

这篇手册把我从入门、配置到高级自动化沉淀下来的完整用法做一个梳理。它不是官方文档的复读,而是我这几个月真实跑项目、踩坑之后留下的实践笔记。适合所有想在终端里把AI当“真同事”用的人,无论是刚接触CLI的新人,还是已经对Agent类工具有一定经验的开发者,都能从中找到能直接落地的操作。

1. 为什么把AI从浏览器搬进终端

1.1 它更接近一个“能干活的人”

网页AI解决的是“生成方案”,Claude Code解决的是“执行方案”。它运行在本地终端里,本质上是一个带着自然语言理解能力的命令行智能体,能够串联完成文件读取、代码搜索、命令执行、结果阅读、再次修改这一整条闭环路径。你不需要把问题拆成一系列shell命令,只需要用一句人话描述目标,它会自己规划步骤。

我刚开始使用时最不适应的一点,就是它真的会动手改文件。第一次让它“修复一个类型错误”时,它先定位到文件,再用编辑工具改掉问题点,然后运行测试验证,整个过程我都没动键盘。这和“复制一段代码去网页里问”是完全不同的协作关系。

1.2 最适合哪些场景

高频场景我总结下来有这么几类:

  • 探索历史遗留代码:对不熟悉的工程,让它解释模块结构、梳理调用链、标注可疑点。
  • 批量机械修改:统一改命名、补缺失的导出、批量加日志,这种工作人做容易漏,AI适合兜底。
  • 补测试和文档:生成单测骨架、补注释、写变更记录,只需要喂给它模块入口。
  • 修复Bug:描述现象,让它从错误栈反查代码,而不是自己逐文件翻。
  • 执行多步骤的工程任务:比如“把某个功能从A模块迁移到B模块,并保持对外接口不变”。

不太适合的场景也有。涉及不可逆的大规模变更,最好先让AI只生成计划,人工确认后再执行;涉及业务上“必须按特定规则”的改动,如果规则没有写在文档里,AI容易按常识处理,翻车概率不低。

1.3 和网页对话的差距在哪里

我用一张表说明两者差别,更直观一些:

能力网页AIClaude Code
读取当前文件需要手动粘贴直接读取
搜索整个工程代码不支持支持内容检索和文件遍历
执行构建、测试命令只给文本建议可以执行并继续处理输出
修改文件需要你手动应用直接落盘,并可查看差异
连续处理长任务上下文容易断会按步骤推进,衔接中间结果
感知git状态无能知道当前分支和变更文件

选择它并不是说网页AI不再有用,而是在“真正要写下代码”的时候,终端这个形态天然离工作现场更近。

2. 五步上手:安装、登录与第一次对话

2.1 第一步:准备好终端环境

Claude Code本质是一个Node命令行应用,所以本机需要先有Node运行环境,并确保npm命令可用。安装前在终端里确认一下:

node -v npm -v

如果两条命令都能正常输出版本号,说明环境就绪。Windows用户建议使用系统自带的现代终端,而不是老的命令提示符窗口,否则中文输出和快捷键都可能遇到一些小问题。

2.2 第二步:全局安装官方CLI包

通过npm把CLI安装到全局环境,命令如下:

npm install -g @anthropic-ai/claude-code

安装完成后,验证是否成功:

claude --version

能看到版本号就说明装好了。如果提示命令找不到,多半是npm全局bin目录没有加入PATH,重新打开终端窗口,或者检查环境变量配置即可。

2.3 第三步:登录与授权

第一次运行claude命令时,它会引导你完成登录认证。这里需要你有一个可用的账号,并按终端提示完成浏览器或验证码授权流程。认证通过后,凭证会保存在本地配置目录,后续使用不需要重复登录。

有一点容易忽略:这个工具的运行权限是你的身份凭证,相当于把你的终端权限交给了AI。因此不要在无法信任的设备上直接登录,也不要随意共享终端会话。

2.4 第四步:用三种方式启动会话

日常使用中最常接触的是交互式会话:

claude

进入后你会看到一个命令行对话界面,可以连续输入指令,它会逐步执行并回显结果。

如果你只想执行一个一次性任务,不需要留在交互界面,可以用非交互模式:

claude -p "请解释当前目录的代码结构"

还能通过管道把内容喂给它:

cat main.py | claude -p "帮我校正这个脚本里的命名"

第三种是继续上一次会话。中断后重新进入时加--continue参数,可以接着刚才的话题继续讨论:

claude --continue

2.5 第五步:第一条指令与基本交互

第一次对话建议从轻量任务开始,比如让它“先看看这个项目里有哪些模块”。它会列出目录结构和关键文件,并解释项目用途。这时候你能直观感受到它读取数据的节奏。

交互界面里还有一些常用操作:

  • 按Esc中断当前正在执行的任务
  • 用/help查看内置命令
  • 用/compact压缩当前对话的上下文
  • 用/clear清空会话记录,重新开始

这些按键和指令会在后面长期使用,建议刚上手时就记下来。

3. 记忆系统:CLAUDE.md就是给AI的工作交接文档

3.1 三个层级的记忆存放位置

用过一段时间你会发现,AI虽然聪明,但从零开始理解一个项目还是要消耗大量上下文。所以Claude Code引入了记忆文件机制,用一个Markdown文件来告诉它“这个项目是什么、常用的命令是什么、有哪些约束”。这个文件是灵魂配置,开局一定要写。

记忆文件分三个层级:

  • 全局记忆:存放在~/.claude/CLAUDE.md,对所有项目生效,适合写个人偏好、通用工作习惯。
  • 项目记忆:存放在项目根目录下的CLAUDE.md,对整个仓库生效,写项目说明、技术栈、命令。
  • 目录记忆:存放在某个子目录下的CLAUDE.md,只对这个子目录及以下层级生效,适合写模块级说明。

项目启动后,它会自动加载这些文件作为“先验知识”,相当于入职培训资料。你在对话开头完全不用解释“这是个什么项目”,AI已经知道了。

3.2 一个合格的CLAUDE.md应该长什么样

写得太空没有价值,写得太长浪费上下文。我提供一个经过多次调整后比较通用的模板:

# 项目说明 这是一个面向企业客户的订单管理后台,提供订单录入、状态流转、报表导出三大核心能力。 ## 技术栈 - 语言:Python 3.11 - 框架:公司内部Web框架 - 数据库:MySQL,通过统一DAO层访问 ## 常用命令 - 启动开发服务:`python dev_server.py` - 运行测试:`pytest --tb=short` - 格式化代码:`black .` ## 工程约定 - 业务逻辑统一放在 `src/services`,不要在路由里写业务 - 异常处理统一使用 `BizException` - 数据库迁移脚本放在 `migrations` 目录,禁止手工改 ## 禁区 - 不要修改 `dist` 目录下由构建工具生成的产物 - 不要向代码库提交任何包含密钥的文件

关键是每一项都要有实际约束力,要写那些“如果AI不知道就会犯错”的信息。比如“禁止手工改迁移脚本”这类规则,正是AI最容易踩的不成文规定。

3.3 记忆文件也要维护和版本控制

CLAUDE.md不是写一次就完了。项目演进时,命令变了、目录结构调整了,都要同步更新。我习惯在每周迭代结束后顺手看一眼,把已经过时的描述替换掉。

版本控制方面,我建议把CLAUDE.md提交进仓库。这样所有协作者共享同一份“AI交接文档”,新成员拉取代码后,AI也能立刻了解项目。只提醒一点:里面千万不要写敏感信息,因为它是会被加载进上下文的普通文件,不是保险箱。

另外要澄清一个误区:CLAUDE.md不等于聊天记录。AI不能靠它回忆“上次会话里聊过的某个具体问题”,它提供的是稳定的项目背景。真正需要长期保存的决策、结论,应该落到文档或代码注释里,而不是只放在对话历史中。

4. 权限、settings与配置:让AI有手脚又有规矩

4.1 权限模式决定它能不能乱动

Claude Code可以执行任何命令,这既是强大之处,也是风险点。它默认会为关键操作请求确认,比如修改文件、执行shell命令。这个“唠叨”模式刚开始会觉得烦,但非常重要。

我建议的顺序是:头一周先用默认审批模式,感受一下它经常提出哪些请求,再决定要不要放开。等建立了足够信任,再通过配置文件把高频安全操作加入白名单。

权限控制通常靠permissions字段完成,支持精确匹配和规则匹配。举个例子:

{ "permissions": { "allow": [ "Bash(npm run test)", "Bash(black .)" ], "deny": [ "Bash(rm -rf *)", "Read(.env*)" ] } }

allow里的命令会自动执行不再询问,deny里的则一律拒绝。这种方式比“全部同意”或“全部拒绝”都高效得多。

4.2 settings.json的核心字段

配置主要通过.claude/settings.json完成,分为用户级(~/.claude/settings.json)和项目级(项目根的.claude/settings.json)。两者合并生效,项目级优先于用户级。

我常用的字段有:

  • permissions:权限规则,上面已经举例。
  • hooks:自动化钩子,下一章重点说。
  • env:给会话注入环境变量。
  • model:指定希望使用的对话模型,控制成本和速度。

一个项目级配置示例:

{ "model": "claude-code-small", "env": { "APP_ENV": "dev" }, "permissions": { "defaultMode": "acceptEdits" } }

注意,配置字段在不同版本会有调整。遇到“某个配置不生效”的情况,先检查是否为当前版本不支持的字段,再怀疑写法问题。

4.3 环境变量与敏感信息保护

很多CLI工具都会读取.env文件,Claude Code也一样。当它需要访问数据库或外部服务时,你可以通过env字段显式传入,而不是让它去读配置文件。

敏感信息保护是我最看重的一条。在settings.json里,我会把.env、密钥目录、证书文件通通加入deny规则:

{ "permissions": { "deny": [ "Read(.env)", "Read(**/*.pem)", "Read(secrets/**)" ] } }

就算AI在某个任务里触发了读取,也会被规则拦下,减少敏感信息进入上下文的可能。

4.4 多项目配置的继承与覆盖

如果同时维护多个项目,我通常把个人偏好写在用户级配置,把项目特定约束写在项目级配置。用户级里定义“所有项目都适用”的规则,项目级里补充只属于该项目的内容。实际运行时会叠加起来。

命令行参数优先级最高,可以临时覆盖配置里的一些行为。比如某次只想快速执行,不想让配置文件里的权限限制挡住,就在启动时显式声明。覆盖能力越强,越要小心,用完最好恢复默认。

5. hooks:在Claude行动的每个环节插一脚

5.1 像Git hooks一样理解它

Claude Code的hooks机制可以理解成“生命周期的监听器”。当AI执行到某个关键节点时,会自动调用你配置的外部脚本。这属于高级自动化里最有价值、也最容易被低估的部分。

先看它提供的几个主要时机:

事件名称触发时机典型用途
UserPromptSubmit用户提交新消息时输入检查、风险提示
PreToolUse工具执行前拦截危险命令、补参数
PostToolUse工具执行后格式化、校验、清理
Stop一轮任务结束时通知、记录、自动提交
Notification需要提醒用户时推送消息到手机或桌面
SubagentStop子代理结束时汇总子代理结果

hooks的配置写在settings.json里,每个事件可以配置一个或多个命令。

5.2 实际跑通的例子:修改代码后自动格式化

我最早接触hooks就是为了解决“AI改完代码风格不统一”的问题。每次代码被修改后,自动调用格式化工具,就不需要事后专门清理。

在.claude/settings.json里配置:

{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "black $CLAUDE_FILE_PATHS" } ] } ] } }

含义是:当AI使用编辑类工具写文件后,把被修改的文件路径传给black做格式化。matcher用来限定只对匹配的工具触发,避免每次读文件都跑脚本,浪费资源。

5.3 用hooks做一个任务完成通知

当任务跨窗口执行时,我可能切到别的终端干别的,等它跑完需要主动通知。Stop事件就可以帮上忙。

配置如下:

{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "notify-send \"Claude Code\" \"任务完成,可以回来看结果了\"" } ] } ] } }

Linux桌面环境用notify-send,macOS可以换成osascript弹通知。配合长任务使用,体验接近“有个同事干完活会喊你一声”。

5.4 排查hooks不生效的问题

hooks不触发是最常见的问题。我的排查顺序是:

  1. 先确认配置文件的路径对不对,项目级应该放在.claude/settings.json,不是CLAUDE.md。
  2. 确认事件名称拼写是否准确,官方版本差异会导致事件名不同。
  3. 单独在终端运行一次hook命令,排除脚本本身的语法错误。
  4. 看日志,CLI会在调试输出中打印hooks的执行情况,加上全局参数可以打印出更详细的信息。

调试过几轮就会发现,绝大多数问题出在路径和权限上,脚本本身反而很少出幺蛾子。

6. 子代理:一次会话里多个专岗助手并行

6.1 为什么需要独立的子代理

当任务变复杂,比如“重构模块并补上测试,同时做一次安全审查”,把所有要求堆给主对话,容易让主线任务被细碎问题干扰。子代理(subagents)就是为此设计的:它可以在项目里定义一组带独立职责的专家代理,主Claude在需要时按描述自动调用它们。

每个子代理有自己的系统提示和职责边界,因此它的上下文更干净,判断更聚焦。这很像给团队里安排专门做测试、专门做大促活动页的人,各管一摊。

6.2 用Markdown定义一个代码审查代理

子代理的定义放在.claude/agents/目录,每个代理对应一个Markdown文件,文件名就是代理名称。

建一个code-reviewer.md:

--- name: code-reviewer description: 审查代码变更,发现潜在的Bug、安全问题和不规范命名。适合在代码改动之后调用。 tools: Read, Grep, Glob, Bash --- 你是一名严格的代码审查专家。你会从以下维度审查代码变更: - 正确性:是否存在边界情况未处理。 - 安全性:是否存在注入、敏感信息泄露风险。 - 可读性:命名是否清晰,函数是否过长。 输出格式: 1. 问题清单,按严重程度排序。 2. 每条问题给出文件路径和建议改法。 3. 没有问题就明确说“没有发现严重问题”。

配置里比较重要的是description,主Claude靠它判断什么时候该调用这个子代理。描述写得越精准,越能命中场景。

6.3 主代理与子代理的协作方式

在主对话中,我通常这样使用子代理:让主Claude完成重构后,直接补充“调用code-reviewer检查刚才的改动”。也可以在主任务描述里就点明“完成后运行代码审查”,它会在合适的时机自动拉起子代理。

子代理结束后,主Claude会收到摘要并整合到主流程中。任务被拆成一段段专业工作,主线不会变乱。我在几个稍微大些的模块改造中试过,子代理模式下的结果比单线程对话更可控,问题发现率也更高。

需要注意的一点是,每个子代理都在消耗上下文和计算资源。一个会话里拉起太多子代理,反而会拖慢速度。合理的做法是限制子代理的tools,只给它必要的工具,减少不必要的尝试。

7. MCP:为Claude装上接入外部系统的“USB口”

7.1 模型上下文协议到底解决了什么

MCP(Model Context Protocol)可以理解为AI与外部数据源、工具之间的标准通信协议。如果说Claude本身是大脑,那么MCP就是外接接口,让它可以读取公司内部数据库、调用自有API、操作专用工具。

没有MCP时,AI只能靠命令行和文件系统间接摸到数据;有MCP之后,它可以直接调用一个标准化的服务接口,拿到结构化数据。类比一下:过去你要让AI读一份数据库报告,得先让它跑sql把结果导出成CSV再读取;现在只需要一个MCP数据源服务,AI直接查询,结果即时可用。

7.2 配置一个MCP服务器

MCP服务通常在项目根目录的.mcp.json里配置。下面是一个本地数据服务的示例:

{ "mcpServers": { "issue-service": { "command": "node", "args": ["mcp-servers/issue-service.js"], "env": { "API_BASE": "http://localhost:7000" } } } }

配置好并重启会话后,AI就能看到这个服务暴露的工具列表,并在合适的任务中调用。整个过程不需要写复杂的胶水代码,服务端遵守MCP规范即可。

7.3 一个比较稳妥的接入方向

MCP的接入范围非常广,文件系统、数据库、消息队列、监控系统都可以接。我的建议是从“只读数据源”开始,比如让AI能够查询项目里的Issue列表、读取某个服务的实时监控指标。只读服务风险低,又能立刻看到价值。

等熟悉协议之后,再考虑接入写操作,比如通过MCP创建工单、发消息。写操作前,最好在服务端做一层权限校验,而不是完全信任AI的调用。毕竟再聪明的模型,也可能在错误判断下发出一个不该发的写请求。MCP让AI手脚变长,但长出来的手脚也需要缰绳。

8. 实战复盘:让Claude Code重构一个历史遗留模块

8.1 任务背景

我用一个模拟项目讲述一次比较完整的实战过程。某后台服务里有一个历史订单模块,文件结构混乱,一个入口文件积累了上千行,循环import严重,测试覆盖率不到两成。改造目标:把这个模块按职责拆成多个小文件,保持对外接口不变。

8.2 我给出的第一段指令

我没有在开始就让它直接动手,而是先输入了下面这段话:

先不要修改任何文件。我需要你分析 src/legacy_order 这个目录: 1. 梳理出模块的职责边界,哪些逻辑是订单状态流转,哪些是计算价格,哪些是数据访问。 2. 找出明显的问题点,比如重复工具函数、不合理的循环引用。 3. 给出一个迁移计划,标注每个步骤的依赖关系。 这份计划我确认之前,不要改代码。

这个开头非常关键:它把“AI当执行者”变成了“AI当参谋”。先产出计划,确保方向一致后再动手。

8.3 它的执行过程

AI读取了目录下所有相关文件,生成了结构分析。它指出价格计算逻辑散落在一个大函数里,没有独立成模块;状态流转依赖隐式字符串常量,没有常亮定义。随后给出了三步拆分计划。

我确认计划后,切换指令:

按计划的第一步执行:拆分价格计算逻辑。保持对外接口不变,完成后运行测试并报告结果。

紧接着,它创建新文件、迁移函数、更新import、搜索旧引用,逐一替换,然后运行测试。第一次测试有两个用例失败,原因是迁移时漏了一个默认参数。AI从报错栈反查到自己改动的逻辑,补上了默认值,再次运行后全量通过。

8.4 中途遇到的几个麻烦

第一个麻烦是高危命令被权限拦下。它想执行一个包含清理临时目录的命令,被deny规则直接拒绝。解决办法是在allow列表里补充精确到具体目录的命令,而不是粗暴地放开整个bash权限。

第二个问题是上下文长度在任务中段开始报警。代码搜索和测试输出占据了大量上下文。我用/compact压缩历史,并在后续步骤里让它“只输出摘要,不要打印完整文件内容”,顺利解决了。

第三个问题是它差点动了一个不该动的公共函数签名。因为项目CLAUDE.md里写了“公共函数签名如需修改必须单独评审”,规则生效,它没有强行改,只是把这个风险点标注出来交给了人工确认。这让我意识到,CLAUDE.md里每一行规则,都是给AI的一根边界线。

8.5 这个案例给我的判断

最终这个拆分任务在半天内完成。如果纯人工处理,按我平时速度大概需要两三天起步。最值得肯定的不是它写代码多快,而是整个过程从分析、计划、执行到反馈闭环了,中间不需要我反复粘贴文件内容。

当然也有局限。那些“只可意会”的领域知识,比如某个模块为什么设计成那样、哪个历史决策不能动,AI无法从代码里自动推断。这些信息必须由人写进CLAUDE.md,或者由我在每个阶段显式告知。没有规则的项目里,AI会按照通用最佳实践给你方案,但未必符合你的实际情况。

9. 高频问题排查与我的防呆习惯

9.1 最常见的几个问题对照

现象可能原因处理方式
终端提示命令找不到安装未生效或PATH未更新重开终端,确认npm全局目录在PATH中
登录后马上退出会话网络无法连接官方服务端点检查本机网络连通情况,确认服务可达后再重试
AI不停询问权限默认审批模式未配置allow规则在settings.json中补充精确allow项
配置文件没生效路径写错或字段名不匹配版本核对官方字段说明和配置路径
上下文越用越卡对话历史过长使用/compact或在长任务中要求短输出
hook始终不触发事件名或配置文件路径错误单独运行hook命令,开启调试模式查看日志
输出乱码终端不支持UTF-8切换终端编码为UTF-8重建会话
修改前没问就动了代码permissions设置了acceptEdits如果不想这样,改回询问模式或限制编辑工具

9.2 我的防呆使用基线

在给别人的团队做工具引入时,我经常分享下面几条习惯,都是在实战中沉淀出来而不是看文档得到的:

  1. 改动前先要计划。任何超过一个文件的任务,先让它输出计划,确认再执行。
  2. 高频命令精确白名单,而不是无脑全部允许。
  3. 敏感文件永远deny。不管什么任务,不给AI读密钥的机会。
  4. 定期使用清理会话。上下文过载时不硬撑,压缩或重建会话都行。
  5. 版本控制是你的退路。让AI改代码之前确保分支干净,出了事用git恢复能力兜底。

最后再分享一个小技巧:每次启动大任务前,我会先输入“这份任务完成后,请用一句话汇总改动范围和遗留风险”,让它在结尾强制输出一个简短交接总结。这样即使会话断了,我也能从最后几行字快速接上状态。这个小习惯省了我很多次翻历史记录的力气,比任何复杂配置都管用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 12:33:57

VLAN划分实战:从广播域隔离到交换机配置与故障排查

网络卡顿这事儿,十有八九不是带宽不够,而是网络架构偷懒了。之前我处理过一家做外贸公司的网络问题:新办公室搬完,两百多台设备全挤在一个二层大广播域里,打开抓包软件一看,ARP广播每秒好几百条&#xff0c…

作者头像 李华
网站建设 2026/10/16 12:33:49

Delphi VCL报表导出:eDocEngine源码编译与PDF生成实战

简介:Gnostice eDocEngine VCL Pro 5.0.0.95 是面向 Delphi 开发者的全源码文档处理组件,专为 Tokyo 10.2 环境优化,可在 VCL 应用中创建、编辑并转换 PDF、HTML、RTF、Text 等格式,适合组件定制或文档自动化需求的中高级工程师。…

作者头像 李华
网站建设 2026/10/16 12:33:12

Python停车计费系统实战:时间切片、免费时长扣除与夜间半价叠加

简介:本资源是2021年第十二届蓝桥杯嵌入式设计与开发组(第一场)真题——停车计费系统的完整工程实现,面向STM32嵌入式初学者、竞赛备赛学生及求职中的IT技术岗候选人。项目基于STM32G4系列MCU,完整覆盖车辆进出识别、时…

作者头像 李华
网站建设 2026/10/16 12:32:18

Python开发者必会的Linux命令实战指南:从排查到自动化

很多Python程序员第一次觉得“电脑不够用”,往往不是在写代码的时候,而是在部署和排查问题的时候。我见过不少能把业务逻辑写得非常漂亮的人,遇到“脚本在服务器上跑了一晚上,早上发现数据一条都没入库”这种问题只能干瞪眼——代…

作者头像 李华
网站建设 2026/10/16 12:31:10

Debian内核升级实战:initramfs与grub引导链完整解析

1. 把新内核变成默认启动项,到底难在哪里 前阵子帮人排查一台业务机器,uname -r 显示 5.10,但 /boot 目录里明明躺着一个编译好的 5.15 内核,grub 菜单里也看得见,可重启之后就是进不去新内核。查了半天,问…

作者头像 李华
网站建设 2026/10/16 12:30:28

基于SSM和Vue的城市公交查询系统毕设完整开发指南

前几天,一个学弟发消息问我:2026年毕业设计想做个公交查询系统,题目写的是“基于SSM和Vue的城市公交查询系统,论文加程序”,可题目拿到手之后整个人是懵的,不知道这个系统到底要从哪里开始做,论…

作者头像 李华