likes
comments
collection
share

被“鹅”追打,谁来拯救我的项目?

作者站长头像
站长
· 阅读数 6

如果您也和我一样准备春招,只为TOP20大厂,欢迎加我微信shunwuyu,一起交流面经,一起屡败屡战。

被“鹅”追打,谁来拯救我的项目?

上图像极了我面完小鹅通后的悲伤遭遇。这只小鹅没想如此彪悍,上来就对项目一顿撕咬,30几分钟的面试问得我毫无招架之力。最后举小白旗投降,却没想面试官不依不饶,不是嘲讽却胜似嘲讽...

太狂了, 跟班上同学交流后,发现小鹅通这家公司基本把我们同学都“咬”了一遍,皆尝败绩。我们同学聊到它都谈虎色变咬牙切齿

各位,如果你最近也面了小鹅通被虐哭的话, 请评论区扣1。 以前我是不吃鹅的, 今年端午,我必杀吃肉。

前言

小鹅通不是大厂, 为何如此大量面人,要求如此之高呢?真是百思不得其解,怎么跟字节一样(吐槽下字节的面试官都很nice, 小鹅通的太盛气凌人,发展中的公司就这样吧)?发展有如此之好吗?

后面想清楚了, 去年小红书电商发展非常火热, 笔记带货成为爆款。小鹅通作为知识付费领域的高手, 肯定是被资本看好它在类小红书电商发展的可能。去电商新贵公司实习也挺好的, 静下心来做面试复盘,妥败妥战!

优化项目

小鹅通被电商资本看中,必然大量招人, 皆是新起项目。面试主要是问项目,锤代码能力。简里的项目在这种项目下, 确实硬不起来,那就规划个新项目,此文来个大纲。

新项目架构

我简历里有两个项目,一个VUE全家桶前端项目和一个Koa全栈项目。确实在介绍项目的时候,跟背八股文差不多,来来回回就是以下几项:

  • JWT 登录流程
  • axios 配置
  • 路由懒加载
  • 路由守卫
  • pinia 数据流
  • keeplive
  • 自定义的组件 .... 没什么亮点和难点,怎么优化呢?愁死我了....

我把简历给了在拼多多工作的学长看,向他取取经项目怎么优化。他告诉我,可以先宏观的从技术架构上下手,增加后台管理系统和aigc两个子项目。尝试使用ts, python, 项目部署上线,docker容器化等...

大佬还是大佬,一下子豁然开朗,确实技术范一下子就搞起来了,亮点、难点都有了。但这么一搞,怕是写完春招早没了吧?学长嘿嘿一笑,其实只要架子搭起来,砖慢慢砌就好,边写边面不影响。

原来,一个顶级大厂的面试, 项目这块是可以设计的。

  • 前端这块还是之前的套路,仿一个移动电商项目。
  • 后台管理系统使用ElementPlus+TS, 这块代码不多,把ts安排上应该好打理
  • 后端api服务 在登录功能的基础上,再安排几张表的crud。
  • aigc 安排些openai 接口的调用, chatbot 啥的。

开干, 上截图。

被“鹅”追打,谁来拯救我的项目?

后端api服务

数据表设计

介绍项目的时候, 我打算从数据表设计开始,这里可以安排索引分表等数据库性能优化的点,是在前端面试中比较有区分度的技术点。

我参考了 xb2-node-assets/database/xb2_node.sql at master · ninghao/xb2-node-assets (github.com)

比如:

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `password` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

用户表是项目数据库性能的核心,字段应该尽可能核心简单,其它的分表做关联查询。除了mysql默认主键外,name 要设置UNIQUE KEY,用户名唯一。

再比如:

