分布式学习

1. 列举三个非冯·诺依曼计算结构

非冯结构是指不遵循传统冯·诺依曼体系的计算架构,包括:

  • 数据流结构(Dataflow Architecture):指令执行取决于数据的可用性而不是程序计数器。

  • 神经网络结构(Neural Network Architecture):模拟生物神经元连接,用于人工智能。

  • 量子计算结构(Quantum Computing Architecture):利用量子比特和量子叠加原理进行计算。


2. 简述同步通信

同步通信指通信双方在数据传输过程中必须同时处于活动状态,例如:

  • 发送方发出数据后等待接收方响应

  • 接收方只有在发送方传输时才能接收;

  • 常见于阻塞式消息传递,如 MPI_SendMPI_Recv


3. 简述云计算中的基础服务模型

云计算有三种基本服务模型:

模型名称功能
IaaSInfrastructure as a Service提供虚拟机、存储、网络等基础资源(如AWS EC2、阿里云ECS)
PaaSPlatform as a Service提供应用开发运行平台(如Google App Engine、Microsoft Azure)
SaaSSoftware as a Service提供在线应用服务(如Gmail、Office 365)

4. 简述Flynn分类法

Flynn分类法根据指令流和数据流的数量将计算机系统分为四类:

分类含义示例
SISD单指令流单数据流传统单核处理器
SIMD单指令流多数据流GPU
MISD多指令流单数据流稀有,用于容错系统
MIMD多指令流多数据流多核多线程系统、分布式系统

5. 举例说明MPI中标签的作用

**MPI标签(Tag)**用于区分不同类型的消息,防止通信混乱。

假设进程 P 向进程 Q 发送两类消息:

// 进程 P
MPI_Send(&data1, count, MPI_INT, dest=Q, tag=100, comm);
MPI_Send(&data2, count, MPI_INT, dest=Q, tag=200, comm);

// 进程 Q
MPI_Recv(&recv1, count, MPI_INT, source=P, tag=100, comm, status);
MPI_Recv(&recv2, count, MPI_INT, source=P, tag=200, comm, status);

📌 作用:标签 100200 确保数据 data1data2 不会混淆。


6. 简述虚拟机和容器的异同

比较项虚拟机(VM)容器(Container)
启动速度慢(分钟级)快(秒级)
占用资源多(完整OS)少(共享宿主OS)
隔离性强(硬件层)相对弱(内核级)
应用场景多系统环境微服务、快速部署
虚拟化层HypervisorDocker Engine / Containerd

7. 简述云计算的三种存储方式

  1. 对象存储(Object Storage)

    • 面向非结构化数据,如图片、音频、备份。

    • 如 Amazon S3、阿里云 OSS。

  2. 块存储(Block Storage)

    • 类似硬盘,适合数据库、虚拟机挂载。

    • 如 Amazon EBS、阿里云云盘。

  3. 文件存储(File Storage)

    • 提供标准文件系统访问,适合共享访问。

    • 如 Amazon EFS、阿里云 NAS。


8. 简述什么是 Cache 一致性问题

Cache一致性问题是指在多处理器系统中,每个CPU都有自己的缓存,如果多个缓存中同一变量副本不一致,可能导致程序结果错误。

📌 示例:

  • CPU1 缓存了变量 X=1,CPU2 更新为 X=2

  • 如果CPU1未刷新,就会读取过时数据。

🔄 常用解决方案:

  • MESI 协议(修改-独占-共享-无效)

  • 总线监听(Bus Snooping)

9. 任务并行 vs 数据并行

类型含义示例
任务并行各处理单元执行不同任务,操作不同数据多线程同时执行输入、处理、输出
数据并行各处理单元执行相同操作,处理不同数据多核同时对不同数组片段求平方

10. 负载均衡 / 通信 / 同步

  • 负载均衡:将任务在各节点上平均分配,避免某些过载、某些空闲。

  • 通信:节点间交换数据,例如发送接收消息(如 MPI)。

  • 同步:进程/线程间协调执行时序,如 barrier、锁等。


11. 并发 / 并行 / 分布式计算对比

特性并发计算并行计算分布式计算
核心思想多任务交替多任务同时多节点协作
硬件需求单/多核多核/多处理器多主机网络
通信同步/共享内存同步/共享内存网络通信
示例单核多线程多核计算矩阵云平台运行搜索引擎

12. 冯诺依曼瓶颈及解决

  • 问题:处理器与内存间数据传输速率差距导致带宽瓶颈

  • 解决方法

    • 多级缓存

    • 指令预取、乱序执行

    • 使用哈佛结构分开指令/数据总线


