6.29-杭州端点科技-面试题总结

3,756 阅读14分钟

前言

6.29 上午面一家深圳健康160,下午考试+面杭州端点+纬创 以下是杭州端点的面试题(面了43分钟, 前面拉胯,后面稍微好点),及其自我总结:

裂开.jpg

1. 自我介绍+项目介绍

2. Vue双向数据绑定原理

我的回答:

采用“数据劫持”结合发布者-订阅者模式,通过Object.definedProperty()的setter和getter来劫持data的各个属性,当数据变化时,通知订阅者,来触发相应的监听回调。

3. Vue监听数组

我的回答:

我说好像不能监听数组,但是我记得可以深度监听(deep:true) 但是我没说...
查资料也有说重写数组方法...

4. Vuex

我的回答:

Vuex是Vue的状态管理模式,相当于一个共享仓库,其他页面可以访问这个仓库;Vuex里面有五个属性:

  1. State,存储数据。

  2. Getters:获取数据,相当于计算属性( computed )。

  3. Mutations:唯一能修改store状态的方式,是同步的。

  4. Actions:提交Mutations修改的数据,是异步的。

  5. Module:当一个store文件太大了,可以拆分成多个模块,组合在一起。

总结的回答:

1. Vuex是Vue的状态管理模式,相当于一个共享仓库,其他页面可以访问这个仓库;

2. Vuex状态存储是响应式的,当Vue组件从store中读取状态时,如果store的状态改变了,那么用到这个store的组件也会更新;

3. State: 存储数据;组件使用 store.state. 获取数据。

4. Getters: 获取数据,相当于state计算属性( computed ),通过this.$store.getters.获取。

5. Mutations: 唯一能修改store状态的方式,只能是同步函数 this.$store.commit(方法名,值)。

6. Actions: 提交Mutations修改的数据,异步操作。

7. Module: 模块化Vuex,当一个store文件太大了,可以拆分成多个模块,让每一个模块都有自己的State、Getters、Mutations、Actions、Module。

5. axios拦截器

我的回答:

只用过响应拦截器,当返回的状态码不是200就进入错误页面。(没细说...)

总结回答:

应该说返回的状态码不同,进入不同的页面(403:无权访问;404:资源不存在;500:服务器内部错误;503:请求太过频繁,稍后再试)。

6. js数据类型 判断引用数据类型

我的回答:

  1. 基本数据类型:Number、String、Boolean、Null、Undefined、Symbol(ES6新增)、BigInt(ES11新增);

  2. 引用数据类型:Function、Array、Object、Date、RegExp。 (忘说两者的区别了...)

3.instanceof和Object.prototype.toString.call() 总结的回答:

  1. 分别说出有哪些

  2. 基本数据类型存在栈中,引用数据类型存在堆中,其指针存在栈中。

  3. typeof:可以判断基本数据类型

  4. 如何判断引用数据类型:可以用instanceof判断;

    也可以用Object.prototype.toString.call()

    判断数组:Array.isArray()

7. instanceof 的限制

我的回答: 我回答成了:instanceof判断 null 和 undefined了...(会报错)

总结的回答: instanceof 左边必须是对象

红宝书P142:使用instanceof的问题是假定只有一个全局执行上下文。如果网页里有多个框架,则可能涉及两个不同的执行期上下文,因此就会有两个不同版本的Array构造函数。如果要把数组从一个框架传给另一个框架,则这个数组的构造函数将有别于第二个框架内本地创建的数组。 所以又出现了Array.isArray(),该方法确定一个值是否为数组,不管它是哪个全局执行上下文中创建的。

8. instanceof 原理

我的回答: 访问原型上面是否有该方法。

总结的回答: MDN的描述:instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

9. 实现instanceof

我的回答: new一个实例,把它的__proto__属性指向构造函数的prototype

总结的回答: instanceof原理.png

10. 原型、原型链

我的回答: 每一个对象都有prototype,如果是继承的话,访问构造函数原型上的方法,如果构造函数的原型上没有该方法,就会想构造函数原型的原型上去找,这样就形成一条链,原型链的顶端是Object。

