输入url到页面显示过程的优化

浏览器架构

线程:操作系统能够进行运算调度的最小单位。

进程:操作系统最核心的就是进程,他是操作系统进行资源分配和调度的基本单位。

一个进程就是一个程序的运行实例。启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,把这样的一个运行环境叫进程。

线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率。

进程和线程之间的关系4个特点。

  1. 进程中任意线程执行出错,都会导致整个进程崩溃
  2. 线程之间共享进程中的数据
  3. 当一个进程关闭后,操作系统会回收进程占用的内存
  4. 进程之间内容相互隔离(通过IPC机制进行通信)

现代浏览器为多进程架构,打开一个页面,浏览器至少会打开四个进程 -- 浏览器主进程、渲染进程、GPU进程、网络进程。

  • 浏览器进程:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。
  • 渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎Blink和JavaScript引擎V8都是运行在该进程中,默认情况下,Chrome会为每个Tab标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。
  • GPU进程:实现3D CSS效果,UI界面绘制。
  • 网络进程。主要负责页面的网络资源加载。
  • 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。

地址栏键入URL后会发生什么?

  1. 构建请求:浏览器准备发起网络请求,构建请求行等
  2. 查找缓存:若命中强缓存,直接拦截请求,从本地获取资源

#URL解析

先进行url解析,提取出协议,端口,域名,路径等信息

判断你输入的是一个合法的URL 还是一个待搜索的关键词,并且根据你输入的内容进行对应操作

#DNS查询

获取到了域名对应的目标服务器IP地址

DNS(Domain Name System)是互联网中用于将域名转换为对应 IP 地址的分布式数据库系统。当客户端需要解析域名时,它会发送 DNS 查询请求到 DNS 服务器,并获取对应的 IP 地址。DNS 查询过程可以分为递归查询和迭代查询两种方式。### 递归查询1. **客户端发起请求**:当客户端需要解析域名时,它会发送一个 DNS 查询请求到本地 DNS 服务器。2. **本地 DNS 服务器查询**:本地 DNS 服务器首先检查自己的缓存中是否有该域名对应的 IP 地址。如果有,它会直接返回给客户端。3. **迭代查询**:如果本地 DNS 服务器的缓存中没有该域名对应的 IP 地址,它会向根域名服务器发送一个 DNS 查询请求。根域名服务器会告诉本地 DNS 服务器负责该顶级域的权威 DNS 服务器的地址。4. **查询顶级域 DNS 服务器**:本地 DNS 服务器再向负责该顶级域的权威 DNS 服务器发送一个 DNS 查询请求。顶级域 DNS 服务器会告诉本地 DNS 服务器负责该二级域的权威 DNS 服务器的地址。5. **查询权威 DNS 服务器**:本地 DNS 服务器继续向负责该二级域的权威 DNS 服务器发送 DNS 查询请求,直到最终获取到域名对应的 IP 地址。本地 DNS 服务器将 IP 地址返回给客户端,并将 IP 地址缓存起来,以便下次查询时使用。### 迭代查询1. **客户端发起请求**:客户端发送一个 DNS 查询请求到 DNS 服务器。2. **DNS 服务器查询**:DNS 服务器首先检查自己的缓存中是否有该域名对应的 IP 地址。如果有,它会直接返回给客户端。3. **迭代查询**:如果 DNS 服务器的缓存中没有该域名对应的 IP 地址,它会向根域名服务器发送一个 DNS 查询请求。根域名服务器会告诉 DNS 服务器负责该顶级域的权威 DNS 服务器的地址。4. **查询顶级域 DNS 服务器**:DNS 服务器再向负责该顶级域的权威 DNS 服务器发送一个 DNS 查询请求。顶级域 DNS 服务器会告诉 DNS 服务器负责该二级域的权威 DNS 服务器的地址。5. **查询权威 DNS 服务器**:DNS 服务器继续向负责该二级域的权威 DNS 服务器发送 DNS 查询请求,直到最终获取到域名对应的 IP 地址。然后,DNS 服务器将 IP 地址返回给客户端。=======递归查询和迭代查询的主要区别在于,递归查询是由 DNS 服务器代为向其他 DNS 服务器查询,直到找到域名对应的 IP 地址并返回给客户端;而迭代查询是由 DNS 服务器一步步地指导客户端自行向其他 DNS 服务器查询,直到最终找到域名对应的 IP 地址。
实际上,DNS 解析过程中既有递归查询,也有迭代查询,这两种查询方式是相辅相成的。1. **递归查询**:在 DNS 解析过程中,客户端向本地 DNS 服务器发起递归查询请求。本地 DNS 服务器会负责向其他 DNS 服务器发送递归查询请求,直到找到域名对应的 IP 地址,并将结果返回给客户端。递归查询的特点是 DNS 服务器会负责完成整个查询过程,直到找到结果并返回给客户端。2. **迭代查询**:在 DNS 解析过程中,当本地 DNS 服务器无法直接返回结果时,它会向其他 DNS 服务器发送迭代查询请求,获取更多的信息。这些迭代查询请求会依次向根域名服务器、顶级域 DNS 服务器和权威 DNS 服务器发送,直到最终找到结果。迭代查询的特点是 DNS 服务器向客户端提供其他 DNS 服务器的地址,然后客户端会继续向这些 DNS 服务器发送查询请求,直到找到结果。因此,DNS 解析过程中通常会同时使用递归查询和迭代查询,以确保客户端能够快速准确地获取到域名对应的 IP 地址。

