2020年各大厂以及热门的前端面试题集锦

前言

2020年注定是一个不平凡的一年,现在所在的创业公司也岌岌可危,不得不在这种情况下为自己提前准备好新的出路。从4月13号便开始着手准备 中高级的前端面试,只是面试结果并不太理想。一来是因为受到疫情期的影响,绝大多数的公司的在大规模裁员,更别说招人了。二来也是因为自身的技术和基础并没有达到一个高的水准所导致。现决定把面试时出现频率较高和比较有意义的题目都记录下来并弄清楚,希望能够顺利通过面试的同时,切实提升自身的原理性基础知识水平。

http相关的面试题

我记得在两年前的时候,前端面试极少会有面试官会去问关于http的一些问题,可是最近发现,几乎每一个面试官都会或多或少去询问你对http/https的理解

1. http和https的区别 (百度)

http是基于tcp协议的,https是基于ssl协议的,ssl协议在tcp协议的基础上的做了一层加密认证。 https比http传输数据更安全,http是明文传递数据,不安全;而https传输数据经过加密。 https需要证书来验证身份,证书需要购买,http不需要。 https默认端口号是443,http默认是80。 https不能向http发出请求。

2. http的请求过程 (苏宁)

浏览器发起请求-> 解析域名得到ip进行TCP连接 ->浏览器发送HTTP请求和头信息发送->服务器对浏览器进行应答,响应头信息和浏览器所需的内容-> 关闭TCP连接或保持-> 浏览器得到数据数据进行页面渲染

3. http的缓存机制 (百度、滴滴都有问)

强缓存:
响应报文头: catch-control:max-age=212121;(最长生效时常212121,默认300)。
expires:服务器绝对时间

catch-control:客户端发请求前,会用当前客户端时间与 (上次请求时间+max-age)进行比较,命中则走缓存。 (HTTP1.1)
expires:expires是一个绝对时间,采用的是服务器的。客户端发送请求前,用客户端时间与这个时间进行比较,命中则走缓存。(如果浏览器不支持HTTP1.1,则用expires判断是否过期)
max-age优先级比expires高,并且更加靠谱;

弱缓存(协商缓存):
响应报文头: last-modified:最后一次修改时间
Etag:当前请求的资源生成的一个唯一标识,只要资源不一样这个串就不一样
请求报文头:
if-modified-since:缓存中文件的最后修改时间
if-None-Match:缓存中文件的etag

客户端发出请求,携带if-modified-since,if-None-Match字段,服务器收到请求 与当前文件的最后修改时间和重新生成etag进行比较,命中则返回304;
如果命中if-none-match,返回304的响应头中,会携带服务器最新生成的etag;
如果命中if-modified-since则304响应头中不会携带last-modified,因为最后修改时间没有改变。

ETag和Last-Modified的作用和用法,他们的区别:

1.Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;

2.在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值;

3.在优先级上,服务器校验优先考虑Etag。

浏览器缓存过程

1.浏览器第一次加载资源,服务器返回200,浏览器将资源文件从服务器上请求下载下来,并把response header及该请求的返回时间一并缓存;

2.下一次加载资源时,先比较当前时间和上一次返回200时的时间差,如果没有超过cache-control设置的max-age,则没有过期,命中强缓存,不发请求直接从本地缓存读取该文件(如果浏览器不支持HTTP1.1,则用expires判断是否过期);如果时间过期,则向服务器发送header带有If-None-Match和If-Modified-Since的请求

3.服务器收到请求后,优先根据Etag的值判断被请求的文件有没有做修改,Etag值一致则没有修改,命中协商缓存,返回304;如果不一致则有改动,直接返回新的资源文件带上新的Etag值并返回200;;

4.如果服务器收到的请求没有Etag值,则将If-Modified-Since和被请求文件的最后修改时间做比对,一致则命中协商缓存,返回304;不一致则返回新的last-modified和文件并返回200;