13. 缓存映射的三种方式

类型映射策略特点
直接映射每块内存映射到唯一缓存位置实现简单,冲突多
全相联映射任意内存块可映射至任何缓存行命中率高,硬件复杂
组相联映射缓存分组,每块映射至某组内任一行折中方案,常用

14. 分布式 vs 共享式存储系统

类型特点示例
共享式所有节点访问同一存储多核服务器共享内存
分布式存储分布在多个节点上HDFS、Ceph 等

15. 阿达姆定律(Amdahl’s Law)

并行化程序的加速比受限于其串行部分

公式:
S=1(1−P)+PNS = \frac{1}{(1 - P) + \frac{P}{N}}S=(1−P)+NP​1​
其中:

  • SSS:加速比

  • PPP:可并行部分比例

  • NNN:处理器数量


16. Foster 并行化方法步骤

  1. 分解(Decomposition)

  2. 分配(Assignment)

  3. 通信(Communication)

  4. 合成/调度(Agglomeration & Mapping)


17. 缓存 / 一致性问题 / 伪共享

  • 缓存:位于CPU与内存之间的高速缓冲。

  • 缓存一致性问题:多核对同一变量副本操作,导致数据不一致。

  • 伪共享:不同线程使用同一缓存行内不同变量,仍引起无效失效。


18. 矩阵向量乘三种实现对比

实现特点
行划分每线程处理矩阵某几行
列划分每线程处理输入向量的某几列
块划分分块组合行列划分,适合大规模计算

19. parallel for 中静态 vs 动态线程分配

分配方式含义适用情况
静态预先划分任务段均匀负载
动态空闲线程动态领取任务不均匀任务(load imbalance)

20. Flynn 分类法四类

类型特征示例
SISD单指令单数据传统CPU
SIMD单指令多数据GPU
MISD多指令单数据容错系统(少见)
MIMD多指令多数据多核/集群系统

21. 流水线 vs 多发射

  • 流水线:将指令划分为阶段(如取指/译码/执行),指令重叠执行

  • 多发射(超标量):同周期多指令发射执行,提升吞吐率。


21. 忙等待 / 互斥量 / 信号量 / 临界区

  • 忙等待:循环检测资源,无睡眠。

  • 互斥量:互斥访问资源(lock/unlock)。

  • 信号量:支持计数、资源控制(P/V操作)。

  • 临界区:程序中访问共享资源的代码段。


22. 点对点通信 vs 集合通信

类型含义示例
点对点通信单对单通信MPI_Send / MPI_Recv
集合通信多个进程参与,如广播、规约MPI_Bcast / MPI_Reduce

23. 事务的4个特性

特性全称描述
AAtomicity(原子性)事务中的操作要么全部执行,要么全部不执行,不能只执行一部分。
CConsistency(一致性)执行前后数据库必须保持一致,符合数据完整性约束。
IIsolation(隔离性)多个事务并发执行时,彼此之间不会互相干扰。
DDurability(持久性)一旦事务提交,其结果就永久保存在数据库中,即使宕机也不会丢失。

🔁 举个实际场景总结一下:
假设你从支付宝给朋友转账:

**原子性:**转账过程要么钱成功转出并到账,要么完全失败,不能只扣钱不收钱。
**一致性:**总金额在转账前后保持不变。
**隔离性:**并发转账不会影响彼此账户的最终状态。
**持久性:**转账成功后,即使系统宕机,钱也不会“消失”或“回滚”

24.ACID 一致性和CAP一致性

ACID 一致性 —— 数据库事务的一致性
✅ 定义:
事务执行前后,数据库必须从一个一致的状态变为另一个一致的状态,满足所有数据完整性约束(如主键唯一、外键、触发器、检查约束等)。
✅ 核心目标:
保证事务内部的逻辑正确性,防止数据出现非法状态

25.CAP 一致性 —— 分布式系统中的一致性

📌 所属领域:分布式系统(如微服务、分布式数据库)中的 CAP 定理
✅ CAP 定理三要素:
C(Consistency)一致性:对分布式系统各个节点对外的表现是一致的
A(Availability)可用性:每个请求都能收到响应(不一定是最新数据)。
P(Partition tolerance)分区容错性:系统能容忍网络分区(节点通信失败)而继续运行。

✅ CAP 中的一致性含义:
指强一致性(Strong Consistency),即:在网络正常或出现分区的情况下,所有用户访问到的数据是最新的、完全一致的。

✅ 举例说明:
有两个节点 A 和 B,当你向 A 写入了数据,立刻再从 B 读取时也必须返回这条最新数据,否则就是不一致。

26.数据冒险是什么