#TCP连接

在确定目标服务器服务器的IP地址后,则经历三次握手建立TCP连接

#发送 http 请求

当建立tcp连接之后,就可以在这基础上进行通信,浏览器发送 http 请求到目标服务器

请求的内容包括:

  • 请求行
  • 请求头
  • 请求主体

#响应请求

当服务器接收到浏览器的请求之后,就会进行逻辑操作,处理完成之后返回一个HTTP响应消息,包括:

  • 状态行
  • 响应头
  • 响应正文

在服务器响应之后,由于现在http默认开始长连接keep-alive,当页面关闭之后,tcp链接则会经过四次挥手完成断开

#页面渲染

当浏览器接收到服务器响应的资源后,首先会对资源进行解析:

  • 查看响应头的信息,根据不同的指示做对应处理,比如重定向(301,302),存储cookie(如果响应头中包含 Set-Cookie 字段,表示服务器希望浏览器存储 cookie,浏览器会根据这些字段存储 cookie 信息。),解压gzip(Content-Encoding :gzip),缓存资源等等
  • 查看响应头的 Content-Type的值,根据不同的资源类型采用不同的解析方式

(Content-Type 是响应头中的一个字段,它指示了响应内容的类型。浏览器会根据 Content-Type 的值来确定响应的内容类型,然后采用不同的解析方式对响应内容进行处理。例如:

  • 如果 Content-Type 表示响应内容是 HTML 文档(如 text/html),浏览器会将其解析为 DOM 结构,并进行页面渲染。
  • 如果 Content-Type 表示响应内容是 JavaScript 脚本(如 application/javascript),浏览器会执行这段 JavaScript 代码。
  • 如果 Content-Type 表示响应内容是 CSS 样式表(如 text/css),浏览器会解析这段 CSS 代码,并应用于页面渲染。
  • 如果 Content-Type 表示响应内容是图片、音频或视频等媒体资源(如 image/jpegaudio/mp3video/mp4 等),浏览器会直接将其展示给用户或者交给相应的插件进行处理。)

渲染流程:HTML、CSS和JavaScript,是如何变成页面的?

