前端分页与瀑布流最佳实践笔记 - React Antd 版
前端分页与瀑布流最佳实践笔记 - React Antd 版
1. 分页与瀑布流对比
分页(Pagination) | 瀑布流(Infinite Scroll) | |
---|---|---|
展示方式 | 按页分批加载,有明确页码控件 | 滚动到底部时自动加载更多内容,无明显分页 |
用户控制 | 用户可主动翻页和跳转到任意页 | 用户只能通过滚动浏览,无法直接跳转 |
数据加载时机 | 用户点击翻页按钮时加载 | 滚动接近底部时自动加载 |
适用场景 | 数据量大且需精准定位(电商、后台管理系统) | 信息流浏览(社交媒体、图片墙) |
体验特点 | 更可控、易跳转,适合严肃场景 | 更流畅、自然,适合娱乐、轻松浏览 |
技术实现 | 通过current 和pageSize 参数请求 | 监听滚动事件,触发加载 |
核心区别:分页更适合管理和精准查找,瀑布流更适合浏览体验和沉浸式内容。
2. 分页实现 - React Antd
基本实现
import { Table, Pagination } from 'antd';
import { useState, useEffect } from 'react';
import axios from 'axios';function PaginatedTable() {const [data, setData] = useState([]);const [loading, setLoading] = useState(false);const [pagination, setPagination] = useState({current: 1,pageSize: 10,total: 0});const fetchData = async (params = {}) => {setLoading(true);try {const response = await axios.get('/api/items', {params: {page: params.current || pagination.current,pageSize: params.pageSize || pagination.pageSize}});setData(response.data.items);setPagination({...pagination,current: params.current || pagination.current,total: response.data.total});} catch (error) {console.error('Error fetching data:', error);} finally {setLoading(false);}};useEffect(() => {fetchData();}, []);const handleTableChange = (paginate) => {fetchData({current: paginate.current,pageSize: paginate.pageSize});};const columns = [// 定义列{ title: 'Name', dataIndex: 'name', key: 'name' },{ title: 'Age', dataIndex: 'age', key: 'age' },// ...其他列];return (<Tablecolumns={columns}dataSource={data}pagination={pagination}loading={loading}onChange={handleTableChange}rowKey="id"/>);
}
分页优化技巧
- 缓存已加载的页面数据
const [cachedData, setCachedData] = useState({});const fetchData = async (params = {}) => {const current = params.current || pagination.current;const pageSize = params.pageSize || pagination.pageSize;const cacheKey = `${current}-${pageSize}`;// 检查缓存中是否已有此页数据if (cachedData[cacheKey]) {setData(cachedData[cacheKey]);return;}setLoading(true);try {const response = await axios.get('/api/items', {params: { page: current, pageSize }});// 更新数据和缓存setData(response.data.items);setCachedData({...cachedData,[cacheKey]: response.data.items});setPagination({...pagination,current,total: response.data.total});} catch (error) {console.error('Error:', error);} finally {setLoading(false);}
};
- 预加载下一页数据
const prefetchNextPage = (current, pageSize) => {const nextPage = current + 1;const cacheKey = `${nextPage}-${pageSize}`;// 如果下一页已缓存或正在加载,则不预加载if (cachedData[cacheKey] || loading) return;// 静默加载下一页axios.get('/api/items', {params: { page: nextPage, pageSize }}).then(response => {setCachedData({...cachedData,[cacheKey]: response.data.items});}).catch(err => {console.error('Prefetch error:', err);});
};// 在数据加载完成后调用预加载
useEffect(() => {if (!loading && data.length > 0) {prefetchNextPage(pagination.current, pagination.pageSize);}
}, [data, loading]);
- 处理搜索和筛选
import { Table, Pagination, Input, Form, Button, Select } from 'antd';
import { debounce } from 'lodash';function EnhancedTable() {// ...之前的状态const [filters, setFilters] = useState({});// 使用防抖处理搜索const handleSearch = debounce((searchText) => {setFilters(prev => ({ ...prev, searchText }));fetchData({ current: 1 }); // 搜索时重置到第一页}, 300);const fetchData = async (params = {}) => {setLoading(true);try {const response = await axios.get('/api/items', {params: {page: params.current || pagination.current,pageSize: params.pageSize || pagination.pageSize,...filters // 添加所有筛选条件}});// 更新数据和分页信息// ...} catch (error) {console.error('Error:', error);} finally {setLoading(false);}};return (<><Form layout="inline" style={{ marginBottom: 16 }}><Form.Item label="搜索"><Input.Search placeholder="输入关键词" onSearch={value => handleSearch(value)}onChange={e => handleSearch(e.target.value)}/></Form.Item><Form.Item label="状态"><Selectplaceholder="选择状态"style={{ width: 120 }}onChange={value => {setFilters(prev => ({ ...prev, status: value }));fetchData({ current: 1 });}}allowClear><Select.Option value="active">活跃</Select.Option><Select.Option value="inactive">非活跃</Select.Option></Select></Form.Item></Form><Table// ...之前的Table属性/></>);
}
3. 瀑布流实现 - React Antd
基于Marker/Cursor的瀑布流
import { List, Spin, message } from 'antd';
import { useState, useEffect, useRef } from 'react';
import InfiniteScroll from 'react-infinite-scroll-component';
import axios from 'axios';function InfiniteScrollList() {const [data, setData] = useState([]);const [loading, setLoading] = useState(false);const [hasMore, setHasMore] = useState(true);const marker = useRef(null);const loadMoreData = async () => {if (loading || !hasMore) return;setLoading(true);try {const response = await axios.get('/api/items', {params: {limit: 20,marker: marker.current}});const newData = response.data.data;if (newData.length === 0) {setHasMore(false);} else {setData([...data, ...newData]);marker.current = response.data.marker;// 如果没有返回marker,说明没有更多数据了if (!response.data.marker) {setHasMore(false);}}} catch (error) {console.error('Error fetching data:', error);message.error('加载失败,请重试');setHasMore(false);} finally {setLoading(false);}};useEffect(() => {loadMoreData();}, []);return (<divid="scrollableDiv"style={{height: 400,overflow: 'auto',padding: '0 16px',border: '1px solid rgba(140, 140, 140, 0.35)'}}><InfiniteScrolldataLength={data.length}next={loadMoreData}hasMore={hasMore}loader={<Spin tip="加载中..." />}endMessage={<div style={{ textAlign: 'center' }}>没有更多数据了</div>}scrollableTarget="scrollableDiv"><ListdataSource={data}renderItem={item => (<List.Item key={item.id}><List.Item.Metatitle={item.title}description={item.description}/></List.Item>)}/></InfiniteScroll></div>);
}
虚拟列表优化
对于大量数据,可以结合虚拟列表以提高性能:
import { List, Avatar, Spin } from 'antd';
import { useState, useEffect, useRef } from 'react';
import VirtualList from 'rc-virtual-list';
import axios from 'axios';function VirtualizedInfiniteList() {const [data, setData] = useState([]);const [loading, setLoading] = useState(false);const [hasMore, setHasMore] = useState(true);const marker = useRef(null);const containerRef = useRef(null);const itemHeight = 47; // 每项的高度const loadMoreData = async () => {if (loading || !hasMore) return;setLoading(true);try {const response = await axios.get('/api/items', {params: {limit: 20,marker: marker.current}});const newData = response.data.data;if (newData.length === 0) {setHasMore(false);} else {setData(prevData => [...prevData, ...newData]);marker.current = response.data.marker;if (!response.data.marker) {setHasMore(false);}}} catch (error) {console.error('Error:', error);setHasMore(false);} finally {setLoading(false);}};useEffect(() => {loadMoreData();}, []);const onScroll = (e) => {if (e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 100) {loadMoreData();}};return (<List>{loading && data.length === 0 ? <Spin /> : null}<VirtualListdata={data}height={400}itemHeight={itemHeight}itemKey="id"onScroll={onScroll}ref={containerRef}>{(item) => (<List.Item key={item.id}><List.Item.Metaavatar={<Avatar src={item.avatar} />}title={item.title}description={item.description}/></List.Item>)}</VirtualList>{loading && data.length > 0 ? (<div style={{ textAlign: 'center', padding: '12px 0' }}><Spin /></div>) : null}</List>);
}
4. 优化策略总结
性能优化
-
虚拟滚动:仅渲染可见区域内的元素,大幅提升性能
// 使用React Window (安装: npm install react-window) import { FixedSizeList as List } from 'react-window';const Row = ({ index, style }) => (<div style={style}>Row {index}</div> );const VirtualizedList = () => (<Listheight={400}itemCount={1000}itemSize={35}width={300}>{Row}</List> );
-
数据预取:提前加载下一页数据,提升用户体验
// 当用户滚动到接近底部时预加载 const handleScroll = (e) => {const { scrollTop, scrollHeight, clientHeight } = e.target;// 当滚动到距离底部20%的位置时预加载if (scrollTop > (scrollHeight - clientHeight) * 0.8) {prefetchNextData();} };
-
请求优化:使用防抖和节流控制请求频率
import { debounce, throttle } from 'lodash';// 防抖:用于搜索输入 const debouncedSearch = debounce((value) => {fetchData(value); }, 300);// 节流:用于滚动事件 const throttledScroll = throttle((e) => {handleScroll(e); }, 200);
用户体验优化
-
加载状态反馈
// 使用骨架屏代替简单的加载指示器 import { Skeleton } from 'antd';{loading ? (<Skeleton active paragraph={{ rows: 4 }} /> ) : (<ContentComponent data={data} /> )}
-
错误处理与重试
const [error, setError] = useState(null);const fetchData = async () => {setLoading(true);setError(null);try {// 数据请求...} catch (err) {setError(err.message || '加载失败');} finally {setLoading(false);} };// 在UI中展示错误信息和重试按钮 {error && (<div className="error-container"><p>{error}</p><Button onClick={fetchData}>重试</Button></div> )}
-
记住滚动位置
// 保存滚动位置到sessionStorage const saveScrollPosition = () => {sessionStorage.setItem('scrollPosition', container.current.scrollTop); };// 组件卸载前保存位置 useEffect(() => {return () => {saveScrollPosition();}; }, []);// 组件挂载时恢复位置 useEffect(() => {const savedPosition = sessionStorage.getItem('scrollPosition');if (savedPosition && container.current) {container.current.scrollTop = parseInt(savedPosition);} }, []);
5. 最佳实践
分页场景选择
- 传统分页(页码导航)适用场景:
- 后台管理系统
- 数据表格/数据列表展示
- 需要精确定位到特定页面的场景
- 数据总量明确的场景
- 瀑布流/无限滚动适用场景:
- 社交媒体信息流
- 图片/卡片展示墙
- 新闻阅读页面
- 产品类目浏览
- 强调浏览体验的场景
实现决策树
选择分页方式
├── 需要精确页码跳转?
│ ├── 是 → 使用传统分页 (Pagination)
│ │ └── 数据量大?
│ │ ├── 是 → 启用虚拟滚动
│ │ └── 否 → 使用标准Table组件
│ └── 否 → 考虑瀑布流/无限滚动
│ ├── 需要保持列表位置?
│ │ ├── 是 → 使用marker/cursor分页
│ │ └── 否 → 可使用offset分页
│ └── 列表项数量可能很大?
│ ├── 是 → 必须启用虚拟滚动
│ └── 否 → 可以使用简单InfiniteScroll
6. React Antd 常用组件示例
完整的Table分页组件(含搜索、筛选、缓存)
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { Table, Input, Button, Form, Select, Space, message, Card } from 'antd';
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
import axios from 'axios';
import { debounce } from 'lodash';const AdvancedPaginationTable = () => {// 状态管理const [data, setData] = useState([]);const [loading, setLoading] = useState(false);const [pagination, setPagination] = useState({current: 1,pageSize: 10,total: 0,showSizeChanger: true,pageSizeOptions: ['10', '20', '50', '100'],showTotal: (total) => `共 ${total} 条数据`});const [filters, setFilters] = useState({});const [cacheData, setCacheData] = useState({});const [form] = Form.useForm();// 生成缓存键const getCacheKey = useCallback((page, pageSize, currentFilters) => {const filtersKey = Object.keys(currentFilters).sort().map(key => `${key}:${currentFilters[key]}`).join('|');return `${page}-${pageSize}-${filtersKey}`;}, []);// 处理数据获取const fetchData = useCallback(async (params = {}) => {const current = params.current || pagination.current;const pageSize = params.pageSize || pagination.pageSize;const currentFilters = params.filters || filters;// 检查缓存中是否有数据const cacheKey = getCacheKey(current, pageSize, currentFilters);if (cacheData[cacheKey]) {setData(cacheData[cacheKey].data);setPagination(prev => ({...prev,current,pageSize,total: cacheData[cacheKey].total}));return;}setLoading(true);try {const response = await axios.get('/api/items', {params: {page: current,pageSize,...currentFilters}});const newData = response.data.items || [];const total = response.data.total || 0;setData(newData);setPagination(prev => ({...prev,current,pageSize,total}));// 更新缓存setCacheData(prev => ({...prev,[cacheKey]: { data: newData, total }}));// 预加载下一页if (current < Math.ceil(total / pageSize)) {prefetchNextPage(current, pageSize, currentFilters);}} catch (error) {console.error('Failed to fetch data:', error);message.error('获取数据失败,请重试');} finally {setLoading(false);}}, [pagination, filters, cacheData, getCacheKey]);// 预加载下一页数据const prefetchNextPage = useCallback((current, pageSize, currentFilters) => {const nextPage = current + 1;const cacheKey = getCacheKey(nextPage, pageSize, currentFilters);// 已缓存则不再请求if (cacheData[cacheKey]) return;// 后台静默加载,不影响当前UIaxios.get('/api/items', {params: {page: nextPage,pageSize,...currentFilters}}).then(response => {setCacheData(prev => ({...prev,[cacheKey]: { data: response.data.items || [], total: response.data.total || 0 }}));}).catch(err => {console.error('预加载下一页失败:', err);});}, [cacheData, getCacheKey]);// 防抖搜索处理const handleSearch = debounce((values) => {const newFilters = {};Object.entries(values).forEach(([key, value]) => {if (value !== undefined && value !== '') {newFilters[key] = value;}});setFilters(newFilters);// 搜索时重置到第一页fetchData({ current: 1, filters: newFilters });}, 300);// 重置筛选const handleReset = () => {form.resetFields();setFilters({});fetchData({ current: 1, filters: {} });};// 处理表格变更 (分页、筛选、排序)const handleTableChange = (pagination, filters, sorter) => {fetchData({current: pagination.current,pageSize: pagination.pageSize,filters: {...form.getFieldsValue(),// 添加表格内置筛选...(filters && Object.keys(filters).length > 0 ? Object.fromEntries(Object.entries(filters).filter(([_, value]) => value && value.length > 0).map(([key, value]) => [key, value.join(',')])) : {}),// 添加排序...(sorter.field ? {sortField: sorter.field,sortOrder: sorter.order} : {})}});};// 初始加载useEffect(() => {fetchData();}, []);// 表格列定义const columns = [{title: 'ID',dataIndex: 'id',key: 'id',width: 80,sorter: true},{title: '名称',dataIndex: 'name',key: 'name',sorter: true,defaultSortOrder: 'ascend'},{title: '状态',dataIndex: 'status',key: 'status',filters: [{ text: '活跃', value: 'active' },{ text: '非活跃', value: 'inactive' }],render: status => (<span style={{ color: status === 'active' ? 'green' : 'gray'}}>{status === 'active' ? '活跃' : '非活跃'}</span>)},{title: '创建时间',dataIndex: 'createdAt',key: 'createdAt',sorter: true},{title: '操作',key: 'action',render: (_, record) => (<Space size="middle"><a onClick={() => console.log('查看', record)}>查看</a><a onClick={() => console.log('编辑', record)}>编辑</a></Space>)}];return (<Card><Formform={form}layout="inline"style={{ marginBottom: 16 }}onFinish={handleSearch}><Form.Item name="keyword" label="关键词"><Input placeholder="搜索名称"prefix={<SearchOutlined />}allowClearonChange={e => form.submit()}/></Form.Item><Form.Item name="dateRange" label="日期范围"><Selectstyle={{ width: 200 }}placeholder="选择日期范围"allowClearonChange={() => form.submit()}><Select.Option value="today">今天</Select.Option><Select.Option value="week">最近一周</Select.Option><Select.Option value="month">最近一个月</Select.Option></Select></Form.Item><Form.Item><Button icon={<ReloadOutlined />} onClick={handleReset}>重置</Button></Form.Item></Form><Tablecolumns={columns}dataSource={data}rowKey="id"pagination={pagination}loading={loading}onChange={handleTableChange}scroll={{ x: 800 }}/></Card>);
};export default AdvancedPaginationTable;
高性能瀑布流组件(虚拟滚动+Marker分页)
import React, { useState, useEffect, useRef, useCallback } from 'react';
import { List, Card, Avatar, Spin, Empty, Button, message } from 'antd';
import { ReloadOutlined } from '@ant-design/icons';
import VirtualList from 'rc-virtual-list';
import axios from 'axios';
import { throttle } from 'lodash';const ITEM_HEIGHT = 180; // 每个卡片高度
const CONTAINER_HEIGHT = 600; // 容器高度
const BATCH_SIZE = 15; // 每次加载条数const HighPerformanceInfiniteScroll = () => {const [data, setData] = useState([]);const [loading, setLoading] = useState(false);const [initialLoading, setInitialLoading] = useState(true);const [error, setError] = useState(null);const [hasMore, setHasMore] = useState(true);const markerRef = useRef(null);const containerRef = useRef(null);// 加载数据的核心函数const loadData = useCallback(async (reset = false) => {// 如果已在加载或没有更多数据,则跳过if ((loading && !reset) || (!hasMore && !reset)) return;try {setLoading(true);if (reset) {setInitialLoading(true);setError(null);markerRef.current = null;}const response = await axios.get('/api/feed', {params: {limit: BATCH_SIZE,marker: reset ? null : markerRef.current}});const { items, marker } = response.data;if (items && items.length > 0) {setData(prevData => reset ? items : [...prevData, ...items]);markerRef.current = marker;setHasMore(!!marker); // 如果没有返回marker,表示没有更多数据} else {setHasMore(false);}} catch (err) {console.error('Failed to fetch data:', err);setError('加载数据失败,请重试');setHasMore(false);} finally {setLoading(false);setInitialLoading(false);}}, [loading, hasMore]);// 初始加载useEffect(() => {loadData(true);}, []);// 保存滚动位置useEffect(() => {const saveScrollPosition = () => {if (containerRef.current) {sessionStorage.setItem('infiniteScrollPos', containerRef.current.scrollTop);}};// 页面关闭或组件卸载时保存位置window.addEventListener('beforeunload', saveScrollPosition);return () => {saveScrollPosition();window.removeEventListener('beforeunload', saveScrollPosition);};}, []);// 恢复滚动位置useEffect(() => {const savedPosition = sessionStorage.getItem('infiniteScrollPos');if (savedPosition && containerRef.current && data.length > 0) {setTimeout(() => {containerRef.current.scrollTop = parseInt(savedPosition);}, 100);}}, [initialLoading, data.length]);// 节流处理的滚动事件const onScroll = throttle(e => {if (e.target.scrollHeight - e.target.scrollTop
相关文章:
前端分页与瀑布流最佳实践笔记 - React Antd 版
前端分页与瀑布流最佳实践笔记 - React Antd 版 1. 分页与瀑布流对比 分页(Pagination)瀑布流(Infinite Scroll)展示方式按页分批加载,有明确页码控件滚动到底部时自动加载更多内容,无明显分页用户控制用…...
【网络原理】从零开始深入理解TCP的各项特性和机制.(三)
上篇介绍了网络原理传输层TCP协议的知识,本篇博客给大家带来的是网络原理剩余的内容, 总体来说,这部分内容没有上两篇文章那么重要,本篇知识有一个印象即可. 🐎文章专栏: JavaEE初阶 🚀若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分…...
MySQL:13.用户管理
13. 用户管理 如果我们只能使用root用户,这样存在安全隐患。这时,就需要使用MySQL的用户管理。 13.1 用户 13.1.1 用户信息 MySQL中的用户,都存储在系统数据库mysql的user表中 mysql> use mysql; Database changed mysql> select h…...
leetcode0103. 二叉树的锯齿形层序遍历-medium
1 题目:二叉树的锯齿形层序遍历 官方标定难度:中 给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行…...
【Go语言】ORM(对象关系映射)库
github.com/jinzhu/gorm 是 Go 语言中一个非常流行的 ORM(对象关系映射)库,用于简化与关系型数据库的交互。以下是关于它的关键信息: 核心特点 全功能 ORM 支持主流数据库:MySQL、PostgreSQL、SQLite、SQL Server 等。…...
Java : GUI
AWT 初始化界面 直接封装起来: panel 的添加 布局 流式布局,控制按钮的位置 东西南北中布局 网格布局 frame.pack();java函数,会自动选择最优的布局 事件监听 给按钮添加 添加文本 画笔 鼠标监听 键盘监听 JDialog”弹窗 默认有关闭事件 标签&#…...
ipa包安装到apple手机上
获ipa包的方式 ipatool 下载appStore的ipa包-CSDN博客 方式一:巨魔商店 原理是利用apple的漏洞,但是有低版本的系统要求 TrollStore - Always Sideload Any IPAs For FreeTrollStore - The ultimate jailbreak app for iOS. Permanently install any …...
JavaScript输出数据的方法
1. console.log() console.log()是最常用的方法之一,用于在浏览器的控制台(Console)中输出信息。这对于调试和查看变量的值非常有用。 console.log("Hello, world!");2. alert() alert()方法会弹出一个带有指定消息和确定按钮的警告…...
操作系统:计算机世界的基石与演进
一、操作系统的本质与核心功能 操作系统如同计算机系统的"总管家",在硬件与应用之间架起关键桥梁。从不同视角观察,其核心功能呈现多维价值: 硬件视角的双重使命: 硬件管理者:通过内存管理、进程调度和设…...
FFmpeg之三 录制音频并保存, API编解码从理论到实战
在学习FFmpeg的时候,想拿demo来练习,官方虽有示例,但更像是工具演示,新手不好掌握,在网上找不到有文章,能给出完整的示例和关键点的分析说明,一步一个错误,慢慢啃过来的,…...
幂等性处理解决方案实战示例
幂等性处理解决方案实战示例 幂等性是指对同一个操作执行一次或多次,产生的结果是相同的。在分布式系统、网络请求和金融交易等场景中,幂等性设计至关重要。下面我将介绍几种常见的幂等性处理方案及其实战示例。 1. 唯一标识符方案 原理:为…...
华为仓颉编程语言的实际用法与使用领域详解
华为仓颉编程语言的实际用法与使用领域详解 一、语言概述与核心特性 华为仓颉编程语言是面向万物智联时代的系统级编程语言,其核心特性包括: 三重内存安全机制:所有权系统 + 引用检查 + 硬件辅助防护零成本抽象:高级语法不牺牲底层性能全场景支持:从嵌入式设备到量子计算…...
JavaEE-多线程实战01
Java 多线程入门:第一个多线程程序 在 Java 中,多线程编程是非常重要的一部分。本篇文章将通过示例,带你快速了解如何创建第一个多线程程序,并深入分析其运行机制。 1. 创建一个线程类并继承 Thread 在 Java 中,我们…...
当AI浏览器和AI搜索替代掉传统搜索份额时,老牌的搜索引擎市场何去何从。
AI搜索与传统搜索优劣势分析 AI搜索优势 理解和处理查询方式更智能:利用自然语言处理(NLP)和机器学习技术,能够更好地理解用户的意图和上下文,处理复杂的问答、长尾问题以及多轮对话,提供更为精准和相关的…...
大模型——Spring.new快速构建AI驱动的定制化商业应用
大模型——Spring.new快速构建AI驱动的定制化商业应用 Spring.new 是一个基于人工智能的在线平台,专注于帮助营销经理和产品经理快速构建定制化工作流和小型应用。它通过自然语言输入,让用户描述需求,自动生成连接 Notion、Airtable、Slack 等工具的工作流或应用,例如将 F…...
django admin 中更新表数据 之后再将数据返回管理界面
在Django中,更新数据库中的数据并将其重新显示在Django Admin界面上通常涉及到几个步骤。这里我将详细说明如何在Django Admin中更新表数据,并确保更新后的数据能够立即在管理界面上显示。 定义模型 首先,确保你的模型(Model&…...
深度理解linux系统—— 进程概念
一、进程 进程,什么是进程? 在课本,教材中是这样描述的:程序的一个执行示例,正在执行的程序; 从内核角度来说,进程就是担当分配系统资源(CPU时间,内存)的实体…...
【如何使用solidwork编辑结构导入到simscope】
这里写自定义目录标题 欢迎使用Markdown编辑器 欢迎使用Markdown编辑器 To use Simscape Multibody Link, you must install MATLAB and the CAD applications on the same computer. To ensure the successful installation of Simscape Multibody Link, before launching yo…...
Flink 时态维度表 Join 与缓存机制实战
一、引言:为什么需要时态维度表? 在实时数仓建设中,维度表是不可或缺的一环,例如: 风控系统中,用户的风险等级在不同时间可能变化; 营销体系中,商品的促销标签会动态调整ÿ…...
Apache Tomcat 漏洞(CVE-2025-24813)导致服务器面临 RCE 风险
CVE-2025-24813Apache Tomcat 中发现了一个严重安全漏洞,标识为,该漏洞可能导致服务器面临远程代码执行 (RCE)、信息泄露和数据损坏的风险。 此缺陷影响以下版本: Apache Tomcat11.0.0-M1通过11.0.2Apache Tomcat10.1.0-M1通过10.1.34Apache Tomcat9.0.0-M1通过9.0.98了解 …...
来自B站-AI匠的“RAG的prompt设计指南“的部分截图
来自B站-AI匠的“RAG的prompt设计指南“的部分截图 0. 引言1. RAG提示词 - 部分视频截图2. 总结 - 部分视频截图3. 举例 - 部分视频截图 0. 引言 这个文章记录的是B站Up主AI匠关于RAG的prompt设计指南的视频截图。 1. RAG提示词 - 部分视频截图 笔记: Up主推荐Fa…...
【Linux】Centos7 在 Docker 上安装 Redis7.0(最新详细教程)
一、拉取 Redis 镜像 1. 从 阿里云加速器(docker hub)拉取 redis镜像,选择镜像标签为 7.2.4 docker pull redis:7.2.4 2. 准备 Redis 的配置文件(便于后期对配置文件进行修改) 3.在服务器上创建需要挂载的文件夹 mk…...
Java使用微信云服务HTTP API操作微信云开发数据库
可以直接用的工具类代码 package com.kstc.qgy.util;import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.kstc.qgy.model.exception.WxException; import com.kstc.qgy.model.service.Limit; imp…...
Linux的权限
目录 1、用户分类 1.1 超级用户(root)和普通用户 1.2 普通<->超级 1.3 sudo 2、文件和目录的权限 2.1 chown&&chgrp 2.1.1 chown 2.1.2 chgrp 2.2 chmod 总结一下: 3、文件和目录的默认权限 4、共享文件 4.1 理解多用户隔离 4.2 /tmp/ 1…...
ACT游戏和MMORPG经济形态区别以及对经济循环的思考
对于原神的明日之后经济形态的不同解析 对于MMORPG游戏来说,如果采用开放市场经济的设计,以明日之后为例,系统产出端为采集、运营活动投放;玩家产出端为交易;消耗端为武器耐久的减少。但我好奇,在ACT游戏里…...
zynq7035的arm一秒钟最多可以支持触发多少次中断
一、概述 1.关于zynq7035的ARM处理器一秒能够支持多少次中断触发,需要综合来考虑。需要确定ARM处理器的参数,目前zynq7000系列,使用的双核Cortex-A9处理器。其中主频大概在500MHZ~1GHZ左右,不同的用户配置的主频可能稍微有差别。 …...
Spring MVC 拦截器教程
一、拦截器核心概念 1.1 拦截器 vs 过滤器 特性过滤器 (Filter)拦截器 (Interceptor)依赖关系Servlet容器Spring MVC框架作用范围所有Web请求Controller请求实现机制Java EE标准Java反射AOP生命周期服务器启动时初始化随Spring容器初始化功能场景字符编码、安全过滤权限校验、…...
【HPC存储性能测试】02-ior带宽性能测试
文章目录 一、前言二、软件安装1、安装依赖2、安装软件 三、参数说明1、mpirun参数2、ior参数 四、测试说明 一、前言 ior introduction | github hpc ior IOR 测试工具使用 POSIX、 MPIIO 或 HDF5接口对并行文件系统进行基准测试 通常使用IOR测试工具时,一般会配合…...
【RabbitMQ】保证消息不丢失
要确保 RabbitMQ 在消费者(Python 服务)重启或挂掉时消息不丢失,需结合 消息持久化、确认机制(ACK) 和 死信队列(DLX) 实现高可靠性: 1. 消息持久化(Durabilityÿ…...
算法效率的钥匙:从大O看复杂度计算 —— C语言数据结构第一讲
目录 1.数据结构与算法 1.1数据结构介绍 1.2算法介绍 2.算法效率 2.1复杂度 2.1.1时间复杂度 2.1.1.1时间复杂度计算示例1 2.1.1.2时间复杂度计算示例2 2.1.1.3时间复杂度计算示例3 2.1.1.4时间复杂度计算示例4 2.1.1.5时间复杂度计算示例5 2.1.1.6时间复杂度计算示例6…...
AI赋能守护行车安全新防线,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建驾驶车辆场景下驾驶员疲劳分心驾驶行为智能检测预警系统
在当今社会,随着科技生产力的飞速发展,汽车早已成为人们日常出行不可或缺的交通工具。它不仅极大地提高了人们的出行效率,也为生活带来了诸多便利。然而,随着汽车保有量的不断增加,交通安全问题也日益凸显。疲劳驾驶和…...
HNUST湖南科技大学-嵌入式考试选择题题库(109道纠正详解版)
HNUST嵌入式选择题题库 1.下面哪点不是嵌入式操作系统的特点。(B) A.内核精简 B.功能强大 C.专用性强 D.高实时性 解析: 嵌入式操作系统特点是内核精简、专用性强、高实时性,而"功能强大"通常指的是通用操作系统&#x…...
【音视频】SDL事件
SDL 事件 函数 SDL_WaitEvent(): 等待一个事件SDL_PushEvent(): 发送一个事件SDL_PumpEvents(): 将硬件设备产生的事件放入事件队列,用于读取事件,在调用该函数之前,必须调用SDL_PumpEvents搜集键盘等事件…...
[特殊字符]实战:使用 Canal + MQ + ES + Redis + XXL-Job 打造高性能地理抢单系统
📚目录 项目背景 技术栈总览 详细流程分析 3.1 Canal监听MySQL Binlog 3.2 MQ中转传递订单变化 3.3 Elasticsearch存储并查询附近订单 3.4 Redis高性能抢单Lua防止抢单冲突 3.5 XXL-Job定时任务处理 完整系统流程图 总结 一、项目背景 针对类似外卖、跑…...
FPGA基础之基础语法
一、基本模块结构 Verilog 代码以 模块(Module) 为单位,每个模块对应一个硬件功能单元(如逻辑门、寄存器等)。 基本格式: module 模块名 (// 输入输出端口声明input 端口1,input 端口2,output 端口3 );…...
影楼精修-皮肤瑕疵祛除算法解析
注意:本文样例图片为了避免侵权,均使用AIGC生成; 顾名思义,皮肤瑕疵祛除旨在祛除人像照片皮肤区域的痘痘/斑点/痣/胎记等瑕疵;当前主流算法方案可分为传统图像处理方法和基于深度学习的方法,本文重点介绍基…...
2025蓝桥杯省赛网络安全组wp
文章目录 黑客密室逃脱ezEvtxflowzipEnigma星际xml解析器EBC-TrainAES-CBC 黑客密室逃脱 提示猜文件名,猜几个常见的,app.py读到源码 这里也是脑抽了一下,把密钥看成1236了。。。卡了五分钟左右,解出来的时候已经降到300多分了&a…...
【数据结构】·励志大厂版(复习+刷题):二叉树
前引:哈喽小伙伴们!经过几个月的间隔,还是逃脱不了再次复习的命运!!!本篇文章没有冗杂的闲话,全是干货教学,带你横扫二叉树的几种遍历,怎么前序、、中序、后续࿱…...
Spark-Streaming2
一.有状态转化操作 1. UpdateStateByKey UpdateStateByKey 原语用于记录历史记录,有时,我们需要在 DStream 中跨批次维护状态(例如流计算中累加 wordcount)。针对这种情况,updateStateByKey()为我们提供了对一个状态变量的访问&…...
《深入浅出Git:从版本控制原理到高效协作实战》
Git的原理和使用 1、Git初识与安装2、Git基本操作2.1、创建Git本地仓库2.2、配置Git2.3、认识工作区、暂存区、版本库2.4、修改文件2.5、版本回退2.6、撤销修改2.7、删除文件 3、Git分支管理3.1、理解分支3.2、创建、切换、合并分支3.3、删除分支3.4、合并冲突3.5、合并模式3.6…...
内耗型选手如何能做到不内耗?
以下是针对「内耗型选手」的系统性解决方案,结合认知神经科学、行为心理学和效能管理理论,提供可落地的策略框架: 一、建立「内耗熵值」监测系统 1. 绘制内耗热力图 用时间轴记录每日内耗触发点: 时间段内耗场景能量损耗值&…...
pyspark将hive数据写入Excel文件中
不多解释直接上代码,少python包的自己直接下载 #!/usr/bin/env python # -*- encoding: utf-8 -*- from pyspark.sql import SparkSession import pandas as pd import os# 初始化 SparkSession 并启用 Hive 支持 spark SparkSession.builder \.appName("sel…...
Java大师成长计划之第5天:Java中的集合框架
📢 友情提示: 本文由银河易创AI(https://ai.eaigx.com)平台gpt-4o-mini模型辅助创作完成,旨在提供灵感参考与技术分享,文中关键数据、代码与结论建议通过官方渠道验证。 在 Java 编程中,集合框架…...
rt-linux下的D状态的堆栈抓取及TASK_RTLOCK_WAIT状态
一、背景 在之前的博客 缺页异常导致的iowait打印出相关文件的绝对路径-CSDN博客 里的 2.1 一节里的代码,我们已经有了一个比较强大的抓取D状态和等IO状态超过阈值的waker和wakee的堆栈状态的内核模块。在之前的博客 增加等IO状态的唤醒堆栈打印及缺页异常导致iowa…...
数据结构【堆和链式结构】
堆和链式结构 1.堆的概念和定义1.1堆1.2二叉树的性质 2.堆的实现3.实现链式二叉树3.1链式二叉树的概念3.2前中后遍历3.3遍历(举例) 1.堆的概念和定义 1.1堆 定义:是特殊的二叉树 #mermaid-svg-vWPNPMGSLe0nGNcd {font-family:"trebuch…...
聊一聊自动化测试
目录 一、自动化测试的定义与核心价值 (一)什么是自动化测试 (二)核心价值:从人工到智能的跨越 二、自动化测试的发展阶段 (一)萌芽阶段(早期) (二&…...
vue2 开发一个实习管理系统电脑端-前端静态网站练习
为了快速的掌握vue2的所学习到的知识点,最近又使用vue2和element-ui 做了一个实习管理系统来巩固自己的前端技术,我觉得对于新手来说,多写代码,多找一些项目练习,是提供自己编程能力的一个很好的办法,这也是…...
【Hive入门】Hive基础操作与SQL语法:DML操作全面解析
目录 1 Hive DML操作概述 2 数据加载操作 2.1 LOAD DATA语句 2.2 INSERT语句 3 数据导出操作 3.1 INSERT OVERWRITE DIRECTORY 3.2 使用HDFS命令导出 4 数据更新与删除 4.1 UPDATE语句 4.2 DELETE语句 5 MERGE操作(Hive 2.2) 6 性能优化建议…...
C++类和对象(上)
目录 类的定义类定义格式访问限定符类域 实例化实例化概念对象大小 this指针C和C语言实现Stack对比 类的定义 类定义格式 在下面的代码中,class为定义类的关键字,Stack为类的名字,{}中为类的主体, 注意类定义结束时后面分号不能省…...
LS2K0300龙芯开发板——智能车竞赛
开启 LS2K0300 调车之旅(自己写的自己慢慢更,可能写的不好欢迎指教) 欢迎大家一起讨论共同进步!逐飞科技针对 LS2K0300 MCU 开发的开源库,涵盖多种实用功能,助力竞赛与产品开发。以下是快速上手指南&#…...