1. 我是皮皮虾首页
  2. 编程开发
  3. 前端

前端面试题整理(持续收集,后期补充答案)

HTTP协议相关

  • HTTP建立连接之tcp三次握手
第一次握手:客户端发送报文(同步位SYN=1(Synchronize Sequence Numbers)seq=j(初始化序列号))到服务端,进入syn_send状态,等待服务器确认
第二次握手:服务器收到SYN报文之后,发出确认报文段(SYN=1,ACK=1,ack=j+1,seq=k)此时进入syn_recv状态
第三次握手:客户端收到后向服务器发送确认报文(ACK=1,ack=k+1,seq=j+1)发送完毕之后进入establish状态。完成三次握手,然后开始数据传送
拓展:
原因:需要三次握手才能确认双方的接收与发送能力是否正常
半连接队列:syn_recv状态,未完全建立连接。
ISN:initial sequence number初始化序列号(seq) 是动态生成的,随时间而变化
第一二次握手不能携带数据,第三次握手可以携带数据,因为此时已经是established状态
syn攻击:客户端在短时间内大量伪造不存在的ip地址,不断向服务端发送syn包。server端则不断回复确认包,但由于源地址不存在,所以需要不断重发。这些伪造的请求大量占用未连接队列,导致正常请求因为队满而抛弃,造成网络拥堵或崩溃。dos/ddos攻击
防御:缩短超时时间,增加最大半连接数,过滤网关防护,syn cookies技术
  • HTTP断开连接之tcp四次挥手
第一次挥手:客户端向服务器发送一个FIN=1,序号seq=u,关闭数据传送。进入fin_wait1状态
第二次挥手:服务端收到FIN后,即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),进入close_wait状态,此时属于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2状态,等待服务端发出的连接释放报文段
第三次挥手:服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认
第四次挥手:客户端发送确认报文段(ACK=1,seq=u+1,ack=w+1)进入time_wait状态,等待2msl进入close状态

为什么需要四次:当服务端收到fin的时候一般不会直接关闭socket,因为存在可能有数据传送未完成的情况,所以先给客户端发送一个确认报文,等到服务端所有报文都发送完了再发送FIN报文

2MSL(Maximum Segment Lifetime最长报文寿命):它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
等待2msl原因:1.保证客户端最后发送的ack确认报文段可以到达服务端(有时候网络不可靠,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文);2.防止“已失效的连接请求报文段”出现在本连接中
  • 缓存:强缓存与协商缓存
缓存优点:
1.减少重复的服务器请求,节省流量
2.降低服务器压力,提高网站性能
3.提升客户端加载速度,提升用户体验

区别:
1.如果命中强缓存,则不需要与服务器通信;而协商缓存最终由服务器来决定是否使用缓存,存在一次通信
2.chrome命中强缓存,会返回200 from cache(disk cache/memory cache快),命中协商缓存是304(not modified)不同浏览器表现不一致,firefox中from cache状态码是304

浏览器请求流程:
1.浏览器在加载资源时,根据请求头的expires和cache-control判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器
2.如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过last-modified和etag验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源
3.若都未命中,直接从服务器加载资源

请求头名词解释:
Expires:是http1.0提出的一个表示资源过期时间的header,由服务器返回,受限于本地时间,如果本地时间修改则缓存失效
Cache-Control:http1.1提出的相对时间,eg:max-age=3600 代表资源的有效期是 3600 秒
               其他设置项:no-store、no-cache、public、private(只能被终端浏览器)

优先级: Cache-Control  > expires > Etag > Last-Modified

Last-Modified:标记最后文件修改时间。浏览器会在request header加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来
Etag:由服务器为每一个资源生成的唯一标识串(hash),只要资源有变化就这个值就会改变。接收到 If-None-Match 字段以后,服务器通过比较两者是否一致来判定文件内容是否被改变

etag解决了Last-Modified什么问题:
1.一些文件也许会周期性的更改,但是内容并不改变
2.文件修改频繁,在秒级以内
3.某些文件服务器不能精确得到文件的最后修改时间

设置:
后端服务器代码逻辑:res.setHeader('max-age': '3600 public')
ngnix配置:add_header Cache-Control "max-age=3600"

Ctrl + F5 强制刷新的时候,会暂时禁用强缓存和协商缓存,从服务器加载资源
  • 网络七层协议
定义:每一层都遵循上下层交互提供服务的原则。上下层交互的约定叫接口,同层交互的约定叫协议
协议分层优点:每个分层可以独立使用,变化不影响整体。各司其职
协议分层缺点:过分模块化,导致有些情况下每层不得不实现相似的处理逻辑
OSI参考模型可以分为:
物理层(0,1交互)
数据链路层(互联设备之间的传送和识别)
网络层(地址管理和路由选择)
传输层(管理两个节点之间的数据传输 TCP、UDP等)
会话层(通信管理,建立和断开连接)
表示层(接收不同形式的信息)
应用层(针对每个应用的协议 HTTP、FTP、DNS等)
  • 浏览器输入一个网址,到页面展示这中间经历了什么?
1.输入地址
2.浏览器查找域名的ip地址(DNS解析)
  先本地host->DNS请求本地服务器(缓存记录->根服务器)->根服务器给出域服务器地址告诉本地服务器去域服务器上查找->域服务器告知域名解析服务器的地址-> 通过域名解析ip
  DNS优化:DNS缓存、负载均衡、CDN、DNS pre-fetch
  DNS负载均衡:DNS服务器为同一个主机名配置多个ip地址,应答查询时返回不同的ip地址,将客户的访问引导到不同的机器上去
