轻流面经
• #面试
自我介绍
Monorepo这种单仓库管理和Multirepo从你的开发体验来说最大的差别是什么(对我来说代码共享和复用)
(导致我有误区的原因是对Multirepo没有搞懂概念,Multirepo指的是将一个大型项目或组织的不同模块/服务拆分到独立的代码仓库中进行管理和开发)
-
代码共享和复用
- 所有项目代码在同一个仓库中,更容易共享和复用代码
- 避免重复开发相同功能
- 工具库可以直接被所有项目引用
-
依赖管理
- 统一的依赖版本控制
- 避免依赖冲突
- 减少node_modules的重复安装
-
工作流程
- 统一的构建流程和工具链
- CI/CD 流程可以统一管理
-
缺点
- 仓库体积较大
软连接/硬链接
-
软链接(符号链接 Symbolic Link)
- 类似于 Windows 的快捷方式
- 仅包含原文件的路径信息
- 原文件删除后,软链接失效
- 可以跨文件系统
- 可以指向目录
-
硬链接(Hard Link)
- 与原文件共享同样的 inode 和数据块
- 不占用额外的磁盘空间
- 删除任意一个链接,文件依然存在
- 不能跨文件系统
- 不能指向目录
从开发到项目落地制定规范
-
分支规范
- master/main: 主分支,保持稳定可发布状态
- develop: 开发分支
- feature/*: 功能分支
- hotfix/*: 紧急修复分支
-
代码规范
- ESLint + Prettier 配置
- Husky + lint-staged 提交前检查
- Commitlint 规范提交信息
-
开发效率(工具选择)
- 组件库/工具库
- 热更新
- TypeScript 类型检查
- API 自动生成
-
自动化构建流程
- 代码编译/转换
- 资源压缩
- 分包策略
-
自动化构建流程
- 代码编译/转换
- 资源压缩
- 分包策略
-
测试阶段
- 单元测试(Jest)
- E2E测试(Cypress)
- 测试覆盖率报告
- UI还原度检查
-
部署阶段
- CI/CD 流程
- 灰度发布
- 回滚机制
-
监控阶段
- 性能监控
- 错误监控
- 用户行为分析
- 性能优化
前端还是后端处理数据的理解
前端专注页面 后端专注数据处理
后端可以加服务器,如果前端处理,项目开发越往后,性能问题前端比后端更难解决
vue2和vue3区别,说一下开发体验差别
-
响应式系统
- Vue2: Object.defineProperty 实现,对数组和对象的监听有限制
- Vue3: Proxy 实现,更完整的响应式支持,性能更好
-
组合式 API vs 选项式 API
- Vue2: 选项式 API,代码按 options 组织,大型组件逻辑分散
- Vue3: 组合式 API,相关逻辑可以组织在一起,更好的代码复用和组织
-
TypeScript 支持
- Vue2: TypeScript 支持有限,需要额外配置
- Vue3: 原生支持 TypeScript,类型推导更完善
-
性能提升
- 更小的打包体积
- 更好的 tree-shaking 支持
- 虚拟 DOM 重写,渲染性能提升
- 编译优化,更好的静态内容提升
-
开发体验优势
- Vue3 的 Composition API 和 hooks 模式使代码复用更简单
- 更好的 IDE 支持和类型提示
- 更清晰的错误提示和警告
- setup 语法糖简化代码编写
设计模式(观察者模式)
-
定义
- 一种行为设计模式,定义了对象之间的一对多依赖关系
- 当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新
-
核心角色
- Subject (主题): 被观察的对象,维护观察者列表
- Observer (观察者): 接收主题通知并作出响应的对象
-
应用场景
- 事件处理系统
- 消息推送
- 状态监听
- UI 更新机制
-
代码示例
// 观察者接口
interface Observer {
update(message: string): void;
}
// 主题接口
interface Subject {
attach(observer: Observer): void;
detach(observer: Observer): void;
notify(message: string): void;
}
// 具体主题
class NewsAgency implements Subject {
private observers: Observer[] = [];
attach(observer: Observer): void {
if (!this.observers.includes(observer)) {
this.observers.push(observer);
}
}
detach(observer: Observer): void {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
notify(message: string): void {
for (const observer of this.observers) {
observer.update(message);
}
}
publishNews(news: string): void {
this.notify(news);
}
}
// 具体观察者
class NewsSubscriber implements Observer {
private name: string;
constructor(name: string) {
this.name = name;
}
update(message: string): void {
console.log(`${this.name} 收到新闻: ${message}`);
}
}
// 使用示例
const newsAgency = new NewsAgency();
const subscriber1 = new NewsSubscriber("订阅者1");
const subscriber2 = new NewsSubscriber("订阅者2");
newsAgency.attach(subscriber1);
newsAgency.attach(subscriber2);
newsAgency.publishNews("重大新闻!");
// 输出:
// 订阅者1 收到新闻: 重大新闻!
// 订阅者2 收到新闻: 重大新闻!
面向对象编程和面向函数编程
-
面向对象编程 (OOP)
- 核心概念
- 封装:将数据和方法捆绑在对象中
- 继承:子类继承父类的属性和方法
- 多态:同一接口可以有不同实现
- 特点
- 以对象为中心组织代码
- 通过类和实例管理状态
- 使用 this 关键字
- 适合复杂的业务模型
- 核心概念
-
面向函数编程 (FP)
- 核心概念
- 纯函数:相同输入总是产生相同输出
- 不可变性:数据不可修改,而是创建新数据
- 函数组合:通过组合小函数构建复杂功能
- 特点
- 避免副作用
- 强调数据转换而非状态修改
- 更容易测试和并行化
- 适合数据处理和计算密集型任务
- 核心概念
-
实际应用
- 现代开发通常混合使用两种范式
- React Hooks 结合了 FP 的思想
- Vue3 的 Composition API 也借鉴了 FP 理念
数据结构
二叉树
- 定义
- 每个节点最多有两个子节点的树结构
- 子节点分为左子节点和右子节点
- 可以为空(空树也是二叉树)
链表是否成环
快慢指针法(Floyd)
图
- 定义
- 由顶点(节点)和边组成的非线性数据结构
- 是否成环
vercel部署是怎么做的
- 自动部署流程
- 监听 GitHub 仓库的变更(通过 GitHub Webhooks)
- 检测到代码推送时自动触发构建
- 根据项目类型选择适当的构建环境
- 执行构建命令(如 npm run build)
- 将构建产物部署到 Vercel 的 CDN
Git
- 撤回提交 git revert HEAD
- 多个commit合成一个 git rebase -i
工作区(Working Directory) 未git add
暂存区(Staging Area/Index) 使用 git add 命令后,文件被添加到的区域
算法
textarea中需要对表单数据进行验证,实现一个算法,验证textarea中的数据不包含单行注释://,
遇到它就进行提示,但是遇到链接如http://www.baidu.com这类情况需要进行保留。
replaceAll match