关于页面的渲染过程如下:dom css render 布局绘制显示

  • 解析HTML,构建 DOM 树
  • 解析 CSS ,生成 CSS 规则树 样式计算
  • 合并 DOM 树和 CSS 规则,生成 render 树,(在这个阶段,浏览器会根据 DOM 树中的每个可见节点和样式计算得到的具体样式来构建渲染树,忽略掉不可见的元素或不影响渲染的节点(比如 <script><meta> 等)。这个渲染树将用于后续的布局和绘制。)
  • 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
  • 绘制 render 树( paint ),绘制页面像素信息
  • 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成,显示在屏幕上
  1. 构建DOM树:浏览器无法直接理解和使用HTML,所以需要将HTML转换为浏览器能够理解的结构——DOM树

  2. 样式计算:

    1. 把CSS转换为浏览器能够理解的结构 -- styleSheets
    2. 转换样式表中的属性值,使其标准化,比如将颜色‘red’转化成渲染引擎可以理解的rgb值
    3. 浏览器会将DOM树和CSS规则树合并,计算每个元素的具体样式信息,即进行样式计算。这个过程中,浏览器会计算出每个DOM节点的最终样式信息,包括继承的样式和自身的样式。
  3. 布局阶段:有了DOM树和样式,还不足以显示页面,接下来就需要计算出DOM树中可见元素的几何位置,这个计算过程叫做布局。

    1. 创建布局树:构建一颗元素布局树,比如去掉head等没有实际元素的标签,去掉display为none的元素等
  4. 分层:页面中有很多复杂的效果,如一些复杂的3D变换、页面滚动,或者使用z-indexing做z轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树。所以浏览器的页面实际上被分成了很多图层,这些图层叠加后合成了最终的页面

  5. 图层绘制:将布局树中的元素转换成屏幕上的像素信息。

  6. 栅格化操作:通常一个页面可能很大,但是用户只能看到其中的一部分,这个部分叫做视口。在有些情况下,有的图层可以很大,比如有的页面要滚动好久才能滚动到底部,但是通过视口,用户只能看到页面的很小一部分,所以在这种情况下,要绘制出所有图层内容的话,就会产生太大的开销,而且也没有必要。基于这个原因,合成线程会将图层划分为图块,这些图块的大小通常是256x256或者512x512。然后合成线程会按照视口附近的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图。而图块是栅格化执行的最小单位。

  7. 合成和显示:所有图块都栅格化完成后,合成线程将指令提交给浏览器进程,浏览器进程根据指令将页面内容绘制到内存中,最后从内存中取出图像显示到屏幕上。

从发起URL请求开始,到首次显示页面的内容,在视觉上经历三个阶段。可能会有阻塞的地方,怎么解决

页面渲染过程中可能出现阻塞的主要环节包括:

  • 等请求发出去之后,到提交数据阶段,这时页面展示出来的还是之前页面的内容。
  • 提交数据之后渲染进程会创建一个空白页面,这段时间称为解析白屏,并等待CSS文件和JavaScript文件的加载完成,生成CSS规则树和dom树,然后合成布局树,最后还要经过一系列的步骤准备首次渲染。
  • 第三个阶段,等首次渲染完成之后,就开始进入完整页面的生成阶段了,然后页面会一点点被绘制出来。

影响第一个阶段的因素主要是网络或者是服务器处理。

第二个阶段主要问题是白屏时间,如果白屏时间过久,就会影响到用户体验。为了缩短白屏时间,需要挨个分析这个阶段的主要任务,包括了解析HTML、下载CSS、下载Js、生成CSSOM、执行JavaScript、生成布局树、绘制页面一系列操作。通常情况下的瓶颈主要体现在下载CSS文件、下载JavaScript文件和执行JavaScript。

1. HTML解析:浏览器解析HTML文档构建DOM树时,如果遇到`<script>`标签,会立即暂停解析,等待脚本执行完毕。这是因为脚本可能会修改DOM,所以浏览器需要等待脚本执行完成后再继续解析。

2. CSS解析:CSSOM(CSS对象模型)的构建也可能阻塞渲染,因为浏览器需要确保页面的样式在脚本执行之前就已经确定。

3. JavaScript执行:JavaScript的执行会阻塞DOM的构建,因为脚本可能会操作DOM元素。

