一面
1. hooks 到底是什么?hooks 的设计理念是什么?解决了什么问题?
- hooks 是什么:
- 允许开发者在函数式组件中使用状态和其他 react 特性,而不是类 class
- hooks 设计理念:
- 提高代码复用性
- 增强组件可读性
- 避免嵌套地狱(class 高阶组件)
- 函数式编程
- 解决的问题:
- 复杂组件难以管理:类组件生命周期包含多个互不相关的逻辑 hooks 可以根据业务逻辑独立使用
- 状态逻辑复用困难:高阶组件存在一定局限 难以重复使用共享组件中的逻辑
- 类组件的 this 添加学习成本:state useState 使用起来更简单 减少了 this 指向不明的问题
2. react 框架原理是什么?和 vue 框架设计有什么区别?
- 模板语法 vs jsx:
- vue 使用简介的模板语法 以声明式的方式将数据渲染到页面上 html 结构在 templete 标签中书写
- react 的语法写在 js 文件中 使用 js 语法
- 数据绑定 vs 单向数据流
- vue 双向数据绑定 v-model 视图改变时更新 model model 改变时更新视图
- react 单向数据流 属性不允许直接修改 通过 onChange 和 setState 实现双向数据流
- 指令系统
- vue 存在 v-if v-for 指令
- react 通过函数的条件语句实现指令
3. 【笔试】实现大文件上传
二面
1. this 指向问题?
2. this 指向 在实际应用中 有遇到什么问题?怎么解决的?
- 类组件+函数组件
- 防抖节流 this 指向
- 函数式弹窗
3. 在类组件中 改变 this 有没有性能问题?
4. 对于开源组件进行二次开发时 您的关注点是什么?您会怎么进行开发?
5. 如果另一个项目 也想用这个开源组件 除了 copy 代码 还有什么方法?
6. 都是用过哪些第三方库?
- zustand
- proComponent
- ahooks
- NextJS
7. 如果让你抉择使用什么库?你会考虑哪些方面?
- 项目规模和复杂性
- 对于小型项目或简单的应用,可能不需要引入复杂的状态管理库,React 自身的状态管理(通过 useState 和 useReducer 等 Hooks)可能就足够了。
- 对于中型到大型项目,或者状态管理变得复杂(如跨组件状态共享、异步操作、全局状态等),我会考虑使用状态管理库。
- 功能需求+特性:
- 根据项目的具体需求,我会评估不同库提供的功能和特性
- 例如,是否需要全局状态管理、时间旅行调试、状态持久化、中间件支持等
- 稳定性+性能优化:
- 确保库能够高效地处理状态更新和渲染优化
- 一些库可能提供了内置的优化机制,如避免不必要的重新渲染、状态持久化等
- 灵活性和可扩展性:
- 选择的库能够灵活地适应项目的需求变化
- 库是否支持插件、中间件或自定义扩展
- 学习曲线+社区资源
- 文档清晰、学习曲线平缓的库,这样团队成员可以更快地上手
- 社区资源:活跃的社区意味着有更多的资源、教程和问题解决方案
- 维护性和未来前景:
- 库的维护频率、是否有活跃的开发者社区和持续的更新
- 库的未来发展规划和兼容性
8. 有没有自己开发过 hooks?有哪些注意事项?
9. react 主要的生命周期有哪些?
10. react 和 vue 有哪些相似之处?有什么区别?
11. 在学习和工作中,最有成就感的事情是什么?
12. 你觉的这个过程中,是技术还是思维还是模式 让你感觉很有成就感?
13. 有没有遇到过沟通上的问题?事后有什么反思?
14. 在学习和工作中 有没有遇到过什么受挫的事情?
三面
1. 前端后续的发展趋势?
- 微前端
- 大前端
2. 客户端有接触过么?APP 相关
3. 【代码】二叉树的层序遍历
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function levelOrderTraversal(root) {
if (!root) return []
const queue = [root];
const result = [];
while (queue.length > 0) {
const levelSize = queue.length;
const currentLevel = [];
for (let i = 0; i < levelSize; i++) {
const node = queue.shift();
currentLevel.push(node.value);
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
result.push(currentLevel);
}
return result;
}
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
root.right.left = new TreeNode(6);
root.right.right = new TreeNode(7);
const result = levelOrderTraversal(root);
console.log(result);