Hooks 进阶:自定义 Hook 的设计与实践

引言

React Hooks 已成为现代 React 开发的核心范式,而自定义 Hook 则为我们提供了强大的代码复用机制。

自定义 Hook 的基础原理

自定义 Hook 本质上是一种函数复用机制,它允许我们将组件逻辑提取到可重用的函数中。与传统的高阶组件(HOC)和 render props 模式相比,Hook 提供了更直接的状态共享方式,不会引入额外的组件嵌套。

自定义 Hook 的核心规则

  1. 命名必须以 use 开头:这不仅是约定,也使 React 能够识别 Hook 函数
  2. 可以调用其他 Hook:自定义 Hook 内部可以调用 React 内置 Hook 或其他自定义 Hook
  3. 状态是隔离的:不同组件调用同一个 Hook 不会共享状态
// 基础自定义 Hook 示例
function useCounter(initialValue = 0, step = 1) {const [count, setCount] = useState(initialValue);const increment = useCallback(() => {setCount(prevCount => prevCount + step);}, [step]);const decrement = useCallback(() => {setCount(prevCount => prevCount - step);}, [step]);const reset = useCallback(() => {setCount(initialValue);}, [initialValue]);return { count, increment, decrement, reset };
}// 使用示例
function CounterComponent() {const { count, increment, decrement, reset } = useCounter(10, 2);return (<div><p>当前计数: {count}</p><button onClick={increment}>增加</button><button onClick={decrement}>减少</button><button onClick={reset}>重置</button></div>);
}

自定义 Hook 设计模式

1. 资源管理型 Hook

这类 Hook 负责管理外部资源的生命周期,如网络请求、事件监听等。

function useFetch(url, options = {}) {const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);const optionsRef = useRef(options);useEffect(() => {let isMounted = true;const controller = new AbortController();const signal = controller.signal;const fetchData = async () => {setLoading(true);try {const response = await fetch(url, {...optionsRef.current,signal});if (!response.ok) {throw new Error(`HTTP error! Status: ${response.status}`);}const result = await response.json();if (isMounted) {setData(result);setError(null);}} catch (err) {if (isMounted && err.name !== 'AbortError') {setError(err.message);setData(null);}} finally {if (isMounted) {setLoading(false);}}};fetchData();return () => {isMounted = false;controller.abort();};}, [url]);return { data, loading, error };
}// 使用示例
function UserProfile({ userId }) {const { data: user, loading, error } = useFetch(`https://api.example.com/users/${userId}`);if (loading) return <div>加载中...</div>;if (error) return <div>错误: {error}</div>;return (<div><h2>{user.name}</h2><p>Email: {user.email}</p></div>);
}

2. 状态逻辑型 Hook

封装复杂状态逻辑,提供简洁的状态管理接口。