所以要想缩短白屏时长,可以有以下策略:

  • 将关键CSS直接内联到HTML中(style标签),可以加快首次渲染的速度(行内>内部>外部)。对于非关键CSS,可以通过媒体查询或JavaScript异步加载。这样只有在特定的场景下才会加载特定的CSS文件。
  • <!-- 异步加载非关键CSS --><script>var link = document.createElement('link');link.rel = 'stylesheet';link.href = 'non-critical.css';document.head.appendChild(link);</script>
    </head>

  • 异步加载脚本:使用asyncdefer属性将JavaScript脚本异步加载,可以使得脚本不会阻塞页面的渲染,从而减少白屏时间。                           async:异步加载脚本,脚本加载完成后,会立即执行,与在页面中出现的顺序无关;            defer:浏览器立即加载,但是延迟执行,需要在DOMContentLoaded事件之前执行,与出现顺序有关,dom加载完毕后按出现顺序依次执行。
  • 使用CDN加速:将页面资源分发到全球各地的CDN(内容分发网络),可以加速资源的加载速度,减少白屏时间。CDN可以使用户从距离较近的服务器获取资源,从而提高访问速度

  • 使用预加载和预渲染技术:可以使用预加载(preload)和预渲染(prerender)等技术,提前加载页面所需的资源或者预渲染页面内容,以减少白屏时间。预加载可以在页面加载过程中提前加载关键资源,而预渲染可以在后台加载整个页面内容,使得用户访问页面时可以立即展示完整内容。
  • HTTP/2通过引入多路复用、头部压缩、服务器推送等技术,优化了网络资源的利用效率,减少了网络连接的延迟,提高了页面加载速度
  • 代码分割和懒加载:可以使用代码分割将代码分成多个小块,然后按需加载。对于不影响首屏渲染的组件或功能,可以使用懒加载技术延迟加载。Webpack提供了一种称为“动态导入”的语法,可以实现代码分割。
// 使用动态导入语法,将代码按需分割成多个小块
import('./module').then(module => {// 在需要的时候加载模块module.doSomething();
});
Webpack会将动态导入的代码块分割成单独的文件,并在需要的时候按需加载。
在React中,可以使用React.lazy和Suspense组件来实现懒加载。
import React, { Suspense } from 'react';const LazyComponent = React.lazy(() => import('./LazyComponent'));function MyComponent() {return (<div><Suspense fallback={<div>Loading...</div>}><LazyComponent /></Suspense></div>);
}
当 MyComponent 被渲染时,它会先显示 fallback 属性指定的加载中提示,
然后在 LazyComponent 加载完成后显示真正的内容。
  • 客户端缓存:浏览器可以通过缓存响应内容来减少对服务器的请求。通过设置合适的缓存控制头(如Cache-ControlExpires),可以告诉浏览器何时可以使用缓存以及缓存的有效期。对于那些不经常变化的静态资源,可以使用强缓存来尽快地加载页面内容,减少白屏时间;而对于那些可能会频繁更新的动态内容,可以使用协商缓存来确保客户端可以获取到最新的资源。在Express中,你可以在路由处理函数中设置缓存控制头,通过 res.setHeader 方法实现。

代码优化

比如下面的代码,实现了一个斐波那契数列,也就是说,在实现的这个数列中,每一个数的值是前面两个数的值之和。可以使用简单的递归算法实现斐波那契数列后,在页面显示计算结果。

function fib(n){ if(n<=1) return 1 return fib(n-1)+fib(n-2) } let count = ref(fib(38))

使用performance:

打开调试窗口中的 Performance 面板,使用录制功能后,便可得到下面的火焰图。通过这个火焰图,可以清晰地定位出这个项目中,整体而言耗时最长的 fib 函数,并且能看到这个函数被递归执行了无数次。到这里,不难意识到这段代码有性能问题。不过,定位到问题出现的地方之后,代码性能的优化就变得方向明确了。

用户体验优化

1.比如用户加载大量图片的同时,如果本身图片清晰度较高,那直接加载的话,页面会有很多图一直是白框。所以可以预先解析出图片的一个模糊版本加载图片的时候,先加载这个模糊的图作为占位符,然后再去加载清晰的版本。虽然额外加载了图片文件,但是用户在体验上得到了提升。

2.类似的场景还有很多,比如用户上传文件的时候,如果文件过大,那么上传可能就会很耗时。而且一旦上传的过程中发生了网络中断,那上传就前功尽弃了。为了提高用户的体验,可以选择断点续传也就是把文件切分成小块后,挨个上传。这样即使中间上传中断,但下次再上传时,只上传缺失的那些部分就可以了。可以看到,断点上传虽然在性能上,会造成网络请求变多的问题,但也极大地提高了用户上传的体验。

3.还有很多组件库也会提供骨架图的组件,能够在页面还没有解析完成之前,先渲染一个页面的骨架和 loading 的状态这样用户在页面加载的等待期就不至于一直白屏