CREATE TABLE `comment` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` longtext COLLATE utf8mb4_unicode_ci,
  `postId` int(11) NOT NULL,
  `userId` int(11) NOT NULL,
  `parentId` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `postId` (`postId`),
  KEY `userId` (`userId`),
  KEY `parentId` (`parentId`),
  CONSTRAINT `comment_ibfk_1` FOREIGN KEY (`postId`) REFERENCES `post` (`id`),
  CONSTRAINT `comment_ibfk_2` FOREIGN KEY (`userId`) REFERENCES `user` (`id`),
  CONSTRAINT `comment_ibfk_3` FOREIGN KEY (`parentId`) REFERENCES `comment` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

可以告诉面试官, 为啥要对postIduserIdparentId三个字段加索引呢?搞明白了,就说明我们彻底理解索引对于提升数据库查询速度的意义。

比如, 评论表有一千万条数据,我们要获取某篇文章的评论,如果不添加KEY postId (postId),那么就必须遍历所有的评论才能找到这些评论,这是无法忍受的。当我们分析出项目中,某查询很频繁时,就要给相应字段加索引。

被“鹅”追打,谁来拯救我的项目?

userId加普通索引,方便我们在小家列出某用户的评论列表;对parentId加索引,方便我们把子列表列出....

到时我的新项目, 数据表设计就按这个思路来设计sql, 整个sql文件。面试官一看有好几张表,而且索引设计妥当,3分钟左右的,有区分度有亮点的项目介绍时间就拿到了。

JWT 登录功能后端实现

登录流程和JWT的实现是项目中的必考点,之前项目中就安排了, 直接搬过来就行。

大家可以参考 xb2-node/src/auth/auth.controller.ts at master · ninghao/xb2-node (github.com),写的非常牛逼。

错误处理中间件

export const defaultErrorHandler = (
  error: any,
  request: Request,
  response: Response,
  next: NextFunction,
) => {
  if (error.message) {
    console.log('🚧', error.message);
  }

  let statusCode: number, message: string;

  /**
   * 处理异常
   */
  switch (error.message) {
    case 'NAME_IS_REQUIRED':
      statusCode = 400;
      message = '请提供用户名';
      break;
    case 'PASSWORD_IS_REQUIRED':
      statusCode = 400;
      message = '请提供用户密码';
      break;
    case 'USER_ALREADY_EXIST':
      statusCode = 409;
      message = '用户名已被占用';
      break;
    case 'USER_DOES_NOT_EXIST':
      statusCode = 400;
      message = '用户不存在';
      break;
    case 'PASSWORD_DOES_NOT_MATCH':
      statusCode = 400;
      message = '密码不对';
      break;
    case 'UNAUTHORIZED':
      statusCode = 401;
      message = '请先登录';
      break;
    case 'USER_DOES_NOT_OWN_RESOURCE':
      statusCode = 403;
      message = '您不能处理这个内容';
      break;
    case 'FILE_NOT_FOUND':
      statusCode = 404;
      message = '文件不存在';
      break;
    case 'TAG_ALREADY_EXISTS':
      statusCode = 400;
      message = '标签已存在';
      break;
    case 'POST_ALREADY_HAS_THIS_TAG':
      statusCode = 400;
      message = '内容已经有这个标签了';
      break;
    case 'UNABLE_TO_REPLY_THIS_COMMENT':
      statusCode = 400;
      message = '无法回复这条评论';
      break;
    case 'FILE_TYPE_NOT_ACCEPT':
      statusCode = 400;
      message = '不能上传此类型文件';
      break;
    case 'NOT_FOUND':
      statusCode = 404;
      message = '没找到 ~~ 🦖';
      break;
    case 'USER_NOT_FOUND':
      statusCode = 404;
      message = '没找到这个用户 ~~';
      break;
    case 'PASSWORD_IS_THE_SAME':
      statusCode = 400;
      message = '要修改的密码不能与原密码一样';
      break;
    default:
      statusCode = 500;
      message = '服务暂时出了点问题 ~~ 🌴';
      break;
  }

  response.status(statusCode).send({ message });
};

koa主要通过中间件机制搭建后端服务,错误处理中间件,可以体现我们对项目稳定性和错误细节的理解,顺手还可以安排一波状态码。上面的代码状态码整的挺好

来来来, 欢迎面试官大佬问一波304 缓存相关,我已准备好。

面试不是被考试, 而是当面展示自己。

文件上传

这个确实很难,面试官会非常感兴趣,以后再展开

后台管理系统

在这个子项目中,主要展示我们对ElementPlusUI组件库的业务熟练度, 同时用TS编写,安排些TS相关考点

登录和角色校验,做登录页, 并实现不同角色不同的树状菜单。

  • 数据列表

分页、翻页、弹窗等功能

  • 产品上新功能

markdown 编辑器, 实时浏览功能

  • typescript

interface 、泛型功能

前端新功能

除了上面说到的传统内容外, 我准备安排以下功能点:

tailwindcss

原子css开发

better-scroll 滚动加载更多

参考loadmore

骨架屏

three.js 数据可视化

hooks

AIGC

23年是AIGC元年,24年是AIGC爆发年,我们这批程序员正走在从AIGC走向AGI(通用人工智能)的大道上。

chatbot

参考lianginx/chatgpt-vue: 使用 Vue3 + Typescript + Tailwind CSS 框架,调用 OpenAI 的 gpt-3.5-turbo 模型 API 实现的简单聊天对话,支持连续对话。 (github.com)

semantic search

RAG

总结

本来想把项目写完,再发文章的。但一想,有太多像我一样在找大厂实习的同学,被面试官大们追问项目,太惨了。于是, 先把想法拿出来, 欢迎在评论区讨论,帮我补充。

此文会一直更新,谢谢。