项目实战 -- 状态管理

redux基础

还记得好久好久之前就想要实现的一个功能吗?

收起侧边栏折叠菜单,没错,现在才实现

因为不是父子通信,所以处理起来相对麻烦一点

可以使用状态树或者中间人模式

这就需要会redux了

Redux工作流:

异步就是比同步多一个中间件

使用它有三大原则:

1.单一数据源

2.State是只读的

3.使用纯函数执行修改

首先安装一下

 npm i --save redux react-redux

创建store

创建一个纯函数:CollApsedReducer

// 纯函数
export const CollApsedReducer = (prevState={isCollapsed:false
},action)=>{return prevState
}
//导入antd
import { Layout, theme, Button,Menu } from 'antd'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import React, { useState } from 'react'
import { changeConfirmLocale } from 'antd/es/modal/locale'
import { Dropdown, Space } from 'antd'
import { DownOutlined, SmileOutlined } from '@ant-design/icons'
import { Avatar } from 'antd'
import { UserOutlined } from '@ant-design/icons'
import { useNavigate } from 'react-router-dom'
import { connect } from 'react-redux'//从Layout组件中解构Header组件
const { Header } = Layout
function TopHeader(props) {console.log(props)//v6的写法
const navigate = useNavigate()const [collapsed, setCollapsed] = useState(false)//定义changeCollapsed函数,用于展开/收起侧边栏,通过取反实现const changeCollapsed = () => {setCollapsed(!collapsed)}const { token } = theme.useToken() // 获取主题 tokenconst { colorBgContainer, borderRadiusLG } = token//使用户名动态渲染// const {role:{roleName},username} = JSON.parse(localStorage.getItem('token'))//使用户名动态渲染const {role:{roleName},username} = JSON.parse(localStorage.getItem('token')) || {}; // 确保 tokenData 是一个对象 const items = [{key: '1',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.antgroup.com">帮{roleName}做模电实验</a>),},{key: '2',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.aliyun.com">帮{roleName}上电磁场课</a>),},{key: '3',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.luohanacademy.com">帮{roleName}辅助面试</a>),},{key: '4',danger: true,label: '要退出吗',onClick: () => {localStorage.removeItem('token')//使用navigate实现重定向navigate('/login')},},]return (<Headerstyle={{padding: '0 16px',background: colorBgContainer,}}><div style={{ float: 'right' }}>{/* 定义欢迎语 */}<span>欢迎<span style={{color:'blue'}}>{username}</span>回来</span>{/* 定义下拉菜单 */}<Dropdownmenu={{items,}}placement="bottomLeft"arrow><Space size={16} wrap><Avatar src={'/头像.jpg'} /></Space>{/* <Button>🥺</Button> */}</Dropdown><Dropdownmenu={{items,}}placement="bottom"arrow></Dropdown></div><Buttontype="text"//展开/收起侧边栏,绑定onClick事件icon={collapsed ? (<MenuUnfoldOutlined onClick={changeCollapsed} />) : (<MenuFoldOutlined onClick={changeCollapsed} />)}onClick={() => setCollapsed(!collapsed)}style={{fontSize: '16px',width: 64,height: 64,}}/></Header>)
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>{return{isCollapsed}
}export default connect(mapStateToProps)(TopHeader)

在这里取出状态

App.jsx:

import { RouterProvider} from 'react-router-dom';
import router from './router/indexRouter';
import './App.css'
import { Provider } from 'react-redux';
import store from './redux/store';function App() {return <Provider store={store}><RouterProvider router={router} />;</Provider>
}export default App;

store.jsx:

import {createStore,combineReducers} from 'redux'
import { CollApsedReducer } from './reducers/CollapsedReducer'const reducer = combineReducers({CollApsedReducer
})
const store = createStore(reducer)export default store

不过现在的createStore已经弃用了

折叠侧边栏

首先开局的时候科文老师的写法就已经弃用了,问了鸡皮替

createStore 已经被官方标记为不推荐使用,在新版 Redux 中推荐使用的是 configureStore 来自 Redux Toolkit(RTK)

先要安装一下:

npm install @reduxjs/toolkit react-redux

对store.jsx进行重写:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'  const store = configureStore({reducer: {CollApsedReducer, // 自动组合多个 reducer},
})export default store

