Mr. Panda
Tech For Fun

前端面试题集锦(1)

HTML&CSS


1.请描述一下 cookie,sessionStorage 和 localStorage 的区别?

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。
cookie数据始终在同源的http请求中携带(即使不需要),也会在浏览器和服务器间来回传递。
sessionStorage 和 localStorage不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie 数据大小不能超过4k 。
sessionStorage 和 localStorage 虽然也有存储大小的限制,但比cookie大得多可以达到5M或更大
有效期时长:
localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
sessionStorage 数据在当前浏览器窗口关闭后自动删除
cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。


2.iframe有那些缺点?

 

缺点:

  • iframe会阻塞主页面的Onload事件
  • 搜索引擎的检索程序无法解读这种页面,不利于SEO;
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。(共享连接池且池中连接数有限制
  • 使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题。

优点:局部刷新 不用每次请求就刷新整个页面。(JS控制iframe刷新)

参考:浏览器多个标签页之间的通信;


3.如何实现浏览器内多个标签页之间的通信?

WebSocketSharedWorker
也可以调用localstorge、cookies本地存储方式
localstorge另一个浏览上下文里被添加、修改或删除时,它都会触发一个事件,我们通过监听事件,控制它的值来进行页面信息通信。
注意:Safari 在无痕模式下设置localstorge值时会抛出异常。(有些浏览器在无痕模式下不能使用localstorge)。

WebSocket: 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。


4.如何在页面上实现一个圆形的可点击区域?

(1)map+area或者svg
(2)border-radius
(3)纯js实现 需要求一个点在不在圆上简单算法、获取鼠标坐标等等

temp-or8

参考:如何在页面上实现一个圆形的可点击区域?


5.介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?

(1)有两种: IE 盒子模型W3C 盒子模型
(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border)。
(3)区 别: IE的content部分把 border 和 padding计算了进去


6.CSS优先级算法如何计算?

优先级就近原则,同权重情况下样式定义最近者为准;
载入样式以最后载入的定位为准;
优先级为:
!important > id > class > tag
important比内联优先级高(style)


7.为什么要使用CSS sprites(精灵)

CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background-position”的组合进行背景定位,这样可以减少很多图片请求的开销,因为请求耗时比较长;请求虽然可以并发,但是如果请求太多会给服务器增加很大的压力。(性能优化)


8.display:none 和 visibility:hidden的区别?

display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当他从来不存在 ,不占位。
visibility:hidden 隐藏对应的元素,但是在文档布局中仍保留原来的空间,占位。


9.position的absolute与fixed区别

absolute 浮动定位是相对于父级中设置position为relative或者absolute最近的父级元素(往上找不到父集的relation 就以html定位)。
fixed浮动定位是相对于浏览器视窗的。


10.IE 8以下版本的浏览器中的盒模型有什么不同?

IE8以下浏览器的盒模型中定义的元素的宽高包括内边距和边框

 

根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的,即width和height只包括content而不包括padding和border。IE5.X 和 6 在怪异模式(Quirks )中使用自己的非标准模型。这些浏览器的 width 属性不是内容的宽度,而是内容、内边距和边框的宽度的总和。 
css3中定义了box-sizing属性:

  • content-box
    这是由 CSS2.1 规定的宽度高度行为。
    宽度和高度分别应用到元素的内容框。
    在宽度和高度之外绘制元素的内边距和边框。
  • border-box 
    为元素设定的宽度和高度决定了元素的边框盒。
    就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。
    通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。

  • JavaScript

     

    1.JS数组去重

    以下是展示三种方法:

    Array.prototype.unique1 = function () {
    var n = []; //一个新的临时数组
    for (var i = 0; i < this.length; i++) //遍历当前数组
    {
    //如果当前数组的第i已经保存进了临时数组,那么跳过,
    //否则把当前项push到临时数组里面
    if (n.indexOf(this[i]) == -1) n.push(this[i]);
    }
    return n;
    }

     

    Array.prototype.unique2 = function()
    {
    var n = {},r=[]; //n为hash表,r为临时数组
    for(var i = 0; i < this.length; i++) //遍历当前数组
    {
    if (!n[this[i]]) //如果hash表中没有当前项
    {
    n[this[i]] = true; //存入hash表
    r.push(this[i]); //把当前数组的当前项push到临时数组里面
    }
    }
    return r;
    }

     

    Array.prototype.unique3 = function()
    {
    var n = [this[0]]; //结果数组
    for(var i = 1; i < this.length; i++) //从第二项开始遍历
    {
    //如果当前数组的第i项在当前数组中第一次出现的位置不是i,
    //那么表示第i项是重复的,忽略掉。否则存入结果数组
    if (this.indexOf(this[i]) == i) n.push(this[i]);


    2.js操作获取和设置cookie

     

    //创建cookie
    function setCookie(name, value, expires, path, domain, secure) {
    var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    if (expires instanceof Date) {
    cookieText += '; expires=' + expires;
    }
    if (path) {
    cookieText += '; path=' + path;
    }
    if (domain) {
    cookieText += '; domain=' + domain;
    }
    if (secure) {
    cookieText += '; secure';
    }
    document.cookie = cookieText;
    }

     

    //获取cookie
    function getCookie(name) {
    var cookieName = encodeURIComponent(name) + '=';
    var cookieStart = document.cookie.indexOf(cookieName);
    var cookieValue = null;
    if (cookieStart > -1) {
    var cookieEnd = document.cookie.indexOf(';', cookieStart);
    if (cookieEnd == -1) {
    cookieEnd = document.cookie.length;
    }
    cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
    }
    return cookieValue;
    }


    3.ajax 有那些优缺点?如何解决跨域问题?

    (Q1)
    优点:
    (1)通过异步模式,提升了用户体验.
    (2)优化了浏览器和服务器之间的传输,减少不必要的数据往返,减少了带宽占用.
    (3)Ajax在客户端运行,承担了一部分本来由服务器承担的工作,减少了大用户量下的服务器负载
    (4)Ajax可以实现动态不刷新(局部刷新
    缺点:
    (1)安全问题 AJAX暴露了与服务器交互的细节
    (2)对搜索引擎的支持比较弱,不利于SEO
    (3)不容易调试

    (Q2)jsonpiframewindow.namewindow.postMessage服务器上设置代理页面。

     


     

    4.JavaScript原型,原型链 ? 有什么特点?

    (1)原型对象也是普通的对象是对象一个自带隐式的 proto 属性原型也有可能有自己的原型如果一个原型对象的原型不为null的话,我们就称之为原型链。
    (2)原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链

    temp-or8


    5.GET和POST的区别,何时使用POST?

    GET:一般用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,一般在2000个字符;
    POST:一般用于修改服务器上的资源,对所发送的信息没有限制。
    GET方式需要使用Request.QueryString来取得变量的值,而POST方式通过Request.Form来获取变量的值,
    也就是说Get是通过地址栏来传值,而Post是通过提交表单来传值。

    然而,在以下情况中,请使用 POST 请求:
    无法使用缓存文件(更新服务器上的文件或数据库)
    向服务器发送大量数据(POST 没有数据量限制)
    发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠


    6.请解释一下 JavaScript 的同源策略

    概念:同源策略是客户端脚本(尤其是Javascript)的重要的安全度量标准。它最早出自Netscape Navigator2.0,其目的是防止某个文档或脚本从多个不同源装载。
    这里的同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。
    指一段脚本只能读取来自同一来源的窗口和文档的属性。
    为什么要有同源限制?
    我们举例说明:比如一个黑客程序,他利用Iframe把真正的银行登录页面嵌到他的页面上,当你使用真实的用户名,密码登录时,他的页面就可以通过Javascript读取到你的表单中input中的内容,这样用户名,密码就轻松到手了。


    7.Flash、Ajax各自的优缺点,在使用中如何取舍?

     

    Flash:

    1. Flash适合处理多媒体、矢量图形、访问机器

    2. 对CSS、处理文本上不足,不容易被搜索

    Ajax:

    1. Ajax对CSS、文本支持很好,支持搜索

    2. 多媒体、矢量图形、机器访问不足

    共同点:

    1. 与服务器的无刷新传递消息

    2. 可以检测用户离线和在线状态

    2. 操作DOM


    8.什么是闭包?

    闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:
    (1)作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
    (2) 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
    简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

    详见:彻底搞懂 JS 闭包各种坑;


    9.javascript里面的继承怎么实现,如何避免原型链上面的对象共享

    构造函数原型链的混合模式去实现继承,避免对象共享可以参考经典的extend()函数,很多前端框架都有封装的,就是用一个空函数当做中间变量。

     <script>
         var a = {name: "m"};
         var b = cloneObj(a);
         function cloneObj(obj) {
             var f = function () {};//空函数作为中间变量
             f.prototype = obj;//把对象挂载到函数原型上
             return new f();//返回函数的调用
         }
         console.log(b.name);
    </script>

    10.ajax过程

    (1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.
    (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
    (3)设置响应HTTP请求状态变化的函数.
    (4)发送HTTP请求.
    (5)获取异步调用返回的数据.
    (6)使用JavaScript和DOM实现局部刷新.

    code:

    function fn1() {
    
                  // 发送异步请求
    
                  //1. 创建 ajax 引擎对象 ---- 所有操作都是由 ajax 引擎完成
    
                  var xmlHttp = new XMLHttpRequest();
    
                  //2. 为引擎对象绑定监听事件
    
                  xmlHttp.onreadystatechange = function() {
    
                         // 当状态变化时处理的事情
    
                         if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
    
                                //5. 接收响应信息
    
                                var data = xmlHttp.responseText;
    
                                //6. 使用JavaScript和DOM实现局部刷新
    
                                document.getElementById("span1").innerHTML=data;
    
                         }
    
                  }
    
                  //3. 绑定服务器地址
    
                  // 第一个参数:请求方式 GET/POST
    
                  // 第二个参数:后台服务器地址
    
                  // 第三个参数:是否是异步 true-- 异步   false-- 同步
    
                  xmlHttp.open("GET", "${pageContext.request.contextPath}/ajaxServlet?username=zhangsan",
    
                                true);
    
            //4. 发送请求
    
                  xmlHttp.send();
    
           }

    11.jQuery四种事件绑定方式.bind(),.live(),.delegate(),on()的区别

     

    参考: http://blog.csdn.net/helloliuhai/article/details/19987509
    个人理解:
    事件委托指的就是目标自身不处理事件,委托给其父元素或祖先元素,甚至是根元素(document)

     

    .bind() 的优点和缺点
    优点:

    这个方法提供了一种在各种浏览器之间对事件处理的兼容性解决方案
    非常方便简单的绑定事件到元素上
    .click(), .hover()...这些非常方便的事件绑定,都是bind的一种简化处理方式
    对于利用ID选出来的元素是非常好的,不仅仅是很快的可以hook上去(因为一个页面只有一个id),而且当事件发生时,handler可以立即被执行(相对于后面的live, delegate)实现方式
    缺点:

    它会绑定事件到所有的选出来的元素上
    它不会绑定到在它执行完后动态添加的那些元素上
    当元素很多时,会出现效率问题
    当页面加载完的时候,你才可以进行bind(),所以可能产生效率问题

     

    .live() 的优点和缺点
    优点:

    这里仅有一次的事件绑定,绑定到document上而不像.bind()那样给所有的元素挨个绑定
    那些动态添加的元素依然可以触发那些早先绑定的事件,因为事件真正的绑定是在document上
    你可以在document ready之前就可以绑定那些需要的事件
    缺点:

    从1.7开始已经不被推荐了,所以你也要开始逐步淘汰它了。
    Chaining没有被正确的支持
    当使用event.stopPropagation()是没用的,因为都要到达document
    因为所有的selector/event都被绑定到document, 所以当我们使用matchSelector方法来选出那个事件被调用时,会非常慢
    当发生事件的元素在你的DOM树中很深的时候,会有performance问题

     

    .delegate() 的优点和缺点
    优点:

    你可以选择你把这个事件放到那个元素上了
    chaining被正确的支持了
    jQuery仍然需要迭代查找所有的selector/event data来决定那个子元素来匹配,但是因为你可以决定放在那个根元素上,所以可以有效的减小你所要查找的元素。
    可以用在动态添加的元素上
    缺点:

    需要查找那个那个元素上发生了那个事件了,尽管比document少很多了,不过,你还是得浪费时间来查找。
    注:.delegate() 比 .live() 好

     

    .On()的优点和缺点

    优点:

    提供了一种统一绑定事件的方法
    仍然提供了.delegate()的优点,当然如果需要你也可以直接用.bind()
    缺点:

    也许会对你产生一些困扰,因为它隐藏了一前面我们所介绍的三种方法的细节。
    结论:

    用.bind()的代价是非常大的,它会把相同的一个事件处理程序hook到所有匹配的DOM元素上
    不要再用.live()了,它已经不再被推荐了,而且还有许多问题
    .delegate()会提供很好的方法来提高效率,同时我们可以添加一事件处理方法到动态添加的元素上。
    我们可以用.on()来代替上述的3种方法


    12.如何理解闭包?

     

    1.闭包的概念
    各种专业文献上的“闭包”(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数
    由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
    所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

     

    2.闭包的用途
    闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。


    13.跨域请求资源的方法有哪些?

     

    1.单向跨域 jsonp:是 JSON with Padding(填充式 json)的简写,JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的 JSON 数据。

    JSONP 的原理:通过 script 标签引入一个 js 文件,这个 js 文件载入成功后会执行我们在 url 参数中指定的函数,并且会把我们需要的 json 数据作为参数传入。所以 jsonp 是需要服务器端的页面进行相应的配合的。

    JSONP 的优缺点:

    JSONP 的优点是:它不像XMLHttpRequest对象实现的 Ajax 请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。

    JSONP 的缺点则是:它只支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求;它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

     

    2.双向跨域 document.domain实现跨域:针对需要处理 Cookie 和 iframe,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置 document.domain 共享 Cookie 或者处理 iframe,只要设置相同的 document.domain,两个网页就可以共享 Cookie。这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法。

     

    3. 跨域资源共享(CORS):服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许 Ajax 进行跨域的访问。

    CORS 和 JSONP 对比:

    CORS 与 JSONP 相比,无疑更为先进、方便和可靠。

    (1)JSONP 只能实现 GET 请求,而 CORS 支持所有类型的 HTTP 请求;

    (2)使用 CORS,开发者可以使用普通的 XMLHttpRequest 发起请求和获得数据,比起 JSONP 有更好的错误处理

    (3)JSONP 主要被老的浏览器支持,它们往往不支持 CORS,而绝大多数现代浏览器都已经支持了 CORS;


    14.谈谈垃圾回收机制方式及内存管理

     

    1、原理

    js 按照固定的时间间隔找到不在继续使用的变量,释放其占用的内存。

    2. 实现方式

    (1)标记清除

    垃圾收集器给存储在内存上的所有变量都加上标记;

    之后,去掉环境中的变量以及被环境引用变量的标记;

    之后,被加上标记的变量就是准备删除的变量(原因是环境中的变量无法访问到这些变量了)。

    目前,IE、firefox、opera、chrome 和 Safari 浏览器都是标记清除的垃圾回收策略,只是回收时间间隔不一样。

    (2)引用计数

    原理:记录每个变量被引用的次数。释放引用计数为 0 的变量所占用的内存。

    IE9 将 BOM 和 DOM 对象转换成了真正的 js 对象。

    3、管理内存

    背景:分配给浏览器的可用内存通常会比桌面应用程序少。

    因此,如何使用最少的内存让页面获得最优的性能,就需要考虑管理内存。

    一个比较好的做法是:解除引用,即不再使用的变量设置为 null。


     

    15.开发过程中遇到的内存泄露情况,如何解决的?

    内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。

    全局变量导致内存泄露问题:

    function foo(){
      name = '前端曰';
    }
    // 其实是把name变量挂载在window对象上
    function foo(){
      window.name = '前端曰';
    }
    
    // 又或者
    function foo(){
      this.name = '前端曰';
    }
    foo() // 其实这里的this就是指向的window对象

    这样无意中一个意外的全局变量就被创建了,为了阻止这种错误发生,在你的 Javascript 文件最前面添加 'use strict;' 。这开启了解析 JavaScript 的阻止意外全局的更严格的模式。或者自己注意好变量的定义!

     

    循环引用导致内存泄露问题

    function func() {
        let obj1 = {};
        let obj2 = {};
    
        obj1.a = obj2; // obj1 引用 obj2  
        obj2.a = obj1; // obj2 引用 obj1  
    }

    当函数 func 执行结束后,返回值为 undefined,所以整个函数以及内部的变量都应该被回收,但根据引用计数方法,obj1 和 obj2 的引用次数都不为 0,所以他们不会被回收。要解决循环引用的问题,最好是在不使用它们的时候手工将它们设为空。

    解决方案:obj1obj2 都设为 null

     

    闭包导致内存泄露问题

    function  showId() {
        var el = document.getElementById("app")
        el.onclick = function(){
          aler(el.id)   // 这样会导致闭包引用外层的el,当执行完showId后,el无法释放
        }
    }
    
    // 改成下面
    function  showId() {
        var el = document.getElementById("app")
        var id  = el.id
        el.onclick = function(){
          aler(id)   // 这样会导致闭包引用外层的el,当执行完showId后,el无法释放
        }
        el = null    // 主动释放el
    }
     

     


     

    其他

     

    1.一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?

     

    简洁版:
    (1)查找浏览器缓存
    (2)DNS解析、查找该域名对应的IP地址、重定向(301)、发出第二个GET请求
    (3)进行HTTP协议会话
    (4)客户端发送报头(请求报头)
    (5)服务器回馈报头(响应报头)
    (6)html文档开始下载
    (7)文档树建立,根据标记请求所需指定MIME类型的文件
    (8)文件显示

     

    详细版:

        1、浏览器会开启一个线程来处理这个请求,对 URL 分析判断如果是 http 协议就按照 Web 方式来处理;

        2、调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法;

        3、通过 DNS 解析获取网址的 IP 地址,设置 UA 等信息发出第二个 GET 请求;

        4、进行 HTTP 协议会话,客户端发送报头 (请求报头);

        5、进入到 web 服务器上的 WebServer,如 Apache、Tomcat、Node.js 等服务器;

        6、进入部署好的后端应用,如 PHPJavaJavaScriptPython 等,找到对应的请求处理;

        7、处理结束回馈报头,此处如果浏览器访问过,缓存上有对应资源,会与服务器最后修改时间对比,一致则返回 304;

        8、浏览器开始下载 html 文档 (响应报头,状态码 200),同时使用缓存;

        9、文档树建立,根据标记请求所需指定 MIME 类型的文件(比如 css、js), 同时设置了 cookie;

        10、页面开始渲染 DOM,JS 根据 DOM API 操作 DOM, 执行事件绑定等,页面显示完成。

     

      其它:

        1:当发送一个 URL 请求时,不管这个 URL 是 Web 页面的 URL 还是 Web 页面上每个资源的 URL,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器获得请求对应的 IP 地址。

        2: 浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步 - 应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。

        3:一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。

        4:此时,Web 服务器提供资源服务,客户端开始下载资源。请求返回后,便进入了我们关注的前端模块。简单来说,浏览器会解析 HTML 生成 DOM Tree,其次会根据 CSS 生成 CSSRule Tree,而 javascript 又可以根据 DOMAPI 操作 DOM。


    2.为什么换工作?

    3.你常用的开发工具是什么,为什么?

    Vscode:开源精神、功能强大、丰富插件、语法提示、前端开发利器。

    4.对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?

    创造力、需求、全栈、领域广、发展快、前景好。

    5.加班的看法?

    趁年轻多努力、先苦后甜、早日经济独立。

jonsam ng

jonsam ng

文章作者

海阔凭鱼跃,天高任鸟飞。

前端面试题集锦(1)
HTML&CSS 1.请描述一下 cookie,sessionStorage 和 localStorage 的区别? cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。 c…
扫描二维码继续阅读
2019-10-10