3.三次握手建立tcp连接
4.发送一个http请求
5.服务器处理请求并返回报文
6.浏览器解析渲染页面
  根据html构建dom树->构建cssom->构建render tree->layout->paint(绘制)
  构建dom树的时候遇到js会阻塞执行,异步脚本不阻塞,但是js也必须等到cssom执行完之后
7.四次挥手断开tcp连接
  • HTTP常用请求方式,以及区别,get和post?
get、post、put、delete、head、trace等
传递参数:get拼接在url后面,post将参数放在message body中
传输长度限制:因为浏览器避免过长的url消耗资源会限制长度,post没有内容长度限制问题
回退无害、参数是否会保存在浏览器历史中、安全性,暴露在url中(但是http都是明文传输的)、报文格式不同
从标准语义规范来说:get是用来获取数据,无副作用,可缓存的;post是用来修改数据,有副作用,非幂等,不可缓存
  • cookie和localStorage、sessionStorage
C:cookie;localStorage:L;sessionStorage:S
生命周期:C可设置过期时间,否则关闭失效;L不清除则永久有效;S会话框关闭失效
存储大小:C 4kb左右,L,S 5M
http请求:C在请求头中携带,在客户端和服务端来回传递;L,S仅在客户端保存
使用场景:C识别用户登录;L跨页面传递参数;S保存临时数据,方式页面刷新数据丢失
  • HTTP状态码
1xx:请求正在被处理。100:已经接收到请求头,客户端应继续发送请求主体
2xx:请求处理成功。200:ok、201:no content
3xx:需要进行附加操作。301:moved permanently、302:临时重定向、304:资源未改变,可直接使用缓存
4xx:客户端错误。400:bad request、401:未经过认证、403:禁止访问、404:not found
5xx:服务端错误。500:服务器故障、502:bad gateway、503:服务暂不可用、504:gateway timeout
  • HTTP劫持
即DNS劫持,DNS污染
用户访问网页的过程:1、输入域名;2.DNS服务器把用户输入的域名翻译成对应的IP;3、网站再把对应IP的网页呈现给用户
在第二步,DNS服务器把域名翻译成的IP被攻击者替换,攻击者劫持正确的IP,然后换成攻击者提供的自己做的网站的IP传给网站,网站调出该IP对应的网页,呈现给用户,这时用户看到的就是攻击者的网站了。这也就是DNS劫持(http劫持)的原理。
解决:1.vpn远程代理解析,不经过当前网络访问dns。2.修改本地host文件
  • HTTP和HTTPS的区别,HTTPS为什么要ca证书 ssl加密的流程,对称加密和非对称加密分别在哪里用到的
http超文本传输协议:是用于从万维网服务器传输超文本到本地浏览器的传输协议
TLS/SSL:安全层,基于应用层(http)与传输层(tcp)协议之间。
具体区别:1.HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
          2.连接方式不同,端口号不同。80与443端口
          3.HTTP是明文传输,是无状态的。HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。

https对称加密进行通信存在秘钥协商过程的不安全性,需要使用非对称加密算法来保证安全

非对称加密算法:生成一对公钥和私钥,私钥加密后持有公钥就可解,公钥加密后的内容只有私钥可解。客户端持有公钥,私钥只有服务器私有。

HTTPS为什么要ca证书:
(为了安全的获取公钥,并确保公钥的获取是安全的)
服务端直接分发公钥给客户端存在中间人篡改公钥的可能性,所以客户端与服务器不直接使用公钥,而是使用数字证书签发机构颁发的证书来进行公钥的分发,一定程度上保证非对称加密过程本身的安全

ssl/tsl加密解密流程:
1.首先,客户端向服务器发出加密请求。"client hello(密码信息和一个随机字符串random1)"
2.服务器收到后响应"server hello(密码组合、证书和一个随即字符串random2)"
3.客户端验证CA证书并且从证书中获取公钥,生成下一个随机字符串random3并用公钥进行加密,并将加密后的random3发给服务端
4.服务端收到后用私钥进行解密
5.客户端与服务端约定使用相同的算法,random1+random2+random3生成相同的密钥KEY,用于后面的对称加密算法
6.客户端和服务端分别发送"finished"消息,成功建立安全链接,使用KEY进行加密通信
参考:https://segmentfault.com/a/1190000021494676 ,https://segmentfault.com/a/1190000021559557 
拓展:有没有别的方法提高安全性,比如不让客户端来做公钥加密?I dont konw
  • HTTP1.0、HTTP2.0、HTTP3.0
HTTP1.0
1.无状态连接
2.基于tcp连接
3.如果丢包则需要重新建立tcp连接
4.传输效率低,每个资源请求都需要排队
http1.1与http1.0主要区别:
1.长连接:http1.0需要使用keep-alive进行长连接,http1.1默认支持
2.支持管道传输,允许一个tcp连接发送多个请求,因为请求本身有先后顺序,所以返回也要有先后顺序,不然对应不上。所以只是节省了发起请求的时间。限制比较多,还是习惯发起多个tcp连接。浏览器最多支持6个并发
http1.1性能瓶颈:
1.请求/响应头未经压缩,比较冗长
2.服务器响应慢会导致队头阻塞
3.没有优先级控制
4.请求只能从客户端发起

HTTP2.0:
1.多路复用(一个连接并发多个请求),二进制分帧,无需响应和请求顺序一致
  三种实现方式:select、poll、epoll