总结的回答:

原型的概念:每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。

原型1.png

person. __ proto __ == Person.prototype

Person = Person.prototype.constructor

11. 继承

我的回答: 我说有6种,但是没列举出来,因为每种的优缺点我忘了...

总结的回答:

  1. 借用构造函数:子类构造函数中使用call()或apply()

  2. 原型链继承:父类的实例作为子类的原型

  3. 组合继承:结合前两者的优点

  4. 原型式继承:利用空对象为中间,将对象赋值给空对象构造函数的原型(浅复制)

  5. 寄生式继承:使用原型式继承对一个目标对象进行浅复制,增强这个浅复制的能力

  6. 寄生组合继承:结合借用构造函数传递参数和寄生模式实现继承(最推荐的方法) 后续会单独写篇文章。

12. new实例化对象的过程

我的回答:

  1. new一个空对象
  2. 将该对象的__ proto__ 指向构造函数的原型 后面就忘了 (改变this指向)

总结的回答:

  1. 创建一个空对象 let person = {}

  2. 将新对象的proto指向构造函数的prototype person.__ proto __ = Person.prototype

  3. 改变this指向 Person.call(person) //{}.构造函数()

  4. 将初始化完毕的新对象地址,保存到等号左边的变量中

13. this指向(严格模式)

我的回答:

  1. 全局上下文

  2. 函数内部的

  3. eval(不推荐)

  4. 严格模式下:this为undefined 总结的回答:

  5. 全局上下文中,不管是严格模式还是非严格模式,this都指向window

  6. 函数上下文,非严格模式:this指向调用函数,非严格模式:this为undefined

  7. eval考虑

  8. 箭头函数的this:离它最近的外层普通函数的this,而且不能改变

  9. new关键字调用函数时,this指向实例对象

  10. 对象调用,指向对象

14. 改变this指向的方法

我的回答:

  1. call():传入的参数是一个一个的

  2. apply():传入的参数是数组

  3. bind():返回一个新的函数,多个bind只有第一次有效

15. {} === {}

我的回答: false,对象是引用类型,存在堆中,每个对象都有自己的空间。

16. 闭包、优缺点

我的回答: 形式上,函数内部返回一个函数,返回的函数对父级作用域的变量存在引用。 优点:私有变量(构造函数的特权方法)、延长变量的作用域 缺点:不释放会引起内存泄漏(占用内存,使我们无法使用)

17. 防抖和节流

我的回答:

防抖:输入框持续输入,设置固定的时间,当这段时间不在输入,就执行该函数。

应用场景:

  1. 输入框搜索内容,通过防抖来节约流量;

  2. 不断触发window.resize事件(改变窗口大小),可以使用防抖。

代码实现: 定时器 防抖.png 节流:再规定的时间内,不管触发多少次,只执行最后一次,即单位时间内,只执行一次。

应用场景:鼠标持续点击,单位时间内只执行一次

代码实现:

  1. 时间戳 节流.png

  2. 定时器

节流2.png

18. 箭头函数与普通函数的区别

我的回答:

  1. 省略function关键字和return;

  2. 当参数只有一个时,可以省略小括号;多个参数时,必须使用小括号;当代码只有一行时,可以省略花括号;

  3. 本身没有this,继承当前上下文中,最近的普通函数的this,而且不能改变this指向;

  4. 不能作为构造函数,不能使用new来是实例化对象,所以没有原型(prototype);

  5. 没有arguments,可以用rest代替。

19. js延迟加载

我的回答: 回答错了,我以为异步加载就是延迟加载...

script标签可以设置defer和async两个属性,实现延迟加载 defer:异步下载脚本,直到文档解析完成后执行该脚本(有序) async:异步下载脚步,下载完成立即执行,脚步执行完后(不保证执行顺序),页面继续解析。

总结的回答:

延迟加载:

  1. 使用setTimeout延迟加载;

  2. js脚本放在最后面。

