0%

hexo博客静态网站项目总结

项目整体回顾

第一层:项目概览与环境准备

问: 我们做的到底是个什么东西?它是怎么工作的?
答: 我们做的叫「静态博客」。它由一系列已经生成好的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文件定义的:

  1. 触发:你git push到my-blog01仓库。
  2. 运行环境:GitHub启动一台临时Ubuntu服务器。
  3. 检出代码:把你的源码下载到临时服务器。
  4. 安装依赖:执行npm install安装Hexo等依赖。
  5. 构建网站:执行hexo generate生成public文件夹。
  6. 部署:将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

基于这个分类,一个完整的网站应用通常会分为:

  1. 前端(客户端):你写的 HTML/CSS/JS 代码。
  2. 后端(服务器端):提供数据的 API 接口或生成页面的程序。
  3. 数据库:真正存储数据的地方(如用户信息、文章内容)。

四、举一反三:知识拓展

从问题出发,可以衍生出两个重要的概念:

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

为什么需要包管理器?

想象一下:如果没有包管理器,你要怎么做?

  1. 去 Hexo 官网下载源码
  2. 手动下载它的每个依赖
  3. 再下载每个依赖的依赖……(依赖地狱)
  4. 把这些文件一个个复制到项目里
  5. 还要处理版本冲突

这几乎是不可能的任务。

包管理器解决了这些问题:

功能 说明
自动解析依赖 你只需要写 "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)。

它的工作流程是:

  1. 输入:读取你的 Markdown 文章 + 主题模板 + 配置文件
  2. 处理:在 Node.js 环境中,把 Markdown 转换成 HTML,把数据填充进模板
  3. 输出:生成一套完整的 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 现代 Web 开发全景图 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📝 开发阶段(本地) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 你写内容:Markdown(数据) + YAML(配置) │ │
│ │ ↓ │ │
│ │ 构建工具:Hexo(运行在 Node.js 环境) │ │
│ │ ↓ │ │
│ │ 依赖管理:npm(包管理器) │ │
│ │ ↓ │ │
│ │ 版本控制:Git → GitHub(远程仓库) │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 🤖 自动化部署阶段(GitHub Actions) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 触发:Webhook(git push 自动触发) │ │
│ │ ↓ │ │
│ │ 执行环境:Ubuntu(Linux 虚拟机) │ │
│ │ ↓ │ │
│ │ 自动构建:npm install → hexo generate → git push │ │
│ │ ↓ │ │
│ │ 持续集成/部署:CI/CD 理念 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 🌐 运行阶段(公网) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 托管服务:GitHub Pages(静态文件托管) │ │
│ │ ↓ │ │
│ │ Web 服务器:Nginx(或 GitHub Pages 内置服务器) │ │
│ │ ↓ │ │
│ │ 用户浏览器:解析 HTML + CSS + JavaScript │ │
│ │ ↓ │ │
│ │ 交互逻辑:JavaScript(运行在浏览器环境) │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────────┤
│ 核心概念分层 │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 🧱 语言层:JavaScript, Markdown, YAML │ │
│ │ 🛠️ 工具层:Hexo, npm, Git │ │
│ │ ⚙️ 环境层:Node.js, 浏览器, Ubuntu │ │
│ │ 📦 平台层:GitHub, GitHub Actions, GitHub Pages │ │
│ │ 🧠 理念层:CI/CD, 静态站点生成, 版本控制 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘

五、回到问题: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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Hexo 完整执行逻辑 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📂 加载阶段(Load) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 1. 加载配置文件:读取项目根目录的 `_config.yml` │ │
│ │ 2. 加载主题配置:读取 `themes/<主题>/_config.yml` │ │
│ │ 3. 加载 package.json:获取项目依赖和脚本信息 │ │
│ │ 4. 加载插件:扫描并加载所有已安装的 Hexo 插件 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 📖 处理阶段(Process) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 5. 加载源文件:扫描 `source/` 目录下所有文件(.md, .html, .js等) │ │
│ │ 6. 解析 Front-matter:提取每篇文章开头的 `---` 元数据区域 │ │
│ │ 7. 分类处理:根据文件扩展名选择对应的渲染器(如 .md 用 Markdown 渲染器) │ │
│ │ 8. 渲染内容:把 Markdown → HTML,应用主题模板 │ │
│ │ 9. 应用标签/插件:处理文章中的 `{% %}` 标签和插件逻辑 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 📝 生成阶段(Generate) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 10. 构建页面:根据模板生成每个页面的完整 HTML │ │
│ │ 11. 生成归档:创建按日期、标签、分类的归档页面 │ │
│ │ 12. 生成索引:生成首页、文章列表页 │ │
│ │ 13. 资源处理:复制主题的静态资源(CSS/JS/图片)到 public 目录 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 💾 输出阶段(Write) │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 14. 写入文件:把所有生成的 HTML 和资源写入 `public/` 目录 │ │
│ │ 15. 输出日志:显示生成了哪些文件,耗时多少 │ │
│ │ 16. 完成:生成完毕,可以执行后续命令(如 hexo server 或 hexo deploy) │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────────┤
│ 关键特性: │
│ • 插件系统:通过 `hexo.extend` API 可以扩展任何环节 │
│ • 缓存机制:增量构建,只处理修改过的文件 │
│ • 异步处理:所有 I/O 操作都是异步的,充分利用 Node.js 的事件循环 │
└─────────────────────────────────────────────────────────────────────────────────┘

二、逐步拆解:每个阶段的具体工作

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 一篇文章的完整处理流程 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📄 原始文件:source/_posts/2026-07-09-markdown语法规则.md │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ --- │ │
│ │ title: markdown的语法规则 │ │
│ │ date: 2026-07-09 15:19:10 │ │
│ │ tags: [Markdown] │ │
│ │ categories: [语言] │ │
│ │ --- │ │
│ │ # markdown的语法规则 │ │
│ │ ## 一、标题 │ │
│ │ ... │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 🧩 解析 Front-matter │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ { │ │
│ │ title: 'markdown的语法规则', │ │
│ │ date: 2026-07-09T15:19:10.000Z, │ │
│ │ tags: ['Markdown'], │ │
│ │ categories: ['语言'], │ │
│ │ content: '# markdown的语法规则\n## 一、标题\n...' │ │
│ │ } │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 📝 渲染内容 │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ Markdown 解析器(marked / markdown-it)把 content 转换成 HTML │ │
│ │ "<h1>markdown的语法规则</h1><h2>一、标题</h2><p>...</p>" │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 🎨 填充模板 │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 主题模板(themes/next/layout/post.swig)接收 Post 对象 │ │
│ │ 把 title 渲染到 `<title>` 标签 │ │
│ │ 把 content 渲染到文章主体区域 │ │
│ │ 把 tags/categories 渲染到文章元数据区 │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 💾 输出文件:public/2026/07/09/markdown语法规则/index.html │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ <!DOCTYPE html> │ │
│ │ <html> │ │
│ │ <head><title>markdown的语法规则</title>...</head> │ │
│ │ <body>...<h1>markdown的语法规则</h1>...</body> │ │
│ │ </html> │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘

四、关键概念: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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
启动命令(hexo generate)
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 1. 初始化 Hexo 实例 │
│ • 加载所有配置文件 │
│ • 扫描并加载所有插件 │
└─────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 2. 执行 process 流程(异步,并行) │
│ • 扫描 source/ 目录 → 生成所有文件列表 │
│ • 对每个文件:检查缓存 → 解析 Front-matter → 渲染内容 │
│ • 把结果存入内存数据库(hexo.locals) │
└─────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 3. 执行 generate 流程 │
│ • 调用每个 Generator 插件,生成页面对象 │
│ • 应用主题模板,填充数据 │
│ • 调用 Filter 插件,修改或补充数据 │
└─────────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 4. 执行 write 流程 │
│ • 把每个页面对象写入 public/ 目录 │
│ • 复制静态资源(CSS/JS/图片) │
│ • 输出构建日志 │
└─────────────────────────────────────────────────────────────────────────────────┘
│
▼
构建完成 ✅