✅ 正确理解 Read After Write (RAW)

它是数据冒险(Data Hazard) 中最常见的一种,准确地说:

Read After Write:指一个指令试图读取某个寄存器(或内存位置),但这个寄存器正在被前一条尚未完成写入的指令所更新


🔍 举个例子说明:

1. ADD R1, R2, R3   ; R1 = R2 + R3
2. SUB R4, R1, R5   ; R4 = R1 - R5
  • 第 1 条指令正在把计算结果写入寄存器 R1

  • 第 2 条指令马上就要读取 R1,但是 R1 还没写好!

  • 这就造成了 Read After Write(RAW) Hazard


❗为什么叫 Read After Write?

因为第二条指令要 Read(读),但它依赖的值 需要在前面的指令 Write(写)之后才正确,因此叫:

Read(第二条) after Write(第一条)


⚠️ 为什么不能翻成“读后写”?

“读后写”会给人一种先读再写的错觉,好像程序顺序是:

读 -> 写

但实际是指:

第一条:写
第二条:读
→ 第二条读太早 → 冒险!

所以准确的理解应该是“写之后才可读”,而不是“读了之后再写”


✅ 更准确的翻译:

  • Read After Write:应翻译为 “写后读”

  • 表达了这个依赖关系:必须先写完,才能读


📚 延伸:数据冒险的三种基本类型

类型简称示例描述
Read After WriteRAW读用到前面尚未写好的值✅ 最常见
Write After ReadWAR写被排在读之前异常情况
Write After WriteWAW两个写竞争通常影响结果一致性

27. 简述一下raft 是啥,写出领导者选举的伪代码

领导者选举(Leader Election)相关算法
最常见的是:

算法关键特点场景
Bully Algorithm编号高者优先,向高编号发起选举,收到回应则放弃同步网络,编号唯一
Ring Algorithm按环传递选举消息,编号最大者当选节点构成环形结构
Raft Election基于任期(term)、多数投票,心跳维持领导地位实现简单、一致性强
以 Raft 为例(常考):
Leader Election 流程图(简化版)
        +--------------------+
        |   Follower         |
        | (Timeout reached)  |
        +---------+----------+
                  |
                  v
        +--------------------+
        |   Candidate        |
        |  - Increment term  |
        |  - Vote for self   |
        |  - Send RequestVote|
        +---------+----------+
                  |
        +---------+----------+
        | Majority votes?    |
        |   Yes        No    |
        v                    v
+---------------+     +-------------+
|   Leader      |     | Back to     |
| (Send heart-  |     | Follower    |
|   beats)      |     +-------------+
+---------------+

✅ C语言实现:模拟 Raft RequestVote

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

// ---------- 定义结构体 ----------

typedef struct {
    int term;           // 候选人当前任期
    int candidateId;    // 候选人 ID
    int lastLogIndex;   // 候选人最后一条日志索引
    int lastLogTerm;    // 候选人最后一条日志任期
} RequestVoteRequest;

typedef struct {
    int term;           // 当前节点任期
    bool voteGranted;   // 是否投票
} RequestVoteResponse;

typedef struct {
    int id;
    int currentTerm;
    int votedFor;          // -1 表示尚未投票
    int lastLogIndex;
    int lastLogTerm;
} RaftNode;

// ---------- 判断日志是否更新 ----------
// 若 a 日志比 b 更新,返回 true
bool isLogUpToDate(int candidateTerm, int candidateIndex, int localTerm, int localIndex) {
    if (candidateTerm > localTerm) return true;
    if (candidateTerm == localTerm && candidateIndex >= localIndex) return true;
    return false;
}

// ---------- 模拟处理 RequestVote 请求 ----------
RequestVoteResponse handleRequestVote(RaftNode *node, RequestVoteRequest req) {
    RequestVoteResponse resp;
    resp.term = node->currentTerm;
    resp.voteGranted = false;

    if (req.term < node->currentTerm) {
        // 候选人任期太旧,拒绝投票
        return resp;
    }

    // 若请求 term 更大,更新当前节点任期,并重置投票
    if (req.term > node->currentTerm) {
        node->currentTerm = req.term;
        node->votedFor = -1;
    }

    // 如果还没投票或者之前就投给这个 candidate
    // 并且候选人日志不落后
    if ((node->votedFor == -1 || node->votedFor == req.candidateId) &&
        isLogUpToDate(req.lastLogTerm, req.lastLogIndex, node->lastLogTerm, node->lastLogIndex)) {
        node->votedFor = req.candidateId;
        resp.voteGranted = true;
    }

    resp.term = node->currentTerm;
    return resp;
}