4. http的常用状态码

2xx (3种)

200 OK:表示从客户端发送给服务器的请求被正常处理并返回;

204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);

206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。

3xx (5种)

301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;

302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;

   301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)

303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;

  302与303的区别:后者明确表示客户端应当采用GET方式获取资源

304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;

307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);

4xx (4种)

400 Bad Request:表示请求报文中存在语法错误;

401 Unauthorized:未经许可,需要通过HTTP认证;

403 Forbidden:服务器拒绝该次访问(访问权限出现问题)

404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;

5xx (2种)

500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;
502 Bad Gateway : 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应;
503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;

5. 常见的请求头中的字段和响应头中的字段

请求头:
Accept: application/json, text/javascript, /; q=0.01 //告诉服务器,客户端支持的数据类型
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 //告诉服务器,发送的数据类型 Origin: https://baidu.com //源
Referer: https://baidu.com/ //源页面
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36 // 浏览器信息
cookie:’’, //cookie信息
if-modified-since:xxxxx //上次请求响应头返回的最后修改时间
if-none-match:xxx //上次请求响应头返回的etag信息

响应头:
Access-Contronl-Allow-origin:* ,//允许源访问
access-control-allow-methods:get ,post //允许请求方式
access-control-allow-headers:‘name’ //允许携带的请求头
access-control-expose-headers:‘name’ //允许浏览器读取的头信息
access-control-allow-credentials:true //表示服务器允许浏览器携带cookie发送
content-type: application/json 响应数据格式
date: Tue, 02 Apr 2019 16:30:02 GMT //服务器时间
catch-control:max-age=36000 //强缓存最强生效时长
expires:xx-xx-xx //服务器失效绝对时间
last-modified:xxx-xxx-xx //服务器最后修改时间
etag:xxxxxx //服务器资源唯一标示符
options Access-Control-Max-Age:秒, 本次预检请求的有效期

6. 复杂请求的与简单请求的区别

复杂请求 会比 简单请求多一个options请求(预检查请求)

简单请求: 浏览器请求头中会默认增加origin字段,表示来自哪个源 服务器接收请求后,根据指定的源作出回应。 响应头中:Access-Control-Allow-Origin:* || domain Access-Control-Allow-Credentials:true, //表示是否允许跨域携带cookie。(后续进行讲解) Access-Control-Expose-Headers:xxx //指定浏览器可以获取到的 自定义响应头

非简单请求: 出现条件:请求方法是PUT或DELETE, Content-Type字段的类型是application/json 增加额外的header字段;
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"options请求(preflight)
浏览器发出options请求头: origin:源 Access-Control-Request-Method:,用来列出浏览器的CORS请求会用到哪些HTTP方法 Access-Control-Request-Headers:浏览器CORS请求会额外发送的头信息字段
服务器返回options响应头: Access-Control-Allow-Origin: http://api.bob.com Access-Control-Allow-Methods: GET, POST, PUT 服务器支持的所有跨域请求的方法 Access-Control-Allow-Headers: X-Custom-Header 表示服务器支持的所有头信息字段 Access-Control-Max-Age:秒, 本次预检请求的有效期
服务器如果否定了options请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。浏览器就 会认定,服务器不同意预检请求,因此触发一个错误,被XMLHttpRequest对象的onerror回调函数捕获。

withCredentials属性 :
cors请求不会发送cookie,如果要发送cookie到服务器,一方面要服务器同意。
Access-Control-Allow-Origin:不能设置*号,必须指定和明确的、与请求网页一致的域名
Access-Control-Allow-credentials:true;//这个只能设为true;如果不需要cookie,则删除该字段即可。

7. TCP三次握手

在这里插入图片描述建立连接协议(三次握手):
第一次握手:客户端发送syn包(syn=x)的数据包到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP连接都将被一直保持下去。

JS相关面试题