六、实际体验对照

你执行的命令 实际执行的流程
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
2
3
4
5
6
7
8
9
JavaScript 代码(你写的)
↓
V8 引擎(解析和执行代码)
↓
Node.js 封装层(提供文件、网络等 API)
↓
操作系统(Windows/Linux/macOS)
↓
硬件(CPU、内存、硬盘)

二、Node.js 的运行逻辑:事件驱动 + 非阻塞 I/O

这是 Node.js 最核心、也最容易被误解的部分。

1. 单线程 + 事件循环

你之前学 C/C++ 时,程序通常是多线程的:每个任务分配一个线程,多个线程可以同时执行。

Node.js 完全不同:它是单线程的,但通过“事件循环”来处理大量并发任务。

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Node.js 运行时架构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 主线程(单线程) │ │
│ │ ┌────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ 事件循环(Event Loop) │ │ │
│ │ │ │ │ │
│ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │
│ │ │ │ 定时器 │ │ I/O │ │ 空闲 │ │ 关闭 │ │ │ │
│ │ │ │ 回调 │──▶│ 回调 │──▶│ 回调 │──▶│ 回调 │ │ │ │
│ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ │
│ │ │ ▲ ▲ ▲ ▲ │ │ │
│ │ └────────┼──────────────┼──────────────┼──────────────┼──────────────┘ │ │
│ │ │ │ │ │ │ │
│ └───────────┼──────────────┼──────────────┼──────────────┼──────────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 异步任务池(由操作系统或线程池处理) │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 文件读取 │ │ 网络请求 │ │ 数据库查询 │ │ 定时器 │ │ │
│ │ │ (fs.read) │ │ (http.get) │ │ (SQL查询) │ │ (setTimeout)│ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────────┘

关键理解:

概念 含义 类比
单线程 只有一个主线程在执行 JavaScript 代码 一个服务员在接待客人
事件循环 主线程不断检查“待办事项队列”,有任务就处理 服务员不断看排队列表,有新的就接待
异步 I/O 耗时的操作(读文件、网络请求)交给操作系统去做,主线程不等待 服务员点完菜后,不站在厨房等,而是去接待下一位客人
非阻塞 主线程不会被阻塞,可以继续执行其他任务 服务员不会被一个客人的慢动作困住

2. 一个具体的例子:hexo generate 在 Node.js 里怎么跑?

当你执行 hexo generate 时,Node.js 内部是这样的:

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1. Node.js 启动,加载 hexo 命令脚本
│
▼
2. 解析命令行参数,确定要执行 `generate` 命令
│
▼
3. 主线程开始执行 hexo 的 `generate` 方法
│
├── 读取 `_config.yml`(同步操作,快)
├── 扫描 `source/_posts/`(同步操作,快)
│
▼
4. 开始处理文章(异步操作,慢)
│
├── 读取文章1.md → 交给操作系统,不等待
├── 读取文章2.md → 交给操作系统,不等待
├── 读取文章3.md → 交给操作系统,不等待
│ │ │
│ ▼ ▼
│ 主线程继续处理其他任务
│ │
└── 等所有文章读取完成后,再处理它们的渲染
│
▼
5. 渲染所有文章(同步操作,快)
│
▼
6. 写入 `public/` 目录(同步操作,快)
│
▼
7. 输出日志,完成

关键点: 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 服务器。

六、一组帮助你加深理解的思考题

  1. 如果 Node.js 是单线程的,为什么 hexo generate 还能并发处理多篇文章?(提示:异步 I/O 把读文件的工作交给了操作系统)
  2. 为什么你不能用浏览器去执行 hexo generate 命令?(提示:浏览器没有 fs 文件系统模块,也没有命令行入口)
  3. 如果把 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站点部署 可运行的站点、基本功能、部署脚本

