当前位置: 首页 > news >正文

《WebKit 技术内幕》之四(3): 资源加载和网络栈

3. 网络栈

3.1 WebKit的网络设施

        WebKit的资源加载其实是交由各个移植来实现的,所以WebCore其实并没有什么特别的基础设施,每个移植的网络实现是非常不一样的。

        从WebKit的代码结构中可以看出,网络部分代码的确比较少的,它们都在目录“WebKit/Source/WebCore/platform/network”中。主要是一些HTTP消息头、MIME消息、状态码等信息的描述和处理,没有实质的网络连接和各种针对网络的优化。

3.2 Chromium网络栈

(1)“net“所包含的主要子目录,是chromium网络栈的主要模块。要实现一些基础的部分,如 HTTP 协议、DNS 解析等模块,还包括一些为了减少网络时间而引入的新技术(如 SPDY、QUIC 等)。

(2)网络栈结构

        在“Net”目录下的子目录,包含了主要的子模块,如下图描述了从URLRequest类到Socket类之间的调用过程。以HTTP协议为例,图中列出了建立TCP的Socket连接过程中涉及的类。

  • URLRequest类被上层调用并启动请求的时候,它会根据URL的“scheme”来决定需要创建什么类型的请求,“scheme”也就是URL的协议类型,如:“http://"、“file://”·,也可以是自定义的scheme,例如Andriod系统的”file://andriod_asset/“。URLRequest对象创建的是一个URLRequestJob子类的一个对象,例如图形的中的URLRequestHttpJob类。为了支持自定义的scheme处理方式,Chromium使用工厂模式。URLRequestJob类和它的工厂类URLRequestJobFactory的管理工作都由URLRequestJobManager类负责。基本思路是,用户可以在该类中注册多个工厂,当有URLRequest请求时,先由工厂检查它是否需要处理该类“scheme”,如果没有,工厂管理类继续交给下一个工厂类来处理。最后,如果没有任何工厂能够处理,Chromium则交给内置的工厂来检查和处理是否为“http://”、“f'tp://”或者“file://”等。
  • 当URLRequestHttpJob对象被创建后,该对象首先从Cookie管理器中获取与该URL相关的信息。之后,它同样借助于HttpTransactionFactory对象创建一个HttpTransaction对象来表示开启一个HTTP连接的事务(当然这里的概念不同于数据库中的事务概念)。通常情况下,HttpTransactionFactory对象对应的是一个它的子类HttpCache对象。HttpCache类使用本地磁盘缓存机制,如果该请求对应的回复已经在磁盘缓存中,那么Chromium无需再建立HttpTransaction来发起连接,而是直接从磁盘中获取即可。如果磁盘中没有该URL的缓存,同时如果目前该URL请求对应的HttpTransaction已经建立,那么只要等待它的回复即可。当这些条件都不满足的时候,Chromium实际上才会真正创建HttpTransaction对象、
  • HttpNetworkTransaction类使用HttpNetworkSession类来管理连接会话。HttpNetworkSession类通过它的成员HttpStreamFactory对象来建立TCPSocket连接,之后Chromium创建HttpStream对象。HttpStreamFactory对象将和网络之间的数据读写交给自己新创建的一个HttpStream子类的对象来处理。
  • 套接字的建立,Chromium中与服务器建立连接的套接字是StreamSocket类,它是一个抽象类,在POSIX系统和Windows系统上有着分别不同的实现。同时为了支持SSL机制,StreamSocket类还有一个子类----SSLSocket。

(3)代理

用户代理由以下几个类来处理:

  • Proxy Service:对于一个URL,HttpStreamFactory类使用ProxyService类来获取代理信息。ProxyService类首先会检查当前代理设置不是最新的。如果不是,它依赖ProxyConfigService来重新获取代理信息。该类不处理实际任务,而是使用ProxyReslover类来做实际代理工作。
  • Proxy Config Service:获取代理信息的类,可获得平台上的代理设置,在Linux】Windows上有不同的实现。
  • ProxyScriptFetcher:Chromium支持代理的JavaScript脚本,该类负责从代理的URL中获取该脚本。
  • Proxy Resolver:实际负责代理的解释和执行,通常启用新的线程来处理,因为当前可能会被域名的解析所阻碍。
  • ProxyResolverV8:ProxyResolver的子类,使用V8引擎来解析和执行脚本。