性能监测报告

解释一下 FCP、TTI 和 LCP 这几个关键指标的含义。

首先是 First Contentful Paint,通常简写为 FCP,它表示的是页面上呈现第一个 DOM 元素的时间。在此之前,页面都是白屏的状态;

然后是 Time to interactive,通常简写为 TTI,也就是页面可以开始交互的时间;

还有和用户体验相关的 Largest Contentful Paint,通常简写为 LCP,这是页面视口上最大的图片或者文本块渲染的时间,在这个时间,用户能看到渲染基本完成后的首页,这也是用户体验里非常重要的一个指标。


可以通过代码中的 performance 对象去动态获取性能指标数据,并且统一发送给后端,实现网页性能的监控。性能监控也是大型项目必备的监控系统之一,可以获取到用户电脑上项目运行的状态。下图展示了 performance 中所有的性能指标,可以通过这些指标计算出需要统计的性能结果。

const timing = window.performance && window.performance.timing
const navigation = window.performance && window.performance.navigation// DNS 解析:
const dns = timing.domainLookupEnd - timing.domainLookupStart// 总体网络交互耗时:
const network = timing.responseEnd - timing.navigationStart// 渲染处理:
const processing = (timing.domComplete || timing.domLoading) - timing.domLoading// 可交互:
const active = timing.domInteractive - timing.navigationStart

在上面的代码中,通过 Performance API 获取了 DNS 解析、网络、渲染和可交互的时间消耗。有了这些指标后,就可以随时对用户端的性能进行检测,做到提前发现问题,提高项目的稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/791574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HDLbits 刷题 --Always nolatches