2.头部压缩
3.允许服务器推送消息
HTTP2.0问题:
丢包性能问题。应答机制,超时未回复则默认丢包重发;通过“滑动窗口”的机制来提升传输效率
但是http2.0是建立在一个tcp连接上的,某个请求的丢包会阻塞其他请求的发送

HTTP3.0(QUIC:quick udp internet connection):
谷歌提出的协议,放弃了tcp协议转向udp协议
udp协议与tcp协议不同,无需等待应答,一旦建立连接就立即传送数据。时效性强
一:解决了丢包问题
根本思路:无需批量等待应答,某个数据包应答收到后就窗口后移,发送下一个包
1.QUIC使用packet_no来标识可靠性,从0开始,每发送一个包+1,即使丢失了也是基于当前的packet_no+1;
2.同时,QUIC利用多路复用时的strem_id以及QUIC新增的stream_offset来判断当前的数据包的正确序列(QUIC支持乱序传输数据)
3.与tcp不同,中间ack的丢失对数据传输影响不大,因为其只需要确认最后一个ack即可,但QUIC要求每个数据包都有明确的ack返回,没返回的就认为是丢包了
二:提供了纠错机制
通过增加一个冗余包的发送,当发生仅一个包丢失的时候,可以根据之前接收的包与冗余包反推出丢失的那个包
  • HTTP报文
请求报文:
请求行(请求方法、请求URL、http协议版本)+请求头+空行+请求内容
请求头:Host、Accept、Accept-Charset、content-type、origin、user-agent、Connection、keep-alive等

响应报文:
状态行(报文协议及版本,状态码及描述)+响应头+空行+响应体
响应头:Server、Date、Content-Type、Connection、keep-alive、Cache-Control、Expires等

  • 网关、代理和隧道
网关:网关是转发其他服务器通信数据的服务器。协议网关、资源网关等

代理:扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。
作用:过滤某些ip的访问、安全防火墙(防止sql注入)、负载均衡、匿名(私密)
代理服务器部署:正向代理(vpn)反向代理(防火墙)网络交换代理(缓存服务器)
请求如何到达代理:1.客户端配置;2.修改网络;3.修改dns;4.web服务器修改,响应重定向命令

隧道:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序
还是不是很懂
  • 常见的网络攻击有哪些?怎么防御?
XSS跨站脚本攻击:是指攻击者利用网站漏洞将代码注入到其他用户浏览器的攻击方式。
常见有三种攻击方式:
1.反射型(非持久型)
原理:在url插入恶意代码,用户访问时服务端在url取出恶意代码后拼接至html并返回给客户端
要点:URL链接;服务端参与;用户访问特定链接
2.持久型
原理:攻击者将脚本提交到被攻击网站数据库中,其他用户访问数据时注入脚本从服务器返回并执行
要点:恶意脚本存储在服务器中;服务端参与;只要访问就被攻击
3.DOM型
原理:在url插入恶意代码后,直接在客户端脚本中执行
要点:只发生在客户端
防范:
1.对于外部输入的内容进行特殊字符转义
2.开启内容安全策略(CSP)规定哪些外部资源可以加载或者执行
3.设置cookie httponly属性,禁止javascript读取cookie信息

CSRF跨站请求伪造:在用户不知情的情况下,窃取用户身份在对应网站进行操作。
原理:引诱用户访问第三方网站,在第三方网站中向被攻击网站发起跨站请求,利用受害者的身份凭证
要点:1.利用http请求会带上cookie信息;2.攻击一般发生在第三方网站上;3.只能冒用,无法获取;4.方式多种:图片url,超链接,表单请求等
防御:
1.使用 CSRF Token 验证用户身份。服务端生成,客户端请求时携带,token通常存在session中
2.双重 Cookie 验证,请求头带上cookie
3.设置白名单,进允许安全域名请求
4.必要时添加验证码验证

MITM中间人攻击:攻击者在通信的两端分别建立独立的联系,充当一个中间人的角色对数据进行监听、拦截、篡改。
两个阶段:拦截和解密
1.拦截:
用户数据在到达目标地址前拦截并通过攻击者的网络。分为主动攻击和被动攻击
被动:恶意wifi热点
主动:1.ARP欺骗,冒充网关或者主机;2.DNS欺骗:冒充域名服务器,将受害者查询的 IP 地址转发到攻击者的 IP 地址。
2.解密
若是使用率SSL/TSL手段加密,还得使用其他手段解密
(1)SSL劫持:tsl握手期间将服务器派发的公钥替换成自己的并且发放给客户端。(证书是伪造的,所以会提示证书错误,此时仍继续操作,则会被劫持)
(2)SSL剥离:被拦截之后继续通信会被降级为不安全的HTTP连接,服务器可以通过开启 HSTS(HTTP Strict Transport Security)策略,告知浏览器必须使用 HTTPS 连接。但是有个缺点是用户首次访问时因还未收到 HSTS 响应头而不受保护。
防范:
开发者:1.HTTPS;2.开启HTTP Strict Transport Security
用户:1.尽可能访问HTTPS连接;2.不链接不清楚来源的wifi;3.收到证书错误警告时保持警惕;4.公共网络不要操作设计私密信息的交互;5.使用可信任的证书源,不下载安装来源不明的证书
  • TCP和UDP各自特点和区别