异步加载:

  1. defer:异步下载脚本,直到文档解析完成后执行该脚本(有序);

  2. async:异步下载脚步,下载完成立即执行,脚步执行完后(不保证执行顺序),页面继续解析。

20. document.write和document.innerHTML

我的回答: 面试官说了两三遍,我都没听清楚啥第一个说的是啥,就听到后面的有个docunent.innerHTML,我以为是document.right,我还在想,我都没见过这个。。。 最后我回答了innerHTML和innerText。

总结的回答: 复习一下innerHTML和innerText:

  1. innerHTML:获取文本信息,包括标签
  2. innerText:获取文本信息,不包括标签

21. 重排和重绘

我的回答:

重排也叫回流:当DOM节点新增或删除,位置大小发生变化,会引起回流;

重绘:改变元素的颜色,字体和visibility会引起重绘。

嘴瓢了,最后改正了:重排必然会重绘,但重绘不会重排。

22. js哪些操作会引起内存泄漏

我的回答:

  1. 闭包

  2. 意外的全局变量(函数内部声明的全局变量)

  3. 未清空的定时器和计时器

23. 事件流

我的回答: 捕获阶段 -> 事件阶段 -> 冒泡阶段, 举了个例子。

总结的回答:

DOM2级,addEventListener事件监听,有事件冒泡;

捕获阶段 -> 事件阶段 -> 冒泡阶段

捕获阶段: Window -> Document -> < html> -> < body>...< div> -> < span> 冒泡阶段: < span> -> < div>...< body> -> < html> -> Document -> Window

例子:若点击< span> 输出1,点击< div>输出2;

  1. 点击< span>,会先输出1,再输出2;
  2. 点击< div>,只输出2。

24. Event.target和Event.currentTarget.

我的回答: 听到个Event.target,另一个听成了Event.parentTarget....

总结的回答: Event.target:目标对象(事件触发元素) Event.currentTarget:绑定事件的对象(绑定事件的当前元素)

25 浏览器事件循环

我的回答: 只说了浏览器的事件循环,没说Node的事件循环:

浏览器中分为同步任务和异步任务,同步任务在主线程上顺序执行,异步任务则进入任务队列,而任务队列分为宏任务和微任务。

  1. 同步任务执行完,检查任务队列,若有宏任务和微任务,先执行微任务,再执行宏任务;
  2. 如果执行微任务的过程中,产生了微任务,就加入到微任务队列,并按顺序执行,直到所有的微任务执行完后,再去执行宏任务;
  3. 如果执行宏任务的过程中,产生了微任务,就等当前宏任务执行完后,执行微任务,直到所有的微任务执行完后,再执行宏任务。

26 宏任务和微任务

我的回答:

浏览器宏任务:I/O、setTimeout、setInterval、requestAnimationFrame

浏览器微任务:Promise.then .catch .finally、MutationObserver

Node宏任务:I/O、setTimeout、setInterval、setImmediate

Node微任务: process.nextTick、 Promise.then .catch .finally

宏任务包括:

MacroTask浏览器Node
I/O
setTimeout
setInterval
setImmediate
requestAnimationFrame

微任务包括:

MicroTask浏览器Node
process.nextTick
MutationObserver
Promise.then catch finally

27. 对Promise的理解

我的回答: 异步编程的一种方案,优化回调地狱 Promise接收两个参数(resolve,reject),这两个参数都是函数;有三个状态:pending进行中,fulfilled成功,rejected失败,返回的结果也是Promise对象, 状态只能改变一次。

28 Promise静态方法

我的回答: Promise.all和 Promise.race

29. ES6新特性

  1. let、const
  2. class
  3. 解构赋值
  4. 箭头函数
  5. promise
  6. async和await

30. let和const 与var的区别

我的回答:

  1. 有变量提升,存在暂时性死区,提前使用会报错;

  2. 有块级作用域,var则没有;

  3. 不能重复声明变量;

  4. const声明变量必须赋值,声明的常量不可修改,声明的对象可以修改属性。

