前端菜鸡在进阶

斜体内容我是一名在读研究生,但是码代码能力较弱,除了完成作业从不主动敲代码。在三四月份两个月,疯狂投简历面试,面试岗位为web前端,五月份成功入职。

在找实习的这段时间,投过很多公司,包括BAT、今日头条、美团等,走过坑、趟过水,每个公司的每次面试我都总结了一些面经。现在先说一下
【笔试】
分为内推和网申,有渠道的同学可以进行内推,免笔试,直接面试,但是今日头条的面试是视频面试(目前面试前端,只遇到过头条是视频面试)
我走的内推,大家需要的话,这是牛客网的链接,今日头条2017前端工程师实习生笔试题
https://www.nowcoder.com/test/1649297/summary

【面试】
在校学生基本采取的是电面或者视频面。
一面:视频面试了一个多小时,头条很注重计算机的基础知识:数据结构、计算机网络、数据库、计算机组成原理。然后开始是专业知识:(视频面试一般都是敲代码的)下面是一些问题,我把找的答案也附在里面了,有点多,会有彩蛋的~
一、js的继承
JS继承的实现方式
既然要实现继承,那么首先我们得有一个父类,代码如下:
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
1、原型链继承
核心: 将父类的实例作为子类的原型
特点:
1.非常纯粹的继承关系,实例是子类的实例,也是父类的实例
2.父类新增原型方法/原型属性,子类都能访问到
3.简单,易于实现
缺点:
1.要想为子类新增属性和方法,必须要在new Animal()这样的语句之后执行,不能放到构造器中
2.无法实现多继承
3.来自原型对象的引用属性是所有实例共享的(详细请看附录代码: 示例1)
4.创建子类实例时,无法向父类构造函数传参
推荐指数:★★(3、4两大致命缺陷)
(prototype属性的引入:这个属性包含一个对象(以下简称"prototype对象"),所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面。)
2、构造继承
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
特点:
1.解决了1中,子类实例共享父类引用属性的问题
2.创建子类实例时,可以向父类传递参数
3.可以实现多继承(call多个父类对象)
缺点:
1.实例并不是父类的实例,只是子类的实例
2.只能继承父类的实例属性和方法,不能继承原型属性/方法
3.无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
推荐指数:★★(缺点3)
3、实例继承
核心:为父类实例添加新特性,作为子类实例返回
function Cat(name){
var instance = new Animal();
instance.name = name || 'Tom';
return instance;
}
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false
特点:
1.不限制调用方式,不管是new 子类()还是子类(),返回的对象具有相同的效果
缺点:
1.实例是父类的实例,不是子类的实例
2.不支持多继承
推荐指数:★★
4、拷贝继承
特点:
1.支持多继承
缺点:
1.效率较低,内存占用高(因为要拷贝父类的属性)
2.无法获取父类不可枚举的方法(不可枚举方法,不能使用for in 访问到)
推荐指数:★(缺点1)
5、组合继承
核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
特点:
1.弥补了方式2的缺陷,可以继承实例属性/方法,也可以继承原型属性/方法
2.既是子类的实例,也是父类的实例
3.不存在引用属性共享问题
4.可传参
5.函数可复用
缺点:
1.调用了两次父类构造函数,生成了两份实例(子类实例将子类原型上的那份屏蔽了)
推荐指数:★★★★(仅仅多消耗了一点内存)
6、寄生组合继承
核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
特点:
1.堪称完美
缺点:
1.实现较为复杂
推荐指数:★★★★(实现复杂,扣掉一颗星)
附录代码:
示例一:
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
//实例引用属性
this.features = [];
}
function Cat(name){
}
Cat.prototype = new Animal();
var tom = new Cat('Tom');
var kissy = new Cat('Kissy');
console.log(tom.name); // "Animal"
console.log(kissy.name); // "Animal"
console.log(tom.features); // []
console.log(kissy.features); // []
tom.name = 'Tom-New Name';
tom.features.push('eat');
//针对父类实例值类型成员的更改,不影响
console.log(tom.name); // "Tom-New Name"
console.log(kissy.name); // "Animal"
//针对父类实例引用类型成员的更改,会通过影响其他子类实例
console.log(tom.features); // ['eat']
console.log(kissy.features); // ['eat']
原因分析:
关键点:属性查找过程
执行tom.features.push,首先找tom对象的实例属性(找不到),
那么去原型对象中找,也就是Animal的实例。发现有,那么就直接在这个对象的
features属性中插入值。
在console.log(kissy.features); 的时候。同上,kissy实例上没有,那么去原型上找。
刚好原型上有,就直接返回,但是注意,这个原型对象中features属性值已经变化了。
二、原型链
css水平垂直居中
方案一:
div绝对定位水平垂直居中【margin:auto实现绝对定位元素的居中】,
兼容性:,IE7及之前版本不支持
div{
width: 200px;
height: 200px;
background: green;
position:absolute;
left:0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
}
方案二:
div绝对定位水平垂直居中【margin 负间距】 这或许是当前最流行的使用方法。
div{
width:200px;
height: 200px;
background:green;
position: absolute;
left:50%;
top:50%;
margin-left:-100px;
margin-top:-100px;
}
方案三:
div绝对定位水平垂直居中【Transforms 变形】
兼容性:IE8不支持;
div{
width: 200px;
height: 200px;
background: green;
position:absolute;
left:50%; / *定位父级的50%* /
top:50%;
transform: translate(-50%,-50%); /*自己的50%* /(translate(x,y) 水平方向和垂直方向同时移动)
}
方案四:(不说)
css不定宽高水平垂直居中
.box{
height:600px;
display:flex;
justify-content:center;
align-items:center;
/ *aa只要三句话就可以实现不定宽高水平垂直居中。* /
}
.box>div{
background: green;
width: 200px;
height: 200px;
}
方案五:
将父盒子设置为table-cell元素,可以使用text-align:center和vertical-align:middle实现水平、垂直居中。比较完美的解决方案是利用三层结构模拟父子结构
tableCell
/*table-cell实现居中
将父盒子设置为table-cell元素,设置
text-align:center,vertical-align: middle;
子盒子设置为inline-block元素* /
.tableCell{
display: table;
}
.tableCell .ok{
display: table-cell;
text-align: center;
vertical-align: middle;
}
.tableCell .innerBox{
display: inline-block;
}
方案六:
对子盒子实现绝对定位,利用calc计算位置
calc
/*绝对定位,calc计算位置*/
.calc{
position: relative;
}
.calc .innerBox{
position: absolute;
left:-webkit-calc((500px - 200px)/2);
top:-webkit-calc((120px - 50px)/2);
left:-moz-calc((500px - 200px)/2);
top:-moz-calc((120px - 50px)/2);
left:calc((500px - 200px)/2);
top:calc((120px - 50px)/2);
}
(对于calc(),总结以下要点:
1.兼容性:在IE9+、FF4.0+、Chrome19+、Safari6+支持较好,移动端支持不理想;
2.表达式支持加、减、乘、除运算,同时也支持单位的混合使用(%、px、em等);
2.表达式中有“+”,“-”运算符的,前后必须要有空格)
Html5新特性,CSS3新特性
HTML5新特性
HTML5 中的一些有趣的新特性:
用于绘画的 canvas 元素
用于媒介回放的 video 和 audio 元素
对本地离线存储的更好的支持
新的特殊内容元素,比如 article、footer、header、nav、section
新的表单控件,比如 calendar、date、time、email、url、search
三、CSS3新特性
1\.  CSS3实现圆角(border-radius),阴影(box-shadow),
2\.  对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform)
3\.  transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);// 旋转,缩放,定位,倾斜
4\.  增加了更多的CSS选择器 多背景 rgba
5\.  在CSS3中唯一引入的伪元素是 ::selection.
6\.  媒体查询,多栏布局
7\.  border-image
    [https://blog.csdn.net/chandoudeyuyi/article/details/69206236](https://blog.csdn.net/chandoudeyuyi/article/details/69206236)
    Ajax实现原理
    [https://www.cnblogs.com/jackson0714/p/AJAX.html](https://www.cnblogs.com/jackson0714/p/AJAX.html)
    [https://blog.csdn.net/fuxiaohui/article/details/72725500](https://blog.csdn.net/fuxiaohui/article/details/72725500)
8\.  创建XMLHttpRequest对象,也就是创建一个异步调用对象XHR
9\.  创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
10\.  设置响应HTTP请求状态变化的函数
11\.  发送HTTP请求
12\.  获取异步调用返回的数据
13\.  使用JavaScript和DOM实现局部刷新
四、闭包
1.闭包是什么?
    闭包是指有权访问另一个函数作用域中的变量的函数。
    特性:
        (1).函数嵌套函数
        (2).函数内部可以引用外部的参数和变量
        (3).参数和变量不会被垃圾回收机制回收
2.如何创建?
在一个函数内部创建另一个函数。
【注意】:通常,函数的作用域及其所有变量都会在函数执行结束后被销毁
但是当函数返回到一个闭包时,这个函数的作用域将会一直在内存中存在到闭包不存在为止;
内部函数执行完成后,其活动对象不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。
    即:当内部函数被返回后,其执行环境作用链会被销毁,但它的活动对象仍然会留在内存中,直到匿名函数被销毁后,内层函数的活动对象才会被销毁。
6 //创建函数
    var comparNames = createComparisonFunction("name");
    //调用函数
    var result = comparNames((name:"mimi"),(name:"haha"));
    //解除对匿名函数的引用(以便释放内存)
    compareNames = null;
3.闭包与变量
闭包只能取得包含函数中任何变量的最后一个值。
    function createFunctions(){
    var result = new Array();
    for(var i=0; i<10;i++){
    result[i] == function(){
    return i ;
    }
    }
    return result;
    }
    ( 结果返回10 )
解决办法:创建另一个匿名函数强制让闭包的行为达到预期。
function createFunctions(){
var result = new Array();
for(i=0;i<10;i++){
result[i]=function(num){
return function(){
return num;
};
}(i);
}
return result;
}
( 结果返回0~9 )
4.关于this对象
(1):全局函数中:this等于window;
(2):匿名函数的执行环境具有全局性,因此其this对象通常指向window.
var name = "The Window"; // 创建全局name
var object = { //创建包含name属性的对象
name:"My name";
getNameFunc:function(){ //包含一个方法 getNameFunc()
return function(){ //返回一个匿名函数
return this.name; //匿名函数返回this.name
}
}
};
alert(objext.getNameFunc(){});
( 返回外部环境中的name ----The Window)
原因: 内部函数在搜索this和arguments时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数的这两个变量;
解决方法:把外部作用域的this对象保存在一个闭包能够访问到的变量里。
var name = "The Window";
var object = {
name:"My name";
getNameFunc:function(){
var that = this;
return function(){
return that.name;
}
}
};
alert(objext.getNameFunc(){});
( 返回匿名函数中的name ----My name)
说明: 定义匿名函数前,我们把this 对象赋值给that变量,在定义了闭包之后,闭包也可以访问之歌变量,因为它是我们在包含函数中特意声明的一个变量,及时函数返回,that仍然引用object,所以返回了“ My name”
测试下自己是否真正了解闭包:
var foo = ( function() {
var secret = 'secret';
// “闭包”内的函数可以访问 secret 变量,而 secret 变量对于外部却是隐藏的
return {
get_secret: function () {
// 通过定义的接口来访问 secret
return secret;
},
new_secret: function ( new_secret ) {
// 通过定义的接口来修改 secret
secret = new_secret;
}
};
} () );
foo.get_secret (); //得到?
foo.secret; //得到?
foo.new_secret ('a new secret');
foo.get_secret (); //得到?
答案:
foo.get_secret (); // 得到 'secret'
foo.secret; // Type error,访问失败
foo.new_secret ('a new secret'); // 通过函数接口,我们访问并修改了 secret 变量
foo.get_secret (); // 得到 'a new secret'
五、跨域
[https://www.cnblogs.com/roam/p/7520433.html](https://www.cnblogs.com/roam/p/7520433.html)
六、浮动,清除浮动
七、Es6(廖雪峰网站),会一个框架,打包(gulp,webpack)
八、css预处理
1、什么是CSS预处理器
CSS预处理器定义了一种新的语言,基本的思想是用一种专门的编程语言,开发者只需要使用这种语言进行编码工作,减少枯燥无味的CSS代码的编写过程的同时,它能让你的CSS具备更加简洁、适应性更强、可读性更加、层级关系更加明显、更易于代码的维护等诸多好处。
CSS预处理器种类繁多,本次就以Sass、Less、Stylus进行比较。
2、语法
在使用CSS预处理器之前最重要的是了解语法,我只写过stylus,就从网上找了下另外两种语法的格式,与大家对比分享。
首先Sass和Less都是用的是标准的CSS语法,因此你可以很方便的把已完成的CSS代码转为预处理器识别的代码,Sass默认使用 .sass扩展名,而Less默认使用.Less扩展名。
3、变量
你可以在CSS预处理中声明变量,并在整个样式单中使用,支持任何类型的变量,例如:颜色、数值(是否包含单位)、文本。然后你可以任意的调取和使用该变量。Sass的变量是必须$开始,然后变量名和值要冒号隔开,跟CSS属性书写格式一致。
Stylus对变量名没有任何限定,你可以是$开始,也可以是任意字符,而且与变量值之间可以用冒号、空格隔开,需要注意的是 Stylus (0.22.4) 将会编译 @ 开始的变量,但其对应的值并不会赋予该变量,换句话说,在 Stylus 的变量名不要用 @ 开头。
mainColor = #0982c1
siteWidth = 1024px
$borderStyle = dotted
body
color mainColor
border 1px $borderStyle mainColor
max-width siteWidth
上面三种不同的CSS写法,最终将会生成相同结果:
body {
color: #0982c1;
border: 1px dotted #0982c1;
max-width: 1024px;
}
最容易体现它的好处的是,假设你在CSS中使用同一种颜色数十次,如果你要修改显色,需要找到并修改十次相同的代码,而有了CSS预处理器,修改一个地方就够了。
4、嵌套
如果你需要在CSS中相同的parent引用多个元素,你需要一遍一遍的去写parent。例如:
section {
margin: 10px;
}
section nav {
height: 25px;
}
section nav a {
color: #0982C1;
}
section nav a:hover {
text-decoration: underline;
}
然而如果用CSS预处理器,就可以少些很多单词,而且父节点关系一目了然。
section {
margin: 10px;
nav {
height: 25px;
a {
color: #0982C1;
&amp;:hover {
    text-decoration: underline;
  }
}
}
}
stylus还可省略花括号,书写更加方便,根据个人喜好还可删除中间冒号。
section
margin: 10px;
nav
height: 25px;
a
color: #0982C1;
&:hover
text-decoration: underline;
最终生成CSS结果是:
section {
margin: 10px;
}
section nav {
height: 25px;
}
section nav a {
color: #0982C1;
}
section nav a:hover {
text-decoration: underline;
}
九、双栏布局
/*方法一: BFC(块级格式化上下文)*/
.container{
width:1000px;height:400px;border: 1px solid red;
}
.left{
width:200px;height:100%;background: gray;
float: left;
}
.rigth{
overflow:hidden; / *触发bfc* /
background: green;
}
/*方法二: flex布局* /
.container{
width:1000px;height:400px;border:1px solid red;
display:flex; /*flex布局*/
}
.left{
width:200px; height:100%;background:gray;
flex:none;
}
.right{
height:100%;background:green;
flex:1; /*flex布局*/
}
/ *方法三: table布局* /
.container{
width:1000px;height:400px;border:1px solid red;
display:table; /*table布局*/
}
.left{
width:200px; height:100%;background:gray;
display:table-cell;
}
.right{
height:100%;background:green;
display: table-cell;
}
/*方法四: css计算宽度calc*/
.container{
width:1000px;height:400px;border:1px solid red;
}
.left{
width:200px;height:100%;background:gray;
float:left;
}
.right{
height:100%;background:green;
float:right;
width:calc(100% - 200px);
}
十、HTTP强缓存和协商缓存
强缓存
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。·
Expires
该字段是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串,比如Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
Cache-Control
Cache-Control是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对时间,例如Cache-Control:max-age=3600,代表着资源的有效期是3600秒。***-control除了该字段外,还有下面几个比较常用的设置值:
no-***:不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
public:可以被所有的用户缓存,包括终端用户和CDN等中间***服务器。
private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。
Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高。
协商缓存
协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。
十一、线性结构和非线性结构
线性结构是什么呢?有什么特点呢?
线性结构有唯一的首元素(第一个元素)
线性结构有唯一的尾元素(最后一个元素)
除首元素外,所有的元素都有唯一的“前驱”
除尾元素外,所有的元素都有唯一的“后继”
数据元素之间存在“一对一”的关系
例如:数组A1,A2,A3,........An,首元素就是A1,尾元素就是An
什么结构属于线性结构呢?
顺序表(一维数组),堆,栈,队列,链表
那非线性结构是什么呢?
数据元素之间是一对多,或者是多对一的关系
非线性结构有什么呢?
图(群结构),树(层次结构),***数组
十二、网络层的七层协议:
tips:如果不是自己比较熟悉领域的问题不要强行扯那么多,说不知道并且虚心向面试官求教也可以(我的面试官一般人都挺好,还带讲解的)。
二面:简历内容必须十分熟悉,简历里的项目要做好准备,面试官会问细节,一般也会让你挑一个有挑战的项目,遇到的问题以及如何解决的。
tips:
准备好简历,一份好的简历还是挺重要的

彩蛋就是:
tips:
1.如果电面,可以进行录音,记录一下面试过程
2.面完马上总结,记不清的听录音
3.在牛客网之类的应用上刷题和问问题,一般都会有人解答,也会有一些内推渠道
祝顺利!

#内推##实习##面经##字节跳动##前端工程师#
全部评论
校友好,好巧哦,我也是前端
点赞 回复 分享
发布于 2018-05-26 20:42
研究生也抢本科生的饭碗,这种码农的事交给我们本科生就好了,你们去研究机器学习深度学习吧
点赞 回复 分享
发布于 2018-05-26 22:16
校友好,你也是北京的头条吗
点赞 回复 分享
发布于 2018-05-27 06:18
大佬最后入职哪里呀
点赞 回复 分享
发布于 2018-05-27 22:22

相关推荐

牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
jack_miller:我给我们导员说我不在这里转正,可能没三方签了。导员说没事学校催的时候帮我想办法应付一下
点赞 评论 收藏
分享
评论
5
121
分享
牛客网
牛客企业服务