计算机底层知识点汇总

    技术2023-07-29  91

    底层知识

    1.本地存储谈谈他们的区别

    本地数据存储机制包括:cookie,sessionStorage 和 localStorage

    cookie:cookie是由服务器端生成发送给客户端的小型文本文件,用于存储一些用户和通信之间的数据sessionStorage是用于保存当前页面的会话数据localStorage可以解决cookie大小不足问题,用于存储用户配置和缓存数据等

    相同点

    三者都受同源策略的影响,不能跨域三者都是用于存储部分网页数据

    不同点

    存储大小有效期与服务器端通信 本地存储存储大小有效期与服务器端通信cookie4KB由服务器端设置cookie的max-age参与服务器端通信,并且每次都会携带于HTTP请求中localStorage5MB永久存储,可以手动删除不参与服务器端通信sessionStorage5MB关闭页面或浏览器时清空不参与服务器端通信

    另外:

    不同浏览器无法共享 localStorage 和 sessionStorage中的数据相同浏览器的不同页面(不同页面但必须是同源的)可共享localStorage而无法共享sessionStorage

    在浏览器控制台的application中可以看到关于页面cookie,sessionStorage和localStorage的信息

    2.JWT

    JWT(JSON Web Token)是一个字符串令牌(是一个含签名并携带用户相关信息的加密串),我们在发起网络请求时,将其放在header或者url中,通过签名保证传递的数据被篡改时能被我们发现,保证安全性

    工作流程:

    用户登录,登录成功后后端生成一个JWT并返回给客户端客户端向服务端发送请求时佩戴JWT,可以放在header或url中当后端收到请求中包含JWT,后端通过数字签名进行校验,检查信息是否被篡改。校验通过则认为是可靠的请求,将正常返回数据

    面试题:跨域了你如何存储用户信息?—> JWT

    3. HTTPS

    HTTP是一种以明文方式传输数据的网络通信协议

    HTTP的缺点

    通信使用明文,内容可能被窃听不验证通信方的身份,因此有可能遭遇伪装无法证明报文的完整性,所以有可能已遭篡改

    HTTPS在HTTP的基础上,通过数据加密和身份验证来保证数据传输的安全性

    HTTPS(Hyper Text Transfer Protocal over SecureSocket Layer)并非应用层的新协议,而是在HTTP协议的通信接口部分加入SSL层,由SSL层对数据进行加密和解密

    用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GCwvtuM5-1594776486384)(./img/https.png)]

    整体流程

    客户端向服务器发送https请求,请求建立SSL通信

    服务器端内部有一对非对称密钥(公钥&私钥),服务器端将公钥证书发送给客户端

    补充:公钥证书里面包含 服务器的公开密钥 和 数字证书认证机构的数字签名,并且公钥证书是被认证机构的私有密钥加密的

    客户端对服务器发来的公钥证书进行认证,避免公钥中途被黑客替换

    补充:客户端拿到公钥证书后,使用数字证书认证机构的公开密钥进行解密并验证公钥真实性。数字证书认证机构的公开密钥已事先植入到浏览器当中了

    若合法,客户端随机产生一个对称密钥(pre-master secret的随机密码串),并用公钥进行加密发送给服务器;若不合法,则中止此次连接建立

    服务器通过私钥对用公钥进行加密的数据进行解密,获得此次数据传输的对称密钥,此时SSL连接建立成功

    服务器端和客户端通过对称密钥进行HTTP数据传输

    此外,应用层发送数据时会附加一种叫做MAC(Message Authentication Code)的报文摘要,MAC能够查知报文是否遭到篡改,从而保护报文的完整性

    HTTPS的优缺点:

    优点:通过数据加密和身份认证保证数据传输和通信的安全性,敏感信息不会被暴露在外缺点:由于HTTPS通信前需要建立SSL通信,并且对于数据的加密和解密过程也是会造成时间,CPU及内存的开销

    所以仅在那些有敏感数据或信息需要隐藏时才需要加密,以节约资源

    4. 如何进行SEO

    何为SEO:SEO(Search Engine Optimization),搜索引擎优化

    搜索引擎工作原理

    搜索引擎的工作原理是:

    抓取网页:搜索引擎相当于一个巨大的爬虫,爬虫顺着一个源网页中的超链接可以爬到另一个网站,被抓取的网页称之为网页快照处理网页:搜索引擎得到一系列网页之后,需要进行大量的处理工作,其中最重要的就是提取和分析网页的关键词。这一部分还包含的工作有文本分词,内容识别,网页分类,分析超链接,计算网页重要度,计算网页丰富度等,并且处理好后建立索引库以便检索提供检索服务:当用户输入关键词并点击搜索按钮后,搜索引擎将从索引库中找到与用户输入最为匹配的网页构成候选网页集,并展示给用户进行浏览

    前端SEO办法

    基于网页的摘要信息

    前端开发者可以在meta标签中配置相关的title,keywords,description等网页的摘要信息

    这些摘要信息的优先级要更高

    基于网页内容

    所谓内容为王,我们对网页进行内容的布局,内容的充实都能利于SEO

    网页中的内链,也就是网页中不重复的链接可以反映一个网页是否充实网页中的图片等无法解析的内容不易过多,比如iframe,flash,gif或图片爬虫都无法知道其具体内容,对于js脚本爬虫也不会执行对于网页中的图片,我们可以使用alt来进行图片的标记,来让爬虫或多或少了解图片的内容语义化标签,构建语义化布局,由于爬虫对于html中提供的标签都有不同的权重(最简单的来说,h1-h6标签具有不同的权重,其重要性是越来越低的),所以计算网页内容时对于语义也是很重要的网页内容中适当多出现关键词,此外,网站也最好经常更新

    基于外部链接

    根据pagerank算法,我们知道如果链接越多或被重要度高的链接所指向,那么网页的重要程度也会上升,所以可以适当与兄弟网站进行外链互换

    值得一提的是:随着刷外链的网页越来越多,对于外链的方法其存在感越来越低。比如百度公司对于关键词的权重才是相对来说重要的

    5. 浏览器的缓存机制

    浏览器通常会将请求得到的资源按照http响应头部的指示缓存在用户个人电脑的磁盘或内存中

    缓存过程的分类

    强制缓存协商缓存

    强制缓存

    强制缓存是指在浏览器发送请求之前,检查是否有缓存并且缓存是否失效

    如果有缓存并且缓存并未失效,缓存命中,即强制缓存生效,直接将缓存作为结果返回

    协商缓存

    协商缓存是指当强制缓存失效或设置cache-control为no-cache,则需要向服务器进行咨询,是否可用缓存中的资源

    协商缓存并不意味着缓存和服务器上的资源有实际的差异,仅仅意味着到需要进行核对的时间了,协商缓存也被称为服务器再验证

    浏览器携带缓存标识(修改日期或Etag)发送给服务器端,有服务器端决定是否使用缓存

    如果服务器端返回304NotModified则表示协商缓存生效,资源无更新,可以继续使用缓存中的内容否则返回200,并返回新的资源,浏览器更新缓存

    设置缓存的cache-control字段

    cache-control字段是一个通用字段,是一种操作缓存的工作机制

    no-cache:强制向服务器进行再验证(协商)no-store:不缓存任何内容max-age:设置缓存的有效时间public:指定响应可以在代理服务器中被缓存private:指定响应只能在指定用户中被缓存…

    另外:Expires是HTTP1.0的东西,而Cache-Control是HTTP1.1的,规定如果max-age和Expires同时存在,前者优先级高于后者

    协商缓存中的字段

    在HTTP1.1中推荐使用 If-None-Match/Etag

    If-None-Match中传递一个Etag值,只有当这个Etag值与服务器端对应资源的Etag值不一致时,处理请求Etag是一个以字符串形式对资源进行唯一标识,每个资源都会分配一个对应Etag,并且,当资源更新时Etag值也需要变化

    在HTTP1.0中推荐使用If-Modified-Since/Last-Modified

    当浏览器获取资源时,会用这个资源最新修改时间作为标识,那么在协商缓存中,将这个时间标识放在If-Modified-Since发送给服务器端,检查资源是否更新如果资源发生了更新,则会返回Last-Modified,该字段中包含了这个资源最新的修改时间;如果资源没有更新,则会返回304Not Modified

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3htFMDuI-1594776486388)(./img/缓存机制.png)]

    一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET,使用弱etag某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)某些服务器不能精确的得到文件的最后修改时间

    缓存的应用场景

    index.html:不缓存,一般设置cache-control:max-age=0静态资源:可以设置强缓存,过期时间设置到极限动态资源:可以设置一定时间的缓存,当一定时间到期进行协商缓存

    6. 禁用缓存的方法

    在浏览网页时,页面请求可能会因为缓存造成一些问题,数据不一致或数据过期等

    用户的浏览器禁用缓存

    即用户设置浏览器禁止使用缓存,但是这个方法只适合用户配置

    服务器端不设置缓存

    通过http响应来设置资源的缓存行为

    http中的通用首部字段cache-control可以操作缓存的工作机制

    将cache-control设置为no-store表示不缓存请求或响应的任何内容

    如果设置为no-cache,表示可以缓存,但使用前强制向服务器再次验证,也就是进行协商缓存阶段

    前端禁止缓存

    在请求的url后面拼接随机数或者是时间戳,加上了随机数之后,对于之前的缓存就不会命中,则会向服务器端发送请求,但是服务器端可以忽略这些查询query,从而禁止缓存对于ajax,可以将get请求设置为post请求,post请求是不允许经过缓存的

    7. 浏览器多进程

    浏览器应用程序是多进程的,每一个Tab页面有一个独立的进程,以及有一个浏览器主进程

    浏览器都包含那些进程?

    Browser进程:即浏览器的主进程,负责浏览器中界面显示;各个页面的管理,创建和销毁;与用户交互(比如前进,后退等);网络资源的管理和下载等第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建GPU进程:最多一个,用于3D绘制浏览器渲染进程:也称浏览器内核,其内部是多线程的。默认每个Tab页面都会有一个渲染进程,并且它们互不影响,主要作用为页面渲染/脚本执行/事件处理等

    浏览器多线程的优势:如果某个Tab页面崩溃了或者插件进程崩溃了,不会影响整个浏览器

    浏览器内核是多线程的

    浏览器内核包含如下线程

    GUI渲染线程:负责渲染页面,解析HTML/CSS,构建DOM树和Render树,布局和绘制等(当页面需要重绘或者重排,该线程就会执行)JS引擎线程:负责处理JavaScript脚本,运行代码,一个Tab页面中无论什么时候都只有一个JS线程,即"JavaScript是单线程的"事件触发线程,用于控制事件循环Event Loop定时触发器线程:setTimeout和setInterval所在的线程,所以说这两种方法并不是由JS引擎来计时的异步http请求线程:进行http请求的线程,进行http请求时会创建一个请求线程

    注意:GUI渲染线程和JS引擎线程互斥,所以如果JS执行的时间过长,就会造成页面的渲染不连贯,导致页面渲染阻塞

    另外:webworker是由主进程开辟的子线程,用于执行JS脚本,并不干扰用户界面。JS引擎线程与worker线程间通信通过特定方式(postmessage),如果某脚本的执行非常耗时,可以单独开辟一个worker线程,但是这个worker线程完全受主进程控制并且不能操作DOM

    8. 浏览器的渲染过程

    浏览器中和的渲染过程主要是由浏览器的渲染进程中的GUI渲染线程完成的

    浏览器的渲染过程分为如下阶段

    第一步:构建DOM树

    abstract:bytes -> characters -> tokens -> nodes -> DOM Tree

    当在浏览器中输入URL后,会建立TCP连接来进行资源获取,在TCP中,资源是以字节流的形式被传输的

    当网页到达浏览器端,会由字节流转换成字符流,最后将字符生成一系列词语(Token)

    HTML解析器将根据词语构建节点Node,最终并以结构化的形式生成DOM树

    如果节点是script标签则需要调用js引擎解析执行,脚本的解析和执行会阻塞DOM树的构建与渲染,是因为js脚本有可能会修改DOM树的结构

    如果节点是图片或css等,调用资源加载器加载,此过程是异步的,但是不会阻塞DOM树的构建。css加载不会阻碍DOM树的构建,但是有可能阻塞渲染过程

    补充—解析器有两个处理过程——词法分析与语法分析

    词法分析负责把输入切分成符号序列,将字符流切分成一个个的词语token语法分析是对该语言语法法则的应用,根据token构建节点和dom树

    第二步:构建CSS树

    与DOM树的构建基本相同,都需要由CSS解析器解析,经过从bytes到Objectmodel的过程

    CSS是一种阻塞渲染的资源,css需要被完全解析才能够进入生成渲染树的环节

    第三步:DOM树和CSS树生成Render树

    DOM树从根节点开始遍历可见节点(script/header/meta除外),最终生成renderObject对象,该对象保存了为布局和绘制DOM节点所必须的各种信息

    Render树一定是基于DOM树和CSS树的产物

    第四步:生成布局layout

    有了Render树我们可以计算出各个节点的确切位置和大小,需要通过布局样式属性生成各元素的布局

    第五步:绘制painting

    通过第四步我们生成了元素的位置信息和布局信息,在绘制阶段我们对像素点进行样式绘制

    第六步:回流和重绘

    当元素的内容,结构,位置或尺寸发生了变化,需要重新计算元素的尺寸和位置信息(reflow)当元素的外观(背景色、边框颜色、文字颜色等)发生了变化,需要重新绘制元素(repaint)

    需要注意的是当出发reflow时都会触发repaint,但是repaint不一定触发reflow,即重绘可以单独触发

    8. QUIC

    QUIC是Google新开发的一个基于UDP的协议,它提供了像TCP一样的传输可靠性保证

    QUIC重要特性:

    彻底解决了HOLB问题,QUIC让不同的流之间真正的实现相互独立传输,互不干扰

    切换网络时的连接保持

    当前移动端的应用环境,用户的网络可能会经常切换,比如从办公室或家里出门,WiFi断开,网络切换为3G或4G。基于TCP的协议,由于切换网络之后,IP会改变,因而之前的连接不可能继续保持

    而基于UDP的QUIC协议,则可以内建与TCP中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接

    9. Cookie

    cookie是一种用于辨别用户身份或维持会话状态的小型文本文件

    cookie大小不超过4KB,里面的数据以Name-Value的形式存储,并且cookie中也存储着控制cookie有效期,安全性和使用范围的属性

    cookie的设置

    客户端发送HTTP请求到服务端服务端收到HTTP请求并在响应头内部(response header)添加Set-Cookie字段,以创建一个cookie浏览器收到响应中的cookie并保存之后向该服务器的每一个请求头部(request header)都带上Cookie字段将Cookie信息发送给服务器

    cookie的属性

    Name-Value:在cookie中存储的数据,其中Value需要进行编码处理

    Expires/Max-Age:用于设置cookie的过期时间,并且Expires的优先级高于Max-Age

    Domain:指定cookie可以送达的服务器主机名,如果没有指定则默认为当前资源访问地址中的主机部分(注意cookie不能跨域)

    Path:指定了请求路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。比如设置 Path=/docs,/docs/Web/ 下的资源会带 Cookie 首部,/test 则不会携带 Cookie 首部

    Secure:标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端,保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改

    HTTPOnly:设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击

    SameSite:同站/跨站(same-site/cross-site)设置,可以让 Cookie 在跨站请求时不会被发送,从而可以阻止跨站请求伪造攻击

    Strict 仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 属于同站Lax 允许部分第三方请求携带 CookieNone 无论是否跨站都会发送 Cookie注意:同站不是同源,cookie中的同站判断较为宽松,不需要考虑协议和端口,只要两个URL的eTLD+1(即 有效顶级域名和二级域名相同即可)eg. www.a.taobao.com 和 www.b.taobao.com是同站

    之前默认是 None 的,Chrome80 后默认是 Lax

    10. 移动端300ms点击延迟

    移动端的300ms延迟是由于双击缩放造成的,双击缩放即用手指在屏幕上快速点击两次,就可以进行页面网页的放大与恢复正常

    那么当用于进行点击时,IOS Safari就会等待300ms来判断用户是否再次点击了屏幕

    解决办法

    禁用缩放,即在meta viewport中设置user-scalable=no,但是这样会导致浏览器无法缩放依赖fastclick,fastclick的原理是在检测到touchend事件的时候,会通过DOM自定义事件立即触发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉

    11. websocket

    websocket协议是基于TCP的一种新的网络协议,websocket协议能够实现浏览器与服务器之间的全双工通信,即允许服务器主动发送信息给客户端

    以前的实现聊天室功能只能使用AJAX轮询,即在特定时间间隔,由浏览器对服务器发出HTTP请求,然后服务器端返回最新数据;这种传统模式会浪费很多带宽等资源

    websocket带来的好处

    Header更小:互相沟通的Header是很小的Server Push:也是最关键的好处,即服务器推送,服务器在有新数据时就主动推送给浏览器

    websocket实现过程

    客户端向服务器端发送一个websocket连接请求(此处仍是http协议支持),在http请求头部添加Upgrade字段为"websocket"服务器接收请求并发出响应,返回状态码101"protocol switching",Upgrade为websocket,建立websocket通信建立了websocket通信通道后,双方可以直接进行数据互相传送

    HTML5中的websocket API

    创建websocket对象

    var Socket = new WebSocket(url, [protocol] );

    websocket事件

    Socket.onopen:连接建立时触发Socket.onmessage:客户端收到服务器端来的数据时触发Socket.onerror:通信发生错误时触发Socket.onclose:连接关闭时触发

    websocket方法

    Socket.send():使用连接发送数据Socket.close():关闭连接

    websocket属性

    Socket.readyState:表示连接状态 — 1表示连接已建立 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title></title> <script type="text/javascript"> function WebSocketTest(){ if ("WebSocket" in window) //检查websocket { alert("您的浏览器支持 WebSocket!"); // 打开一个 web socket var ws = new WebSocket("ws://localhost:9998/echo"); ws.onopen = function(){ // Web Socket 已连接上,使用 send() 方法发送数据 ws.send("发送数据"); alert("数据发送中..."); }; ws.onmessage = function (evt) //接收服务端数据 { var received_msg = evt.data; alert("数据已接收..."); }; ws.onclose = function(){ // 关闭 websocket alert("连接已关闭..."); }; } else{ // 浏览器不支持 WebSocket alert("您的浏览器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">运行 WebSocket</a> </div> </body> </html>

    12. 进程和线程

    同一个进程中可以包括多个线程,并且线程共享进程的资源,一个进程至少包括一个线程

    进程线程进程是操作系统资源分配的基本单位线程是CPU调度和执行的基本单位进程会有独立的内存空间,包括代码和相关数据同一进程下的线程共享该进程的资源(代码,数据段,内存由进程分配),每个线程都有自己独立的运行栈和程序计数器进程又称重型进程,其创建和切换开销大线程又称轻型进程,其创建和切换开销小

    13. 简单请求和复杂请求

    对于复杂请求,浏览器必须首先使用OPTIONS方法发起一个预检请求(preflight request)

    预检:浏览器询问服务器的权限信息,当前网页所在的域是否在服务器的许可名单中,以及可以使用那些请求方法和头部字段,服务器确认允许之后,才发起实际的 HTTP 请求

    简单请求范畴:

    使用下列方法之一:GET/POST/HEAD不得人为设置该集合之外的其他首部字段,集合为Accept,Accept-Language,Content-Language,Content-TypeContent-Type 的值仅限于下列三者之一:text/plain,multipart/form-data,application/x-www-form-urlencoded

    简单请求之外的就是复杂请求

    当在跨域请求时:在正式post之前,浏览器会先发出一个options请求(也叫preflight),同时header带上origin还有Access-Control-Request-*(method/headers)😗*之类的头,服务器响应会返回相应的access-control-allow-origin,如果匹配,那么浏览器就会发送正式post,否则就会出现错误。跨域访问时,我们明明发送的post请求,失败的话,查看chrome network会发现是options方法的原因

    14. 如何在前端获取Cookie

    HttpResponse中提供Set-Cookie字段,可以获取想要的Cookie信息,可以保存在document.cookie中

    通过document.cookie可以添加新的cookie

    Cookie–>请求首部字段Set-Cookie–>响应首部字段

    当设置了cookie为HttpOnly则无法使用js脚本获取Cookie,只能在http请求时使用cookie.这样可以防止XSS攻击窃取Cookie信息

    15. 重定向

    301 Moved Permanently:永久性重定向。表示请求的资源已被分配了新的URL,应使用新的URL进行访问

    如果之前已经把资源对应的URL保存为书签了,这时应该按Location字段提示的URL重新保存(更新书签)

    302 Found:临时性重定向。表示请求的资源被分配了新的URL,但是该资源对应的URL将来还有可能发生变化

    希望用户在本次请求中使用新的URL重新访问,但不会像301状态码去更新书签

    16. Etag原理

    Etag分为强Etag和弱Etag

    服务器会参照资源一些属性(文件大小,文件类型)等,通过一定算法生成Etag,Etag的属性之间使用-进行连接

    强Etag

    不论实体发生多么细微变化都会改变Etag的值

    弱Etag

    弱Etag值只用于提示资源是否相同,只有资源不相同(发生了根本性的变化),产生差异时才会改变Etag的值

    弱Etag会在字段值最开始处附加W/表示弱Etag

    ETag: W/"usagi123"

    17. 跨域

    同源

    URL由协议+域名+端口+路径组成,如果两个URL的协议,域名和端口相同,则表示它们同源,相反,协议,域名和端口有任何一个不同,就被当作不同源,需要进行跨域

    eg: http://store.company.com/dir/page.html

    http表示协议store.company.com表示域名该url为默认端口即80/dir/page.html表示路径 http://store.company.com/dir2/other.html,同源https://store.company.com/secure.html,不同源,协议不同,https与http是两个不同的协议http://store.company.com:81/dir/etc.html,不同源,端口不同,http默认端口80http://news.company.com/dir/other.html,不同源,域名不同,虽然顶级域名和二级域名相同,但是三级域名不同

    JSONP原理

    步骤:

    创建一个callback创建一个script标签设置script标签的url属性将script标签插入head中 let flightQuery = function(data){ console.log("你需要的data:", data); } let script = document.createElement("script"); let url = "请求url,不同源的"; script.setAttribute("src", url); document.getElementsByTagName("head")[0].appendChild(script);

    18. 输入一个URL发生的过程

    Processed: 0.013, SQL: 9