(4)域名解析(DNS)

        通常情况下,用户都是使用域名来访问网络资源的,所以在建立TCP连接前需要解析域名。Chromium中使用HostResolverImpl类来解析域名,具体调用的函数时“getaddrinfo()”,该函数是一个阻塞式的函数,所以Chromium理所当然使用单独的线程来处理它,这是Chromium的原则之一。

        为了保证效率,使用HostCache类来保存解析后的域名,最多时会有多达1000个域名和地址映射关系会被存储起来。

3,3 磁盘本地缓存

浏览器的缓存机制能够提高网页的加载速度。

(1)特性

  • 虽然需要缓存的资源可能很多,但磁盘空间不是无限大的,所以必须要有相应的机制来移除合适的缓存资源,以便加入新的资源。
  • 能够保证在浏览器崩溃时不破坏磁盘文件,至少能够保护原先在磁盘中的数据。
  • 能够高效和快速地访问磁盘中现有的数据结构,支持同步和异步两种访问方式。
  • 能够避免同时存储两个相同的资源。
  • 能够很方便地从磁盘中删除一个项,同时可以在操作一个项的时候不受其他请求的影响。
  • 磁盘不支持多线程访问,所以需要把所有磁盘缓存的操作放入单独的一个线程。
  • 升级版本时,如果磁盘缓存的内部存储结构发生改变,Chromium仍然能够支持老版本的结构。

(2)结构

        实现上主要有两个类,Backend(整个磁盘缓存) 和 Entry(表中的表项)。至少需要一个索引文件和四个数据文件。索引文件用来索引,数据文件又称块文件。缓存通常是一个表,对于整个表的操作作用在 Backend 类上,包括创建表中的一个个项,每个项由关键字来唯一个确定,这个关键字就是资源的 URL。对于项目内的操作包括读写都是由 Entry 类来处理。

  • Backend 类表示整个磁盘缓存,是所有磁盘缓存操作的主入口,表示一个缓存表。
  • Entry 类指的是表中的表项,表项的结构分为两个部分。

        表和表项如何组织和存储在磁盘上:至少有一个索引文件和四个数据文件(块文件),每个块文件的大小是固定的,当资源文件超过某个块的大小就会为其分配多个块来解决,但最多不能超过四个块,超过四个块能存储的时候会建立单独的文件来保存。如果一个表项需要分配四个块则这些块在文件中的索引位置是对齐的(起始块的位置是4 的倍数)

  • 索引文件:用来检索存放在数据文件中的众多索引项,用来索引表项,包括一个索引头部和索引地址表。直接将文件映射到内存地址。头部用来表示该索引文件的信息,如索引文件版本号、索引项数量、文件大小等。索引地址表:保存各个表项对应的索引地址。该索引文件直接将文件映射到内存地址,这样可以快速地找到表项的索引地址。 

        struct NET_EXPORT_PRIVATEIndex Header{

                uint32  magic;

                uint32 version;

                int32 num_entries;     //nuimuber entries currently stored.

                int32 num_bytes;       //Total size of the stored data.

                int32 last_file;             //Last external file created.

                int32  this_id;              //Id for all entries being changed (dirty flag).

                CacheAddr status;      //Storage for usage data.

                int32  table_len;         //Actual size of the table(0==kIndexTablesize),

                int32  crash;                //Signals a previous crash.

                int32  experiment;       //Id of an ongoing test.

                uint64   create_time;   //Creation time for this set of files.

                int32   pad[52];

                LruData  lru;             //Eviction control data.

        };

        strunct  Index  {                 // The structure of the whole index file.

                IndexHeader header;

                CacheAddr table[kIndexTablesize] ;   //Default size Actual size controlled by header.table_len.

        };

  • 数据文件:块文件,有很多不同大小的块,用于快速检索,这些数据块的内容是表项,包括 HTTP 文件头、请求数据和资源数据。资源文件大小超过一定值的时候,Chromium会捡来单独的文件来保存它们,而不是将它们放入四个数据文件中。这些单独存储的文件中并没有元数据信息,只是资源文件的内容,其文件名形如“f_xxxx,xxxx是0-9A-F是十六进制数来表示编号。

   表项的结构也分为两个部分:

  • 第一部分用于标记自己,包括各种元数据信息和自身的内容,较少变动
  • 第二部分主要为表项的回收算法服务,经常发生变动,里面保存了回收算法所需要的信息

     struct EntryStore {

                uint32  hash;                           //Full hash of the key.

                CacheAddr  next;                 //Next entry with the same hash or bucket.

                CacheAddr  rankings_node;   //Rankings node for this entry.

                int32   reuse_count;                //How often is this entry used.

                int32  refetch_count;               //How often is this fetched from the net.

                int32  state;                             //Current state

                uint64  creation_time;

                int32   key_len;

                CachedAddr  long_key;                   //Optional adddress of a  long key.

                int32           data_size[4];                   //We can store up to 4 data streams for each

                CacheAddr  data_add[4];                 //entry

                uint32      flags;                                //Any Combination of EntryFlags.

                int32   pad[4];

                uint32    self_hash;                           // The hash of EntryStore up to this point.

                char   key[256-24*4];                        //null terminated

        };