reducer(进行redux state的设计,维护了一个布尔值isCollapsed,reducer函数是纯函数可以根据传入的旧的state和action返回新的state,redux会自动把dispatch的action扔进这个函数里):

const initialState = {isCollapsed: false,
}export default function CollApsedReducer(state = initialState, action) {console.log('CollApsedReducer收到 action:', action)switch (action.type) {case 'change_collapsed':return {...state,isCollapsed: !state.isCollapsed,}default:return state}
}

侧边栏:

import React, { useState, useEffect } from'react';
import { Layout, Menu } from 'antd';
import { useNavigate } from'react-router-dom';
import axios from 'axios';
import {UserOutlined,SettingOutlined,UploadOutlined,VideoCameraOutlined,AuditOutlined,FormOutlined,HomeOutlined,
} from '@ant-design/icons';
import { connect } from 'react-redux';
import './index.css';
import { useLocation } from'react-router-dom';const { SubMenu } = Menu;
const { Sider } = Layout;// **手动映射菜单项对应的图标**
const iconMap = {首页: <HomeOutlined />,用户管理: <UserOutlined />,用户列表: <UserOutlined />,权限管理: <SettingOutlined />,新闻管理: <FormOutlined />,审核管理: <AuditOutlined />,发布管理: <UploadOutlined />,
};function SideMenu(props) {const [menu, setMenu] = useState([]);const location = useLocation(); // 获取当前的路径useEffect(() => {axios.get('http://localhost:3000/rights?_embed=children').then((res) => {setMenu(res.data);}).catch((error) => {console.error('获取菜单数据失败:', error);// 可根据情况设置默认菜单数据或提示用户});
}, []);const navigate = useNavigate();const tokenData = JSON.parse(localStorage.getItem('token')) || {};
const { role = {} } = tokenData;
let allRights = [];// 兼容数组结构(普通角色)和对象结构(超级管理员)
if (Array.isArray(role.rights)) {allRights = role.rights;
} else if (typeof role.rights === 'object' && role.rights !== null) {const { checked = [], halfChecked = [] } = role.rights;allRights = [...checked, ...halfChecked];
}const checkPermission = (item) => {// 检查用户是否具有访问权限return item.pagepermisson && allRights.includes(item.key);};const renderMenu = (menuList) => {return menuList.map((item) => {const icon = iconMap[item.title] || <VideoCameraOutlined />; // 默认图标if (item.children?.length > 0 && checkPermission(item)) {return (<SubMenu key={item.key} icon={icon} title={item.title}>{renderMenu(item.children)}</SubMenu>);}return (checkPermission(item) && (<Menu.Itemkey={item.key}icon={icon}onClick={() => navigate(item.key)}>{item.title}</Menu.Item>));});};//找到路径const selectKeys = [location.pathname];//分割字符串const openKeys = ['/' + location.pathname.split('/')[1]];return (<Sider trigger={null} collapsible collapsed={props.isCollapsed}><div style={{ display: 'flex', height: '100%', flexDirection: 'column' }}><div className="logo">新闻发布系统</div><div style={{ flex: 1, overflow: 'auto' }}><Menutheme="dark"mode="inline"selectedKeys={selectKeys}defaultOpenKeys={openKeys}>{renderMenu(menu)}</Menu></div></div></Sider>);
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>({isCollapsed})export default connect(mapStateToProps)(SideMenu);
//导入antd
import { Layout, theme, Button,Menu } from 'antd'
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'
import React, { useState } from 'react'
import { changeConfirmLocale } from 'antd/es/modal/locale'
import { Dropdown, Space } from 'antd'
import { DownOutlined, SmileOutlined } from '@ant-design/icons'
import { Avatar } from 'antd'
import { UserOutlined } from '@ant-design/icons'
import { useNavigate } from 'react-router-dom'
import { connect } from 'react-redux'//从Layout组件中解构Header组件
const { Header } = Layout
function TopHeader(props) {console.log(props)//v6的写法
const navigate = useNavigate()const [collapsed, setCollapsed] = useState(false)//定义changeCollapsed函数,用于展开/收起侧边栏,通过取反实现const changeCollapsed = () => {// 改变state的isCollapsed的值// setCollapsed(!collapsed)// console.log(props)props.changeCollapsed()}const { token } = theme.useToken() // 获取主题 tokenconst { colorBgContainer, borderRadiusLG } = token//使用户名动态渲染// const {role:{roleName},username} = JSON.parse(localStorage.getItem('token'))//使用户名动态渲染const {role:{roleName},username} = JSON.parse(localStorage.getItem('token')) || {}; // 确保 tokenData 是一个对象 const items = [{key: '1',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.antgroup.com">帮{roleName}做模电实验</a>),},{key: '2',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.aliyun.com">帮{roleName}上电磁场课</a>),},{key: '3',label: (<atarget="_blank"rel="noopener noreferrer"href="https://www.luohanacademy.com">帮{roleName}辅助面试</a>),},{key: '4',danger: true,label: '要退出吗',onClick: () => {localStorage.removeItem('token')//使用navigate实现重定向navigate('/login')},},]return (<Headerstyle={{padding: '0 16px',background: colorBgContainer,}}><div style={{ float: 'right' }}>{/* 定义欢迎语 */}<span>欢迎<span style={{color:'blue'}}>{username}</span>回来</span>{/* 定义下拉菜单 */}<Dropdownmenu={{items,}}placement="bottomLeft"arrow><Space size={16} wrap><Avatar src={'/头像.jpg'} /></Space>{/* <Button>🥺</Button> */}</Dropdown><Dropdownmenu={{items,}}placement="bottom"arrow></Dropdown></div><Buttontype="text"//展开/收起侧边栏,绑定onClick事件icon={props.isCollapsed ? (<MenuUnfoldOutlined onClick={changeCollapsed} />) : (<MenuFoldOutlined onClick={changeCollapsed} />)}onClick={() => setCollapsed(!collapsed)}style={{fontSize: '16px',width: 64,height: 64,}}/></Header>)
}const mapStateToProps = ({CollApsedReducer:{isCollapsed}})=>{return{isCollapsed}
}const mapDispatchToProps ={changeCollapsed(){return{type:"change_collapsed"}}
}export default connect(mapStateToProps,mapDispatchToProps)(TopHeader)

在App.jsx中还要包一下

import { RouterProvider} from 'react-router-dom';
import router from './router/indexRouter';
import './App.css'
import { Provider } from 'react-redux';
import store from './redux/store';function App() {return <Provider store={store}><RouterProvider router={router} />;</Provider>
}export default App;

 使用 connect() 获取 Redux 中的 isCollapsed 状态

使用Redux管控侧边栏状态的意义: 

 loading加载

现在想给程序加上一个加载的效果做指引

加载中 Spin - Ant Designhttps://ant-design.antgroup.com/components/spin-cn这个的使用就是在数据请求的外面包上loading就好了

这个效果应该是让数据请求到了就消失

使用一下拦截器捏!

axios/axios: Promise based HTTP client for the browser and node.jshttps://github.com/axios/axios?tab=readme-ov-file#interceptors

 http.jsx:

import axios from "axios";
import store from "../redux/store";
// 对axios做全局配置
axios.defaults.baseURL = "http://localhost:300"// const instance = axios.create();// Add a request interceptor
axios.interceptors.request.use(function (config) {// Do something before request is sent// 显示loadingstore.dispatch({type:"change_loading",payload:true})return config;}, function (error) {// Do something with request errorreturn Promise.reject(error);});// Add a response interceptor
axios.interceptors.response.use(function (response) {// Any status code that lie within the range of 2xx cause this function to trigger// Do something with response data// 隐藏loadingstore.dispatch({type:"change_loading",payload:false})return response;}, function (error) {store.dispatch({type:"change_loading",payload:false})// Any status codes that falls outside the range of 2xx cause this function to trigger// Do something with response errorreturn Promise.reject(error);});

store.jsx:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'
import LoadingReducer from './reducers/LoadingReducer'const store = configureStore({reducer: {CollApsedReducer, // 自动组合多个 reducerLoadingReducer},
})export default store

Loading.jsx:

const initialState = {isLoading: false,}export default function LoadingReducer(state = initialState, action) {//   console.log('CollApsedReducer收到 action:', action)let {type,payload} = actionswitch (action.type) {case 'change_loading':return {...state,isLoading: payload}default:return state}}

 NewsRouter.jsx:

import SideMenu from "../../components/sandbox/sidemenu";
import TopHeader from '../../components/sandbox/TopHeader'
import { Routes, Route } from'react-router-dom'
import Home from '../../views/sandbox/home/Home'
import RightList from '../../views/sandbox/right-manage/RightList'
import UserList from '../../views/sandbox/user-manage/UserList'
import RoleList from '../../views/sandbox/right-manage/RoleList'
import { Navigate } from'react-router-dom'
import Nopermission from '../../views/sandbox/nopermission/Nopermission'
//引入antd
import { theme, Layout, ConfigProvider, Spin } from 'antd'
import NewsAdd from '../../views/sandbox/news-manage/NewsAdd'
import NewsDraft from '../../views/sandbox/news-manage/NewsDraft'
import NewsCategory from '../../views/sandbox/news-manage/NewsCategory'
import Audit from '../../views/sandbox/audit-manage/Audit'
import AuditList from '../../views/sandbox/audit-manage/AuditList'
import Published from '../../views/sandbox/publish-manage/Published'
import Unpublished from '../../views/sandbox/publish-manage/Unpublished'
import Sunset from '../../views/sandbox/publish-manage/Sunset'
import NewsUpdate from '../../views/sandbox/news-manage/NewsUpdate'
import NewsPreview from '../../views/sandbox/news-manage/NewsPreview'
import { useEffect, useState } from'react'
import axios from 'axios'
import { connect } from "react-redux";//创建一个本地的路由映射表
const LocalRouterMap = {'/home': Home,'/user-manage/list': UserList,'/right-manage/right/list': RightList,'/right-manage/role/list': RoleList,//写什么新闻列表啊,各种权限啊'/news-manage/add': NewsAdd,'/news-manage/draft': NewsDraft,'/news-manage/category': NewsCategory,'/news-manage/preview/:id':NewsPreview,'/news-manage/update/:id':NewsUpdate,'/audit-manage/audit': Audit,'/audit-manage/list': AuditList,'/publish-manage/published': Published,'/publish-manage/unpublished': Unpublished,'/publish-manage/sunset': Sunset,
}function NewsRouter(props) {// 后端返回的路由映射表const [BackRouteList, setBackRouteList] = useState([])useEffect(() => {Promise.all([axios.get('http://localhost:3000/rights'),axios.get('http://localhost:3000/children'),]).then((res) => {setBackRouteList([...res[0].data, ...res[1].data])})}, [])const tokenData = JSON.parse(localStorage.getItem('token')) || {}; // 确保 tokenData 是一个对象const { role = {} } = tokenData; // 确保 role 是一个对象let rights = []; // 初始化 rights 为一个空数组if (role.rights) {if (Array.isArray(role.rights)) {rights = role.rights;} else if (typeof role.rights === 'object') {// 如果 rights 是对象,提取 checked 和 halfChecked 数组并合并rights = [...(role.rights.checked || []), ...(role.rights.halfChecked || [])];}}// console.log(rights)const checkRoute = (item) => {return LocalRouterMap[item.key] && (item.pagepermisson || item.routepermisson)}const checkUserPermisson = (item) => {const hasPermission = rights.includes(item.key);return hasPermission; }return (<Spin size="large" spinning={props.isLoading}><Routes>{/* 动态渲染路由 */}{BackRouteList.map((item) => {const Component = LocalRouterMap[item.key]// console.log(item.key)if (checkRoute(item) && checkUserPermisson(item)) {return (Component && (<Route path={item.key} key={item.key} element={<Component />} />))}return null})}{/* 首页重定向 */}<Route path="/" element={<Navigate to="/home" />} />{/* 权限不足页面 */}{BackRouteList.length > 0 && (<Route path="*" element={<Nopermission />} />)}</Routes></Spin>)
}const mapStateToProps = ({LoadingReducer:{isLoading}})=>({isLoading
})export default connect(mapStateToProps)(NewsRouter)

这样就实现了一闪而过的加载效果勒 

持久化

本来我们设置了侧边栏,比如我们把侧边栏收起,但是一刷新就会被打回原形,这就涉及到了持久化的概念

我们应该让redux持久化的存储在系统中捏

redux持久化的工具:

rt2zz/redux-persist: persist and rehydrate a redux storehttps://github.com/rt2zz/redux-persist进行数据持久化的操作:

import { configureStore } from '@reduxjs/toolkit'
import CollApsedReducer from './reducers/CollapsedReducer'
import LoadingReducer from './reducers/LoadingReducer'import { combineReducers} from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for webconst persistConfig = {key: 'root',storage: storage,blacklist: ['LoadingReducer']//放在黑名单中的数据不会被持久化
}const reducer = combineReducers({CollApsedReducer,LoadingReducer
})const persistedReducer = persistReducer(persistConfig, reducer)const store = configureStore({reducer:persistedReducer
})
const persistor = persistStore(store)export {store,persistor}

持久化有黑名单白名单的机制,放在黑名单的数据就不会被持久化了

持久化数据的逻辑是,配置redux-persist 的规则,然后进行把两个小模块的状态进行合并,最后使用persistReducer包装(persistReducer会根据persistConfig给reducer加上存到localStorage的能力)然后是创建store

最后创建persistor,负责在应用初始化的时候把localStorage里面的数据还原到Redux store中

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

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

相关文章

Go语言之路————指针、结构体、方法

Go语言之路————指针、结构体、方法 前言指针结构体声明初始化使用组合引用结构体和指针结构体的标签 方法例子结合结构体总结 前言 我是一名多年Java开发人员&#xff0c;因为工作需要现在要学习go语言&#xff0c;Go语言之路是一个系列&#xff0c;记录着我从0开始接触Go…

[创业之路-390]:人力资源 - 社会性生命系统的解构与重构:人的角色嬗变与组织进化论

前言&#xff1a; 人、财、物、信息、机制、流程、制度、方法共同组合了一个持续的消耗资源、持续的价值创造、持续面临生存与发展、遗传与变异的社会性生命系统。 "人"是所有社会性生命系统最最基础性的要素&#xff0c;它弥漫在系统中多维立体空间的不同节点上&am…

JS执行器在UI自动化测试中的应用

前言 在进行UI自动化过程会遇到滚动条下拉、隐藏元素定位、只读属性元素的编辑、富文本处理等&#xff0c;此时可以使用JS执行器简化我们的一些处理操作。 具体应用 JS执行器的使用步骤&#xff1a; 1.先写个JS脚本&#xff0c;如果需要获取操作后的值&#xff0c;JS脚本前面…

解析Suna:全球首款开源通用AI智能体

导语&#xff1a; 嘿&#xff0c;哥们儿&#xff0c;最近 AI Agent 这块儿挺火的&#xff0c;有个叫 Suna 的开源项目冒出来挺快&#xff01;听说只用了 3 周就开发出来了&#xff0c;但功能上感觉已经能跟那个商业版的 Manus掰掰手腕了。它能帮你搞定浏览器自动化、管文件、爬…

模板方法模式:定义算法骨架的设计模式

模板方法模式&#xff1a;定义算法骨架的设计模式 一、模式核心&#xff1a;模板方法定义算法骨架&#xff0c;具体步骤延迟到子类实现 在软件开发中&#xff0c;经常会遇到这样的情况&#xff1a;某个算法的步骤是固定的&#xff0c;但具体步骤的实现可能因不同情况而有所不…

浅谈Java 内存管理:栈与堆,垃圾回收

在Java编程世界里&#xff0c;内存管理是一项极为关键的技能&#xff0c;它就像程序运行背后的“隐形守护者”&#xff0c;默默影响着程序的性能与稳定性。今天&#xff0c;咱们就来简单学习一下Java内存管理中的两大核心要点&#xff1a;栈与堆的内存分配机制&#xff0c;以及…

【WebGL小知识】WebGL平台上不同Json的比较

今天来总结一下WebGL平台上不同Json插件的差别&#xff0c;话不多说直接开始。 JsonUtility JsonUtility是Unity自带的Json解析&#xff0c;无需另外安装插件。 优点&#xff1a; Unity自带&#xff0c;兼容性好&#xff0c;WebGL平台可以使用轻量级&#xff0c;性能较好。 …

4.22tx视频后台开发一面

总时长大概在一个小时&#xff0c;主要提问C、操作系统、计网以及数据库等方面&#xff0c;最后两个算法编程题。 一上来先介绍项目 Linux下的mybash命令处理器和内存池 mybash可以再总结归纳一下&#xff0c;一上来有点紧张没有条理 内存池是用边界标识法写的&#xff0c;…

从StandardMaterial和PBRMaterial到PBRMetallicRoughnessMaterial:Babylon.js材质转换完全指南

在现代3D图形开发中&#xff0c;基于物理的渲染(PBR)已成为行业标准。本文将深入探讨如何在Babylon.js中将传统StandardMaterial和PBRMaterial转换为PBRMetallicRoughnessMaterial&#xff0c;并保持视觉一致性。 为什么需要转换&#xff1f; PBRMetallicRoughnessMaterial作…

UEditor文档在Servlet项目上的应用

UEditor 是一款功能强大的富文本编辑器&#xff0c;在项目中应用广泛。 Ueditor使用 引入 UEditor 下载 UEditor&#xff1a;从 UEditor 官方网站&#xff08;ueditor 官网&#xff09;下载适合项目需求的版本。解压文件&#xff1a;将下载的压缩包解压到项目的静态资源目录…

ThinkPHP快速使用手册

目录 介绍 安装&#xff08;windows环境&#xff09; 安装Composer 安装ThinkPHP 目录结构 配置文件 第一个接口&#xff08;Controller层&#xff09; Hello World 自定义Controller 请求参数 获取查询参数&#xff08;Get请求&#xff09; 获取指定请求参数 获取…

面向 C# 初学者的完整教程

&#x1f9f1; 一、项目结构说明 你的项目大致结构如下&#xff1a; TaskManager/ ├── backend/ │ ├── TaskManager.Core/ // 实体类和接口 │ ├── TaskManager.Infrastructure/ // 数据库、服务实现 │ └── TaskManager.API/ // We…

Axios 的 GET 和 POST 请求:前端开发中的 HTTP 通信

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

【前端】如何检查内存泄漏

在实际的场景中&#xff0c;如果观察到内存持续出现峰值&#xff0c;并且内存消耗一直没有减少&#xff0c;那可能存在内存泄漏。 使用 Chrome DevTools 来识别内存图和一些内存泄漏&#xff0c;我们需要关注以下两个方面&#xff1a; ● 使用性能分析器可视化内存消耗&#xf…

JavaScript的JSON处理Map的弊端

直接使用 Map 会遇到的问题及解决方案 直接使用 Map 会导致数据丢失&#xff0c;因为 JSON.stringify 无法序列化 Map。以下是详细分析及解决方法&#xff1a; 问题复现 // 示例代码 const myMap new Map(); myMap.set(user1, { name: Alice }); myMap.set(user2, { name: B…

【数据结构】第五弹——Stack 和 Queue

文章目录 一. 栈(Stack)1.1 概念1.2 栈的使用1.3 栈的模拟实现1.3.1 顺序表结构1.3.2 进栈 压栈1.3.3 删除栈顶元素1.3.4 获取栈顶元素1.3.5 自定义异常 1.4 栈的应用场景1.改变元素序列2. 将递归转化为循环3. 四道习题 1.5 概念分区 二. 队列(Queue)2.1 概念2.2 队列的使用2.3…

第七届能源系统与电气电力国际学术会议(ICESEP 2025)

重要信息 时间&#xff1a;2025年6月20-22日 地点&#xff1a;中国-武汉 官网&#xff1a;www.icesep.net 主题 能源系统 节能技术、能源存储技术、可再生能源、热能与动力工程 、能源工程、可再生能源技术和系统、风力发…

深入解析C++ STL Stack:后进先出的数据结构

一、引言 在计算机科学中&#xff0c;栈&#xff08;Stack&#xff09;作为一种遵循后进先出&#xff08;LIFO&#xff09;​原则的数据结构&#xff0c;是算法设计和程序开发的基础构件。C STL中的stack容器适配器以简洁的接口封装了底层容器的操作&#xff0c;为开发者提供了…

Golang | 自行实现并发安全的Map

核心思路&#xff0c;读写map之前加锁&#xff01;哈希思路&#xff0c;大map化分为很多个小map

Mac 「brew」快速安装MySQL

安装MySQL 在 macOS 上安装 MySQL 环境可以通过Homebrew快速实现&#xff0c;以下是步骤指南&#xff1a; 方法 1&#xff1a;使用 Homebrew 安装 MySQL 1. 安装 Homebrew 如果尚未安装 Homebrew&#xff0c;可以通过以下命令安装&#xff1a; /bin/bash -c "$(curl -…