1.TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接
2.TCP提供可靠的服务。保证数据正确性和顺序,UDP可能丢包,无顺序
3.TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,没有阻塞控制
4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5.首部开销TCP(20字节)>UDP(8字节)
6.TCP的逻辑通信信道是全双工(同时进行双向传输)的可靠信道,UDP则是不可靠信道

HTML

  • iframe的优缺点
优点:可原封不动把嵌入的网页引入进来;如果多个页面引入iframe,只需要修改iframe的内容即可统一更新;适合加载广告这类第三方内容
缺点:会产生很多页面,不便于管理;与主页面共享连接池,增加http请求,会影响页面的并行加载;代码复杂,有完整的头尾,不利于搜索引擎的优化;存在兼容问题
  • src和href的区别
src用来替代这个元素,而href用来建立这个标签与外部资源的联系
  • html5新属性
语义标签、增强型表单、音频视频、canvas绘图、地理坐标、svg绘图、拖放api、websocket、webstorage
  • 什么情况下会阻塞DOM渲染
css的加载不会阻塞DOM的解析,但是会阻塞DOM渲染

CSS

  • 说一下BFC
创建原则:根元素;浮动元素;绝对定位元素;overflow不为visible的元素;.display取值为 inline-block、
table-cell、table-caption、flex、inline-flex之一的元素
作用:1.可以包含浮动元素不被浮动元素覆盖;阻止父子元素的margin折叠
  • 多种方式实现水平垂直居中
固定宽高:
1.定位:(1)position: absolute;left,top,减去一半宽度的间距;
        (2)absolute + margin auto,设置top left bottom right都为0
        (3)absolute + calc
             .wp {
                position: relative;
             }
             .box{
                position: absolute;
                top: calc(50% - 50px);
                left: calc(50% - 50px);
             }
不固定宽高:
(1)absolute + transform
       .box{
            position: absolute;
            left: 50%;
            top:50%;
            transform: translate(-50%,-50%);
        }
 (2)text-align和line-height
        .wp{
            text-align: center;
            line-height: 300px;
        }
        .box{
            display: inline-block;
            vertical-align: middle;
            line-height: initial;
        }
(3) flex布局
        .wp{
            display: flex;
            justify-content: center;
            align-items: center;
        }
(4)grid布局
       .wp{
            display: grid;
        }
        .box{
            justify-self: center;
            align-self: center;
        }
(5)css table
        .wp{
            display: table-cell;
            text-align: center;
            vertical-align: middle;
        }
        .box{
            display: inline-block;
        }
(6)writing-mode
PC端有兼容性要求,宽高固定,推荐absolute+负margin
PC端有兼容要求,宽高不固定,推荐css-table
PC端无兼容性要求,推荐flex
移动端推荐使用flex
  • 多种方式实现三栏布局
1.浮动布局:float:left
2.flex布局:display:flex
3.grid布局:width: 100%;display:grid;grid-template-columns:100px auto 100px;grid-template-rows: 100px;
4.position定位
5.table布局:display:table-cell
  • flex布局
弹性布局
flex-direction:项目排列方式。row|row-reverse|column|column-reverse
flex-wrap:项目换行方式。nowrap|wrap|wrap-reverse
flex-flow:排列方式和换行方式的简写,用||连接
justify-content:项目在主轴上的对其方式。flex-start|flex-end|center|space-between|
space-around
align-items:项目在交叉轴上如何对齐。flex-start|flex-end|center|baseline|stretch;
align-content:多根轴线的对齐方式。flex-start|flex-end|center|baseline|stretch;
项目的属性:order,flex-grow,flex-shrink,flex-basis,flex,align-self
  • grid布局
grid-template-columns:设置列宽(可以是具体数值或者百分比、rem、fr)
grid-template-rows:设置行高
grid-gap:网格项间隙
grid-column-start/grid-column-end/grid-row-start/grid-row-end:垂直方向/水平方向的开
始结束位置网格线
可简写为:grid-column,grid-row。用/符号分隔。亦可 grid-area
justify-items 属性,
align-items 属性,
place-items 属性
justify-self 属性,
align-self 属性,
place-self 属性
  • px,em,rem尺寸单位
px:像素
rem:针对根元素的font-size布局
em:根据父元素的font-size布局
拿不准的时候,用rem设置字号,用px设置边框,用em设置其他大部分属性
  • 怎么适配页面大小兼容的
flex布局
响应式布局
媒体查询
vw+vh单位
rem+em布局方式
百分比布局
  • 有几种定位方式?分别有什么区别
static 默认
relative 相对定位,未脱离文档流
absolute  绝对定位,脱离文档流,根据非static定位的父元素确定位置,可设置top right bottom left的值
fixed 固定定位,根据浏览器窗口定位
sticky 粘性定位 可以说是static(没有定位) 和 固定定位fixed 的结合;它主要用在对 scroll 事件的监听上,当滚动到该元素的触发定位时相当于fixed定位
注意:父元素不能overflow:hidden或者overflow:auto属性
      必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
      父元素的高度不能低于sticky元素的高度 sticky元素仅在其父元素内生效
  • 有没有遇到一些浏览器兼容性问题,你是怎么解决的?