磁盘缓存的存储结构如下:

        Chomium使用LRU算法来回收表项,因为磁盘存储的空间是有限的,不能无限的增长下去,所以对于很少使用到的表项,可以回收这一部分磁盘空间。

3.4  Cookie机制

        Cookie就是一系列的“关键字+值”对。

        test1=webkit;test2=chromium;Expires=Sun,30 Oct 2016 21:35:00 GMT;Domain.myweb.com;

        test1,test2 自定义的关键字

        Expires、Domain:为预定义的关键字,表示的是该Cookie的失效时间和该Cookie对应的域。

        一个网页的 Cookie 只能被该网页(或者说是该域的网页)访问。根据 Cookie 的时效性可以将 Cookie 分成两种类型,第一种是会话型 Cookie(Session Cookie),这些 Cookie 只是保存在内存中,当浏览器退出的时候即清除这些 Cookie。如果 Cookie 没有设置失效时间,就是会话型 Cookie。第二中是持续型 Cookie(Persistent Cookie),也就是当浏览器退出的时候,仍然保留 Cookie 的内容。该类型的 Cookie 有一个有效期,在有效期内,每次访问该 Cookie 所属域的时候,都需要将该 Cookie 发送个服务器,这样服务器就能够追踪用户的行为。

        Chromium中支持Cookie的机制也较为简单和清晰,CookieMonster是Cookie机制中最重要的类,实际上相当于Cookie的管理器,它包括几个作用:

  • 实现CookieStore的接口,它是对外的接口,调用者可以设置和获得Cookie。
  • 报告各种Cookie的事件,如更新信息等,主要使用Delegate类。
  • Cookie对象的集合,也就是CanonicalCookie的集合,每个CanonicalCookie对象表示一个域的Cookie集合。
  • 持续型Cookie的存储

        以上的是在内存中保存的,当需要存储到磁盘的时候使用PersistentCookieStore,具体由SQLLitePersistenCookieStore类负责实际的存储动作。