31. for...of与for...in

我的回答: for...of:遍历数组,不能单独遍历普通对象,需要借助Object.keys() for...in: 遍历可迭代对象的属性名,不推荐遍历数组

32. HTTP状态码

我的回答:

1. 200:OK  //返回成功
2. 301:Moved Permanently  //永久重定向
3. 302:Found  //临时重定向
4. 304:Not Modified  //资源未修改,使用协商缓存
5. 307:Temporary Direction  //与302类似,临时重定向,使用GET方式
6. 400:Bad Request  //请求报文出现语法错误
7. 401:Unauthorized  //未登录,需要请求认证
8. 403:Forbidden  //无权限访问,被拒绝
9. 404: Not Found  //资源不存在
10. 408:Request Time-out  //请求超时
11. 500: Internal Server Error  //服务器内部错误
12. 503: Service Unavailable  //服务器繁忙或维护(请求太频繁)
13. 505:HTTP Version not Supported  //不支持请求的HTTP版本

33. 强缓存和协商缓存

可以去看看这篇文章

34. 为什么需要三次握手

我的回答:

第一次:证明客户端可以发送数据

第二次:证明服务器可以接收数据发送数据

第三次:证明客户也可以接收数据

35. BFC

我的回答: Block Formatting Context,用处解决统一父元素的两个盒子外边距重叠问题;

触发条件:

  1. body根元素(最大的BFC);

  2. position:absolute或fixed;

  3. display(inline-block table-cell table-caption flex);

  4. float不为none;

  5. overflow不为visibility(hidden,scroll,auto,inherit)。

36. Flex

  1. flex-direction:定义主轴的方向:

     row (默认值):水平方向,从左边开始。
     row-reverse:水平方向,从右边开始。
     column:垂直方向,从上往下。
     column-reverse:垂直方向,从下往上。
    
  2. flex-wrap:项目是否换行:

     nowrap (默认值):不换行。 (1,2,3,4,5,6)
     
     wrap:换行,第一行在上面。    (1,2,3,4)
                                 (5,6)
                                 
     wrap-reverse:换行,第一行下面。  (5,6)
                                     (1,2,3,4)
    
  3. flex-flow: (flex-direction) (flex-wrap)。 默认值:row nowrap

  4. justify-content: 项目在主轴上的排列方式

    1. flex-start:左对齐
    2. flex-end:右对齐
    3. center:居中
    4. space-between:两段对齐,项目之间的间隔相等,及等分
    5. space-around:每个项目两侧的间距相等,所以项目之间的间距是边缘两倍
  5. align-items:项目在交叉轴上的对齐方式

    1. flex-start:交叉轴起点对齐
    2. flex-end:交叉轴重点对齐
    3. center:交叉轴中点对齐
    4. baseline:第一行文字基线对齐
    5. stretch:默认值,未设置高度或设置auto,占满容器
  6. align-content:多跟轴线时,项目在交叉轴上的对齐方式(一根轴线,该属性无效)

    1. flex-start:左对齐
    2. flex-end:右对齐
    3. center:居中
    4. space-between:两段对齐,项目之间的间隔相等,及等分
    5. space-around:每个项目两侧的间距相等,所以项目之间的间距是边缘两倍 参考justify-content

37. 左侧定宽,右侧宽度自适应

我的回答

  1. 左边设置宽高,左浮动;右边只给高度,宽度100%,margin-left:左边盒子的宽度;
  2. 父级display:flex,左边左边设置宽高,右边只给高度,宽度100%;
  3. 定位,左边绝对定位,右边只给高度,margin-left:左边盒子的宽度;
  4. BFC,左边浮动,右边overflow:hidden。

38. TypeScript

我的回答:用得不多,做react项目用到了泛型和接口,写代码时检测错误,规范编码。

39. 反问

对实习生的要求

学习方法

最后

总体上来说,这些知识点基本上都是知道的,但是没有答得太完整,这次没进,努力两个月,等秋招再来。加油!