CSS 样式兼容性
1.针对各个浏览器的的样式存在差异,我们可以用Normalize.css 抹平差异,也可以定制自己的 reset.css,例如通过通配符选择器,全局重置样式。
2.在存在一些CSS3属性浏览器兼容问题的时候,我们之前都是惯用浏览器的前缀。开发过程中我们一般是使用CSS预处理器以及前端自动化构建工程帮我们处理
3.还有一些IE9一下不兼容的属性比如opacity,我们一般使用兼容写法
JavaScript 交互兼容性
1.事件兼容的问题,我们通常需要会封装一个适配器的方法,过滤事件绑定、移除、冒泡阻止以及默认事件行为处理
2.new Date构造函数的正确使用
3.非chrome浏览器获取scrollTop需要兼容
浏览器hack
判断IE版本,safiri浏览器和chrome浏览器,对此做一些特殊处理
  • css3新属性
animation,transition,transform,选择器,@font-face特性,gradient渐变,阴
影 shadow,圆角,背景效果
  • 0.5px的线
利用transfrom:scaleY(0.5)
scale(x轴,y轴):scaleX,scaleY
  • 清除浮动
浮动的原因:父元素因为子级元素浮动导致父级对象盒子不能被撑开,高度塌陷
方法:1.在最后一个浮动标签后新增一个标签并设置 clear:both;(过多的无语义
化标签)
      2.父级元素添加 overflow:hidden(会导致内容被隐藏,无法显示要溢出的元素)
      3.使用 after伪元素清除浮动;
  • overflow:hidden 为什么能清除浮动,以及它的副作用
原因:会生成一个块级格式化上下文,在计算BFC的高度时,浮动元素的高度也要参与计算,BFC就是页面上的一个隔离的独立容器,容器里面的子元素不应该影响到外面的元素,如果父元素不计算浮动元素的高度而是坍塌的话,那么浮动元素就会影响到其后面的元素。所以BFC会计算浮动元素的高度来不影响后面的元素。
副作用:无法显示要溢出的元素
  • CSS选择器以及优先级
通用选择器 * id选择器 类选择器 标签选择器 属性选择器  后代元素选择器 多元素选择器 相邻选择器 子代选择器
伪类选择器 :focus :linked :active :hover :before :after
  • CSS3中对溢出的处理
visible→默认值,内容不会被剪切,内容会溢出显示在元素框之外
hidden→内容会被剪切,溢出于元素框的内容不可见
scroll→内容会溢出被你剪切,但会自动生成滚动条
auto→内容如果溢出, 会自动生成滚动条
inherit→继承父级的overflow值
  • 隐藏页面中某个元素的方法
opacity:0
display:none
visible:hidden
position:absolute;利用z-index层叠属性置于底层
  • 了解回流和重绘么?怎么减少回流和重绘?
  • CSS画正方体,三角形
  • 设置一个元素的背景颜色,背景颜色会填充哪些区域?
  • img图片后面的文字如何水平垂直居中?
  • 如何实现动画?transition和animation的区别
  • CSS 选择器的优先级是怎样的?熟悉什么类库吗?
  • z-index注意点
同级元素间的堆叠:整数值越大,则被层叠在越上面。
如果两个对象的此属性具有同样的值,那么将依据它们在HTML文档中流的顺序层叠,写在后面的将会覆盖前面的
父子关系是无法用z-index来设定上下关系 的,一定是子级在上父级在下。
用static 定位或无position定位的元素z-index属性是无效的。

JavaScript

  • 图片懒加载是怎么实现的?一次加载一张,加载完再加载一张
1.首先前端的img的src属性设置一个缩略图,或者不设置src,然后自定义一个属性(data-src)值为真实图片地址。并且定义一个类名,表示该图片需要懒加载
2.判断图片的元素集合是否在可视化区域,如果在可视化区域,设置图片的src为真实地址
如何判断:
(1)通过获取元素的getBoundingClientRect属性的top值和页面的clientHeight进行对比,top<clientHeight则出现在视区内
(2)使用高级特性new IntersectionObserver方法判断图片是否在可视区域内,不需要监听滚动事件,但是存在浏览器兼容问题
3.滚动窗口的时候,遍历并且判断是否再可视区域。注意节流
  • 什么是纯函数?
  • 柯里化是什么?如何实现柯里化,以及柯里化的应用场景
  • 实现一个once函数 传入的函数只执行一次
  • 闭包,闭包的副作用
  • 防抖函数
  • 节流函数
  • apply,call和bind的区别,自己实现一个bind函数
  • 深克隆和浅克隆的区别?实现深克隆
  • 说一下原型和原型链
  • 说一下类的创建和继承
  • 前端中的事件流和事件模型
  • 事件委托
  • js的new操作符做了哪些事情
  • 事件循环机制Eventloop,宏任务与微任务
  • 异步加载js的方法
  • JS中的垃圾回收机制
引用计数,标记清除,
  • 如何理解前端模块化标准
为什么需要?
有哪些模块化标准,以及相应的特性
  • 说一下Commonjs、AMD和CMD
  • js监听对象属性的改变
  • 如何实现一个私有变量,用getName方法可以访问,不能直接访问
  • ==和===、以及Object.is的区别
  • 如何实现sleep的效果
  • 虚拟dom
diff算法是一种通过同层的树节点进行比较的高效算法,避免了对树进行逐层搜索遍历,所以时间复杂度只有 O(n)。
diff算法有两个比较显著的特点:
1、比较只会在同层级进行, 不会跨层级比较。
2、在diff比较的过程中,循环从两边向中间收拢。
diff流程:
1 、首先定义 oldStartIdx、newStartIdx、oldEndIdx 以及 newEndIdx 分别是新老两个 VNode 的两边的索引。