3.5  安全机制

        HTTP是一种使用明文来传输数据的应用层协议。构建建在SSL之上的HTTPS提供了安全的网络传输机制。支持一种新的标准 HSTS 协议(HTTP Strict Transport Security):能够让网络服务器声明它只支持 HTTPS 协议。浏览器能够理解服务器的声明,发送基于 HTTPS 的连接和请求。通常情况下,浏览器的用户不会输入“scheme(http://),l浏览器的补齐功能通常会加入该“scheme”,但是,服务器可能需要”https://",在这样的情况下,该协议就显得非常有用。一般情况次啊,服务在返回的消息头中加入以下信息表明它支持该标准。

        Strict-Transport-Security:max-age=16070400;includesSubDomains

3.6  高性能网络栈

        Chromium的网络模块有两个重要目标,其一是安全,其二是速度。

(1)DNS 预取和 TCP 预连接:

  • DNS 预取就是利用现有的 DNS 机制,提前解析网页中可能的网络连接。当用户正在浏览当前网页的时候,Chromium 提取网页中的超链接,将域名抽取出来,利用比较少的 CPU 和网络带宽来解析这些域名和 IP 地址,这样一来,用户根本感觉不到这一过程。当用户单击这些链接的时候,可以节省不少时间,特别在域名解析比较慢的时候,效果特别明显。
  • DNS预取技术直接利用系统的域名解析机制,不会阻碍当前网络栈的工作,DNS预取技术针对多个域名采取并行处理的方式,每个域名的解析须由新开启一个线程来处理,结束后此线程即退出。
  • 网页的开发者可以显示指定预取那些域名来让Chromium解析,这非常直接了当,特别对于那些需要重定向的域名,具体做法如下:<link rel="dns-prefetch" href="http://this-is-a-dns-prefetch-example.com">。当然,DNS预取技术不仅应用于网页中的超链接,在用户敲下回车键获取网页之前,Chromium 就已经开始用 DNS 预解析技术解析该域名。
  • 可以通过在地址栏中输入“chrome://dns/”查看Chromium的DNS预取的域名。
  • Chromium使用追踪技术来获取用户从什么网页跳转到另一个网页,可以利用这些数据、一些启发式规则和其他一些暗示来预测用户下面会单击什么超链接,当有足够的把握时,它便先DNS预取,更进一步,还可以预先建立TCP连接。
  • 同DNS预取技术一样,追踪技术不仅应用于网页中的超链接,当用户在地址栏输入地址,如候选项同输入的地址很匹配,则在用户敲下回车键获取该网页之前,Chromium就已经开始尝试建立TCP连接了。

(2)支持 HTTP 管线化技术(Pipelining):

        HTTP 1.1 中新增的管线化技术:将多个 HTTP 请求一次性提交给服务器,可能将多个 HTTP 请求填充在 TCP 数据包内(相当于 HTTP 权威指南中串行事务处理中的管道化连接),HTTP管线化需要在网络上传较少的TCP数据包,因此减少了网络的负载。

        请求结果的管线化使得HTML网页加载时间动态提升,特别在具体有高延迟的连接环境下,管线化机制需要通过永久连接(Persistent Connection)完成,并且只有 GET 和 HEAD 等幂等请求可以进行管线化。使用场景有很大的限制。

(3)  SPDY

        解决 HTTP 管线技术的使用限制。SPDY 协议是一种新的会话层协议,定义在 HTTP 协议和 TCP 协议之间。核心思想是多路复用,仅使用一个连接来传输一个网页中的众多资源,没有改变 HTTP 协议,将 HTTP 协议头通过 SPDY 来封装和传输,服务器只需要从 SPDY 的消息头中获取各个资源的 HTTP 头即可。SPDY 的工作方式有以下四个特征:

  • 利用一个 TCP 连接来传输不限个数的资源请求的读写数据流。
  • 根据资源请求的特性和优先级, SPDY 可以调整这些资源请求的优先级。
  • 只对 https 请求使用压缩技术,可以大大减少需要传输的字节数。
  • 当用户需要浏览某个网页,支持 SPDY 的服务器在发送网页内容时可以发送一些信息给浏览器告诉后面可能需要哪些资源,浏览器可以提前知道并决定是否需要下载。更极端的情况是,服务器可以主动发送资源。

下图是是基于SPDY协议的网络栈结构

与前面的调用栈结构有三点不同:

  • 虚线框表示可能有多个SpdyStream和SpdyHttpStream对象,也就是多个流使用一个SpdySession会话,同时使用一个socket连接。多多个Stream对象的管理、删除、创建、数量限制等都是由SpdySession来处理。
  • 对于之前的一些类,Spdy有专门的实现,因为需要支持新协议的关系。
  • SpdyHttpStream类继承自之前的HttpStream类会对应一个SpdyStream并将Spdy协议部分等实际工作交给SpdyStream类来做

(4)QUIC

        新的网络传输协议,改进 UDP 数据协议的能力。同SPDY建立传输层之上不同,QUIC所要解决的问题就是传输层的传输效率,并提供了数据加密。所以,SPDY可以在QUIC上工作。

3.7 实践:chromium网络工具和信息

     Chromium提供了网路信息工具Chrome://net-internals.可以看到Capture、Export、Import、Proxy、Events、Timeline、DNS、Sockets、SPDY、QUIC、Pipelining、擦车、SPIs、Tests、HSTS、Bandwidth、Prerender等类别。

        首先是Events类别,该类别记录了所有网络栈完成的工作和传送消息。记录ID、对象类。其中有些以_JOB结尾的类,表示一个个的任务,这些任务可能是连接、域名解析等。它们不负责具体的工作,只起到一层桥接和封装的作用,任务完成后就直接结束了,当用户单击表中一项的时候,当前页面会给当前对象从过去到现在发生的各个操作,或者叫事件。

        其次是类别“Timeline”.它的含义就是一个按照时间绘制的图,图中记录在各个时间点Chromium 使用网络资源。

相关文章:

《WebKit 技术内幕》之四(3): 资源加载和网络栈

3. 网络栈 3.1 WebKit的网络设施 WebKit的资源加载其实是交由各个移植来实现的&#xff0c;所以WebCore其实并没有什么特别的基础设施&#xff0c;每个移植的网络实现是非常不一样的。 从WebKit的代码结构中可以看出&#xff0c;网络部分代码的确比较少的&#xff0c;它们都在…...

vue3-模板引用

//1.调用ref函数 -> ref对象 const h1Ref ref(null) const comRef ref(null) //组件挂载完毕之后才能获取 onMounted(()>{console.log(h1Ref.value);console.log(comRef.value); })<div class"father"><!-- 通过ref标识绑定ref对象 --><h2 re…...

聚类模型评估指标

聚类模型评估指标-轮廓系数 计算样本i到同簇其它样本到平均距离ai&#xff0c;ai越小&#xff0c;说明样本i越应该被聚类到该簇&#xff08;将ai称为样本i到簇内不相似度&#xff09;&#xff1b;计算样本i到其它某簇Cj的所有样本的平均距离bij&#xff0c;称为样本i与簇Cj的…...

测试 ASP.NET Core 中间件

正常情况下&#xff0c;中间件会在主程序入口统一进行实例化&#xff0c;这样如果想单独测试某一个中间件就很不方便&#xff0c;为了能测试单个中间件&#xff0c;可以使用 TestServer 单独测试。 这样便可以&#xff1a; 实例化只包含需要测试的组件的应用管道。发送自定义请…...

智能小程序小部件(Widget)媒体组件属性说明和示例代码汇总

camera 基础库 2.2.0 开始支持, 低版本需做兼容处理。 系统相机。相关 API&#xff1a;ty.createCameraContext。这是基于异层渲染的原生组件, 请注意原生组件使用限制。 属性说明 属性名类型默认值必填说明modestringnormal否应用模式&#xff0c;只在初始化时有效&#xff…...

enum的比较

enum的比较 使用enum定义的枚举类是一种引用类型。 前面我们讲到&#xff0c;引用类型比较&#xff0c;要使用equals()方法&#xff0c;如果使用比较&#xff0c;它比较的是两个引用类型的变量是否是同一个对象。 因此&#xff0c;引用类型比较&#xff0c;要始终使用equals…...

网工每日一练(1月15日)

1.某计算机系统由下图所示的部件构成&#xff0c;假定每个部件的千小时可靠度为R&#xff0c;则该系统的千小时的可靠度为 ( D ) 。 2.以下IP地址中&#xff0c;属于网络 201.110.12.224/28 的主机IP是&#xff08; B &#xff09;。 A.201.110.12.224 B.201.110.12.238 C.20…...

henauOJ 1113: 计算x的n次方

题目描述 给定x和n&#xff0c;计算出x^n。 0<x<10,0<n<9; 要求定义一个函数:int pow1(int x,int n);//返回x^n。 本题只允许提交函数及其内容&#xff0c;提交多余内容会编译错误 C/C函数原型 int pow1(int x,int n); Java函数原型 public static int pow1(int…...

64.Spring事件监听的核心机制是什么?

Spring事件监听的核心机制是什么? spring的事件监听有三个部分组成 事件(ApplicationEvent) 负责对应相应监听器 事件源发生某事件是特定事件监听器被触发的原因监听器(ApplicationListener) 对应于观察者模式中的观察者。监听器监听特定事件,并在内部定义了事件发生后的响应…...

《C++大学教程》3.12Account类

题目&#xff1a; (Account类)创建一个名为Account 的类&#xff0c;银行可以使用它表示客户的银行账户。这个类应该包括一个类型为int 的数据成员&#xff0c;表示账户余额。【注意:在后续章节中&#xff0c;将使用称为浮点值的包含小数点的数(例如2.75)表示美元数。】 这个…...

【工作记录】基于springboot3+springsecurity实现多种方式登录及鉴权(二)

前言 上篇文章介绍了基于springboot3+springsecurity实现的基于模拟数据的用户多种方式登录及鉴权的流程和代码实现,本文我们继续完善。 主要完善的点 主要通过如下几个点来完成优化和完善: 用户信息获取通过查询mysql数据库实现token生成方式使用jwt用户信息存储及读取使用…...

CSS笔记III

选择器 结构伪类选择器 作用&#xff1a;根据元素的结构关系查找元素 选择器说明E:first-child查找第一个E元素E:last-child查找最后一个E元素E:nth-child(N)查找第N个E元素(第一个元素N值为1) nth-child(公式) 作用是可以根据元素的结构关系查找多个元素 偶数标签&#x…...

Bit.Store 加密卡集成主流 BRC20通证,助力 BTC 生态流动性

...

openssl3.2 - 官方demo学习 - mac - siphash.c

文章目录 openssl3.2 - 官方demo学习 - mac - siphash.c概述笔记END openssl3.2 - 官方demo学习 - mac - siphash.c 概述 MAC算法为 SIPHASH, 设置参数(C-rounds, D-rounds, 也可以不设置, 有默认值) 用key初始化MAC算法, 算明文的MAC值 笔记 /*! \file siphash.c \note op…...

(六)深入理解Bluez协议栈之“GATT Client Profile”

前言: 本章节我们继续介绍GATT Client Profile的实现,参考的程序是tools\btgatt-client.c,需要注意的一点,在./configure时,需要添加 --enable-test --enable-testing才会编译该c文件,编译完成后,生成的可执行程序为btgatt-client。本文主要以btgatt-client运行时可能会…...

SVO编译

文章目录 软件版本错误编译运行轨迹路径保存运行TUM数据集 附录针对svo slam的/svo/pose_imu转为tum格式代码 软件版本 ubuntu 20 rosnoeticSVO SLAM虚拟机 windows 11 错误 常见的git clone问题可以使用DevSidecar解决&#xff0c;在 加速服务-基本设置-绑定IP 设置为0.0.0…...

探索未知:最新发布的顶级浏览器,为你带来前所未有的浏览体验

目录 学习目标&#xff1a; 学习内容&#xff1a; 学习时间&#xff1a; 学习产出&#xff1a; 基本功能和操作方法&#xff1a; 如何打开和关闭浏览器 如何新建和关闭标签页 前进、后退、刷新页面等导航操作 使用地址栏和搜索栏进行访问和搜索 管理浏览器的历史记录 高级功能&…...

EasyX图形化学习(三)

1.帧率&#xff1a; 即每秒钟界面刷新次数&#xff0c;下面以60帧为例&#xff1a; 1.数据类型 clock_t&#xff1a; 用来保存时间的数据类型。 2.clock( ) 函数&#xff1a; 用于返回程序运行的时间,无需参数。 3.例子&#xff1a; 先定义所需帧率&#xff1a; const …...

git-生成证书、公钥、私钥、error setting certificate verify locations解决方法

解决方法 方法1-配置证书、公钥、私钥打开Git Bash设置名称和邮箱执行&#xff0c;~/.ssh执行&#xff0c;ssh-keygen -t rsa -C "这是你的邮箱"&#xff0c;如图&#xff1a;进入文件夹可以看到用记事本之类的软件打开id_rsa.pub文件&#xff0c;并且复制全部内容。…...

论文笔记(四十)Goal-Auxiliary Actor-Critic for 6D Robotic Grasping with Point Clouds

Goal-Auxiliary Actor-Critic for 6D Robotic Grasping with Point Clouds 文章概括摘要1. 介绍2. 相关工作3. 学习 6D 抓握政策3.1 背景3.2 从点云抓取 6D 策略3.3 联合运动和抓握规划器的演示3.4 行为克隆和 DAGGER3.5 目标--辅助 DDPG3.6 对未知物体进行微调的后视目标 4. 实…...

k8s学习-Deployment

Kubernetes通过各种Controller来管理Pod的生命周期 。 为了满足不同业 务 景 &#xff0c; Kubernetes 开发了Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等多种Controller。我们⾸先学习最常用Deployment。 1.1 Kubectl命令直接创建 第一种是通过kubectl命令直接…...

Unity之四元数

欧拉角 万向节死锁 四元数是什么 Unity中四元数的初始化 四元数和欧拉角的互相转换 补充 四元数相乘代表旋转四元数...

【计算机硬件】3、输入输出技术、总线结构

文章目录 输入输出技术内存与接口地址的编址方法1、 内存与接口地址独立编址方法2、内存与接口地址统一编址方法 计算机和外设间的数据交互方式1、程序控制(查询)方式2、程序中断方式3、DMA方式&#xff08;直接主存存取&#xff09; 总线结构 输入输出技术 内存与接口地址的编…...

k8s的对外服务--ingress

service作用体现在两个方面 1、集群内部 不断跟踪pod的变化&#xff0c;更新endpoint中的pod对象&#xff0c;基于pod的IP地址不断变化的一种服务发现机制 2、集群外部 类似负载均衡器&#xff0c;把流量ip端口&#xff0c;不涉及转发url&#xff08;http&#xff0c;https&a…...

CSS 雷达监测效果

<template><view class="center"><view class="loader"><view></view></view></view></template><script></script><style>/* 设置整个页面的背景颜色为深灰色 */body {background-col…...

C# System.MissingMethodException

C#应用程序工程调用C#类库工程生成的动态链接库调试时报错&#xff1a; System.MissingMethodException HResult0xFFFFFFFF Message找不到方法…… 软件结构如下&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Text; usi…...

Redis面试题23

Redis 的持久化机制是什么&#xff1f; 答&#xff1a;Redis 提供了两种持久化机制来保证数据的持久性&#xff0c;即 RDB&#xff08;Redis Database&#xff09;和 AOF&#xff08;Append Only File&#xff09;。 RDB 持久化&#xff1a;RDB 是 Redis 默认的持久化方式。它…...

Linux中的yum源仓库和NFS文件共享服务

一.yum简介 1.1 yum简介 yum&#xff0c;全称“Yellow dog Updater, Modified”&#xff0c;是一个专门为了解决包的依赖关系而存在的软件包管理器。类似于windows系统的中电脑软件关键&#xff0c;可以一键下载&#xff0c;一键安装和卸载。yum 是改进型的 RPM 软件管理器&am…...

【LeetCode2744】最大字符串配对数目

1、题目描述 【题目链接】 标签&#xff1a;数组&#xff0c;哈希表&#xff0c;字符串&#xff0c;模拟  给你一个下标从 0 开始的数组 words &#xff0c;数组中包含 互不相同 的字符串。  如果字符串 words[i] 与字符串 words[j] 满足以下条件&#xff0c;我们称它们可以…...

安全加速SCDN是什么

安全加速SCDN&#xff08;Secure Content Delivery Network&#xff0c;SCDN&#xff09; 是集分布式DDoS防护、CC防护、WAF防护、BOT行为分析为一体的安全加速解决方案。已使用内容分发网络&#xff08;CDN&#xff09;或全站加速网络&#xff08;ECDN&#xff09;的用户&…...