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

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件

  • 前言
  • 一. 什么是CSR、SSR、SSG、ISR
    • 1.1 CSR 客户端渲染
    • 1.2 SSR 服务端渲染
    • 1.3 SSG 静态站点生成
      • ① 没有数据请求的页面
      • ② 页面内容需要请求数据
      • ③ 页面路径需要获取数据
    • 1.4 ISR 增量静态再生
    • 1.5 四种渲染方式的对比和总结
  • 二. 服务端组件和客户端组件
    • 2.1 水合(Hydration)
    • 2.2 Suspense 和 Streaming
    • 2.3 React Server Components 和 SSR
    • 2.4 服务端组件 VS 客户端组件

前言

在 NextJs 初级篇 中讲了关于NextJs的安装、路由、中间件等内容,本篇文章来一起学习一下关于 NextJs 的渲染知识。

一. 什么是CSR、SSR、SSG、ISR

我们先来说下这几个名词的专业解释:

  • CSR(Client-side Rendering)客户端渲染
  • SSR(Server-side Rendering)服务端渲染
  • SSG(Static Site Generation)静态站点生成
  • ISR(Incremental Static Regeneration)增量静态再生

接下来我们对每种渲染进行详细的解释以及NextJs的实现案例。后续都用简称来说明。

1.1 CSR 客户端渲染

CSR 常规的实现就是我们常规的React开发,就是一种客户端渲染:

  1. 一般浏览器会下载一个非常小的HTML文件以及必要的JS文件。
  2. 我们在JS中发送请求,更新DOM和渲染页面。比如useEffect钩子函数中初始化页面数据。

NextJs 中,在AppRouter模式下,使用CSR,在组件中使用 'use client' 标明,用useEffect请求初始化数据渲染即可,例如以下伪代码:

'use client'
import React, { useEffect, useState } from 'react'
const Home = () => {const [data, setData] = useState<any>(null);useEffect(() => {setTimeout(() => {setData({ id: 1 })}, 5000);})return <>{data ? <span id='test'>{data.id}</span> : 'Loading'}</>
}export default Home

刚开始的时候页面长这个样子:
在这里插入图片描述
渲染完毕后:
在这里插入图片描述

1.2 SSR 服务端渲染

SSR 服务渲染有啥好处,我们举个例子:假如客户端网速非常差,那么在CSR的情况下,由客户端发起请求加载数据就会非常慢,倘若我们把加载数据的工作丢给服务端,而服务器的网络情况非常良好,那么最终的首屏加载时长FCP也就更短

但是同样的,由于SSR情况下,它的响应时长还算上了数据的请求,因此响应时间更长,最终的TTFB指标也就更长。

例如NextJs中要想实现SSR,我们可以在pages目录下创建个ssr.tsx文件:
在这里插入图片描述

内容如下,我们需要借助getServerSideProps函数来获取数据并通过props返回给前端组件,

// pages/ssr.js
export async function getServerSideProps() {const data = [{ 'id': 1, 'name': 'ljj' }]return { props: {data} }
}
// getServerSideProps 传入的是什么,这里就接收什么名称的参数
const SSR = ({ data }: any) =>{return <span id='test'>{JSON.stringify(data)}</span>
}
export default SSR;

1.3 SSG 静态站点生成

SSR ,会在构建阶段,就将页面编译成一个静态的HTML文件。

例如,当我们的站点,上面的Layout总是一样的时候,或者是面对所有的用户,展示的都是一个内容,那么这块部分就没必要在用户请求页面的时候来渲染。干脆提前编译为HTML文件,在用户访问的时候,直接返回一个HTML则会更快。

NextJs 中实现SSG,分为这么几种情况:

① 没有数据请求的页面

例如:

const SonA = () => {return <>我是SonA!!!</>
}
export default SonA

这种页面,NextJs 在构建的时候就会生成一个单独的HTML文件,

② 页面内容需要请求数据

如果我们的HTML文件的某些内容,需要通过接口获取,那怎么办?这种方式就需要结合 getStaticProps 函数来使用。例如我们在pages目录下创建ssg.tsx文件:

export default function SSG({ data }: any) {return (<ul>{data.map((item: any) => (<li key={item.id}>{item.title}</li>))}</ul>)
}
export async function getStaticProps() {const res = await fetch('https://jsonplaceholder.typicode.com/posts')const data = await res.json()return {props: {data,},}
}

getStaticProps 这个函数,会在构建的时候被调用,然后通过props属性传递给组件。

③ 页面路径需要获取数据

我们知道NextJs 中有一个动态路由,只需要将动态部分用[]括起来即可,例如:
在这里插入图片描述
那如果我们希望这类路由的页面都通过SSG来实现:

  • blog/1
  • blog/2

如何实现?我们在 getStaticProps 的基础上,追加一个函数的实现 getStaticPaths

export default function Blog({ post }: any) {return (<><header>{post.title}</header><main>{post.body}</main></>)
}
export async function getStaticPaths() {const res = await fetch('https://jsonplaceholder.typicode.com/posts')const posts = await res.json()const paths = posts.map((post: any) => ({params: { id: String(post.id) },}))return { paths, fallback: false }
}export async function getStaticProps({ params }: any) {// 如果路由地址为 /posts/1, params.id 为 1const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`)const post = await res.json()return { props: { post } }
}
  • getStaticProps 用来定义获取的数据传递给HTML
  • getStaticPaths 则用来定义哪些路径将会实现SSG
  • fallback 返回false代表当访问这些静态路径以外的,则返回404.
    当我们执行npm run build的时候,可以看到构建产物如下,这些都是SSG的产物。

在这里插入图片描述

1.4 ISR 增量静态再生

我们的一些页面例如博客,主题内容可能永远是不变的,但是部分内容是改变的,例如这篇博客的阅读量。在我们使用SSG的情况下,这个HTML文件就被固定生成了,那么如何让这个阅读量能够实时的改变呢?那么在SSG的基础上,就有了ISR

  1. 在访问某个SSG页面的时候,可能依旧是老的HTML内容。
  2. 但是与此同时,NextJs 会静态编译一个新的HTML文件。
  3. 那么在第二次访问的时候,就会变成新的HTML文件内容了。

我们在``案例的基础上,稍微改造一下:

export default function Blog({ post }: any) {return (<><header>{post.title}</header><main>{post.body}</main></>)
}
export async function getStaticPaths() {const res = await fetch('https://jsonplaceholder.typicode.com/posts')const posts = await res.json()const paths = posts.map((post: any) => ({params: { id: String(post.id) },}))return { paths, fallback: 'blocking' }
}
function getRandomInt(max: number) {return Math.floor(Math.random() * max);
}
export async function getStaticProps({ params }: any) {const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${getRandomInt(100)}`)const post = await res.json()return {props: { post },revalidate: 3,}
}

可以看到,我们在 getStaticProps 函数中,多暴露了一个属性:revalidate。代表发生请求的时候,需要间隔多少秒才会更新页面,我这里填的是3,也就是3秒会刷新一次,构建新的HTML

注意:ISR需要在生产环境下生效。因此我们npm run build 之后再npm run start
结果如下:
在这里插入图片描述
可以看到我们第一次访问以及接下来的3秒内,博客的内容都是一样的。但是3秒过后,博客的内容就发生了改变,实际上是HTML刷新了。每3秒就会重新构建一个新的HTML,缓存3秒的时长。

1.5 四种渲染方式的对比和总结

CSRSSRSSGISR
名词解释客户端渲染服务端渲染静态站点生成(即生成HTML文件返回给客户端)增量静态再生
实现方式例如ReactuseEffect借助getServerSideProps函数,在服务端请求数据并通过props属性传递给组件①没有数据请求的页面自动生成HTML ②文件内容则借助 getStaticProps 函数获取数据,再生成静态文件 ③ 动态路由则借助getStaticPaths来指定生成HTML的路径在SSG的基础上getStaticProps函数追加暴露revalidate属性,代表刷新HTML的时长
优缺点只有少量的静态文件先加载,由客户端发起请求触发渲染, TTFB 短。但是在网络特别差的情况下,会大大增加FCP(首屏加载时长)可以让初始化请求交给服务端完成,由服务端完成渲染,解决客户端网络不一的情况,FCP缩短,但是会增加响应时长,TTFB时长高。每次请求都会触发SSG渲染可以让页面生成静态HTML在编译时机就可以完成构建,只会触发一次可以控制HTML的刷新时长,在指定的时间范围内使用同一个HTML,时间过后自动重新构建

二. 服务端组件和客户端组件

在第一节当中,我们讲到了SSR,在 NextJs v12之前,都是通过 getServerSideProps 这个函数来实现服务端渲染,即SSR

2.1 水合(Hydration)

SSR 服务端渲染,会将整个组件渲染为HTML,但是HTML是没有交互性的。而客户端在渲染HTML之后,还需要等待JS下载完毕并且执行,由JS来赋予HTML交互性,那么这个阶段就叫做水合。水合过后,内容就会变为可交互性。

那么SSR有这么几个缺陷:

  • SSR渲染,数据的获取必须在组件渲染之前。
  • 组件的JS必须先加载到客户端,才能开始水合。
  • 所有组件都必须水合完毕,组件之间才能够进行交互。

因此,一旦有部分组件渲染慢了,就会导致整体的渲染效率降低。不仅如此,SSR 只能适用于页面的初始化加载,对于后续的页面交互、数据修改等操作,SSR 就无作用了。

2.2 Suspense 和 Streaming

上面提到了,服务端只能在获取所有数据后渲染 HTMLReact 只能在下载了所有组件代码后才能进行水合

为了解决这个问题,就有了 Suspense 组件,它允许你推迟渲染某些内容,直到满足某些条件(例如数据加载完毕)

给个案例如下:

import { Suspense } from 'react'const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));async function Component1() {await sleep(2000)return <h1>Hello Component1</h1>
}async function Component2() {await sleep(3000)return <h1>Hello Component2</h1>
}async function Component3() {await sleep(4000)return <h1>Hello Component3</h1>
}export default function MySuspense() {return (<section style={{ padding: '20px' }}><Suspense fallback={<p>Loading Component1</p>}><Component1 /></Suspense><Suspense fallback={<p>Loading Component2</p>}><Component2 /></Suspense><Suspense fallback={<p>Loading Component3</p>}><Component3 /></Suspense></section>)
}

效果如下:
在这里插入图片描述
这种方式我们可以看下请求头:
在这里插入图片描述
Transfer-Encoding 的值为 chunked,表示允许 HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分

倘若我们这三个组件都不使用Suspense封装,效果如下:
在这里插入图片描述
整体的效果一目了然。不使用Suspense封装的情况下,需要等待所有组件都渲染完毕才能完整的展示页面。

Suspense 背后的实现技术就叫做Streaming。即将页面的HTML 拆分多个chunks,逐步从服务端发送给客户端。有这么几个好处:

  • 提前发送到客户端的组件,就可以提前进行水合,那么用户就可以和提前水合完毕的组件进行交互。
  • 从页面性能角度来考虑就是:减少 TTFBFCP 以及 TTI的时长。有兴趣的可以看下我这篇文章 性能优化 - 前端性能监控和性能指标计算方式

传统的SSR
在这里插入图片描述
使用Streaming之后:
在这里插入图片描述

那么在NextJs中有两种实现Streaming的方式:

  • 针对组件级别:使用Suspense组件(就上面的案例)。
  • 针对页面级别:使用loading.tsx

例如这样的目录结构:
在这里插入图片描述
组件1:

const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));export default async function Component1() {await sleep(2000)return <h1>Hello Component1</h1>
}

组件2:

const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));export default async function Component2() {await sleep(3000)return <h1>Hello Component2</h1>
}

page.tsx

import Link from 'next/link'
export default function MySuspense({ children }) {return (<section><nav className="flex items-center justify-center gap-10 text-blue-600 mb-6"><Link href="/suspense/component1">component1</Link><Link href="/suspense/component2">component2</Link></nav>{children}</section>)
}

loading.tsx

export default async function loading() {return <h1>loading....</h1>
}

效果如下:
在这里插入图片描述

2.3 React Server Components 和 SSR

RSCReact Server Components)和 SSR 的区别

  • RSC:重点在Components,即组件。提供了更细粒度的组件渲染方式,可**以在组件中直接获取数据。组件依赖的代码并不会打包到bundle中。并且只有在客户端请求相关组件的时候才会返回。 **
  • SSR:重点在Rendering,即渲染。在服务端将组件渲染成HTML发送给客户端,因此SSR需要将组件的所有依赖都打包到bundle中。

Suspense以及Streaming的实现确实能优化我们的页面渲染,将原本只能先获取数据、再渲染水合的传统 SSR 改为渐进式渲染水合

但是对于用户需要下载的JS代码量依旧是没有减少。因此使用RSC,服务端组件,就能将不必要的代码隐藏到服务器当中。

2.4 服务端组件 VS 客户端组件

NextJs 中,组件默认就是服务端组件。这类组件,请求会在服务端执行,最后会将组件渲染成HTML返回给客户端,例如以下就是一个服务端组件的例子:

const Address = async () => {const res = await fetch('https://jsonplaceholder.typicode.com/posts')const data = (await res.json()).slice(0, 10)console.log(data)return <ul>{data.map(({ title, id }: any) => {return <li key={id}>{title}</li>})}</ul>
}
export default Address

相关的console打印会在服务端执行:
在这里插入图片描述
数据的渲染也会直接在HTML当中。
在这里插入图片描述
那么再来看下对应的客户端组件版本:

  • 使用 'use client' 声明。
  • 配合 useEffect 钩子函数
'use client'
import { useEffect, useState } from 'react';const Address = () => {const [list, setList] = useState([]);const fetchData = async () => {const res = await fetch('https://jsonplaceholder.typicode.com/todos')const data = (await res.json())setList(data)}useEffect(() => {fetchData()}, [])return <ul>{list.map(({ title, id }: any) => {return <li key={id}>{title}</li>})}</ul>
}export default Address

两者对比的优势如下:

服务端组件客户端组件
优势数据获取更快。 ② 安全(服务端逻辑不会暴露给前端)缓存(服务端渲染的结果可缓存) ④ 服务端组件的代码不会打包到bundleFCP时长更短 ⑥ 可以使用Streaming,将渲染工作拆分为chunks通过流式传输到客户端,用户可以更早的看到部分页面,而无需等待整个页面渲染完毕① 交互性更好,可以使用useEffect、useState等钩子函数。 ② 可以使用浏览器的API
劣势不可使用useEffect、useState等钩子函数,也就无法管理状态网络很差的情况下,由客户端完成渲染会导致FCP特别长
运行时机服务端组件运行在构建时和服务端运行在构建时、服务端(生成初始HTML)和客户端(管理DOM

除此之外,还有几个非常重要的点:

  1. 服务端组件可以直接导入客户端组件,但客户端组件并不能导入服务端组件。
  2. 服务端组件当导入到客户端组件中,就会被认为是客户端组件。

相关文章:

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件

NextJs 渲染篇 - 什么是CSR、SSR、SSG、ISR 和服务端/客户端组件 前言一. 什么是CSR、SSR、SSG、ISR1.1 CSR 客户端渲染1.2 SSR 服务端渲染1.3 SSG 静态站点生成① 没有数据请求的页面② 页面内容需要请求数据③ 页面路径需要获取数据 1.4 ISR 增量静态再生1.5 四种渲染方式的对…...

Python 二叉数的实例化及遍历

首先创建一个这样的二叉树&#xff0c;作为我们今天的实例。实例代码在下方。 #创建1个树类型 class TreeNode:def __init__(self,val,leftNone,rightNone):self.valvalself.leftleftself.rightright #实例化类 node1TreeNode(5) node2TreeNode(6) node3TreeNode(7) node4Tre…...

计算 x 的二进制表示中 1 的个数

计算 x 的二进制表示中 1 的个数 代码如下&#xff1a; int func(int x){int countx 0;while (x>0){countx;x x & (x - 1);}return countx;} 完整代码&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat…...

基于Vue的前端瀑布流布局组件的设计与实现

摘要 随着前端技术的不断演进&#xff0c;复杂业务场景和多次迭代后的产品对组件化开发提出了更高的要求。传统的整块应用开发方式已无法满足快速迭代和高效维护的需求。因此&#xff0c;本文将介绍一款基于Vue的瀑布流布局组件&#xff0c;旨在通过组件化开发提升开发效率和降…...

WinSW使用说明

WinSW使用说明 Windows系统下部署多个java程序 场景&#xff1a; 多个java的jar程序&#xff0c;通常来说一个程序使用一个cmd窗口&#xff0c;通过java -jar xxx.jar 命令来运行。这样如果程序多了打开cmd窗口也就多了。 解决&#xff1a; 通过使用WinSW程序&#xff0c;把ja…...

SpringBoot 多模块 多环境 项目 单元测试

环境描述 假设项目中有以下三个yml文件&#xff1a; application.ymlapplication-dev.ymlapplication-prod.yml 假设项目各Module之间依赖关系如下&#xff1a; 其中&#xff0c;D依赖C&#xff0c;C依赖B&#xff0c;B依赖A&#xff0c;D对外提供最终的访问接口 现在要想采…...

网络安全法中的网络安全规定和措施

《中华人民共和国网络安全法》是中国首部全面规范网络空间安全管理的基础性法律&#xff0c;旨在加强网络安全&#xff0c;保障国家安全和社会公共利益&#xff0c;保护公民、法人和其他组织的合法权益&#xff0c;促进互联网的健康发展。以下是该法律中关于网络安全的一些核心…...

一、搭建 Vue3 Admin 项目:从无到有的精彩历程

在前端开发的领域中&#xff0c;Vue3 展现出了强大的魅力&#xff0c;而搭建一个功能丰富的 Vue3 Admin 项目更是充满挑战与乐趣。今天&#xff0c;我将和大家分享我搭建 Vue3 Admin 项目的详细过程&#xff0c;其中用到了一系列重要的依赖包。 首先 让我们开启这个旅程。在确…...

Qt | Qt 资源简介(rcc、qmake)

1、资源系统是一种独立于平台的机制,用于在应用程序的可执行文件中存储二进制文件(前面所讨论的数据都存储在外部设备中)。若应用程序始终需要一组特定的文件(比如图标),则非常有用。 2、资源系统基于 qmake,rcc(Qt 的资源编译器,用于把资源转换为 C++代码)和 QFile …...

对boot项目拆分成cloud项目的笔记

引言&#xff1a;这里我用的是新版本的技术栈 spring-boot-starter-parent >3.2.5 mybatis-spring-boot-starter >3.0.3 mybatis-plus-boot-starter >3.5.5 spring-cloud-dependencies …...

CTF本地靶场搭建——基于阿里云ACR实现动态flag题型的创建

接上文&#xff0c;这篇主要是结合阿里云ACR来实现动态flag题型的创建。 这里顺便也介绍一下阿里云的ACR服务。 阿里云容器镜像服务&#xff08;简称 ACR&#xff09;是面向容器镜像、Helm Chart 等符合 OCI 标准的云原生制品安全托管及高效分发平台。 ACR 支持全球同步加速、…...

【面试经典150题】删除有序数组中的重复项

目录 一.删除有序数组中的重复项 一.删除有序数组中的重复项 题目如上图所示&#xff0c;这里非严格递增排序的定义是数字序列&#xff0c;其中相邻的数字可以相等&#xff0c;并且数字之间的差值为1。 这题我们依旧使用迭代器进行遍历&#xff0c;比较当前的数据是否与下一个数…...

太阳能辐射整车综合性能环境试验舱

产品别名 步入式恒温恒湿试验箱、步入式温湿度试验箱、温度试验室、模拟环境试验室、大型恒温恒湿箱、步入式高低温湿热交变试验箱、大型高低温箱、步入式老化箱、恒温恒湿试验房、步入式高低温试验箱. 整车综合性能环境试验舱:整车综合性能环境试验舱:主要用于整车高低温存放…...

JS脚本打包成一个 Chrome 扩展(CRX 插件)

受这篇博客 如何把CSDN的文章导出为PDF_csdn文章怎么导出-CSDN博客 启发&#xff0c;将 JavaScript 代码打包成一个 Chrome 扩展&#xff08;CRX 插件&#xff09;。 步骤&#xff1a; 1.创建必要的文件结构和文件&#xff1a; manifest.jsonbackground.jscontent.js 2.编写…...

js事件对象

js事件对象概念说明 在JavaScript中&#xff0c;事件对象是在事件触发时由浏览器自动创建的一个对象。它包含了与事件相关的信息&#xff0c;例如触发事件的元素、事件类型、鼠标的坐标等。 可以通过事件处理函数的第一个参数来访问事件对象。例如&#xff0c;在一个鼠标点击…...

希捷硬盘怎么恢复数据? 5 个免费希捷数据恢复软件

希捷已迅速成为全球最大的数字存储提供商。许多人选择并使用希捷外置硬盘来存储他们的媒体文件、学校或工作文件以及其他重要数据。有时&#xff0c;希捷硬盘中的数据会丢失。 如果您丢失了希捷硬盘上的数据&#xff0c;请不要惊慌。在专业的希捷数据恢复软件的帮助下&#xf…...

Nvidia Jetson/Orin +FPGA+AI大算力边缘计算盒子:京东无人配送机器人

电商巨头京东已选用NVIDIA Jetson AGX Xavier 平台&#xff0c;作为下一代自主配送机器人核心AI算力。 在过去的几十年中&#xff0c;中国占据了全球40&#xff05;以上的电商交易——每年约为千亿美元。根据麦肯锡全球研究院的数据&#xff0c;这一数字已经高于法国、德国、…...

STM32作业实现(七)OLED显示数据

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…...

elementui el-tooltip文字提示组件弹出层内容格式换行处理

1、第一种 1.1 效果图 1.2、代码 <template><div class"wrapper"><el-tooltip class"content" effect"dark" placement"top"><div slot"content"><div v-html"getTextBrStr(text)"&…...

Python3 笔记:每天一个函数——str.join()

join() &#xff1a;连接字符串数组。将字符串、元组、列表中的元素以指定的字符&#xff08;分隔符&#xff09;连接生成一个新的字符串。 语法&#xff1a;sep.join(seq) 参数说明&#xff1a; sep&#xff1a;分隔符。可以为空。 seq&#xff1a;要连接的元素序列、字符串…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…...

SQL注入篇-sqlmap的配置和使用

在之前的皮卡丘靶场第五期SQL注入的内容中我们谈到了sqlmap&#xff0c;但是由于很多朋友看不了解命令行格式&#xff0c;所以是纯手动获取数据库信息的 接下来我们就用sqlmap来进行皮卡丘靶场的sql注入学习&#xff0c;链接&#xff1a;https://wwhc.lanzoue.com/ifJY32ybh6vc…...

深度解析云存储:概念、架构与应用实践

在数据爆炸式增长的时代&#xff0c;传统本地存储因容量限制、管理复杂等问题&#xff0c;已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性&#xff0c;成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理&#xff0c;云存储正重塑数据存储与…...

P10909 [蓝桥杯 2024 国 B] 立定跳远

# P10909 [蓝桥杯 2024 国 B] 立定跳远 ## 题目描述 在运动会上&#xff0c;小明从数轴的原点开始向正方向立定跳远。项目设置了 $n$ 个检查点 $a_1, a_2, \cdots , a_n$ 且 $a_i \ge a_{i−1} > 0$。小明必须先后跳跃到每个检查点上且只能跳跃到检查点上。同时&#xff0…...

DriveGPT4: Interpretable End-to-end Autonomous Driving via Large Language Model

一、研究背景与创新点 (一)现有方法的局限性 当前智驾系统面临两大核心挑战:一是长尾问题,即系统在遇到新场景时可能失效,例如突发交通状况或非常规道路环境;二是可解释性问题,传统方法无法解释智驾系统的决策过程,用户难以理解车辆行为的依据。传统语言模型(如 BERT…...