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

Next.js 新手容易犯的错误 _ 加载与缓存管理的关键(5)

1 错误地处理搜索参数(Search Params)

问题是什么?

在 Next.js 中,搜索参数指的是 URL 中用 ?key=value 表示的部分,比如 https://example.com/products?color=red 中的 color=red。这通常用于过滤、排序或选择某些选项,比如商品颜色、价格范围等。

很多人在使用搜索参数时,会误解如何正确地读取和处理它们,导致页面体验不流畅。具体问题有两个:

  1. 用服务器端方式处理searchParams):参数变化时,页面会触发服务器请求。这种方式需要等待服务器响应,尤其在网络较慢时,用户会感到页面卡顿。
  2. 用客户端方式错误处理:虽然 useSearchParams 可以即时更新,但它需要将组件设置为客户端组件,很多人会忘记这一点,导致错误。

如何正确处理?

搜索参数的处理分为两种情况:

  1. 需要服务器端渲染:如果搜索参数用于改变服务器端的内容,比如动态生成某些数据或页面,使用 searchParams 是合适的。
  2. 需要即时更新内容(无需服务器端渲染):如果只是简单地修改页面显示(如更改颜色),可以用 useSearchParams 在客户端更新,避免不必要的服务器请求。

举例:商品颜色切换
场景:

你有一个商品页面 /products,用户可以通过 URL 切换商品颜色,比如 ?color=red,希望页面能动态显示对应颜色,而不需要每次刷新页面。

错误示例:使用 searchParams(服务器端方式)
// page.tsx
export default function ProductPage({ searchParams }: { searchParams: { color: string } }) {const color = searchParams.color || 'default'; // 从 URL 中获取颜色return <div>当前颜色是:{color}</div>;
}

当用户切换颜色时,页面会发送网络请求到服务器,获取新的搜索参数:

<button onClick={() => router.push('/products?color=blue')}>蓝色</button>

问题

  • 每次点击按钮,都会触发服务器请求。
  • 服务器响应较慢时,用户会感到页面卡顿。
正确示例:使用 useSearchParams(客户端方式)
'use client';import { useSearchParams } from 'next/navigation';export default function ProductPage() {const searchParams = useSearchParams(); // 使用 Hook 读取参数const color = searchParams.get('color') || 'default'; // 获取颜色参数return (<div><h1>当前颜色是:{color}</h1><button onClick={() => window.history.pushState({}, '', '/products?color=red')}>红色</button><button onClick={() => window.history.pushState({}, '', '/products?color=blue')}>蓝色</button><button onClick={() => window.history.pushState({}, '', '/products?color=green')}>绿色</button></div>);
}
示例解读:
  1. useSearchParams 是一个客户端 Hook,可以直接从 URL 中读取参数,而不需要触发服务器请求。
  2. 当点击按钮时,页面通过 window.history.pushState 修改 URL,这不会触发服务器请求。
  3. 页面根据 color 参数的变化,立即显示新的颜色。
用户体验:
  • 参数变化时,页面不会刷新。
  • 用户立即看到新的内容,体验更流畅。