一、项目与代码库配置

这部分内容涉及项目组织方式、版本控制、编辑器配置。

可以查阅的位置:

  1. **项目根目录的 _config.yml**:站点的核心配置文件,包含站点名称、作者、主题、部署信息等,是了解项目整体配置的第一入口。
  2. .gitignore 文件:记录哪些文件和目录不提交到 Git(如 node_modules/、public/),这是版本控制配置的直接体现。
  3. **package.json 和 package-lock.json**:记录项目依赖和脚本,可以看到用到了哪些包和工具链。
  4. VS Code 设置(.vscode/ 目录或全局设置):编辑器相关的配置,如自动保存、插件等。
  5. 实验手册实验二和三:有详细的 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
2
3
4
my-blog01/
└── .vscode/
├── settings.json # 项目专属 VS Code 设置
└── extensions.json # 推荐给其他开发者的插件列表

你的项目里可能没有这些文件,因为它们是可选的,不属于 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 项目与代码库配置 三层结构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📋 项目配置(店铺信息) │
│ ├── _config.yml:站点标题、URL、主题、部署目标(营业执照) │
│ ├── package.json:项目名称、依赖包(进货清单) │
│ └── package-lock.json:依赖精确版本(清单明细) │
│ │ │
│ │ 在编辑器中操作 │
│ ▼ │
│ ✏️ 编辑器配置(收银台布局) │
│ ├── VS Code 用户设置:自动保存、字体大小、折行(操作习惯) │
│ ├── VS Code 插件:Markdown All in One、Preview Enhanced(专业工具) │
│ └── 项目级 .vscode/:项目专属编辑器设置(可选) │
│ │ │
│ │ 用 Git 管理 │
│ ▼ │
│ 🔄 Git 配置(记账系统) │
│ ├── 全局配置 `~/.gitconfig`:用户名、邮箱、换行符处理(总店规则) │
│ ├── 本地配置 `.git/config`:远程仓库地址、分支关联(分店规则) │
│ └── `.gitignore`:排除 node_modules/、public/ 等(不记账的东西) │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

五、一句话总结

项目配置定义了“这是一个什么项目”(_config.yml + package.json),编辑器配置定义了“用什么工具、怎么编辑”(VS Code 设置 + 插件),Git 配置定义了“怎么版本控制和提交”(.gitconfig + .gitignore)。三者共同构成了项目的“基本盘”,是你在本地开发的起点。

二、Web运行环境

这部分涉及Node.js、npm、Hexo 及其插件的运行环境。

可以查阅的位置:

  1. **package.json 中的 dependencies 和 devDependencies**:列出所有运行时依赖,是了解环境组成的最佳入口。
  2. hexo -v 命令的输出:显示 Hexo 版本和依赖组件列表。
  3. 实验手册实验二:有 Node.js、npm、Git 的安装和验证步骤。
  4. 镜像源配置: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
2
3
4
5
6
7
8
                    hexo-cli(全局工具,用来执行命令)
│
▼
┌───────────────────hexo(核心框架)───────────────────┐
│ │ │ │
▼ ▼ ▼ ▼
hexo-server hexo-generator- hexo-symbols- hexo-helper-
(本地预览) searchdb(搜索) count-time(统计) live2d(看板娘)

查看所有已安装的包:

bash

1
2
3
4
5
# 查看项目依赖(在项目根目录执行)
npm list --depth=0

# 查看 package.json 中的依赖
cat package.json