// ---------- 测试主函数 ----------
int main() {
    // 模拟 follower 节点
    RaftNode follower = {
        .id = 1,
        .currentTerm = 3,
        .votedFor = -1,
        .lastLogIndex = 5,
        .lastLogTerm = 3
    };

    // 模拟候选人发送投票请求
    RequestVoteRequest request = {
        .term = 4,
        .candidateId = 2,
        .lastLogIndex = 5,
        .lastLogTerm = 3
    };

    // 处理请求
    RequestVoteResponse response = handleRequestVote(&follower, request);

    // 输出结果
    printf("Follower Term: %d\n", follower.currentTerm);
    printf("Vote Granted to Candidate %d: %s\n", request.candidateId,
           response.voteGranted ? "YES" : "NO");

    return 0;
}

🔹28. “电梯调度:事件优先 vs 时间优先”

这个问题其实很经典,常用于考察事件驱动 vs 时间驱动调度模型的理解。

✅ 电梯控制问题中的两种调度策略:
模型描述
事件优先模型电梯状态变化由外部事件触发(如按钮被按)。适用于低负载、响应快的场景。
时间优先模型定期轮询电梯状态进行调度(如每秒检查一次状态)。适用于状态稳定但响应延迟。
🧠 通常参考点:

实时性要求高 → 事件优先
系统结构简单、可预测 → 时间优先
✅ 二、电梯调度:事件驱动 vs 时间驱动模型

🎯 场景题型:给定电梯调度场景,选择合适模型并解释原因

模型类型优点缺点适用场景
事件驱动模型响应快、资源高效实现复杂按键触发、请求频繁的系统
时间驱动模型实现简单易浪费资源、延迟高状态稀疏、周期任务

💡 答题模板(事件 vs 时间):

在本场景下,电梯响应的关键为用户输入(如按钮按下),且要求快速响应,因此应采用事件优先模型。此模型可在每次事件触发时直接调度处理,避免定期轮询所带来的资源浪费与响应延迟。

28. 行存储 和 列存储 分别是啥意思

“行存储”和“列存储”是数据库中两种数据物理存储方式。它们的最大区别在于:是按行还是按列来组织和存储数据。下面我给你通俗又系统地解释一下:


✅ 什么是行存储(Row-Oriented Storage)

📦 存储方式:

一整行的数据作为一个整体存储在一起。

例如,有这样一张表:

IDNameAgeGender
1Alice23F
2Bob30M

在行存储中,物理存储是这样的(按行):

[1, Alice, 23, F], [2, Bob, 30, M]

✅ 特点:

  • 适合事务型操作(OLTP),例如插入/更新/删除整行。
  • 每次访问都能获得一行完整信息,适合频繁的随机访问。

✅ 什么是列存储(Column-Oriented Storage)

每一列的数据存储在一起。
上述表的数据在列存储中会变成这样:

ID:     [1, 2]
Name:   [Alice, Bob]
Age:    [23, 30]
Gender: [F, M]

✅ 特点:

  • 适合分析型操作(OLAP),例如统计、聚合、筛选某一列。
  • 只读取相关列即可,大大减少 I/O。
  • 通常配合压缩算法,节省空间。
特性行存储(Row Store)列存储(Column Store)
数据组织方式按行存储整条记录按列存储每个字段
适合场景高并发写入、快速读取整行数据(OLTP)快速聚合分析、少列访问(OLAP)
查询优化快速读取一整行快速读取某几列,列压缩效率高
示例系统MySQL(InnoDB)、PostgreSQLClickHouse、Amazon Redshift、HBase

🎯 你要查“所有用户的平均年龄”

  • 行存储要把所有行读出来(包括姓名、性别等),然后提取年龄列

  • 列存储只读年龄列即可,更快、更省资源


