项目整体回顾
第一层:项目概览与环境准备
问: 我们做的到底是个什么东西?它是怎么工作的?
答: 我们做的叫「静态博客」。它由一系列已经生成好的HTML、CSS、JS文件组成,当用户访问时,服务器直接把这些文件发给浏览器,浏览器解析渲染成页面。没有数据库,没有服务端动态计算,所以加载快、安全、部署简单。
问: 为什么需要Node.js和npm?它们分别干什么?
答: 这个项目里的所有工具(Hexo、插件等)都是用JavaScript写的,而JavaScript需要在Node.js这个运行环境里才能执行。npm是Node.js的包管理器,用来下载和管理这些工具和依赖库。
问: Git和GitHub在项目中扮演什么角色?两者有什么区别?
答: Git是版本控制软件,能记录你对代码的所有修改。GitHub是一个网站,用来托管Git仓库,充当代码的远程备份和协作平台。我们用Git将代码推送到GitHub,然后用它提供的GitHub Pages或Actions功能来部署。
问: YAML文件是干嘛的?为什么配置文件要用它?
答: YAML是一种数据序列化格式,用来写配置文件(比如_config.yml)。它的特点是缩进表示层级,可读性非常好,适合人类手写和阅读。程序读取这个文件就能获得配置参数。
问: Markdown是编程语言吗?它和HTML什么关系?
答: Markdown是轻量级标记语言,不是编程语言。它设计的目的是易读易写,让你专注于内容。Hexo会把它转换成包含正确样式的HTML文件,这个过程叫渲染。
第二层:本地开发与预览
问: hexo init、hexo generate、hexo server这几个命令具体做了什么?
答:
hexo init:初始化一个博客骨架,帮你建好所有目录和必要的配置文件。hexo generate:构建命令,它读取你的所有Markdown文章和配置,生成整个网站的静态HTML文件,存放到public文件夹里。hexo server:启动一个本地开发服务器,让你在http://localhost:4000预览网站,方便调试。
第三层:虚拟化与Linux基础
问: 虚拟机是什么?我们为什么需要它,而不是直接在Windows上装Linux?
答: 虚拟机是用软件模拟的一台完整电脑,可以安装独立的操作系统。我们需要它来搭建一个纯净的Linux学习环境,模拟真实的云服务器,并且方便通过克隆创建多台机器,而不影响你自己的主机系统。
问: 虚拟机的NAT和Host-Only网络模式是什么意思?为什么需要双网卡?
答:
- NAT模式:虚拟机通过宿主机上网,相当于躲在宿主机后面,外部网络无法直接访问它。我们用来让虚拟机安装软件。
- Host-Only模式:宿主机和虚拟机之间建立一个独立的内部网络,和外部隔离。我们用来实现虚拟机之间互相通信。
- 双网卡:就是为了让虚拟机既能安装软件(走NAT),又能相互访问(走Host-Only)。
问: Linux里的sudo和root是什么?为什么很多命令前要加它?
答: root是Linux里的超级管理员,拥有最高权限。sudo是让普通用户临时以root身份执行后面的命令,用来安装软件、修改系统配置等。加它是为了获取执行所需的高权限。
第四层:远程管理与部署
问: SSH是什么?它解决了什么问题?
答: SSH是一种加密网络协议,用来在不安全的网络上安全地远程登录和执行命令。它解决了明文传输密码的风险,让你能安全地控制远端的Linux服务器(比如我们的node2)。
问: SSH密钥认证比密码认证好在哪里?我们生成的公钥和私钥分别是什么?
答: 密钥认证更安全(破解难度极大),也更方便(可免密登录)。它使用一对密钥:公钥(锁)放在你想登录的服务器(如node2)上,私钥(钥匙)由你保管(在node1上)。登录时,服务器用公钥验证你手里的私钥,配对成功就放行。
问: scp和rsync都是传文件,有什么区别?
答: scp是简单复制,每次都会把指定文件全部传一遍。rsync是增量同步,它会比较源和目标的差异,只传输有变化的部分,所以效率更高,尤其适合频繁同步整个文件夹。
第五层:Web服务器与部署上线
问: Nginx是一个什么软件?在我们项目中扮演什么角色?
答: Nginx是一个高性能的Web服务器。在我们项目中,它扮演的角色是 “文件服务员” ,监听80端口,接收浏览器请求,然后从/var/www/blog目录里找到对应的HTML文件返回给浏览器,让我们的博客能被访问到。
问: GitHub Actions是什么?它怎么让我们实现”自动化”的?
答: GitHub Actions是GitHub提供的CI/CD(持续集成/部署)平台。它让你可以定义一套自动化流程(比如:当git push发生时,自动检出代码、安装依赖、构建网站、推送到Pages仓库)。我们把部署步骤写成.yml文件提交,之后的每次推送都由它自动执行。
问: 这套”自动部署”流程的具体步骤是什么?
答: 自动部署流程核心是.github/workflows/deploy.yml文件定义的:
- 触发:你
git push到my-blog01仓库。 - 运行环境:GitHub启动一台临时Ubuntu服务器。
- 检出代码:把你的源码下载到临时服务器。
- 安装依赖:执行
npm install安装Hexo等依赖。 - 构建网站:执行
hexo generate生成public文件夹。 - 部署:将
public文件夹内容推送到tristan1116.github.io仓库。
问: 什么是CI/CD?这个概念在我们项目里怎么体现的?
答: CI(持续集成)和CD(持续部署)是自动化开发和上线的理念。在项目里,你每次推送代码都是一个 “集成” 动作,之后GitHub Actions自动执行构建、测试、部署这一整套流程,就是持续集成与持续部署的实现。
项目总览与概念全景图
问: 现在你能用一句话总结,这个博客项目到底是怎么运作的吗?
答: 这个项目是我在本地用 Markdown 写文章,Hexo 将文章和主题渲染成静态HTML网站,然后通过 Git 和 GitHub Actions 自动部署到公网(GitHub Pages),同时通过 SSH 和 rsync 手动部署到内网的 Nginx 服务器上。
问: 整个项目涉及的所有核心技术,能按层级总结一下吗?
答:
- 开发层:
Markdown、YAML、VS Code - 应用层:
Node.js、npm、Hexo - 版本控制层:
Git、GitHub - 操作系统层:
Linux(Ubuntu)、命令行(bash) - 网络与服务层:
SSH、SCP、rsync、Nginx - 虚拟化层:
VirtualBox、虚拟机网络(NAT/Host-Only) - 自动化运维层:
CI/CD、GitHub Actions、Webhook - 托管与部署层:
GitHub Pages、云服务器概念、内网静态服务器
问题深究
问题一:HTML、CSS、JS文件;前端后端
一、HTML、CSS、JS 到底是什么?
它们不是数据,而是构成网页的三种核心代码,各司其职。
| 文件类型 | 通俗理解 | 它在做的事 | 你项目中的例子 |
|---|---|---|---|
| HTML | 网页的骨架和内容 | 负责“有什么内容”。比如标题、段落、图片、链接。 | Hexo 生成的 .html 文件 |
| CSS | 网页的衣服和样式 | 负责“长什么样”。比如字体、颜色、间距、布局。 | 主题里的 .css 文件(如 main.css) |
| JS | 网页的大脑和动作 | 负责“能做什么事”。比如点击按钮弹出菜单、搜索功能。 | 主题里的 .js 文件(如 search.js) |
在你的项目里,Hexo 把 Markdown 内容填充进主题模板,最后生成的就是这三种文件的组合,交付给浏览器。浏览器拿到它们,解析、渲染,就变成了你看到的漂亮页面。
二、它们是前端项目需要的数据吗?
不完全是。 更准确地说,它们是构建用户界面的代码。
我们对比一下就容易理解了:
| 概念 | 作用 | 例子 |
|---|---|---|
| HTML/CSS/JS | 界面代码。定义“如何展示”和“如何交互”。 | 一个按钮的样式、点击后的搜索逻辑。 |
| 数据 | 内容本身。定义“展示什么”。 | 一篇博客的标题、正文、作者、发布时间。 |
数据通常以 JSON、XML 或数据库记录的形式存在。在你的项目中,Markdown 文件就是数据,它记录了文章内容;而 Hexo 这个工具,就是负责把 Markdown 数据和 HTML/CSS/JS 模板结合起来,生成最终的网页文件。
三、与之相对的有哪些?
与之相对的,通常指后端技术。我们可以从几个维度来理解“相对”:
| 对比维度 | 前端(你问的这部分) | 后端(与之相对) |
|---|---|---|
| 运行位置 | 浏览器(用户端) | 服务器(云端) |
| 主要语言 | HTML, CSS, JavaScript | Python, Java, Go, PHP, Node.js |
| 核心任务 | 负责展示和交互(用户看得见) | 负责业务逻辑和数据(用户看不见) |
| 典型功能 | 点击按钮、页面跳转、动画 | 用户登录验证、读取数据库、处理支付 |
| 你的项目 | 你访问的博客页面(全静态) | 几乎没有。但如果你用云服务器部署,后端就是 Nginx |
基于这个分类,一个完整的网站应用通常会分为:
- 前端(客户端):你写的 HTML/CSS/JS 代码。
- 后端(服务器端):提供数据的 API 接口或生成页面的程序。
- 数据库:真正存储数据的地方(如用户信息、文章内容)。
四、举一反三:知识拓展
从问题出发,可以衍生出两个重要的概念:
1. 静态网页 vs 动态网页
- 静态网页:服务器上存着现成的
.html文件,用户请求什么就发什么。你现在的博客就是完全静态的。 - 动态网页:服务器上没有现成的
.html,用户请求时,后端程序(如 PHP、Python)实时从数据库读取数据,临时拼装出一个.html返回。
2. 数据格式:JSON
如果后端要向前端提供数据,它们最常用的语言就是 JSON(JavaScript Object Notation)。它轻量、易读,是目前 Web API 的事实标准。以后你学后端,打交道最多的就是它。
总结一下:HTML/CSS/JS 是构成页面的界面代码,不是数据。在开发领域,它们属于前端,与之相对的通常是处理逻辑和数据的后端。你目前的项目是一个纯前端 + 静态生成的博客。
问题二:JavaScipt,Java,运行环境,包管理器
一、JavaScript 是一种什么样的语言?
JavaScript 是一种轻量级的、解释型的、基于对象和事件驱动的脚本语言。
把它拆开看:
| 特性 | 含义 |
|---|---|
| 轻量级 | 语法相对简单,上手快,运行时开销小 |
| 解释型 | 不需要先编译成机器码,而是由解释器逐行执行 |
| 基于对象 | 可以操作对象(如 document、window),但不是严格的面向对象语言 |
| 事件驱动 | 可以响应用户操作,比如点击、滚动、键盘输入 |
在你项目里,JavaScript 主要负责:
- 本地搜索:当你在博客里输入关键词,JS 会实时过滤文章列表
- 页面交互:比如点击“回到顶部”、滚动加载动画等
二、JavaScript 和 Java 的区别
一句话:它们是两种完全不同的语言,关系就像“汉堡”和“汉堡包”一样——名字像,但本质不同。
| 对比维度 | Java | JavaScript |
|---|---|---|
| 出身 | Sun 公司(1995年) | Netscape 公司(1995年) |
| 类型 | 编译型 + 静态类型 | 解释型 + 动态类型 |
| 运行方式 | 先编译成字节码,再在 JVM 上运行 | 直接在浏览器或 Node.js 中解释执行 |
| 主要用途 | 企业级后端、Android 开发 | Web 前端、服务端(Node.js)、脚本工具 |
| 典型场景 | 银行系统、电商后台 | 网页交互、API 服务、自动化脚本 |
通俗比喻:
- Java 像一个大型建筑公司:严谨、规范、项目大
- JavaScript 像一个灵活的街头艺人:上手快、适应性强、能即兴表演
三、运行环境是什么?为什么需要运行环境?
运行环境 是指执行代码所需的所有基础设施,包括解释器、内存管理、API 接口等。
JavaScript 有两种主流运行环境:
| 运行环境 | 谁提供的 | 主要用途 |
|---|---|---|
| 浏览器 | Chrome、Firefox、Edge 等 | 让前端 JS 操作 DOM、响应用户事件 |
| Node.js | 基于 Chrome V8 引擎 | 让 JS 读写文件、启动服务器、执行命令行工具 |
为什么需要运行环境?
因为 JavaScript 本身只是一个语法规范,它不能自己做事。它需要依赖运行环境提供的 API 才能发挥功能:
| API 类型 | 谁提供的 | 举例 |
|---|---|---|
| 浏览器 API | 浏览器运行环境 | document.getElementById()(操作网页元素) fetch()(发送网络请求) |
| Node.js API | Node.js 运行环境 | fs.readFile()(读文件) http.createServer()(启动服务器) |
在你的项目里:
hexo generate命令依赖 Node.js 运行环境,因为 Hexo 是用 JS 写的- 你写 Markdown 时预览的页面,依赖 浏览器运行环境,因为页面交互需要浏览器中的 JS
四、包管理器是什么?为什么需要包管理器?
包管理器 是一个工具,用于自动下载、安装、更新、卸载项目依赖的第三方代码库。
| 包管理器 | 对应语言/平台 |
|---|---|
| npm | Node.js / JavaScript |
| pip | Python |
| Maven / Gradle | Java |
| gem | Ruby |
为什么需要包管理器?
想象一下:如果没有包管理器,你要怎么做?
- 去 Hexo 官网下载源码
- 手动下载它的每个依赖
- 再下载每个依赖的依赖……(依赖地狱)
- 把这些文件一个个复制到项目里
- 还要处理版本冲突
这几乎是不可能的任务。
包管理器解决了这些问题:
| 功能 | 说明 |
|---|---|
| 自动解析依赖 | 你只需要写 "hexo": "^7.0.0",npm 会自动下载它需要的所有依赖 |
| 版本管理 | 通过 package.json 和 package-lock.json 锁定版本,确保每次安装一致 |
| 一键安装 | npm install 就能装完所有依赖 |
| 发布与共享 | 你写好的插件也可以发布到 npm 上,让别人使用 |
在你的项目里:
bash
1 | npm install hexo --save |
npm:包管理器install:安装命令hexo:包名--save:把依赖写入package.json,下次别人npm install时自动安装
举一反三:知识拓展
| 问题 | 答案 |
|---|---|
| JavaScript 和 TypeScript 什么关系? | TypeScript 是 JavaScript 的超集,加了类型系统,能提前发现错误,但最终要编译成 JS 运行。 |
| Node.js 和 浏览器 JS 有什么区别? | 浏览器 JS 有 window、document,但没有文件系统;Node.js 有 fs 文件系统模块,但没有 DOM 操作。 |
package.json 和 package-lock.json 有什么区别? |
package.json 记录依赖范围(如 ^7.0.0);package-lock.json 记录精确版本,确保每次安装完全相同。 |
| 为什么 Hexo 能用 npm 安装? | 因为 Hexo 是一个 Node.js 包,发布在 npm 上。npm install -g hexo-cli 把它下载到全局,并提供了 hexo 命令。 |
问题三:Hexo,Node.js;现代Web开发;
一、从最底层开始:JavaScript 和运行环境
先明确一个根本事实:JavaScript 本身只是一套语法规则,它不能自己运行。它需要一个“容器”来执行它,这个容器就是运行环境。
| 运行环境 | 作用 | 类比 |
|---|---|---|
| 浏览器 | 执行前端 JS,操作 DOM,响应用户事件 | 像一个舞台,让 JS 表演“交互” |
| Node.js | 执行后端 JS,读写文件,启动服务器 | 像一个工坊,让 JS 做“工具”能做的工作 |
你的项目里,Hexo 就是在 Node.js 这个工坊里运行的。
关系链: JavaScript 语言 → 需要运行环境(Node.js/浏览器)→ 才能执行具体任务
二、Hexo 的本质是什么?
Hexo 的本质是一个“静态站点生成器”(Static Site Generator,SSG)。
它的工作流程是:
- 输入:读取你的 Markdown 文章 + 主题模板 + 配置文件
- 处理:在 Node.js 环境中,把 Markdown 转换成 HTML,把数据填充进模板
- 输出:生成一套完整的 HTML/CSS/JS 文件(也就是你的博客)
所以,Hexo 是一个运行在 Node.js 上的“构建工具”,它把“内容+模板”编译成“静态网页”。
三、现代 Web 开发的完整流程(串联所有概念)
现在我们把所有概念放进一个完整的 Web 开发流程里,你可以看到每一步用到什么、为什么需要它。
阶段一:开发阶段 —— 你在本地写代码
| 步骤 | 你在做什么 | 用到的工具/概念 | 为什么需要 |
|---|---|---|---|
| 1. 写内容 | 用 Markdown 写文章 | Markdown(轻量级标记语言) | 让你专注于内容,而不是排版 |
| 2. 配置站点 | 修改 _config.yml |
YAML(配置文件格式) | 结构化配置,易读易写 |
| 3. 安装依赖 | npm install hexo |
npm(包管理器) Node.js(运行环境) | 自动下载 Hexo 及其依赖,无需手动处理 |
| 4. 本地预览 | hexo server |
Hexo(静态站点生成器) Node.js(执行 Hexo) 浏览器(预览页面) | 在本地生成并预览网站,便于调试 |
| 5. 版本控制 | git add / git commit |
Git(版本控制工具) | 记录每一次修改,方便回溯和协作 |
| 6. 同步远程 | git push |
GitHub(远程仓库托管平台) | 备份代码,触发自动部署 |
这一步的关键理解:
- Markdown 是你的数据(文章内容)
- YAML 是你的配置(站点参数)
- Hexo + Node.js 是你的构建工具链
- Git + GitHub 是你的版本控制与备份系统
阶段二:自动化部署 —— 代码推送到 GitHub 后发生的事
| 步骤 | 谁在做 | 用到的工具/概念 | 为什么需要 |
|---|---|---|---|
| 1. 触发 | GitHub 检测到 git push |
Webhook(事件触发机制) | 自动启动部署流程 |
| 2. 构建环境 | GitHub Actions 启动临时虚拟机 | CI/CD(持续集成/部署) Ubuntu(Linux 环境) | 在一个干净的环境里执行构建 |
| 3. 安装依赖 | Actions 执行 npm install |
npm + Node.js | 在云端重新安装项目依赖 |
| 4. 生成网站 | Actions 执行 hexo generate |
Hexo | 在云端把 Markdown 编译成 HTML |
| 5. 部署网站 | Actions 推送到 username.github.io 仓库 |
Git GitHub Pages(静态托管服务) | 把生成的静态文件放到公网服务器上 |
| 6. 访问网站 | 用户访问 https://username.github.io |
浏览器(解析 HTML/CSS/JS) CDN(内容分发网络) | 全球用户都能快速访问你的网站 |
这一步的关键理解:
- CI/CD 不是某一个工具,而是一种理念:代码提交后自动完成构建和部署
- GitHub Actions 是这个理念的具体实现工具
- GitHub Pages 是一个静态文件托管服务,不需要你维护服务器
阶段三:运行阶段 —— 网站被访问时发生的事
| 步骤 | 谁在做 | 用到的工具/概念 | 为什么需要 |
|---|---|---|---|
| 1. 请求到达 | 用户在浏览器输入 URL | DNS(域名解析) HTTP/HTTPS(网络协议) | 把域名转换成 IP 地址,建立网络连接 |
| 2. 服务器响应 | GitHub Pages 服务器返回文件 | Nginx(Web 服务器) CDN(缓存加速) | 高效地返回 HTML/CSS/JS 文件 |
| 3. 浏览器渲染 | 浏览器解析文件 | HTML(结构) CSS(样式) JavaScript(交互) | 把代码渲染成用户看到的页面 |
| 4. 动态交互 | 用户点击、搜索 | JavaScript(交互逻辑) 浏览器 API(DOM 操作) | 让页面“活”起来,响应用户操作 |
四、全景图:所有概念的关系
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
五、回到问题:Hexo 和 Node.js 的本质
| 概念 | 本质 | 在整个流程中的位置 |
|---|---|---|
| Node.js | JavaScript 的运行环境,让 JS 能读写文件、启动服务器、执行命令 | 开发阶段:执行 Hexo 自动化阶段:执行构建命令 运行阶段:不直接参与 |
| Hexo | 静态站点生成器,把 Markdown + 模板 → 编译成 HTML | 开发阶段:本地预览 自动化阶段:云端构建网站 |
一句话总结:
Node.js 是“舞台”,Hexo 是“演员”。没有 Node.js,Hexo 无法运行;没有 Hexo,你的 Markdown 不会自动变成网页。
问题四:C/C++ 与 web开发
一、核心概念对比表:C/C++ vs Web开发(JavaScript/Node.js)
| 概念维度 | C/C++(传统桌面/系统开发) | Web开发(JavaScript/Node.js/前端) |
|---|---|---|
| 核心目标 | 编译成机器码,直接和操作系统、硬件打交道 | 编写脚本,由解释器执行,操作浏览器或服务器环境 |
| 代码运行方式 | 编译型:源代码 → 编译 → 链接 → 生成可执行文件(.exe)→ 运行 | 解释型:源代码 → 由解释器(浏览器或Node.js)逐行读取并执行 |
| 入口点 | 必须有 main() 函数,程序从这里开始 |
没有强制入口点;脚本从上到下依次执行;Node.js中可通过 module.exports 组织代码 |
| 内存管理 | 手动管理(malloc/free,new/delete),容易内存泄漏 |
自动垃圾回收(Garbage Collection),开发者不需要手动释放内存 |
| 类型系统 | 静态类型:变量类型在编译时必须确定(int a = 10;) |
动态类型:变量类型在运行时确定(let a = 10; a = "hello"; 合法) |
| 面向对象 | C是面向过程;C++支持面向对象(类、继承、多态) | 支持基于原型的面向对象(ES6后也支持 class 语法) |
| 标准库 | C标准库(stdio.h)、C++标准库(STL:vector、map、string) |
Node.js 标准库(fs、http、path)、浏览器 API(document、window) |
| 包管理器 | 没有统一的包管理器(CMake 管理构建,vcpkg/conan 管理库,但不是语言标配) | npm 是标配,几乎是现代 JavaScript 生态的核心 |
| 构建工具 | CMake、Makefile,用于编译链接多个源文件 | Webpack、Vite,用于打包前端资源;Hexo 本身就是一个构建工具 |
| 跨平台性 | 需要为不同平台重新编译 | JavaScript 源码可以在任何有解释器的平台上运行(浏览器、Node.js) |
| 并发模型 | 多线程(pthread、std::thread),共享内存 |
事件循环(Event Loop)+ 异步 I/O(async/await),单线程但非阻塞 |
| 错误处理 | 返回值(int)、异常(try/catch) |
异常(try/catch)、回调错误(err)、Promise 的 reject |
| 典型应用场景 | 操作系统、游戏引擎、嵌入式、数据库、高性能计算 | Web 网站、API 服务、命令行工具、自动化脚本、移动应用(React Native) |
| IDE与调试 | VS2022、CLion;编译时静态检查、GDB调试 | VS Code;浏览器DevTools、console.log、Node.js调试器 |
二、详细对比与解读
1. 运行方式:编译型 vs 解释型(最关键的区别)
C/C++ 的流程:
text
1 | 源代码 (.c/.cpp) → 预处理 → 编译 → 汇编 → 链接 → 可执行文件 (.exe/elf) → 操作系统加载运行 |
你按下“运行”按钮,编译器会把你的代码翻译成机器指令,生成一个独立的可执行文件。这个文件可以直接在操作系统上运行,不需要任何额外环境(除了系统库)。
Web开发的流程(以你的博客为例):
text
1 | JavaScript 源码 → (不需要编译) → Node.js 或浏览器解释器 → 逐行执行 |
代码不会被翻译成机器码,而是由解释器(比如 Chrome 的 V8 引擎)一边读一边执行。因此,Web 应用运行在“虚拟机”里,不能直接访问硬件,只能通过解释器提供的 API 操作环境(如浏览器 DOM、Node.js 文件系统)。
2. 内存管理:手动 vs 自动垃圾回收
| 方面 | C/C++ | JavaScript |
|---|---|---|
| 分配内存 | malloc、new |
使用对象、数组时自动分配 |
| 释放内存 | free、delete |
自动垃圾回收,开发者不可干预 |
| 常见问题 | 内存泄漏、野指针、重复释放 | 内存泄漏(闭包未释放)、GC 暂停导致卡顿 |
新手常见误区: 学 Web 开发时,你不需要关心内存的分配和释放,垃圾回收会自动帮你清理不再使用的变量和对象。你可以把精力更多地放在业务逻辑上。
3. 类型系统:静态类型 vs 动态类型
| 场景 | C/C++ | JavaScript |
|---|---|---|
| 变量声明 | int a = 10; |
let a = 10; 或 let a = "hello"; |
| 类型检查时机 | 编译时 | 运行时 |
| 优点 | 编译阶段就能发现类型错误,更安全 | 写起来快,更灵活 |
| 缺点 | 代码更啰嗦,类型约束强 | 运行时类型错误难以预测,需要更多测试 |
| 类型安全 | 强类型 | 弱类型("1" + 1 = "11") |
当前趋势: TypeScript 是 JavaScript 的超集,加入了类型系统,可以理解为“带有类型注解的 JavaScript”,编译时检查类型错误,正成为大型 Web 项目的标准。
4. 构建工具:CMake vs 你项目里的 Hexo
| 方面 | C/C++(CMake) | Hexo(你的项目) |
|---|---|---|
| 作用 | 管理多个源文件的编译、链接关系,生成可执行文件 | 把 Markdown 和配置“编译”成静态 HTML 网站 |
| 输入 | .cpp 和 .h 文件 |
Markdown 文章 + 主题模板 + _config.yml |
| 输出 | .exe 或 .elf 可执行文件 |
public/ 文件夹(HTML + CSS + JS) |
| 配置文件 | CMakeLists.txt |
_config.yml 和 package.json |
| 依赖管理 | find_package 查找系统库 |
npm install 安装 npm 包 |
类比理解: 你在 C/C++ 里用 CMake 把多个 .cpp 文件“编译”成一个 .exe;你在 Hexo 里用 hexo generate 把多篇 .md 文章“编译”成一个网站。两者都是构建工具,只是输入输出不同。
5. 并发模型:多线程 vs 事件循环
| 方面 | C/C++ | JavaScript/Node.js |
|---|---|---|
| 并发方式 | 多线程(pthread、std::thread) |
单线程 + 事件循环 + 异步 I/O |
| 同步/阻塞 | 默认同步阻塞,需要手动管理线程同步(互斥锁、条件变量) | 默认异步非阻塞(fs.readFile 不会阻塞主线程) |
| 处理并发 | 创建多个线程,每个线程处理一个任务 | 一个主线程,通过事件循环处理所有任务(如网络请求、文件读写) |
| 复杂度 | 高(死锁、竞态条件) | 低(但要注意回调地狱,可用 async/await 解决) |
为什么 Web 开发用事件循环? Web 应用的大部分操作是 I/O 密集型的(读取文件、网络请求),而不是 CPU 密集型的。事件循环可以让一个线程处理成千上万个 I/O 操作,效率极高。
类比理解: C/C++ 多线程像多个人同时干活(线程切换开销大,要协调好资源);JavaScript 的事件循环像一个超级高效的秘书,你给他一堆任务(I/O 请求),他排队处理,干完一个就通知你。
三、一句话总结
C/C++ 开发 = 造发动机(直接控制硬件,精细管理资源);Web 开发 = 开自动驾驶汽车(在成熟的平台上编写逻辑,快速迭代)。
四、举一反三:这些概念在 Web 开发里的“影子”
| C/C++ 概念 | Web 开发里的对应物 | 说明 |
|---|---|---|
main() 入口函数 |
module.exports 或 export default |
定义模块导出内容 |
#include <stdio.h> |
import fs from 'fs' |
引入依赖模块 |
条件编译 #ifdef |
环境变量 process.env.NODE_ENV |
区分开发/生产环境 |
Makefile |
package.json 里的 scripts |
定义构建任务(如 npm run build) |
gdb 调试器 |
console.log() 或 Chrome DevTools |
调试程序状态 |
静态库(.lib) |
npm 包(node_modules) |
可复用的代码库 |
问题五:Hexo逻辑深挖
一、Hexo 执行逻辑的核心流程
Hexo 本质上是一个管道式处理系统(Pipeline),数据像流水线一样经过多个处理阶段。它的完整执行流程可以用一个图来概括:
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
二、逐步拆解:每个阶段的具体工作
1. 加载阶段(Load)
这是 Hexo 启动时的初始化过程,决定了后续所有行为。
| 步骤 | 具体工作 | 涉及的关键文件 | 为什么重要 |
|---|---|---|---|
| 加载配置文件 | 读取站点根目录的 _config.yml,解析成 JavaScript 对象 |
_config.yml |
决定站点标题、URL、主题、部署方式等 |
| 加载主题配置 | 读取 themes/ 目录下主题的 _config.yml,覆盖或扩展主配置 |
themes/next/_config.yml |
决定主题样式、菜单、侧边栏等 |
| 加载 package.json | 读取项目的 package.json,获取依赖列表和脚本信息 |
package.json |
确定安装的 Hexo 版本和插件 |
| 加载插件 | 扫描 node_modules/ 中所有 hexo-* 命名的包,加载并注册 |
node_modules/hexo-* |
扩展 Hexo 功能(如搜索插件、字数统计) |
类比理解: 这就像 C/C++ 程序启动时,先读取配置文件、加载动态库(.dll/.so)。
2. 处理阶段(Process)
这是 Hexo 最核心的工作:把源文件转换成可渲染的数据结构。
| 步骤 | 具体工作 | 涉及的关键文件 | 为什么重要 |
|---|---|---|---|
| 加载源文件 | 扫描 source/ 目录,识别所有 .md、.html、.css 等文件 |
source/_posts/*.md |
找到所有需要处理的原始内容 |
| 解析 Front-matter | 提取每篇文章开头的 --- 区域,解析成元数据对象 |
文章开头的 --- 区域 |
决定文章的标题、日期、标签、分类等 |
| 分类处理 | 根据文件扩展名,匹配对应的渲染器(renderer) |
.md → Markdown 渲染器 |
不同类型的文件用不同方式处理 |
| 渲染内容 | 把 Markdown 转换为 HTML,把元数据和内容合并成 Post 对象 | Markdown 语法 | 核心转换,从纯文本变成结构化内容 |
| 应用标签/插件 | 处理文章中的 Nunjucks 标签({% %}),执行插件逻辑 |
文章中的 Nunjucks 标签 | 实现自定义功能(如图片画廊、提示框) |
类比理解: 这就像 C++ 的模板处理——源文件(.md)经过处理,生成了包含内容 + 元数据的中间表示(Post 对象)。
3. 生成阶段(Generate)
这是把处理好的数据组合成完整页面的过程。
| 步骤 | 具体工作 | 涉及的关键文件 | 为什么重要 |
|---|---|---|---|
| 构建页面 | 根据主题模板(.swig/.ejs),把 Post 对象填充进布局 |
主题中的模板文件 | 生成每个文章的完整 HTML 页面 |
| 生成归档 | 按日期、标签、分类创建汇总页面 | 主题中的归档模板 | 让读者按时间线浏览文章 |
| 生成索引 | 生成首页、文章列表页 | 主题中的首页模板 | 展示所有文章的摘要列表 |
| 资源处理 | 复制主题的 CSS/JS/图片到 public/ 目录 |
主题中的 source/ 文件夹 |
确保样式和脚本能正常加载 |
类比理解: 这就像 C++ 的链接阶段——所有 .o 文件(Post 对象)被组合成最终的可执行文件(HTML 页面)。
4. 输出阶段(Write)
这是最后的写入和完成步骤。
| 步骤 | 具体工作 | 涉及的关键文件 | 为什么重要 |
|---|---|---|---|
| 写入文件 | 把所有生成的 HTML 和资源写入 public/ 目录 |
public/ 文件夹 |
产生最终可部署的静态文件 |
| 输出日志 | 在终端显示生成了哪些文件,耗时多少 | 终端输出 | 让你了解构建结果 |
| 完成 | 生成完毕,可以执行后续命令 | — | 这是 hexo generate 的终点 |
类比理解: 这就像 C++ 的安装阶段——把可执行文件和资源复制到最终位置。
三、关键概念:Hexo 是怎么处理文章的?
Hexo 对每篇 Markdown 文章的处理逻辑非常标准化:
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
四、关键概念:Hexo 的插件机制
Hexo 提供了多个扩展点,让你可以介入处理流程的不同阶段:
| 扩展点 | 作用 | 示例 |
|---|---|---|
| Filter | 在特定时机修改数据(如文章生成前/后) | hexo-symbols-count-time 在文章渲染后添加字数和阅读时间 |
| Tag | 添加自定义标签({% tag %}) |
{% youtube video_id %} 嵌入 YouTube 视频 |
| Generator | 生成额外页面(如归档、标签页) | hexo-generator-searchdb 生成 search.xml |
| Console | 添加自定义命令(hexo my-command) |
你的 deploy-blog 脚本可以做成自定义命令 |
| Processor | 添加新的文件处理方式(如支持 .less) |
处理 .less 文件并生成 .css |
五、执行流程图(完整版)
text
1 | 启动命令(hexo generate) |
六、实际体验对照
| 你执行的命令 | 实际执行的流程 |
|---|---|
hexo clean |
删除 public/ 和 .deploy_git/ 目录,重置缓存 |
hexo generate |
执行完整的 加载 → 处理 → 生成 → 输出 流程 |
hexo server |
执行 hexo generate → 启动 HTTP 服务器 → 监听文件变化 |
hexo deploy |
执行 hexo generate → 调用部署插件(hexo-deployer-git)推送到远程仓库 |
七、一句话总结
Hexo 是一个基于 Node.js 的静态站点生成器。它加载配置文件,解析 Markdown 文章和主题模板,经过 加载 → 处理 → 生成 → 输出 四个阶段,最终生成可部署的静态 HTML 网站。它的插件系统允许你在任何阶段扩展功能,而 Node.js 的异步特性保证了构建效率。
问题六:Node.js逻辑深挖
一、Node.js 的本质:一个“JavaScript 运行时”
先给你一个最本质的定义:
Node.js 是一个让 JavaScript 可以脱离浏览器运行的程序。它是一个用 C++ 写的、封装了 Google V8 引擎的“容器”。
这句话拆开来看:
| 部分 | 含义 | 类比 |
|---|---|---|
| Google V8 引擎 | 一个可以解析和执行 JavaScript 代码的程序(由 Google 开发,用在 Chrome 浏览器里) | 汽车的发动机(能产生动力,但不能自己跑) |
| Node.js | 在 V8 引擎外面包了一层,提供了操作系统级别的 API(文件读写、网络、进程管理等) | 汽车的底盘+车身+方向盘(让发动机可以驱动汽车前进) |
| 你写的 JS 代码 | 你写的逻辑 | 驾驶员(告诉车怎么走) |
三者关系:
text
1 | JavaScript 代码(你写的) |
二、Node.js 的运行逻辑:事件驱动 + 非阻塞 I/O
这是 Node.js 最核心、也最容易被误解的部分。
1. 单线程 + 事件循环
你之前学 C/C++ 时,程序通常是多线程的:每个任务分配一个线程,多个线程可以同时执行。
Node.js 完全不同:它是单线程的,但通过“事件循环”来处理大量并发任务。
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
关键理解:
| 概念 | 含义 | 类比 |
|---|---|---|
| 单线程 | 只有一个主线程在执行 JavaScript 代码 | 一个服务员在接待客人 |
| 事件循环 | 主线程不断检查“待办事项队列”,有任务就处理 | 服务员不断看排队列表,有新的就接待 |
| 异步 I/O | 耗时的操作(读文件、网络请求)交给操作系统去做,主线程不等待 | 服务员点完菜后,不站在厨房等,而是去接待下一位客人 |
| 非阻塞 | 主线程不会被阻塞,可以继续执行其他任务 | 服务员不会被一个客人的慢动作困住 |
2. 一个具体的例子:hexo generate 在 Node.js 里怎么跑?
当你执行 hexo generate 时,Node.js 内部是这样的:
text
1 | 1. Node.js 启动,加载 hexo 命令脚本 |
关键点: hexo generate 之所以快,是因为所有文章并发读取(由操作系统并行执行),而不是一篇文章一篇文章地串行读取。
三、Node.js 和 C++ 程序运行方式的对比
| 方面 | C++ 程序 | Node.js 程序 |
|---|---|---|
| 启动方式 | 双击 .exe 或命令行直接运行 |
执行 node 脚本.js,Node.js 加载并执行 |
| 运行环境 | 直接在操作系统上运行 | 在 Node.js 虚拟机里运行 |
| 多任务方式 | 多线程(多个服务员同时干活) | 单线程 + 事件循环(一个服务员高效管理) |
| I/O 操作 | 默认同步阻塞(读文件时线程等待) | 默认异步非阻塞(读文件时不等待) |
| 内存管理 | 手动分配/释放 | 自动垃圾回收 |
| 原生代码 | 直接编译成机器码 | 通过 V8 引擎即时编译(JIT) |
| 系统调用 | 直接调用操作系统的 API | 通过 Node.js 封装层间接调用 |
四、为什么 Hexo 需要 Node.js?(重新理解)
你之前问过这个问题,现在我们可以更深地回答了:
| Hexo 的每一步 | 它在 Node.js 里做了什么 | Node.js 提供了什么能力 |
|---|---|---|
读取 _config.yml |
调用 fs.readFileSync() |
文件系统 API |
扫描 source/_posts/ |
调用 fs.readdirSync() |
文件系统 API |
| 解析 Markdown | 调用 marked.parse()(JS 库) |
V8 引擎执行 JS 代码 |
| 渲染模板 | 调用 nunjucks.render()(JS 库) |
V8 引擎执行 JS 代码 |
写入 public/ |
调用 fs.writeFileSync() |
文件系统 API |
| 启动服务器 | 调用 http.createServer() |
网络 API |
| 监听文件变化 | 调用 fs.watch() |
文件系统 API |
没有 Node.js,Hexo 什么也做不了,因为:
- 它没法读写文件(没有
fs模块) - 它没法解析 Markdown(没有 V8 引擎执行 JS 代码)
- 它没法启动服务器(没有
http模块)
五、Node.js 的“两种用法”
你可能接触过 Node.js 的两种使用方式,它们本质是一样的:
| 用法 | 场景 | 例子 |
|---|---|---|
| 运行工具 | 执行命令行工具,完成构建任务 | hexo generate、npm install |
| 启动服务器 | 运行一个持续服务的程序,接受网络请求 | 用 Express 写的后端 API 服务 |
在你的项目里,你用到了第一种用法:Node.js 作为 Hexo 的执行环境。第二种用法是更典型的 Web 后端开发,你可以把它理解为:hexo server 命令启动的本地预览服务器,就是一个“微缩版”的 Web 服务器。
六、一组帮助你加深理解的思考题
- 如果 Node.js 是单线程的,为什么
hexo generate还能并发处理多篇文章?(提示:异步 I/O 把读文件的工作交给了操作系统) - 为什么你不能用浏览器去执行
hexo generate命令?(提示:浏览器没有fs文件系统模块,也没有命令行入口) - 如果把
hexo generate的核心逻辑用 C++ 改写,它还会是一个“Web 开发工具”吗?(提示:核心逻辑不变,但生态会完全改变)
一句话总结: Node.js 是一个让 JavaScript 能像 C++ 一样操作操作系统(文件、网络、进程) 的程序。而 Hexo 只是一个运行在 Node.js 上的 JS 脚本
问题七:linux命令归纳
一、系统信息与文件操作类
这类命令用于查看系统状态、管理文件和目录。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
whoami |
查看当前登录的用户名 | 确认你是 tongshixuan 还是 root |
hostname |
查看或临时修改主机名 | 确认当前在 node1、node2 还是 node3 |
hostnamectl set-hostname |
永久修改主机名 | 把模板机克隆出来的节点改名为 node1、node2、node3 |
pwd |
显示当前所在目录的完整路径 | 确认你现在在哪个目录下操作 |
ls |
列出目录内容 | 查看 /var/www/blog/ 里有没有文件 |
ls -la |
列出所有文件(包括隐藏文件),显示详细信息 | 查看 .ssh/ 目录的权限和文件 |
cd |
切换目录 | 进入 /etc/nginx/sites-available/ 修改配置 |
mkdir |
创建目录 | 创建 /var/www/blog/ 站点目录 |
mkdir -p |
创建多级目录(父目录不存在则自动创建) | 创建 .github/workflows/ 等嵌套目录 |
touch |
创建空文件或更新文件时间戳 | 创建测试文件(用得少) |
cat |
查看文件内容 | 查看 ~/.ssh/id_ed25519.pub 公钥内容 |
echo |
输出文本到终端或文件 | echo "Hello" > test.txt 创建测试文件 |
cp |
复制文件或目录 | 复制配置文件(本项目用得少) |
mv |
移动或重命名文件 | 重命名文件(本项目用得少) |
rm |
删除文件 | 删除 /etc/nginx/sites-enabled/default |
rm -rf |
强制递归删除目录(非常危险!) | 清理旧文件(慎用) |
ln -s |
创建软链接(类似 Windows 的快捷方式) | ln -s /etc/nginx/sites-available/blog /etc/nginx/sites-enabled/ |
chmod |
修改文件权限 | chmod 600 ~/.ssh/authorized_keys |
chown |
修改文件所有者和所属组 | sudo chown -R tongshixuan:tongshixuan /var/www/blog |
du -sh |
查看目录大小 | 查看博客文件夹占用空间(实验六练习用) |
二、系统管理与软件安装类
这类命令用于安装软件、管理系统服务。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
sudo |
以超级管理员权限执行命令 | 几乎所有系统级操作(安装软件、修改配置) |
apt update |
更新软件包列表 | 安装 Nginx 前先更新源 |
apt install |
安装软件包 | apt install nginx -y、apt install rsync -y |
systemctl start |
启动一个系统服务 | systemctl start nginx、systemctl start ssh |
systemctl stop |
停止一个系统服务 | 重启服务前停止 |
systemctl restart |
重启一个系统服务 | systemctl restart ssh、systemctl restart nginx |
systemctl reload |
重新加载服务配置(不中断服务) | systemctl reload nginx(修改配置后使用) |
systemctl enable |
设置服务开机自启 | systemctl enable nginx、systemctl enable ssh |
systemctl status |
查看服务运行状态 | systemctl status nginx、systemctl status ssh |
三、网络与远程管理类
这类命令用于网络配置和远程连接。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
ping |
测试网络连通性 | 验证虚拟机之间、虚拟机与宿主机之间的网络 |
ip a 或 ifconfig |
查看网络接口的 IP 地址 | 确认虚拟机的 IP 是否为 192.168.56.x |
ssh |
远程登录到另一台服务器 | ssh tongshixuan@192.168.56.103 从 node1 登录 node2 |
ssh-keygen |
生成 SSH 密钥对 | ssh-keygen -t ed25519 -C "邮箱" 生成公钥/私钥 |
ssh-copy-id |
将公钥复制到远程服务器 | ssh-copy-id tongshixuan@192.168.56.103 配置免密登录 |
scp |
基于 SSH 的远程文件复制 | scp test.txt tongshixuan@192.168.56.103:/home/tongshixuan/ |
rsync |
远程或本地文件增量同步 | rsync -avz --delete ~/public/ tongshixuan@192.168.56.103:/var/www/blog/ |
curl |
发送 HTTP 请求或测试 Web 服务 | curl http://localhost 测试 Nginx 是否运行 |
四、文本编辑与查看类
这类命令用于查看和编辑配置文件。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
nano |
一个简单易用的终端文本编辑器 | 编辑 sshd_config、Nginx 配置文件、_config.yml |
cat |
查看文件内容 | 查看公钥、查看日志 |
head / tail |
查看文件开头或结尾的内容 | 查看日志文件(实验六练习用) |
五、权限与用户管理类
这类命令用于管理系统用户和文件权限。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
sudo |
以 root 权限执行命令 | 几乎所有系统操作 |
passwd |
修改用户密码 | 修改 node1 或 node2 的密码 |
chmod |
修改文件权限 | chmod 600 ~/.ssh/authorized_keys 确保 SSH 认证安全 |
chown |
修改文件所有者 | sudo chown -R tongshixuan:tongshixuan /var/www/blog |
六、命令执行与任务管理类
这类命令用于管理任务和查阅帮助。
| 命令 | 作用 | 你在项目中哪里用到 |
|---|---|---|
exit |
退出当前 Shell 或 SSH 会话 | 从 node2 退出回到 node1,或退出 Xshell |
Ctrl+C |
中断当前正在运行的命令 | 停止 hexo server 或卡住的命令 |
Ctrl+D |
退出终端(相当于输入 exit) |
退出 SSH 会话 |
--help 或 -h |
查看命令的帮助信息 | 探索不熟悉的命令(如 rsync --help) |
man |
查看命令的完整手册(Manual) | man rsync 查看 rsync 的详细文档 |
七、整个项目涉及到的关键文件路径
为了让命令更清晰,这里整理一下你操作过的所有关键文件路径:
| 文件/目录 | 作用 | 在哪台机器上 |
|---|---|---|
~/.ssh/id_ed25519 |
SSH 私钥(绝对不要泄露!) | node1 |
~/.ssh/id_ed25519.pub |
SSH 公钥(复制到其他机器) | node1 |
~/.ssh/authorized_keys |
存放允许登录的公钥列表 | node2、node3 |
~/.ssh/config |
SSH 客户端配置文件 | node1 |
/etc/ssh/sshd_config |
SSH 服务端配置文件 | node1、node2、node3 |
/etc/netplan/50-cloud-init.yaml |
网络配置文件(静态IP) | node1、node2、node3 |
/etc/hosts |
主机名解析文件 | node1、node2、node3 |
/etc/nginx/sites-available/blog |
站点配置文件(未启用) | node2 |
/etc/nginx/sites-enabled/blog |
站点配置文件(已启用) | node2 |
/etc/nginx/sites-enabled/default |
Nginx 默认站点配置 | node2(已删除) |
/var/www/blog/ |
博客文件存放目录 | node2 |
/etc/profile |
系统级环境变量配置 | 所有 Linux 机器 |
~/.bashrc |
用户级 Shell 配置文件 | 所有 Linux 机器 |
八、快速查阅表
如果你想快速回顾某个命令,可以参照这个列表:
- 查看系统状态:
whoami、hostname、pwd、ip a、ping - 文件和目录操作:
ls、cd、mkdir、rm、cp、mv、ln -s - 文件内容操作:
cat、echo、grep、nano - 权限管理:
sudo、chmod、chown、passwd - 软件安装与服务:
apt、systemctl - 网络与远程:
ssh、scp、rsync、curl - 任务控制:
exit、Ctrl+C
细节追溯
六个方向
项目与代码库配置 项目配置、编辑器配置、git配置等
Web运行环境 语言包、包管理器、关键软件包及配置等
Linux环境配置 系统profile配置、用户配置、环境变量等
Linux账户配置 账户配置、Home配置、关键文件的权限配置等
远程管理配置 SSH服务、端口配置、登录配置等s
Web站点部署 可运行的站点、基本功能、部署脚本
一、项目与代码库配置
这部分内容涉及项目组织方式、版本控制、编辑器配置。
可以查阅的位置:
- **项目根目录的
_config.yml**:站点的核心配置文件,包含站点名称、作者、主题、部署信息等,是了解项目整体配置的第一入口。 .gitignore文件:记录哪些文件和目录不提交到 Git(如node_modules/、public/),这是版本控制配置的直接体现。- **
package.json和package-lock.json**:记录项目依赖和脚本,可以看到用到了哪些包和工具链。 - VS Code 设置(
.vscode/目录或全局设置):编辑器相关的配置,如自动保存、插件等。 - 实验手册实验二和三:有详细的 Node.js、Git、VS Code 安装和配置步骤。
这个问题直接对应你答辩框架里的“项目与代码库配置”这一项。我们用你项目里实际用到的配置来拆解。
一、项目配置(Project Configuration)
项目配置是指项目本身的元数据和运行参数,它定义了“这是一个什么项目”、“需要哪些资源”、“如何运行”。
在你的 Hexo 博客项目中,项目配置主要体现在以下文件:
| 配置文件 | 作用 | 关键内容 |
|---|---|---|
_config.yml |
站点核心配置文件 | 站点标题、URL、主题、部署目标、插件配置等 |
package.json |
项目元数据和依赖清单 | 项目名称、版本、依赖包、脚本命令 |
package-lock.json |
依赖版本锁定文件 | 锁定每个依赖包的精确版本号,确保每次安装一致 |
.gitignore |
Git 忽略文件列表 | 指定哪些文件和目录不提交到版本库 |
1. 站点配置(_config.yml)
这是 Hexo 站点的核心配置文件,你在这里定义了博客的所有基础信息。
| 配置项 | 你的值 | 作用 |
|---|---|---|
title |
你的博客标题 | 显示在浏览器标签和页面标题中 |
subtitle |
副标题 | 显示在网站描述中 |
description |
网站描述 | SEO 和社交媒体卡片会用到 |
author |
作者名 | 文章底部显示的作者信息 |
language |
zh-CN |
网站语言,影响日期格式和主题文字 |
timezone |
Asia/Shanghai |
文章发布时间使用的时区 |
url |
https://tristan1116.github.io |
站点根地址,影响生成的文件路径 |
theme |
next |
使用的主题名称 |
deploy |
Git 仓库地址 | 部署目标配置(你在实验四中配置的) |
你在项目中添加的自定义配置:
| 功能 | 配置项 | 配置文件 |
|---|---|---|
| 搜索 | search: path: search.xml |
_config.yml |
| 字数统计 | symbols_count_time: enable: true |
themes/next/_config.yml |
| 进度条 | pace: enable: true |
themes/next/_config.yml |
| 看板娘 | live2d: enable: true(后删除) |
_config.yml |
2. 项目元数据(package.json)
这是 Node.js 项目的身份证和清单,记录了项目的基本信息和所有依赖。
| 字段 | 作用 | 你的项目中的值 |
|---|---|---|
name |
项目名称 | my-blog01 |
version |
项目版本 | 1.0.0 |
description |
项目描述 | 你的博客描述 |
main |
入口文件 | index.js(通常 Hexo 项目没有主入口) |
scripts |
自定义命令 | 可以用 npm run 执行的命令 |
dependencies |
生产环境依赖 | Hexo 核心及其插件(如 hexo-generator-searchdb) |
devDependencies |
开发环境依赖 | 只在开发时需要的工具(如主题开发工具) |
你项目中的关键依赖(dependencies):
| 包名 | 作用 |
|---|---|
hexo |
静态站点生成器核心 |
hexo-generator-searchdb |
生成搜索索引文件 |
hexo-symbols-count-time |
文章字数统计和阅读时间 |
hexo-deployer-git |
Git 部署插件(实验四提到) |
hexo-server |
本地预览服务器(随 Hexo 安装) |
核心理解:
项目配置 = “店铺的营业执照 + 进货清单” ——
_config.yml是营业执照(你是谁、在哪开店),package.json是进货清单(店里需要哪些货架、收银机、灯光设备)。
二、编辑器配置(Editor Configuration)
编辑器配置是指 VS Code 编辑器的个性化设置和插件,用来提高代码编写效率和统一团队编码风格。
在你的项目中,编辑器配置主要体现在以下方面:
1. VS Code 用户设置(全局)
你通过 Ctrl + , 或 settings.json 配置的编辑器行为:
| 配置项 | 你的值 | 作用 |
|---|---|---|
files.autoSave |
afterDelay |
自动保存文件,防止丢失内容 |
editor.wordWrap |
on |
自动折行,方便查看长行文本 |
editor.fontSize |
14(默认) | 编辑器字体大小 |
editor.tabSize |
2(默认) | 缩进空格数(YAML 推荐 2 空格) |
2. VS Code 插件配置
你安装了多个 Markdown 相关插件,每个插件都有自己的配置项:
| 插件 | 作用 | 关键配置 |
|---|---|---|
| Markdown All in One | 目录生成、快捷键、自动完成 | 默认配置即可 |
| Markdown Preview Enhanced | 增强预览、导出 PDF、Mermaid 图表 | 默认配置即可 |
| Paste Image | 粘贴图片到 Markdown | Paste Image: Path Type → relative(相对路径) |
3. 项目级编辑器配置(可选)
如果你的项目根目录有 .vscode/ 文件夹,里面的 settings.json 和 extensions.json 就是项目级编辑器配置:
1 | my-blog01/ |
你的项目里可能没有这些文件,因为它们是可选的,不属于 Hexo 必须配置项。但如果你创建了它们,它们就属于“编辑器配置”。
核心理解:
编辑器配置 = “店铺收银台的布局和工具摆放” —— 你喜欢把记事本放左边、计算器放右边、自动保存打开,让别人用你的店铺也觉得顺手。
三、Git 配置(Git Configuration)
Git 配置是指 Git 版本控制系统的设置,它决定了你的代码如何被追踪、如何提交、如何与远程仓库交互。
在你的项目中,Git 配置主要体现在三个层面:
1. 全局 Git 配置(~/.gitconfig)
这个配置影响你电脑上所有 Git 仓库的行为。
| 配置项 | 你的值 | 作用 |
|---|---|---|
user.name |
你的姓名 |
提交记录中的作者名字 |
user.email |
你的邮箱@example.com |
提交记录中的作者邮箱(关联 GitHub 账户) |
core.autocrlf |
true(Windows 默认) |
自动处理换行符(LF vs CRLF),你遇到的警告就来自这里 |
credential.helper |
store(如果你配置过) |
缓存 GitHub 凭证,避免重复输入密码 |
查看全局配置:
1 | git config --global --list |
你在项目中的实际操作:
| 操作 | 命令 | 目的 |
|---|---|---|
| 配置用户名和邮箱 | git config --global user.name "你的姓名" |
提交记录中显示正确的作者信息 |
| 配置凭据缓存 | git config --global credential.helper store |
避免每次 git push 都输入用户名和 Token |
2. 本地仓库配置(my-blog01/.git/config)
这个配置只影响当前 Git 仓库,会覆盖全局配置。
| 配置项 | 你的值 | 作用 |
|---|---|---|
remote.origin.url |
git@github.com:tristan1116/my-blog01.git |
远程仓库地址(你从 HTTPS 改成了 SSH) |
branch.main.remote |
origin |
当前分支关联的远程仓库 |
branch.main.merge |
refs/heads/main |
当前分支关联的远程分支 |
查看本地仓库配置:
1 | git config --local --list |
3. Git 忽略配置(.gitignore)
.gitignore 指定哪些文件和目录不应该被 Git 追踪。
你的项目中的 .gitignore 内容:
| 忽略项 | 原因 |
|---|---|
node_modules/ |
依赖包体积大,从 package.json 可还原,不应提交 |
.DS_Store |
macOS 系统文件,与代码无关 |
public/ |
生成的静态文件,源码仓库只存源码,不存构建产物 |
.deploy_git/ |
Hexo 部署时生成的临时目录,不应提交 |
你在项目中的实际操作:
| 操作 | 命令 | 目的 |
|---|---|---|
创建 .gitignore |
echo "node_modules/" >> .gitignore |
排除依赖包文件夹 |
| 添加忽略项 | 手动编辑 .gitignore |
排除 public/、.deploy_git/ 等 |
| 检查忽略状态 | git status |
确认被忽略的文件不会出现在未追踪列表中 |
核心理解:
Git 配置 = “店铺的记账系统” —— 全局配置是总店的记账规则(谁写的账本、用什么格式),本地配置是分店的个性化规则(账本放在哪个分店),
.gitignore是“哪些东西不用记账”(一次性用品、临时货物)。
四、三者关系总结
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
五、一句话总结
项目配置定义了“这是一个什么项目”(
_config.yml+package.json),编辑器配置定义了“用什么工具、怎么编辑”(VS Code 设置 + 插件),Git 配置定义了“怎么版本控制和提交”(.gitconfig+.gitignore)。三者共同构成了项目的“基本盘”,是你在本地开发的起点。
二、Web运行环境
这部分涉及Node.js、npm、Hexo 及其插件的运行环境。
可以查阅的位置:
- **
package.json中的dependencies和devDependencies**:列出所有运行时依赖,是了解环境组成的最佳入口。 hexo -v命令的输出:显示 Hexo 版本和依赖组件列表。- 实验手册实验二:有 Node.js、npm、Git 的安装和验证步骤。
- 镜像源配置:
npm config get registry查看是否使用了国内镜像源。
一、语言包(Language Package)
语言包,在这里指的是 Node.js 本身及其运行环境。
在 Web 开发语境下,“语言包”不是一个官方术语,但在你的答辩框架里,它指的就是支撑整个项目运行的编程语言运行时。
在你的项目里:
- Node.js 是唯一的“语言包”。它是一个 JavaScript 运行时环境,让 JavaScript 代码可以在服务器端执行。
- 你安装的 Node.js 版本(比如 LTS 20.x)就是“语言包”的具体体现。
相关命令:
bash
1 | node -v # 查看 Node.js 版本 |
类比理解:
就像你要运行 C++ 程序需要安装 Visual C++ Redistributable 或 GCC,要运行 Java 程序需要安装 JRE/JDK 一样,运行 JavaScript/Hexo 需要安装 Node.js。
二、包管理器(Package Manager)
包管理器是一个工具,用于自动下载、安装、更新、卸载项目依赖的第三方代码库。
在你的项目里:
- npm(Node Package Manager)是唯一的包管理器。它随 Node.js 一起安装,不需要单独安装。
- 你配置了国内镜像源(
https://registry.npmmirror.com),这是为了加速下载。
npm 的核心作用:
| npm 功能 | 对应命令 | 你在项目中哪里用到 |
|---|---|---|
| 安装依赖 | npm install |
初始化 Hexo 项目后安装所有依赖 |
| 全局安装工具 | npm install -g hexo-cli |
全局安装 Hexo 命令行工具 |
| 安装并保存到 package.json | npm install hexo --save |
安装 Hexo 核心及其插件 |
| 查看已安装的包 | npm list |
查看项目依赖树(用得少) |
| 更新依赖 | npm update |
更新包到最新版本(用得少) |
为什么需要包管理器?
- 没有它,你需要手动下载每个依赖的源码,还要处理它们之间的依赖关系和版本冲突,这在现代 Web 项目中几乎不可能手动完成。
类比理解:
- npm 之于 Node.js,就像 apt 之于 Ubuntu,vcpkg/conan 之于 C++,Maven 之于 Java。
三、关键软件包(Key Software Packages)
关键软件包是指项目直接依赖的核心第三方库和工具,它们提供了项目的核心功能。
在你的项目里:
| 软件包名称 | 作用 | 安装命令 |
|---|---|---|
| hexo | 静态站点生成器核心框架 | npm install hexo |
| hexo-cli | Hexo 命令行工具(全局安装) | npm install -g hexo-cli |
| hexo-server | 本地预览服务器(通常随 hexo 一起安装) | 随 hexo 自动安装 |
| hexo-generator-searchdb | 生成搜索索引文件(search.xml) |
npm install hexo-generator-searchdb --save |
| hexo-symbols-count-time | 文章字数统计和阅读时间 | npm install hexo-symbols-count-time --save |
| hexo-deployer-git | Git 部署插件(实验四中提到) | npm install hexo-deployer-git --save |
这些包之间的关系:
text
1 | hexo-cli(全局工具,用来执行命令) |
查看所有已安装的包:
bash
1 | # 查看项目依赖(在项目根目录执行) |
四、配置(Configuration)
配置是指项目的配置文件,用来控制 Hexo 及其插件的行为。
在你的项目里,配置分为三个层次:
| 配置文件 | 作用 | 关键配置项 |
|---|---|---|
**_config.yml**(站点根目录) |
站点全局配置 | title(站点标题)、url(站点地址)、theme(主题)、deploy(部署配置) |
themes/next/_config.yml |
主题配置 | menu(菜单)、sidebar(侧边栏)、symbols_count_time(字数统计)、pace(进度条) |
package.json |
依赖和脚本配置 | dependencies(依赖列表)、scripts(自定义命令) |
关键配置项举例:
| 配置项 | 作用 | 在哪个文件中 |
|---|---|---|
theme: next |
指定使用 NexT 主题 | _config.yml |
search: path: search.xml |
指定搜索索引文件路径 | _config.yml |
symbols_count_time: enable: true |
启用字数统计 | themes/next/_config.yml |
live2d: enable: false |
启用/禁用看板娘 | _config.yml |
deploy: repo: git@github.com:... |
配置 Git 部署地址 | _config.yml |
查看配置的方法:
bash
1 | # 查看站点配置 |
五、总结:四者关系
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
一句话总结:
语言包(Node.js)是运行环境,包管理器(npm)是下载工具,关键软件包(Hexo 及插件)是功能组件,配置是让它们按你期望方式工作的“说明书”。四者缺一不可,共同构成了 Web 运行环境的完整生态。
三、Linux环境配置
这部分涉及系统级配置文件、环境变量、Shell 行为。
可以查阅的位置:
- **
/etc/profile**:系统级环境变量配置,影响所有用户。 - **
/etc/environment**:系统级环境变量(更底层)。 - **
/etc/netplan/50-cloud-init.yaml**:网络配置(静态IP),这是实验五中的核心配置。 - **
/etc/hosts**:主机名解析文件,配置了 node1、node2、node3 的 IP 映射。 - **
~/.bashrc和~/.profile**:用户级 Shell 配置文件,包含别名(如deploy-blog)和自定义变量。 - 实验手册实验六:专门讲解系统 profile 配置、用户配置、环境变量。
hostnamectl命令:查看和修改主机名。echo $PATH和env命令:查看当前环境变量。
一、系统 profile 配置(System-wide Profile Configuration)
系统 profile 配置是指影响所有用户的全局配置文件,它们定义了系统的默认行为和所有用户的基础环境。
在你的 Linux 虚拟机中,主要涉及以下文件:
| 配置文件 | 作用 | 加载时机 |
|---|---|---|
/etc/profile |
系统级全局配置,为所有用户设置环境变量和登录行为 | 用户登录时执行 |
/etc/environment |
系统级环境变量定义文件,格式更简单(只支持 KEY=VAL 格式) |
系统启动时加载,早于任何 Shell |
/etc/profile.d/ 目录 |
存放多个独立的 .sh 脚本,每个脚本设置一组环境变量 |
登录时由 /etc/profile 自动执行 |
你在项目中的实际操作:
| 你做过的事 | 对应的系统 profile 配置 |
|---|---|
修改 /etc/ssh/sshd_config |
这是系统级的 SSH 服务配置,影响所有用户的 SSH 登录行为 |
使用 sudo apt install 安装软件 |
软件安装后,系统 profile 会更新 PATH 等环境变量 |
配置 /etc/netplan/50-cloud-init.yaml |
这是系统级的网络配置,影响整个虚拟机的网络行为 |
核心理解:
系统 profile 配置 = “大楼的门禁系统” —— 一旦设定,所有进入大楼的人(所有用户)都会受到影响。
二、用户配置(User-specific Configuration)
用户配置是指只影响当前用户的个性化配置文件,它们位于用户的主目录(~)下,通常以点(.)开头。
在你的 Linux 虚拟机中,主要涉及以下文件:
| 配置文件 | 作用 | 加载时机 |
|---|---|---|
~/.bashrc |
Bash Shell 的用户级配置,定义别名、函数、环境变量 | 每次打开新的交互式 Bash Shell 时执行 |
~/.profile |
用户级登录配置,设置环境变量 | 用户登录时执行(仅在登录 Shell 中) |
~/.bash_logout |
用户退出 Shell 时执行的命令 | 退出 Shell 时 |
~/.ssh/config |
SSH 客户端用户级配置 | 执行 ssh 命令时读取 |
你在项目中的实际操作:
| 你做过的事 | 对应的用户配置 |
|---|---|
配置 ~/.ssh/config 文件 |
为 SSH 客户端指定默认用户名、端口、密钥文件(如你配置的 github.com Host) |
在 ~/.bashrc 中设置别名(如 deploy-blog) |
自定义命令,方便快速执行部署脚本 |
查看 ~/.ssh/id_ed25519.pub 公钥 |
SSH 密钥存放在用户级别,不与其他用户共享 |
修改 ~/.bashrc 中的 PATH |
只影响你自己的命令行工具路径 |
核心理解:
用户配置 = “你房间里的个人物品” —— 只有你(当前用户)使用,不影响别人。
三、环境变量(Environment Variables)
环境变量是操作系统用来存储系统环境信息的键值对(KEY=VALUE 形式)。它们是程序运行时的“上下文信息”,告诉程序“你在哪里”、“你是谁”、“怎么操作”。
常见的环境变量:
| 环境变量 | 作用 | 你的项目中的例子 |
|---|---|---|
PATH |
指定可执行文件的搜索路径 | echo $PATH 显示 /usr/local/bin:/usr/bin:/bin 等,Hexo 命令才能被找到 |
HOME |
当前用户的主目录路径 | /home/tongshixuan,SSH 默认配置文件 ~/.ssh/config 就在这个路径下 |
USER |
当前用户名 | tongshixuan,sudo 命令会检查这个变量 |
SHELL |
当前使用的 Shell 类型 | /bin/bash,决定命令解释器 |
PWD |
当前工作目录 | 你执行 cd 命令时自动更新 |
NODE_ENV |
Node.js 运行环境(你的 Hexo 项目用) | 可以设置为 production 或 development,但本项目未显式设置 |
环境变量的三种设置方式:
| 方式 | 作用范围 | 示例命令 | 用途 |
|---|---|---|---|
| 临时设置(命令行) | 当前终端会话 | export MY_VAR="hello" |
测试、一次性任务 |
| 用户级永久设置 | 当前用户的所有会话 | 在 ~/.bashrc 中添加 export PATH=$PATH:/my/bin |
个性化配置 |
| 系统级永久设置 | 所有用户的会话 | 在 /etc/profile 或 /etc/environment 中添加 |
全局统一配置 |
你在项目中的实际操作:
| 你做过的事 | 对应的环境变量操作 |
|---|---|
执行 echo $PATH |
查看当前 PATH 变量,确认 Hexo 命令是否能被找到 |
ssh tongshixuan@192.168.56.103 免密登录 |
SSH 读取 ~/.ssh/id_ed25519 私钥,这依赖于 HOME 环境变量 |
hexo generate 执行成功 |
因为 PATH 变量中包含 Hexo 的安装路径(/usr/local/bin 或 ~/node_modules/.bin) |
nano ~/.bashrc 编辑 |
添加自定义别名,这是用户级环境变量配置 |
核心理解:
环境变量 = “GPS 导航数据” —— 告诉程序“你在哪”、“能去哪”、“怎么走”。
四、三者在实际项目中的层次关系
text
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
五、一句总结
系统 profile 配置是给所有用户立规矩(大楼门禁),用户配置是给自己留空间(房间装饰),环境变量是在这些配置中定义的具体参数(GPS数据)。三者在实际运行中层层覆盖,共同决定了你在这个 Linux 环境中的操作体验。
四、Linux账户配置
这部分涉及用户账户、Home目录、权限管理。
可以查阅的位置:
- **
/etc/passwd**:用户账户信息(用户名、UID、Home 目录、默认 Shell)。 - **
/etc/group**:用户组信息,查看用户属于哪些组。 - **
/etc/shadow**:加密密码信息(需要sudo才能查看)。 ~/.ssh/目录:SSH 密钥和认证文件,其中authorized_keys是公钥认证的核心。id命令:查看当前用户的 UID、GID 和所属组。groups命令:查看用户所属的组。- **
ls -la ~/**:查看 Home 目录下所有文件和权限(包括隐藏文件)。 - 实验手册实验六:有
adduser、passwd、usermod、chmod、chown的详细用法。 - **
~/.bash_history**:记录你执行过的所有命令,可以回顾操作历史。
这个问题直接对应你答辩框架里的“Linux账户配置”这一项。我们用你在项目里实际做过的事情来拆解。
一、账户配置(Account Configuration)
账户配置是指Linux系统中与用户身份、组归属、登录行为相关的设置。它决定了“你是谁”、“你能做什么”。
账户配置的核心文件:
| 文件 | 作用 | 内容示例 |
|---|---|---|
/etc/passwd |
存储用户账户的基本信息(不包含密码) | tongshixuan:x:1000:1000::/home/tongshixuan:/bin/bash |
/etc/shadow |
存储用户的加密密码(只有root可读) | tongshixuan:$y$j9T$...:19000:0:99999:7::: |
/etc/group |
存储用户组信息 | sudo:x:27:tongshixuan |
/etc/sudoers |
定义哪些用户可以用sudo提权 |
tongshixuan ALL=(ALL:ALL) ALL |
字段解析:
| 字段 | 含义 | 在你的项目中的值 |
|---|---|---|
tongshixuan |
用户名 | 安装Ubuntu时创建的用户 |
x |
密码占位符(实际密码在/etc/shadow) |
固定值 |
1000 |
UID(用户ID) | 第一个普通用户为1000 |
1000 |
GID(主组ID) | 与UID相同 |
/home/tongshixuan |
Home目录路径 | 用户的主目录 |
/bin/bash |
登录Shell | 默认使用Bash |
你在项目中的实际操作:
| 操作 | 对应的账户配置 |
|---|---|
sudo adduser testuser |
在/etc/passwd和/etc/shadow中添加新用户条目 |
sudo usermod -aG sudo tongshixuan |
将用户添加到sudo组,修改/etc/group |
sudo passwd tongshixuan |
更新/etc/shadow中的加密密码 |
ssh tongshixuan@192.168.56.103 |
使用账户名tongshixuan登录,系统读取/etc/passwd验证用户是否存在 |
执行命令时加sudo |
系统检查/etc/sudoers,确认当前用户有提权权限 |
核心理解:
账户配置 = “身份证 + 门禁卡” —— 它记录了你是谁(UID)、住哪里(Home目录)、有什么权限(sudo组)。
二、Home配置(Home Directory Configuration)
Home配置是指用户主目录(/home/用户名/) 的组织方式和内容结构。它是用户在系统中的“个人空间”。
Home目录的典型结构:
1 | /home/tongshixuan/ |
你在项目中的实际操作:
| 操作 | 对应的Home配置 |
|---|---|
cd ~ 或 cd /home/tongshixuan |
进入用户主目录 |
ls -la ~/ |
查看Home目录下所有文件(包括.开头的隐藏文件) |
mkdir ~/.ssh |
创建.ssh目录,存放SSH相关配置 |
nano ~/.bashrc |
编辑用户级Shell配置文件,添加别名和环境变量 |
scp test.txt tongshixuan@192.168.56.103:/home/tongshixuan/ |
复制文件到目标用户的Home目录 |
核心理解:
Home配置 = “你的私人办公室” —— 里面的一切(
.bashrc、.ssh/)都只属于你,你可以随意布置。
三、关键文件的权限配置(File Permission Configuration)
权限配置是指通过chmod、chown等命令,为文件或目录设置读(r)、写(w)、执行(x)权限,以及所有者(owner)和所属组(group)。
权限的基本格式:
1 | -rw------- 1 tongshixuan tongshixuan 1693 Jul 7 15:35 .bash_history |
| 部分 | 含义 | 说明 |
|---|---|---|
-rw------- |
文件类型 + 权限 | -(文件)、rw-(所有者读写)、---(组无权限)、---(其他人无权限) |
1 |
硬链接数 | 通常为1 |
tongshixuan |
所有者 | 文件的创建者 |
tongshixuan |
所属组 | 文件所属的组 |
1693 |
文件大小(字节) | — |
Jul 7 15:35 |
修改时间 | — |
.bash_history |
文件名 | — |
权限的数字表示法:
| 数字 | 权限组合 | 含义 |
|---|---|---|
7 |
rwx |
读 + 写 + 执行(完全控制) |
6 |
rw- |
读 + 写 |
5 |
r-x |
读 + 执行 |
4 |
r-- |
只读 |
0 |
--- |
无权限 |
你在项目中的实际操作(关键文件权限配置):
| 操作 | 目的 | 命令 |
|---|---|---|
chmod 600 ~/.ssh/authorized_keys |
确保只有所有者能读/写该文件,防止其他用户篡改公钥 | SSH安全要求 |
chmod 700 ~/.ssh |
确保只有所有者能进入.ssh目录 |
SSH安全要求 |
chmod 644 ~/.ssh/id_ed25519.pub |
公钥可以公开读取(任何人可读),但只有所有者能写 | 公钥本身是公开的 |
sudo chown -R tongshixuan:tongshixuan /var/www/blog |
把站点目录的所有权从root改回普通用户,方便后续操作 |
避免每次都用sudo |
为什么这些权限配置如此重要?
| 场景 | 不正确的权限 | 风险 |
|---|---|---|
authorized_keys 权限为644 |
其他用户可以读取该文件,复制公钥,分析你的认证方式 | 信息泄露,但风险较低 |
authorized_keys 权限为777 |
其他用户可以修改该文件,添加他们自己的公钥,从而免密登录你的账户 | 严重安全问题! |
~/.ssh 权限为777 |
其他用户可以进入你的.ssh目录,删除或修改密钥文件 |
严重安全问题! |
/var/www/blog 权限不正确 |
无法正常读写站点文件,导致部署失败 | 功能性问题 |
核心理解:
权限配置 = “保险柜的密码” —— 好的权限管理能确保:你的私钥别人读不了(600)、你的公钥别人可以看(644)、你的关键目录别人进不去(700)。
四、三者关系总结
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
五、一句话总结
账户配置告诉系统“你是谁”(身份),Home配置决定“你在哪里”(空间),权限配置控制“你能做什么”(操作边界)。三者共同构成了Linux账户管理的完整体系。SSH安全的关键就在于:私钥文件(
id_ed25519)必须只有你一个人能读写(600),而公钥文件(id_ed25519.pub)可以公开分享(644)。
五、远程管理配置
这部分涉及SSH 服务、端口配置、登录认证。
可以查阅的位置:
- **
/etc/ssh/sshd_config**:SSH 服务端配置文件,包含端口、PermitRootLogin、PubkeyAuthentication、PasswordAuthentication 等关键配置。 - **
~/.ssh/config**:SSH 客户端配置文件,方便管理多个主机连接。 - **
~/.ssh/known_hosts**:记录已信任的远程主机指纹。 - **
systemctl status ssh**:查看 SSH 服务的运行状态。 - 实验手册实验七:有 SSH 服务安装、配置、密钥认证的完整步骤。
- **
ssh -Tv git@github.com**:详细调试信息,帮助排查 SSH 连接问题。 - Xshell 会话配置:你用来连接 node1 的会话设置(主机、端口、用户名)。
这个问题直接对应你答辩框架里的“远程管理配置”这一项。我们用你在项目里实际配置过的内容来拆解。
一、SSH服务(SSH Service)
SSH服务是指在服务器上运行的 SSH守护进程(sshd) ,它负责监听来自客户端的SSH连接请求,并在验证身份后建立安全的加密会话。
在你的Linux虚拟机中,SSH服务的核心信息:
| 项目 | 内容 | 说明 |
|---|---|---|
| 服务名称 | ssh 或 sshd |
systemctl 管理时使用 ssh |
| 主程序 | /usr/sbin/sshd |
SSH服务端的守护进程 |
| 配置文件 | /etc/ssh/sshd_config |
服务端配置文件(重要!) |
| 开机自启 | enabled(你已设置) |
虚拟机启动时自动运行SSH服务 |
| 当前状态 | active (running)(你已确认) |
服务正在运行,监听22端口 |
你在项目中的实际操作:
| 操作 | 命令 | 目的 |
|---|---|---|
| 检查SSH服务状态 | sudo systemctl status ssh |
确认SSH服务是否正在运行 |
| 安装SSH服务 | sudo apt install openssh-server -y |
如果未安装,手动安装 |
| 设置开机自启 | sudo systemctl enable ssh |
保证虚拟机重启后还能远程登录 |
| 重启SSH服务 | sudo systemctl restart ssh |
修改配置文件后使配置生效 |
核心理解:
SSH服务 = “大楼的门卫室” —— 它始终在运行,随时准备接待来访者(SSH客户端),验证身份后放行。
二、端口配置(Port Configuration)
端口配置是指设置SSH服务监听哪个网络端口,以及相关网络层级的访问控制。
在你的项目中,端口配置主要体现在两个层面:
1. SSH服务端端口配置(/etc/ssh/sshd_config)
| 配置项 | 默认值 | 你项目中的状态 | 说明 |
|---|---|---|---|
Port |
22 |
保持默认(未修改) | SSH服务监听的标准端口 |
ListenAddress |
0.0.0.0(所有网卡) |
保持默认 | 监听所有网络接口的SSH请求 |
PermitRootLogin |
prohibit-password |
保持默认 | 禁止root用密码登录(但可用密钥登录) |
你在项目中的实际操作:虽然没有修改端口,但你在
sshd_config中检查了PermitRootLogin、PubkeyAuthentication、PasswordAuthentication等配置项,确保SSH服务按预期工作。
2. 网络层端口访问控制
| 层级 | 工具 | 你项目中的状态 | 说明 |
|---|---|---|---|
| 防火墙 | ufw 或 iptables |
未启用(默认) | Ubuntu 22.04默认防火墙关闭 |
| 云安全组 | 不适用 | 虚拟机Host-Only网络 | 内网环境,无外部网络限制 |
| SELinux/AppArmor | AppArmor | 默认启用,未干预 | 不影响SSH连接 |
你在项目中的实际操作:
| 操作 | 命令 | 目的 |
|---|---|---|
| 查看SSH服务状态 | sudo systemctl status ssh |
确认服务正常运行 |
| 检查SSH服务监听端口 | sudo netstat -tlnp | grep ssh(未使用,但可参考) |
确认SSH在22端口监听 |
| 检查配置文件 | sudo nano /etc/ssh/sshd_config |
确认端口配置未被修改 |
核心理解:
端口配置 = “门卫室的窗口编号” —— 默认在22号窗口接待访客,你也可以改成其他窗口(但会让访客找不到门)。
三、登录配置(Login Configuration)
登录配置是指SSH服务端如何验证用户身份、允许哪些用户登录、以什么方式登录。
登录配置的核心参数(都在/etc/ssh/sshd_config中):
| 配置项 | 你项目中的值 | 作用 | 安全影响 |
|---|---|---|---|
PasswordAuthentication |
yes |
允许使用密码登录 | 方便但安全性较低(易被暴力破解) |
PubkeyAuthentication |
yes |
允许使用密钥登录 | 本项目核心认证方式,更安全 |
PermitRootLogin |
prohibit-password |
禁止root用密码登录,但允许密钥登录 | 防止root密码被暴力破解 |
PermitEmptyPasswords |
no(默认) |
禁止空密码登录 | 防止无密码账户被登录 |
MaxAuthTries |
6(默认) |
最大认证尝试次数 | 防止暴力破解 |
ClientAliveInterval |
未设置 | 客户端空闲超时时间 | 防止僵尸连接 |
AllowUsers |
未设置 | 只允许指定用户登录 | 可限制为 tongshixuan,更严格 |
你在项目中的实际操作:
| 操作 | 命令 | 目的 |
|---|---|---|
| 生成SSH密钥对 | ssh-keygen -t ed25519 -C "3360373468@qq.com" |
创建公钥/私钥,用于密钥认证 |
| 复制公钥到远程服务器 | ssh-copy-id tongshixuan@192.168.56.103 |
将公钥添加到node2的authorized_keys |
| 测试免密登录 | ssh tongshixuan@192.168.56.103 |
验证密钥认证是否成功 |
| 查看SSH配置文件 | sudo nano /etc/ssh/sshd_config |
确认PubkeyAuthentication yes和PasswordAuthentication yes |
核心理解:
登录配置 = “门卫室的访客登记规则” :你可以用密码(口令)进门,也可以用钥匙(密钥)进门。本项目推荐用钥匙,更安全。规则还规定:老板(root)不能只用口令进门,必须带钥匙。
四、SSH认证的两种方式对比
| 认证方式 | 原理 | 你项目中的状态 | 安全性 | 便捷性 |
|---|---|---|---|---|
| 密码认证 | 客户端输入密码,服务端验证 | ✅ 保持开启 | 较低(可被暴力破解) | 高(无需提前配置) |
| 密钥认证 | 客户端持有私钥签名,服务端用公钥验证 | ✅ 主要使用 | 极高(2048位以上加密) | 中(需提前部署公钥) |
你配置密钥认证的完整步骤:
1 | 客户端(node1) 服务端(node2) |
五、三者关系总结
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
六、一句话总结
SSH服务是远程管理的入口(门卫室),端口配置决定从哪个门进入(窗口编号),登录配置规定用什么方式验证身份(进门规则)。你在项目中主要完成了SSH服务的安装确认、配置检查和密钥认证部署,实现了从node1免密登录node2,这是远程管理的核心配置。
六、Web站点部署
这部分涉及可运行的站点、基本功能、部署脚本。
可以查阅的位置:
/var/www/blog/目录:站点文件存放位置,包含所有 HTML/CSS/JS。- **
/etc/nginx/sites-available/blog和/etc/nginx/sites-enabled/blog**:Nginx 站点配置文件。 http://192.168.56.103(虚拟机内网)和https://tristan1116.github.io(公网):两个可访问的站点地址。deploy-blog脚本:你创建的部署脚本(通常在~/.bashrc中定义了别名,或者是一个.sh文件)。- **
.github/workflows/deploy.yml**:GitHub Actions 自动化部署工作流文件。 - 实验手册实验四和实验八:有 Hexo 初始化、主题配置、部署到 GitHub Pages 和 Nginx 的完整步骤。
hexo generate生成的public/目录:构建后的静态文件,是最终部署的内容。rsync和scp命令的历史记录:查看你是如何将文件从本地传到 node1 再到 node2 的。
这个问题直接对应你答辩框架里的“Web站点部署”这一项,也是你所有实验成果的最终体现。我们用你项目里实际跑起来的东西来拆解。
一、可运行的站点(Running Site)
可运行的站点是指已经部署完成、可以通过浏览器访问的网站。它不是一个压缩包或一堆源代码,而是一个正在服务的、可访问的 Web 应用。
在你的项目中,有两个可运行的站点:
| 站点 | 访问地址 | 托管方式 | 访问范围 |
|---|---|---|---|
| 公网站点 | https://tristan1116.github.io |
GitHub Pages | 全球可访问 |
| 内网站点 | http://192.168.56.103 |
虚拟机 Nginx | 仅内网可访问 |
两个站点的部署架构:
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
可运行站点的组成:
| 组成部分 | 说明 | 你的站点中的体现 |
|---|---|---|
| HTML 文件 | 页面结构和内容 | Hexo 从 Markdown 生成的 .html 文件 |
| CSS 文件 | 样式和布局 | NexT 主题的 main.css |
| JavaScript 文件 | 交互功能 | 搜索、动画、统计等 .js 文件 |
| 静态资源 | 图片、字体等 | images/、fonts/ 目录 |
| 配置文件 | 站点元数据 | _config.yml 中的 title、url 等 |
核心理解:
可运行的站点 = “已经开张的店铺” —— 不是图纸(源码),不是建筑材料(Markdown),而是装修好、开门营业、客人可以进去逛的实体店。
二、基本功能(Basic Functionality)
基本功能是指站点为用户提供的核心能力,也是你作为博客系统必须实现的特性。
你的博客站点具备的基本功能:
| 功能 | 说明 | 技术实现 | 用户如何体验 |
|---|---|---|---|
| 文章展示 | 在首页和归档页显示文章列表 | Hexo 生成 index.html 和 archives/index.html |
访问首页看到文章列表 |
| 文章阅读 | 点击文章标题进入详情页,阅读完整内容 | Hexo 为每篇文章生成独立的 HTML | 点击任意文章标题查看 |
| 文章分类 | 按分类组织文章 | Hexo 生成 categories/ 目录 |
点击分类标签查看同类文章 |
| 文章标签 | 按标签组织文章 | Hexo 生成 tags/ 目录 |
点击标签查看相同标签文章 |
| 本地搜索 | 在站点内搜索文章内容 | hexo-generator-searchdb 生成 search.xml,主题 JS 实现搜索界面 |
点击搜索图标,输入关键词,实时过滤结果 |
| 字数统计 | 显示每篇文章的字数和阅读时间 | hexo-symbols-count-time 插件 |
文章顶部显示“字数:X |
| 页面加载进度 | 页面切换时显示顶部进度条 | pace 主题配置 |
切换页面时,屏幕顶部显示加载进度 |
| 响应式设计 | 适配电脑、平板、手机屏幕 | NexT 主题内置 | 在不同设备上自动调整布局 |
你在项目中的实际操作(功能配置示例):
| 配置的功能 | 你在哪里配置的 | 关键配置项 |
|---|---|---|
| 搜索 | _config.yml |
search: path: search.xml |
| 字数统计 | themes/next/_config.yml |
symbols_count_time: enable: true |
| 进度条 | themes/next/_config.yml |
pace: enable: true |
| 主题 | _config.yml |
theme: next |
核心理解:
基本功能 = “店铺里的商品和服务” —— 文章展示是书架,搜索是导购台,字数统计是标签。
三、部署脚本(Deployment Script)
部署脚本是指自动化执行部署步骤的命令或程序,它把“从源码到可运行站点”的手动操作变成一键执行。
你在项目中有两种部署方式:
1. 公网部署(GitHub Actions)
这是你通过 .github/workflows/deploy.yml 配置的自动化流程,不需要手动执行脚本,而是由 GitHub 自动触发。
工作流内容:
| 步骤 | 命令 | 作用 |
|---|---|---|
| 检出源码 | actions/checkout@v3 |
将 GitHub 仓库中的源码下载到 Actions 临时服务器 |
| 安装 Node.js | actions/setup-node@v3 |
在临时服务器上安装 Node.js 运行环境 |
| 缓存依赖 | actions/cache@v3 |
缓存 node_modules,加速后续构建 |
| 安装依赖 | npm install |
安装 package.json 中声明的所有依赖 |
| 生成静态文件 | npx hexo generate |
将 Markdown 编译成 HTML,生成 public/ 文件夹 |
创建 .nojekyll 文件 |
echo "" > public/.nojekyll |
告诉 GitHub Pages 不要用 Jekyll 处理文件 |
| 部署到 GitHub Pages | peaceiris/actions-gh-pages@v3 |
将 public/ 文件夹推送到 tristan1116.github.io 仓库 |
2. 内网部署(手动脚本)
你创建的 deploy-blog 脚本(在 ~/.bashrc 中设置别名),用来将本地生成的博客同步到虚拟机 Nginx 服务器。
脚本内容:
| 步骤 | 命令 | 作用 |
|---|---|---|
| 进入项目目录 | cd /d/blog/my-blog01 |
定位到博客源码根目录 |
| 生成静态文件 | hexo generate |
生成 public/ 文件夹 |
| 上传到 node1 | scp -r public/ tongshixuan@192.168.56.102:/home/tongshixuan/ |
把 public/ 文件夹传到跳板机 |
| 同步到 node2 | ssh node1 "rsync -avz --delete ~/public/ tongshixuan@192.168.56.103:/var/www/blog/" |
从 node1 增量同步到 node2 的 Nginx 站点目录 |
两种部署方式的对比:
| 对比维度 | GitHub Actions(公网) | 你的 deploy-blog 脚本(内网) |
|---|---|---|
| 触发方式 | git push 自动触发 |
手动执行 deploy-blog |
| 运行环境 | GitHub 临时服务器(Ubuntu) | 你的 Windows 本地(Git Bash) |
| 部署目标 | GitHub Pages(tristan1116.github.io) |
Nginx 服务器(/var/www/blog/) |
| 是否自动 | ✅ 完全自动 | ❌ 需手动运行 |
| 部署时间 | 1-2 分钟 | 几十秒 |
| 适用场景 | 正式发布 | 内网预览、快速测试 |
核心理解:
部署脚本 = “店铺的进货流程自动化” —— 把“关门 → 进货 → 摆货 → 开门”变成按一个按钮就完成的事。公网有全自动的进货机器人(GitHub Actions),内网是你手动推车(
deploy-blog脚本)。
四、三者关系总结
1 | ┌─────────────────────────────────────────────────────────────────────────────────┐ |
五、一句话总结
可运行的站点是最终产出物(两个能访问的网址),基本功能是站点的核心能力(文章展示、搜索、统计等),部署脚本是让产出物从“源码”变成“可运行站点”的自动化流程(GitHub Actions 和
deploy-blog)。三者共同构成了“从开发到上线”的完整闭环。
总结
| 问题模块 | 最核心的文件/命令 | 实验手册对应章节 |
|---|---|---|
| 项目与代码库配置 | _config.yml、.gitignore、package.json |
实验二、三 |
| Web运行环境 | package.json、hexo -v、npm config |
实验二 |
| Linux环境配置 | /etc/profile、/etc/netplan/、~/.bashrc |
实验六 |
| Linux账户配置 | /etc/passwd、~/.ssh/、chmod |
实验六 |
| 远程管理配置 | /etc/ssh/sshd_config、~/.ssh/config |
实验七 |
| Web站点部署 | /var/www/blog/、Nginx 配置、deploy.yml |
实验四、八 |