feat: add comprehensive backend topics and fix build issues

## 新增内容

### 附录文档扩展
- 扩展前端项目架构文档 (frontend-project-architecture.md)
- 扩展后端项目架构文档 (backend-project-architecture.md)
- 扩展数据治理文档 (data-governance.md)
- 扩展数据可视化文档 (data-visualization.md)
- 扩展分布式系统文档 (distributed-systems.md)
- 扩展高可用文档 (high-availability.md)
- 扩展单体到微服务文档 (monolith-to-microservices.md)
- 扩展系统设计方法论文档 (system-design-methodology.md)
- 扩展 Docker 容器文档 (docker-containers.md)
- 扩展 Kubernetes 文档 (kubernetes.md)
- 扩展 Linux 基础文档 (linux-basics.md)
- 扩展神经网络文档 (neural-networks.md)

### 新增交互式组件
- 数据治理组件: DataQualityDemo, DataGovernanceFrameworkDemo, DataLineageDemo
- 数据可视化组件: ChartTypeSelectorDemo, DashboardLayoutDemo
- 分布式系统组件: CAPTheoremDemo, ConsistencyModelsDemo, DistributedChallengesDemo
- 高可用组件: AvailabilityCalculatorDemo, FailoverStrategyDemo
- 系统设计组件: SystemDesignStepsDemo, CapacityEstimationDemo
- Docker 容器组件: DockerArchitectureDemo, DockerLifecycleDemo
- Kubernetes 组件: K8sArchitectureDemo, K8sWorkloadsDemo
- Linux 基础组件: LinuxFileSystemDemo, LinuxCommandDemo, LinuxPermissionsDemo
- 神经网络组件: NeuronDemo, NetworkLayersDemo, NetworkArchitectureDemo
- 单体到微服务组件: ArchEvolutionDemo
- 项目架构组件: ProjectArchitectureComparisonDemo
- 附录导航组件: AppendixFlowMap

### 英文版重构
- 将 en-us 目录重命名为 en
- 更新相关配置和组件中的语言代码

## Bug 修复
- 修复 index.js 中重复的组件导入语句导致的 build 失败
- 恢复被注释的 InvertedIndexDemo 和 SearchRelevanceDemo 导入
- 修复 HomeFeatures.vue 中 en-us 与 config.mjs 中 en 不一致导致的语言切换问题

