程序员的资源宝库

网站首页 > gitee 正文

前端面试总结

sanyeah 2024-04-25 18:47:07 gitee 8 ℃ 0 评论

HTML

CSS

元素水平垂直居中的方法

水平垂直居中

1.flex

.outer {
  display: flex;
  justify-content: center; /* 水平居中 */
  align-items: center; /* 垂直居中 */
}

2.absolute + transform

.outer {
  position: relative;
}

.inner {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

3.absolute + calc(需要固定居中元素的宽高)

.outer {
  position: relative;
}

.inner {
  position: absolute;
  left: calc(50% - 50px);
  top: calc(50% - 50px);
}

4.absolute + 负margin(需要固定居中元素的宽高)

.outer {
  position: relative;
}

.inner {
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -50px;
  margin-top: -50px;
}

5.absolute + margin: auto(需要固定居中元素的宽高,否则其宽高会被设为 100%)

.outer {
  position: relative;
}

.inner {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
}

水平居中

1.margin: auto(需要固定局中元素的宽)

.inner {
  display: block; /* 还可以是 table | flex | grid,但不能是 inline-xxx */
  margin: 0 auto;
}

2.text-align + inline-block

.outer {
  text-align: center;
}

.inner {
  display: inline-block;
  text-align: left; /* 重置文字位置(如果需要) */
}

垂直居中

1.table-cell + vertical-align

.outer {
  display: table-cell;
  vertical-align: middle;
}

2.inline-block + line-height

.outer {
  line-height: 300px; //父元素高度
}

.inner {
  line-height: initial; /* 重置 */
  vertical-align: middle;
  display: inline-block;
}

less

1.声明变量 @baseColor:#fff
2.运算
3.代码嵌套
4.mixin extend 代码块,减少重复代码

.block(@baseColor){
   background-color:@baseColor;
   position:relative;
}
.div{
   .block(@baseColor);
}
.block{
   background-color:@baseColor;
   position:relative;
}
.div:extend(.block){
}

5.import模块化 @import "library"; // library.less 后缀名可带可不带
6.使用 ~ 禁止编译
7.使用 JavaScript 表达式

通过反引号的方式可以再 LESS 中使用 JavaScript 表达式。

@var: `"hello".toUpperCase() + '!'`; // 结果:HELLO!

JS

实现compose函数

compose函数可以将需要嵌套执行的函数平铺,嵌套执行就是一个函数的返回值将作为另一个函数的参数。
const compose = (...args) => x => args.reduceRight((res, cb) => cb(res), x);

实现pipe函数

pipe函数跟compose函数的作用是一样的,也是将参数平铺,只不过他的顺序是从左往右。
const pipe = (...args) => x => args.reduce((res, cb) => cb(res), x)

实现缓存函数

有时候一个复杂的计算函数需要反复运行,如果每次都对他进行计算,会浪费大量性能,我们可以用一个记忆函数来缓存计算过的值,比较典型的就是斐波拉契数列:

  const fibonacci = (x) => {
      if (x === 1 || x === 2) {
        return 1;
      }
      return fibonacci(x - 1) + fibonacci(x - 2);
    };
    const memo = (fn) => {
      const cache = {};
      return (x) => {
        if (!cache[x]) {
          cache[x] = fn(x);
        }
        return cache[x];
      };
    };
    const cachedfFibonacci = memo(fibonacci);
    // 然后看下效果
    let startTime = new Date().getTime();
    cachedfFibonacci(40);
    let needTime = new Date().getTime() - startTime;
    console.log(needTime); // 第一次运行时间还是959毫秒

    // 再调一次
    startTime = new Date().getTime();
    cachedfFibonacci(40);
    needTime = new Date().getTime() - startTime;
    console.log(needTime); // 时间直接变为0了,直接取缓存,快到1毫秒都不要

柯里化函数

柯里化就是将一个接收多个参数的函数转化为一系列使用一个参数的函数的技术。

网络

TCP和UDP的区别

HTTP协议

HTTP 1.0
HTTP 1.0 是在 1996 年引入的,从那时开始,它的普及率就达到了惊人的效果。
HTTP 1.0 仅仅提供了最基本的认证,这时候用户名和密码还未经加密,因此很容易收到窥探。
HTTP 1.0 被设计用来使用短链接,即每次发送数据都会经过 TCP 的三次握手和四次挥手,效率比较低。
HTTP 1.0 只使用 header 中的 If-Modified-Since 和 Expires 作为缓存失效的标准。
HTTP 1.0 不支持断点续传,也就是说,每次都会传送全部的页面和数据。
HTTP 1.0 认为每台计算机只能绑定一个 IP,所以请求消息中的 URL 并没有传递主机名(hostname)。
HTTP 1.1
HTTP 1.1 是 HTTP 1.0 开发三年后出现的,也就是 1999 年,它做出了以下方面的变化
HTTP 1.1 使用了摘要算法来进行身份验证
HTTP 1.1 默认使用长连接,长连接就是只需一次建立就可以传输多次数据,传输完成后,只需要一次切断连接即可。长连接的连接时长可以通过请求头中的 keep-alive 来设置
HTTP 1.1 中新增加了 E-tag,If-Unmodified-Since, If-Match, If-None-Match 等缓存控制标头来控制缓存失效。
HTTP 1.1 支持断点续传,通过使用请求头中的 Range 来实现。
HTTP 1.1 使用了虚拟网络,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。
HTTP 2.0
HTTP 2.0 是 2015 年开发出来的标准,它主要做的改变如下
头部压缩,由于 HTTP 1.1 经常会出现 User-Agent、Cookie、Accept、Server、Range 等字段可能会占用几百甚至几千字节,而 Body 却经常只有几十字节,所以导致头部偏重。HTTP 2.0 使用 HPACK 算法进行压缩。
二进制格式,HTTP 2.0 使用了更加靠近 TCP/IP 的二进制格式,而抛弃了 ASCII 码,提升了解析效率
强化安全,由于安全已经成为重中之重,所以 HTTP2.0 一般都跑在 HTTPS 上。
多路复用,即每一个请求都是是用作连接共享。一个请求对应一个id,这样一个连接上可以有多个请求。

HTTP请求报文与响应报文格式

请求报文包含三部分:
a、请求行:包含请求方法、URI、HTTP版本信息
b、请求头部(headers)字段
c、请求内容实体(body)
响应报文包含三部分:
a、状态行:包含HTTP版本、状态码、状态码的原因短语
b、响应头部(headers)字段
c、响应内容(body)实体

HTTP常见的请求方法有哪些?

方法 描述 是否包含主体
GET 从服务端获取指定信息 否
POST 向服务端发送待处理的数据 是
HEAD 从服务端获取指定信息的头部 否
PUT 向服务端发送数据并替换服务端上指定的数据 是
OPTIONS 查询针对请求URL指定的资源支持 否
DELETE 从服务端删除指定数据 否
TRACE 沿着目标资源的路径执行消息环回测试 否

GET和POST的区别

GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

HTTP协议与HTTPS协议的区别

1.HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
2.HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
3.HTTP 的端口号是 80,HTTPS 的端口号是 443。
4.HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。

HTTP缓存

强缓存不用发请求直接用本地缓存,协商缓存要发请求去问服务器有没有更新。

协商缓存

1.ETag和If-None-Match
ETag是一个URL资源的标识符,当服务器返回时,可以根据返回内容计算一个hash值或者一个数字版本号(具体返回什么值要看服务器的计算策略)。然后将它加到response的header里面,可能长这样:
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
客户端拿到后会将这个ETag和返回值一起存下来,等下次请求时,使用配套的If-None-Match,将这个放到request的header里面,可能长这样:
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
然后服务端拿到请求里面的If-None-Match跟当前版本的ETag比较下:
如果是一样的话,直接返回304,语义为Not Modified,不返回内容(body),只返回header,告诉浏览器直接用缓存。
如果不一样的话,返回200和最新的内容
与ETag配套的还有一个不太常用的request header----If-Match,这个和前面If-None-Match的语义是相反的。前面If-None-Match的语义是如果不匹配就下载。而If-Match通常用于post或者put请求中,语义为如果匹配才提交,比如你在编辑一个商品,其他人也可能同时在编辑。当你提交编辑时,其他人可能已经先于你提交了,这时候服务端的ETag就已经变了,If-Match就不成立了,这时候服务端会给你返回412错误,也就是Precondition Failed,前提条件失败。如果If-Match成立,就正常返回200。
2.Last-Modified & If-Modified-Since
Last-Modified是资源的最后修改时间。Last-Modified是放到response的header里面的,可能长这样:
Last-Modified: Wed, 21 Oct 2000 07:28:00 GMT
而客户端浏览器在使用时,应该将配套的If-Modified-Since放到request的header里面,长这样:
If-Modified-Since: Wed, 21 Oct 2000 07:28:00 GMT
服务端拿到这个头后,会跟当前版本的修改时间进行比较:
当前版本的修改时间比这个晚,也就是这个时间后又改过了,返回200和新的内容
当前版本的修改时间和这个一样,也就是没有更新,返回304,不返回内容,只返回头,客户端直接使用缓存
3.ETag和Last-Modified优先级
ETag的优先级比Last-Modified高。因为Last-Modified在设计上有个问题,那就是Last-Modified的精度只能到秒,如果一个资源频繁修改,在同一秒进行多次修改,你从Last-Modified上是看不出来区别的。但是ETag每次修改都会生成新的,所以他比Last-Modified精度高,更准确。但是ETag也不是完全没问题的,你的ETag如果设计为一个hash值,每次请求都要计算这个值,需要额外耗费服务器资源。具体使用哪一个,需要根据自己的项目情况来进行取舍。

强缓存

1.Expires
Expires比较简单,就是服务器response的header带上这个字段:
Expires: Wed, 21 Oct 2000 07:28:00 GMT
然后在这个时间内,客户端浏览器都不会再发起请求,而是直接用缓存资源。
2.Cache-Control
Cache-Control相对比较复杂,可设置属性也比较多,max-age只是其中一个属性,长这样:
Cache-Control: max-age=20000
这表示当前资源在20000秒内都不用再请求了,直接使用缓存。
上面提到的immutable也是Cache-Control的一个属性,但是是个实验性质的,各个浏览器兼容并不好。设置了Cache-control: immutable表示这辈子都用缓存了,再请求是不可能的了。
其他常用属性还有:
no-cache:使用缓存前,强制要求把请求提交给服务器进行验证(协商缓存验证)。
no-store:不存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。
3.Expires和Cache-Control的优先级
如果在Cache-Control响应头设置了 max-age,那么 Expires 头会被忽略。

协商缓存和强制缓存优先级

先判断强制缓存,如果强制缓存生效,直接使用缓存;如果强制缓存失效,再发请求跟服务器协商,看要不要使用缓存。

常见的HTTP状态码

2XX 成功

200 OK,表示从客户端发来的请求在服务器端被正确处理 ?
201 Created 请求已经被实现,而且有一个新的资源已经依据请求的需要而建立
202 Accepted 请求已接受,但是还没执行,不保证完成请求
204 No content,表示请求成功,但响应报文不含实体的主体部分
206 Partial Content,进行范围请求 ?

3XX 重定向

301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
302 found,临时性重定向,表示资源临时被分配了新的 URL ?
303 see other,表示资源存在着另一个 URL,应使用 GET 方法丁香获取资源
304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
307 temporary redirect,临时重定向,和302含义相同

4XX 客户端错误

400 bad request,请求报文存在语法错误 ?
401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息 ?
403 forbidden,表示对请求资源的访问被服务器拒绝 ?
404 not found,表示在服务器上没有找到请求的资源 ?
408 Request timeout, 客户端请求超时
409 Confict, 请求的资源可能引起冲突

5XX 服务器错误

500 internal sever error,表示服务器端在执行请求时发生了错误 ?
501 Not Implemented 请求超出服务器能力范围,例如服务器不支持当前请求所需要的某个功能,或者请求是服务器不支持的某个方法
503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
505 http version not supported 服务器不支持,或者拒绝支持在请求中使用的 HTTP 版本

输入 url 到页面渲染的整个流程

1、首先,在浏览器地址栏中输入url,先解析url,检测url地址是否合法
2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统,获取操作系统的记录(保存最近的DNS查询缓存);
路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
ISP缓存:若上述均失败,继续向ISP搜索。
3、在发送http请求前,需要域名解析(DNS解析),解析获取相应的IP地址。
4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
6、服务器处理收到的请求,将数据返回至浏览器
7、浏览器收到HTTP响应
8、浏览器解码响应,如果响应可以缓存,则存入缓存。
9、 浏览器发送请求获取嵌入在HTML中的资源(html,css,javascript,图片,音乐······),对于未知类型,会弹出对话框。
10、 浏览器发送异步请求。
11、页面全部渲染结束。

1.url解析
检查缓存

2.浏览器根据DNS服务器得到域名对应的IP地址
3.发起tcp三次握手
第一次握手(SYN=1, seq=x):
客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及初始序号 X,保存在包头的序列号(Sequence Number)字段里。
发送完毕后,客户端进入 SYN_SEND 状态。
第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。 发送完毕后,服务器端进入 SYN_RCVD 状态。
第三次握手(ACK=1,ACKnum=y+1)
客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入 ESTABLISHED 状态,当服务器端接收到这个包时,也进入 ESTABLISHED 状态,TCP 握手结束。完成三次握手,随后客户端与服务器端之间可以开始传输数据了。

  • 为什么要三次握手
    我们假设client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。
    本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。
    假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。
    4.建立TCP连接后向这个 IP 的机器发送 HTTP 请求
  • 四次挥手
    第一次挥手(FIN=1,seq=x)
    假设客户端想要关闭连接,客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。
    发送完毕后,客户端进入 FIN_WAIT_1 状态。
    第二次挥手(ACK=1,ACKnum=x+1)
    服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。
    发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
    第三次挥手(FIN=1,seq=y)
    服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。
    发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
    第四次挥手(ACK=1,ACKnum=y+1)
    客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。
    服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。
    客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。
  • 为什么要四次挥手
    服务器在收到客户端的 FIN 报文段后,可能还有一些数据要传输,所以不能马上关闭连接,但是会做出应答,返回 ACK 报文段,接下来可能会继续发送数据,在数据发送完后,服务器会向客户单发送 FIN 报文,表示数据已经发送完毕,请求关闭连接,然后客户端再做出应答,因此一共需要四次挥手。
  • 客户端为什么需要在 TIME-WAIT 状态等待 2MSL 时间才能进入 CLOSED 状态?
    按照常理,在网络正常的情况下,四个报文段发送完后,双方就可以关闭连接进入 CLOSED 状态了,但是网络并不总是可靠的,如果客户端发送的 ACK 报文段丢失,服务器在接收不到 ACK 的情况下会一直重发 FIN 报文段,这显然不是我们想要的。因此客户端为了确保服务器收到了 ACK,会设置一个定时器,并在 TIME-WAIT 状态等待 2MSL 的时间,如果在此期间又收到了来自服务器的 FIN 报文段,那么客户端会重新设置计时器并再次等待 2MSL 的时间,如果在这段时间内没有收到来自服务器的 FIN 报文,那就说明服务器已经成功收到了 ACK 报文,此时客户端就可以进入 CLOSED 状态了。
  • 常用的请求头部
Accept: 接收类型,表示浏览器支持的MIME类型
(对标服务端返回的Content-Type)
Accept-Encoding:浏览器支持的压缩类型,如gzip等,超出类型不能接收
Content-Type:客户端发送出去实体内容的类型
Cache-Control: 指定请求和响应遵循的缓存机制,如no-cache
If-Modified-Since:对应服务端的Last-Modified,用来匹配看文件是否变动,只能精确到1s之内,http1.0中
Expires:缓存控制,在这个时间内不会请求,直接使用缓存,http1.0,而且是服务端时间
Max-age:代表资源在本地缓存多少秒,有效时间内不会请求,而是使用缓存,http1.1中
If-None-Match:对应服务端的ETag,用来匹配文件内容是否改变(非常精确),http1.1中
Cookie: 有cookie并且同域访问时会自动带上
Connection: 当浏览器与服务器通信时对于长连接如何进行处理,如keep-alive
Host:请求的服务器URL
Origin:最初的请求是从哪里发起的(只会精确到端口),Origin比Referer更尊重隐私
Referer:该页面的来源URL(适用于所有类型的请求,会精确到详细页面地址,csrf拦截常用到这个字段)
User-Agent:用户客户端的一些必要信息,如UA头部等
  • 常用的响应头部
Access-Control-Allow-Headers: 服务器端允许的请求Headers
Access-Control-Allow-Methods: 服务器端允许的请求方法
Access-Control-Allow-Origin: 服务器端允许的请求Origin头部(譬如为*)
Content-Type:服务端返回的实体内容的类型
Date:数据从服务器发送的时间
Cache-Control:告诉浏览器或其他客户,什么环境可以安全的缓存文档
Last-Modified:请求资源的最后修改时间
Expires:应该在什么时候认为文档已经过期,从而不再缓存它
Max-age:客户端的本地资源应该缓存多少秒,开启了Cache-Control后有效
ETag:请求变量的实体标签的当前值
Set-Cookie:设置和页面关联的cookie,服务器通过这个头部把cookie传给客户端
Keep-Alive:如果客户端有keep-alive,服务端也会有响应(如timeout=38)
Server:服务器的一些相关信息

5.服务器收到、处理并返回http请求
6.浏览器得到返回内容,开始渲染页面

  • 浏览器将获取的HTML文档解析成DOM树(DOM Tree)
  • 处理CSS标记,构成层叠样式表模型(CSSOM)
  • 将DOM树和CSSOM整合形成渲染树(Render Tree)
  • 根据Render Tree开始渲染和展示
  • 布局render树(Layout/reflow),负责各元素尺寸、位置的计算
  • 绘制render树(paint),绘制页面像素信息
  • 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上
  • 遇到script标签时会阻塞渲染

算法

React/Vue/微信小程序

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表