面试题总结(一)
laizimo opened this issue · 4 comments
前言
2017年的秋招,截至今天已经有了三场面试,接下来的篇幅,主要会对面试题做一下总结,为自己接下来的面试打一下基础,积累一些运气。
正文
阿里一面
这是本次秋招的第一次内推面试,面试官挺温和的。面试总时长在45分钟左右,前面大约5分钟做了一些自我介绍,下面进入正题。
1. js的事件,事件流,以及事件委托的理解
原生的js可以通过addEventListener的函数来为元素增加监听事件,在IE上会使用attachEvent来增加元素的监听事件,当然,还有最原始的写法通过onClick类似的方式来为元素增加监听事件。
js中的事件流可以分为两种事件冒泡和事件捕获。两种最主要的区别是,事件冒泡是从最具体的元素开始向外层传递事件,而事件捕获是从外层开始,像里层元素传递事件。现在主要使用的是事件冒泡的事件流机制。
事件委托,就是一个元素将监听事件的请求委托给其他的元素,使用的是事件冒泡的机制。最常见的就是子元素将监听事件挂在到父元素上,然后当点击子元素的时候,由于事件冒泡,最终会在父元素上触发监听函数,然后执行子元素的回调函数。这样做的好处,就是可以避免在每个子元素上都去挂载监听事件。坏处是有些事件没有冒泡机制,如focus、blur,就无法使用事件委托的方式,还有像一些事件mousemove、mouseout只能通过位置去计算定位,性能消耗太大,不适宜使用事件委托。
2. jquery的链式写法的原理
其实对于链式的这种写法,最终返回的都是自身的对象,即return this;举另一个例子Rxjs,它的使用也是链式的写法,而它的实现方式,也是每次操作一种函数操作完之后,就返回一个Observable对象。或许,这个例子举的不是特别形象,因为一个是函数式的编程,而另一个并不是。但是,其实某些原理性的东西还是相似的。
3. 对于跨域的理解(面试必问)
主要是将如何造成的,以及如何解决。其实跨域这个问题,我们平时做项目的时候也会遇到,造成的原因就是浏览器的同源策略。同源策略规定不同域下面的脚本资源,在未经授权的前提下,不能对其他域的资源进行修改。所谓的同源,指的是协议、域名、端口相同的。
使用最频繁的两种方式是jsonp和CORS。首先,来理解一下第一种jsonp。jsonp的原理就是通过script标签的src接受后端发送的资源,然后通过对约定好的回调函数的调用将资源导入进来。这个方法的优点就是使用起来方便快捷,而且简单,但是缺点也比较明显,只能对GET请求起作用。之后是CORS的原理。CORS,即在http响应头中添加一个属性Access-Control-Allow-Origin,并且在它的后面加上运行访问的ip以及端口,或者使用*表示都允许。
4. web存储
最初,web存储的方式就是cookie。通常,开发者会在其中存储一些用户的信息数据,存储的大小是在4kb以下,4kb以上的cookie会被浏览器自动丢弃。cookie在使用过程中,往往有很多的缺点:1. 存储大小有限 2. 客户端不同域下cookie的数量也是有限的 3. 每次存储的数据都会向服务端发送,而往往存储的数据并不需要如此 4. cookie本身的不安全性,很容易导致信息的泄漏和盗取。
html5提出了新的数据存储的方式localstorage和sessionstorage。localstorage和sessionstorage本身都是客户端的存储。可存储大小在50M左右。localstorage的存储是持久型的,除非手动对数据进行清除,否则,数据将会被一直保留。sessionstorage的存储会在浏览器关闭的时候,被清除掉。
5. 继承
6. 闭包
闭包是js内部函数对外部函数作用域的引用。而在外部作用域使用函数作用域的变量是闭包的一种实现。闭包的用法,往往在模块的使用中较为突出。通常,封装好的模块,都会将一部分内部变量通过闭包的形式,导出到外部,给外部的函数使用。
7. ES6的特性
在ES6方面,主要问了一下generator的使用。generator,即生成器,通常会用来写迭代器,以及异步转化成同步写法时的使用。迭代器的原理,往往也就是给Symbol.iterator的属性值,赋值一个generator的生成器,然后使用next()进行一步一步的迭代。而异步方面,generator往往可以配合回调函数,将值赋给当前步骤的变量,方便在下一步骤中调用。通常也会和promise进行结合,来完成一系列的异步操作。
apply、call和bind的区别
问了一下,这么三个函数的作用是什么?这么三个函数的作用就是调整上下文,即this的指向。在js中,this的指向是琢磨不定的,往往有四条规律可以总结它,
- 在全局空间中调用函数,this往往会指向window,而在严格模式下,会指向undefined。
- 在对象的方法中调用this,往往会指向该对象,但是这种方式很容易造成this的隐性丢失
- 显示调用,即使用apply、call、bind等对this进行显式指向,this会指向指定的元素。
- new构造函数时的this,会指向新生成的实例。
在讲讲它们之间的区别:
apply和call的区别是,apply只接受两个参数,一个是this的指向参数,另一个则是数组类型的参数;而call后面可以接受多个参数。
bind和前两者的区别就是bind绑定完之后,函数并不直接运行,并且bind的绑定是硬绑定,无法被修改;而前两者绑定完之后,直接调用函数。
css盒子模型
这个感觉是前端面试基础面必问的题目。盒子模型,即在DOM元素中,元素呈现矩形的盒子。盒子模型主要可分为四部分:content、padding、border和margin。盒子模型也主要分为两类,一类是W3C标准的盒子模型,另一类是早期的IE浏览器下的盒子模型。主要的区别是:W3C标准的盒子模型的width长度是等于内容的长度,并不包含padding和border部分。而IE下的盒子模型包含了content+padding+border的部分。
渐进增强和优雅降级
首先,何为渐进增强,何为优雅降级。这两种方式是实现浏览器界面时的一种选择,对于不同的浏览器版本而言,如果同样的代码,呈现的效果是不同的,因此需要这两种方式进行填补。渐进增强,指的是现在低版本浏览器上面实现基础的功能,然后在给高版本浏览器添加更好的功能。而优雅降级则是将实现思路相反了一下,先在高版本浏览器上面实现响应的功能,然后通过一些补充的方式,在低版本浏览器中将界面尽量的实现完全。
清除浮动的方式
其实,清除浮动的方式有三种。首先,谈的是最实用的一种方式,就是after的伪类,在父元素块上添加after伪类,然后将after伪类中的content设置为空,之后是display设置为block,clear设置为both。
.clearfix:after{
content: '';
display: block;
clear: both;
}
.clearfix{
zoom:1;
}
这是第一种方式,也是最简单的方法。第二种,就是在父元素后面添加一个clearfix的块,进行浮动的清除.
<div class="parent">
<div class="child"></div>
</div>
<div class="clearfix"></div>
<div class="parent1"></div>
.parent{
width: 100%;
position: relative;
border: 1px solid black;
}
.clearfix{
clear: both;
display: block;
}
.parent .child{
float: left;
width: 100px;
height: 100px;
background: red;
}
.parent1{
width: 200px;
height: 200px;
background: yellow;
}
这种方式并不好,而且会导致标签混乱,让人无法理解。还有一种方法就是,在父元素中将overflow设置为hidden,这种情况往往会将一些溢出的部分隐藏,而达不到预期的效果。
总结
阿里的一面覆盖面比较广,当然也问了一些http协议和缓存的问题,我会将我在面试中有疑问的地方,单独拿出来详细的分析,顺便帮助自己巩固。有http缓存优化,flex布局及其兼容性,js引擎和js模块等。
博主拿到offer了么
博主拿到offer了么
这么优秀,会愁Offer吗?
好奇博主现在在哪工作。
博主能不能举几个闭包的应用场景。