您的位置:首页 > 职场人生

2018秋招前端面试回顾(阿里、百度、网易、迅雷、美团等)

2018-01-05 07:23 781 查看
今年秋招对我是个打击,不过也让我认清了现实。借用鲁迅先生的一句话,真正的勇士敢于直面惨淡的人生,敢于正视失败的面试。面试失败不可怕,可怕的是不能吸取教训。在吸取教训上我做的不好,不然也不会有些面试问题记不住了。回顾几次面试失败经历,我总结了一下各家公司问的问题,为未来作打算,也为师弟师妹们做个参考。总结了一下,发现实习经历真的很重要,而且项目经验也要重点突出一些东西,展现自己的技术特点,让面试官无懈可击。不然问一些东西说不出来就很尴尬了。

阿里一面(其实一面挺简单的,但发挥不好,面试官希望你会框架。问我react时,我一谦虚说不算很会,就不问我了,然后就挂了):
web语义化
meta标签作用(页面信息、搜索引擎、不同设备)认识
<meta>
这篇文章讲得很全面。
行内元素、块元素有哪些,布局
布局方式
三栏布局
css选择器优先级
http请求过程
http2.0了解
es2015了解哪些新特性(let/const,promise,class,set/map等忘了说箭头函数)
箭头函数和普通函数区别(this指向、不能做构造函数、不能使用arguments等)
异步编程(回调函数、监听/订阅、promise、async/await)
promise相关,规范、状态

百度三面(百度做了一个试题集,真是用心!!!面试感觉还是挺好的,很愉快的面试,但可怜的我并没有收到offer。另外有些面试会考手写代码,从头写到尾,不知道为什么没考我。。。) 

百度一面:
自我介绍
获取页面上个数top3标签
提取url键值对
console.log输出加上“hello”
linux bash命令cp/rm/mv/cat/ln -s/alias
有一个目录很深,如何很快的进入(建立软链接、设置别名?)
ajax跨域(cors、反向代理)
简述jsonp过程
ajax请求过程
两栏布局
css选择器优先级
离线缓存(manifest(貌似废弃了)、service worker(还不成熟))
客户端存储方式及异同
自定义表单,使各浏览器表现一致

百度二面:
自我介绍
继承方式(原型链、组合模式、寄生组合式继承)
web性能优化、图片优化(雪碧图懒加载)
web安全:xss csrf sql注入
linux部分知识tail top
自定义dialog组件(注意:要用闭包封装模块)
nodejs http获取百度页面,把百度改为千百度
输入url过程
单纯的聊天(不记入面试):看一个页面布局,说出布局想法

百度三面(总监面):
自我介绍
某个取值范围的随机数生成
nodejs优点
ajax请求过程
项目相关
谈人生规划

网易一面:
写一个继承,解释原型链
css规范化
闭包应用、模块
mvvm相关
知道哪些设计模式
两列布局
跨域方法
flex布局属性
事件流的三个阶段,哪些事件不能冒泡

迅雷一面(不得不说,迅雷笔试很有水平):
项目相关
unicode与utf-8字符编码方式关系
nodejs处理请求过程
require(‘child_process’).fork和linux fork区别

美团一面:
webpack原理
闭包自由发挥
react优势(组件化、虚拟dom)
怎么设计好的组件
项目相关
反转链表
https与http区别
git命令了解哪些
github开源做过哪些,贡献过什么,pr过吗

最后说一句:厉兵秣马,砥砺前行。我还要继续再战。

------------------------------------------------------------------------------------

2018年搜狗秋招前端笔试题:字符串删除

昨天做了搜狗前端笔试题,其中有一道题目是为字符串添加一个删除方法,给定一个参数n,求从该字符串删除n个字符组成的不同子串个数。题目看起来很简单,但是并不好编写。如果字符串字符各不相同还好说,直接可以使用排列组合公式来得到最终的个数;否则的话就得考虑删除后可能会产生相同的子串了。这样的话就得做一个Set来保存所有的字符串了。(我是这样想的,不知道还没有什么其他的方法。)当时想的是递归,但迫于时间没有写出来,所以趁着最近时间充裕,把算法实现了出来。如有错误,请不吝指正。
console.log('---从长为m字符串删除k个字符组成的不同子串个数---');
String.prototype.delete=function(k){
if(k==0)return 1;
var l=this.length;
var tmp=[];
var set=new Set();
help(this.split(''),0,k,tmp);
//print(set)
return set.size;
function help(arr,start,k,tmp){
if(k==0){
var rest=arr.filter((item,index)=>tmp.indexOf(index)==-1);
set.add(rest.join(''));
return;
}
if(l-start-1<k-1)return;
for(var i=start;i<l;i++){
tmp.push(i);
help(arr,i+1,k-1,tmp);
tmp.pop(i);
}
}
}
console.log('------test------');
console.log('segeg'.delete(0))  //1
console.log('segeg'.delete(1))  //5
console.log('segeg'.delete(2))  //8
console.log('segeg'.delete(3))  //6
console.log('segeg'.delete(4))  //3
console.log('segeg'.delete(5))  //1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

