zoukankan      html  css  js  c++  java
  • 慕客--面试题

    考点分析

    页面布局、css盒模型、DOM事件、HTTP协议、面向对象、原型链

    通信:异步通信、前后端通信

    安全:CSRF XSS

    算法:不规律

     

    一、页面布局

    回答:有5种布局解决方案

    1、浮动 2、定位 3、flexbox布局 4、table表格布局 5、grid布局

    延伸:

    1、每个解决方案的优缺点,他们之间的比较

    回答:

    浮动问题:缺点:需要清楚浮动,脱离文档流,处理不好会出现问题。优点:兼容性好

    绝对定位:缺点:同样脱离文档流,下面子元素也脱离文档流,可使用性比较差。 优点:快捷。

    flexbox布局:缺点:IE8不支持 优点:比较完美解决方案

    表格布局:缺点:除了大家诟病的那些缺点(繁琐、不利于seo),还有同行一列单元格增高,同时增高问题。优点: 兼容性好   具体情况比较看 用flexbox还是用表格布局。

    grid布局(网格布局):缺点:优点: 

    2、假如把高度去掉,哪个方案不太适用了?

    回答:只有flex布局和表格布局获胜

    3、兼容性,真正的在业务中哪个是最实用的?

    二、CSS盒模型

    1、谈谈你对CSS盒模型的认识

    回答:

    css盒模型是css的基石

    CSS盒模型本质上是一个盒子,包括margin-border-padding-content

    基本概念:标准模型+IE模型

    2、标准模型和IE模型的区别?

    回答:

    标准模型的宽和高只是content的宽和高

    IE模型的宽和高还包括 border和padding

    3、css如何设置这两种模型?

    回答:

    box-sizing:content   浏览器默认的是标准模型

    box-sizing:border-box

    4、js如何设置获取盒模型对应的宽和高?

    dom.style.width/height   只能取出内联样式的宽和高

    dom.currentStyle.width/height  取出的是渲染后的宽和高,但是只有IE支持

    window.getComputedStyle(dom).width/height   兼容

    dom.getBoundingClientRect().widht/height  获取元素绝对位置,left,top,widht,height
    5、实例题(根据盒模型解释边距重叠),父元素的高是多少?

    回答:默认是100,父元素加上“overflow:hidden”属性后,高度变成110;

    边距重叠的三种情况:a、父子元素,子元素margin-top设值 b、兄弟元素,设margin值,原则上取最大值 c、空元素margin值也会取最大值

    6、BFC(边距重叠解决方案)

    回答:

    BFC基本概念:块级元素格式化上下文 block formatting context  (BFC比IFC常问)

          —> BFC的原理(就是渲染规则:1,BFC元素的垂直方向会发生重叠;2,BFC的区域不会与
    浮动元素的box重叠;3,BFC在页面上是一个独立的容器,外面的元素和里面的元素不会相互影
    响;4, 计算BFC高度时,浮动元素也会参与计算)
                —> 如何创建BFC(1,float值不为none,只要设置了浮动,就创建了BFC;position值
    不为static和relative就创建了BFC;3,display属性inline-block, table-cell, table等等都可以;4,
    overflow: hidden/auto(不为visible即可))
                      —> BFC的使用场景
    编程演示:
    a 给元素创建一个父元素,创建一个BFC,就可以解决垂直方向边距重叠。
    b 元素侵占浮动元素的剩余空间,则在这个元素上面创建BFC,就可以解决,使得BFC不与float
    重叠。
    c 父级元素创建BFC,可以解决由于浮动元素导致父级元素高度为0的情况。创建方法可以是:
    父级也float,或者父级overflow:hidden/auto

     三、DOM事件

    1、基本概念:DOM事件级别

    回答:DOM标准定义的级别:DOM0、DOM2、DOM3

    DOM0,   element.onclick = function(){}
    DOM2,  element.addEventListener(’click’, ()=>{}, false)
    DOM3,  element.addEventListener(‘keyup’, ()=>{}, false)

    2、DOM事件模型

    回答: 捕获和冒泡

    3、事件流

    回答:一个完整的事件流分三个阶段:捕获阶段、目标阶段、冒泡阶段

    4、描述DOM事件捕获的具体流程

    回答:window --> document —>html —> body —> …… —> target

    如何获取html标签?
          document.body ==> 获取body
          document.documentElement ==> 获取html

    5、Event对象的常见应用

    回答:

    event.preventDefault() // 阻止默认事件行为
    event.stopPropagation() // 阻止冒泡事件行为
    event.stopImmediatePropagation() // (一个按钮注册两个事件a、b)在a的响应函数中加此语句,可以阻止b事件

    event.currentTarget // 和this 的作用是差不多的,始终返回的是绑定事件的元素    
    event.target // 当前被点击的元素

    (for循环遍历节点添加事件的时候都可以用事件委托来做,可以提高性能。)

    6、自定义事件

    // 创建自定义事件
    var eve = new Event(‘custome’);
    ev.addEventListener(‘custome’, ()=>{})
    // 触发自定义事件
    ev.dispatch(eve)

    window.addEventListener('click',function(){},false)   默认是fasle,表示冒泡阶段触发

    也可以使用CustomEvent创建自定义事件,并且可以指定一些参数

     四、类型转换

    1、数据类型

    回答:最新ECMAScript标准定义了7种数据类型

    原始类型:Boolean Number String  Symbol  Null Undefind 

    对象:Object

    2、显式类型转换

    回答:显式调用Number函数、String函数、Boolean函数

    Number函数

    原始类型转换

    数值:转换后还是原来的值

    字符串:如果可以被解析为数值,则转换为相应的数值,否则得到NaN。空字符串转为0

    布尔值:true转为1,false转为0

    undefined:转为NaN

    null:转为0

    对象类型转换

      先调用对象自身的 valueOf 方法,如果返回原始类型的值(数值、字符串、布尔),则直接使用Number方法,结束。

                     如果返回复合类型的值,则调用 toString方法,如果返回原始类型的值,则使用Number方法,结束。

                                          如果返回复合类型的值,则报错。

    String函数

     原始类型转换:

     数值:转为相应的字符串 

    字符串:转换后还是原来的值

     布尔值:true 转为"true" ,fasle 转为"false"

     undefined:"undefined"

     null:转为"null"

    对象类型转换:

     先调toString方法,如果返回原始类型,则使用String方法,结束。

             如果返回复合类型,再调用valueOf,如果返回原始类型,则使用String方法,结束。

                              如果返回复合类型,则报错。

    Boolean函数

    原始类型转换:

    undefined、null、+0、-0、NaN、''(空字符串)  他们都返回false  6个

    其他的都是true 

    3、隐式类型转换

    回答:

    四则运算(+-×)

    判断语句(if、三目运算符)

    Native调用(console.log()  alert() 自动转换为字符串类型)

     五、HTTP协议类

    1、HTTP协议的主要特点

    回答:简单快速、灵活、无连接、无状态(后两个一定要说)

      简单快速:每个资源都是固定的,统一资源符
         灵活:通过一个http协议就可以完成不同数据类型的传输,只需要更改头文件中的数据类型
         无连接:连接一次就断掉,不会保持连接
         无状态:一次连接之后,服务端是无法记住客户端的状态的(通过session等手段才能实现)

    2、HTTP报文的组成部分

    回答:HTTP报文由请求报文和响应报文组成;请求报文包括:请求行、请求头、空行、请求体; 响应报文包括:状态行、响应头、空行、响应体

    请求行包含(http方法、页面地址、http协议以及版本)(example: GET /home/xxx HTTP/1.1)

    请求头:(key-value值)告诉服务端请求的内容是什么

    空行(告诉服务器端该解析请求体了)

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

    状态行:(example:HTTP/1.1 200 OK)

    3、HTTP方法

    回答:

    GET —> 获取资源
      POST —> 传输资源
      PUT —> 更新资源
      DELETE —> 删除资源
      HEAD —> 获取报文首部

    4、GET和POST的区别

    回答:(记住三四个即可)

    GET在浏览器中回退是无害的,而POST会再次提交请求
    GET产生的URL地址可以被收藏,而POST不可以
    GET请求可以被浏览器主动缓存,POST不会,需要手动设置
    GET请求只能进行url编码,而POST支持多种编码方式
    GET请求的参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留
    GET请求在URL中传输的参数长度是有限制的,而POST请求没有限制
    对参数的数据类型,GET只接受ASCII字符,而POST没有限制
    GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
    GET参数通过URL传递,POST放在Request body中

    5、HTTP状态码

    回答:

    1xx:指示信息 ---请求已接收,继续处理
    2xx:成功 ---表示请求已被成功接收
    3xx:重定向  --- 要完成请求必须进行更进一步的操作
    4xx:客户端错误  --- 请求有语法错误或请求无法实现
    5xx:服务端错误  --- 服务器未能实现合法的请求

    200,206,301,302,304,400,401,403,404,500,503

    6、什么是持久连接

    回答:

    HTTP协议采用“请求-应答”模式,当使用普通模式,即非keep-alive模式时,每次连接都需要重新
    建立。持久连接只有在1.1版本才支持。

    7、什么是管线化

    回答:

    持久连接的情况下,请求和连接是对应的,即:
          请求1-->响应1-->请求2-->响应2

    管线化是指,将请求和响应都进行了打包进行发送:
          请求1,2,3—>响应1,2,3

    管线化机制是通过持久连接完成的,至少1.1版本
    只有GET和HEAD请求可以进行管线化,POST有所限制
    初次建立不应启动管线化,因为服务端不一定支持1.1  
    管线化不会影响到来的顺序
    HTTP/1.1要求服务器支持管线化,但并不要求服务端一定能进行管线化处理,只是要求对于管线化的请求不失败即可
    开启管线化很可能不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持
    并不好,因此现代浏览器,如Chrome和Firefox是默认关闭管线化的。

     六、原型链

    1、创建对象有几种方法

    回答:

    对象字面量:
                         var 01 = {name: ‘o1’};
                         var 011 = new Object({name: ‘o11’});
    构造函数:
                        var M = function(){
                          this.name = ‘m’;
                         }
                        var o2 = new M();
    Object.create():
                        var P = {name: ‘o3'}
                        var o3 = Object.create(P);


    2、原型,构造函数,对象实例,原型链

    构造函数—new—>实例对象—__proto__—>原型对象
    构造函数—prototype—>原型对象
    构造函数<—constructor--原型对象

    +作用域链是什么?(scope chain)

    当代码在一个环境执行时,会创建由变量对象构成的一个作用域链

    如果这个环境是函数,则将其活动对象(activation object)作为变量对象。

    函数被创建的时候,会创建一个包含全局变量对象的作用域链,保存在内部属性[Scope]中。

    当调用函数时,会创建一个执行环境,然后复制函数的[Scope]属性中的对象构建起执行环境的作用域链。然后呢又有一个活动对象(使用this、arguments、其他命名参数的值初始化)(在此作为变量对象)被创建并被推入作用域链的前端。

    作用域链的本质是一个指向变量对象的指针列表,它只引用并不实际包含对象。

    作用域链的用途:保证对执行环境有权访问的变量和函数的有序访问。


    3、 instanceof的原理

    回答:判断实例对象__proto__属性和构造函数的prototype是不是同一个引用 ,在判断实例对象是不是这个构造函数的实例的时候,其实判断的是实例的__proto__属性与构造函数的prototype是不是引用的同一个地址。 实例的原型对象有可能是另一个类型的实例,以此类推。在intanceof判断,实例对象是不是构造函数(原型对象指向的超类型的原型对象的构造函数)的实例时候,返回true
    4、new运算符

    Step1: 一个新对象被创建,它继承自foo.prototype
          ==>
    Step2: 构造函数foo被执行,执行的时候,相应的传参会被传入,同时上下文(this)会被指定为
    这个新实例。new foo等同于new foo(),只能用在不传递任何参数的情况下
         ==>
    Step3: (如果构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函
    数没有返回对象,)那么new出来的结果为步骤1创建的对象。
    new的代码:
    var new2 = function(func) {
      var o = Object.create(func.prototype);
      var k = func.call(o);
       If(typeof k === ‘object’ ) {
         return k;
       } else {
         return o;
       }
    }

    var M = function (name) {this.name =name;};

    o6 = new2(M)    new M

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

      How new works

           Brendan Eich wanted Javascript to look like traditional Object Oriented programming languages such as Java and C++. In those, we use the new operator to make a new instance of a class. So he wrote a new operator for Javascript.

    1. Create the instance of the class. It is an empty object with its __proto__ property set to F.prototype.
    2. Initialize the instance. The function F is called with the arguments passed and this set to be the instance.
    3. Return the instance

    Now that we understand what the new operator does, we can implement it in Javascript.

    1    function New (f) {
    2 /*1*/  var n = { '__proto__': f.prototype };
    3        return function () {
    4 /*2*/    f.apply(n, arguments);
    5 /*3*/    return n;
    6        };
    7      }

      七、面向对象

    1、类与实例:怎么生成一个类,类的声明,怎么生成一个实例

    回答:

     1 //类的声明
     2 //*ES5中class声明*/
     3 function Person () {
     4     this.name = 'name';
     5 }
     6 //*ES6中class声明*/
     7 class Person2 {
     8     constructor () {
     9         this.name = 'name';
    10     }
    11 }
    12 //实例化类的对象
    13 new Person();
    14 new Person2();

    2、类与继承:如何实现继承,继承的几种方式

    回答:

    实现继承的基本原理就是原型链。

    第一种,借助构造函数实现继承:

    1 function Parent1 () {
    2     this.name = 'parent1';
    3 }
    4 function Child1 () {
    5     Parent1.call(this); //这句是执行父级的构造函数,也可用apply,改变函数运行的上下文
    6     this.type = 'child1';
    7 }
    8 new Child1();

    缺点:既然是函数里面的方法,就谈不上函数的复用性。Parent1的prototype上面的属性或者方法是不能被Chlid1继承的,只实现了部分继承。

    第二种,借助原型链实现继承:

     1 function Parent2 () {
     2     this.name = 'parent2';
     3     this.play = [1,2,3];
     4 }
     5 function Child2 () {
     6     this.type = 'child2';
     7 }
     8 Child2.prototype = new Parent2();
     9 new Child2();
    10 var s1 = new Child2();
    11 var s2 = new Child2();
    12 s1.play.push(4);
    13 console.log(s1.play, s2.play); // [1,2,3,4] [1,2,3,4]

    缺点:

    父类中增加新的属性,那么所有的实例都会同时改变。如果某个实例的属性值(来自父类的)发生了
    变化,那么其他实例也都跟着发生了变化。因为所有实例的__proto__是同一个,所以相互之间会有
    影响。(还有一个问题,这创建子类型的实例时,不能向超类型的构造函数中传递参数。)

    第三种,组合方式:

     1 function Parent3() {
     2   this.name = ‘parent3’;
     3    This.play = [1,2,3,4];
     4 }
     5 function Child3(){
     6   Parent3.call(this);
     7   this.type = ‘child3’;
     8 }
     9 Child3.prototype = new Parent3();
    10 var s3 = new Child3();
    11 var s4 = new Child3();

    缺点:父级的构造函数执行了两次,而并没有必要

    优化方式1:

     1 function Parent4() {
     2   this.name = ‘parent4’;
     3    This.play = [1,2,3,4];
     4 }
     5 function Child4(){
     6   Parent4.call(this);
     7   this.type = ‘child4’;
     8 }
     9 Child4.prototype = Parent4.prototype;
    10 var s5 = new Child4();
    11 var s6 = new Child4();
    12 s5 instanceof Child4  ======>>>true
    13 s5 instanceof Parent4 ======>>>true

    问题:

    怎么区分一个对象是由子类实例化的,还是父类实例化的(直接实例化)
    constructor方法在这里会出问题,因为s5.constructor 指向的是 Parent4。(其实前面的方法也有
    这个问题)

    优化方式2:

     1 function Parent5() {
     2   this.name = ‘parent5’;
     3    This.play = [1,2,3,4];
     4 }
     5 function Child5(){
     6   Parent5.call(this);
     7   this.type = ‘child5’;
     8 }
     9 Child5.prototype = Object.create(Parent5.prototype);
    10 Child5.prototype.constructor = Child5;
    11 var s7 = new Child5();
    12 var s8 = new Child5();

    完美!(此处王祖蓝)

    八、通信类

    1、什么是同源策略及限制:

    回答:

    源:协议,域名,端口
    限制:不是一个源的文档没有权利去操作另一个源的文档,包括Cookie, LocalStorage, IndexDB,
    DOM无法获取, Ajax无法发送
    同源策略限制不同的源的文档之间进行交互。

    2、前后端如何通信:

    回答:

    Ajax:同源限制
    WebSocket:不受限制
    CORS:支持同源,也支持非同源(新的通信协议标准)

    3、如何创建Ajax:有以下几个要点

    XMLHttpRequest对象的工作流程
    兼容性处理
    事件的触发条件
    事件的触发顺

    4、跨域通信的几种方式

    JSONP
    Hash(hash改变,页面是不刷新的,?后是search,改变时会刷新页面)
    postMessage(新技术,h5的标准)
    WebSocket
    CORS(可以理解为支持跨域通信的变种Ajax。当你在浏览器中发送一个ajax跨域请求时,浏
    览器会在http头中加入一个origin。如果只是一个普通的ajax,则会被浏览器拦截)

    5、JSONP的原理:

    回答:利用script标签的可以不同源加载实现的。

    1. 在window全局注册一个函数
    2. 给服务端传递这个函数的名字,同时可以有参数
    3. 服务端返回这个函数,内部填充有数据,就可以拿到数据
    4. 删除全局注册的那个函数

    6、Hash的原理

    页面A中通过iframe或frame嵌入了B窗口。目标是A给B发消息。
    1. 拿到B的url地址
    2. 改变其hash值
    3. 在B中接收,onhashchange

    7、WebSocket的原理:

    1. var ws = new WebSocket('wss:echo.websocket.org');
    2. onopen, onmessage, onclose

    8、CORS的原理:

    fetch(‘/some/url’, {
      method: ‘get’,
    // 加一些配置就可以实现跨域的通信,这里可以参考一篇文章
    }).then(function (response) {
      // xxx
    }).catch(function(err){
      // yyy
    });

      八、安全类

    1、前端安全有几种分类

    XSS
    CSRF

    CSRF:
    基本概念和缩写:跨站请求伪造,cross-site request forgery
    攻击原理:
    用户   ——1登陆——>               网站A
    用户   <—— 2下发cookie——       网站A
    用户   —— 3访问——>               网站B
    用户   <——4引诱点击——          网站B
    用户   ——5访问——>               网站A(A就会通过cookie判断,觉得是合法用户)

    XSS:
    跨域脚本攻击:Cross-site scripting
    攻击原理:不需要登陆认证,是向页面注入脚本,写入一些标签。
    防御措施:目的是让插入的这些东西无法执行

      九、算法类

    -------------二面三面--------------

    一、渲染机制

    二、js运行机制

    三、页面性能

    提高页面性能的方法有哪些?

    1、资源压缩合并,减少http请求

    2、非核心代码异步加载   ->  异步加载的方式   ->  异步加载的区别

    3、利用浏览器缓存   ->  缓存的分类  ->  缓存的原理

    4、使用CDN  (CDN加速资源是非常快的,属于网络优化这一块)

    5、预解析DNS

    <meta http-equiv = "x-dns-prefetch-control" content = "on">

    <link rel = "dns-prefetch" href="//host_name_to_prefetch.com">

    6、sprite雪碧图处理 

    四、错误监控

  • 相关阅读:
    人生苦短,我用python!
    Pycharm快捷键
    查看java进程
    带你掌握Arthas
    高并发场景下System.currentTimeMillis()的性能问题的优化
    SpringBoot整合Dubbo&ZooKeeper
    CentOS7下yum安装Mysql5.7
    SpringCache整合Redis实现自定义缓存时间
    Java开发神器lombok
    CentOS7安装Nginx
  • 原文地址:https://www.cnblogs.com/sanerandm/p/8480538.html
Copyright © 2011-2022 走看看