中软国际 - 前端面试
面试时间:2023-02-21
公司全称:中软国际科技服务有限公司(分公司)
公司性质:人力外派 💥
公司位置:广州天河区广东长线大厦1
面试题
防抖与节流的理解?各自的应用场景?
查看答案
防抖:在一次操作过程中,如果有新的操作则重新刷新定时器。应用:输入框输入后延迟自动搜索。
节流:前一次操作未完成时无法开启下一次操作。应用:下拉刷新和上拉加载更多。
浅拷贝与深拷贝的理解
查看答案
浅拷贝:拷贝对象的引用,对于复杂数据类型而言拷贝后的数据更改会影响原数据。
深拷贝:创建一块新的内存空间用于存储拷贝后的数据,拷贝数据与原数据由于地址不同,所以互不影响
this 指向的几种情况
查看答案
大多数情况下,函数调用方式决定了 this 的指向。
全局环境中定义的函数,this 指向 window。
new 关键字创建的实例对象,this 指向这个实例对象。
如果使用 apply()、call()、bind() 进行借调操作,this 指向这些方法第一个参数所绑定的对象。
箭头函数由于没有 this,它内部的 this 指向外层函数的 this,如果外层函数也没有 this,逐层向上找,直到 window 对象为止。
单页应用与多页应用的区别
查看答案
单页:应用只有一个 HTML 作为入口,一开始只需要加载一次 JS、CSS 等资源。页面的切换都是由路由去完成组件的切换,仅刷新局部资源。但无法实现 SEO 且首屏加载相对较慢。
多页:包含多个独立页面的应用,访问每一个页面都必须重新加载 JS、CSS 等资源。页面跳转需要整个页面刷新,用户体验不友好。由于返回完整的页面内容,利于 SEO。
Vue 的优势
查看答案
渐进式:易上手,开发者可以从简单的组件开始,逐渐去搭建复杂的系统。
轻量级:框架体积小。
组件化:组件化开发,提高开发效率。
MVVM 数据双向绑定:模型、视图同步更新,减少 dom 操作。
高性能:虚拟 dom + diff 算法。
插件化:插件生态丰富。
谈谈你对渐进式的理解?
查看答案
学习时可以从某个很小的部分入手,循序渐进,在后续通过增量学习的方式扩充所需的项目功能。
Vue 父子组件如何传值?
查看答案
父传子:父组件通过在子组件上添加属性的方式传递数据,子组件通过 props 属性接收。
子传父:子组件通过 this.$emit('eventName', data)
回传事件的方式传递数据,父组件通过 @eventName='fn'
绑定事件函数接收。
Vue 组件封装过程
查看答案
将公共常用的部分提取出去。通过 props 接收父组件传递的数据,通过 this.$emit() 传递事件的方式将数据传递给父组件。
v-model 的实现原理
查看答案
通过 :value 绑定响应式数据,@input 触发事件获取当前 $event.target.value,再赋值给 :value 绑定的变量。
computed 与 watch 的区别
查看答案
computed 计算属性基于 data 中声明过或 props 传递过来的数据通过计算得到一个新值,新值会根据已知值得变化而变化,且 computed 具有缓存功能,多次使用同一个 computed 计算得属性值,只会执行一次 computed 内定义的 function,直到依赖项改变才会重新计算。
watch 监听属性可以用来监听 data、props、computed 内的数据变化,然后执行某些具体的业务操作,当属性变化时,监听的的回调函数会自动执行。
对于多个监听对象要进行同一操作,watch 需要监听多次,而 computed 只需要执行一次。 在执行异步或开销比较大的操作时,watch 方式更合适。
笔试题
x.y.z
,xyz均为大于等于0的整数,至少有x位
题目1:实现 compareVersion 方法,用于比较两个版本号(version1、version2)。1) 如果version1 > version2,返回1;2)如果version1 < version2,返回-1;3)其他情况,返回0。版本号规则目标:
compareVersion('0.1', '1.1.1'); // 返回-1
compareVersion('13.37', '1.2 '); // 返回1
compareVersion('1.1', '1.1.0'); // 返回0
compareVersion('1.1', '1.1.1'); // 返回-1
查看答案
/**
* 题目1:
*
* 问题:实现 compareVersion 方法,用于比较两个版本号(version1、version2)
* 如果version1 > version2,返回1;
* 如果version1 < version2,返回-1;
* 其他情况,返回0。
* 版本号规则`x.y.z`,xyz均为大于等于0的整数,至少有x位
*
* 目标:
* ```js
* compareVersion('0.1', '1.1.1'); // 返回-1
* compareVersion('13.37', '1.2 '); // 返回1
* compareVersion('1.1', '1.1.0'); // 返回0
* compareVersion('1.1', '1.1.1'); // 返回-1
* ```
*/
function compareVersion(version1, version2) {
// ... 这里写代码实现
// 版本号字符串转成数字数组
const arr1 = version1.split('.').map(Number)
const arr2 = version2.split('.').map(Number)
// 长度不同时补 0 以保证长度一致
while (arr1.length < arr2.length) {
arr1.push(0)
}
while (arr2.length < arr1.length) {
arr2.push(0)
}
// 比较每一位数字的大小
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] > arr2[i]) {
return 1
} else if (arr1[i] < arr2[i]) {
return -1
}
}
// 相等返回 0
return 0
}
题目2:井字棋游戏。输入一个二维数组代表棋盘,其中『1』代表当前玩家的棋子,『0』代表没有棋子,『-1』代表对方玩家的棋子。若一方棋子在横、竖、斜方向连成排则为获胜,返回当前玩家是否胜出
示例:入参为 [[1,0,1],[1,-1,-1],[1,-1,0]] 时,返回 true
查看答案
/**
* 题目2:
*
* 问题:井字棋游戏。输入一个二维数组代表棋盘,其中
* 『1』代表当前玩家的棋子,『0』代表没有棋子,『-1』代表对方玩家的棋子。
* 若一方棋子在横、竖、斜方向连成排则为获胜,返回当前玩家是否胜出。
* 示例:入参为 [[1,0,1],[1,-1,-1],[1,-1,0]] 时,返回 true
*
*/
function gameCheck(arr) {
// ... 这里写代码实现
const len = arr.length
// 检查行
for (let i = 0; i < len; i++) {
let count = 0
for (let j = 0; j < len; j++) {
if (arr[i][j] === 1) {
count++
}
if (count === 3) {
return true
}
}
}
// 检查列
for (let j = 0; j < len; j++) {
let count = 0
for (let i = 0; i < len; i++) {
if (arr[i][j] === 1) {
count++
}
if (count === 3) {
return true
}
}
}
// 检查 2 条对角线
if (
(arr[0][0] === 1 && arr[1][1] === 1 && arr[2][2] === 1) ||
(arr[0][2] === 1 && arr[1][1] === 1 && arr[2][0] === 1)
) {
return true
}
return false
}