学习: Your circuit has one 16-bit input, and four outputs. Build this circuit that recognizes these four scancodes and asserts the correct output. To avoid creating latches, all outputs must be assigned a value in all possible conditions (See also always…

【HTML】简单制作一个3D动画效果重叠圆环

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的…

搞学术研究好用免费的学术版ChatGPT网站-学术AI

学术版ChatGPThttps://chat.uaskgpt.com/mobile/?user_sn88&channelcsdn&scenelogin 推荐一个非常适合中国本科硕士博士等学生老师使用的学术版ChatGPT&#xff0c; 对接了超大型学术模型&#xff0c;利用AI技术实现学术润色、中英文翻译&#xff0c;学术纠错&#…

centOS如何升级python

centOS下升级python版本的详细步骤 1、可利用linux自带下载工具wget下载&#xff0c;如下所示&#xff1a; 笔者安装的是最小centos系统&#xff0c;所以使用编译命令前&#xff0c;必须安装wget服务&#xff0c;读者如果安装的是界面centos系统&#xff0c;或者使用过编译工具…

在 Amazon Timestream 上通过时序数据机器学习进行预测分析

由于不断变化的需求和现代化基础设施的动态性质&#xff0c;为大型应用程序规划容量可能会非常困难。例如&#xff0c;传统的反应式方法依赖于某些 DevOps 指标&#xff08;如 CPU 和内存&#xff09;的静态阈值&#xff0c;而这些指标在这样的环境中并不足以解决问题。在这篇文…

Stable Diffusion 本地化部署

一、前言 最近在家背八股文背诵得快吐了&#xff0c;烦闷的时候&#xff0c;看到使用 AI 进行作图&#xff0c;可以使用本地话部署。刚好自己家里的电脑&#xff0c;之前买来玩暗黑4&#xff0c;配置相对来说来可以&#xff0c;就拿来试试。 此篇是按照 Github 上的 stable-d…

Android JNI基础

目录 一、JNI简介1.1 什么是JNI1.2 用途1.3 优点 二、初探JNI2.1 新建cpp\cmake2.2 build.gradle配置2.3 java层配置2.4 cmake和c 三、API详解3.1 JNI API3.1.1 数据类型3.1.2 方法 3.2 CMake脚本 四、再探JNI 一、JNI简介 1.1 什么是JNI JNI&#xff08;Java Native Interfa…

适配器: stack与queue

模板的使用 容器的复用 传容器: 控制底层是那个控制传仿函数: 控制大小堆的建立 stack 特点: 后进先出底层: 容器的封装(vector, list, dequeue)场景: 模拟递归, 函数压栈等接口:empty(), size(), top(), push(), pop()代码: stack queue 特点: 先进先出底层: 容器的封装…

Linux文件IO(3):使用文件IO进行文件的打开、关闭、读写、定位等相关操作

目录 1. 文件IO的概念 2. 文件描述符概念 3. 函数介绍 3.1 文件IO-open函数 3.2 文件IO-close函数 3.3 文件IO-read函数 3.4 文件IO-write函数 3.5 文件IO-lseek函数 4. 代码练习 4.1 要求 4.2 具体实现代码 4.3 测试结果 5. 总结 1. 文件IO的概念 posix(可移植操作系统接…

【Python系列】Python中的YAML数据读取与解析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

如何做用户体验优化

本文是从用户体验优化角度谈用户体验&#xff0c;其实用户体验不是设计必须的步骤&#xff0c;而是分散在产品设计中的产品设计思想。 一、用户体验分类 用户体验是指用户在“使用”某个产品或服务过程中的全部感受&#xff0c;包括情感、信仰、喜好、认知印象、生理和心理反应…

【设计原则】CQRS

文章目录 概述组成与特点优缺点何时使用 CQRS 模式推荐阅读 概述 CQRS&#xff08;Command Query Responsibility Segregation&#xff09;是一种软件设计模式&#xff0c;其核心设计理念是将一个对象的数据访问&#xff08;查询&#xff09;和数据操作&#xff08;命令&#…

node.js的错误处理

当我打开一个不存在的文件时&#xff0c;错误如下&#xff1a; 在读取文件里面写入console.log&#xff08;err&#xff09;&#xff0c;在控制台中可以看到我的错误代码类型&#xff1a;文件不存在的错误代码 ENOENT。见更多错误代码---打开node.js官方API文档Error 错误 | N…

LangChain-06 RAG With Source Doc 通过文档进行检索增强

安装依赖 pip install --upgrade --quiet langchain-core langchain-community langchain-openai编辑代码 from operator import itemgetter from langchain_core.messages import AIMessage, HumanMessage, get_buffer_string from langchain_core.prompts import format_d…

Java对象Object对象头-MarkWord分析-hashCode

代码主要通过打印对象的内存布局来观察对象头在不同状态下的变化&#xff0c;进而分析对象头在不同情况下的内存布局情况。 System.out.println(ClassLayout.parseInstance(o).toPrintable());&#xff1a;这一行代码通过使用开源库 openjdk.jol 的 ClassLayout 类来解析对象 o…

【Apache Doris】周FAQ集锦:第 1 期

【Apache Doris】周FAQ集锦&#xff1a;第 1 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

31. UE5 RPG使用增强输入激活GameplayAbility(一)

在前面文章中&#xff0c;我们实现了对技能添加并直接激活功能&#xff0c;介绍了GA的相关参数配置。现在&#xff0c;我们还不能通过键位触发技能&#xff0c;正常在游戏时&#xff0c;我们需要通过键位触发技能&#xff0c;实现技能的激活。 在UE5里面添加了增强输入&#xf…

AcWing 786. 第k个数——算法基础课题解

AcWing 786. 第k个数 题目描述 给定一个长度为 n的整数数列&#xff0c;以及一个整数 k&#xff0c;请用快速选择算法求出数列从小到大排序后的第 k 个数。 输入格式 第一行包含两个整数 n 和 k。 第二行包含 n 个整数&#xff08;所有整数均在 1∼10^9 范围内&#xff09…

Linux制作C++静态库和动态库并使用示例

创建动态库&#xff1a; 编写源文件&#xff1a; // sub.h 显式调用 #include <iostream>extern "C" int sub(int a, int b);// sub.cpp #include "sub.h"int sub(int a, int b) {return a - b; }// quadrature.h 隐式调用 #include <iostream&…

使用MySQL和PHP创建一个公告板

目录 一、创建表 二、制作首页&#xff08;创建主题以及显示列表&#xff09; 三、制作各个主题的页面&#xff08;输入回帖和显示列表&#xff09; 四、制作消息的查询界面 五、制作读取数据库信息的原始文件 六、制作数据重置页面 七、效果图 八、问题 1、目前无法处…