前端面试无非包含css、js、框架、我的项目等几大方面。以下是本人在面试过程中对于js被问到的问题,有的偏根底,也有比拟深刻的,了解这些问题不仅仅有助于面试,最重要的是可能在理论过程中尽可能少开发些BUG。当初记个笔记,临时没有分类,想到哪个记哪个。。
一、url输出浏览器后干了些什么事件?

1.DNS(Domain Name System, 域名零碎) 解析

  • DNS解析的过程就是寻找哪台机器上有你真正须要的资源过程。
  • 当咱们在浏览器地址栏中输出一个地址时,例如:baidu.com,其实不是百度网站真正意义上的地址,因为互联网上每一台计算机的惟一标识是他的IP地址,然而IP地址并不不便记忆。
  • 所以互联网设计者须要在用户的方便性与可用性做一个衡量,这个衡量就是一个网址到IP地址的转换,这个过程就是DNS解析
  • 它(DNS解析)实际上充当了一个翻译的角色,实现了网址到IP地址的转换。当然如果你间接输出的是另一台电脑的IP地址来拜访,那么不存在这一步

2.TCP连贯(三次握手)

晓得了服务器的IP地址,就开始和服务器简历连贯了。连贯的建设须要经验三次握手(两个在)
  • 第一次握手: 建设连贯时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT,期待服务器确认.
  • 第二次握手: 服务器收到syn包,必须确认客户的SYN(ack=j+1),同时本人发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
  • 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送结束,客户端和服务器进入ESTABLISHED(TCP链接胜利状态),实现三次握手

3.发送HTTP申请

当服务器与主机建设了链接当前,留神开始和服务器进行通信.网页申请是一个单向申请的过程.即一个主机向服务器申请数据,服务器返回相应的数据的过程.浏览器依据URL内容生成HTTP申请,HTTP申请报文是由三局部组成:申请行,申请报头,申请注释.

4.服务器解决申请并返回HTTP报文

服务器接到申请后,会依据HTTP申请中的内容来决定如何获取相应的HTML文件,服务器失去的HTML文件发送给浏览器.HTTP响应报文也是由三局部组成:状态码,响应头,响应报文.
  • 状态码

    • 1xx: 批示信息,标示申请已接管,急需处理.
    • 2xx: 胜利信息,标示申请已被胜利接管,了解,接管
    • 3xx: 重定向,要实现申请必须进行更进一步的操作
    • 4xx: 客户端谬误,申请有语法错误或申请无奈实现
    • 5xx: 服务器端谬误,服务器未能实现非法的谬误
  • 响应头

    • 常见的响应头字段有:Server,Connection..
  • 响应报文

    • 服务器返回给浏览器的文本信息。HTML,CSS,JS,图片等文件就放在这一部分

5.浏览器解析渲染页面

在浏览器还没有在齐全承受HTML文件时便开始渲染,显示网页
在执行HTML中的代码时,依据须要,浏览器会持续申请图片,CSS,JavaScript等文件.过程同申请HTML

6.连贯完结


7.四次回收连贯

  • 客户端过程收回连贯开释报文,并且进行发送数据。开释数据报文首部.FIN=1,其序列号为seq=u(依据后面曾经传过来的数据的最初一个序号+1)。此时客户端进入FIN-WAIT-1(终止期待1)状态。TCP规定,FIN报文段即便不携带数据,也要耗费一个序号
  • CLOSE-WAIT状态继续期间。服务器收到连贯开释报文,收回确认报文ACK=1,ack=u+1,并且带上本人的序列号seq=v此时,服务端就退出了CLOSE-WAIT(敞开-期待)状态。这时连贯处于半敞开状态,客户端曾经没有数据要发送了。然而服务器若发送数据,客户端依然接管。这个状态还要继续一段时间,也就是整个CLOSE-WAIT状态继续的工夫
  • 客户端收到服务器的确认申请后,就进入FIN-WAIT-2(终止期待2)状态,期待服务器发送连贯开释报文(在这之前还须要接管服务器发送的最初数据)
  • 服务器将最初的数据发送结束后,就像客户端发送连贯开释报文:FIN=1,ack=u+1。因为在半敞开状态,服务器很可能又发送了一些数据,假设此时的序列号为seq=w,此时服务器就进入了LAST-ACK(最初确认)状态,期待客户端的确认
  • 客户端收到服务器的连贯开释报文后,必须收回确认:ACK=1,ack=w+1。而本人的序列号是seq=u+1,此时客户端进入了TIME-WAIT(工夫期待)状态。留神此时TCP连贯没有开释,必须通过2MSL(最长报文段寿命)的工夫后,当客户端撤销相应的TCB后,才进入CLOSED状态
  • 服务器只有收到客户端收回的确认,立刻进入CLOSED状态。同样,撤销TCB后,就完结了这次TCP连贯。能够看到,服务器完结TCP连贯的工夫比客户端要更早一些

8.对于TCP三次握手及相干面试题可参考:https://www.cnblogs.com/bj-mr-li/p/11106390.html

二、http协定理解多少?
  • 只是理解下的话这篇文章足够:https://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html
  • PS:各种申请形式及其含意
申请形式含意
GET申请获取Request-URI所标识的资源
POST在Request-URI所标识的资源后附加新的数据
PUT申请服务器存储一个资源,并用Request-URI作为其标识
DELETE申请服务器删除Request-URI所标识的资源
HEAD申请获取由Request-URI所标识的资源的响应消息报头
TRACE申请服务器回送收到的申请信息,次要用于测试或诊断
CONNECT保留未来应用
OPTIONS申请查问服务器的性能,或者查问与资源相干的选项和需要
三、webpack打包