1. 什么是闭包,说下项目中应用场景?(又是它,还是它,总是它)

闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
场景:
1.可以实现公有变量,函数外或在其他函数中访问某一函数内部的参数

function add() { 
	var num = 0; 
	function demo(){ 
		num++; 
		console.log(num); 
	} 
	return demo; 
} 
var test = add(); 
test();//1 
test();//2`

2.为节点循环绑定click事件,在事件函数中使用当次循环的值或节点,而不是最后一次循环的值或节点

var a = document.getElementsByTagName("a");
for(var i =0; i<a.length; i++){ 
   a[i].onclick = (function(i){
        return function(){alert(i);}
   })(i);
}

3.计数器

function checkCount(target) {
        let count = 0
        const callbacks = []
        return function(fn) {
          count++
          if (count == target) {
            callbacks.forEach(fn => fn())
          } else {
            callbacks.push(fn)
          }
        }
      }
      const d = checkCount(3)
      d(fn)
      d(fn)
      d(n)

4.函数节流和防抖

2. 节流和防抖

防抖原理:
函数防抖是指在函数被高频触发时当停止触发后延时n秒再执行函数(即每次触发都清理延时函数再次开始计时),一般用于resize,scroll,mousemove等

function debounce(fn) {
      let timeout = null; // 创建一个标记用来存放定时器的返回值
      return function () {
        clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
        timeout = setTimeout(() => { // 然后又创建一个新的 setTimeout, 这样就能保证输入字符后的 interval 间隔内如果还有字符输入的话,就不会执行 fn 函数
          fn.apply(this, arguments);
        }, 500);
      };
    }
    function sayHi() {
      console.log('防抖成功');
    }

    var inp = document.getElementById('inp');
    inp.addEventListener('input', debounce(sayHi)); // 防抖

节流原理:
函数被高频触发时延时n秒后才会再次执行。

function throttle(fn) {
      let canRun = true; // 通过闭包保存一个标记
      return function () {
        if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
        canRun = false; // 立即设置为false
        setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
          fn.apply(this, arguments);
          // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。当定时器没有执行的时候标记永远是false,在开头被return掉
          canRun = true;
        }, 500);
      };
    }
    function sayHi(e) {
      console.log(e.target.innerWidth, e.target.innerHeight);
    }
    window.addEventListener('resize', throttle(sayHi));

3. 讲一下js循环事件池event loop,微任务和宏任务 (boss直聘、小米,苏宁)

1.浏览器的event loop
浏览器的event loop执行会存在一个执行栈,当前执行的同步代码都会放到执行栈中执行(宏任务); 同步代码执行过程中,如果遇到异步代码(settIimeout、promise等),会将他们挂起,继续执行同步代码; 同步代码执行完毕后,执行栈清空,会去查看微任务队列是否有可执行函数,然后拿到执行栈执行; 当微任务队列执行完成后, 会去宏任务取一个任务放到执行栈执行,执行完成后再去查看微任务是不是有可执行函数, 有的话取到执行栈执行;如此循环下去,就是event loop;
挂起的异步代码,可执行后,会放到异步任务队列;异步任务队列分为两种队列,一种是微任务(promise,process.nextTick) 一种是宏任务(setTimeout等); 微任务包括 process.nextTick ,promise ,MutationObserver。 宏任务包括 script , setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。

过程: 执行完主执行线程中的任务。 取出Microtask Queue中任务执行直到清空。 取出Macrotask Queue中一个任务执行。 取出Microtask Queue中任务执行直到清空。 重复3和4。

4. js中的this是如何工作的

调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数。除了声明时定义的形式参数,每个函数还接收两个附加的参数:this和arguments。参数this在面向对象编程中非常重要,它的值取决于调用的模式。在JavaScript中一个有4中调用模式:方法调用模式函数调用模式构造器调用模式apply调用模式。这些模式在如何初始化关键参数this上存在差异。

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值