docs: 重构 README 附录展示 & 新增多个附录交互组件
README 更新: - 移除顶部 header.png 横幅图片 - 新增「附录知识库」板块,以 3×3 网格展示 9 大知识领域精选内容 - 附录链接指向部署版网站 (datawhalechina.github.io) - 阶段表格新增「附录」行,突出 80+ 交互式专题 - 章节标题「新手入门 & PM」简化为「零基础入门」 - News 新增 2026-02-25 附录知识库更新条目 新增交互组件: - 异步任务队列 (async-task-queues) 演示组件 - 文件存储 (file-storage) 演示组件 - 项目架构 (project-architecture) 演示组件 - 限流与背压 (rate-limiting) 演示组件 - 搜索引擎 (search-engines) 演示组件 - 计算机基础: AppLaunch/BiosUefi/OSBoot 等启动流程演示组件 新增附录文档: - 前端项目架构 (frontend-project-architecture.md) - 后端项目架构 (backend-project-architecture.md) 内容优化: - 算法思维、数据结构、编程语言、调试艺术等多篇附录内容更新 - HTML/CSS 布局、请求旅程等前后端文档完善 - 附录索引页 (index.md) 同步更新
This commit is contained in:
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div class="launch-demo">
|
||||
<div class="demo-header">
|
||||
<span class="demo-icon">🌐</span>
|
||||
<span class="demo-title">浏览器启动过程</span>
|
||||
<span class="demo-hint">点击每一步查看详情</span>
|
||||
</div>
|
||||
|
||||
<div class="timeline">
|
||||
<div
|
||||
v-for="(step, i) in steps"
|
||||
:key="i"
|
||||
class="timeline-item"
|
||||
:class="{ active: active === i, done: active > i }"
|
||||
@click="active = active === i ? -1 : i"
|
||||
>
|
||||
<div class="marker-col">
|
||||
<div class="dot">
|
||||
<span v-if="active > i" class="check">✓</span>
|
||||
<span v-else>{{ i + 1 }}</span>
|
||||
</div>
|
||||
<div v-if="i < steps.length - 1" class="line"></div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<span class="step-icon">{{ step.icon }}</span>
|
||||
<div class="card-titles">
|
||||
<div class="step-name">{{ step.name }}</div>
|
||||
<div class="step-brief">{{ step.brief }}</div>
|
||||
</div>
|
||||
<span class="expand-icon">{{ active === i ? '▾' : '▸' }}</span>
|
||||
</div>
|
||||
|
||||
<transition name="slide">
|
||||
<div v-if="active === i" class="card-detail">
|
||||
<div class="detail-desc">{{ step.detail }}</div>
|
||||
<div class="detail-visual">
|
||||
<div
|
||||
v-for="(item, j) in step.items"
|
||||
:key="j"
|
||||
class="visual-item"
|
||||
>
|
||||
<span class="vi-icon">{{ item.icon }}</span>
|
||||
<div class="vi-text">
|
||||
<span class="vi-label">{{ item.label }}</span>
|
||||
<span class="vi-desc">{{ item.desc }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="step.analogy" class="analogy">
|
||||
<span class="analogy-icon">💡</span>
|
||||
<span class="analogy-text">{{ step.analogy }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const active = ref(-1)
|
||||
|
||||
const steps = [
|
||||
{
|
||||
icon: '👆',
|
||||
name: '双击图标',
|
||||
brief: '用户触发启动请求,操作系统开始响应',
|
||||
detail: '你双击桌面上的浏览器图标时,操作系统的窗口管理器捕获这个鼠标事件,通过文件关联表查找该图标对应的可执行文件路径。',
|
||||
items: [
|
||||
{ icon: '🖱️', label: '鼠标事件捕获', desc: '窗口管理器检测到双击动作,识别点击目标' },
|
||||
{ icon: '🔗', label: '快捷方式解析', desc: '读取 .lnk(Windows)或 .desktop(Linux)文件中的目标路径' },
|
||||
{ icon: '📂', label: '文件关联查找', desc: '在注册表或 MIME 数据库中找到对应的可执行文件' }
|
||||
],
|
||||
analogy: '就像你按下遥控器的开机键,电视先要识别你按的是哪个按钮,再决定执行什么操作。'
|
||||
},
|
||||
{
|
||||
icon: '🔍',
|
||||
name: '查找可执行文件',
|
||||
brief: '根据文件关联,找到浏览器的 .exe 或可执行文件',
|
||||
detail: '操作系统根据路径在硬盘上定位浏览器的可执行文件(如 chrome.exe),验证文件完整性和权限,准备加载。',
|
||||
items: [
|
||||
{ icon: '📋', label: '路径解析', desc: '将快捷方式中的路径转换为硬盘上的实际文件位置' },
|
||||
{ icon: '🔒', label: '权限检查', desc: '验证当前用户是否有执行该文件的权限' },
|
||||
{ icon: '✅', label: '签名验证', desc: '检查数字签名确认文件未被篡改(Windows UAC)' }
|
||||
],
|
||||
analogy: '好比你要找一本书,先查图书馆目录(路径),确认你有借阅权限(权限检查),再确认书没有被损坏(签名验证)。'
|
||||
},
|
||||
{
|
||||
icon: '📋',
|
||||
name: '创建浏览器进程',
|
||||
brief: '为浏览器创建一个新的进程,分配进程 ID',
|
||||
detail: '操作系统内核调用 fork()+exec()(Linux)或 CreateProcess()(Windows),在进程表中创建新条目,分配唯一的 PID,建立进程控制块(PCB)。',
|
||||
items: [
|
||||
{ icon: '🆔', label: '分配 PID', desc: '为新进程分配唯一的进程标识符' },
|
||||
{ icon: '📊', label: '创建 PCB', desc: '记录进程状态、优先级、寄存器上下文等元信息' },
|
||||
{ icon: '🧠', label: '分配虚拟地址空间', desc: '为进程创建独立的 4GB(32位)虚拟内存空间' },
|
||||
{ icon: '📑', label: '初始化文件描述符', desc: '打开 stdin/stdout/stderr 三个标准 I/O 通道' }
|
||||
],
|
||||
analogy: '就像新生儿出生要办户口——分配身份证号(PID)、建立档案(PCB)、分配住房(内存空间)。'
|
||||
},
|
||||
{
|
||||
icon: '💾',
|
||||
name: '加载代码到内存',
|
||||
brief: '把浏览器的程序代码从硬盘读取到内存中',
|
||||
detail: '操作系统的加载器(Loader)解析可执行文件格式(PE/ELF),将代码段、数据段映射到虚拟内存,并加载所需的动态链接库(DLL/SO)。',
|
||||
items: [
|
||||
{ icon: '📦', label: '解析文件格式', desc: '读取 PE(Windows)或 ELF(Linux)文件头,确定各段位置' },
|
||||
{ icon: '🗺️', label: '内存映射', desc: '将 .text(代码)、.data(数据)、.bss 段映射到虚拟地址' },
|
||||
{ icon: '🔗', label: '动态链接', desc: '加载 DLL/SO 共享库,解析函数符号引用' },
|
||||
{ icon: '📍', label: '重定位', desc: '修正代码中的绝对地址引用,适配实际加载位置' }
|
||||
],
|
||||
analogy: '好比搬家——把家具(代码)从仓库(硬盘)搬到新房(内存),还要接通水电(链接库)。'
|
||||
},
|
||||
{
|
||||
icon: '🚀',
|
||||
name: '初始化各模块',
|
||||
brief: '启动主线程、渲染引擎、网络引擎、JS 引擎等',
|
||||
detail: '浏览器的 main() 函数开始执行,依次初始化多进程架构中的各个核心模块:Browser 主进程、GPU 进程、网络进程等。',
|
||||
items: [
|
||||
{ icon: '🧵', label: '主线程启动', desc: '初始化消息循环(Event Loop),处理 UI 事件和任务调度' },
|
||||
{ icon: '🎨', label: '渲染引擎', desc: '初始化 Blink/Gecko 引擎,准备解析 HTML/CSS' },
|
||||
{ icon: '🌐', label: '网络模块', desc: '启动网络栈,初始化 DNS 缓存、连接池、Cookie 管理' },
|
||||
{ icon: '⚡', label: 'JS 引擎', desc: '初始化 V8/SpiderMonkey,编译内置 JavaScript 代码' }
|
||||
],
|
||||
analogy: '就像一家餐厅开业前——厨房(渲染)、前台(UI)、外卖(网络)、收银(JS)各部门同时准备就绪。'
|
||||
},
|
||||
{
|
||||
icon: '🖼️',
|
||||
name: '显示浏览器窗口',
|
||||
brief: '所有模块就绪,浏览器界面呈现在屏幕上',
|
||||
detail: '浏览器向操作系统请求创建窗口,GPU 进程完成界面的合成与光栅化,最终将像素数据提交给显卡,浏览器窗口出现在屏幕上。',
|
||||
items: [
|
||||
{ icon: '🪟', label: '创建窗口', desc: '调用系统 API 创建原生窗口,设置大小和位置' },
|
||||
{ icon: '🎨', label: 'UI 绘制', desc: '渲染地址栏、标签页、工具栏等浏览器 Chrome 界面' },
|
||||
{ icon: '🖥️', label: 'GPU 合成', desc: '将各图层合成为最终画面,提交给显卡输出' },
|
||||
{ icon: '✨', label: '加载首页', desc: '打开新标签页或恢复上次会话,浏览器进入可用状态' }
|
||||
],
|
||||
analogy: '幕布拉开,灯光亮起——舞台(窗口)搭好了,演员(界面元素)就位,等待观众(你)的第一次操作。'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.launch-demo {
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 10px;
|
||||
background: var(--vp-c-bg-soft);
|
||||
padding: 1.2rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
.demo-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.demo-icon { font-size: 1.2rem; }
|
||||
.demo-title {
|
||||
font-size: 0.85rem;
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
.demo-hint {
|
||||
font-size: 0.65rem;
|
||||
color: var(--vp-c-text-3);
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.timeline { display: flex; flex-direction: column; }
|
||||
|
||||
.timeline-item {
|
||||
display: flex;
|
||||
gap: 0.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.marker-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 2rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.dot {
|
||||
width: 1.8rem;
|
||||
height: 1.8rem;
|
||||
border-radius: 50%;
|
||||
background: var(--vp-c-bg);
|
||||
border: 2px solid var(--vp-c-divider);
|
||||
color: var(--vp-c-text-3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 700;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.timeline-item.active .dot {
|
||||
background: var(--vp-c-brand);
|
||||
border-color: var(--vp-c-brand);
|
||||
color: white;
|
||||
transform: scale(1.15);
|
||||
box-shadow: 0 0 0 4px var(--vp-c-brand-soft);
|
||||
}
|
||||
.timeline-item.done .dot {
|
||||
background: #10b981;
|
||||
border-color: #10b981;
|
||||
color: white;
|
||||
}
|
||||
.check { font-size: 0.65rem; }
|
||||
.line {
|
||||
flex: 1;
|
||||
width: 2px;
|
||||
background: var(--vp-c-divider);
|
||||
min-height: 0.8rem;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
.timeline-item.done .line { background: #10b981; opacity: 0.5; }
|
||||
.timeline-item.active .line { background: var(--vp-c-brand); opacity: 0.4; }
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
background: var(--vp-c-bg);
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 8px;
|
||||
padding: 0.7rem 0.9rem;
|
||||
margin-bottom: 0.5rem;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.timeline-item.active .card {
|
||||
border-color: var(--vp-c-brand);
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.step-icon { font-size: 1.2rem; }
|
||||
.card-titles { flex: 1; }
|
||||
.step-name {
|
||||
font-size: 0.78rem;
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
.step-brief {
|
||||
font-size: 0.68rem;
|
||||
color: var(--vp-c-text-3);
|
||||
margin-top: 0.1rem;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.expand-icon {
|
||||
font-size: 0.7rem;
|
||||
color: var(--vp-c-text-3);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.card-detail {
|
||||
margin-top: 0.7rem;
|
||||
padding-top: 0.7rem;
|
||||
border-top: 1px dashed var(--vp-c-divider);
|
||||
}
|
||||
.detail-desc {
|
||||
font-size: 0.72rem;
|
||||
color: var(--vp-c-text-2);
|
||||
line-height: 1.6;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
.detail-visual {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.visual-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.4rem;
|
||||
background: var(--vp-c-bg-soft);
|
||||
border-radius: 6px;
|
||||
padding: 0.45rem 0.55rem;
|
||||
}
|
||||
.vi-icon { font-size: 0.9rem; flex-shrink: 0; margin-top: 0.05rem; }
|
||||
.vi-text { display: flex; flex-direction: column; }
|
||||
.vi-label {
|
||||
font-size: 0.68rem;
|
||||
font-weight: 600;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
.vi-desc {
|
||||
font-size: 0.62rem;
|
||||
color: var(--vp-c-text-3);
|
||||
line-height: 1.4;
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.analogy {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 0.4rem;
|
||||
margin-top: 0.6rem;
|
||||
padding: 0.5rem 0.6rem;
|
||||
background: var(--vp-c-brand-soft);
|
||||
border-radius: 6px;
|
||||
}
|
||||
.analogy-icon { font-size: 0.85rem; flex-shrink: 0; }
|
||||
.analogy-text {
|
||||
font-size: 0.66rem;
|
||||
color: var(--vp-c-text-2);
|
||||
line-height: 1.5;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.slide-enter-active, .slide-leave-active {
|
||||
transition: all 0.3s ease;
|
||||
overflow: hidden;
|
||||
}
|
||||
.slide-enter-from, .slide-leave-to {
|
||||
opacity: 0;
|
||||
max-height: 0;
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
.slide-enter-to, .slide-leave-from {
|
||||
opacity: 1;
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.detail-visual { grid-template-columns: 1fr; }
|
||||
.demo-hint { display: none; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user