2、接下来是一个 while 循环,在这过程中,oldStartIdx、newStartIdx、oldEndIdx 以及 newEndIdx 会逐渐向中间靠拢。while 循环的退出条件是直到老节点或者新节点的开始位置大于结束位置。
while 循环中会遇到四种情况:
情形一:当新老 VNode 节点的 start 是同一节点时,直接 patchVnode 即可,同时新老 VNode 节点的开始索引都加 1。
情形二:当新老 VNode 节点的 end 是同一节点时,直接 patchVnode 即可,同时新老 VNode 节点的结束索引都减 1。
情形三:当老 VNode 节点的 start 和新 VNode 节点的 end 是同一节点时,这说明这次数据更新后 oldStartVnode 已经跑到了 oldEndVnode 后面去了。这时候在 patchVnode 后,还需要将当前真实 dom 节点移动到 oldEndVnode 的后面,同时老 VNode 节点开始索引加 1,新 VNode 节点的结束索引减 1。
情形四:当老 VNode 节点的 end 和新 VNode 节点的 start 是同一节点时,这说明这次数据更新后 oldEndVnode 跑到了 oldStartVnode 的前面去了。这时候在 patchVnode 后,还需要将当前真实 dom 节点移动到 oldStartVnode 的前面,同时老 VNode 节点结束索引减 1,新 VNode 节点的开始索引加 1。

3、while 循环的退出条件是直到老节点或者新节点的开始位置大于结束位置。
情形一:如果在循环中,oldStartIdx大于oldEndIdx了,那就表示oldChildren比newChildren先循环完毕,那么newChildren里面剩余的节点都是需要新增的节点,把[newStartIdx, newEndIdx]之间的所有节点都插入到DOM中
情形二:如果在循环中,newStartIdx大于newEndIdx了,那就表示newChildren比oldChildren先循环完毕,那么oldChildren里面剩余的节点都是需要删除的节点,把[oldStartIdx, oldEndIdx]之间的所有节点都删除
  • 事件监听
  • JS的基本数据类型有哪些,基本数据类型和引用数据类型的区别,NaN是什么的缩写,JS的作用域类型,undefined==null返回的结果是什么,undefined与null的区别在哪,写一个函数判断变量类型
  • setTimeout和setInterval差别,以及哪个定时更准
  • for in /for of
  • 数组和链表的区别 各自的优缺点
  • 数组的一些算法
  • 数学运算精度丢失问题怎么处理
  • es新特性
  • es 静态分析原理
  • 堆和栈的区别,分别的应用场景
  • js 中怎么实现封装和多态?
  • replace方法
  • 常用那些 js 模板引擎?Handlebars 之类的
  • 有哪些异步函数
  • JS 执行过程中是如何保存上下文的
es6相关
  • var,let,const区别
  • 说说你理解的Symbol
  • promise底层实现,解决了什么问题
  • generator
  • async/await实现原理
  • js类型判断方式
  • 数组常用方法
  • set和map结构
  • typeScript的优缺点
  • 对比下javaScript和typeScript
  • typeScript的新属性
  • 怎么与后台请求交互的,怎么跨域?跨域问题有几种解决方式?,反向代理中为什么服务器端不受跨域限制
  • 多维数组变成一维数组
  • 箭头函数和普通函数的区别,this指向会随外层作用域改变吗
  • Proxy
  • ES6/ES7/ES8的特性

vue

  • 什么是单页面应用
  • 生命周期
  • 父子组件传值
  • vuex
action和mutation
  • 循环中为什么最好添加key值
在我们进行虚拟dom新旧节点更新的时候,比较新旧节点会使用key值,所以设置key值能更高效的进行判断,不设置key值的话新旧节点都是undefined则需要更多的判断,同时会更大程度上去复用旧节点,有时候会存在一些更新问题
  • v-bind的原理
  • v-model的原理
实际上就是 $emit('input') 以及 props:value 的组合语法糖。它在内部会监听表单控件相关特性的变化,并触发相应的事件,监听的特性:value,checked,<option>子元素的value,触发的事件:input,change
  • v-for和v-if为什么不能一起使用
一起使用会带来性能上的浪费,因为每次迭代都要执行一次v-if的判断条件(vue2中v-for的优先级比v-if高,vue3中v-if优先级高一点)
如果判断在循环外部,可以使用template标签包一层,如果判断再循环内部,则最好使用computed属性过滤一下。
  • axios怎么用的,拦截器你都拦了点啥,实现原理
  • MVVM模式
  • 如何优化SPA应用的首屏加载速度慢的问题
  • vue响应式(双向绑定)的实现原理
  • vue.extend()方法有什么作用?
  • 内容分发
  • 一些源码上的重点
vue双向绑定原理

vue响应式原理


keep-alive怎么实现的
  • vueRouter 原理
  • vue3对比vue2有哪些更新的点
  • 用到了什么导航守卫钩子函数
  • mixin
  • 如何实现一个弹窗组件?提供哪些接口?封装一个组件
  • computed的实现原理
  • watch的运行原理
  • Vue的数据为什么频繁变化但只会更新一次
使用虚拟dom优化渲染过程,因为渲染真实dom的开销很大,会引起浏览器的回流和重绘,每次修改的时候都会用js对象描述一个虚拟dom,先比较js数据对象是否发生变化,找到变化位置,最小化更新
  • vite工具有什么优势
  • Vue的事件绑定方式相比传统的dom方式有哪些优势
