1. HTTP/HTML浏览器
1.1 说一下HTTP和HTTPS
https的SSL加密是在传输层实现的。
http和https的基本概念
1.1.1 HTTP
http:超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地的传输协议,它可以使浏览器更加高效,使网络传输减少。
1.1.2 HTTPS
https:是以安全为目标的http通道,简单讲是http的安全版,即http下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
https协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。
1.2 HTTP1.0,HTTP1.1,HTTP2,0的区别
1.2.1 HTTP1.0
浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接。
1.2.2 HTTP1.1
- 引入了持久连接,即TCP连接默认不关闭,可以被多个请求复用。
- 同一个TCP连接里面,客户端可以同时发送多个请求。
- 虽然允许复用TCP连接,但是同一个TCP连接里面,所有的数据通信是按照次序进行的,服务器只有处理完一个请求,才会接着处理下一个请求。如果前面的处理的特别慢,后面就会有许多请求排队等着。
- 新增了一些请求方法,新增了一些请求头和请求头。
1.2.3 HTTP2.0
- 采用二进制格式而非文本格式
- 完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行。
- 使用报头压缩,降低开销。
- 服务器推送
1.3https协议的工作原理
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤 :
- 客户使用https url访问服务器,则要求web 服务器建立ssl链接。
- web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端。
- 客户端和web服务器端开始协商SSL链接的安全等级,也就是加密等级。
- 客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
- web服务器通过自己的私钥解密出会话密钥。
- web服务器通过会话密钥加密与客户端之间的通信。
1.4 https协议的优点
使用https协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
https协议是由SSL+HTTP协议构建的可进行加密传输,身份认证的网络协议,比http协议安全,可防止数据在传输过程中不被窃取、改变、确保数据的完整性。
https是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等http网站,采用https加密的网站在搜索结果中的排名将会更高。”
1.5 https协议的缺点
- https握手阶段比较费时,会使页面加载时间延长50%,增加10%-20%的耗电。
- https缓存不如http高效,会增加数据开销。
- SSL证书也需要钱,功能越强大的证书费用越高。
- SSL证书需要保定IP,不能在同一个IP上绑定多个域名,ipv4资源支持不了这种消耗。
1.6 TCP三次握手的过程(建立连接)
第一次握手:客户端发送一个SYN码给服务器,要求建立数据连接。
第二次握手:服务器发送SYN+ACK(确认包),发送给客户端,可以建立连接。
第三次握手:客户端再次发生ACK给服务器,服务器验证ACK没有问题,则建立起连接。
1.7 四次挥手的过程(关闭连接)
第一次挥手:客户端发送FIN报文,通知服务器数据已经传输完毕。
第二次挥手:服务器接收到之后,通知客户端我收到了SYN,发送ACK(确认包)给客户端,数据还没有传输完成。
第三次挥手:服务器已经传输完毕,服务器再次发送FIN通知客户端,数据已经传输完毕。
第四次挥手:客户端再次发送ACK,进入TIME_WAIT状态。服务器和客户端关闭连接。
1.8 为什么建立连接是三次握手,断开连接是四次挥手?
因为服务器端向客户端发送ACK和FIN是分开发送的,所以多了一次。
1.9 TCP和UDP的区别
- TCP是面向连接的,UDP是无连接的即发送数据前不需要先建立链接。
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复且按序到达;UDP尽最大努力交付,即不保证可靠交付。并且因为TCP可靠,面向连接,不会丢失数据因此适合大数据量交换。
- TCP是面向字节流的,UDP面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实施的应用比如IP电话和视频会议等)。
- TCP只能是1对1的,UDP支持1对1,1对多。
- TCP的首部较大为20字节,而UDP只有8字节。
- TCP是面向连接的可靠性传输,而UDP是不可靠的。
1.10 WebSocket的实现与应用
1.10.1 什么是WebSocket?
WebSocket是HTML5中的的协议,支持持久连续,http协议不支持持久性连接。http1.0和http1.1都不支持持久性的链接,HTTP1.1的keep-alive,将多个http请求合并为1个。
1.10.2WebSocket是什么样的协议,具体有什么优点?
HTTP的生命周期通过Request来界定,也就是Request一个Response,那么Http1.0协议中,这次htto请求就结束了。在Http1.1中进行了改进,是的有一个connection:Keep-alive,也就是说,在一个Http连接中可以发送多个Request,接受多个Response。但是必须记住,在Http中一个Request只能对应有一个Response,而且这个Response是被动的,不能主动发起。
WebSocket是基于http协议的,或者说借用了Http协议来完成一部分握手,在握手阶段与Http是相同的。我们来看一个webSocket握手协议的实现,基本是两个属性,upgrade,connection。
1.11 HTTP请求的方式,HEAD方式
head:类似于get请求,只不过返回的响应中没有具体的内容,用户获取报头。
options:允许客户端查看服务器的性能,比如说服务器支持的请求方式等等。
1.12 说一下web Quality(无障碍)
能够被残障人士使用的网站才能称得上一个易用的(易访问的)网站。
残障人士指的是那些带有残疾或者身体不健康的用户。
使用alt属性:
<img src = "person.jpg alt = "this is a person"
有时候浏览器会无法显示图像。具体的原因有:
- 用户关闭了图像显示
- 浏览器是不支持图形显示的迷你浏览器
- 浏览器是语音浏览器(供盲人和弱视人群使用)
- 如果您使用了alt属性,那么浏览器至少可以显示或读出有关图像的描述。
1.13 几个很实用的BOM属性对象方法?
什么是BOM? BOM是浏览器对象
有哪些常用的Bom属性呢?
1.13.1 lication对象
location.href
——返回或设置当前文档的URLlocation.search
——返回URL中的查询字符串部分。例如 http://www.dreamdu.com/dreamdu.php?id=5&name=dreamdu 返回包括(?)后面的内容?id=5&name=dreamdulocation.hash
——返回URL#后面的内容,如果没有#,返回空。location.host
——返回URL中的域名部分,例如www.dteamdu.comlocation.hostname
——返回URL中的主域名部分,dreamdu.comlocation.pathname
——返回URL的域名后的部分,例如 http://www.dreamdu.com/xhtml/ 返回/xhtml/location.port
– 返回URL中的端口部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回8080location.protocol
– 返回URL中的协议部分。例如 http://www.dreamdu.com:8080/xhtml/ 返回(//)前面的内容http:location.assign
– 设置当前文档的URLlocation.replace()
– 设置当前文档的URL,并且在history对象的地址列表中移除这个URL,location.replace(url);location.reload()
– 重载当前页面
1.13.2 history对象
history.go()
——进退或后退指定的页面数history.go(num);history.back
——后退一页history.forward
——前进一页
1.13.3 Navigator对象
navigator.userAgent
——返回用户代理头的字符串(就是包括浏览器版本信息的字符串)navigator.cookieEnabled
——返回浏览器是否支持(启用)cookie
1.14 说一下HTML5.0 drag api
- dragstart:事件主体是被拖放元素,在开始拖放被拖放元素时触发。
- darg:事件主体是被拖放元素,在正在拖放被拖放元素时触发。
- dragenter:事件主体是目标元素,在被拖放元素进入某元素时触发。
- dragover:事件主体是目标元素,在被拖放在某元素内移动时触发。
- dragleave:事件主体是目标元素,在被拖放元素移出目标元素是触发。
- drop:事件主体是目标元素,在目标元素完全接受被拖放元素时触发。
- dragend:事件主体是被拖放元素,在整个拖放操作结束时触发
1.15 补充400和401、403状态码
(1)400状态码:请求无效
产生原因:
前端提交数据的字段名称和字段类型与后台的实体没有保持一致
前端提交到后台的数据应该是json字符串类型,但是前端没有将对象JSON.stringify转化成字符串。
解决方法:
对照字段的名称,保持一致性
将obj对象通过JSON.stringify实现序列化
(2)401状态码:当前请求需要用户验证,权限不足
(3)403状态码:服务器已经得到请求,但是拒绝执行
1.16 fetch发送2次请求的原因
fetch发送post请求的时候,总是发送2次,第一次状态码是204,第二次才成功?
原因很简单,因为你用fetch的post请求的时候,导致fetch 第一次发送了一个Options请求,询问服务器是否支持修改的请求头,如果服务器支持,则在第二次中发送真正的请求。
1.17 Cookie、sessionStorage、localStorage的区别
共同点:都是保存在浏览器端,并且是同源的
Cookie:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下,存储的大小很小只有4K左右。 (key:可以在浏览器和服务器端来回传递,存储容量小,只有大约4K左右)
sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持,localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。(key:本身就是一个回话过程,关闭浏览器后消失,session为一个回话,当页面不同即使是同一页面打开两次,也被视为同一次回话)
localStorage:localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。(key:同源窗口都会共享,并且不会失效,不管窗口或者浏览器关闭与否都会始终生效)
补充说明一下cookie的作用:
保存用户登录状态。例如将用户id存储于一个cookie内,这样当用户下次访问该页面时就不需要重新登录了,现在很多论坛和社区都提供这样的功能。 cookie还可以设置过期时间,当超过时间期限后,cookie就会自动消失。因此,系统往往可以提示用户保持登录状态的时间:常见选项有一个月、三个 月、一年等。
跟踪用户行为。例如一个天气预报网站,能够根据用户选择的地区显示当地的天气情况。如果每次都需要选择所在地是烦琐的,当利用了cookie后就会显得很人性化了,系统能够记住上一次访问的地区,当下次再打开该页面时,它就会自动显示上次用户所在地区的天气情况。因为一切都是在后 台完成,所以这样的页面就像为某个用户所定制的一样,使用起来非常方便定制页面。如果网站提供了换肤或更换布局的功能,那么可以使用cookie来记录用户的选项,例如:背景色、分辨率等。当用户下次访问时,仍然可以保存上一次访问的界面风格。
1.18 说一下web worker
在HTML页面中,如果在执行脚本时,页面的状态是不可响应的,直到脚本执行完成后,页面才变成可响应。web worker是运行在后台的js,独立于其他脚本,不会影响页面你的性能。并且通过postMessage将结果回传到主线程。这样在进行复杂操作的时候,就不会阻塞主线程了。
如何创建web worker:
检测浏览器对于web worker的支持性
创建web worker文件(js,回传函数等)
创建web worker对象
1.19 对HTML语义化标签的理解
HTML5语义化标签是指正确的标签包含了正确的内容,结构良好,便于阅读,比如nav表示导航条,类似的还有article、header、footer等等标签。
1.20 iframe是什么?有什么缺点?
定义:iframe元素会创建包含另一个文档的内联框架
提示:可以将提示文字放在之间,来提示某些不支持iframe的浏览器
缺点:
会阻塞主页面的onload事件
搜索引擎无法解读这种页面,不利于SEO
iframe和主页面共享连接池,而浏览器对相同区域有限制所以会影响性能。
1.21 Doctype作用?严格模式与混杂模式如何区分?它们有何意义?
Doctype声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。
严格模式的排版和JS 运作模式是 以该浏览器支持的最高标准运行。
混杂模式,向后兼容,模拟老式浏览器,防止浏览器无法兼容页面。
1.22 Cookie如何防范XSS攻击
XSS(跨站脚本攻击)是指攻击者在返回的HTML中嵌入javascript脚本,为了减轻这些攻击,需要在HTTP头部配上,set-cookie:
httponly-这个属性可以防止XSS,它会禁止javascript脚本来访问cookie。
secure - 这个属性告诉浏览器仅在请求为https的时候发送cookie。
需要在http头部配上:Set-Cookie:httponly
1.23 Cookie和session的区别
作用范围不同,cookie保存在客户端(浏览器),session保存在服务器端。存取的方式不同,cookie只能保存ascii,session可以存任意的数据类型,一般情况下我们可以在session中保持一些常用的变量信息, 比如说userId。
1.24 click在ios上有300ms延迟,原因及如何解决?
(1)粗暴型,禁用缩放
(2)利用FastClick,其原理是:
检测到touchend事件后,立刻出发模拟click事件,并且把浏览器300毫秒之后真正出发的事件给阻断掉
1.25 addEventListener参数
addEventListener(event, function, useCapture)
其中,event指定事件名;function指定要事件触发时执行的函数;useCapture指定事件是否在捕获或冒泡阶段执行。
1.26 cookie sessionStorage localStorage区别
cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递
cookie数据还有路径(path)的概念,可以限制。cookie只属于某个路径下
存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如回话标识。
webStorage虽然也有存储大小的限制,但是比cookie大得多,可以达到5M或更大
数据的有效期不同sessionStorage:仅在当前的浏览器窗口关闭有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前一直有效,即使窗口和浏览器关闭
作用域不同sessionStorage:不在不同的浏览器窗口中共享,即使是同一个页面;localStorage:在所有同源窗口都是共享的;cookie:也是在所有同源窗口中共享的
1.27 cookie session区别
-
cookie数据存放在客户的浏览器上,session数据放在服务器上。
-
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。 -
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。 -
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
1.28 iframe通信,同源和不同源两种情况
同源:根据父页面以及cookie
不同源:设置子域的方法
1.29 介绍知道的http返回的状态码
- 100 Continue 继续。客户端应继续其请求
- 101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
- 200 OK 请求成功。一般用于GET与POST请求
- 201 Created 已创建。成功请求并创建了新的资源
- 202 Accepted 已接受。已经接受请求,但未处理完成
- 203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
- 204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
- 205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
- 206 Partial Content 部分内容。服务器成功处理了部分GET请求
- 300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
- 301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
- 302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
- 303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
- 304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
- 305 Use Proxy 使用代理。所请求的资源必须通过代理访问
- 306 Unused 已经被废弃的HTTP状态码
- 307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
- 400 Bad Request 客户端请求的语法错误,服务器无法理解
- 401 Unauthorized 请求要求用户的身份认证
- 402 Payment Required 保留,将来使用
- 403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
- 404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
- 405 Method Not Allowed 客户端请求中的方法被禁止
- 406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
- 407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
- 408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
- 409 Conflict 服务器完成客户端的PUT请求是可能返回此代码,服务器处理请求时发生了冲突
- 410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
- 411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
- 412 Precondition Failed 客户端请求信息的先决条件错误
- 413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
- 414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
- 415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
- 416 Requested range not satisfiable 客户端请求的范围无效
- 417 Expectation Failed 服务器无法满足Expect的请求头信息
- 500 Internal Server Error 服务器内部错误,无法完成请求
- 501 Not Implemented 服务器不支持请求的功能,无法完成请求
- 502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
- 503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
- 504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
- 505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
1.30 http常用请求头
协议头 | 说明 |
---|---|
Accept | 可接受的响应内容类型(Content-Type) |
Accept-Charset | 可接受字符集 |
Accept-Encoding | 可接受的相应内容的编码方式 |
Accept-Language | 可接受的响应内容语言列表 |
Accept-Datetime | 可接受的按照时间来表示的响应内容版本 |
Authorization | 用于HTTP协议中需要认证资源的认证信息 |
Cache-Control | 用于指定当前的请求/回复中的,是否使用缓存机制 |
Connection | 客户端(浏览器)想要优先使用的连接类型 |
Cookie | 由之前服务器通过Set-Cookie设置的一个HTTP协议Cookie |
Content-Length | 以8进制表示的请求体的长度 |
Content-MD5 | 请求体的内容的二进制MD5散列值(数字签名),以Base64编码的结果 |
Content-Type | 请求体的MIME类型(用于POST和PUT请求中) |
Date | 发送该消息的日期和时间(以RFC 7231中定义的“HTTP日期”格式来发送) |
Expect | 表示客户端要求服务器做出的特定的行为 |
From | 发起此请求的用户的邮件地址 |
Host | 表示服务器的域名以及服务器所监听的端口号。如果所请求的端口对应的服务的标准端口(80),则端口号可以省略。 |
If-Match | 仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要用于像 PUT 这样的方法中,仅当从用户上次更新某个资源后,该资源未被修改的情况下,才更新该资源。 |
If-Modified-Since | 允许在对应的资源未被修改的情况下返回304未修改 |
If-None-Match | 允许在对应的内容未被修改的情况下返回304未修改( 304 Not Modified ),参考 超文本传输协议 的实体标记 |
If-Range | 如果该实体未被修改过,则向返回所缺少的那一个或多个部分。否则,返回整个新的实体 |
If-Unmodified-Since | 仅当该实体自某个特定时间以来未被修改的情况下,才发送回应。 |
Max-Forwards | 限制该消息可被代理及网关转发的次数。 |
Origin | 发起一个针对跨域资源共享的请求(该请求要求服务器在响应中加入一个Access-Control-Allow-Origin的消息头,表示访问控制所允许的来源)。 |
Pragma | 与具体的实现相关,这些字段可能在请求/回应链中的任何时候产生。 |
Proxy-Authorization | 用于向代理进行认证的认证信息。 |
Range | 表示请求某个实体的一部分,字节偏移以0开始。 |
Referer | 表示浏览器所访问的前一个页面,可以认为是之前访问页面的链接将浏览器带到了当前页面。Referer其实是Referrer这个单词,但RFC制作标准时给拼错了,后来也就将错就错使用Referer了。 |
TE | 浏览器预期接受的传输时的编码方式:可使用回应协议头Transfer-Encoding中的值(还可以使用"trailers"表示数据传输时的分块方式)用来表示浏览器希望在最后一个大小为0的块之后还接收到一些额外的字段。 |
User-Agent | 浏览器的身份标识字符串 |
Upgrade | 要求服务器升级到一个高版本协议。 |
Via | 告诉服务器,这个请求是由哪些代理发出的。 |
Warning | 一个一般性的警告,表示在实体内容体中可能存在错误。 |
1.31 强缓存,协商缓存的区别
缓存分为两种:强缓存和协商缓存,根据响应的header内容来决定。
状态码 | 发送请求到服务器 | ||
---|---|---|---|
强缓存 | 从缓存取 | 200(from cache) | 否,直接从缓存取 |
协商缓存 | 从缓存取 | 304(not modified) | 是,通过服务器来告知缓存是否可用 |
强缓存相关字段有expires,cache-control。如果cache-control与expires同时存在的话,cache-control的优先级高于expires。
协商缓存相关字段有Last-Modified/If-Modified-Since,Etag/If-None-Match
1.32 讲讲304
304:如果客户端发送了一个带条件的GET请求已经被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务区应当返回这个304状态码。
1.33 强缓存、协商缓存什么时候用哪个
因为服务器上的资源不是一直固定不变的,大多数情况下它会更新,这个时候如果我们还访问本地缓存,那么对用户来说,那就相当于资源没有更新,用户看到的还是旧的资源;所以我们希望服务器上的资源更新了浏览器就请求新的资源,没有更新就使用本地的缓存,以最大程度的减少因网络请求而产生的资源浪费。
1.34 前端页面优化有哪些方法?**
- 降低请求量:合并资源,减少HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
- 加快请求速度:预解析DNS,减少域名数,并行加载,CDN 分发。
- 缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存localStorage。
- 渲染:JS/CSS优化,加载顺序,服务端渲染,pipeline。
- 图片比较多的网页使用图片懒加载。
- 在js中尽量减少闭包的使用
- 减少对dom的操作
1.35 GET和POST的区别
- get参数通过url传递,post放在request body中。
- get请求在url中传递的参数是有长度限制的,而post没有。
- get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
- get请求只能进行url编码,而post支持多种编码方式
- get请求会浏览器主动cache,而post支持多种编码方式。
- get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。
- GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
- GET产生一个TCP数据包;POST产生两个TCP数据包。
1.36 301和302的区别
301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302 Found 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
字面上的区别就是301是永久重定向,而302是临时重定向。
301比较常用的场景是使用域名跳转。302用来做临时跳转 比如未登陆的用户访问用户中心重定向到登录页面。
1.37 HTTP支持的方法
GET、POST、HEAD、OPTIONS、PUT、DELETE、TRACE、CONNECT
1.38 如何画一个三角形
三角形原理:边框的均分原理
div {
width:0px;
height:0px;
border-top:10px solid red;
border-right:10px solid transparent;
border-bottom:10px solid transparent;
border-left:10px solid transparent;
}
1.39 状态码304和200
状态码200:请求已成功,请求所希望的响应头或数据体将随此响应返回。即返回的数据为全量的数据,如果文件不通过GZIP压缩的话,文件是多大,则要有多大传输量。
状态码304:如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。即客户端和服务器端只需要传输很少的数据量来做文件的校验,如果文件没有修改过,则不需要返回全量的数据。
1.40 HTML5新增的元素
首先html5为了更好的实践web语义化,增加了header,footer,nav,aside,section等语义化标签,在表单方面,为了增强表单,为input增加了color,emial,data ,range等类型,在存储方面,提供了sessionStorage,localStorage,和离线存储,通过这些存储方式方便数据在客户端的存储和获取,在多媒体方面规定了音频和视频元素audio和vedio,另外还有地理定位,canvas画布,拖放,多线程编程的web worker和websocket协议
1.41 在地址栏里输入一个URL,到这个页面呈现出来,中间会发生什么?
- 查找浏览器缓存(浏览器缓存—系统缓存—路由器缓存)
- DNS解析
- TCP连接
- 发送HTTP请求
- 服务器处理请求并返回HTTP报文
- 浏览器解析渲染页面
- 连接结束
1.42 常见HTTP的头部
可以将http首部分为通用首部,请求首部,响应首部,实体首部
通用首部表示一些通用信息,比如date表示报文创建时间,
请求首部就是请求报文中独有的,如cookie,和缓存相关的如if-Modified-Since
响应首部就是响应报文中独有的,如set-cookie,和重定向相关的location,
实体首部用来描述实体部分,如allow用来描述可执行的请求方法,content-type描述主题类型,content-Encoding描述主体的编码方式
1.43 HTTP2.0 的特性
1、内容安全,应为http2.0是基于https的,天然具有安全特性,通过http2.0的特性可以避免单纯使用https的性能下降
2、二进制格式,http1.X的解析是基于文本的,http2.0将所有的传输信息分割为更小的消息和帧,并对他们采用二进制格式编码,基于二进制可以让协议有更多的扩展性,比如引入了帧来传输数据和指令
3、多路复用,这个功能相当于是长连接的增强,每个request请求可以随机的混杂在一起,接收方可以根据request的id将request再归属到各自不同的服务端请求里面,另外多路复用中也支持了流的优先级,允许客户端告诉服务器那些内容是更优先级的资源,可以优先传输,
1.44 cache-control的值有哪些
cache-control是一个通用消息头字段被用于HTTP请求和响应中,通过指定指令来实现缓存机制,这个缓存指令是单向的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
1.45 浏览器在生成页面的时候,会生成那两颗树?
构造两棵树,DOM树和CSSOM规则树
当浏览器接收到服务器相应来的HTML文档后,会遍历文档节点,生成DOM树,
CSSOM规则树由浏览器解析CSS文件生成。
1.46 图片的懒加载和预加载?
懒加载就是延迟加载。
当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次,俗称占位图),只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。
为什么要使用懒加载?
很多页面,内容很丰富,页面很长,图片较多。图片大小比较大,要是页面载入就一次性加载完毕,比较耗时,影响性能。
预加载,提前加载图片,当用户需要查看时可直接从本地缓存中渲染。
懒加载的实现步骤?
- 首先,不要将图片地址放到src属性中,而是放到其它属性(data-original)中。
- 页面加载完成后,根据scrollTop判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中。
- 在滚动事件中重复判断图片是否进入视野,如果进入,则将data-original属性中的值取出存放到src属性中。
为什么要使用预加载?
图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度。这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速、无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验。
实现预加载的方法有哪些?
方法一:用CSS和JavaScript实现预加载
方法二:仅使用JavaScript实现预加载
方法三:使用Ajax实现预加载
懒加载和预加载的区别:
两种技术的本质:两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。
2. JavaScript面试题
2.1 数组常用的方法
-
concat(),不改变原数组,
arr1.concat(arr2)
连接两个或多个数组,返回一个新的数组。 -
join(),不改变原数组,
join(str)
数组转换成字符串,方法只接受一个参数,默认为逗号分隔符。实现重复字符串。const str = new Array(4).join('啦') console.log(str) //啦啦啦
-
push() & unshift() 添加元素操作,改变了原数组。
- push()向数组的末尾添加一个或多个元素,并返回新的长度。
- unshift()向数组的开头添加一个或多个元素,并返回新的长度。
-
shift() & pop()删除元素操作,改变了原数组
- shift()删除并返回数组第一个元素
- pop()删除并返回数组最后一个元素
-
sort()数组排序,改变原数组,sort()对数组的元素进行排序。sort() 不按照数组元素数值的大小对数字进行排序,是按照字符编码的顺序进行排序
-
reverse()反转数组,改变原数组。reverse() 颠倒数组中元素的顺序。
-
slice()截取数组,不改变原数组。arr.slice(start, end) 从start处开始选取(不包括该元素),从end处结束选取,如果为空的话,那么选取从start到数组结束的所有元素。负数代表方向,从数组尾部开始计算位置。
const arr = [1, 2, 3, 4, 6] console.log(arr.slice(1)) // [2, 3, 4, 6] console.log(arr.slice(1, -2)) // [2, 3] console.log(arr.slice(-3, 1)) // [2] console.log(arr) // [1, 2, 3, 4, 6]
-
splice()更新数组,,改变原数组,
arr.splice(index, howmany, item1,...,itemX)
向/从数组中添加/删除项目,然后返回被删除的项目,返回含有被删除的元素的数组,若没有删除元素则返回一个空数组。
2.2 new操作符具体干了什么?
- 创建一个空对象,并且this变量引用该对象,同时还继承了该函数的原型。
- 属性和方法被加入到this引用的对象中。
- 新创建的对象由this所引用,并且最后隐式的返回this。
2.3 eval是做什么的?
它的功能是把对应的字符串解析成js代码并运行,应该避免使用eval,不安全,非常消耗性能(2次,依次解析成js语句,一次执行)。
2.4 箭头函数有哪些特点?
不需要function关键字来创建函数,省略return关键字,改变this指向。
2.5 js的数据类型?什么是基本类型?什么是引用类型?
数据类型只要包括两部分:
基本数据类型:Undedined、Null、Boolean、Number、String
引用数据类型:Object(包括Object、Array、Function)
ES6新增:Symbol(创建后独一无二且不可变的数据类型)
2.6 NaN、null和undefined的区别?
NaN:保留字(不是数字),NaN和任何数据都不相等,包括NaN本身,其他数据类型和NaN运算的结果都是NaN.
null:表示一个对象被定义了,值为“空值”。
undefined:表示不存在这个值。
- 变量被声明了,但没有赋值,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
2.7 document.write和innerHTML的区别?
documen.write只能重绘整个页面。
innerHTML可以重绘页面的一部分。
2.8 AJAX的过程?
- 创建XMLHttpRequest对象,也就是创建一个异步调用对象。
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL以及验证信息。
- 设置响应HTTP请求状态变化的函数。
- 发送HTTP请求。
- 获取异步调用返回的数据。
- 使用Javascript和DOM实现局部刷新。
2.9 请解释下JavaScript的同源策略?
概念:同源策略是客户端脚本,其目的是防止某个文档或脚本从多个不同源装载。
这里的同源策略指的是:协议、域名、端口相同。
同源策略是一种安全协议,指一段脚本只能读取来自同一来源的窗口和文档的属性, 不同源的客户端脚本在没有明确的授权下,不能读写对方资源 。
2.10 同源策略限制了什么内容?
它限制了一个源(origin)加载的文档或脚本如何与来自另一个源的资源交互。
2.11 如何解决跨域问题?
1.使用jsonp实现,网页通过script标签向服务器请求json数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数里面传给前端。
2.使用Jquery.ajax实现
$.ajax({
url: 'http://www.test.com:8888/getData',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {}
})
3.在vue开发中实现跨域:在vue项目根目录下找到vue.config.js文件,在proxy中设置跨域。在vue是中使用proxy进行跨域的原理是:将域名发送给本地的服务器(启动vue项目的服务,localhost:8080),再由本地的服务器去请求真正的服务器。
2.12 ES6新特性有哪些?
1.不一样的变量声明:const和let
2.模板字符串:基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定。ES6反引号(``)直接搞定。
3.箭头函数:ES6中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个=>,紧接着是函数体。
箭头函数最直观的三个特点:
- 不需要function关键字来创建函数。
- 省略return关键字。
- 继承当前上下文this关键字。
4.函数的参数默认值
// ES6之前,当未传入参数时,text = 'default';
function printText(text) {
text = text || 'default';
console.log(text);
}
// ES6;
function printText(text = 'default') {
console.log(text);
}
printText('hello'); // hello
printText();// default
5.对象和数组解构
// 对象
const student = {
name: 'Sam',
age: 22,
sex: '男'
}
// 数组
// const student = ['Sam', 22, '男'];
// ES5;
const name = student.name;
const age = student.age;
const sex = student.sex;
console.log(name + ' --- ' + age + ' --- ' + sex);
// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);
6.for…of 和 for…in
for…of 用于遍历一个迭代器,允许遍历获取键值如数组:
let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
console.log(letter);
}
// 结果: a, b, c
for…in 用于遍历对象中的属性,只能获取对象的键名,不能获取键值:
let stus = ["Sam", "22", "男"];
for (let stu in stus) {
console.log(stus[stu]);
}
// 结果: Sam, 22, 男
2.13 js的事件委托/事件代理
利用js事件冒泡动态为元素绑定事件的方法称为事件委托,为称为事件代理。
事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown等)委托给它的父元素,让父元素来监听子元素的冒泡事件。并在子元素发生事件冒泡时找到这个子元素。
2.14 为什么要使用事件委托?
在javascript中,页面内事件处理程序的个数会直接影响页面的整体性能,因为每个事件处理程序都是对象,对象会占用内存,内存中的对象越多,页面的性能则越差。此外,事件处理程序需要与DOM节点进行交互,访问DOM的次数越多,引起浏览器重绘和重排的次数也就越多,从而影响页面的性能。
当页面重很多表格或列表需要添加事件时,如果逐个添加那就太麻烦了,但是使用事件委托就能极大的减轻我们的工作量,同时也能提高页面的性能。
2.15 事件委托的原理?
事件委托是利用事件的冒泡原理来实现的,大致可以分为三个步骤:
1.确定要添加事件元素的父级元素;
2.给父元素定义事件,监听子元素的冒泡事件。
3.使用event.target来定位触发事件冒泡的子元素。
注意:使用事件委托时,并不是说把事件委托随意一个父元素就行。因为事件冒泡的过程也需要消耗事件,距离越远,所需的事件也就越长,所有最好在直接父元素上使用事件委托。
2.16 js事件委托的优点?
-
减小内存消耗
-
动态绑定事件
2.17 减少一下闭包和闭包常用的场景?
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包常见的方式,就是在一个函数内部创建另一个函数。
使用闭包主要为了设计私有的方法和变量,闭包的优点是可以避免变量的污染,缺点是闭包会常驻内存,会增加内存使用量,使用不当很容易造成内存泄漏。在js中,函数即闭包,只有函数才会产生作用域的概念。
闭包的三个特性:
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
闭包的两个作用:
- 子函数可以访问父函数中的所有局部变量。
- 保护变量不受外界的污染。
应用场景:设置私有变量的方法
不适用场景:返回闭包的函数时个非常大的函数
闭包的缺点就是常驻内存,会增大内存使用量,使用不当会在造成内存泄漏。
2.18 javascript原型,原型链?有什么特点?
每个对象都会在其内部初始化一个属性,就是prototype(原型),当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去prototype里面找这个属性,这个prototype又会有自己的prototype,于是就这样一直查找下去,也就是我们平时所说的原型链概念。
关系:instance.construction.prototype = instance.proto
特点:javascript对象是通过引用来传递的,我们创建的每个新对象实体中并没有一份属于自己的原型副本。当我们修改原型时,与之相关的对象也会继承这一改变。
2.19 什么是回调函数?
回调函数:当一个函数作为参数传入另一个参数中,并且他不会立即执行,只有当满足一定条件后该函数才可以执行,这种函数就称为回调函数。我们熟悉的定时器和ajax就存在有回调函数。
2.20 什么是回调地狱?如何解决回调地狱?
回调函数中嵌套回调函数的情况就叫做回调地狱 。
在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱。
解决方法有:异步回调——generator函数、promise对象、async / wait函数。
promise对象解决异步回调地狱
pronise是js中的一个原生对象,是一种异步编程的解决方案,用来传递异步编程操作的信息。
有了promise对象,就可以让异步操作以及同步操作的流程来表达出来,避免层层嵌套的回调地狱。
- promise构造函数接受一个函数作为参数,我们需要处理的异步任务就写在该函数体内,该函数的两个参数是resolve,reject。异步任务执行成功时调用resolve函数返回结果,反之调用reject。
- promise对象的then方法用来接受处理成功时相应的数据,catch方法用来接受处理失败时相应的数据。
- promise的链式编程可以保证代码的执行顺序,前提是每一次在then做完处理后,一定要return一个Promise对象,这样才能在下一次then时接收到数据。
promise 代表一个异步状态,有三个状态 pending(进行中), Resolve(以完成),Reject(失败) 。
一旦状态改变,就不会在变。任何时候都可以得到结果。从进行中变为以完成或者失败。
promise.all() 里面状态都改变,那就会输出,得到一个数组。
promise.race() 里面只有一个状态变为 rejected 或者 fulfilled 即输出。
promis.finally()不管指定不管 Promise 对象最后状态如何,都会执行的操作(本质上还是 then 方法的特例) 。
async/await解决异步回调地狱
async,作为一个关键字放到声明函数前面,表示该函数为一个异步任务,不会阻塞后面函数的执行。 和Promise对象一样,处理异步任务时也可以按照成功和失败来返回不同的数据,处理成功时用then方法来接收,失败时用catch方法来接收数据 。
await关键字:
- await关键字只能在使用async定义的函数中使用。
- await后面只能跟一个promise实例对象(可以跟任何表达式,更多的是跟一个返回的promise对象的表达式)。
- await函数不能单独使用。
- await可以直接拿到promise中resolve中的数据。
2.21 js中同步和异步,以及js的事件流
同步:在同一时间内做一件事情
异步:在同一时间内做多个事情,js是单线程的,每次只能做一件事情,js运行在浏览器中,浏览器是多线程的,可以在同一时间内执行多个任务。
js事件流: 在js中,事件流就是事件在目标元素和祖先元素间的触发顺序。按照事件传播的顺序,事件流可分两种:
1、冒泡型事件流,事件的传播是从最特定的事件目标到最不特定的事件目标;
2、捕获型事件流,事件的传播是从最不特定的事件目标到最特定的事件目标。
2.22 call bind apply 的区别?
call() 和 apply()的第一个参数相同,就是指定的对象。这个对象就是 该函数的执行上下文。
call()和 apply()的区别就在于,两者之间的参数。 call()在第一个参数之后的 后续所有参数就是传入该函数的值。 apply() 只有两个参数,第一个是对象,第二个是数组,这个数组就是 该函数的参数。
bind() 方法和前两者不同在于: bind() 方法会返回 执行上下文被改变的函数而不会立即执行,而前两者是 直接执行该函 数。他的参数和 call()相同。
2.23 谈一谈深克隆和浅克隆?
浅克隆: 只是拷贝了基本类型的数据,而引用类型数据,复制后也是会发生引用,我们把这种拷贝叫做“(浅复制)浅拷贝”,换句话说, 浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了, 那么浅复制出来的对象也会相应改变。
深克隆: 创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
JSON.parse、JSON.stringify()
2.24 实现浅拷贝的方法
- for…in只循环第一层
- Object.assign方法
- 直接用=赋值
2.25 实现深拷贝的方法
-
采用递归去拷贝所有层级属性
-
通过json对象来实现深拷贝。缺点:无法实现对对象中方法的深拷贝,会显示为undefine
-
通过JQuery的extend方法实现深拷贝
var array = [1,2,3,4]; var newArray = $.extend(true, [], array) //true为深拷贝,false为浅拷贝
-
lodash函数库实现深拷贝
let result = _.cloneDeep(test)
-
reflect法
// 代理法 function deepClone(obj) { if (!isObject(obj)) { throw new Error('obj 不是一个对象!') } let isArray = Array.isArray(obj) let cloneObj = isArray ? [...obj] : { ...obj } Reflect.ownKeys(cloneObj).forEach(key => { cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key] }) return cloneObj }
-
如果对象的value是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
var obj = { a: 1, b: 2 } var obj1 = Object.assign({}, obj); // obj赋值给一个空{} obj1.a = 3; console.log(obj.a);// 1
-
用slice实现对数组的深拷贝
// 当数组里面的值是基本数据类型,比如String,Number,Boolean时,属于深拷贝 // 当数组里面的值是引用数据类型,比如Object,Array时,属于浅拷贝 var arr1 = ["1","2","3"]; var arr2 = arr1.slice(0); arr2[1] = "9"; console.log("数组的原始值:" + arr1 ); console.log("数组的新值:" + arr2 );
3. CSS面试题
3.1 介绍一下css的盒子模型
css的盒模型有两种:标准(W3C)盒模型和IE盒模型。
盒模型:内容(content)、填充(padding)、边界(margin)、边框(border)
区别:IE的content部分把border和padding计算了进去。
3.2 css选择器优先级?
!impotant > 行内样式(比重1000) > ID选择器(比重100) > 类选择器(比重10) > 标签(比重1) > 通配符 > 继承 > 浏览器默认属性
3.3 常用的css不可继承的属性?
- display:规定元素应该生成的框的类型
- text-decoration:规定添加到文本的装饰
- text-shadow:文本阴影效果
- white-space:空白符的处理
- 盒子模型的属性:width、height、margin 、border、padding
- 背景属性:background
- 定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
3.4 常用的css可继承的属性有哪些?
- font:组合字体
- font-family:规定元素的字体系列
- font-weight:设置字体的粗细
- font-size:设置字体的尺寸
- font-style:定义字体的风格
- text-indent:文本缩进
- text-align:文本水平对齐
- line-height:行高
- color:文本颜色
- visibility:元素可见性
- 光标属性:cursor
3.5 所有元素可以继承的属性
元素可见性:visibility
光标属性:cursor
2.6内联元素可以继承的属性?
字体系列属性
除text-indent、text-align之外的文本系列属性。
3.7 块级元素可以继承的属性
text-indent、text-align
css属性一旦继承了不能被取消,只能重新定义样式。
3.5 画一条0.5px的线
height: 1px;
transform: scale(0.5);
3.6 垂直居中的几种方式
单行文本:line-height = height
图片:vertical-align: middle
absolute定位:top:50%;left:50%;transform:translate:(-50%,-50%)
flex:display:flex;margin:auto
3.7 简单说一下css中的link和@inport的区别和用法?
link是xhtml标签,除了加载css外,还可以定义RSS等其他事务;@import属于css范畴,只能加载css。
link引用css时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
link是XHTML标签,无兼容问题;@import是在css2.1提出的,低版本的浏览器不支持。
link支持使用javascript控制dom去改变样式;而@import不支持。
3.8 rgba和opcacity的透明效果有什么不同?
opacity会继承父元素的opacity属性,而RGBA设置的元素后代不会继承不透明属性。
3.9 display:none和visibility:hidden的区别?
-
display:none隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢,就当不存。
-
visibility:hidden隐藏对应的元素,但是在文档布局仍保留原来的空间。
3.10 position的值,relative和absolute分别是对应谁进行定位的?
-
relative:相对定位,相对于自己本身在正常文档流中的位置进行定位。
-
absolute:绝对定位,相对于最近一级定位不为static的父元素进行定位。
-
fixed:(老版本IE不支持),固定定位,相对于浏览器窗口或者frame进行定位。
-
static:默认值,没有定位,元素出现在正常的文档流中。
-
sticky:生成粘性定位的元素,容器的位置根据正常文档流计算得出。
3.11 css3的新特性?
-
transtion transition-property 规定设置过渡效果的 CSS 属性的名称。
-
transition-duration 规定完成过渡效果需要多少秒或毫秒。
-
transition-timing-function 规定速度效果的速度曲线。
-
transition-delay 定义过渡效果何时开始。
-
animation 属性可以像 Flash 制作动画一样,通过控制关键帧来控制 动画的每一步,实现更为复杂的动画效果。
-
ainimation 实现动画效果主要由两部分组成: 通过类似 Flash 动画中的帧来声明一个动画; 在 animation 属性中调用关键帧声明的动画。
-
translate 3D 建模效果
3.12 css的Sprites
CSS Sprites
在国内很多人叫css精灵,是一种网页图片应用处理方式。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像以前那样一幅一幅地慢慢显示出来了。
利用CSS的“background-image”
,“background- repeat”
,“background-position”
的组合进行背景定位,background-position
可以用数字精确的定位出背景图片的位置。
利用CSS Sprites能很好地减少网页的http请求,从而大大的提高页面的性能,这也是CSS Sprites
最大的优点,也是其被广泛传播和应用的主要原因;
CSS Sprites能减少图片的字节,曾经比较过多次3张图片合并成1张图片的字节总是小于这3张图片的字节总和。
解决了网页设计师在图片命名上的困扰,只需对一张集合的图片上命名就可以了,不需要对每一个小元素进行命名,从而提高了网页的制作效率。
更换风格方便,只需要在一张或少张图片上修改图片的颜色或样式,整个网页的风格就可以改变。维护起来更加方便。
4. Jquery面试题
4.1 JQuery链式调用的原理?
正常的一个obj对象在调用自身的某个方法后,正常的返回是underfine。但是链式调用的关键就是在函数执行后return this
返回自身实例,然后就可以继续调用自身方法实现链式调用。JQuery中,$("#id")
会获取该结点的信息obj
,涵多个属性及方法(执行return this
)。
5. GITEE面试题
5.1 git rebase和git merge的区别?
git merge
的优势是它保留了分支的结构与历史提交目录,但同时这也导致了提交历史会被大量的 merge
污染
git rebase
的优势是可以获得更清晰的项目历史。首先,它消除了 git merge
所需的不必要的合并提交;其次,rebase
会产生完美线性的项目历史记录,你可以在 feature
分支上没有任何分叉的情况下一直追寻到项目的初始提交。
但是, rebase
会丢失合并提交的上下文, 使我们无法看到真实的更改是何时合并到目标分支上的
5.2 进程和线程有什么区别?
-
根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位
-
资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
-
包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
-
内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的
-
影响关系:一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
-
执行过程:每个独立的进程有程序运行的入口、顺序执行序列和程序出口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制,两者均可并发执行
6. Vue面试题
6.1 谈谈对vue的理解?
vue 是一个渐进式的 JS 框架。他易用,灵活,高效; 可以把一个页面 分隔成多个组件;当其他页面有类似功能时,直接让封装的组件进行 复用; 他是构建用户界面的声明式框架,只关心图层;不关心具体是 如何实现 的。
6.2 V-model 的原理是什么?
Vue 的双向数据绑定是由数据劫持结合发布者订阅者实现的。 数据劫持是通过 Object.defineProperty()来劫持对象数据的 setter 和 getter 操作。 在数据变动时作你想做的事。
原理 通过 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化->视图更新 在初始化 vue 实例时,遍 历 data 这个对象,给每一个键值对利用 Object.definedProperty 对 data 的键值对新增 get 和 set 方法,利用了事件监听 DOM 的机制, 让视图去改变数据
6.3 Vue的生命周期
-
beforeCreate阶段:vue实例的挂载元素el和数据对象data都是undefined,还没有初始化。
-
created阶段:vue实例的数据对象data有了,可以访问里面的数据和方法,未挂载到dom,el还没有。
-
beforeMount阶段:vue实例的el和data都初始化了,但是挂在之前为虚拟的dom。
-
Mounted阶段:vue实例挂在到真实的dom上,就可以通过dom获取dom节点。
-
beforeUpdate:响应式数据更新时调用,发生在虚拟dom打补丁之前,适合在更新之前访问现有的dom,比如手动移除已添加的时间监听器。
-
updated阶段:虚拟dom重新渲染和打补丁之后调用,组成新的dom已经更新,避免在这个钩子函数中操作数据,防止死循环。
-
beforeDestory阶段:实例销毁前调用,实例还可以用,this能获取到实例,常用于销毁定时器,解绑事件。
-
destory阶段:实例销毁后调用,调用后所有事件监听器会被移除,所有的子实例都会被销毁。
6.4 为什么在大型项目中data需要使用return返回数据呢?
不使用return包裹的数据会在项目的全局可见,会造成变量污染。
使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。
6.5 v-show和v-if的区别?
-
**v-show:**通过css样式中的display:none控制元素的显示,隐藏。
-
**v-if:**通过控制vue的虚拟dom上的节点,来联动控制真实dom上的节点,从而控制元素的显示,隐藏。
6.6 v-if 和v-for为什么避免一起使用?
原因:v-for 比 v-if 优先级高,所以使用的话,每次v-for 都会执行 v-if ,造成不必要的计算,影响性能, 尤其是当之需要渲染很小一部分的时候。
6.7 说说你对nextTick的理解?
nextTick:就是在下次dom更新循环结束之后执行延迟回调。在修改数据后立即使用这个方法,获取更新之后的dom。
使用场景:如果想要在修改数据后立即得到更新的dom结构,可以使用Vue.nextTick()
。
第一个参数为:回调函数(可以获取最新的dom结构)
第二个参数为:执行函数上下文。
6.8 说说你对slot的理解?slot的使用场景有哪些
slot是什么?
在HTML中slot
元素,作为web compinents
技术套件的一部分,是web组件内的一个占位符。该占位符可以在后期使用自己的标记语言填充。
在Vue中,也是插槽的意思,我们可以理解为slot
在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填坑(替换组建模板中slot
位置),作为承载分发内容的出口。
使用场景:
通过插槽可以让用户可以拓展组件,去更好地复用组件和对其做定制化处理。
如果父组件在使用到一个复用组件的时候,获取这个组件在不同的地方有少量的更改,如果去重写组件是一件不明智的事情。
通过slot
插槽向组件内部指定位置传递内容,完成这个复用组件在不同场景的应用。
比如布局组件、表格列、下拉选、弹框显示内容等。
slot
可以分来以下三种?
- 默认插槽
- 具名插槽
- 作用域插槽
默认插槽:子组件用标签来确定渲染的位置,标签里面可以放DOM
结构,当父组件使用的时候没有往插槽传入内容,标签内DOM
结构就会显示在页面。父组件在使用的时候,直接在子组件的标签内写入内容即可。
**具名插槽:**子组件用name
属性来表示插槽的名字,不传为默认插槽。父组件中在使用时在默认插槽的基础上加上slot
属性,值为子组件插槽name
属性值。
**作用域插槽:**子组件在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件v-slot
接受的对象上。父组件中在使用时通过v-slot:
(简写:#)获取子组件的信息,在内容中使用。
总结:
v-slot
属性只能在`上使用,但在只有默认插槽时可以在组件标签上使用- 默认插槽名为
default
,可以省略default直接写v-slot
- 缩写为
#
时不能不写参数,写成#default
- 可以通过解构获取
v-slot={user}
,还可以重命名v-slot="{user: newName}"
和定义默认值v-slot="{user = '默认值'}"
。
原理分析: slot
本质上是返回VNode
的函数,一般情况下,Vue
中的组件要渲染到页面上需要经过template -> render function -> VNode -> DOM
过程。
6.9 你对SPA单页面的理解?
SPA(single-page application),单页面应用。SPA是一种网络应用程序或网站的模型,它通过静态重写当前页面来与用户交互,这种方法避免了页面之间切换打断用户体验在单页应用中,所有必要的代码(HTML、JavaScript和CSS)都通过单个页面的加载而检索,或者根据需要(通常是为响应用户操作)动态装载适当的资源并添加到页面,页面在任何时间都不会被重新加载,也不会控制转移到其他页面。
举个例子来讲,就是一个杯子,早上装的牛奶,中午装的是开水,晚上装的是茶,我们发现变得始终是杯子里的内容,而杯子始终是那个杯子。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D81Uj9RJ-1673000743079)(C:\Users\jiayin\AppData\Roaming\Typora\typora-user-images\1647951750984.png)]
我们熟知的js框架如react、vue、angular、都属于SPA
6.10 SPA(单页应用)的优缺点?
6.10.1 优点:
- 具有桌面应用的即时性、网站的可移植性和可访问性。
- 用户体验好,快,内容的改变不需要重新加载整个页面。
- 良好的前后端分离,分工更明确。
6.10.2 缺点:
- 不利于搜索引擎的抓取
- 首次渲染速度相对较慢。
6.11 SPA与MPA的区别:
多页应用MPA(multipage-page application),在MPA中,每个页面都是一个主页面,都是独立的,当我们在访问另一个页面的时候,都需要重新加载html、css、js文件,公共文件则根据需求按需加载。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-naCPUlQD-1673000743081)(C:\Users\jiayin\AppData\Roaming\Typora\typora-user-images\1647952347957.png)]
单页应用于多页应用的区别
SPA | MPA | |
---|---|---|
组成 | 一个主页面和多个页面片段 | 多个主页面 |
刷新方式 | 局部刷新 | 整页刷新 |
url模式 | 哈希模式 | 历史模式 |
SEO搜索引擎优化 | 难实现,可使用SSR方式改善 | 容易实现 |
数据传递 | 容易 | 通过url、cookie、localStorage等传递 |
页面切换 | 速度快,用户体验良好 | 切换加载资源,速度慢,用户体验差 |
维护成本 | 相对容易 | 相对复杂 |
6.12 Vue3更新了哪些新特性?
在vue3中,新增了一个setup生命周期函数,setup执行的时机是在beforeCreate声明函数之前执行,因此在这个函数中是不能通过this来获取实例的。同时为了命名统一,将beforeDestory改名为beforeUnmount,destoryed改名为unmount。
同时,vue3新增了生命周期沟子,我们可以通过在生命周期函数前加on
来访问组件的生命周期。
**ref()函数:**ref()这个函数使得我们的变量拥有了双向绑定属性。
使用步骤:
- 引入ref
- 给变量赋初始值,
ref(1)
- 重点!!变量的值要用
.value
来获取,例如a, a.value
reactive()函数:这也是和ref一样使得我们的变量拥有了双向绑定属性,这个函数接受一个对象作为参数。
6.13 vue3 proxy实现双向数据绑定的原理?
什么是Proxy?它的作用是什么?
Proxy可以理解成,在目标对象之前架设一层“拦截”,当外界对该对象访问时侯,都必须经过这次拦截,而Proxy就充当了这种机制,类似于代理的含义,他可以对外界访问对象之前进行过滤和改写该对象。
Object.defineProperty的缺点:
- 深度监听需要一次性递归(遍历每个对象的每个属性,如果对象嵌套很深的话,需要使用递归调用。)
- 无法监听新增属性 / 删除属性(Vue.set Vue.delete,未在data中定义的属性会报undefined)
- 无法原生监听数组,需要特殊处理。
6.14 Vue通信方式?父子组件如何通信?兄弟组件如何进行数据通信?
6.14.1 方法一:props/$emit
父组件A通过props的方式向子组件B传递,B to A通过B组件中 $emit ,A组件中 v-on 的方式实现。
父组件通过props向下传递数据给子组件,注:组件中的数据共有三种形式:data、props、computed。
子组件通过events(通过事件形式)给父组件发送消息,实际上就是子组件把自己的数据发送到父组件。
6.14.2 方法二:$emit / $on
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。
6.14.3 方法三:vuex
vuex实现了一个单向数据流,在全局拥有一个state存放数据,当组件要更改state中的数据时,必须通过mutation进行,mutation同时提供了订阅者模式供外部插件调用获取state数据的更新。而当所有异步操作或批量的同步操作需要走Action,但是Action也是无法直接修改的State,还是需要通过mutation来修改state的数据。最后,根据State的变化,渲染到视图上。
6.15 vuex的流程
页面通过mapAction
异步提交事件到action
。action
通过commit
把对应参数同步提交到mutation
。mutation
会修改state
中对应的值。最后通过getter
把对应值跑出去,在页面的计算属性中通过mapGetter
来动态获取state
中的值。
6.16 vuex有哪几种状态和属性?
- state 中保存着共有数据,数据是响应式的 。
- getter 可以对 state 进行计算操作,主要用来过滤一些数据,可以在 多组件之间复用。
- mutations 定义的方法动态修改 state 中的数据,通过 commit 提交 方法,方法必须是同步的 。
- actions 将 mutations 里面处理数据的方法变成异步的,就是异步操 作数据,通 store.dispatch 来分发 actions,把异步的方法写在 actions 中,通过 commit 提交 mutations,进行修改数据。
- modules:模块化 vue
6.17 Vue的前端路由的两种模式?
hash和history。
hash:——即地址栏URL中的#符号,hash虽然出现在URL中,但不会被包含在HTTP请求中,对后端完全没有影响,因此改变hash不会重新加载页面。
hisstory——利用了HTML5 History Interface中新增的pushState()和replaceState()方法。
这两个方法应用于浏览器的历史记录站,在当前已有的back、forward、go的基础之上,他们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的URL,但浏览器不会立即向后端发送请求。
6.18 vue中Key的作用?
当vue.js用v-for
正在更新已渲染过的元素列表时,它默认用“就地复用”的策略。如果数据项的顺序被改变,Vue将不会移动Dom元素来匹配数据项的顺序,而是简单复用此处的每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
Key的作用主要是为了更高效的更新虚拟dom。
6.19 $route
和$router
的区别?
$route
是路由信息对象,包括path、params、hash、query、fullPath、matched、name等路由信息参数。
$router
是路由实例对象,包含了路由的跳转方法,钩子函数等。
6.20 vue-router
守卫?
导航守卫router.beforeEach
全局前置守卫
to:Router
——即将要进入的目标(路由对象)
from: Router
——当前导航正要离开定位路由
next: Function
——一定要调用该方法来resolve这个钩子。(一定要用这个函数才能去到下一个路由,如果不用就拦截)执行效果依赖next方法的调用参数。
next()
——进行管道中的下一个钩子。如果全部钩子执行完了,则导航的转态就是confirm(确认的)。
next(false)
——取消进入路由,url地址重置为from路由地址(也就是将会要离开的路由地址)
6.21 vue.extend 和 vue.component
extend是构造一个组件的语法器。然后这个你可以作用到Vue.component这个全局注册方法里,还可以在任意vue模板里使用组件。也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件。
Vue.component你可以创建,也可以取组件。
6.22 vue的修饰符
-
stop:阻止事件的冒泡
-
prevent:阻止事件的默认行为
-
once:只触发一次
-
self:只触发自己的事件行为时,才会执行
6.23 vue项目中的性能优化
-
不要在模板里面写过多的表达式
-
循环调用子组件时添加key
-
频繁切换的使用v-show,不频繁切换的使用v-if
-
尽量少用float,可以用flex
-
按需加载,可以用require或者import()按需加载需要的组件。
-
路由懒加载。
6.24 axios是什么?怎么使用? 描述使用它实现登录功能的流程?
axios是请求后台资源的模块。
$ npm install axios -S
安装好
然后发送的是跨域,需在配置文件中config / index.js
进行设置。后台如果是TP5则定义一个资源路由。js中使用import导入进来,然后.get或者.post
。如果成功返回在.then
函数中,失败咋是在.catch
函数中。
6.25 MVC和MVVM的区别是什么?
MVC和MVVM的区别并不是VM完全取代了C,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用。
-
MVC中Controller演变成MVVM中的ViewModel
-
MVVM通过数据来显示视图层而不是节点操作
-
MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验等问题。
是路由信息对象,包括path、params、hash、query、fullPath、matched、name等路由信息参数。
$router
是路由实例对象,包含了路由的跳转方法,钩子函数等。
6.20 vue-router
守卫?
导航守卫router.beforeEach
全局前置守卫
to:Router
——即将要进入的目标(路由对象)
from: Router
——当前导航正要离开定位路由
next: Function
——一定要调用该方法来resolve这个钩子。(一定要用这个函数才能去到下一个路由,如果不用就拦截)执行效果依赖next方法的调用参数。
next()
——进行管道中的下一个钩子。如果全部钩子执行完了,则导航的转态就是confirm(确认的)。
next(false)
——取消进入路由,url地址重置为from路由地址(也就是将会要离开的路由地址)
6.21 vue.extend 和 vue.component
extend是构造一个组件的语法器。然后这个你可以作用到Vue.component这个全局注册方法里,还可以在任意vue模板里使用组件。也可以作用到vue实例或者某个组件中的components属性中并在内部使用apple组件。
Vue.component你可以创建,也可以取组件。
6.22 vue的修饰符
-
stop:阻止事件的冒泡
-
prevent:阻止事件的默认行为
-
once:只触发一次
-
self:只触发自己的事件行为时,才会执行
6.23 vue项目中的性能优化
-
不要在模板里面写过多的表达式
-
循环调用子组件时添加key
-
频繁切换的使用v-show,不频繁切换的使用v-if
-
尽量少用float,可以用flex
-
按需加载,可以用require或者import()按需加载需要的组件。
-
路由懒加载。
6.24 axios是什么?怎么使用? 描述使用它实现登录功能的流程?
axios是请求后台资源的模块。
$ npm install axios -S
安装好
然后发送的是跨域,需在配置文件中config / index.js
进行设置。后台如果是TP5则定义一个资源路由。js中使用import导入进来,然后.get或者.post
。如果成功返回在.then
函数中,失败咋是在.catch
函数中。
6.25 MVC和MVVM的区别是什么?
MVC和MVVM的区别并不是VM完全取代了C,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。也就是说MVVM实现的是业务逻辑组件的重用。
-
MVC中Controller演变成MVVM中的ViewModel
-
MVVM通过数据来显示视图层而不是节点操作
-
MVVM主要解决了MVC中大量的dom操作使页面渲染性能降低,加载速度变慢,影响用户体验等问题。