zoukankan      html  css  js  c++  java
  • 百度前端面试总结

    1. 跨域问题:

    5大方法:

    (1)     CORS(cross origin resources sharing跨域资源共享):ajax请求采用绝对路径,在服务器端设置Access-Control-Allow-Origin来进行。

    (2)     JSONP: 主要采用的是js的引入可以跨域共享,通过callback来载入其他域的资源,形式是:callback({数据名:数据值}),但是需要后台支持,并且只支持get方式,但基本没有兼容问题,老浏览器也很支持

    (3)     window.domain:通过在两个页面中设置相同的window.domain,但是window.domain只能设置成自身或者更高一级的父域,所以只能解决的是不同子域的问题,也就是主域一定要相同。

    (4)     window.name: 在一个窗口(window)的生命周期中,窗口载入的所有的页面都是共享一个window.name。(不是很理解跟跨域有什么关系)

    (5)     window.postMessage(message,targetOrigin)(HTML5的方法:IE8+,FireFox.Chrome,Opera等):可以用这个向其他的window对象发送消息,无论这个window对象是否属于同源或不同源。

    答:什么是跨域?

    概念:只要协议、域名、端口有任何一个不同,都被当作是不同的域。

    URL                      说明       是否允许通信

    http://www.a.com/a.js

    http://www.a.com/b.js     同一域名下   允许

    http://www.a.com/lab/a.js

    http://www.a.com/script/b.js 同一域名下不同文件夹 允许

    http://www.a.com:8000/a.js

    http://www.a.com/b.js     同一域名,不同端口  不允许

    http://www.a.com/a.js

    https://www.a.com/b.js 同一域名,不同协议 不允许

    http://www.a.com/a.js

    http://70.32.92.74/b.js 域名和域名对应ip 不允许

    http://www.a.com/a.js

    http://script.a.com/b.js 主域相同,子域不同 不允许

    http://www.a.com/a.js

    http://a.com/b.js 同一域名,不同二级域名(同上) 不允许(cookie这种情况下也不允许访问)

    http://www.cnblogs.com/a.js

    http://www.a.com/b.js 不同域名 不允许

    对于端口和协议的不同,只能通过后台来解决。

    跨域资源共享(CORS

    CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。

    <script type="text/javascript">

        var xhr = new XMLHttpRequest();

        xhr.open("GET", "/trigkit4",true);

        xhr.send();

    </script>

    以上的trigkit4是相对路径,如果我们要使用CORS,相关Ajax代码可能如下所示:

    <script type="text/javascript">

        var xhr = new XMLHttpRequest();

        xhr.open("GET", "http://segmentfault.com/u/trigkit4/",true);

        xhr.send();

    </script>

    代码与之前的区别就在于相对路径换成了其他域的绝对路径,也就是你要跨域访问的接口地址。

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


    要解决跨域的问题,我们可以使用以下几种方法:

    通过jsonp跨域

    现在问题来了?什么是jsonp?维基百科的定义是:JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。

    JSONP也叫填充式JSON,是应用JSON的一种新方法,只不过是被包含在函数调用中的JSON,例如:

    callback({"name","trigkit4"});

    JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的JSON数据。

    在js中,我们直接用XMLHttpRequest请求不同域上的数据时,是不可以的。但是,在页面上引入不同域上的js脚本文件却是可以的,jsonp正是利用这个特性来实现的。 例如:

    <script type="text/javascript">

        function dosomething(jsondata){

            //处理获得的json数据

        }

    </script>

    <script src="http://example.com/data.php?callback=dosomething"></script>

    js文件载入成功后会执行我们在url参数中指定的函数,并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。

    <?php

    $callback = $_GET['callback'];//得到回调函数名

    $data = array('a','b','c');//要返回的数据

    echo $callback.'('.json_encode($data).')';//输出

    ?>

    最终,输出结果为:dosomething(['a','b','c']);

    如果你的页面使用jquery,那么通过它封装的方法就能很方便的来进行jsonp操作了。

    <script type="text/javascript">

        $.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){

            //处理获得的json数据

        });

    </script>

    jquery会自动生成一个全局函数来替换callback=?中的问号,之后获取到数据后又会自动销毁,实际上就是起一个临时代理函数的作用。$.getJSON方法会自动判断是否跨域,不跨域的话,就调用普通的ajax方法;跨域的话,则会以异步加载js文件的形式来调用jsonp的回调函数。

    JSONP的优缺点

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

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

    CORSJSONP对比

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

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

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

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

    通过修改document.domain来跨子域

    浏览器都有一个同源策略,其限制之一就是第一种方法中我们说的不能通过ajax的方法去请求不同源中的文档。 它的第二个限制是浏览器中不同域的框架之间是不能进行js的交互操作的。
    不同的框架之间是可以获取window对象的,但却无法获取相应的属性和方法。比如,有一个页面,它的地址是http://www.example.com/a.html , 在这个页面里面有一个iframe,它的src是http://example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获取iframe中的东西的:

    <script type="text/javascript">

        function test(){

            var iframe = document.getElementById('ifame');

            var win = document.contentWindow;//可以获取到iframe里的window对象,但该window对象的属性和方法几乎是不可用的

            var doc = win.document;//这里获取不到iframe里的document对象

            var name = win.name;//这里同样获取不到window对象的name属性

        }

    </script>

    <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

    这个时候,document.domain就可以派上用场了,我们只要把http://www.example.com/a.html 和http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。

    1.在页面 http://www.example.com/a.html 中设置document.domain:

    <iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>

    <script type="text/javascript">

        document.domain = 'example.com';//设置成主域

        function test(){

            alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 对象

        }

    </script>

    2.在页面 http://example.com/b.html 中也设置document.domain:

    <script type="text/javascript">

        document.domain = 'example.com';//在iframe载入这个页面也设置document.domain,使之与主页面的document.domain相同

    </script>

    修改document.domain的方法只适用于不同子域的框架间的交互。

    使用window.name来进行跨域

    window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的

    使用HTML5window.postMessage方法跨域

    window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。

    1. 块状元素,内联元素,显示上的区别和举例有哪些元素?

    答:

    块状元素
    一般是其他元素的容器,可容纳内联元素和其他块状元素,块状元素排斥其他元素与其位于同一行,宽度(width)高度(height)起作用。常见块状元素为div和p、h1~h6,hr,pre,table、ul、ol、li等

    内联元素

    内联元素不能设置宽高,竖直方向上不能设置marginpadding。但水平方向上可以设置marginpadding
    内联元素只能容纳文本或者其他内联元素,它允许其他内联元素与其位于同一行,但宽度(width)高度(height)不起作用。常见内联元素为“a”、big、em、span、strong、img、textarea、label、input等

    1. 块状元素的水平、垂直居中显示如何实现?

    答: 让div内的内容(包括文字及图片)垂直居中: vertical-align的值是middle,水平居中:center.

    关于居中使用css为:position:fixed;left:50%;top:50%;margin-left:width/2;

    margin-top:height/2; 对于ie6,只能把position:改成absolute;(在其他浏览器换成absolute也没什么问题,因为fixed与absolute定位元素是一样的)

    1. Position

    答:position:absolute和float会隐式地改变display类型,不论之前什么类型的元素(display:none除外),只要设置了position:absolute、float:left或float:right中任意一个,都会让元素以display:inline-block的方式显示。

    1. cmd和amd模块化,requirejs等。。还有MVC模式

    答 :

    1.对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

    2. CMD 推崇依赖就近,AMD 推崇依赖前置。

    3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。

    1. 变量声明提前

    答:

    javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。

    先看一段代码

    1

    2

    3

    4

    5

    var v = "hello";

    (function(){

      console.log(v);

      var v = "world";

    })();

    这段代码运行的结果是什么呢?
    答案是:undefined
    这段代码说明了两个问题,
    第一,function作用域里的变量v遮盖了上层作用域变量v。代码做少些变动

    1

    2

    3

    4

    5

    var v = "hello";

    if(true){

      console.log(v);

      var v = "world";

    }

    输出结果为"hello",说明javascript是没有块级作用域的函数是JavaScript中唯一拥有自身作用域的结构。

    第二,在function作用域内,变量v的声明被提升了。所以最初的代码相当于:

    1

    2

    3

    4

    5

    6

    var v = "hello";

    (function(){

      var v; //declaration hoisting

      console.log(v);

      v = "world";

    })();

    声明、定义与初始化

    声明宣称一个名字的存在,定义则为这个名字分配存储空间,而初始化则是为名字分配的存储空间赋初值。
    用C++来表述这三个概念

    1

    2

    3

    extern int i;//这是声明,表明名字i在某处已经存在了

    int i;//这是声明并定义名字i,为i分配存储空间

    i = 0;//这是初始化名字i,为其赋初值为0

    javascript中则是这样

    1

    2

    var v;//声明变量v

    v = "hello";//(定义并)初始化变量v

    因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。

    声明提升

    当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明

    1

    2

    3

    4

    5

    6

    (function(){

      var a = "1";

      var f = function(){};

      var b = "2";

      var c = "3";

    })();

    变量a,f,b,c的声明会被提升到函数作用域的最前面,类似如下:

    1

    2

    3

    4

    5

    6

    7

    (function(){

      var a,f,b,c;

      a = "1";

      f = function(){};

      b = "2";

      c = "3";

    })();

    请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    (function(){

      //var f1,function f2(){}; //hoisting,被隐式提升的声明

     

      f1(); //ReferenceError: f1 is not defined

      f2();

     

      var f1 = function(){};

      function f2(){}

    })();

    上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

    名字解析顺序

    javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
    1、语言内置:所有的作用域中都有 this 和 arguments 关键字
    2、形式参数:函数的参数在函数作用域中都是有效的
    3、函数声明:形如function foo() {}
    4、变量声明:形如var bar;

    名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。看代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    (function(){

        var foo;

        console.log(typeof foo); //function

         

        function foo(){}

     

        foo = "foo";

        console.log(typeof foo); //string

    })();

    如果形式参数中有多个同名变量,那么最后一个同名参数会覆盖其他同名参数,即使最后一个同名参数并没有定义。

    以上的名字解析优先级存在例外,比如可以覆盖语言内置的名字arguments。

    命名函数表达式

    可以像函数声明一样为函数表达式指定一个名字,但这并不会使函数表达式成为函数声明。命名函数表达式的名字不会进入名字空间,也不会被提升。

    1

    2

    3

    4

    5

    f();//TypeError: f is not a function

    foo();//ReferenceError: foo is not defined

    var f = function foo(){console.log(typeof foo);};

    f();//function

    foo();//ReferenceError: foo is not defined

    命名函数表达式的名字只在该函数的作用域内部有效。

    1. 数组去重(看来是百度的常见问题,在其他人的总结中看到了答案)

    答:方法一:(这个方法通过两层嵌套,实现查找,效率较低。总体思路是把数组元素逐个搬运到另一个数组,搬运的过程中检查这个元素是否有重复,如果有就直接丢掉。)

    function unique(arr) {

        var result = [], isRepeated;

        for (var i = 0, len = arr.length; i < len; i++) {

            isRepeated = false;

            for (var j = 0, len = result.length; j < len; j++) {

                if (arr[i] == result[j]) {  

                    isRepeated = true;

                    break;

                }

            }

            if (!isRepeated) {

                result.push(arr[i]);

            }

        }

        return result;

    }

    方法二:(这个方法是利用hash表中(的key值存不存在的方法实现,也可以说是map、reduce的方法))

    function unique(arr) {

        var result = [], hash = {};

        for (var i = 0, elem; (elem = arr[i]) != null; i++) {

            if (!hash[elem]) {

                result.push(elem);

                hash[elem] = true;

            }

        }

        return result;

    //http://www.cnblogs.com/sosoft/

    }

    1. Jquery的defered实现原理
    2. 继承
    3. 除去字符串中的空格

    答:1.s.replace(" ","");      

    2.text.replace(/s/ig,'');

    1. 闭包

    答:闭包的形式是function a中return function b,b中会用到a 中的局部变量,也可能用到函数a的外部变量,根据js内存回收机制,一旦function a执行完成,a中定义的局部变量就会被回收清除,采用闭包以后就会将function b所用到的所有变量跟b绑在一起,只要function b不被清除,这些变量就不会被回收和清除。闭包容易产生内存泄露,要注意在不用b时,手动的清除b。

    (实际上任何函数都是全局作用域的内部函数,都能访问全局变量,所以都是window的闭包) 

    闭包的用处:闭包可以将函数中的局部变量给以保存下来,作用:

    1. 匿名函数自执行(而且这种机制不会污染对象)
    2. 缓存,再来看一个例子,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
      那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,
      然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,
      从而函数内部的值可以得以保留。
    3. 实现封装
    4. 闭包的另一个重要用途是实现面向对象中的对象,传统的对象语言都提供类的模板机制,
      这样不同的对象(类的实例)拥有独立的成员及状态,互不干涉。虽然JavaScript中没有类这样的机制,但是通过使用闭包,
      我们可以模拟出这样的机制。
    1. 前端优化

    答:答案同网易面试题

    1. css文件引入的方法,import和link方法的区别
    (1) link属于HTML标签,而@importCSS提供的; 
      (
    2) 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
      (
    3) import只在IE5以上才能识别,而linkHTML标签,无兼容问题;
      (
    4) link方式的样式的权重 高于@import的权重.

    答:有4种,分别是行内式、内嵌式、链接式和导入式。

    1. 行内式:直接在html标签中用style设定css
    2. 嵌入式:采用<style>标签,  缺点是对于一个包含很多网页的网站,在每个网页中使用嵌入式,进行修改样式时非常麻烦。单一网页可以考虑使用嵌入式

    3.导入式: 将一个独立的.css文件引入HTML文件中,导入式使用CSS规则引入外部CSS文件,<style>标记也是写在<head>标记中,使用的语法如下:

              <style type="text/css">

                        @import"mystyle.css"; 此处要注意.css文件的路径

             </style>

    缺陷:  导入式会在整个网页装载完后再装载CSS文件,因此这就导致了一个问题,如果网页比较大则会儿出现先显示无样式的页面,闪烁一下之后,再出现网页的样式。这是导入式固有的一个缺陷。

    4.链接式: 也是将一个.css文件引入到HTML文件中,但它与导入式不同的是链接式使用HTML规则引入外部CSS文件,它在网页的<head></head>标签对中使用<link>标记来引入外部样式表文件,使用语法如下:

              <link href="mystyle.css" rel="stylesheet" type="text/css"/>

              使用链接式时与导入式不同的是它会以网页文件主体装载前装载CSS文件,因此显示出来的网页从一开始就是带样式的效果的,它不会象导入式那样先显示无样式的网页,然后再显示有样式的网页,这是链接式的优点。

    总结:一般来说,做网站时把样式多写在多个样式表文件中,因此我们先用链接式引入一个总的CSS文件,然后在这个CSS文件中在使用导入式来引入其他的CSS文件。但如果通过JavaScrip来动态引入CSS文件则只能使用链接式。

    1. 事件冒泡及其应用

    答:事件发生的顺序是:先是事件捕获阶段:根节点逐级送到子节点。

    然后是冒泡过程是:子节点到根节点往下冒。

    应用是事件代理。事件代理好处:减少事件绑定的对象的内存。

    其他人补充:

    1. 淘宝为何将图片放在另一个域中,实现跨域加载?

    答:对于这道题,我是这么想的:不同的域名经过dns(域名解析系统)解析以后,映射到的是不同的ip地址,不同的ip地址对应的就是不同的服务器存储地址,所以淘宝将图片放在另一个域中,主要考虑的应该是服务的存储方面。而且将图片放在其他服务器上,减少主服务的存储压力,可以减少IO口的压力,加快速度。

    1. display的几种方式,具体区别?

    答: 主要说一下display为inline-block和display为inline-table的区别,

    这是别人的测试成果:(原文地址:http://blog.csdn.net/yenange/article/details/7520789)

      IE6/7(IE_Test) IE8(xp/2003) IE9 Chrome 18.0.1025.162 m Firefox 12.0
    inline X
    inline-block X ?
    inline-table X

       

     该博主得出的结论是:

    所以在一般情况下, 希望并排, 最好是用 inline ,  判断一下是Chrome则用 inline-table

    var display= navigator.userAgent.indexOf("Chrome") > -1 ? "inline-table" : "inline";

    我觉得inline-block和inline-table最大的区别是都是行内块级元素,(具体差别下次再整理,找不到好的博文)

  • 相关阅读:
    U盘修复
    在tomcat中配置jdk的不同版本
    集​群​t​o​m​c​a​t​+​a​p​a​c​h​e​配​置​文​档
    如何挂自己的web项目(免费拥有自己的网站及域名)
    JQuery对表格进行排序
    JQuery中对各种域进行隐藏和显示操作
    大文件批量上传断点续传文件秒传
    web 开发常用字符串表达式匹配
    spring 工具类大集合
    spring 是如何注入对象的和bean 创建过程分析
  • 原文地址:https://www.cnblogs.com/shixiaomiao/p/4758434.html
Copyright © 2011-2022 走看看