虽然vue的事件绑定违背了关注点分离,但是由于vue的事件处理程序和表达式都声明在当前视图的ViewModel上。因此维护上会更加清晰
使用v-on有如下三个好处:
1.查看模板就能定位JavaScript代码中对应的方法
2.ViewModel是纯粹的逻辑代码,与DOM完全解耦
3.无需手动管理事件,ViewModel被销毁之后所有绑定的事件都会被自动删除

react

  • 框架特点以及与vue框架的对比
  • 单向数据流
  • react生命周期函数和react组件的生命周期
  • 组件之间的通信
  • 有了解过react的虚拟DOM吗,虚拟DOM是怎么对比的呢
  • 怎么获取真正的dom
  • setState之后的流程
  • 高阶组件,使用场景,写高阶组件的时候要注意什么
  • React的jsx,函数式编程 
  • react的组件是通过什么去判断是否刷新的

node

  • node.js的事件循环
  • node是一门怎样编程语言
  • Node.js的加载机制(require和module.exports)
  • node 与其他语言有什么区别,其优劣势是什么

工程化

  • 谈谈你对工程化的初步认识,结合你对工程化的认识说出三个以上工程化能够解决的问题或带来的价值?
工程化就是将前端开发过程规范化,标准化。它包括了技术选型,代码规范,开发流程,项目构建等方面,提高了前端工程师的开发质量和效率。一切以提高效率、降低成本、质量保证为目的的手段。
问题场景:
1.使用es6+新特性,但是浏览器兼容有问题
2.使用css预编译语言使用模块化的方式提高项目的可维护性,但是运行环境不能直接支持
3.部署前需要手动压缩代码及资源,上传代码到服务器等操作
4.多人协作开发的时候无法硬性统一风格
5.部分接口需要等待后端完成才能开始
解决的问题和价值:
1.制定各项规范:编码规范,接口规范,开发流程规范等等
2.使用合适的前端技术和框架,提高生产效率,降低维护难度。使用前端模块化、组件化数据分离等等
3.代码可测试,单元测试,端对端测试等
4.开发部署自动化
  • 脚手架的流程以及脚手架的深远意义
1.在命令行询问用户一些问题
2.根据用户对问题的回答渲染出模板文件
意义:
1.减少了重复性的工作,不用再复制大量重复代码再删除或者从零构建
2.可以根据回答动态生成项目结构和配置文件
3.多人协作更方便
ps:脚手架具体细节详见另一篇文章:搭建自己的脚手架
  • gzip压缩有了解吗
  • 图片压缩怎么做
  • eslint模块化标准
  • ES Modules
webpack
  • webpack的价值体现/你对webpack的看法
  • Webpack 的构建流程主要有哪些环节?如果可以请尽可能详尽的描述 Webpack 打包的整个过程
webpack是运行在node环境下,配置文件遵循common.js规范。
1.webpack启动后会从入口文件开始,通过import、require等语句解析资源依赖模块,生成一个资源依赖关系模块树
2.递归模块树,根据module.rules里配置的loader规则进行转换操作
3.这些模块会以entry为单位进行分组,即一个chunk。所以一个chunk就是一个模块以及它的依赖模块合并的结果
4.最后webpack会将所有的chunk作为文件输出。
同时,整个构建流程中webpack会在恰当的时机实行plugin里定义的优化逻辑。其主流程如下:
1、配置初始化
webpack会首先读取配置文件,执行默认配置
2、编译前准备
webpack 会实例化compiler,注册plugins、resolverFactory、hooks。
3、reslove前准备
webpack 实例化compilation、NormalModuleFactory和ContextModuleFactory
4、reslove流程
解析文件的路径信息以及inline loader和配置的loader合并、排序
5、构建module
runLoaders处理源码,得到一个编译后的字符串或buffer。将文件解析为ast,分析module间的依赖关系,递归解析依赖文件
6、生成chunk
实例化chunk并生成chunk graph,设置module id,chunk id,hash等
7、资源构建
使用不同的template渲染chunk资源
8、文件生成
创建目标文件夹及文件并将资源写入,打印构建信息
  • loader和plugin的差异,请描述一下开发 Loader 和 Plugin 的思路。用过的loader和plugin
loader:用于对模块源码的转换,因为webpack本身只支持js处理,loader描述了webpack如何处理非javascript模块,并且在build中引入这些依赖。loader可以将文件从不同css预处理转换为css,将ts转换为JavaScript,或者将内联图像转换为data URL。
常见的loader:sass-loader、css-Loader,style-Loader、file-loader,url-loader、babel-loader等。

loader开发:就像开发中间件管道,可以首先新建一个导出模块,入参为source,对source进行一系列处理,然后返回js代码
module.exports = (source)=>{
    return result(source)
}

plugin通过webpack钩子机制实现,相比于loader,plugin拥有更宽的能力。其目的在于解决loader无法实现的其他事,从打包优化和压缩,到重新定义环境变量,功能强大到可以用来处理各种各样的任务。 
常见的plugin:clean-webpack-plugin、html-webpack-plugin、copy-webpack-plugin等

plugin开发:plugin被要求必须是一个函数或者是包含apply方法的对象。入参是一个compiler对象,其包含构建所需信息,开发时可以通过compiler中hooks属性访问到emit钩子,并通过其tap方法注册一个钩子函数,定制钩子名称和挂载函数。该函数入参为compilation打包上下文,通过遍历compilation下assets的所有键得到所有文件名称。然后根据 键 的source()方法拿到对应的content内容,然后对content进行一些处理,并返回给souce函数,以达到我们的插件目的。
  • tree-shaking
  • sideEffets
  • 模块热替换 HMR
  • SourceMap的最佳实践
  • webpack按顺序加载
  • 文件名hash(文件指纹)控制缓存
  • webpack内rules的常用属性和规则
  • webpack优化开发体验的问题
  • webpack常见api
