前端面试题总结

1:为何选择前端这个方向和对前端的理解

为什么:

第一的话就是对前端很感兴趣,之前也接触过其他的语言,但是直到接触到前端才发现真的有兴趣做下去,兴趣是一个人最好的老师,

第二的话前端很有前途,像现在nodejs,rn,微信小程序这类工具和框架可以让前端进行后端和移动开发,所以我觉得前端的前途会更多一点。

理解:

首先前端工程师最核心的技能还是:Html、CSS、JS。前端负责的是用户可以看到的部分,所以也是最接近用户的工程师。同时在产品研发流程中前端要同时与产品、设计、后端等很多人合作。

2:Vue双向数据绑定的实现

vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的settergetter,在数据变动时发布消息给订阅者(文本节点则是作为订阅者),在收到消息后执行相应的更新操作。

compile主要做的事情是解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图

MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

AngularJS 采用“脏值检测”的方式,数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变。

3:react和vue有哪些不同 说说你对这两个框架的看法

都用了virtual dom的方式, 性能都很好

ui上都是组件化的写法,开发效率很高

vue是双向数据绑定,react是单项数据绑定,当工程规模比较大时双向数据绑定会很难维护

vue适合不会持续的  小型的web应用,使用vue.js能带来短期内较高的开发效率. 否则采用react

4:let和const的区别

let声明的变量可以改变,值和类型都可以改变,没有限制。

const声明的变量不得改变值

5:平时用了es6的哪些特性,体验如何 和es5有什么不同

let const关键字 箭头函数 字符串模板 class类 模块化 promise

es5 require react.createclass

6:浏览器原生支持module吗,如果支持,会带来哪些便利

不支持

7:介绍一下你对webpack的理解,和gulp有什么不同

Webpack是模块打包工具,他会分析模块间的依赖关系,然后使用loaders处理它们,最后生成一个优化并且合并后的静态资源。

gulp是前端自动化工具 能够优化前端工作流程,比如文件合并压缩

8:webpack打包速度慢,你觉得可能的原因是什么,该如何解决

模块太多

Webpack 可以配置 externals 来将依赖的库指向全局变量,从而不再打包这个库 或者dllplugin

webpack-parallel-uglify-plugin 并行压缩

CommonsChunkPlugin提取公共的模块

happypack 多进程构建

9:http响应中content-type包含哪些内容

请求中的消息主体是用何种方式编码

application/x-www-form-urlencoded

这是最常见的 POST 提交数据的方式 按照 key1=val1&key2=val2 的方式进行编码

application/json

告诉服务端消息主体是序列化后的 JSON 字符串

10:浏览器缓存有哪些,通常缓存有哪几种方式

强缓存 强缓存如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器。

协商缓存 当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果协商缓存命中,服务器会将这个请求返回(304),若未命中请求,则将资源返回客户端,并更新本地缓存数据(200)。

HTTP头信息控制缓存

Expires(强缓存)+过期时间   ExpiresHTTP1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间

Cache-control(强缓存) 描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断 管理更有效,安全一些 Cache-Control: max-age=3600

服务端返回头Last-Modified/ 客户端请求头If-Modified-Since(协商缓存) 标示这个响应资源的最后修改时间。Last-Modified是服务器相应给客户端的,If-Modified-Sinces是客户端发给服务器,服务器判断这个缓存时间是否是最新的,是的话拿缓存。

服务端返回头Etag/客户端请求头If-None-Match(协商缓存) etag和last-modified类似,他是发送一个字符串来标识版本。

强缓存不请求服务器,客户端判断 、协商缓存要请求服务器

11:如何取出一个数组里的图片并按顺序显示出来

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

function loadImage(imgList,callback){

        if(!$.isArray(imgList) || !$.isFunction(callback)) return ;

        var imageData = [] ;

        $.each(imgList, function(i,src){

            var img = new Image() ;

            img.onload = function(){

                $(imageData.shift()).appendTo("body") ;

                if(!imageData.length){

                    callback() ;

                    return ;

                }

                this.onload = null ;

            } ;

            img.src= src ;

            imageData.push(img) ;

        }) ;

    } ;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

async function loadImgs(imgList, cb) {

 

    console.log("start")

    forvar i =0; i<imgList.length; i++) {

        await imgLoader(imgList[i], i);

        console.log("finish"+i)

    }

    cb();

}

 

async function imgLoader(url, num){

    return new Promise((resolve, reject) => {

        console.log("request"+num)

         

        setTimeout(resolve, 1000);

        // let img = new Image();

        // img.onload = () => resolve(img);

        // img.onerror = reject;

 

        console.log("return"+num)

    })

}

 

loadImgs(["xxx/a.png","xxx/b.png"],function() {

    console.log("开始干活");

})

12:平时是怎么学新技术的

伯乐在线 infoq 掘金 简书 慕课网

13:Node,Koa用的怎么样

koa是一个相对于express来说,更小,更健壮,更富表现力的Web框架,不用写回调

koa是从第一个中间件开始执行,遇到next进入下一个中间件,一直执行到最后一个中间件,在逆序

async await语法的支持

 

14:使用模块化加载时,模块加载的顺序是怎样的,如果不知道,根据已有的知识,你觉得顺序应该是怎么样的

commonjs 同步 顺序执行

AMD 提前加载,不管是否调用模块,先解析所有模块 requirejs 速度快 有可能浪费资源

CMD 提前加载,在真正需要使用(依赖)模块时才解析该模块 seajs 按需解析 性能比AMD差

 

15: 介绍一下闭包和闭包常用场景

  • 闭包是指有权访问另一个函数作用域中的变量的函数. 创建闭包常见方式,就是在一个函数内部创建另一个函数.
  • 本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

应用场景 设置私有变量和方法让这些变量的值始终保持在内存中还有读取函数内部变量。