## 其他改进
- 添加构建脚本 (scripts/build.mjs)
- 更新依赖版本
This commit is contained in:
sanbuphy
2026-02-26 04:35:28 +08:00
parent df51f84ab5
commit ef70b1d8e1
84 changed files with 12917 additions and 3477 deletions
@@ -0,0 +1,222 @@
<!--
NetworkArchitectureDemo.vue
神经网络架构对比演示
-->
<template>
<div class="net-arch-demo">
<div class="header">
<div class="title">常见神经网络架构</div>
<div class="subtitle">点击查看不同网络架构的特点和应用</div>
</div>
<div class="arch-tabs">
<button
v-for="arch in architectures"
:key="arch.key"
:class="['arch-btn', { active: activeArch === arch.key }]"
@click="activeArch = arch.key"
>
{{ arch.name }}
</button>
</div>
<div v-if="current" class="detail-panel">
<div class="detail-header">
<div class="detail-title">{{ current.name }}{{ current.abbr }}</div>
<div class="detail-year">{{ current.year }}</div>
</div>
<div class="detail-desc">{{ current.desc }}</div>
<div class="structure">
<div class="struct-label">网络结构</div>
<div class="struct-visual">
<span v-for="(layer, i) in current.layers" :key="i" class="layer-tag">
{{ layer }}
<span v-if="i < current.layers.length - 1" class="layer-arrow"></span>
</span>
</div>
</div>
<div class="apps">
<div class="apps-label">典型应用</div>
<div class="apps-list">
<span v-for="(app, i) in current.applications" :key="i" class="app-tag">{{ app }}</span>
</div>
</div>
<div class="key-idea">
<span class="idea-label">核心思想</span>{{ current.keyIdea }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const activeArch = ref('ffn')
const architectures = [
{
key: 'ffn',
name: '前馈神经网络',
abbr: 'FNN',
year: '1958',
desc: '最基础的神经网络结构,数据从输入层经过隐藏层到输出层,单向流动,没有循环。每一层的每个神经元与下一层的所有神经元相连(全连接)。',
layers: ['输入层', '隐藏层 ×N', '输出层'],
applications: ['分类', '回归', '函数逼近'],
keyIdea: '通过多层非线性变换,将输入映射到输出。层数越多,能表达的函数越复杂。'
},
{
key: 'cnn',
name: '卷积神经网络',
abbr: 'CNN',
year: '1998',
desc: '专为处理网格状数据(如图像)设计。通过卷积核在输入上滑动提取局部特征,池化层降低维度,最后全连接层做分类。参数共享大幅减少了参数量。',
layers: ['输入', '卷积层', '池化层', '...', '全连接层', '输出'],
applications: ['图像分类', '目标检测', '人脸识别', '医学影像'],
keyIdea: '局部感受野 + 参数共享。卷积核只关注局部区域,同一个卷积核在整张图上共享参数。'
},
{
key: 'rnn',
name: '循环神经网络',
abbr: 'RNN/LSTM',
year: '1997',
desc: '专为处理序列数据设计。隐藏状态会传递到下一个时间步,让网络具有"记忆"能力。LSTM 通过门控机制解决了长序列中的梯度消失问题。',
layers: ['输入序列', '循环层(含记忆)', '...', '输出序列'],
applications: ['机器翻译', '语音识别', '时间序列预测', '文本生成'],
keyIdea: '引入时间维度的循环连接,让网络能处理变长序列并保持上下文记忆。'
},
{
key: 'transformer',
name: 'Transformer',
abbr: 'Transformer',
year: '2017',
desc: '用自注意力机制替代循环结构,可以并行处理整个序列。每个位置都能直接关注序列中的任意其他位置,解决了 RNN 的长距离依赖问题。是 GPT、BERT 等大模型的基础。',
layers: ['输入嵌入', '位置编码', '多头注意力', '前馈网络', '...×N', '输出'],
applications: ['ChatGPT', 'BERT', '机器翻译', '代码生成', '图像生成'],
keyIdea: '自注意力(Self-Attention):让序列中的每个元素都能"看到"其他所有元素,计算相关性权重。'
},
{
key: 'gan',
name: '生成对抗网络',
abbr: 'GAN',
year: '2014',
desc: '由生成器和判别器两个网络对抗训练。生成器试图生成以假乱真的数据,判别器试图区分真假。两者博弈的结果是生成器越来越强。',
layers: ['随机噪声', '生成器', '生成数据', '判别器', '真/假'],
applications: ['图像生成', '风格迁移', '超分辨率', '数据增强'],
keyIdea: '对抗训练:生成器和判别器互相博弈,共同进步,最终生成器能产生逼真的数据。'
}
]
const current = computed(() => architectures.find(a => a.key === activeArch.value))
</script>
<style scoped>
.net-arch-demo {
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg-soft);
border-radius: 12px;
padding: 1.5rem;
margin: 1.5rem 0;
}
.header { margin-bottom: 1rem; }
.title { font-weight: 700; font-size: 1.1rem; }
.subtitle { color: var(--vp-c-text-2); font-size: 0.9rem; }
.arch-tabs {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-bottom: 1rem;
}
.arch-btn {
padding: 0.35rem 0.7rem;
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
background: var(--vp-c-bg);
cursor: pointer;
font-size: 0.8rem;
font-weight: 600;
color: var(--vp-c-text-2);
transition: all 0.2s;
}
.arch-btn:hover { border-color: var(--vp-c-brand); }
.arch-btn.active {
background: var(--vp-c-brand);
color: #fff;
border-color: var(--vp-c-brand);
}
.detail-panel {
background: var(--vp-c-bg);
border-radius: 8px;
padding: 1rem;
border: 1px solid var(--vp-c-divider);
}
.detail-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.4rem;
}
.detail-title { font-weight: 700; font-size: 0.95rem; }
.detail-year {
font-size: 0.72rem;
padding: 0.1rem 0.4rem;
background: rgba(var(--vp-c-brand-rgb, 100, 108, 255), 0.1);
color: var(--vp-c-brand);
border-radius: 4px;
font-weight: 600;
}
.detail-desc {
font-size: 0.82rem;
color: var(--vp-c-text-2);
margin-bottom: 0.75rem;
line-height: 1.6;
}
.structure, .apps {
margin-bottom: 0.5rem;
}
.struct-label, .apps-label {
font-size: 0.72rem;
font-weight: 600;
color: var(--vp-c-text-3);
margin-bottom: 0.3rem;
}
.struct-visual {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.2rem;
}
.layer-tag {
font-size: 0.75rem;
padding: 0.2rem 0.5rem;
background: var(--vp-c-bg-soft);
border-radius: 4px;
font-weight: 600;
}
.layer-arrow {
color: var(--vp-c-text-3);
margin: 0 0.1rem;
}
.apps-list {
display: flex;
flex-wrap: wrap;
gap: 0.3rem;
}
.app-tag {
font-size: 0.72rem;
padding: 0.15rem 0.4rem;
background: rgba(34, 197, 94, 0.1);
color: var(--vp-c-text-1);
border-radius: 4px;
}
.key-idea {
font-size: 0.8rem;
padding: 0.5rem;
background: var(--vp-c-bg-soft);
border-radius: 6px;
line-height: 1.5;
}
.idea-label { font-weight: 600; color: var(--vp-c-text-2); }
</style>
@@ -0,0 +1,132 @@
<!--
NetworkLayersDemo.vue
神经网络层类型交互演示
-->
<template>
<div class="layers-demo">
<div class="header">
<div class="title">神经网络常见层类型</div>
<div class="subtitle">点击查看各层的作用和参数</div>
</div>
<div class="layer-tabs">
<button v-for="l in layers" :key="l.key"
:class="['tab-btn', { active: activeLayer === l.key }]"
@click="activeLayer = activeLayer === l.key ? null : l.key">
{{ l.name }}
</button>
</div>
<div v-if="current" class="layer-detail">
<div class="detail-name">{{ current.name }}</div>
<div class="detail-desc">{{ current.desc }}</div>
<div class="detail-section">
<span class="section-label">核心参数</span>
<code v-for="(p, i) in current.params" :key="i" class="param-tag">{{ p }}</code>
</div>
<div class="detail-section">
<span class="section-label">典型用途</span>
<span class="usage-text">{{ current.usage }}</span>
</div>
<div class="detail-code">
<code>{{ current.code }}</code>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const activeLayer = ref('dense')
const layers = [
{
key: 'dense',
name: '全连接层',
desc: '每个神经元与上一层所有神经元相连。最基础的层类型,用于学习输入特征的组合。',
params: ['units(神经元数)', 'activation(激活函数)'],
usage: '分类、回归任务的输出层,以及简单特征提取',
code: 'Dense(128, activation="relu")'
},
{
key: 'conv',
name: '卷积层',
desc: '用滑动窗口(卷积核)扫描输入,提取局部特征。参数共享大幅减少参数量,是图像处理的核心。',
params: ['filters(卷积核数)', 'kernel_size(核大小)', 'stride(步长)'],
usage: '图像分类、目标检测、图像分割',
code: 'Conv2D(64, kernel_size=3, stride=1, padding=1)'
},
{
key: 'rnn',
name: '循环层',
desc: '具有"记忆"能力,能处理序列数据。每个时间步的输出会作为下一步的输入,形成循环。',
params: ['hidden_size(隐藏维度)', 'num_layers(层数)'],
usage: '文本生成、语音识别、时间序列预测',
code: 'LSTM(hidden_size=256, num_layers=2)'
},
{
key: 'attention',
name: '注意力层',
desc: '让模型学会"关注"输入中最重要的部分。Transformer 的核心,彻底改变了 NLP 领域。',
params: ['embed_dim(嵌入维度)', 'num_heads(注意力头数)'],
usage: 'GPT、BERT 等大语言模型,机器翻译',
code: 'MultiHeadAttention(embed_dim=512, num_heads=8)'
},
{
key: 'norm',
name: '归一化层',
desc: '将数据标准化到合理范围,加速训练收敛,缓解梯度消失/爆炸问题。',
params: ['num_features(特征数)'],
usage: '几乎所有深度网络中都会使用,通常跟在卷积或全连接层后面',
code: 'BatchNorm2d(64) / LayerNorm(512)'
},
{
key: 'dropout',
name: 'Dropout 层',
desc: '训练时随机"关闭"一部分神经元,防止网络过度依赖某些特征,是最常用的正则化手段。',
params: ['p(丢弃概率,通常 0.1~0.5'],
usage: '防止过拟合,提升模型泛化能力',
code: 'Dropout(p=0.3)'
}
]
const current = computed(() => layers.find(l => l.key === activeLayer.value))
</script>
<style scoped>
.layers-demo {
border: 1px solid var(--vp-c-divider); background: var(--vp-c-bg-soft);
border-radius: 12px; padding: 1.5rem; margin: 1.5rem 0;
}
.header { margin-bottom: 1rem; }
.title { font-weight: 700; font-size: 1.1rem; }
.subtitle { color: var(--vp-c-text-2); font-size: 0.9rem; }
.layer-tabs { display: flex; gap: 0.4rem; margin-bottom: 1rem; flex-wrap: wrap; }
.tab-btn {
padding: 0.35rem 0.7rem; border-radius: 6px; cursor: pointer;
font-size: 0.8rem; font-weight: 600; background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider); transition: all 0.2s;
color: var(--vp-c-text-2);
}
.tab-btn:hover { border-color: var(--vp-c-brand); }
.tab-btn.active { border-color: var(--vp-c-brand); background: rgba(var(--vp-c-brand-rgb), 0.05); color: var(--vp-c-text-1); }
.layer-detail {
background: var(--vp-c-bg); border-radius: 8px; padding: 1rem;
border: 1px solid var(--vp-c-divider);
}
.detail-name { font-weight: 700; font-size: 0.95rem; color: var(--vp-c-brand); margin-bottom: 0.3rem; }
.detail-desc { font-size: 0.82rem; color: var(--vp-c-text-2); margin-bottom: 0.6rem; line-height: 1.5; }
.detail-section { font-size: 0.8rem; margin-bottom: 0.4rem; display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.section-label { font-weight: 600; color: var(--vp-c-text-2); }
.param-tag {
background: rgba(var(--vp-c-brand-rgb), 0.08); padding: 0.15rem 0.4rem;
border-radius: 4px; font-size: 0.72rem;
}
.usage-text { color: var(--vp-c-text-2); }
.detail-code {
margin-top: 0.5rem; padding: 0.5rem 0.7rem; background: var(--vp-c-bg-soft);
border-radius: 6px; font-family: var(--vp-font-family-mono); font-size: 0.75rem;
color: var(--vp-c-brand);
}
</style>
@@ -0,0 +1,202 @@
<!--
NeuronDemo.vue
神经元结构演示展示单个神经元的工作原理
-->
<template>
<div class="neuron-demo">
<div class="header">
<div class="title">神经元工作原理</div>
<div class="subtitle">调整输入和权重观察神经元的输出变化</div>
</div>
<div class="neuron-layout">
<div class="inputs-col">
<div class="col-label">输入 × 权重</div>
<div v-for="(inp, i) in inputs" :key="i" class="input-row">
<div class="input-pair">
<label>x{{ i + 1 }}</label>
<input v-model.number="inp.value" type="range" min="-1" max="1" step="0.1" />
<span class="val">{{ inp.value.toFixed(1) }}</span>
</div>
<span class="multiply">×</span>
<div class="input-pair">
<label>w{{ i + 1 }}</label>
<input v-model.number="inp.weight" type="range" min="-2" max="2" step="0.1" />
<span class="val">{{ inp.weight.toFixed(1) }}</span>
</div>
<span class="equals">=</span>
<span class="partial">{{ (inp.value * inp.weight).toFixed(2) }}</span>
</div>
</div>
<div class="output-col">
<div class="sum-box">
<div class="sum-label">加权求和 + 偏置({{ bias.toFixed(1) }})</div>
<div class="sum-value">{{ weightedSum.toFixed(2) }}</div>
</div>
<div class="arrow"></div>
<div class="activation-box">
<div class="act-label">激活函数: {{ activationName }}</div>
<div class="act-value">{{ activationOutput.toFixed(4) }}</div>
</div>
<div class="controls">
<div class="control-row">
<label>偏置 b</label>
<input v-model.number="bias" type="range" min="-2" max="2" step="0.1" />
<span class="val">{{ bias.toFixed(1) }}</span>
</div>
<div class="control-row">
<label>激活函数</label>
<select v-model="activation">
<option value="sigmoid">Sigmoid</option>
<option value="relu">ReLU</option>
<option value="tanh">Tanh</option>
</select>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
const inputs = reactive([
{ value: 0.5, weight: 0.8 },
{ value: -0.3, weight: 1.2 },
{ value: 0.7, weight: -0.5 }
])
const bias = ref(0.1)
const activation = ref('sigmoid')
const activationName = computed(() => {
const names = { sigmoid: 'Sigmoid', relu: 'ReLU', tanh: 'Tanh' }
return names[activation.value]
})
const weightedSum = computed(() => {
return inputs.reduce((sum, inp) => sum + inp.value * inp.weight, 0) + bias.value
})
const activationOutput = computed(() => {
const z = weightedSum.value
switch (activation.value) {
case 'sigmoid': return 1 / (1 + Math.exp(-z))
case 'relu': return Math.max(0, z)
case 'tanh': return Math.tanh(z)
default: return z
}
})
</script>
<style scoped>
.neuron-demo {
border: 1px solid var(--vp-c-divider);
background: var(--vp-c-bg-soft);
border-radius: 12px;
padding: 1.5rem;
margin: 1.5rem 0;
}
.header { margin-bottom: 1rem; }
.title { font-weight: 700; font-size: 1.1rem; }
.subtitle { color: var(--vp-c-text-2); font-size: 0.9rem; }
.neuron-layout {
display: grid;
grid-template-columns: 1.2fr 1fr;
gap: 1rem;
}
@media (max-width: 640px) {
.neuron-layout { grid-template-columns: 1fr; }
}
.col-label {
font-weight: 600;
font-size: 0.8rem;
color: var(--vp-c-text-2);
margin-bottom: 0.5rem;
}
.input-row {
display: flex;
align-items: center;
gap: 0.3rem;
margin-bottom: 0.4rem;
font-size: 0.78rem;
}
.input-pair {
display: flex;
align-items: center;
gap: 0.2rem;
}
.input-pair label {
font-weight: 600;
font-size: 0.72rem;
color: var(--vp-c-text-3);
min-width: 18px;
}
.input-pair input[type="range"] { width: 60px; }
.val {
font-family: var(--vp-font-family-mono);
font-size: 0.72rem;
min-width: 28px;
text-align: right;
}
.multiply, .equals {
color: var(--vp-c-text-3);
font-weight: 600;
}
.partial {
font-family: var(--vp-font-family-mono);
font-weight: 600;
color: var(--vp-c-brand);
min-width: 40px;
text-align: right;
}
.output-col {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.4rem;
}
.sum-box, .activation-box {
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 0.5rem 0.8rem;
text-align: center;
width: 100%;
}
.sum-label, .act-label {
font-size: 0.72rem;
color: var(--vp-c-text-3);
}
.sum-value, .act-value {
font-size: 1.1rem;
font-weight: 700;
font-family: var(--vp-font-family-mono);
color: var(--vp-c-brand);
}
.arrow { color: var(--vp-c-text-3); font-size: 1.2rem; }
.controls { width: 100%; margin-top: 0.5rem; }
.control-row {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.78rem;
margin-bottom: 0.3rem;
}
.control-row label {
font-weight: 600;
color: var(--vp-c-text-2);
min-width: 55px;
font-size: 0.72rem;
}
.control-row select {
padding: 0.2rem 0.4rem;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
font-size: 0.78rem;
background: var(--vp-c-bg);
color: var(--vp-c-text-1);
}
</style>