四、配置(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
2
3
4
5
6
7
8
# 查看站点配置
cat _config.yml

# 查看主题配置
cat themes/next/_config.yml

# 查看依赖配置
cat package.json

五、总结:四者关系

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Web运行环境 四要素关系 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 📦 语言包(Node.js) │
│ └── 提供运行环境,让 JavaScript 代码可以执行 │
│ │ │
│ ▼ │
│ 📦 包管理器(npm) │
│ └── 自动下载和管理软件包,配置镜像源加速下载 │
│ │ │
│ ▼ │
│ 📦 关键软件包(Hexo + 插件) │
│ └── 提供博客生成、搜索、统计等具体功能 │
│ │ │
│ ▼ │
│ 📦 配置(_config.yml + package.json) │
│ └── 控制语言包、包管理器、软件包的行为,把所有东西串在一起 │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

一句话总结:

语言包(Node.js)是运行环境,包管理器(npm)是下载工具,关键软件包(Hexo 及插件)是功能组件,配置是让它们按你期望方式工作的“说明书”。四者缺一不可,共同构成了 Web 运行环境的完整生态。

三、Linux环境配置

这部分涉及系统级配置文件、环境变量、Shell 行为。

可以查阅的位置:

  1. **/etc/profile**:系统级环境变量配置,影响所有用户。
  2. **/etc/environment**:系统级环境变量(更底层)。
  3. **/etc/netplan/50-cloud-init.yaml**:网络配置(静态IP),这是实验五中的核心配置。
  4. **/etc/hosts**:主机名解析文件,配置了 node1、node2、node3 的 IP 映射。
  5. **~/.bashrc 和 ~/.profile**:用户级 Shell 配置文件,包含别名(如 deploy-blog)和自定义变量。
  6. 实验手册实验六:专门讲解系统 profile 配置、用户配置、环境变量。
  7. hostnamectl 命令:查看和修改主机名。
  8. 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Linux环境配置 三层结构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 🏢 系统级(影响所有用户) │
│ ├── /etc/profile 系统全局配置 │
│ ├── /etc/environment 系统环境变量 │
│ └── /etc/ssh/sshd_config 系统 SSH 服务配置 │
│ │ │
│ │ 继承并覆盖 │
│ ▼ │
│ 👤 用户级(影响当前用户) │
│ ├── ~/.bashrc 用户 Shell 配置 │
│ ├── ~/.profile 用户登录配置 │
│ ├── ~/.ssh/config 用户 SSH 配置 │
│ └── ~/.bash_logout 用户退出配置 │
│ │ │
│ │ 定义和存储 │
│ ▼ │
│ 🔑 环境变量(键值对) │
│ ├── PATH 可执行文件搜索路径 │
│ ├── HOME 用户主目录 │
│ ├── USER 当前用户名 │
│ └── MY_VAR 自定义变量 │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

五、一句总结

系统 profile 配置是给所有用户立规矩(大楼门禁),用户配置是给自己留空间(房间装饰),环境变量是在这些配置中定义的具体参数(GPS数据)。三者在实际运行中层层覆盖,共同决定了你在这个 Linux 环境中的操作体验。

四、Linux账户配置

这部分涉及用户账户、Home目录、权限管理。

可以查阅的位置:

  1. **/etc/passwd**:用户账户信息(用户名、UID、Home 目录、默认 Shell)。
  2. **/etc/group**:用户组信息,查看用户属于哪些组。
  3. **/etc/shadow**:加密密码信息(需要 sudo 才能查看)。
  4. ~/.ssh/ 目录:SSH 密钥和认证文件,其中 authorized_keys 是公钥认证的核心。
  5. id 命令:查看当前用户的 UID、GID 和所属组。
  6. groups 命令:查看用户所属的组。
  7. **ls -la ~/**:查看 Home 目录下所有文件和权限(包括隐藏文件)。
  8. 实验手册实验六:有 adduser、passwd、usermod、chmod、chown 的详细用法。
  9. **~/.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
2
3
4
5
6
7
8
9
10
11
12
13
/home/tongshixuan/
├── .bashrc # Bash Shell 配置文件(用户级)
├── .profile # 登录配置文件
├── .bash_logout # 退出时执行的命令
├── .ssh/ # SSH 配置目录
│ ├── id_ed25519 # SSH 私钥(权限600)
│ ├── id_ed25519.pub # SSH 公钥(权限644)
│ ├── authorized_keys # 允许登录的公钥列表(权限600)
│ └── config # SSH 客户端配置
├── .cache/ # 缓存文件目录
├── .bash_history # 命令历史记录
├── public/ # Hexo 生成的静态文件(你同步过来的)
└── test_rsync/ # 测试用的同步目录

你在项目中的实际操作:

操作 对应的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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Linux账户配置 三层结构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 🪪 账户配置(身份) │
│ ├── /etc/passwd → 你是谁? │
│ ├── /etc/shadow → 你的密码是什么? │
│ └── /etc/group → 你在哪个组? │
│ │ │
│ │ 定位到 │
│ ▼ │
│ 🏠 Home配置(空间) │
│ ├── /home/tongshixuan/ → 你的专属目录 │
│ ├── .ssh/ → SSH相关文件存放位置 │
│ └── .bashrc → Shell个性化配置 │
│ │ │
│ │ 通过权限控制 │
│ ▼ │
│ 🔒 权限配置(控制) │
│ ├── chmod 600 ~/.ssh/authorized_keys → 只有你能写 │
│ ├── chmod 700 ~/.ssh → 只有你能进 │
│ └── chown tongshixuan:tongshixuan /var/www/blog → 你是所有者 │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

五、一句话总结

账户配置告诉系统“你是谁”(身份),Home配置决定“你在哪里”(空间),权限配置控制“你能做什么”(操作边界)。三者共同构成了Linux账户管理的完整体系。SSH安全的关键就在于:私钥文件(id_ed25519)必须只有你一个人能读写(600),而公钥文件(id_ed25519.pub)可以公开分享(644)。

五、远程管理配置

这部分涉及SSH 服务、端口配置、登录认证。

可以查阅的位置:

  1. **/etc/ssh/sshd_config**:SSH 服务端配置文件,包含端口、PermitRootLogin、PubkeyAuthentication、PasswordAuthentication 等关键配置。
  2. **~/.ssh/config**:SSH 客户端配置文件,方便管理多个主机连接。
  3. **~/.ssh/known_hosts**:记录已信任的远程主机指纹。
  4. **systemctl status ssh**:查看 SSH 服务的运行状态。
  5. 实验手册实验七:有 SSH 服务安装、配置、密钥认证的完整步骤。
  6. **ssh -Tv git@github.com**:详细调试信息,帮助排查 SSH 连接问题。
  7. 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
2
3
4
5
6
7
8
9
10
11
12
13
客户端(node1)                          服务端(node2)
│
├── ssh-keygen 生成密钥对
│ ├── id_ed25519(私钥,自己保管)
│ └── id_ed25519.pub(公钥,准备发送)
│
├── ssh-copy-id tongshixuan@node2
│ └── 公钥被追加到 ~/.ssh/authorized_keys
│
├── ssh tongshixuan@node2
│ ├── 客户端用私钥签名请求
│ ├── 服务端用公钥验证签名
│ └── ✅ 验证通过,免密登录

五、三者关系总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 远程管理配置 三层结构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 🛡️ SSH服务(谁在接待) │
│ ├── sshd 守护进程:持续运行,监听22端口 │
│ ├── systemctl status ssh:确认服务状态 │
│ └── systemctl enable ssh:保证开机自启 │
│ │ │
│ │ 绑定到 │
│ ▼ │
│ 📡 端口配置(从哪个门进) │
│ ├── Port 22:默认端口(未修改) │
│ ├── ListenAddress 0.0.0.0:监听所有网卡 │
│ └── 防火墙规则:未启用(内网环境) │
│ │ │
│ │ 定义规则 │
│ ▼ │
│ 🔑 登录配置(怎么验证身份) │
│ ├── PasswordAuthentication yes:允许密码登录 │
│ ├── PubkeyAuthentication yes:允许密钥登录(推荐) │
│ ├── PermitRootLogin prohibit-password:root只能密钥登录 │
│ └── ssh-copy-id:将公钥部署到远程服务器 │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

六、一句话总结

SSH服务是远程管理的入口(门卫室),端口配置决定从哪个门进入(窗口编号),登录配置规定用什么方式验证身份(进门规则)。你在项目中主要完成了SSH服务的安装确认、配置检查和密钥认证部署,实现了从node1免密登录node2,这是远程管理的核心配置。

六、Web站点部署

这部分涉及可运行的站点、基本功能、部署脚本。

可以查阅的位置:

  1. /var/www/blog/ 目录:站点文件存放位置,包含所有 HTML/CSS/JS。
  2. **/etc/nginx/sites-available/blog 和 /etc/nginx/sites-enabled/blog**:Nginx 站点配置文件。
  3. http://192.168.56.103(虚拟机内网)和 https://tristan1116.github.io(公网):两个可访问的站点地址。
  4. deploy-blog 脚本:你创建的部署脚本(通常在 ~/.bashrc 中定义了别名,或者是一个 .sh 文件)。
  5. **.github/workflows/deploy.yml**:GitHub Actions 自动化部署工作流文件。
  6. 实验手册实验四和实验八:有 Hexo 初始化、主题配置、部署到 GitHub Pages 和 Nginx 的完整步骤。
  7. hexo generate 生成的 public/ 目录:构建后的静态文件,是最终部署的内容。
  8. rsync 和 scp 命令的历史记录:查看你是如何将文件从本地传到 node1 再到 node2 的。

这个问题直接对应你答辩框架里的“Web站点部署”这一项,也是你所有实验成果的最终体现。我们用你项目里实际跑起来的东西来拆解。


一、可运行的站点(Running Site)

可运行的站点是指已经部署完成、可以通过浏览器访问的网站。它不是一个压缩包或一堆源代码,而是一个正在服务的、可访问的 Web 应用。

在你的项目中,有两个可运行的站点:

站点 访问地址 托管方式 访问范围
公网站点 https://tristan1116.github.io GitHub Pages 全球可访问
内网站点 http://192.168.56.103 虚拟机 Nginx 仅内网可访问

两个站点的部署架构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 两个站点的部署架构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 你的博客源码(Markdown + 主题 + 配置) │
│ │ │
│ ├──────────────────┬─────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────────────────┐ │
│ │ GitHub Actions 自动构建 │ │ 本地 hexo generate 手动构建 │ │
│ │ └── 生成 public/ 文件夹 │ │ └── 生成 public/ 文件夹 │ │
│ └─────────────────────────────┘ └─────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────────────────┐ │
│ │ GitHub Pages 托管 │ │ Nginx 托管(虚拟机 node2) │ │
│ │ └── 全球 CDN 加速 │ │ └── 内网访问 │ │
│ └─────────────────────────────┘ └─────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ 🌍 https://tristan1116.github.io 🏠 http://192.168.56.103 │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

可运行站点的组成:

组成部分 说明 你的站点中的体现
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Web站点部署 三层结构 │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ 🏪 可运行的站点(开店营业) │
│ ├── https://tristan1116.github.io(公网店铺,全球客人都能来) │
│ └── http://192.168.56.103(内网店铺,只有你自己能看) │
│ │ │
│ │ 提供服务 │
│ ▼ │
│ 📋 基本功能(店内商品和服务) │
│ ├── 文章展示、阅读、分类、标签 │
│ ├── 本地搜索(`hexo-generator-searchdb`) │
│ ├── 字数统计(`hexo-symbols-count-time`) │
│ └── 加载进度条(`pace`) │
│ │ │
│ │ 靠脚本维持 │
│ ▼ │
│ ⚙️ 部署脚本(自动上货流程) │
│ ├── GitHub Actions(公网:git push 自动触发) │
│ └── deploy-blog(内网:手动执行) │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘

五、一句话总结

可运行的站点是最终产出物(两个能访问的网址),基本功能是站点的核心能力(文章展示、搜索、统计等),部署脚本是让产出物从“源码”变成“可运行站点”的自动化流程(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 实验四、八