不适合场景:返回闭包的函数是个非常大的函数

闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function f1(){

 

  var n=999;

 

  function f2(){

    alert(n);

  }

 

  return f2;

 

}

 

var result=f1();

 

result(); // 999

  

16: 为什么会出现闭包这种东西,解决了什么问题

受JavaScript链式作用域结构的影响,父级变量中无法访问到子级的变量值,为了解决这个问题,才使用闭包这个概念

17: 介绍一下你所了解的作用域链,作用域链的尽头是什么,为什么

每一个函数都有一个作用域,比如我们创建了一个函数,函数里面又包含了一个函数,那么现在 就有三个作用域,这样就形成了一个作用域链。

作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域链往上找。

18: 一个Ajax建立的过程是怎样的,主要用到哪些状态码

ajax:在不切换页面的情况下完成异步的HTTP请求

(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.

(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

(3)设置响应HTTP请求状态变化的函数.

(4)发送HTTP请求.

(5)获取异步调用返回的数据.

(6)使用JavaScript和DOM实现局部刷新.

1

2

3

4

5

6

7

8

9

10

11

12

13

var xmlHttp = new XMLHttpRequest();

 

  xmlHttp.open('GET','demo.php','true');

 

  xmlHttp.send()

 

  xmlHttp.onreadystatechange = function(){

 

      if(xmlHttp.readyState === 4 & xmlHttp.status === 200){

 

      }

 

  }

使用promise封装

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

function getJSON(url) { 

    return new Promise(function(resolve, reject) { 

        var XHR = new XMLHttpRequest(); 

        XHR.open('GET', url, true); 

        XHR.send(); 

   

        XHR.onreadystatechange = function() { 

            if (XHR.readyState == 4) { 

                if (XHR.status == 200) { 

                    try 

                        var response = JSON.parse(XHR.responseText); 

                        resolve(response); 

                    catch (e) { 

                        reject(e); 

                    

                else 

                    reject(new Error(XHR.statusText)); 

                

            

        

    }) 

   

getJSON(url).then(res => console.log(res)); 

  

 

当前状态readystate

0 代表未初始化。 还没有调用 open 方法
1 代表正在加载。 open 方法已被调用,但 send 方法还没有被调用
2 代表已加载完毕。send 已被调用。请求已经开始
3 代表交互中。服务器正在发送响应
4 代表完成。响应发送完毕

常用状态码status

404 没找到页面(not found)
403 禁止访问(forbidden)
500 内部服务器出错(internal service error)
200 一切正常(ok)
304 没有被修改(not modified)(服务器返回304状态,表示源文件没有被修改)

19: 说说你还知道的其他状态码,状态码的存在解决了什么问题

302/307  临时重定向

301 永久重定向

借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了什么错误

20: 知道语义化吗?说说你理解的语义化,如果是你,平时会怎么做来保证语义化

像html5的新的标签header,footer,section等就是语义化

一方面,语义化就是让计算机能够快速的读懂内容,高效的处理信息,可以对搜索引擎更友好。

另一方面,便于与他人的协作,他人通过读代码就可以理解你网页标签的意义。

21: 说说content-box和border-box,为什么看起来content-box更合理,但是还是经常使用border-box

content-box 是W3C的标准盒模型 元素宽度=内容宽度+padding+border

border-box 是ie的怪异盒模型  他的元素宽度等于内容宽度  内容宽度包含了padding和border

 比如有时候在元素基础上添加内距padding或border会将布局撑破 但是使用border-box就可以轻松完成

22:介绍一下HTML5的新特性

  • 新的DOCTYPE声明  <!DOCTYPE html> 
  • 完全支持css3
  • video和audio
  • 本地存储
  • 语义化标签
  • canvas
  • 新事件 如ondrag onresize

23:对自己未来的规划是怎样的

对于刚毕业的人来说,前两年是很重要的,先打好基础,多提升js能力。三至四年在提升JS能力的同时,开始要往多方面发展,前端工程师远远不仅是JS而已。制作一个性能高、交互好、视觉美的页面,需要从前端框架选型、架构设计、构建工具,到后端通信机制、设计与交互、网络和浏览器优化等各方面的知识。一专多长才是前端工程师的终极目标。

 24: 在一个UI李有10个li,实现点击对应的li,输出对应的下标

1

2

3

4

5

6

7

8

var lis = querySelectorAll('li')

for(var i=0;i<10;i++){

   lis[i].onclick = (function(a) {

      return function() {

       alert(a)

    }

  })(i)

}   

  事件委托

利用冒泡的原理,把事件加到父级上,触发执行效果。

1.可以大量节省内存占用,减少事件注册。
2.可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。

1

2

3

4

5

6

7

8

9

10

11

12

13

var ul = document.querySelector('ul'); 

var list = document.querySelectorAll('ul li'); 

   

ul.addEventListener('click'function(ev){ 

    var ev = ev || window.event; 

    var target = ev.target || ev.srcElemnt; 

   

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

        if(list[i] == target){ 

            alert(i + "----" + target.innerHTML); 

        

    

}); 

25:实现三个DIV等分排布在一行(考察border-box)

1.设置border-box width33.3%

2.flexbox flex:1 

26: 说说你知道JavaScript的内存回收机制

垃圾回收器会每隔一段时间找出那些不再使用的内存,然后为其释放内存。

一般使用标记清除方法  当变量进入环境标记为进入环境,离开环境标记为离开环境

还有引用计数方法

堆栈

stack为自动分配的内存空间,它由系统自动释放;而heap则是动态分配的内存,大小不定也不会自动释放。

基本数据类型存放在栈中

引用类型 存放在堆内存中,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据

27函数防抖和函数节流

函数防抖是指频繁触发的情况下,只有足够的空闲时间,才执行代码一次

函数防抖的要点,也是需要一个setTimeout来辅助实现。延迟执行需要跑的代码。
如果方法多次触发,则把上次记录的延迟执行代码用clearTimeout清掉,重新开始。
如果计时完毕,没有方法进来访问触发,则执行代码。

1

2

3

4

5

6

7

8

//函数防抖

var timer = false

document.getElementById("debounce").onScroll = function() {

        clearTimeout(timer)  

        timer = setTimeout(function(){

                console.log(‘函数防抖’) 

  }, 300)     

}

函数节流是指一定时间内js方法只跑一次

函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。
如果空闲,则可以正常触发方法执行。
如果代码正在执行,则取消这次方法执行,直接return

1

2

3

4

5

6

7

8

9

10

11

12

//函数节流

var canScroll = true;

document.getElementById('throttle').onScroll = function() {

               if (!canScroll) {

                return;

               }

                canScroll = false;

                setTimeout(function(){

                   console.log('函数节流');

                   canScroll = true;

                },300)       

}

  

28:编程实现输出一个数组中第N大的数据

29.实现两栏布局有哪些方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

*{margin:0; padding: 0;}

html,body{

        height: 100%;/*高度百分百显示*/

}

#left{

    width: 300px;

    height: 100%;

    background-color: #ccc;

    float: left;

}

#right{

    height: 100%;

    margin-left: 300px;

    background-color: #eee;

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

*{margin:0; padding: 0;}

html,body{

        height: 100%;/*高度百分百显示*/

}

#left{

    width: 300px;

    height: 100%;

    background-color: #ccc;

    float: left;

}

#right{

    height: 100%;

    overflow:hidden;

    background-color: #eee;

}

第二种方法,我利用的是创建一个新的BFC(块级格式化上下文)来防止文字环绕的原理来实现的。BFC就是一个相对独立的布局环境,它内部元素的布局不受外面布局的影响。它可以通过以下任何一种方式来创建: 
float 的值不为 none 
position 的值不为 static 或者 relative 
display 的值为 table-cell , table-caption , inline-block , flex , 或者 inline-flex 中的其中一个 
overflow 的值不为 visible

第三种flex布局

30:设置width的flex元素,flex属性值是多少

flex属性是flex-growflex-shrink 和 flex-basis的简写

flex-grow属性定义项目的放大比例,默认为0

flex-shrink属性定义了项目的缩小比例,默认为1

flex-basis属性定义了项目的固定空间

31get和post有什么不同

 get是从服务器上获取数据,post是向服务器传送数据

get请求可以将查询字符串参数追加到url的末尾; post请求应该把数据作为请求的主体提交.

get请求数据有大小限制;post没有

post比get安全性更高

32:cookie和session有什么联系和区别

cookie数据存放在客户的浏览器上,session数据放在服务器上。

session比cookie更安全

单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

一般用cookie来存储sessionid

33:判断链表是否有环

使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

34:输出二叉树的最小深度

 判断左子树或右子树是否为空,若左子树为空,则返回右子树的深度,反之返回左子树的深度,如果都不为空,则返回左子树和右子树深度的最小值。

35: javaScript中的this是什么,有什么用,它的指向是什么

全局代码中的this  是指向全局对象

作为对象的方法调用时指向调用这个函数的对象。

作为构造函数指向新创建的对象

使用apply和call设置this

36写一个快速排序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

var quickSort = function (arr){

        if(arr.lenght <= 1) {

           return arr;

          }

 

       var left = [];

       var right = [];

       var mid = arr.splice(Math.floor(arr.length/2), 1);

 

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

             if(arr[i]<mid) {

                 left.push(arr[i]);

            }

             if(arr[i]>mid) {

                 right.push(arr[i]);

            }

          return quickSort(left).concat(mid, quickSort(right));

     }  

}  

37怎么实现从一个DIV左上角到右下角的移动,有哪些方法,都怎么实现

改变left值为window宽度-div宽度 top值为window高度-div高度

jquery的animate方法

css3的transition

38: 简单介绍一下promise,他解决了什么问题

Promise,就是一个对象,用来传递异步操作的消息。有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。

有了 Promise 对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。

 

39: 写一个组合继承

1

2

3

4

5

6

7

8

9

var Super = function(name){

  this.name = name;

}

Super.prototype.func1 = function() { console.log('func1'); }

var Sub = function(name,age) {

  Super.call(this, name);

  this.age = age;

}

Sub.prototype = new Super();

40:深拷贝方案有哪些,手写一个深拷贝

1

2

3

4

5

6

7

var clone = function(v) {

  var o = v.constructor === Array ? [] : {};

  for (var in v) {

    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];

  }

  return o;

}

41:判断数组有哪些方法

a instanceof Array
a.constructor == Array
Object.prototype.toString.call(a) == [Object Array]

42: 跨域通信有哪些方案,各有什么不同

JSONP:由于同源策略的限制,XmlHttpRequest只允许请求当前源,script标签没有同源限制

通过动态<script>元素使用,使用时为src指定一个跨域url。回调函数处理JSON数据  兼容性好 不支持post

简述原理与过程:首先在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成一个function , function 名字就是传递上来的参数。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里

1

2

3

4

5

6

7

8

9

10

11

  <script> 

  var url = "http://localhost:8080/crcp/rcp/t99eidt/testjson.do?jsonp=callbackfunction";  

  var script = document.createElement('script');  

  script.setAttribute('src', url);  //load javascript   

  document.getElementsByTagName('head')[0].appendChild(script);  

   

  //回调函数 

   function callbackfunction(data){ 

var html=JSON.stringify(data.RESULTSET); 

alert(html); 

     

cors:通过设置Access-Control-Allow-Origin来允许跨域 cors可用ajax发请求获取数据 但是兼容性没有jsonp好 

43:多页面通信有哪些方案,各有什么不同

localstorge在一个标签页里被添加、修改或删除时,都会触发一个storage事件,通过在另一个标签页里监听storage事件,即可得到localstorge存储的值,实现不同标签页之间的通信。

settimeout+cookie

44:用Node实现一个用户上传文件的后台服务应该怎么做

multer模块

45: XSS和CSRF攻击

xss:比如在一个论坛发帖中发布一段恶意的JavaScript代码就是脚本注入,如果这个代码内容有请求外部服务器,那么就叫做XSS

写一个脚本将cookie发送到外部服务器这就是xss攻击但是没有发生csrf

防范:对输入内容做格式检查 输出的内容进行过滤或者转译

CSRF:又称XSRF,冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的请求 如恶意发帖,删帖

比如在论坛发了一个删帖的api链接 用户点击链接后把自己文章给删了 这里就是csrf攻击没有发生xss

防范:验证码 token 来源检测

46:圣杯布局和双飞翼布局

【圣杯布局】

html代码中  middle部分首先要放在container的最前部分。然后是left,right

1.将三者都 float:left , 再加上一个position:relative (因为相对定位后面会用到)

2.middle部分 width:100%占满

3.此时middle占满了,所以要把left拉到最左边,使用margin-left:-100%

4.这时left拉回来了,但会覆盖middle内容的左端,要把middle内容拉出来,所以在外围container加上 padding:0 220px 0 200px

5.middle内容拉回来了,但left也跟着过来了,所以要还原,就对left使用相对定位 left:-200px  同理,right也要相对定位还原 right:-220px

6.到这里大概就自适应好了。如果想container高度保持一致可以给left middle right都加上min-height:130px

【双飞翼布局】

前几步都一样 后边把外围padding和相对定位做法换成内层margin

给middle增加一个内层div-- middle-inner, 然后margin:0 220px 0 200px

47:offsetHeight, scrollHeight, clientHeight分别代表什么

clientHeight:包括内容可见部分的高度,可见的padding;不包括border,水平方向的scrollbarmargin

offsetHeight:包括内容可见部分的高度,border,可见的padding,水平方向的scrollbar(如果存在);不包括margin

scrollHeight:包括内容的高度(可见与不可见),padding(可见与不可见);不包括bordermargin

48:垂直居中

单行行内元素 1.可以设置padding-top,padding-bottom 2.将height和line-height设为相等

多行行内元素 1.可以将元素转为table样式,再设置vertical-align:middle; 2.使用flex布局

块级元素

已知高度绝对定位负边距

未知高度transform: translateY(-50%);

flex布局 

display: flex;

justify-content: center;

align-items: center;

49:transition的属性值和应用

属性的名称 过渡时间 时间曲线 延迟

50:rem和em的区别

em相对于父元素,rem相对于根元素

51:严格模式的特性

严格模式对Javascript的语法和行为,都做了一些改变。

全局变量必须显式声明。

对象不能有重名的属性

函数必须声明在顶层

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

52:js的原型链,如何实现继承?

原型链实际上就是js中数据继承的继承链。
在访问一个实例的属性的时候,现在实例本身中找,如果没找到就去它的原型中找,还没找到就再往上找,直到找到。这就是原型链。

1

2

3

4

5

6

7

8

function foo(){}

foo.prototype.z = 3;

var obj = new foo();

obj.x=1;

obj.y=2;

obj.x //1

obj.y //2

obj.z //3<br><br>obj.__proto__===foo.prototype   true<br>foo.prototype.constructor === foo<br>

53:图片预加载和懒加载

预加载:

1

2

3

4

5

6

7

8

9

10

11

function loadImage(url, callback) {

    var img = new Image();

    img.src = url;

    if (img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数 防止IE6不执行onload BUG

        callback.call(img);

        return;

    }

    img.onload = function () {

        callback.call(img);//将回调函数的this替换为Image对象

    };

};

懒加载:

当网页滚动的事件被触发 -> 执行加载图片操作 -> 判断图片是否在可视区域内 -> 在,则动态将data-src的值赋予该图片。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

var aImages = document.getElementById("SB").getElementsByTagName('img'); //获取id为SB的文档内所有的图片

loadImg(aImages);

window.onscroll = function() { //滚动条滚动触发

loadImg(aImages);

};

//getBoundingClientRect 是图片懒加载的核心

function loadImg(arr) {

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

 if(arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad) {

 arr[i].isLoad = true//图片显示标志位

 //arr[i].style.cssText = "opacity: 0;";

 (function(i) {

  setTimeout(function() {

  if(arr[i].dataset) { //兼容不支持data的浏览器

   aftLoadImg(arr[i], arr[i].dataset.imgurl);

  else {

   aftLoadImg(arr[i], arr[i].getAttribute("data-imgurl"));

  }

  arr[i].style.cssText = "transition: 1s; opacity: 1;" //相当于fadein

  }, 500)

 })(i);

 }

}

}

 

function aftLoadImg(obj, url) {

var oImg = new Image();

oImg.onload = function() {

 obj.src = oImg.src; //下载完成后将该图片赋给目标obj目标对象

}

oImg.src = url; //oImg对象先下载该图像

}

 

54.输入网址后到页面展现的过程

通过dns解析获取ip

tcp链接

客户端发送http请求

tcp传输报文

服务器处理请求返回http报文

客户端解析渲染页面 (构建DOM树 –> 构建渲染树 –> 布局渲染树:计算盒模型位置和大小 –> 绘制渲染树)

 

55:UMD规范和ES6模块化,Commonjs的对比

CommonJS是一个更偏向于服务器端的规范。用于NodeJS 是同步的

AMD是依赖前置的

CMD推崇依赖就近,延迟执行。可以把你的依赖写进代码的任意一行

AMD和CMD都是用difine和require,但是CMD标准倾向于在使用过程中提出依赖,就是不管代码写到哪突然发现需要依赖另一个模块,那就在当前代码用require引入就可以了,规范会帮你搞定预加载,你随便写就可以了。但是AMD标准让你必须提前在头部依赖参数部分写好(没有写好? 倒回去写好咯)。这就是最明显的区别。

UMD写一个文件需要兼容不同的加载规范

ES6通过importexport实现模块的输入输出。其中import命令用于输入其他模块提供的功能,export命令用于规定模块的对外接口。

56:http请求头

get post delete put head options trace connect

OPTIONS:返回服务器针对特定资源所支持的HTTP请求方法

57:nginx的好处?和node的比较

高并发 响应快

区别不是很大,一个更专业,一个更全面:
1.相似点:
1.1异步非阻塞I/O, 事件驱动;
2.不同点:
2.1Nginx 采用C编写,更性能更高,但是它仅适合于做web服务器,用于反向代理或者负载均衡等服务;Nginx背后的业务层编程思路很还是同步编程方式,例如PHP.
2.2NodeJs高性能平台,web服务只是其中一块,NodeJs在处理业务层用的是JS编写,采用的是异步编程方式和思维方式。

58.框架问题

  • 什么是 MVVM , 和 MVC 是什么区别, 原理是什么?

  mvc的界面和逻辑关联紧密,数据直接从数据库读取,必须通过Controller来承上启下,通信都是单向的。mvvm的View 和 ViewModel可以互相通信,界面数据从viewmodel中获取。

  • 父子组件怎么通信的?

  vue:父组件是通过props属性给子组件通信  在子组件里面emit,在父组件监听

  react:props传递  父给子传一个回调函数 将数据传给父亲处理

  • 兄弟组件怎么通信的?

  vuex 建立一个vue实例 emit触发事件 on监听事件

  redux  子A -> 父 -> 子B

  • 生命周期有哪些, 怎么用?

  beforecreated:el 和 data 并未初始化 
  created:完成了 data 数据的初始化,el没有
  beforeMount:完成了 el 和 data 初始化 

  mounted :完成挂载  updated;destroyed

  react:初始化阶段、运行中阶段、销毁阶段

  初始化getDefaultProps()getInitialState()初始化

    componentWillMount() 在组件即将被渲染到页面

  render() 组件渲染
    componentDidMount() 组件被渲染到页面上,

  运行中shouldComponentUpdate() componentWillUpdate() render() componentDidUpdate() 
  销毁componentWillUnmount()

59:清除浮动

两种原理:

1、利用clear属性进行清理

具体的实现原理是通过引入清除区域,这个相当于加了一块看不见的框把定义clear属性的元素向下挤
父容器结尾插入空标签<div style="clear: both;"></div>

利用CSS伪元素:

1

2

3

4

5

6

7

.clearfix:after {

  content: ".";

  height: 0;

  visibility: hidden;

  display: block;

  clear: both;

}

通过将这个类添加到父容器当中,会在父容器的末尾增加了一个高度为0、具有清除属性的、不可见的块级元素。

2、将父容器形成BFC

BFC能清理浮动主要运用的是它的布局规则:

  1. 内部的Box会在垂直方向,一个接一个地放置。
  2. Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
  3. 每个元素的margin box的左边, 与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
  4. BFC的区域不会与float box重叠。
  5. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
  6. 计算BFC的高度时,浮动元素也参与计算

浮动清理利用的主要是第六条规则,只要将父容器触发为BFC,就可以实现包含的效果。

那么触发BFC有哪几种方法?

  1. 根元素
  2. float属性不为none
  3. position为absolute或fixed
  4. display为inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不为visible

60.前端性能优化

1.减少http请求 使用sprite图、合并js和css文件

2.使用cdn 将用户安排在近的服务器上

3.使用缓存 缓存ajax 使用外部的css和js以便缓存 使用expire cach-control etag

4.压缩资源 使用gzip压缩js和css文件

5.代码层面 避免使用样式表达式、通配符选择器、样式放在顶部、脚本放在底部

61.事件模型和事件代理

事件三个阶段:事件捕获,目标,事件冒泡(低版本ie不支持捕获阶段)

w3c绑定事件target.addEventListener(event,handler,false)

解绑target.removeEventListener(eventType, handler, false)

ie绑定 target.attachEvent(on+event, handler)

解绑target.detachEvent("on"+eventType, handler)

事件代理优点:

  • 可以大量节省内存占用,减少事件注册,比如在table上代理所有td的click事件就非常棒

  • 可以实现当新增子对象时无需再次对其绑定事件,对于动态内容部分尤为合适

bind和trigger实现:

创建一个类或是匿名函数,在bind和trigger函数外层作用域创建一个字典对象,用于存储注册的事件及响应函数列表,bind时,如果字典没有则创建一个,key是事件名称,value是数组,里面放着当前注册的响应函数,如果字段中有,那么就直接push到数组即可。trigger时调出来依次触发事件响应函数即可。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

function Emitter() {

    this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2]

}

  

//注册事件

Emitter.prototype.bind = function(eventName, callback) {

    var listener = this._listener[eventName] || [];//this._listener[eventName]没有值则将listener定义为[](数组)。

    listener.push(callback);

    this._listener[eventName] = listener;

}

  

 //触发事件

Emitter.prototype.trigger = function(eventName) {

    var args = Array.prototype.slice.apply(arguments).slice(1);//atgs为获得除了eventName后面的参数(注册事件的参数)

    var listener = this._listener[eventName];

  

    if(!Array.isArray(listener)) return;//自定义事件名不存在

    listener.forEach(function(callback) {

        try {

            callback.apply(this, args);

        }catch(e) {

            console.error(e);

        }

    })

}

  

62.将url的查询参数解析成字典对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

function getQueryObject(url) {

    url = url == null ? window.location.href : url;

    var search = url.substring(url.lastIndexOf("?") + 1);

    var obj = {};

    var reg = /([^?&=]+)=([^?&=]*)/g;

    search.replace(reg, function (rs, $1, $2) {

        var name = decodeURIComponent($1);

        var val = decodeURIComponent($2);              

        val = String(val);

        obj[name] = val;

        return rs;

    });

    return obj;

}

  

getQueryObject("http://www.cnblogs.com/leee/p/4456840.html?name=1&dd=ddd**")

Object {name: "1", dd: "ddd**"}

  

63.position的值, relative和absolute分别是相对于谁进行定位的?
<1>、relative:相对定位,相对于自己本身在正常文档流中的位置进行定位。
<2>、absolute:生成绝对定位,相对于最近一级定位不为static的父元素进行定位。
<3>、fixed: 生成绝对定位,相对于浏览器窗口或者frame进行定位。
<4>、static:默认值,没有定位,元素出现在正常的文档流中。
<5>、sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。

64.position:absolute和float属性的异同?
共同点:对内联元素设置float和absolute属性,可以让元素脱离文档流,并且可以设置其宽高。
不同点:float仍可占据位置,不会覆盖在另一个BFC区域上,浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。absolute会覆盖文档流中的其他元素。

65.CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?

选择符
<1>、id选择器(#myId);
<2>、类选择器(.myClassName);
<3>、标签选择器(div,p,h1);
<4>、相邻选择器(h1 + p);
<5>、子选择器(ul > li);
<6>、后代选择器(li a);
<7>、通配符选择器(*);
<8>、属性选择器(button[disabled="true"]);
<9>、伪类选择器(a:hover,li:nth-child);表示一种状态
<10>、伪元素选择器(li:before、:after,:first-letter,:first-line,:selecton);表示文档某个部分的表现

优先级
!important > 行内样式(比重1000) > id(比重100) > class/属性(比重10) > tag / 伪类(比重1);

伪类和伪元素区别
1>、伪类:a:hover,li:nth-child;
2>、伪元素:li:before、:after,:first-letter,:first-line,:selecton;

65.两个数组合并成一个数组排序返回

先依次比较两个数组,按照小的就传入新的数组。当这次比较完之后可能有一个数组的长度很长,留下一些数组,然后在新数组的末尾插入即可。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

functiongetRes(arr1, arr2){

   var len1 = arr1.length,

       len2 = arr2.length,

       i = 0,

       j = 0,

       k = 0,

       res = new Array(len1+len2);

  

       while(i < len1 && j <len2){

res[k++] = arr[(arr[i] > arr[j]) ? j++ : i++];

}

While(i < len1)   res[k++]= arr1[i++];

While(j < len2)   res[k++]= arr2[j++];

Return res;

}

66.zepto和jquery区别

zepto比jquery体积小很多,移动端的兼容性不需要要考虑很多,jquery中的很多功能都没有。

width()和height()不一样  解决用.css('width')

67.css3动画和jquery动画的差别

1.css3中的过渡和animation动画都是基于css实现机制的,属于css范畴之内,并没有涉及到任何语言操作。效率略高与jQuery中的animate()函数,但兼容性很差。

2.jQuery中的animate()函数可以简单的理解为css样式的“逐帧动画”,是css样式不同状态的快速切换的结果。效率略低于css3动画执行效率,但是兼容性好。‍

68.如何解决ajax无法后退的问题

HTML5里引入了新的API,即:history.pushState, history.replaceState

可以通过pushState和replaceState接口操作浏览器历史,并且改变当前页面的URL。

onpopstate监听后退

69.实现一个once函数

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function test () {console.log('test')}

 

var once = function (fn) {

  var isFirst = true;

  return function () {

    if (isFirst) {

      isFirst = !isFirst;

      fn();

    }

  };

};

 

var b = once(test);

b(); // 'test'

b(); // nothing

 

70.分域名请求图片的原因和好处

浏览器的并发请求数目限制是针对同一域名的,超过限制数目的请求会被阻塞

浏览器并发请求有个数限制,分域名可以同时并发请求大量图片

 

71.页面的加载顺序

html顺序加载,其中js会阻塞后续dom和资源的加载,css不会阻塞dom和资源的加载但是会阻塞js的加载。

浏览器会使用prefetch对引用的资源提前下载

1.没有 defer 或 async,浏览器会立即加载并执行指定的脚本

2.有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(下载异步,执行同步,加载完就执行)。

3.有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

72.生成10个20-50之间的随机数,存在数组中,常见排序方法,数组乱序方法

1

2

3

4

5

6

var arr = [];

for(var i = 0;i<10;i++){

    var num = Math.random()*30 + 20;

    num = parseInt(num, 10);

    arr.push(num);

}

 

1

2

3

arr.sort(function(a,b){

    return 0.5 - Math.random();

})

73.计算机网络的分层概述

tcp/ip模型:从下往上分别是链路层,网络层,传输层,应用层

osi模型:从下往上分别是物理层,链路层,网络层,传输层,会话层,表示层,应用层。

73.jscss缓存问题

浏览器缓存的意义在于提高了执行效率,但是也随之而来带来了一些问题,导致修改了js、css,客户端不能更新

都加上了一个时间戳作为版本号

<script type=”text/javascript” src=”{JS文件连接地址}?version=XXXXXXXX”></script>

74.setTimeout,setInterval,requestAnimationFrame之间的区别

setInterval如果函数执行的时间很长的话,第二次的函数会放到队列中,等函数执行完再执行第二次,导致时间间隔发生错误。

而settimeout一定是在这个时间定时结束之后,它才会执行

requestAnimationFrame是为了做动画专用的一个方法,这种方法对于dom节点的操作会比较频繁。

75.webpack常用到哪些功能

设置入口  设置输出目 设置loader  extract-text-webpack-plugin将css从js代码中抽出并合并 处理图片文字等功能 解析jsx解析bable

76.介绍sass

&定义变量 css嵌套 允许在代码中使用算式 支持if判断for循环

77.websocket和ajax轮询

Websocket是HTML5中提出的新的协议,注意,这里是协议,可以实现客户端与服务器端的通信,实现服务器的推送功能。

其优点就是,只要建立一次连接,就可以连续不断的得到服务器推送的消息,节省带宽和服务器端的压力。

ajax轮询模拟长连接就是每个一段时间(0.5s)就向服务器发起ajax请求,查询服务器端是否有数据更新

其缺点显而易见,每次都要建立HTTP连接,即使需要传输的数据非常少,所以这样很浪费带宽

78.tansition和margin的百分比根据什么计算

transition是相对于自身,margin相对于参照物

 79.冒泡排序、快速排序、去重、查找字符串最多值

1

2

3

4

5

6

7

8

9

10

11

12

13

//冒泡排序

var bubbleSort = function(arr) {

   for (var i = 0; i < arr.length-1; i++) {

     for (var j = i+1; j < arr.length; j++) {

       if (arr[i]>arr[j]) {

         var temp = arr[i];

         arr[i] = arr[j];

         arr[j] = temp;

       }

     }

   }

   return arr;

};

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

//快速排序

var quickSort = function(arr) {

  if (arr.length <= 1) {

    return arr;

  }

  var len = arr.length;

  var midIndex = Math.floor(len/2);

  var mid = arr.splice(midIndex,1);

  var left = [];

  var right = [];

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

    if (arr[i] < mid) {

      left.push(arr[i]);

    else {

      right.push(arr[i]);

    }

  }

  return quickSort(left).concat(mid,quickSort(right))

}

  

1

2

3

4

5

6

7

8

9

10

11

12

// 去重

 var distinct = function(arr) {

   var map = {};

   var result = [];

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

      if (!map[arr[i]]) {

        map[arr[i]] = true;

        result.push(arr[i]);

      }

   }

   return result;

 }

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

//查找字符串中最多的值

var search = function(str) {

  var json = {};

  var max = 0;

  var char;

  for (var i = 0; i < str.length; i++) {

    if (!json[str[i]]) {

      json[str[i]]=1;

    else {

      json[str[i]]++;

    }

  }

  console.log(json);

  for(var in json){

        if(json[i]>max){

                max = json[i];

                char = i;

        }

}

  console.log(max, char);

}

 80.函数组合继承

原型继承、构造函数继承、call aplly继承

1

2

3

4

5

6

7

8

9

var Super = function(name){

  this.name = name;

}

Super.prototype.func1 = function() { console.log('func1'); }

var Sub = function(name,age) {

  Super.call(this, name);

  this.age = age;

}

Sub.prototype = new Super();

 81.事件绑定

1

2

3

4

5

6

7

8

9

var addEvent = function(e, type, handler, capture ) {

  if (e.addEventListener) {

    e.addEventListener(type, handler, capture);

  else if (e.attachEvent) {

    e.attachEvent('on'+type, handler);

  else {

    e['on'+type] = handler;

  }

}

82.浅克隆和深度克隆

 

1

2

3

4

5

6

7

8

9

//浅克隆

function extendCopy(p) {

    var c = {};

    for (var in p) {

      c[i] = p[i];

    }

    c.uber = p;

    return c;

 }

1

 

1

2

3

4

5

6

7

8

//深度克隆

var clone = function(v) {

  var o = v.constructor === Array ? [] : {};

  for (var in v) {

    o[i] = typeof v[i] === "Object" ? clone(v[i]) : v[i];

  }

  return o;

}

es6的深度克隆

通过Object.getPrototypeOf函数得到obj被克隆函数的原型上的属性,然后通过Object.assign实现深度克隆。

 

1

2

3

4

const deepClone=(obj)=>{

   var proto=Object.getPrototypeOf(obj);

   return Object.assign({},Object.create(proto),obj);

}

 

83.实现一个秒针绕一点转动的效果

1

2

3

4

5

6

7

8

9

10

11

12

  animation: move 60s infinite steps(60); 

 /*设置旋转的中心点为中间底部*/ 

  transform-origin: center bottom; 

/*旋转从0度到360度*/ 

@keyframes move { 

    from { 

        transform: rotate(0deg); 

    

    to { 

        transform: rotate(360deg); 

    

84.移动端兼容问题

IOS移动端click事件300ms的延迟响应

一些情况下对非可点击元素如(label,span)监听click事件,ios下不会触发,css增加cursor:pointer就搞定了

85.bootstrap的栅格系统如何实现的

 

box-sizing: border-box;
container row column设置百分比

 

85.js基本类型及判断方法

null, undefined,bool,number,string,object,symbol(es6 独一无二)

1.typeof()出来的没有null 对象,数组和null typeof(x) = "object"

2.instanceof() 对象的原型是否在对象的原型链上

如下:判断Person的原型是否在p的原型链上

1

2

3

function Person(){};

var p =new Person();

console.log(p instanceof Person);//true

3.Object.prototype.toString.call()

每种对象对toString都进行了改写,只有Object.prototype.toString.call(obj)可以进行类型判断

1

2

3

4

var a=new Number(12);

var toString=Object.prototype.toString;

console.log(toString.call(a));//'[object Number]''

console.log(a.toString());//'12'

  

86 JavaScript为什么是单线程?eventloop

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

异步执行:

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。

node里的process.nextTick指定的回调函数是在本次”事件循环”触发,而setImmediate指定的是在下次”事件循环”触发,所以很显然,前者总是比后者发生得早,而且执行效率也高。

 

87 http http2 https

http(超文本传输协议)是一种常用于应用层的协议,它是基于文本传输内容。

https可以称为http安全版,主要是http下增加了SSL(安全套接层)或者TSL(传输层安全),在SSL或TSL在传输层对数据进行了加密处理。

http/2(超文本传输协议第二版),他对http进行了一些升级改造

  • 新的二进制格式
  • 多路复用
  • header压缩
  • 支持server push

 87  枚举

 

 

88  meta属性

1.name 网页描述

<meta name="参数" content="描述内容">

a.keword

b.description

c.viewport

2.http-equiv http相关描述

<meta http-equiv="参数" content="描述内容">

a.content-type

b.cache-control

c.expires

89 react 相关

react router:

实现URL与UI界面的同步。其中在react-router中,URL对应Location对象,而UI是由react components来决定的,这样就转变成location与components之间的同步问题。

react事件:

React并不是将click事件绑在该div的真实DOM上,而是在document处监听所有支持的事件,当事件发生并冒泡至document处时,React将事件内容封装并交由真正的处理函数运行。

90 js css加载顺序

js全阻塞,css半阻塞

  1. JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载。
  2. CSS 不会阻塞后续 DOM 结构的解析,不会阻塞其它资源(如图片)的加载,但是会阻塞 JS 文件的加载。
  3. 现代浏览器很聪明,会进行 prefetch 优化,浏览器在获得 html 文档之后会对页面上引用的资源进行提前下载。

js为什么阻塞?

  1. JS 运行在浏览器中,是单线程的,每个 window 一个 JS 线程,所以当然会阻塞后续 DOM 树的解析咯。
  2. JS 有可能会修改 DOM 结构,给 DOM 添加样式等等,所以这就意味着在当前 JS 加载执行完成前,后续资源的加载可能是没有意义的

css为什么阻塞js?

JS 代码在执行前,浏览器必须保证在 JS 之前的所有 CSS 样式都解析完成,不然不就乱套了,前面的 CSS 样式可能会覆盖 JS 文件中定义的元素样式,这是 CSS 阻塞后续 JS 执行的根本原因。

defer,async?

JS 会阻塞后续 DOM 解析以及其它资源(如 CSS,JS 或图片资源)的加载,这是在没有考虑到 defer, async 的情况下。

  1. 由于现代浏览器都存在 prefetch,所以 defer, async 可能并没有太多的用途,可以作为了解扩展知识,仅仅将脚本文件放到 body 底部就可以起到很不错的优化效果。
  2. defer 和 async 都是异步加载脚本文件,defer异步加载,最后执行。
  3. 慎用 async,因为它完全不考虑依赖关系,只要下载完后就加载,不考虑此时页面样式先后的加载顺序,不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics。
  4. 耗时较长的脚本代码可以使用 defer 来推迟执行。

 91. 三次握手四次挥手

第一次握手:客户端请求与服务端建立连接。第二次:服务端返回确认信息。第三次:客户端收到。

客户:喂?你在吗?我想跟你聊会儿天儿!(发送SYN请求同步报文)

服务:好的,我听着呢(发送SYN请求同步报文,意思是说,咱俩同步着呢),你说吧!(发送ACK确认报文,即可以说了)

客户:好的!(发送ACK确认报文,开始吐槽XXXX)

 

第一次挥手:客户端传完了,想要断开连接。第二次:服务端收到,半关闭状态。第三次:服务端没信息发了,发送结束报文。第四次:客户端确认,关闭。

然后客户有事儿要挂电话了,又有了下面一段对话,即四次挥手:

客户:我有事儿要挂电话了!(发送Fin结束报文,1次挥手)

服务:好吧(发送ACK确认报文,2次挥手),对了,还有个事儿要跟你说!

......

服务:好了,就这些了,挂了吧!(发送Fin结束报文,3次挥手)

客户:行,挂了吧!(发送ACK确认报文,4次挥手)

服务挂断电话.....

2MSL后......

客户:喂,你还在吗?

啪!(这才断开连接)

 为什么四次挥手?

当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。

但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,

原文https://www.cnblogs.com/bhan/p/6802644.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在2023年的前端面试中,可能会涉及到以下几个高频面试题: 1. 浏览器兼容性问题及解决方案:面试官可能会询问你在开发过程中遇到的浏览器兼容性问题以及你是如何解决的。你可以提到一些常见的兼容性问题,比如不同浏览器对CSS属性的支持不一致或JavaScript API的兼容性问题。解决方案可以包括使用CSS前缀、Polyfill库或检测浏览器特性并提供不同的代码实现。 2. 前后端接口文档和接口测试:你可能会被问到在前端开发中如何与后端协作。你可以提到根据后端提供的接口文档进行开发,使用工具(比如Postman)测试接口的可用性和返回值是否符合预期。同,你还可以提到与后端沟通以了解前端需要的参数和数据结构。 3. 跨域问题及解决方案:面试官可能会问到前端如何实现跨域。你可以解释浏览器的同源策略以及由此带来的限制。然后提到一些解决方案,如使用JSONP、CORS(跨源资源共享)、代理服务器或反向代理等。 综上所述,2023年前端面试可能涉及浏览器兼容性问题及解决方案、前后端接口文档和接口测试、跨域问题及解决方案等。记住在回答面试问题,要清晰、简洁地说明问题和解决方案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [2023高频前端面试题总结(附答案)](https://blog.csdn.net/weixin_45102366/article/details/125525247)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [2023高频前端面试题(含答案)](https://blog.csdn.net/weixin_44672169/article/details/116011608)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值