总结
  • 服务器端方式(searchParams:适用于需要动态加载数据的场景,但会有延迟。
  • 客户端方式(useSearchParams:适用于即时更新的场景,比如更改颜色、排序等简单操作。

一个更直观的小比喻

假设你有一个餐馆的菜单,顾客想看某个菜品(比如红色菜品)。用两种方式理解:

  1. 服务器端方式
    • 顾客(浏览器)每次想换一个菜品时,都要向后厨(服务器)发送请求,后厨再重新做一份完整的菜单交给顾客。
    • 优点:菜单是最新鲜的。
    • 缺点:每次都要等待后厨出菜,速度慢。
  2. 客户端方式
    • 顾客拿着一张菜单,只需要翻一下(修改 URL 中的参数),马上就能看到新的菜品。
    • 优点:速度快,反应即时。
    • 缺点:菜单内容是固定的,后厨不会帮你更新。

选择哪种方式,要看你的需求。如果你只是在已有菜单中切换,直接翻菜单(客户端方式)就够了;如果需要最新数据,那就得联系后厨(服务器端方式)。

2 忽视加载状态(Loading States)

问题是什么?

在开发页面时,特别是数据需要从服务器获取的情况下,页面加载速度可能因网络状况、数据复杂性等原因变慢。如果没有专门处理 加载状态,用户可能在等待页面加载时只看到空白屏幕,误以为页面出问题,导致非常糟糕的用户体验。

在本地开发时,加载速度通常非常快,因为一切都运行在本地服务器上。开发者容易忽视这个问题,以为页面永远加载很快。但在生产环境中,服务器请求和响应有延迟,加载时间可能变得显著。


为什么加载状态很重要?
  1. 告诉用户正在加载:让用户知道页面正在努力加载,而不是卡死或出错。
  2. 避免用户误解:如果页面是空白的,用户可能会认为系统出错了,甚至会直接关闭页面。
  3. 提升用户体验:通过友好的加载提示(如旋转的加载动画、文字“加载中”),可以让等待变得更耐心。

如何正确处理加载状态?

Next.js 提供了一个简单的解决方案:loading.tsx 文件。

  1. loading.tsx 是一个特殊的文件,专门用来显示页面加载中的状态。
  2. 当页面的数据还没有加载完成时,Next.js 会自动渲染 loading.tsx 中的内容。
  3. 数据加载完成后,loading.tsx 的内容会被页面真实内容替换。

举例:一个商品页面
场景:

你有一个商品页面 /products,用户打开这个页面时,需要从服务器获取商品数据。假设数据加载需要 3 秒,如果不设置加载状态,用户在这 3 秒内只能看到空白页面。

错误示例:没有加载状态
// app/products/page.tsx
export default async function ProductPage() {const data = await fetch("https://api.example.com/products").then((res) => res.json());return (<div><h1>商品列表</h1><ul>{data.map((product: any) => (<li key={product.id}>{product.name}</li>))}</ul></div>);
}

问题

  • 当用户打开页面时,数据加载期间(比如 3 秒),页面什么都不显示,用户可能认为页面卡住或出错。
  • 如果网络慢,体验会非常糟糕。
正确示例:添加加载状态
  1. 创建 loading.tsx 文件,放在与 page.tsx 同一级别的目录下。
  2. loading.tsx 中定义加载状态。

文件结构

/app/productspage.tsx       // 主页面loading.tsx    // 加载状态

loading.tsx 文件内容:

export default function Loading() {return (<div style={{ textAlign: "center", marginTop: "50px" }}><p>加载中,请稍等...</p></div>);
}

page.tsx文件内容:

export default async function ProductPage() {// 模拟延迟 3 秒加载数据const data = await new Promise((resolve) =>setTimeout(() => resolve([{ id: 1, name: "商品 A" }, { id: 2, name: "商品 B" }]), 3000));return (<div><h1>商品列表</h1><ul>{data.map((product: any) => (<li key={product.id}>{product.name}</li>))}</ul></div>);
}
示例解读:
  1. 当用户访问 /products 时:
    • 数据需要 3 秒加载完成。
    • 在这 3 秒内,Next.js 会自动显示 loading.tsx 中的内容(加载中,请稍等...)。
  2. 数据加载完成后:
    • loading.tsx 的内容会被替换成 page.tsx 中的数据(即商品列表)。

用户体验对比
  1. 没有加载状态时
    • 页面打开时显示空白,用户会感到困惑甚至关闭页面。
  2. 有加载状态时
    • 用户打开页面时,会看到“加载中,请稍等…”的提示。
    • 数据加载完成后,提示自动消失,商品列表正常显示。
    • 用户会知道页面正在加载,体验更加友好。

现实生活中的类比

想象你去餐厅点餐:

  1. 没有加载状态的情况
    • 服务员直接离开,你只能盯着空桌子,完全不知道餐点是否正在准备,甚至怀疑订单没被记录。
  2. 有加载状态的情况
    • 服务员告诉你“请稍等,餐点正在准备,大概需要 3 分钟”,你会更有耐心等待,因为你知道有人在处理。

加载状态就像服务员的“正在准备中”提醒,它给了用户反馈,避免误解,提高了体验。

3 加载边界不够精细(Granular Suspense Boundaries)

问题是什么?

在 Next.js 中,当页面加载时,有时只有部分内容需要等待数据加载(例如某个商品详情),而页面的其他部分(如标题、导航栏等)已经可以立即显示。如果我们直接为整个页面设置加载状态,就会 阻塞整个页面,导致用户在等待数据加载时看不到其他内容。这会让用户体验变差。

核心问题:没有为需要等待的数据设置更细粒度的加载边界,导致页面中的非相关部分也一起被延迟显示。


为什么要精细化加载边界?

通过对加载状态进行精细化处理:

  1. 提升用户体验:在加载某些内容时,页面的其他部分可以正常显示。
  2. 减少用户等待时间:让用户先看到页面的框架内容(如标题、按钮等),即使部分数据还在加载中。
  3. 灵活控制加载逻辑:只对真正需要等待的数据设置加载状态,不阻塞整个页面。

举例:一个商品详情页面
场景:

一个商品详情页面 /products/[id],用户打开时:

  • 标题(如“商品详情”)、导航栏等页面框架内容可以立即显示。
  • 商品详情需要从服务器加载(可能需要几秒钟),此部分应有单独的加载状态,而不影响页面框架的显示。

错误示例:为整个页面设置加载状态
// app/products/[id]/loading.tsx
export default function Loading() {return <div>加载中,请稍等...</div>;
}// app/products/[id]/page.tsx
export default async function ProductPage({ params }: { params: { id: string } }) {const product = await fetch(`https://api.example.com/products/${params.id}`).then((res) => res.json());return (<div><h1>商品详情</h1><div>名称:{product.name}</div><div>价格:{product.price}</div></div>);
}

问题

  • 当用户打开页面时,整个页面都会显示“加载中,请稍等…”,包括标题和其他不依赖数据的部分。
  • 用户无法看到标题和页面结构,体验很差。

正确示例:为部分内容设置加载状态

文件结构

/app/products/[id]page.tsx       // 主页面ProductDetail.tsx // 商品详情组件

ProductDetail.tsx文件:

import { Suspense } from "react";async function ProductDetail({ id }: { id: string }) {// 模拟延迟加载商品数据const product = await new Promise((resolve) =>setTimeout(() => resolve({ name: "商品 A", price: "$100" }), 3000));return (<div><h2>名称:{product.name}</h2><p>价格:{product.price}</p></div>);
}export default function ProductDetailWrapper({ id }: { id: string }) {return (<Suspense fallback={<div>加载商品详情中...</div>}><ProductDetail id={id} /></Suspense>);
}

page.tsx 文件:

import ProductDetailWrapper from "./ProductDetailWrapper";export default function ProductPage({ params }: { params: { id: string } }) {return (<div><h1>商品详情</h1><ProductDetailWrapper id={params.id} /></div>);
}

示例解读
  1. 页面框架立即显示
    • 页面加载时,<h1>商品详情</h1> 会立即显示,用户知道自己进入了正确的页面。
    • 即使商品详情数据还在加载中,页面的整体结构也不会空白。
  2. 单独加载商品详情
    • 商品详情部分被 <Suspense> 包裹。
    • 在数据加载完成前,会显示 fallback 提供的加载状态(如“加载商品详情中…”)。
  3. 提升用户体验
    • 用户在加载时,不会看到一个完全空白的页面。
    • 页面上的静态内容(如标题)先显示,动态内容加载完成后再更新。

用户体验对比
  1. 错误的全页面加载状态
    • 用户点击页面时,只看到“加载中,请稍等…”。
    • 即使加载的内容只是商品详情,整个页面都会被阻塞,用户感到困惑。
  2. 正确的精细化加载边界
    • 用户点击页面时,标题立即显示。
    • 页面框架内容立刻可见,商品详情部分则显示“加载商品详情中…”。
    • 加载完成后,商品详情替换加载状态,用户体验更加自然流畅。

现实生活中的类比

想象你去一场音乐会:

  • 错误做法:音乐会开始前,主办方让观众在外面等,说“所有内容准备好后才能入场”。观众什么都看不到,只能焦急等待。
  • 正确做法:主办方先让观众入场,提供饮料、音乐会介绍等背景内容,而主角乐队在后台准备。观众即使等乐队上台,也不会感到无聊。

  1. 精细化加载边界很重要:只为需要加载的数据部分设置加载状态,不阻塞页面的其他部分。
  2. 提升用户体验:让用户先看到页面的框架内容,同时提供清晰的加载提示。
  3. 实现方式:使用 Suspense 包裹需要加载的组件,提供 fallback 提示内容,让页面结构尽早显示。

4 将 Suspense 放在错误位置

什么是 Suspense?

Suspense 是 React 提供的一个组件,用来处理 异步数据加载延迟渲染 的问题。它允许开发者为等待数据的部分内容设置 占位符(fallback),在数据加载完成前显示一个加载状态(如“加载中…”),并在加载完成后显示实际内容。

Suspense 的作用
  • 提升用户体验:用户在等待数据加载时不会看到空白页面,而是看到清晰的加载状态。
  • 优化页面渲染:只延迟需要等待的数据部分,不阻塞其他不需要等待的内容。

错误的核心问题

Suspense 必须放在等待数据加载的逻辑 上层,否则它无法正确捕获数据加载状态。如果将 Suspense 放在错误的位置,比如数据加载逻辑的下层或内部,页面可能会出现以下问题:

  1. 加载状态无法显示:页面会一直空白,直到数据加载完成。
  2. 整个页面被阻塞:即使其他部分不需要等待数据加载,也会因为 Suspense 放置错误而延迟显示。

正确用法:Suspense 的关键点

  1. Suspense 必须包裹需要等待加载的数据组件
  2. Suspense 的 fallback 属性定义加载状态(如“加载中…”)的显示内容
  3. Suspense 应该位于数据加载逻辑的上层,而不是下层或内部。

举例:商品详情页面

错误示例:将 Suspense 放在错误位置

场景:一个商品详情页面,加载商品数据时需要 3 秒。页面需要显示标题和加载状态,但因为 Suspense 放错位置,导致加载状态无法正确显示。

async function ProductDetail({ id }: { id: string }) {// 模拟延迟加载商品数据const product = await new Promise((resolve) =>setTimeout(() => resolve({ name: "商品 A", price: "$100" }), 3000));return (<div><h2>名称:{product.name}</h2><p>价格:{product.price}</p></div>);
}export default function ProductPage({ params }: { params: { id: string } }) {return (<div><h1>商品详情</h1>{/* 错误:将 Suspense 放在数据加载逻辑的下层 */}<ProductDetail id={params.id} /></div>);
}

问题分析

  1. 没有加载状态:即使商品数据加载需要 3 秒,页面在这段时间内也不会显示“加载中…”。
  2. 用户体验差:用户只会看到空白屏幕,无法知道页面是否正常加载。

正确示例:将 Suspense 放在数据加载逻辑的上层
import { Suspense } from "react";async function ProductDetail({ id }: { id: string }) {// 模拟延迟加载商品数据const product = await new Promise((resolve) =>setTimeout(() => resolve({ name: "商品 A", price: "$100" }), 3000));return (<div><h2>名称:{product.name}</h2><p>价格:{product.price}</p></div>);
}export default function ProductPage({ params }: { params: { id: string } }) {return (<div><h1>商品详情</h1>{/* 正确:将 Suspense 放在需要等待加载的数据组件上层 */}<Suspense fallback={<div>加载商品详情中...</div>}><ProductDetail id={params.id} /></Suspense></div>);
}

示例解读

1. 正确的 Suspense 放置位置

  • Suspense 包裹了 ProductDetail 组件,这个组件包含了需要加载的数据逻辑。
  • 当数据还没加载完成时,Suspense 会显示 fallback 中的内容(即“加载商品详情中…”)。

2. 用户体验

  • 页面打开时,标题“商品详情”会立即显示。
  • 商品数据加载时,用户看到加载提示“加载商品详情中…”。
  • 数据加载完成后,加载提示会被实际的商品详情替代。

更直观的现实类比

想象你在餐厅点餐:

  • 错误示例:餐厅让你等所有菜都准备好后再通知你入座。你不知道餐厅正在准备菜品,也看不到桌子是否已经布置好,你会感到困惑。
  • 正确示例:餐厅先让你入座(页面的标题部分先显示),然后告诉你“菜品正在准备中”(加载状态)。当菜品准备好时(数据加载完成),服务员上菜。

  1. Suspense 的作用:为异步加载的内容设置加载状态,提高用户体验。
  2. 正确放置位置:必须包裹需要等待加载的组件,并放在数据加载逻辑的上层。
  3. 关键点:避免阻塞页面的其他部分,让非依赖数据的内容尽快显示。

5 忽视缓存的作用

问题是什么?

在 Next.js 中,当页面或组件需要从服务器获取数据时,系统会自动进行 缓存。如果不了解缓存的机制,可能会导致以下问题:

  1. 重复请求:每次访问页面都重新请求相同的数据,浪费资源,增加延迟。
  2. 未正确使用缓存:没有设置合适的缓存策略,导致数据无法及时更新或长时间不变。

为什么缓存很重要?

缓存的作用是减少不必要的网络请求和服务器负载,从而提升性能和用户体验:

  1. 减少延迟:缓存的内容可以直接使用,避免每次都重新请求数据。
  2. 降低服务器压力:服务器只需要处理未缓存的请求,负载更低。
  3. 优化用户体验:用户访问页面时,加载速度更快,感知更流畅。

Next.js 的缓存机制

Next.js 提供多种缓存策略:

  1. 静态生成(Static Generation)
    • 页面在构建时生成,内容是静态的。
    • 适合不会频繁变化的数据,比如博客文章。
  2. 增量静态生成(Incremental Static Regeneration, ISR)
    • 页面在构建时生成,但可以设置重新验证的时间,确保数据定期更新。
    • 适合需要定期更新但不需要实时更新的数据,比如商品库存。
  3. 服务器端渲染(Server-Side Rendering, SSR)
    • 页面每次请求都会从服务器获取数据,实时更新。
    • 适合需要实时更新的数据,比如用户个性化信息。

举例:商品列表页面

假设我们有一个商品列表页面,需要从服务器获取数据。

错误示例:忽视缓存,导致重复请求
export default async function ProductPage() {// 每次请求都重新获取数据const data = await fetch("https://api.example.com/products").then((res) => res.json());return (<div><h1>商品列表</h1><ul>{data.map((product: any) => (<li key={product.id}>{product.name}</li>))}</ul></div>);
}
问题分析
  1. 每次访问页面都发送请求:即使商品数据没有变化,还是会重复请求相同的数据。
  2. 浪费资源:增加服务器负担,导致页面加载变慢。
  3. 用户体验差:每次都要等待网络请求完成才能显示页面。

正确示例:使用增量静态生成(ISR)
export async function getStaticProps() {// 获取商品数据const data = await fetch("https://api.example.com/products").then((res) => res.json());return {props: { products: data },revalidate: 60, // 每隔 60 秒重新验证数据};
}export default function ProductPage({ products }: { products: any[] }) {return (<div><h1>商品列表</h1><ul>{products.map((product) => (<li key={product.id}>{product.name}</li>))}</ul></div>);
}

示例解读
  1. 缓存机制的使用
    • 页面通过 getStaticProps 在构建时生成,数据被缓存。
    • 设置了 revalidate: 60,表示数据每 60 秒会重新验证一次,确保内容较为新鲜。
  2. 加载过程
    • 第一次访问:Next.js 会从服务器获取数据并缓存起来。
    • 第二次及以后访问(60 秒内):直接使用缓存的数据,无需重新请求。
    • 超过 60 秒:Next.js 会重新验证数据。如果数据更新,则生成新的页面并更新缓存。
  3. 性能优化
    • 减少了重复请求,提升了页面加载速度。
    • 数据可以定期更新,兼顾了性能和实时性。

现实生活中的类比

想象你去超市买东西:

  • 错误示例:每次去超市买相同的商品时,超市都要重新整理货架、检查库存。这样浪费时间和资源,你也得等很久。
  • 正确示例:超市提前整理好货架,并定期检查库存。如果你来得比较快,直接拿现成的商品,不需要等整理完成。

缓存就像超市提前准备好的货架,既省时又省力,而重新验证数据就像定期检查库存,确保商品的新鲜度


  1. 正确使用缓存机制可以优化页面性能
    • 静态生成(Static Generation):适合静态内容。
    • 增量静态生成(ISR):适合定期更新的数据。
    • 服务器端渲染(SSR):适合实时更新的数据。
  2. 避免重复请求:通过缓存,减少服务器负担和加载时间。
  3. 用户体验提升:页面加载更快,内容更新及时。

关键点:根据实际需求选择合适的缓存策略,平衡性能和实时性。

相关文章:

Next.js 新手容易犯的错误 _ 加载与缓存管理的关键(5)

1 错误地处理搜索参数&#xff08;Search Params&#xff09; 问题是什么&#xff1f; 在 Next.js 中&#xff0c;搜索参数指的是 URL 中用 ?keyvalue 表示的部分&#xff0c;比如 https://example.com/products?colorred 中的 colorred。这通常用于过滤、排序或选择某些选…...

/etc/fstab 文件学习systemd与该文件关系

文章目录 一、文件字段1.1、设备标识1.2、挂载点1.3、文件系统类型1.4、挂载选项1.5、dump1.5、fsck顺序 二、/etc/fstab 与systemd 的关系2.1、/etc/fstab 与systemd 的关系2.2、systemd 之前/etc/fstab生效过程2.3、systemd 时代/etc/fstab生效过程 三、相关知识3.1、如何更具…...

从源码分析swift GCD_DispatchGroup

前言&#xff1a; 最近在写需求的时候用到了DispatchGroup&#xff0c;一直没有深入去学习&#xff0c;既然遇到了那么就总结下吧。。。。 基本介绍&#xff1a; 任务组&#xff08;DispatchGroup&#xff09; DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…...

25计软新增考研院校!或可捡漏上岸!

C哥专业提供——计软考研院校选择分析专业课备考指南规划 新增的计算机与软件工程考研院校为考研同学带来了多方面的机遇&#xff0c;这些机遇不仅体现在过国家线后可能面临的更低竞争压力&#xff0c;还包括更多元化的教育选择和更广阔的就业前景&#xff1a; 一、降低竞争压…...

C# 线程安全集合

文章目录 引言一、ConcurrentBag<T>二、ConcurrentQueue<T>三、ConcurrentStack<T>四、ConcurrentDictionary<TKey, TValue>五、总结引言 在多线程编程环境中,多个线程可能同时访问和操作集合数据。如果使用普通集合,很容易引发数据不一致、错误结果…...

箱包发霉怎么处理 箱包发霉处理修复方法

箱包发霉怎么处理&#xff1f;箱包不仅是我们出行的必需品&#xff0c;更是承载着个人风格与品味的时尚配饰。然而箱包工厂生产的箱包&#xff0c;在潮湿多变的环境中&#xff0c;箱包很容易成为霉菌滋生的温床&#xff0c;尤其是那些长时间储存的箱包&#xff0c;更是霉菌的“…...

【每日学点鸿蒙知识】Charles抓包、lock文件处理、WebView组件、NFC相关、CallMethod失败等

1、HarmonyOS系统中如何使用Charles抓包&#xff1f; 在HarmonyOS操作系统中&#xff0c;使用Charles进行抓包的步骤如下&#xff1a; 在Charles中设置代理。 首先&#xff0c;在Charles的菜单栏上选择“Proxy”→“Proxy Settings”&#xff0c;然后填入代理端口&#xff0…...

【异常】GL-SFT1200路由器中继模式,TL-CPE1300D无法搜寻5G网问题分析

【异常】GL-SFT1200路由器中继模式,TL-CPE1300D无法搜寻5G网问题 情况实验结论情况 在用GL-SFT1200路由器切换中继模式时,由于web密码忘却,需要重置,但根据官网使用手册,或者对应的中文版手册,重置失败。通过跟商家联系,进行uboot刷机,提供了指导文档,尝试后刷机成功…...

LINUX--shell

函数 格式&#xff1a; func() { command } function 关键字可写&#xff0c;也可不写。 示例 1&#xff1a; #!/bin/bash func() { #定义函数 echo "Hello $1" } func world #执行主文件 # bash test.sh Hello world 数组 数组是相…...

TCP常见问题

文章目录 一、两种状态图二、常见问题1、MSL是什么 3、为何等待2MSL3、为何三次握手&#xff0c;不握手、握手一次、两次行吗4、为何四次挥手&#xff0c;三次行吗&#xff0c;两次行吗 一、两种状态图 四次挥手 二、常见问题 1、MSL是什么 MSL是Maximum Segment Lifetime的英…...

OpenCV学习——图像融合

import cv2 as cv import cv2 as cvbg cv.imread("test_images/background.jpg", cv.IMREAD_COLOR) fg cv.imread("test_images/forground.png", cv.IMREAD_COLOR)# 打印图片尺寸 print(bg.shape) print(fg.shape)resize_size (1200, 800)bg cv.resize…...

网速、续航双在线!2024随身WiFi品牌精选推荐!格行按键切三网值得买吗?

随身wifi这个东西大家用的还是蛮多的&#xff0c;特别是一些户外工作的人员&#xff0c;往往都需要配备一个随身wifi&#xff0c;这样户外工作的时候才有网络&#xff0c;工作才会比较方便一些。今天就来盘点2024年热门随身wifi哪个牌子的好用&#xff1f; 1.华为&#xff1a;通…...

ubuntu18.04连接不上网络问题

现象&#xff1a;右上角的网络图标消失&#xff0c;仅剩输入法、音量和开关图标&#xff0c;ifconfig只显示本地回环 原因&#xff1a;网络适配器未开启 解决&#xff1a; 1. 查看网络状态&#xff1a;cat /var/lib/NetworkManager/NetworkManager.state 这里显示是false&a…...

访谈积鼎科技总经理:国产CFD软件发展与未来趋势展望

傅彦国&#xff0c;上海积鼎信息科技有限公司创始人 记者&#xff1a;请傅总介绍下我国流体仿真行业的发展现状是怎样的&#xff1f; 傅彦国&#xff1a;自2018年政府加大了对核心技术自主研发的支持力度&#xff0c;国产CFD软件逐渐步入发展正轨。 首先&#xff0c;从市场规…...

【Linux知识】exec命令行详解

文章目录 概述主要用途和 bash 有什么区别&#xff1f; 概述 在 Linux 系统中&#xff0c;exec 命令用于执行一个可执行文件&#xff0c;替换当前进程的映像。也就是说&#xff0c;当你在终端中使用 exec 命令后&#xff0c;当前的 shell 会被替换为 exec 指定的程序&#xff…...

【学术小白的学习之路】基于情感词典的中文句子情感分析(代码词典获取在结尾)

【学术小白的学习之路】基于情感词典的情感分析 1.基础函数1.1 判断情感词的否定词数量1.2 导入情感词典1.3 切分句子1.3.1为什么划分1.3.2 划分代码 1.4 完整代码 2.导入词典3.中文情感分析算法思路4.1情感词获取思路4.2 计算情感分值4.3 得分的归一化处理 4.实证5.总结 本文的…...

Linux 中 grep、sed、awk 命令

1. awk&#xff1a;强大的文本分析工具 awk&#xff0c;全称“Awk语言”&#xff0c;是一种专门用于处理文本文件的语言。它不仅能够根据关键字匹配某一行&#xff0c;还能进行复杂的文本分析和处理。awk的语法简洁明了&#xff0c;功能强大&#xff0c;是文本处理领域的佼佼者…...

一起考高项啊--现代化基础设施(工业互联网)

1、工业互联网的内涵和外延 工业互联网不是互联网在工作的简单应用&#xff0c;是具有更为丰富的内涵和外延。 它既是工业数字化、网络化、智能化转型的基础设施&#xff0c;也是互联网、大数据、人工智能与实体经济深度融合的应用模式&#xff0c;同时也是一种新业态、新产业…...

python学opencv|读取图像(二十)使用cv2.circle()绘制圆形进阶

【1】引言 前序已经掌握了使用cv2.circle()绘制圆形的基本操作&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;二十&#xff09;使用cv2.circle()绘制圆形-CSDN博客 由于圆形本身绘制起来比较简单&#xff0c;因此可以自由操作的空间也就大&#x…...

期权懂|如何减小个股期权交易中的风险?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 如何减小个股期权交易中的风险&#xff1f; 一、选择合适的期权合约 &#xff08;1&#xff09;选择活跃的期权合约&#xff1a;投资者应优先选择交易活跃的期权合约。交易活跃的…...

ubuntu20.04 wget下载--段错误 (核心已转储)

用wget下载时总是在快下载完成时遇到段错误 untu2004-9.1.0_1.0-1_am 99%[> ] 1.63G 3.11MB/s 剩余 1s s段错误 (核心已转储)有以下两种解决方法&#xff1a; 1.手动下载 wget后面就是要下载的资源的链接&#xff0c;直接复制到浏览器中下载即可 如&#xff1a…...

怎么样保持mysql和redis数据一致性

保持 MySQL 和 Redis 数据的一致性是一个常见的挑战,因为 MySQL 是传统的关系型数据库,而 Redis 是内存数据库,通常用于缓存和高性能存储。这两者的数据更新方式不同,特别是当 Redis 用作缓存时,可能会存在缓存和数据库之间的数据不一致问题。为了保持数据一致性,通常可以…...

剑指Offer|LCR 013. 二维区域和检索 - 矩阵不可变

LCR 013. 二维区域和检索 - 矩阵不可变 给定一个二维矩阵 matrix&#xff0c;以下类型的多个请求&#xff1a; 计算其子矩形范围内元素的总和&#xff0c;该子矩阵的左上角为 (row1, col1) &#xff0c;右下角为 (row2, col2) 。 实现 NumMatrix 类&#xff1a; NumMatrix(…...

aosp15 - Activity生命周期切换

本文探查的是&#xff0c;从App冷启动后到MainActivity生命周期切换的系统实现。 调试步骤 在com.android.server.wm.RootWindowContainer#attachApplication 方法下断点&#xff0c;为了attach目标进程在com.android.server.wm.ActivityTaskSupervisor#realStartActivityLock…...

vxe-table 虚拟滚动的动态响应

虚拟滚动主要是在有限范围内渲染想要显示的数据&#xff0c;主要体现在懒加载数据和动态渲染上。如何提高虚拟滚动的操作性呢&#xff1f;请看本章解析 1.什么是虚拟滚动&#xff1f;代码如何实现&#xff1f; VXE-Table提供了一种名为“虚拟滚动”的功能&#xff0c;该功能可…...

quasar dev 命令卡住很久

别以为这是一个瞬间的截图&#xff0c;其实停留在这里很久很久。 折腾挺久&#xff0c;无论npm run dev:proxy还是 quasar dev&#xff0c;都是一样的情况。 最终解决办法&#xff1a; 有语法问题&#xff0c;通过 quasar build 命令暴露出来错误所在的行数。...

黑盒RCE测试 异或测试

前言 了解了漏洞的原理之后就需要知道 他在哪能出现 并且被利用 这个还是很重要的 异或测试 使用异或&#xff08;XOR&#xff09;运算进行加密解密的原理_异或加密-CSDN博客 异或测试是在 白盒内执行的 一个例题看一下 输入什么都是会报错 这种情况就需要使用 异或计…...

kotlin中泛型中in和out的区别

概念含义 in关键字&#xff08;逆变&#xff09; 在Kotlin泛型中&#xff0c;in关键字主要用于定义逆变&#xff08;Contravariance&#xff09;。它表示一个泛型类型参数可以是指定类型或者它的超类型。简单来说&#xff0c;就是对于类型A和B&#xff0c;如果A是B的子类型&…...

c# iis 解决跨域问题

该错误是一个典型的跨域问题&#xff0c;说明从 http://www.fuc.com 发起的请求被目标服务器&#xff08;https://aip.baidubce.com&#xff09;拒绝&#xff0c;原因是目标服务器未返回正确的 AccessControlAllowOrigin 响应头。 解决方法 1. 了解问题的本质 CORS&#xff08…...

MySQL版本对应的mysql-connector-java版本下载地址

MySQL版本mysql-connector-java版本mysql-connector-java下载地址MySQL安装版下载地址MySQL免安装版下载地址5.1.x5.1.xmysql-connector-java 5.1.xMySQL Installer 5.1.xMySQL Community Server 5.1.x5.5.x5.1.x, 5.5.x mysql-connector-java 5.1.x, mysql-connector-java 5.5…...