面试准备

阶段4 | 第43-44周

📅 2周面试冲刺计划

集中准备手撕代码、系统设计、性能分析三类核心问题。每天练习1-2道手撕题。

💻 手撕代码题(高频)

1. 矩阵乘法CUDA实现 ⭐⭐⭐

  • 要点1: 朴素实现 - 三重循环,每个线程计算一个元素
  • 要点2: Shared Memory优化 - Tiling分块,减少Global Memory访问
  • 要点3: 向量化加载 - 使用float4一次加载128位
  • 要点4: 边界处理 - 处理矩阵大小不是Block倍数的情况
// Shared Memory优化的矩阵乘法
#define TILE_SIZE 16

__global__ void matmul_shared(float *A, float *B, float *C, int N) {
    __shared__ float As[TILE_SIZE][TILE_SIZE];
    __shared__ float Bs[TILE_SIZE][TILE_SIZE];
    
    int bx = blockIdx.x, by = blockIdx.y;
    int tx = threadIdx.x, ty = threadIdx.y;
    int row = by * TILE_SIZE + ty;
    int col = bx * TILE_SIZE + tx;
    
    float sum = 0.0f;
    
    for (int t = 0; t < N/TILE_SIZE; ++t) {
        // 协作加载到Shared Memory
        As[ty][tx] = A[row * N + t * TILE_SIZE + tx];
        Bs[ty][tx] = B[(t * TILE_SIZE + ty) * N + col];
        __syncthreads();
        
        // 计算部分和
        for (int k = 0; k < TILE_SIZE; ++k)
            sum += As[ty][k] * Bs[k][tx];
        __syncthreads();
    }
    
    C[row * N + col] = sum;
}

2. Softmax CUDA实现 ⭐⭐⭐

  • 要点1: 找最大值 - 数值稳定性,防止exp溢出
  • 要点2: 在线计算 - 一次遍历完成,减少内存访问
  • 要点3: Warp归约 - 使用__shfl_down_sync高效归约
  • 要点4: 大数组处理 - 多Block协作归约
// 高效Softmax实现
__global__ void softmax_kernel(float *input, float *output, int n) {
    __shared__ float shared_max;
    __shared__ float shared_sum;
    
    int tid = threadIdx.x + blockIdx.x * blockDim.x;
    
    // Step 1: 找最大值 (Warp归约)
    float val = (tid < n) ? input[tid] : -INFINITY;
    float max_val = val;
    for (int offset = 16; offset > 0; offset >>= 1) {
        float other = __shfl_down_sync(0xFFFFFFFF, max_val, offset);
        max_val = fmaxf(max_val, other);
    }
    
    // Step 2: 计算exp和求和
    float exp_val = (tid < n) ? expf(val - max_val) : 0.0f;
    // ... 归约求和 ...
    
    // Step 3: 归一化
    if (tid < n) output[tid] = exp_val / sum_val;
}

3. FlashAttention实现 ⭐⭐⭐⭐

  • 要点1: Tiling - 将Q,K,V分块加载到Shared Memory
  • 要点2: Online Softmax - 分块计算,维护最大值和求和统计
  • 要点3: 精确输出 - 保证数学等价性
  • 要点4: 内存优化 - O(N)内存 vs O(N²)

4. 向量归约求和 ⭐⭐

  • 要点1: 朴素归约 - 线性时间,效率低
  • 要点2: Shared Memory归约 - 树形归约,O(log n)
  • 要点3: Warp Shuffle - 寄存器级操作,最快
  • 要点4: 处理剩余元素 - 最后32个元素的特殊处理

5. TopK / Sorting ⭐⭐

  • 要点1: 基数排序 - GPU上高效的并行排序
  • 要点2: Bitonic Sort - 适合GPU的排序网络
  • 要点3: TopK选择 - 使用堆或部分排序

🏗️ 系统设计题

1. 设计高并发LLM推理服务 ⭐⭐⭐⭐

  • 要点1: KV Cache管理 - PagedAttention,动态分配
  • 要点2: 请求调度 - Continuous Batching,最大化GPU利用率
  • 要点3: 负载均衡 - 多卡/多机调度策略
  • 要点4: 监控告警 - GPU利用率、延迟、队列长度
// 系统架构
┌─────────────────────────────────────────┐
│           Load Balancer                 │
├─────────────────────────────────────────┤
│    │         │         │         │      │
│    ▼         ▼         ▼         ▼      │
│ ┌─────┐  ┌─────┐  ┌─────┐  ┌─────┐   │
│ │GPU 0│  │GPU 1│  │GPU 2│  │GPU 3│   │
│ └─────┘  └─────┘  └─────┘  └─────┘   │
│                                         │
│ ┌─────────────────────────────────────┐ │
│ │        KV Cache Manager            │ │
│ │    (PagedAttention + CoW)         │ │
│ └─────────────────────────────────────┘ │
│                                         │
│ ┌─────────────────────────────────────┐ │
│ │        Request Scheduler           │ │
│ │    (Continuous Batching)          │ │
│ └─────────────────────────────────────┘ │
└─────────────────────────────────────────┘

2. 设计分布式训练架构 ⭐⭐⭐

  • 要点1: 并行策略 - Data/Model/Pipeline Parallelism选择
  • 要点2: 通信优化 - AllReduce、梯度压缩、异步通信
  • 要点3: 内存优化 - 梯度检查点、混合精度
  • 要点4: 故障恢复 - 检查点保存、弹性训练

3. 设计GPU资源调度系统 ⭐⭐⭐

  • 要点1: GPU分配 - 独占/共享,MIG切分
  • 要点2: 任务调度 - 优先级队列,公平调度
  • 要点3: 故障处理 - GPU健康检查,自动重启
  • 要点4: 成本优化 - 混合精度,显存优化

🔍 性能分析题

常见问题与解答

  • Q: Occupancy低怎么优化?
    A: 减少寄存器使用(__launch_bounds__)、调整Block大小、使用动态Shared Memory
  • Q: 显存不足(Out of Memory)?
    A: 梯度检查点、混合精度训练、模型并行、KV Cache量化、减小batch size
  • Q: Kernel延迟高(Latency)?
    A: 用Nsight Compute分析瓶颈(计算/内存/同步),优化访存模式,减少分支发散
  • Q: 吞吐量低(Throughput)?
    A: 批处理(Batching)、流水线(Pipeline)、Kernel融合、提高Occupancy
  • Q: 多卡通信慢?
    A: 使用NVLink、梯度压缩、异步通信、Ring-AllReduce优化

📋 面试清单

💡 面试技巧:

📚 面试资源

🛠️ 面试练习项目