美团到店前端一二面面经
一面--一个半小时
1.自我介绍
2.介绍下项目3.vue双向绑定原理
4.学习前端的路径,途径 (js, html, css, vue),博客,电子书,github...
5.vue2.0版本中的数据劫持有什么缺陷,vue3.0怎么改进的,原理(没说出来,面试官说这个不重要。。。)
6.自定义组件的data为什么定义为函数
7.computed和watch的区别,使用场景有什么区别
8.v-for为什么要绑定key,什么场景下不绑定key反而效率更高,绑定key效率一定高吗,怎么样就不会起作用(绑定index),自定义组件不绑定key效率更高???
9.vue对watch的优化?
export default { name: 'com', data: function(){ return { msg: 0 } }, mounted(){ this.msg = 1 this.msg = 2 this.msg = 3 }, watch: { msg(){ console.log(this.msg) // 此处输出? // 3 原因:vue的优化 } } }10.场景题:在一个自定义组件a中包裹一个element-ui组件库中的input,如何将input组件的绑定属性透传到a组件?$attr, 事件呢? $listener
11.vue-router的模式,讲一下history在浏览器层面的原理?不清楚 html5中的historyAPI知道吗?不知道
12.组件传值的方式(父子、兄弟),$emit, v-bind;provide, inject;$on,$listener; vuex; Event bus(待会再问,然鹅待会也没问。。。)
13.递归实现n的阶乘,O(1)空间复杂度,提示借助参数化 没做出来(考察尾递归)
function f(n, total = 1){ if (n <= 1) { return total } else { return f(n-1, total * n) } } f(5) // 12014.描述进程和线程,区别
setTimeout(function(){ console.log('setTimeout 1...') new Promise((resolve, reject) => { console.log('executor start...') resolve() }).then(res => { console.log('then1...') }).then(res => { console.log('then2...') }) }) setTimeout(function(){ console.log('setTimeout 2...') })16.浏览器有哪些进程?浏览器进程,渲染进程,网络进程,渲染进程有哪些线程?
17.http状态码?203是啥,301和302区别是啥,缓存失效的状态码是啥
缓存失效的状态码是200 2XX 203 Non-Authoritative Information,服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝 由于正在使用的是文档副本所以某些响应头信息可能不正确。这是 HTTP 1.1中新加入的 204 (No Content/无内容): 比如Delete请求 301:永久重定向,服务器会返回一个Location:XXX,告诉客户端去新地址请求资源 302:临时重定向(Found),返回Location: XXX,暂时转移 303:See Other, 类似301,返回一个Location: XXX,还会要求使用GET方法请求 说明:实际浏览器在处理301和302时,默认就会把原先的POST改为GET,303只是让语义更清晰 304:Not Modified,一般是GET请求中带有附加条件,例如请求头中含有If-Match, If-Modified-Since 307:临时重定向,Location: XXX,不允许从POST转为GET 4XX 400:Bad Request,请求中有语法错误 401:未授权,没有认证信息 403:Forbidden,禁止访问资源 404:Not Found18.缓存策略,对应的头部字段是啥
20.数组反转 js
21.描述下数组跟链表的区别
22.js中的数组跟刚刚描述的数组有什么区别
23.js中数组有哪些方法
24.js箭头函数,给了一段类似如下的程序,判断输出
var obj = { diame: 10, zh: function() { return this.diame * 2 }, mj: () => { return this.diame * 3 // NaN undefined*3 } } console.log(obj.zh()) console.log(obj.mj())25.promise中的catch会捕获什么来源的错误
二面-四十分钟
1.实现单循环链表的insertHead()函数
// 写了个单链表形式的,没有写成循环链表 function ListNode(val){ this.value = val; this.next = null; this.insertHead = function(node) { if (!this.next) { this.next = node; } else { var p = this.next; this.next = node; node.next = p; } } } var head = new ListNode(-1); var p1 = new ListNode(2); var p2 = new ListNode(3); var p3 = new ListNode(4); head.insertHead(p1); head.insertHead(p2); head.insertHead(p3); var p = head; while(p.value != -1) { console.log(p.value); p = p.next; }2.一个班级的同学,分数存储格式为{name, score},实现一个算法,用最少的时间复杂度返回某同学的名次;输入为名字,输出为名次
/** * 班级成绩表,输入姓名,输出名次 * 要求: O(1)时间复杂度 * {name: score} */ function getRank(arr, name) { var pivot = _readscore(arr, name); return _getRank_helper(arr, 0, arr.length-1, pivot); } function _readscore(arr, name) { for(let index= 0; index < arr.length; index++) { if (arr[index].name === name ) { return index; } } } function _getRank_helper(arr, left, right, pivot) { //将pivot元素移到数组最左边或最右边,方便交换、遍历 var tmp = arr[left]; arr[left] = arr[pivot]; arr[pivot] = tmp; var target = arr[left].score; pivot = arr[left]; // 记录目标 var l = left, r = right; while (l < r) { while(l < r && arr[r].score <= target) --r; arr[l] = arr[r]; while(l < r && arr[l].score >= target) ++l; arr[r] = arr[l]; } arr[l] = pivot; return l+1; } // [94, 84, 14, 7] // 94,84,31,24,14,7 var scores = [{name: 'lucy', score: 14}, {name: 'tom', score: 84}, {name: 'danny', score: 7},{name: 'danniu', score: 94}, {name: 'dann', score: 31}, {name: 'dniu', score: 24}] var rank = getRank(scores, 'lucy'); console.log(rank) var rank = getRank(scores, 'dann'); console.log(rank) var rank = getRank(scores, 'dniu'); console.log(rank) var rank = getRank(scores, 'danny'); console.log(rank) console.log(scores)3.项目,登录怎么实现的,为什么要用盐值,如何验证用户信息