NodeJS全栈开发面试题讲解——P8实战场景题(建议重点准备)

✅ 8.1 请设计一个「用户登录 + JWT 鉴权 + 角色权限」系统

面试官您好,我曾在实际项目中搭建过完整的用户系统,下面我从 登录流程、Token 生成、角色权限控制 三方面来讲解。


一、登录流程:

  1. 用户输入账号密码,前端发起 /login 请求

  2. 后端验证用户名、密码(bcrypt 加密比对)

  3. 验证通过后生成 JWT,返回给前端

const token = jwt.sign({ userId, role }, secret, { expiresIn: '2h' });


️ 二、JWT 鉴权中间件:

后端接口使用中间件校验:

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) return res.status(401).send('Unauthorized');
  try {
    const user = jwt.verify(token, secret);
    req.user = user;
    next();
  } catch (err) {
    return res.status(403).send('Token Invalid');
  }
}

‍⚖️ 三、角色权限控制(RBAC):

通过装饰器或中间件判断:

function roleGuard(allowedRoles: string[]) {
  return (req, res, next) => {
    if (!allowedRoles.includes(req.user.role)) return res.status(403).send('Forbidden');
    next();
  };
}
router.get('/admin/dashboard', authMiddleware, roleGuard(['admin']), handler);

✅ 8.2 实现一个「博客系统」,包含:增删改查 + 评论 + 权限控制

我实现过一个基于 NestJS + TypeORM + MySQL 的博客系统,具备完整的 CRUD 和评论功能,还结合了用户权限管理。


模型设计(简化版):

  • User(id, username, role)

  • Post(id, title, content, userId)

  • Comment(id, content, postId, userId)


核心功能实现:

1. 文章管理:
@Post('/post')
@UseGuards(JwtAuthGuard, RolesGuard('admin', 'editor'))
createPost(@Body() dto: CreatePostDto) {
  return this.postService.create(dto);
}
2. 评论功能:
@Post('/post/:id/comment')
@UseGuards(JwtAuthGuard)
addComment(@Param('id') postId, @Body() dto) {
  return this.commentService.add(postId, req.user.id, dto);
}
3. 权限限制:
  • admin:全权

  • editor:发文

  • user:评论、点赞

  • 权限控制通过守卫/中间件实现


✅ 8.3 实现「大文件分片上传 + 秒传 + 合并」的后端逻辑

这个场景在我们上传 100MB+ 视频、压缩包等资源时经常会遇到,我用过 Node.js 结合前端分片上传方案处理。


功能分三步:

✅ Step 1:分片上传接口
@Post('/upload/chunk')
uploadChunk(@UploadedFile() file, @Body() { fileHash, index }) {
  const chunkPath = `${uploadDir}/${fileHash}/${index}`;
  fs.writeFileSync(chunkPath, file.buffer);
}
✅ Step 2:秒传判断接口
@Get('/upload/check')
checkFile(@Query() { fileHash }) {
  return fs.existsSync(`${uploadDir}/${fileHash}.merged`);
}
✅ Step 3:合并接口
@Post('/upload/merge')
async merge(@Body() { fileHash, total }) {
  const chunks = [...Array(total).keys()].map(i => fs.readFileSync(`${fileHash}/${i}`));
  const filePath = `${uploadDir}/${fileHash}.merged`;
  fs.writeFileSync(filePath, Buffer.concat(chunks));
}

✅ 8.4 写一个「接口限流」中间件,按 IP 限制频率

为了防止某些接口被恶意调用,我写过一个简单的基于内存缓存或 Redis 的限流中间件。


场景:每个 IP 每 1 分钟最多访问某接口 10 次

const ipCache = new Map();

function rateLimiter(req, res, next) {
  const ip = req.ip;
  const now = Date.now();
  const limit = 10;
  const windowMs = 60 * 1000;

  if (!ipCache.has(ip)) {
    ipCache.set(ip, []);
  }

  const timestamps = ipCache.get(ip).filter(t => now - t < windowMs);
  if (timestamps.length >= limit) {
    return res.status(429).send('Too many requests');
  }

  timestamps.push(now);
  ipCache.set(ip, timestamps);
  next();
}

如果是分布式部署,建议将缓存迁移到 Redis:

redis.incr(`rate:${ip}`)
redis.expire(`rate:${ip}`, 60)

✅ 8.5 写一个「定时任务」系统,每天定时发日报邮件

我使用 node-cronnodemailer 实现过日报定时任务,部署在服务器长期运行。


使用 node-cron 设置每天 9 点发送邮件:

import cron from 'node-cron';
import nodemailer from 'nodemailer';

cron.schedule('0 9 * * *', async () => {
  const transporter = nodemailer.createTransport({ /* SMTP 配置 */ });

  const users = await getAllUsers(); // 查询收件人
  for (const user of users) {
    await transporter.sendMail({
      from: '"日报系统" ',
      to: user.email,
      subject: '你的日报',
      html: '

今日数据...

', }); } console.log('日报发送完毕'); });
  • 支持任务日志、失败重试

  • 可结合数据库记录发送状态,防止重复发送


✅ 总结一图

编号 场景题 核心设计与实现
8.1 登录 + JWT + 权限系统 JWT 中间件 + 角色守卫 + bcrypt 加密
8.2 博客系统(文章+评论+权限) NestJS 模块 + TypeORM 关系 + RBAC
8.3 大文件上传 + 秒传 + 合并 分片上传接口 + Hash 判断 + Buffer 合并
8.4 接口限流 基于 IP 的时间窗口限流策略,内存/Redis
8.5 定时任务系统(日报) node-cron + nodemailer,每天定时群发邮件


你可能感兴趣的:(全栈,前端,数据库,node.js,面试,前端)