https://segmentfault.com/a/1190000016068450

四、性能优化

性能优化太宽泛了,我总结了下本人在理论开发中用到的优化伎俩,大略有以下几个方面:

  • 图片--雪碧图、svg雪碧图、webpack插件优化、第三方工具压缩图片
  • 三方库优化--按需(lodash、echarts)、懒加载
  • CDN引入
  • HTML--语义化标签
  • JS/TS--代码精简-公共函数封装、页面优化-节流/防抖等
五、冒泡排序法
  • 冒泡排序(更多js排序算法:https://www.cnblogs.com/ybygb-geng/p/9355425.html)
原理:把一个数组中的每一个数从前往后顺次进行比拟,而后依据大小替换地位,每一轮的比拟都确定出一个当轮比拟的最大值,最终实现数组的大小排序
var arr = [4,23,100,9,7,49,36,57];console.log("原始数据:"+arr);for (var i = 0; i < arr.length-1; i++) { //确定轮数    for (var j = 0; j < arr.length-i-1; j++) { //确定每次比拟的次数        if (arr[j] > arr[j+1]) {            tem = arr[j];            arr[j] = arr[j+1];            arr[j+1] = tem;        }    }    console.log("第"+i+"次排序"+arr)}console.log("最终排序:"+arr)
console控制台打印如下:
六、一行代码实现数组去重
办法一:ES6 Set数据结构。其相似于数组,然而它的成员都是惟一的 ,其构造函数能够承受一个数组作为参数
 let array = [1, 1, 1, 1, 2, 3, 4, 4, 5, 3]; let set = new Set(array); console.log(set); // => Set {1, 2, 3, 4, 5}
办法二:ES6中Array新函数:Array.from
let array = Array.from(new Set([1, 1, 1, 2, 3, 2, 4]));console.log(array);// => [1, 2, 3, 4]
办法三:应用三方库,如:lodash
var list= [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];list = lodash.uniqWith(list, lodash.isEqual)// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]

七、解构赋值

  • 解构赋值是对赋值运算符的扩大。
  • 它针对数组或者对象进行模式匹配,而后对其中的变量进行赋值。
  • 在代码书写上简洁且易读,语义更加清晰明了;也不便了简单对象中数据字段获取。
  • 在解构中,有两局部参加:解构的源,解构赋值表达式的左边局部;解构的指标,解构赋值表达式的右边局部
数组模型的解构(Array)
// 根本let [a, b, c] = [1, 2, 3]; // a = 1 // b = 2 // c = 3// 可嵌套let [a, [[b], c]] = [1, [[2], 3]]; // a = 1 // b = 2 // c = 3// 可疏忽let [a, , b] = [1, 2, 3]; // a = 1 // b = 3// 不齐全解构let [a = 1, b] = []; // a = 1, b = undefined// 残余运算符let [a, ...b] = [1, 2, 3]; //a = 1 //b = [2, 3]/* 字符串等 */// 在数组的解构中,解构的指标若为可遍历对象,皆可进行解构赋值。可遍历对象即实现 Iterator 接口的数据。let [a, b, c, d, e] = 'hello'; // a = 'h' // b = 'e' // c = 'l' // d = 'l' // e = 'o'// 解构默认值let [a = 2] = [undefined]; // a = 2// 当解构模式有匹配后果,且匹配后果是 undefined 时,会触发默认值作为返回后果。let [a = 3, b = a] = []; // a = 3, b = 3 let [a = 3, b = a] = [1]; // a = 1, b = 1 let [a = 3, b = a] = [1, 2]; // a = 1, b = 2// a 与 b 匹配后果为 undefined ,触发默认值:a = 3; b = a =3// a 失常解构赋值,匹配后果:a = 1,b 匹配后果 undefined ,触发默认值:b = a =1// a 与 b 失常解构赋值,匹配后果:a = 1,b = 2
对象模型的解构(Object)
// 根本let { foo, bar } = { foo: 'aaa', bar: 'bbb' }; // foo = 'aaa' // bar = 'bbb' let { baz : foo } = { baz : 'ddd' }; // foo = 'ddd'// 可嵌套可疏忽let obj = {p: ['hello', {y: 'world'}] }; let {p: [x, { y }] } = obj; // x = 'hello' // y = 'world' let obj = {p: ['hello', {y: 'world'}] }; let {p: [x, { }] } = obj; // x = 'hello'// 不齐全解构let obj = {p: [{y: 'world'}] }; let {p: [{ y }, x ] } = obj; // x = undefined // y = 'world'// 残余运算符let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}; // a = 10 // b = 20 // rest = {c: 30, d: 40}// 解构默认值let {a = 10, b = 5} = {a: 3}; // a = 3; b = 5; let {a: aa = 10, b: bb = 5} = {a: 3}; // aa = 3; bb = 5;
八、js原型链
  • 简略一行代码示意(详见我另一篇文章js原型及原型链):
function Person() {};var p = new Person();p.__proto__ === p.contructor.prototype // p.contructor就是Person,所以上述代码也能够是:p.__proto__ === Person.prototype 
九、 js是同步还是异步,单线程还是多线程,操作原理
十、数据结构理解吗?讲一下链表?
十一、跨域如何解决
十二、js原生轮播插件如何制作
十三、js数组去重,数组罕用api
十四、ajax的过程、xmlhttprequest对象