算法的关键是递归函数help(arr,start,k,tmp)。它接收四个参数,arr是字符数组,把原来的字符串转为了数组。start是开始位置,表示从start开始的位置都可以删除,之前的保持不变。k表示还能删除几个字符,当k=0时递归停止。tmp是保存的删除的字符索引。set保存删除字符之后的数组,该数组是过滤tmp中保存的索引得到的。最后只返回set的长度就可以了。每次递归的时候选择一个字符,把它保存下来,start+1,k-1,继续递归,等它完成后弹出该字符,继续下一个字符的递归。

最近感觉自己的递归水平太差了,笔试题的递归基本都写不出来,像全排列什么的,所以要加强联系了。这道题是我自己理解的解法,如果您有更好的方法,欢迎讨论。

--------------------------------------

前端面试题:如何使字符串可执行

这是一道今年腾讯春招的面试题。当考官一开始问我这道题的时候,我没有反应过来,什么叫使字符串可执行。好吧,请原谅我的无知。考官耐心的解释,字符串可执行的意思是将字符串转为立即执行的代码,如字符串
var a=23;
,使其经过某种操作后确实有个值为23的a变量。听了面试官的话后,我第一时间想到了
eval
方法。然而面试官并不满意,追问我还有其他方式吗,我一时没有想起来。面试过后我就想总结一下这个问题,不过因为拖延症,拖到今天才写,敬请见谅。本文内容主要借鉴《JavaScript忍者秘籍》中使字符串转为立即执行的代码一节。下面将讲述字符串可执行的四种方式。


1. 
eval()
方法

eval()
方法是一个很强大的方法,它接收一个字符串作为参数,当解析器发现代码中调用该方法时,会将传入的参数当作ECMAScript语句来解析,然后把执行结果插入到原位置。如代码
eval('var str="hi"');
,执行了这个语句后,就可以直接使用变量
str
了,如
console.log(str)
将输出”hi”。不过关于这个方法有以下几点要注意:

(1). 通过该方法执行的代码有与该执行环境相同的作用域链。这意味着它可以引用在包含环境中定义的变量。也意味着它可以形成闭包,这与下文的Function方法形成对比。
var str="hi, I'm student!";
eval('console.log(str)');
//output:hi, I'm student!
1
2
3

(2). 在eval()中创建的任何变量或函数都不会被提升。这很好理解,因为它只有在解析之后才会运行。
f1()    //Uncaught ReferenceError: f1 is not defined
eval("function f1(){console.log('hi')}")
1
2

(3). 任何不是简单变量、原始值、赋值语句的内容都需要在外面包装一个括号。执行返回结果则是最后一个表达式的执行结果。
eval("{name:1}")
的结果是1,惊不惊喜,意不意外?
var o1=eval("1");
console.log(o1);
//output:1

var o2=eval("{name:1}")
console.log(o2);
//output:1    why?

var o3=eval("({name:1})")
console.log(o3);
//output: Object {name: 1}

eval("3+4,5+6")//output:11
1
2
3
4
5
6
7
8
9
10
11
12
13

(4). eval()方法是全局方法,但eval和window.eval结果有时不同的。前者作用域顶端是当前上下文,后者作用域是window对象。
var color='red';
function test(){
var color='blue';
eval('console.log(color)');
window.eval('console.log(color)');
with(window){
eval('console.log(color)');
}
}
test()
//outputs:
//blue
//red
//red
1
2
3
4
5
6
7
8
9
10
11
12
13
14


2. 使用
Function
构造器

我们都知道函数实际上是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数除了使用函数声明和函数表达式,第三种定义函数的方式就是使用Function构造函数。以下摘自《JavaScript高级程序设计》:

Function构造函数可以接受任意数量的参数,但最后一个参数始终都被看成是函数体,而前面的参数则枚举出了新函数的参数。 

我们不推荐读者使用这种方法定义函数,因为这种语法会导致解析两次代码(第一次是解析常规的ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。

我相信大家平常也很少使用这种方式,不过这种方式在模板引擎中(如EJS)应用很广泛。使用它确实能使字符串执行,只不过作用域是在函数里。但有一点要注意,就是它不会创建闭包,请看如下代码:
var color="red"
function test1(){
var color="blue";
eval("var f1=function(){console.log(color)}");
return f1;
}
test1()()
//output:blue

function test2(){
var color="blue";
var f2=new Function("console.log(color)");
return f2;
}
test2()()
//output:red       no closure!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16


3. 使用
setTimeout

setTimeout通常被用来执行异步代码,如可以用
setTimeout(function(){console.log(2)},1000)
来实现隔1s后输出2。不过你也可以在第一个参数中传入字符串,如下所示:
function print(num){
console.log(num);
}
setTimeout("print(2)",1000);
1
2
3
4

当传入的第一个参数为字符串时,感觉像是在使用eval方法处理似的,至于是不是,我也不知道。如果您知道,请不吝赐教。其实setTimeout很强大,我也收集过一篇讲述setTimeout的好文章,就是它了:你应该知道的setTimeout秘密


4. 巧用
<script>
标签

将要执行的代码放在动态生成的script标签內,并将标签注入文档中,同样可实现字符串的执行。如下所示:
var str="console.log(2222)"
var script=document.createElement('script');
script.text=str;
document.body.appendChild(script);
document.body.removeChild(script);
//output:2222
1
2
3
4
5
6

由于本人才疏学浅,暂时只知道这四种,如果您还有其他方法,欢迎指教。如您发现错误,请不吝指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