从输入URL到渲染的过程中到底发生了什么?
- CDN
- 缓存
- DNS
- TCP三次握手、四次挥手
- 浏览器渲染过程
- 输入URL到页面渲染过程的一些优化
下面我将“从输入URL到渲染的全过程”大概的描述出来,再对其过程加以解释,了解过程中可以做哪些优化。文章内容有点长,需要有足够的耐心看完哟!!下面我要开始啦!
1、URL解析
2、DNS解析
3、建立TCP链接
4、客户端发送请求
5、服务器处理和响应请求
6、浏览器解析并渲染响应内容
7、TCP四次挥手断开连接
一、URL解析
地址解析和编码
我们输入URL后,浏览器会解析输入的字符串,判断是URL还是搜索关键字,如果是URL就开始编码。
一般来说URL只能使用英文字母、阿拉伯数字和某些标点符号,不能使用其他文字和符号,所以,如果URL中有文字就必须编码后使用。但是URL编码很混乱,不同的操作系统、浏览器、网页字符集,会导致不同的编码结果。所以我们需要使用JavaScript先对URL编码,然后提交给服务器,不给浏览器插手的机会。我们通常会使用encodeURI()函数或者encodeURIComponent()函数来编码URL
HSTS
HSTS(HTTP Strict TransportSecurity)是一种新的Web安全协议,HSTS的作用是强制客户端使用HTTPS与服务器创建连接。比如你在地址栏输入http://xxx/,浏览器会自动将http转写成https,然后直接向 https://xxx/ 发送请求。
缓存检查
浏览器在发送请求之前先检查有没有缓存,过程如下:
浏览器会先去查看强缓存(Expires和cache-control)判断是否过期,如果强缓存生效,直接从缓存中读取资源;若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag/If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,并重新返回资源和缓存标识,再次存入浏览器缓存中;生效则返回304,并从缓存中读取资源。(协商缓存之前要经过DNS域名解析,之后建立TCP链接)
那么浏览器缓存的位置在哪呢?
- Service Worker:浏览器独立线程进行缓存
- Memory Cache:内存缓存
- Disk Cache:硬盘缓存
- Push Cache:推送缓存(HTTP/2中的)
注意:输入网址之后,会查找内存缓存,没有再找硬盘,都没有就发生网络请求。
普通刷新(F5):因为TAB没有关闭,所以内存缓存可用,如果匹配上会被优先使用,其次是磁盘缓存
强制刷新(Ctrl+F5):浏览器不使用缓存,因此发送的请求头均带有Cache-control:no-cache,服务器直接返回200和最新内容。
二、进行DNS解析
DNS
(1)、DNS:把域名和ip地址相互映射分布式数据库,让用户能更方便的访问互联网,DNS协议运行在UDP协议之上
(2)、DNS解析:通过域名最终得到对应ip地址的过程。
(3)、DNS缓存:浏览器,操作系统,路由器,本地DNS,根域名服务器都会对DNS结果作出一定的缓存
DNS解析过程
(1)、首先搜索浏览器自身的DNS缓存,有缓存直接返回;
(2)、浏览器自身DNS不存在,浏览器就会调用一个类似gethostbyname的库函数,此函数会先去检测本地hosts文件,查看是否有对应ip。
(3)、如果本地hosts文件不存在映射关系,就会查询路由缓存,路由缓存不存在就去查找本地DNS服务器(一般TCP/IP参数里会设首选DNS服务器,通常是8.8.8.8)(客户端到本地DNS服务器是递归过程)
(4)、如果本地DNS服务器还没找到就会向根服务器发出请求。(DNS服务器之间是迭代过程)
具体过程:
本地DNS服务器代我们的浏览器发起迭代DNS解析请求,首先它会找根域的DNS的IP地址(全球13台哟,可惜中国没有!)。找到根域的DNS地址,就会向其发起请求(请问www.baidu.com这个域名的IP地址是多少呀?);
根域发现这是一个顶级域com域的一个域名,于是告诉本地DNS服务器我不知道这个域名的IP地址,但是我知道com域的IP地址,你去找它去吧;
于是本地DNS服务器就得到了com域的IP地址,又向com域的IP地址发起了请求(请问www.baidu.com这个域名的IP地址是多少呀?),于是com域服务器告诉本地DNS服务器我不知道www.baidu.com这个域名的IP地址,但是我知道baidu.com这个域的DNS地址,你去找它去;
于是本地DNS服务器又向baidu.com这个域名的DNS地址(这个一般就是由域名注册商提供的,像万网,新网等)发起请求(请问www.baidu.com这个域名的IP地址是多少?),这个时候baidu.com域的DNS服务器一查,呀!果真在我这耶,于是就把找到的结果发送给本地DNS服务器;
这个时候本地DNS服务器就拿到了www.baidu.com这个域名对应的IP地址。
参考 前端进阶面试题详细解答
DNS优化
DNS也是开销,通常浏览器查找一个给定域名的IP地址要花费20~120毫秒,在完成域名解析之前,浏览器不能从服务器加载到任何东西。那么如何减少域名解析时间,加快页面加载速度呢?
(1)、减少DNS请求次数
(2)、DNS预获取,DOM还没开始,浏览器预解析地址,把解析好的地址放在本地缓存里面,DOM树生成完,要加载图片类的发现DNS已经解析好了,再发送请求。<link rel=‘dns-prefetch’href=’//dfns.tanx.com’>
(主要对图片资源)
(3)、DNS 查询的过程经历了很多的步骤,如果每次都如此,会耗费太多的时间、资源。所以我们应该尽早的返回真实的IP地址:(减少查询过程,也就是DNS缓存。浏览器获取到IP地址后,一般都会缓存到浏览器的缓存中,本地的DNS缓存服务器,也可以去记录。另外,每天几亿网名的访问需求,一秒钟几千万的请求域名服务器如何满足?就是DNS负载均衡。通常我们的网站应用各种云服务,或者各种服务商提供类似的服务,由他们去帮我们处理这些问题。 DNS系统根据每台机器的负载量,地理位置的限制(长距离的传输效率)等等,去提供高效快速的 DNS 解析服务。
(4)、当客户端DNS缓存(浏览器和操作系统)缓存为空时,DNS查找的数量与要加载的Web页面中唯一主机名的数量相同,包括页面URL、脚本、样式表、图片、Flash对象等的主机名。减少主机名的数量就可以减少DNS查找的数量;
(5)、减少唯一主机名的数量会潜在减少页面中并行下载的数量(HTTP1.1规范建议从每个主机名并行下载两个组件,但实际上可以多个);但是减少主机名和并行下载的方案会产生矛盾,需要大家自己权衡。建议将组件放到至少两个但不多于4个主机名下,减少DNS查找的同时也允许高度并行下载。
DNS解析后会把域名的解析权交给cname()指向的内容分发(CDN)专用的DNS服务器。CDN专用的DNS服务器把CDN的全局负载均衡设备的ip地址返回给用户。
CDN
举个例子:以前坐火车买票,都要到火车站买,所有人都去火车站买票,火车站售票厅的压力可想而知有多大。
后来火车票代售点出现了,分布在各个城市,城镇,我们只需要去距离我们最近的火车票售卖点买票就可以了。
卖火车票的代理售票点(缓存服务器),为买票者提供了方便,帮助他们在最近的地方(最近的CDN节点),
用最短的时间(最短的请求时间)买到票(拿到资源)。减轻了售票大厅的压力(起到分流作用,减轻服务器负载压力)
CDN缓存:
在浏览器本地缓存失效后,浏览器会像CDN边缘节点发起请求,类似浏览器缓存,CDN边缘节点也存在一套缓存机制,
- CDN边缘节点缓存策略因服务商不同而不同,通过http响应头中的cache-control:max-age字段设置CDN边缘节点数据缓存时间。
- 当浏览器向CDN节点请求数据时,CDN节点会判断缓存数据是否过期,若缓存数据过期,CDN会向服务器发出回源请求,从服务器拉取最新数据,更新本地缓存,并将最新数据返回给客户端,CDN服务商一般会提供基于文件后缀,目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。
CDN工作方式:
(1)、当你点击网站页面的url时,经过本DNS解析,DNS解析后会把域名的解析权交给cname()指向的内容分发专用的DNS服务器。内容分发专用的DNS服务器把内容分发的全局负载均衡(GSLB)设备的ip地址返回给用户。
(2)、当你向CDN的全局负载均衡设备的ip地址发起url访问请求,CDN的全局负载均衡设备会为你选择一台合适的缓存服务器提供服务。
选择的依据:用户的ip地址,判断哪台服务器距离用户最近,根据用户请求的url中携带的内容名称判断哪台服务器上有用户要的数据,查询各个服务器当前负载情况,判断哪台服务器有服务能力。
分配:基于这些条件综合分析后,区域负载均衡设备会向全局负载均衡设备请求返回一台缓存服务器的IP地址。全局负载均衡设备返回服务器IP地址,用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端,如果这台缓存服务器没有用户想要的内容,而区域均衡设备依然将它分配给了用户,那么这台服务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉到本地。域名解析服务器根据用户ip地址,把域名解析成相应节点的缓存服务器ip地址,实现用户就近访问,使用CDN服务的网站,只要将其域名解析权交给CDN的全局负载均衡设备,将需要分发的内容注入到CDN就可以实现内容加速了。
CDN优势:
(1)、CDN节点解决了跨运营商和跨地域访问的问题,访问延时大大降低;
(2)、大部分请求在CDN边缘节点完成,CDN起到分流作用,减轻了源服务器的负载。
CDN劣势
(1)、当网站更新时,如果CDN节点上数据没有及时更新,即便用户在浏览器使用 Ctrl +F5 的方式使浏览器端的缓存失效,也会因为CDN边缘节点没有同步最新数据而导致用户访问异常。
(2)、CDN不同的缓存时间会对“回源率”产生直接的影响:
- 如果缓存时间短,CDN边缘节点的内容经常失效,导致频繁回源。不仅增加服务器压力,也增加了用户访问时间。
- 如果缓存时间长,数据更新了,边缘节点的内容都还没更新,开发者对特定的任务做特定的数据缓存时间管理。
CDN刷新缓存
CDN边缘节点对开发者是透明的,相比于浏览器Ctrl+F5的强制刷新来使浏览器本地缓存失效,开发者可以通过CDN服务商提供的“刷新缓存”接口来达到清理CDN边缘节点缓存的目的。这样开发者在更新数据后,可以使用“刷新缓存”功能来强制CDN节点上的数据缓存过期,保证客户端在访问时,拉取到最新的数据。 |
CDN优化
(1)、前端需要被加速的文件大致包括:
js、css、图片、视频、和页面等文件。页面文件有动态和静态之分。这些文件和页面(比如html)最大的区别是:这些文件都是静态的,改动比较小,这类静态文件适合做CDN加速。我们把这些静态文件通过CDN分发到世界各地的节点,用户可以在距离最近的边缘节点拿到需要的内容,从而提升内容下载速度加快网页打开速度。页面分为动态页面和静态页面,动态页面不适合做CDN缓存,因为页面是动态的话,内容的有效期就比较活跃。边缘节点的数据经常失效要回源,造成源服务器压力。
(2)、减少资源请求的等待时间
不同浏览器的并发数量不一样:IE11 、IE10 、chrome、Firefox 的并发连接数是 6个,IE9是10个。如果页面静态资源(图片等)过多(大于6个)会存在资源请求等待的情况。目前现实状况是大多用户带宽越来越大,但是我们的静态资源并非那么大,很多文件都是几k或者几十k,6个文件加起来都小于带宽。这样就导致了资源的浪费。
- 解决方案是:用多个不同IP的服务器来存储这些文件,并在页面中通过绝对路径的方式引用(要求同一IP的文件不超过6个)。这样就可以尽可能的减少资源请求等待的情况。
至此,你已经获取到缓存服务器的IP地址,并且准备向这个IP地址发送请求了。
三、建立TCP连接
TCP
(1)、TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议。
(2)、建立TCP连接需要进行三次握手。过程如下:
TCP握手过程
(1)、客户端发送带有SYN标识(SYN=1,seq=x)的请求报文段,然后进入SYN_SEND状态,等待服务端确认;
(2)、服务端接收到客户端SYN报文段后,需要发送ACK信息对这个SYN进行确认,同时还要发送自己的SYN信息(SYN=1,ACK=1,seq=y,ack=x+1)服务端把这些信息放在一个报文段中((SYN+ACK报文段),一并发给客户端,此时客户端进入SYN_RECV状态;
(3)、客户端接收到服务端的SYN+ACK报文段后会向服务端发送ACK(ACK=1,seq=x+,ack=y+1)确认报文段,这个报文段发送后,客户端和服务端都进入ESTABLISHED状态,完成三次握手。
为什么TCP建立一定要三次呢?两次不行吗?
原因:
- 双方要明确对方接收能力都是正常的,(客户端发之后,服务端可以确定客户端发送能力正常,服务端发送给客户端,客户端可以确定服务端的接收和发送能力正常,最后客户端发送确认,来确定客户端的接收能力。
- 为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
四、客户端发送请求
TCP三次握手建立连接成功后,客户端按照指定的格式开始向服务端发送HTTP请求。
请求过程优化
减少HTTP请求次数和请求资源大小
(1)、资源合并压缩
(2)、字体图标(精灵图基本不是好的优化方式了,不好维护)
(3)、base64
(4)、Gzip(一般文件能压缩60%)
(5)、图片懒加载
(6)、数据延迟分批加载
(7)、CDN资源
五、服务器响应请求
服务器端收到请求后由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,了解了要调度哪些资源文件,再通过响应的资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。
六、断开连接
服务器响应完客户端请求之后,解除TCP连接,释放过程(四次挥手过程)如下:
(1)、客户端发送标记为FIN=1(finished的缩写,表示接收完成,请求释放连接),同时生成一个Seq=u的序列号,之后进入FIN-WAIT-1半关闭阶段(此时客户端到服务端发送数据的通道已经关闭,但是仍然可以接收服务端发过来的数据);
(2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
(3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
(4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
(5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。
(6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态,就结束了这次的TCP连接。
为什么要四次握手而不是三次、两次
因为建立一旦连接,双方既是发送方,又是接收方,为了保证在最后断开的时候,客户端发送的最后一个ACK报文段能够被服务器接收到。如果客户端在收到服务器给它的断开连接的请求之后,回应完服务器就直接断开连接的话,服务器就会因为一直没得到客户端响应而一直等待,所以客户端要等待两个最长报文段寿命的时间,以便于服务器没有收到请求之后重新发送请求。
七、浏览器解析并渲染响应内容
在这之前我们先来补充一点基础知识:
浏览器的渲染引擎组成(列举的是基本组成)
(1)、HTML解析器:将HTML解析成DOM树。
(2)、CSS解析器: 为DOM中各个元素对象计算出样式信息,为布局提供基础设施。
(3)、JavaScript引擎:解析并执行javascript代码。
(4)、布局layout模块:在DOM树创建后,webkit需要将其中的元素对象同样式信息结合起来,计算他们的大小位置等布局信息,形成一个能表达这所有信息的模型。
(5)、绘图模块:使用图形库将布局计算后的各个网页的节点绘制成图像的结果。
渲染过程
(1)、浏览器拿到文件后(拿到的是一些字节码)通过编码方式(一般是utf-8)转换为对应的字符。
(2)、浏览器至上而下解析文档,遇见HTML标记,调用HTML解析器解析为对应的tocken,tocken就是标签文本的序列号,将tocken按词法解析解析成具体的标记结构,这个过程已经构建出一颗有标签,有层级,有结构的DOM树(就是一块内存,这块内存实际就是一个个Tocken构成的);
(3)、遇见style/link标记,调用CSS解析器处理CSS标记并构建CSSOM样式树;
(4)、遇见script标记,调用javascript解析器处理,绑定事件、修改DOM树/CSS树等;
(5)、将DOM树和CSSOM树合并成一颗render树(渲染树)。
(6)、根据渲染树来渲染,计算每个节点的几何信息(这一过程要依赖图形库);
(7)、将各个节点绘制到屏幕上。
如果用户操作页面,会触发第(6)或者第(7)步骤,也就是重排和重绘
阻塞渲染
(1)、style标签的样式:
由HTML解析器解析(异步解析);
不阻塞浏览器渲染(可能会出现闪屏(解析一点,显示一点现象);
不阻塞DOM解析。
(2)、link引入的外部css样式(推荐使用)
由CSS解析器解析(同步解析);
阻塞浏览器渲染(可以利用这种阻塞避免闪屏);
阻塞其后js语句的执行:
原因:如果后面js的内容是获取元素的样式,例如宽高等属性,如果不等样式解析完毕,后面的js就获得了错误的信息,由于浏览器也不知道后续js的具体内容,所以只好等前面所有样式解析完毕,再执行js。例如:firefox在样式加载和解析过程,会禁止所有脚本。(webkit内核的浏览器只会在js尝试访问样式属性或者可能受到未加载的样式影响时才会禁止脚本。不阻塞DOM的解析:
原因:DOM解析和CSS解析是两个并行的线程。
(3)、优化核心概念:尽可能快的提高外部css加载速度。
使用CDN节点进行外部资源打包;
对css进行压缩(利用打包工具,比如webpack,glup等;
减少对http请求数量,将多个css文件合并;
优化样式的代码。
(4)、js阻塞:
阻塞DOM解析:
原因:浏览器不知道后续脚本的内容,如果先去解析了下面的DOM,而随后js删除了后面的所有DOM,做了无用功。浏览器无法预估脚本具体做了什么操作,索性全部暂停,等脚本执行完,浏览器再继续向下解析。阻塞页面的渲染:
原因:js中也可以给DOM设置样式,浏览器同样等该脚本执行完再继续干活,避免做无用功。阻塞后续js的执行:
原因:维护依赖关系,例如:必须先引入jQuery再引入bootstrap。如果script脚本加了defer:浏览器会发送请求加载js,但是不会阻塞DOM解析,等DOM解析完,再执行js。
如果script加了async:浏览器会发送请求加载js,不阻塞DOM解析,等js加载过来了,就先停止DOM解析,去执行js(谁先回来先执行谁),等js执行完,继续DOM解析。
渲染过程优化
(1)、标签语义化(使用合适的标签,如果不是w3c规定的标签,Tocken令牌和词法解析语法得识别分析,是不是wc3规定的)
(2)、减少标签嵌套(生成结构树嵌套太多,就得递归(在DOM树构建时候快可以一点)
(3)、样式尽可能少的层级嵌套(使用与编译器的时候,层级嵌套要慎用。CSS选择器渲染从右到左,.box a{}会 比a{} 慢
(4)、尽早把CSS下载到客户端(充分利用HTTP多请求并发机制)
(5)避免阻塞js放在底部
(6)、减少回流
放弃传统操作DOM时代,基于vue/react开始数据影响试图模式
样式集中改变
缓存布局信息,
动画效果应用到position属性为absolute或fixed的元素上(脱离文档流)
CSS3硬件加速(比起考虑如何减少回流重绘,更期望不要回流重绘:transform、opacity、filters这些属性会触发硬件加速,不会引发回流重绘(过多使用占用大量内存,性能消耗严重
避免使用table布局和使用css的js表达式
结语
通过阅读本文,相信小伙伴们对从输入URL到页面渲染的过程有了一个大概的理解。其实整个过程是很复杂也比较繁琐的,不是一篇文章或者几张图就可以囊括的,在这有很多细节不便展开,有兴趣的小伙伴可以对这个过程中的一些细节深入研究研究哦!文章中肯定会有些说的不是很清楚的地方,恳请各位大佬不吝赐教,一起成长!
相关文章:

从输入URL到渲染的过程中到底发生了什么?
CDN缓存DNSTCP三次握手、四次挥手浏览器渲染过程输入URL到页面渲染过程的一些优化 下面我将“从输入URL到渲染的全过程”大概的描述出来,再对其过程加以解释,了解过程中可以做哪些优化。文章内容有点长,需要有足够的耐心看完哟!&…...
旋转屏幕导致 Fragment 中的 onConfigurationChanged 被调用两次
环境 IDE Android Studio Dolphin 2021.3.1; 项目配置 Android Gradle plugin version: 7.1.3 Gradle Version: 7.2 Gradle JDK: 11 Compile Sdk Version: 32 问题描述 项目使用的 Bottom Navigation Activity 基本结构,在调试程序时发现,…...

23年校招DL/NLP/推荐系统/ML/算法基础面试必看300问及答案
2020年校招已经开始了,在疫情全球肆虐的背景下,全球就业情况异常艰难,加上美国对中国企业打压持续升级,对于马上开始秋招找工作的毕业生而言,更是难上加难。我们不能凭一己之力改变现状,但我们可以凭借自己…...
Python基础知识汇总(字符串二)
目录 检索字符串 count()方法 find()方法 in关键字 index()方法 rindex()方法 startswith()方法...

【FPGA】Verilog:实现十六进制七段数码管显示 | 7-Segment Display
写在前面:本章主要内容为理解七点数码管显示的概念,并使用 Verilog 实现。生成输入信号后通过仿真确认各门的动作,通过 FPGA 检查在 Verilog 中实现的电路的操作。 Ⅰ. 前置知识 七段数码管是利用多重输出功能的非常有用的元件。该元件用于字…...

Android开发:Activity启动模式
1.怎样设置Activity的启动模式 可以在清单文件中自己添加活动的启动模式, android : launchMode"standard", 不写的话系统默认就是标准模式. 2.启动模式 2.1.默认启动模式 标准启动模式就是栈, 打开一个活动就将活动压入栈中, 返回就将活动退出栈中. 不同的Activit…...

01_Docker 简介
01_Docker 简介 文章目录01_Docker 简介1.1 Docker 简介1.2 Docker 组件1.2.1 Docker 客户端和服务区1.2.2 Docker 镜像1.2.3 Registry1.2.4 Docker 容器参考资料https://www.runoob.com/docker/ubuntu-docker-install.html 1.1 Docker 简介 Docker 是一个能够把开发的应用程…...

一文精通MVCC机制
MVCC(Multi-Version Concurrency Control)多版本并发控制机制使用串行化隔离级别时,mysql会将所有的操作加锁互斥,来保证并发安全。这种方式必然降低并发性能。mysql在读已提交和可重复读隔离级别下,对一行数据的读和写两个操作默认是不会通过…...
商用ESP32协议采集器源码分享开篇
这是一个关于chatGPT帮助嵌入式程序员开发商业项目的故事. 在开发这个项目的过程中,chatGPT发布了,在它的帮助下,项目开发量减少了10%,所以这个专栏,既是一个关于Micropython开发ESP32的专栏,也是一个程序员在AI的帮助下,提升效率,加速挣钱的案例. 看完之后,你将知道如何用mic…...

代码随想录算法训练营第三十四天 | 860.柠檬水找零,406.根据身高重建队列,452. 用最少数量的箭引爆气球
一、参考资料柠檬水找零https://programmercarl.com/0860.%E6%9F%A0%E6%AA%AC%E6%B0%B4%E6%89%BE%E9%9B%B6.html 根据身高重建队列 https://programmercarl.com/0406.%E6%A0%B9%E6%8D%AE%E8%BA%AB%E9%AB%98%E9%87%8D%E5%BB%BA%E9%98%9F%E5%88%97.html 用最少数量的箭引爆气球ht…...

DDR4介绍01
DDR4(第四代双倍数据率同步动态随机存储器SDRAM) 关于内存方面知识,大部分人、包括我自己也不是很懂,希望此篇文章能起到点作用,做硬件的就得把相关专业知识学牢了,尤其是专业术语。 下面是DDR4知识做一次…...
扫地机器人行业投资逻辑:国内以价换量元年,海外需求企稳回升
1、国内以价换量元年,投资逻辑由产品迭代转向行业的渗透率提升 2019-2022 年国内扫地机行业主要的投资逻辑是产品迭代的价增带动销额增长。 2019-2022 年国内热销的扫地机产品从单机向自清洁扫地机、全能基站扫地机持续迭 代升级,产品功能日益完善、瞄准用户痛点更新,真正实…...

(考研湖科大教书匠计算机网络)第四章网络层-第七节:IPv4数据报首部格式
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:IP数据报首部格式概述二:各字段作用概述(1)版本(2)首部长度和可选字段(3&am…...

每天10个前端小知识 【Day 18】
前端面试基础知识题 1.如何实现单行/多行文本溢出的省略样式? 在日常开发展示页面,如果一段文本的数量过长,受制于元素宽度的因素,有可能不能完全显示,为了提高用户的使用体验,这个时候就需要…...

【Java集合类】ArrayList
内部结构 ArrayList内部核心是一个Object数组elementDataObject数组的长度(length)视为ArrayList当前的容量(capacity)size对象表示ArrayList当前的元素个数 类上的重要注释 内部是Object数组 允许put null值,会自动扩容 size、…...

页面置换算法
页面置换算法 在进程运行过程中,若需要访问的物理块不在内存中,就需要通过一定的方式来将页面载入内存,而此时内存很可能已无空闲空间,因此就需要一定的算法来选择内存中要被置换的页面,这种算法就被称为页面置换算法…...

算法导论【在线算法】—The Ski-Rental Problem、The Lost Cow Problem、The Secretary Problem
算法导论【在线算法】The Ski-Rental Problem问题描述在线算法证明The Lost Cow Problem问题描述在线算法类似问题—寻宝藏The Secretary Problem问题描述在线算法The Best Possible kThe Ski-Rental Problem 问题描述 假设你正在上滑雪课。每节课结束后,你决定&a…...
linux 下怎样给pdf 文件加书签
linux 下怎样给pdf 文件加书签 对于没有书签的pdf文件,怎样给pdf加标签呢? 以方便阅读. 以前总是要借助windows下pdf 工具, 叫什么来者? 忘了 记得是编辑一个用tab表示目录级别的文本文件, 有一种直观的感觉,大目录下嵌套着小目录 ..., 然后导入到文件中 linux 下有没有这种…...

[软件工程导论(第六版)]第2章 可行性研究(课后习题详解)
文章目录1. 在软件开发的早期阶段为什么要进行可行性研究?应该从哪些方面研究目标系统的可行性?2. 为方便储户,某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员输入系统,如果是存款,系统记录存款人姓名…...

[软件工程导论(第六版)]第3章 需求分析(课后习题详解)
文章目录1. 为什么要进行需求分析?通常对软件系统有哪些需求?2. 怎样与用户有效地沟通以获取用户的真实需求?3. 银行计算机储蓄系统的工作过程大致如下:储户填写的存款单或取款单由业务员输入系统,如果是存款则系统记录…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
CppCon 2015 学习:REFLECTION TECHNIQUES IN C++
关于 Reflection(反射) 这个概念,总结一下: Reflection(反射)是什么? 反射是对类型的自我检查能力(Introspection) 可以查看类的成员变量、成员函数等信息。反射允许枚…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...