function useForm(initialValues = {}) {const [values, setValues] = useState(initialValues);const [errors, setErrors] = useState({});const [touched, setTouched] = useState({});const [isSubmitting, setIsSubmitting] = useState(false);const handleChange = useCallback((e) => {const { name, value } = e.target;setValues(prev => ({...prev,[name]: value}));}, []);const handleBlur = useCallback((e) => {const { name } = e.target;setTouched(prev => ({...prev,[name]: true}));}, []);const reset = useCallback(() => {setValues(initialValues);setErrors({});setTouched({});setIsSubmitting(false);}, [initialValues]);return {values,errors,touched,isSubmitting,handleChange,handleBlur,setValues,setErrors,setIsSubmitting,reset};
}// 使用示例
function LoginForm() {const { values, errors, touched, isSubmitting, handleChange, handleBlur, setErrors, setIsSubmitting } = useForm({ email: '', password: '' });const validate = () => {const newErrors = {};if (!values.email) newErrors.email = '邮箱不能为空';if (!values.password) newErrors.password = '密码不能为空';setErrors(newErrors);return Object.keys(newErrors).length === 0;};const handleSubmit = async (e) => {e.preventDefault();if (!validate()) return;setIsSubmitting(true);try {// 登录逻辑await loginUser(values);alert('登录成功');} catch (err) {setErrors({ form: err.message });} finally {setIsSubmitting(false);}};return (<form onSubmit={handleSubmit}><div><label htmlFor="email">邮箱</label><inputid="email"name="email"type="email"value={values.email}onChange={handleChange}onBlur={handleBlur}/>{touched.email && errors.email && <div className="error">{errors.email}</div>}</div><div><label htmlFor="password">密码</label><inputid="password"name="password"type="password"value={values.password}onChange={handleChange}onBlur={handleBlur}/>{touched.password && errors.password && <div className="error">{errors.password}</div>}</div>{errors.form && <div className="error">{errors.form}</div>}<button type="submit" disabled={isSubmitting}>{isSubmitting ? '登录中...' : '登录'}</button></form>);
}

3. 行为型 Hook

封装特定用户交互行为的逻辑,如拖拽、虚拟滚动等。

function useDrag(ref, options = {}) {const {onDragStart,onDrag,onDragEnd,disabled = false} = options;const [isDragging, setIsDragging] = useState(false);const [position, setPosition] = useState({ x: 0, y: 0 });const startPosRef = useRef({ x: 0, y: 0 });const currentPosRef = useRef({ x: 0, y: 0 });useEffect(() => {if (!ref.current || disabled) return;const element = ref.current;const handleMouseDown = (e) => {// 避免与点击事件冲突if (e.button !== 0) return;setIsDragging(true);startPosRef.current = {x: e.clientX - currentPosRef.current.x,y: e.clientY - currentPosRef.current.y};if (onDragStart) {onDragStart({x: currentPosRef.current.x,y: currentPosRef.current.y});}document.addEventListener('mousemove', handleMouseMove);document.addEventListener('mouseup', handleMouseUp);e.preventDefault();};const handleMouseMove = (e) => {if (!isDragging) return;const newPos = {x: e.clientX - startPosRef.current.x,y: e.clientY - startPosRef.current.y};currentPosRef.current = newPos;setPosition(newPos);if (onDrag) {onDrag(newPos);}};const handleMouseUp = () => {setIsDragging(false);document.removeEventListener('mousemove', handleMouseMove);document.removeEventListener('mouseup', handleMouseUp);if (onDragEnd) {onDragEnd({x: currentPosRef.current.x,y: currentPosRef.current.y});}};element.addEventListener('mousedown', handleMouseDown);return () => {element.removeEventListener('mousedown', handleMouseDown);document.removeEventListener('mousemove', handleMouseMove);document.removeEventListener('mouseup', handleMouseUp);};}, [ref, disabled, isDragging, onDragStart, onDrag, onDragEnd]);return { isDragging, position, setPosition };
}// 使用示例
function DraggableBox() {const boxRef = useRef(null);const { isDragging, position } = useDrag(boxRef, {onDragStart: (pos) => console.log('开始拖动', pos),onDragEnd: (pos) => console.log('结束拖动', pos)});return (<divref={boxRef}style={{position: 'absolute',left: `${position.x}px`,top: `${position.y}px`,width: '100px',height: '100px',background: isDragging ? '#5c7cfa' : '#339af0',cursor: 'grab',userSelect: 'none',boxShadow: isDragging ? '0 8px 16px rgba(0,0,0,0.2)' : '0 2px 4px rgba(0,0,0,0.1)',transition: isDragging ? 'none' : 'box-shadow 0.3s, background 0.3s'}}>拖拽我</div>);
}

高级技巧与优化

1. 依赖收集与性能优化

自定义 Hook 的性能优化主要关注两个方面:减少不必要的重渲染和优化内部逻辑执行效率。

function useSearch(initialQuery = '') {const [query, setQuery] = useState(initialQuery);const [results, setResults] = useState([]);const [loading, setLoading] = useState(false);// 使用 useRef 保存最新值,避免 useCallback 和 useEffect 依赖过多const stateRef = useRef({ query });stateRef.current.query = query;// 使用 useCallback 缓存函数引用const search = useCallback(debounce(async () => {const currentQuery = stateRef.current.query;if (!currentQuery.trim()) {setResults([]);return;}setLoading(true);try {const response = await fetch(`https://api.example.com/search?q=${encodeURIComponent(currentQuery)}`);const data = await response.json();setResults(data);} catch (error) {console.error('搜索出错:', error);setResults([]);} finally {setLoading(false);}}, 300), []);// 查询变化时触发搜索useEffect(() => {search();// 返回清理函数,取消正在进行的请求return () => {search.cancel();};}, [query, search]);return {query,setQuery,results,loading};
}// 节流/防抖辅助函数
function debounce(fn, delay) {let timer = null;const debounced = function(...args) {if (timer) clearTimeout(timer);timer = setTimeout(() => {fn.apply(this, args);}, delay);};debounced.cancel = function() {if (timer) {clearTimeout(timer);timer = null;}};return debounced;
}

2. 组合 Hooks 实现复杂功能

通过组合多个基础 Hook 实现更复杂的功能,遵循单一职责原则。

// 基础 Hook: 管理分页状态
function usePagination(initialPage = 1, initialPageSize = 10) {const [page, setPage] = useState(initialPage);const [pageSize, setPageSize] = useState(initialPageSize);const reset = useCallback(() => {setPage(initialPage);setPageSize(initialPageSize);}, [initialPage, initialPageSize]);return {page,pageSize,setPage,setPageSize,reset};
}// 基础 Hook: 管理排序状态
function useSorting(initialSortField = '', initialSortDirection = 'asc') {const [sortField, setSortField] = useState(initialSortField);const [sortDirection, setSortDirection] = useState(initialSortDirection);const toggleSort = useCallback((field) => {if (field === sortField) {setSortDirection(prev => prev === 'asc' ? 'desc' : 'asc');} else {setSortField(field);setSortDirection('asc');}}, [sortField]);return {sortField,sortDirection,toggleSort};
}// 组合 Hook: 实现数据表格功能
function useDataTable(fetchFn, initialFilters = {}) {const [filters, setFilters] = useState(initialFilters);const [data, setData] = useState([]);const [total, setTotal] = useState(0);const [loading, setLoading] = useState(false);const [error, setError] = useState(null);// 组合分页 Hookconst pagination = usePagination();// 组合排序 Hookconst sorting = useSorting();// 加载数据的函数const loadData = useCallback(async () => {setLoading(true);setError(null);try {const params = {page: pagination.page,pageSize: pagination.pageSize,sortField: sorting.sortField,sortDirection: sorting.sortDirection,...filters};const result = await fetchFn(params);setData(result.data);setTotal(result.total);} catch (err) {setError(err.message);} finally {setLoading(false);}}, [fetchFn,pagination.page, pagination.pageSize, sorting.sortField, sorting.sortDirection, filters]);// 过滤条件、分页或排序变化时重新加载数据useEffect(() => {loadData();}, [loadData]);// 更新过滤条件的函数const updateFilters = useCallback((newFilters) => {setFilters(prev => ({...prev,...newFilters}));// 重置到第一页pagination.setPage(1);}, [pagination]);// 重置所有状态const reset = useCallback(() => {pagination.reset();setFilters(initialFilters);}, [pagination, initialFilters]);return {// 数据状态data,total,loading,error,// 分页相关page: pagination.page,pageSize: pagination.pageSize,setPage: pagination.setPage,setPageSize: pagination.setPageSize,// 排序相关sortField: sorting.sortField,sortDirection: sorting.sortDirection,toggleSort: sorting.toggleSort,// 过滤相关filters,updateFilters,// 操作方法reload: loadData,reset};
}// 使用示例
function UsersTable() {const fetchUsers = async (params) => {const queryString = new URLSearchParams(params).toString();const response = await fetch(`https://api.example.com/users?${queryString}`);return await response.json();};const {data: users,total,loading,page,pageSize,setPage,setPageSize,sortField,sortDirection,toggleSort,filters,updateFilters} = useDataTable(fetchUsers, { status: 'active' });return (<div><div className="filters"><inputplaceholder="搜索用户"value={filters.keyword || ''}onChange={e => updateFilters({ keyword: e.target.value })}/><selectvalue={filters.status}onChange={e => updateFilters({ status: e.target.value })}><option value="active">活跃</option><option value="inactive">非活跃</option><option value="all">全部</option></select></div>{loading ? (<div>加载中...</div>) : (<table><thead><tr><th onClick={() => toggleSort('name')}>姓名 {sortField === 'name' && (sortDirection === 'asc' ? '↑' : '↓')}</th><th onClick={() => toggleSort('email')}>邮箱 {sortField === 'email' && (sortDirection === 'asc' ? '↑' : '↓')}</th><th onClick={() => toggleSort('lastLogin')}>最近登录 {sortField === 'lastLogin' && (sortDirection === 'asc' ? '↑' : '↓')}</th></tr></thead><tbody>{users.map(user => (<tr key={user.id}><td>{user.name}</td><td>{user.email}</td><td>{new Date(user.lastLogin).toLocaleString()}</td></tr>))}</tbody></table>)}<div className="pagination"><button disabled={page === 1} onClick={() => setPage(page - 1)}>上一页</button><span>第 {page} 页,共 {Math.ceil(total / pageSize)} 页</span><button disabled={page >= Math.ceil(total / pageSize)}onClick={() => setPage(page + 1)}>下一页</button><selectvalue={pageSize}onChange={e => setPageSize(Number(e.target.value))}><option value={10}>10条/页</option><option value={20}>20条/页</option><option value={50}>50条/页</option></select></div></div>);
}

3. 利用 Context 优化 Hook 共享状态

当多个组件需要共享同一个 Hook 的状态时,可以结合 Context API 实现。

// 创建一个主题上下文
const ThemeContext = createContext(null);// 主题 Provider 组件
function ThemeProvider({ children, initialTheme = 'light' }) {const [theme, setTheme] = useState(initialTheme);// 在 localStorage 中保存主题偏好useEffect(() => {localStorage.setItem('theme', theme);}, [theme]);const toggleTheme = useCallback(() => {setTheme(prev => prev === 'light' ? 'dark' : 'light');}, []);// 创建主题值对象const themeValue = useMemo(() => ({theme,setTheme,toggleTheme,isDark: theme === 'dark'}), [theme, toggleTheme]);return (<ThemeContext.Provider value={themeValue}>{children}</ThemeContext.Provider>);
}// 自定义 Hook 用于访问主题上下文
function useTheme() {const context = useContext(ThemeContext);if (context === null) {throw new Error('useTheme 必须在 ThemeProvider 内部使用');}return context;
}// 使用示例
function App() {return (<ThemeProvider initialTheme="light"><MainLayout /></ThemeProvider>);
}function MainLayout() {const { theme, toggleTheme } = useTheme();return (<div className={`app ${theme}`}><header><h1>我的应用</h1><button onClick={toggleTheme}>切换到{theme === 'light' ? '暗色' : '亮色'}主题</button></header><main><Content /></main></div>);
}function Content() {const { isDark } = useTheme();return (<section className="content"><h2>内容区域</h2><p>当前使用的是{isDark ? '暗色' : '亮色'}主题</p></section>);
}

自定义 Hook 与现代前端架构

1. 与状态管理的整合

自定义 Hook 可以与 Redux、Zustand 等状态管理库无缝集成,提供更集中的状态管理方案。

// 集成 Redux 的自定义 Hook
function useReduxActions(slice) {const dispatch = useDispatch();const state = useSelector(state => state[slice]);// 使用 useMemo 缓存创建的 actions 对象const actions = useMemo(() => {// 示例:为一个用户模块创建actionsif (slice === 'users') {return {fetchUsers: (params) => {dispatch({ type: 'users/fetchUsersStart', payload: params });return fetch(`/api/users?${new URLSearchParams(params)}`).then(res => res.json()).then(data => {dispatch({ type: 'users/fetchUsersSuccess', payload: data });return data;}).catch(error => {dispatch({ type: 'users/fetchUsersFailure', payload: error.message });throw error;});},createUser: (userData) => {dispatch({ type: 'users/createUserStart', payload: userData });return fetch('/api/users', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify(userData)}).then(res => res.json()).then(data => {dispatch({ type: 'users/createUserSuccess', payload: data });return data;}).catch(error => {dispatch({ type: 'users/createUserFailure', payload: error.message });throw error;});}};}return {};}, [dispatch, slice]);return { state, ...actions };
}// 使用示例
function UserList() {const { state: usersState, fetchUsers } = useReduxActions('users');const { data, loading, error } = usersState;useEffect(() => {fetchUsers({ page: 1, limit: 10 });}, [fetchUsers]);if (loading) return <div>加载中...</div>;if (error) return <div>错误: {error}</div>;return (<ul>{data.map(user => (<li key={user.id}>{user.name}</li>))}</ul>);
}

2. 与组件库的协同设计

自定义 Hook 可以成为组件库的强大辅助工具,为复杂组件提供逻辑层抽象。

// 自定义 Hook 和组件协同
function useMenuControl(initialOpenKeys = []) {const [openKeys, setOpenKeys] = useState(initialOpenKeys);const [selectedKey, setSelectedKey] = useState(null);const onOpenChange = useCallback((key) => {setOpenKeys(prev => {const keyIndex = prev.indexOf(key);if (keyIndex >= 0) {// 已打开,则关闭const newKeys = [...prev];newKeys.splice(keyIndex, 1);return newKeys;} else {// 未打开,则添加return [...prev, key];}});}, []);const isOpen = useCallback((key) => {return openKeys.includes(key);}, [openKeys]);return {openKeys,selectedKey,setSelectedKey,onOpenChange,isOpen};
}// 菜单组件
function Menu({ items, defaultOpenKeys = [] }) {const {openKeys,selectedKey,setSelectedKey,onOpenChange,isOpen} = useMenuControl(defaultOpenKeys);return (<nav className="menu">{items.map(item => {if (item.children) {return (<div key={item.key} className="submenu"><divclassName="submenu-title"onClick={() => onOpenChange(item.key)}>{item.icon && <span className="icon">{item.icon}</span>}<span>{item.label}</span><span className={`arrow ${isOpen(item.key) ? 'open' : ''}`}>▾</span></div>{isOpen(item.key) && (<div className="submenu-items">{item.children.map(child => (<divkey={child.key}className={`menu-item ${selectedKey === child.key ? 'active' : ''}`}onClick={() => setSelectedKey(child.key)}>{child.icon && <span className="icon">{child.icon}</span>}<span>{child.label}</span></div>))}</div>)}</div>);}return (<divkey={item.key}className={`menu-item ${selectedKey === item.key ? 'active' : ''}`}onClick={() => setSelectedKey(item.key)}>{item.icon && <span className="icon">{item.icon}</span>}<span>{item.label}</span></div>);})}</nav>);
}// 使用示例
function SidebarNavigation() {const menuItems = [{key: 'dashboard',label: '仪表盘',icon: '📊'},{key: 'users',label: '用户管理',icon: '👥',children: [{key: 'user-list',label: '用户列表'},{key: 'user-groups',label: '用户组'}]},{key: 'settings',label: '系统设置',icon: '⚙️',children: [{key: 'profile',label: '个人资料'},{key: 'security',label: '安全设置'}]}];return (<div className="sidebar"><div className="logo">应用名称</div><Menu items={menuItems} defaultOpenKeys={['users']} /></div>);
}

自定义 Hook 测试最佳实践

测试自定义 Hook 是确保其可靠性和可维护性的关键环节。以下是针对自定义 Hook 的测试策略:

// 示例:使用 @testing-library/react-hooks 测试自定义 Hook// useCounter.js
import { useState, useCallback } from 'react';export function useCounter(initialValue = 0, step = 1) {const [count, setCount] = useState(initialValue);const increment = useCallback(() => {setCount(prevCount => prevCount + step);}, [step]);const decrement = useCallback(() => {setCount(prevCount => prevCount - step);}, [step]);const reset = useCallback(() => {setCount(initialValue);}, [initialValue]);return { count, increment, decrement, reset };
}// useCounter.test.js
import { renderHook, act } from '@testing-library/react-hooks';
import { useCounter } from './useCounter';describe('useCounter', () => {test('应该使用默认初始值', () => {const { result } = renderHook(() => useCounter());expect(result.current.count).toBe(0);});test('应该使用提供的初始值', () => {const { result } = renderHook(() => useCounter(10));expect(result.current.count).toBe(10);});test('应该递增计数', () => {const { result } = renderHook(() => useCounter(0, 2));act(() => {result.current.increment();});expect(result.current.count).toBe(2);});test('应该递减计数', () => {const { result } = renderHook(() => useCounter(10, 5));act(() => {result.current.decrement();});expect(result.current.count).toBe(5);});test('应该重置计数', () => {const { result } = renderHook(() => useCounter(10));act(() => {result.current.increment();result.current.reset();});expect(result.current.count).toBe(10);});test('当步长变化时应该更新递增/递减行为', () => {const { result, rerender } = renderHook(({ initialValue, step }) => useCounter(initialValue, step),{ initialProps: { initialValue: 0, step: 1 } });act(() => {result.current.increment();});expect(result.current.count).toBe(1);// 更新 step 参数rerender({ initialValue: 0, step: 3 });act(() => {result.current.increment();});expect(result.current.count).toBe(4); // 1 + 3});
});

实际项目应用

在实际项目中应用自定义 Hook 时,应采取以下建议:

  1. 职责单一:每个 Hook 应专注于单一功能,避免过度复杂
  2. 明确的命名:使用描述性的名称清晰表达 Hook 的用途
  3. 文档完善:为每个 Hook 编写详细文档,包括参数、返回值和使用示例
  4. 版本控制:随着 API 的演进,保持版本兼容性并提供迁移路径
  5. 优先考虑性能:使用 useCallback、useMemo 优化 Hook 内部逻辑

结语

自定义 Hook 是 React 应用开发中强大的抽象工具,能够显著提升代码复用性和可维护性。

未来,随着 React 生态的不断发展,自定义 Hook 的设计模式也将继续演进。保持学习新的模式和技术,才能帮助我们在前端开发领域保持竞争力。

参考资源

官方文档

  • React 官方文档 - Hooks 介绍
  • React 官方文档 - 自定义 Hook
  • React API 参考 - Hooks

技术博客和文章

  • Dan Abramov: Making Sense of React Hooks
  • Kent C. Dodds: The State Reducer Pattern with React Hooks
  • Robin Wieruch: React Hooks Tutorial
  • Tanner Linsley: React Query - 重新思考数据获取的自定义 Hook

测试资源

  • React Testing Library 官方文档
  • Testing React Hooks
  • @testing-library/react-hooks 使用指南

社区讨论

  • React Hooks RFC 讨论
  • StackOverflow: React Hooks 问答
  • React Subreddit

高级模式和实践

  • React Patterns: 组合与自定义 Hooks
  • React Recipes: 常用自定义 Hook 实现
  • Josh W. Comeau: 使用 useSound Hook 增强用户体验

如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

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

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

相关文章

锂电电动扭剪扳手市场报告:现状、趋势与竞争格局深度解析

一、锂电电动扭剪扳手市场概述 锂电电动扭剪扳手作为建筑施工、钢结构安装等领域的关键工具&#xff0c;凭借其便携性、高效性及环保特性&#xff0c;正逐步替代传统手动及气动工具。该设备通过锂电池供电&#xff0c;结合智能扭矩控制技术&#xff0c;可精准完成高强度螺栓的…

[面试精选] 0076. 最小覆盖子串

文章目录 1. 题目链接2. 题目描述3. 题目示例4. 解题思路5. 题解代码6. 复杂度分析 1. 题目链接 76. 最小覆盖子串 - 力扣&#xff08;LeetCode&#xff09; 2. 题目描述 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字…

rabbitmq的高级特性

一.发送者的可靠性 1.生产者重试机制 修改publisher模块的application.yaml文件 spring:rabbitmq:connection-timeout: 1s # 设置MQ的连接超时时间template:retry:enabled: true # 开启超时重试机制initial-interval: 1000ms # 失败后的初始等待时间multiplier: 1 # 失败后下…

北京大学肖臻老师《区块链技术与应用》公开课:02-BTC-密码学原理

文章目录 1.比特币中用到的密码学的功能2. hash3. 签名 1.比特币中用到的密码学的功能 比特币中用到密码学中两个功能&#xff1a; hash、 签名。 2. hash hash函数的三个特性&#xff1a;抗碰撞性&#xff08;Collision Resistance&#xff09;、隐蔽性&#xff08;Hiding&…

Spring Cloud Gateway高并发限流——基于Redis实现方案解析

本文是一个基于 Spring Cloud Gateway 的分布式限流方案&#xff0c;使用Redis Lua实现高并发场景下的精准流量控制。该方案支持动态配置、多维度限流&#xff08;API路径/IP/用户&#xff09;&#xff0c;并包含完整的代码实现和性能优化建议。 一、架构设计 #mermaid-svg-vg…

SpringAI--RAG知识库

SpringAI–RAG知识库 RAG概念 什么是RAG&#xff1f; RAG(Retrieval-Augmented Genreation&#xff0c;检索增强生成)是一种结合信息检索技术和AI内容生成的混合架构&#xff0c;可以解决大模型的知识时效性限制和幻觉问题。 RAG在大语言模型生成回答之前&#xff0c;会先从…

【PhysUnits】14 二进制数的标准化表示(standardization.rs)

一、源码 这段代码主要用于处理二进制数的标准化表示。它定义了两个特质(trait) IfB0 和 IfB1&#xff0c;以及它们的实现&#xff0c;用于处理二进制数的前导零及前导一的简化。 use super::basic::{B0, B1, Z0, N1, Integer, NonZero, NonNegOne};/// 处理 B0<H> 类型…

将 ubutun 的网络模式 从NAT 改到 桥接模式后,无法上网,linux 没有IP地址 的解决方案

首先要将 ubutun 的网络模式设置为桥接模式 这里再从 NAT 模式改动成 桥接模式的时候&#xff0c;还出现了一个问题。改成桥接模式后&#xff0c;linux没有ip地址了。原因是 不知道什么时候 将 虚拟网络编辑器 中的值改动了 要选择这个 自动 选项

多模态大语言模型arxiv论文略读(九十)

Hybrid RAG-empowered Multi-modal LLM for Secure Data Management in Internet of Medical Things: A Diffusion-based Contract Approach ➡️ 论文标题&#xff1a;Hybrid RAG-empowered Multi-modal LLM for Secure Data Management in Internet of Medical Things: A Di…

电脑主板VGA长亮白灯

电脑主板VGA长亮白灯 起因解决方法注意事项&#xff1a; 起因 搬家没有拆机整机在车上晃荡导致显卡松动接触不良&#xff08;一般VGA长亮白灯都和显卡有关&#xff0c;主要排查显卡&#xff09; 解决方法 将显卡拆下重新安装即可 注意事项&#xff1a; 不可直接拔下显卡&a…

【监控】pushgateway中间服务组件

Pushgateway 是 Prometheus 生态中的一个中间服务组件&#xff0c;以独立工具形式存在&#xff0c;主要用于解决 Prometheus 无法直接获取监控指标的场景&#xff0c;弥补其定时拉取&#xff08;pull&#xff09;模式的不足。 其用途如下&#xff1a; 突破网络限制&#xff1…

打造AI智能旅行规划器:基于LLM和Crew AI的Agent实践

引言 今天来学习大佬开发的一个AI驱动的旅行规划应用程序&#xff0c;它能够自动处理旅行规划的复杂性——寻jni找航班、预订酒店以及优化行程。传统上&#xff0c;这个过程需要手动搜索多个平台&#xff0c;常常导致决策效率低下。 通过利用**代理型人工智能&#xff08;Age…

21. 自动化测试框架开发之Excel配置文件的测试用例改造

21. 自动化测试框架开发之Excel配置文件的测试用例改造 一、测试框架核心架构 1.1 组件依赖关系 # 核心库依赖 import unittest # 单元测试框架 import paramunittest # 参数化测试扩展 from chap3.po import * # 页面对象模型 from file_reader import E…

如何在电力系统中配置和管理SNTP时间同步?

在电力系统中配置和管理 SNTP 时间同步需结合行业标准&#xff08;如《DL/T 1100.1-2019》&#xff09;和分层架构特点&#xff0c;确保安全性、可靠性和精度适配。以下是具体操作指南&#xff0c;涵盖架构设计、设备配置、安全管理、运维监控四大核心环节&#xff0c;并附典型…

MTK-关于HW WCN的知识讲解

前言: 最近做项目过程中和硬件打交道比较多,现在关于整理下硬件的HW wcn的知识点 一 MTK常见的MT6631 Wi-Fi 2.4GHz 匹配调谐指南 ‌拓扑结构选择‌ 推荐采用并联电容拓扑(‌shunt cap topology‌)代替并联电感拓扑(‌shunt inductor topology‌),以减少潜在电路设计…

(1)课堂 1--5,这五节主要讲解 mysql 的概念,定义,下载安装与卸载

&#xff08;1&#xff09;谢谢老师&#xff1a; &#xff08;2&#xff09;安装 mysql &#xff1a; &#xff08;3&#xff09;镜像下载 &#xff0c;这个网址很好 &#xff1a; &#xff08;4&#xff09; 另一个虚拟机的是 zhang 123456 &#xff1a; 接着配置…

U-Boot ARMv8 平台异常处理机制解析

入口点&#xff1a;arch/arm/cpu/armv8/start.S 1. 判断是否定义了钩子&#xff0c;如有则执行&#xff0c;否则往下走。执行save_boot_params&#xff0c;本质就是保存一些寄存器的值。 2. 对齐修复位置无关码的偏移 假设U-Boot链接时基址为0x10000&#xff0c;但实际加载到0…

mysql安装教程--笔记

一、Windows 系统安装 方法1&#xff1a;使用 MySQL Installer&#xff08;推荐&#xff09; 1. 下载安装包 访问 MySQL 官网下载页面&#xff0c;选择 MySQL Installer for Windows。 2. 运行安装程序 双击下载的 .msi 文件&#xff0c;选择安装类型&#xff1a; ◦ Developer…

投资策略规划最优决策分析

目录 一、投资策略规划问题详细 二、存在最优投资策略&#xff1a;每年都将所有钱投入到单一投资产品中 &#xff08;一&#xff09;状态转移方程 &#xff08;二&#xff09;初始条件与最优策略 &#xff08;三&#xff09;证明最优策略总是将所有钱投入到单一投资产品中…

NGINX HTTP/3 实验指南安装、配置与调优

一、HTTP/3 简介 基于 QUIC&#xff1a;在 UDP 之上实现的多路复用传输&#xff0c;内置拥塞控制与前向纠错&#xff0c;无需三次握手即可恢复连接。零 RTT 重连&#xff1a;借助 TLS 1.3&#xff0c;实现连接恢复时的 0-RTT 数据发送&#xff08;视底层库支持&#xff09;。多…