1.entry:入口,构建依赖的开始
2.output:出口,告诉webpack在哪里输出它所创建的bundles以及文件命名
3.module:loader文件处理规则
      module: {
        rules: [
          { test: /\.txt$/, use: 'raw-loader' }
        ]
      }
4.plugins:插件
      plugins: [
               new HtmlWebpackPlugin({template: './src/index.html'})
      ]
5.mode:development 或者 production
6.resolve 解析:
  resolve.alias 设置模块如何被解析
  resolve.modules 解析模块时应该搜索的目录
  • webpack打包优点
1.专注于模块化的项目,开箱即用
2.可通过plugin进行扩展
3.使用场景不局限于web开发
4.社区庞大,良好的生态链,开发体验好
  • webpack和gulp区别(模块化与流的区别)
gulp:强调的是规范前端开发的流程。是一个基于流的自动化构建工具,不包括模块化的功能,通过配置一系列Task,例如文件压缩合并,样式编译等,然后定义执行顺序让gulp去执行task,从而构建前端项目。
webpack:前端模块化方案。自动化模块打包工具,把资源全局看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,划分为不同的模块,实现按需加载。

算法

  • 缓存优化算法
一般是优化递归算法重复计算的问题,下面以优化斐波那契数列为例来展示
function fabnacci(n) {
 if(n === 1 || n===2) return 1
 return fabnacci(n-1)+fabnacci(n-2)
}
上面代码可以实现一个简单的算法,但是很明显性能上存在很大问题,递归调用会导致很多重复调用。所以需要把已经计算过的结果进行一个缓存操作。
let obj = {1:1,2:1}
function fabnacci(n) {
 if(obj[n]){
   return obj[n]
 } else {
   let res = fabnacci(n-1)+fabnacci(n-2)
   obj[n] = res
   return res
 }
}
  • 快速排序,时间复杂度?是一直是nlogn吗?如果是最坏情况的话等价于哪个排序
  • 冒泡排序
  • 选择排序
  • 堆排序
  • 归并排序
  • 动态规划算法
  • 递归算法
  • 柯里化

手写代码题

  • 出入栈算法,一道算法题括号匹配([]{})这种,问文件很大怎么办?
  • 尾递归
  • 大数相乘
  • 找出数组中第k大的数组出现多少次
  • url参数解析
  • 下面的代码输出什么,为什么?
function A(x) {
this.x = x;
}
A.prototype.x = 1;
function B(x) {
this.x = x;
}
B.prototype = new A(2);
const b = new B(3);
delete b.x;
console.log(b.x); // 2
  • 对每个单词开头字母实现大写:var a = ‘My name is zhang’
  • 写一个函数,第一秒打印1,第二秒打印2
  • 数组拍平并去重
  • 对于一个给定的数据结构转成树形结构
  • 有一个游戏叫做Flappy Bird,就是一只小鸟在飞,前面是无尽的沙漠,上下不断有钢管生成,你要躲避钢管。然后小明在玩这个游戏时候老是卡顿甚至崩溃,说出原因(3-5个)以及解决办法(3-5个)
  • 编写代码,满足以下条件: (1)Hero(“37er”);执行结果为 Hi! This is 37er (2)Hero(“37er”).kill(1).recover(30);执行结果为 Hi! This is 37er Kill 1 bug Recover 30 bloods (3)Hero(“37er”).sleep(10).kill(2)执行结果为 Hi! This is 37er //等待10s后 Kill 2 bugs  //注意为bugs (双斜线后的为提示信息,不需要打印)

综合

  • 你了解的业界比较前沿的技术
  • websocket以及websocket应用场景,一些API 和心跳机制
  • TCP/IP的网络模型
  • 什么是进程 线程,单核cpu为什么要用多线程?如何做到多线程同步?进程在内存中是如何分配的?线程池了解吗?用户线程和内核线程的区别?
  • 进程间的通信方式有哪些
  • 一些linux的命令
  • CI/CD的配置
  • 为什么大图片不用base64,base64的缺点
  • base64优化的原理
  • 介绍一下CDN,CDN优化的原理,它怎么做到加速的?
  • CDN加速服务器有什么缺点(一个新疆的人访问深圳的服务器,要经过一层一层地找,找到深圳的节点,比直接来深圳的节点拿慢多了,有什么好的方案解决这个问题)
  • 前端如何优化网站性能
  • 首屏加载优化
  • 前端测试
  • 自我介绍,讲讲项目,遇到的技术难点怎么解决
  • 设计模式,比如单例模式
  • 项目部署全流程
  • socket编程
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
未完待续...
  • git常用命令,svn 和 git 的主要区别?
  • 以后的职业规划
  • 如何跨标签页通信?比如一个页面和它里面的 iframe 通信
  • React、Vue和JQuery在什么场景下怎么选型
  • 你觉得你有做过推动流程或者改善流程的事件么,举例说明
  • ng 负载均衡的方式有哪些

原创文章,作者:一苇,如若转载,请注明出处:https://wsppx.cn/985/%e7%bd%91%e7%bb%9c%e5%bc%80%e5%8f%91/%e5%89%8d%e7%ab%af/

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注