I/请求投票RPC RequestI/请求投票RPC Response type RequestVoteRequest struct {type RequestVoteResponse struct { termint自己当前的任期号termint川自己当前任期号 candidateld int // 自己的IDvoteGranted bool //自己会不会投票给这 lastLoglndex int//自己最后一个日志号//个candidate lastLogTermint //自己最后一个日志的任期


✅ 可能含义 1:Raft 中的任期(Term)变化与时钟模型

Raft 中“时钟题”一般是围绕:

  • 任期(term)的变化规则

  • 各节点间时间(选举超时、心跳超时)的关系

  • 事件发生顺序:如谁先成为 Candidate、是否会分裂投票


📌 常见题型:Raft 时钟题例子

给定多个节点的超时时间和网络延迟,请判断哪个节点最可能先成为 Leader?是否会发生分裂投票?如何避免?

🧠 解题思路:
  1. 超时时间短的节点更可能最早成为 Candidate。

  2. **分裂投票(split vote)**发生在多个 Candidate 几乎同时发起选举。

  3. 引入随机超时是防止分裂投票的重要机制。


✅ 示例题(考试常见):

Raft 集群中有 3 个节点 A、B、C,其选举超时分别为 150ms、200ms、250ms。若网络没有延迟,谁最可能成为 Leader?为什么?

答案

  • A 最先超时,先发起投票。

  • 如果 B、C 接收到请求且没投过票,A 会赢得多数选票 → 成为 Leader。


✅ 可能含义 2:Lamport 时钟 / 向量时钟题

如果“RA 时钟题”不是 Raft 的简写,也可能是:

分布式系统考试里经典的“逻辑时钟”题,用来判断事件的先后关系

🎯 题型特点:

  • 给出一组事件、节点间通信

  • 要你给每个事件分配 Lamport 时钟值

  • 或者用向量时钟判断“是否并发”、“谁先发生”

示例:Lamport 时钟

事件 A1 → A2
A1 发消息给 B2
→ 问各事件的 Lamport 时钟是多少?


✅ 总结:RA 时钟题常考点

类型涉及内容考察点
Raft 任期时钟题超时、term 增长、选举过程选举机制是否正确、防止 split vote
Lamport 时钟事件编号、消息传递逻辑因果顺序
向量时钟多节点时间戳数组并发性判断(是否存在先后关系)

29. 超时例题

Raft 集群中有 3 个节点 A、B、C,选举超时分别是:

  • A:150ms

  • B:200ms

  • C:250ms

网络无延迟。问:谁最可能成为 Leader?为什么?


✅ 关键概念:Raft 中的选举超时

Raft 中每个节点在 “Follower 状态” 时会启动一个“选举超时计时器”:

  • 如果超时时间到了还没有收到来自 Leader 的心跳(AppendEntries),它就认为 Leader 挂了,会:

    • 转为 Candidate

    • 启动一次选举


✅ 步骤解析(无网络延迟):

  1. 150ms 到达时:

    • A 的选举超时先触发 → A 转为 Candidate

    • A 向 B 和 C 发送 RequestVote 请求

  2. B 和 C 的状态:

    • 当前任期一致(假设都是 term=1)

    • 没有投过票(votedFor == null

    • 如果 A 的日志不落后 → 会投票给 A

  3. A 获得了 自己 + B 或 C 的票数 = 2 票

    • 超过半数(3 个节点的一半是 2)

    • → A 成为 Leader


❗为什么不会发生分裂投票?

因为 A 先触发,B 和 C 还没超时,也就是说:

  • B、C 都还是 Follower 状态

  • 都愿意投票给第一个发来 RequestVote 的 Candidate(A)


🔄 如果网络有延迟或超时很接近怎么办?

假设 A、B 几乎同时超时(如 A=150ms,B=151ms),就可能出现:

  • A 和 B 同时发起选举、都给自己投票

  • A 请求到 C 时,C 可能已经投给 B

  • → 三个节点各自一票 / 或 2:1 分裂

这种情况就叫 分裂投票(split vote)


原因
谁先超时谁先变成 Candidate,先发起投票
谁能赢选举谁先获得多数投票(> N/2)
如何得票其他节点还没投票,并且你日志不落后
如何避免冲突随机选举超时(避免多个节点同时选)

如果你想,我可以给你扩展出多个变种题(比如有日志不一致、网络延迟、有节点宕机的情况),帮助你训练这类题目的答题思维。要来几道练练吗?


30.三阶段提交(3PC)的三个阶段

1️⃣ 阶段一:CanCommit(询问阶段
协调者向所有参与者发送 “Can you commit?”
参与者检查自己是否可以提交(如资源锁是否可用),然后回复 Yes/No。
(这里跟 2PC 的 prepare 阶段类似)
2️⃣ 阶段二:PreCommit(预提交阶段)
如果所有参与者都回复 Yes:
协调者发送 PreCommit 给所有参与者,要求进入预提交状态(写 WAL 日志、锁定资源,但暂不真正执行 Commit)。
参与者执行预提交,写入日志,并回复 ACK。
(2PC 在这里会直接 Commit,而 3PC 多了一个过渡状态)

3️⃣ 阶段三:DoCommit(正式提交阶段)
协调者收到所有参与者的 ACK 后,发送 DoCommit。
参与者正式执行 Commit,释放锁,并反馈已提交。
如果在阶段 2 或 3 发生网络异常,超时后可以通过超时和超时恢复来避免阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值