java-数据结构与算法-02-数据结构-05-栈
文章目录
- 1. 栈
- 1. 概述
- 2. 链表实现
- 3. 数组实现
- 4. 应用
- 2. 习题
- E01. 有效的括号-Leetcode 20
- E02. 后缀表达式求值-Leetcode 120
- E03. 中缀表达式转后缀
- E04. 双栈模拟队列-Leetcode 232
- E05. 单队列模拟栈-Leetcode 225
1. 栈
1. 概述
计算机科学中,stack 是一种线性的数据结构,只能在其一端添加数据和移除数据。习惯来说,这一端称之为栈顶,另一端不能操作数据的称之为栈底,就如同生活中的一摞书
栈是一种特殊的线性表,只能在一端进行操作
- 往栈中添加元素的操作,一般叫做 push,入栈
- 从栈中移除元素的操作,一般叫做 pop,出栈(只能移除栈顶元素,也叫做:弹出栈顶元素)
- 后进先出的原则,Last In First Out,LIFO
先提供一个栈接口
public interface Stack<E> {/*** 向栈顶压入元素* @param value 待压入值* @return 压入成功返回 true, 否则返回 false*/boolean push(E value);/*** 从栈顶弹出元素* @return 栈非空返回栈顶元素, 栈为空返回 null*/E pop();/*** 返回栈顶元素, 不弹出* @return 栈非空返回栈顶元素, 栈为空返回 null*/E peek();/*** 判断栈是否为空* @return 空返回 true, 否则返回 false*/boolean isEmpty();/*** 判断栈是否已满* @return 满返回 true, 否则返回 false*/boolean isFull();
}
栈的应用
浏览器的前进和后退
2. 链表实现
package com.itheima.datastructure.stack;import java.util.Iterator;
import java.util.StringJoiner;/*** 链表实现的栈。* 该类实现了Stack接口和Iterable接口,允许对栈中的元素进行迭代。** @param <E> 栈中元素的类型。*/
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {/*** 栈的容量,默认为Integer.MAX_VALUE,表示不限制容量。*/private int capacity = Integer.MAX_VALUE;/*** 栈中元素的数量。*/private int size;/*** 链表的头节点,用于简化插入和删除操作。*/private final Node<E> head = new Node<>(null, null);/*** 默认构造函数。*/public LinkedListStack() {}/*** 带容量限制的构造函数。** @param capacity 栈的容量限制。*/public LinkedListStack(int capacity) {this.capacity = capacity;}/*** 将元素压入栈顶。** @param value 要压入栈的元素。* @return 如果栈未满,则返回true;否则返回false。*//*head -> 2 -> 1 -> null*/@Overridepublic boolean push(E value) {if (isFull()) {return false;}head.next = new Node<>(value, head.next);size++;return true;}/*** 从栈顶弹出一个元素。** @return 如果栈不为空,则返回栈顶元素;否则返回null。*//*head -> 2 -> 1 -> null*/@Overridepublic E pop() {if (isEmpty()) {return null;}Node<E> first = head.next;head.next = first.next;size--;return first.value;}/*** 查看栈顶元素。** @return 如果栈不为空,则返回栈顶元素;否则返回null。*/@Overridepublic E peek() {if (isEmpty()) {return null;}return head.next.value;}/*** 检查栈是否为空。** @return 如果栈为空,则返回true;否则返回false。*/@Overridepublic boolean isEmpty() {return size == 0;}/*** 检查栈是否已满。** @return 如果栈已满,则返回true;否则返回false。*/@Overridepublic boolean isFull() {return size == capacity;}/*** 创建一个迭代器,用于遍历栈中的元素。** @return栈的元素迭代器。*/@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {Node<E> p = head.next;@Overridepublic boolean hasNext() {return p != null;}@Overridepublic E next() {E value = p.value;p = p.next;return value;}};}/*** 链表节点类,用于存储栈中的元素。** @param <E> 节点中存储的元素类型。*/static class Node<E> {E value;Node<E> next;public Node(E value, Node<E> next) {this.value = value;this.next = next;}}/*** 将栈中的元素转换为字符串表示。** @return 栈的字符串表示,元素之间用逗号分隔。*/@Overridepublic String toString() {StringJoiner sj = new StringJoiner(",");for (E e : this) {sj.add(e.toString());}return sj.toString();}
}
3. 数组实现
/*** 数组实现的栈类,支持泛型元素。* @param <E> 栈中元素的类型。*/
package com.itheima.datastructure.stack;import java.util.Iterator;public class ArrayStack<E> implements Stack<E>, Iterable<E> {/*** 存储栈元素的数组。*/private final E[] array;/*** 栈顶指针,指示当前栈的顶部元素的位置。*/private int top; // 栈顶指针/*** 构造一个指定容量的栈。* @param capacity 栈的初始容量。*/@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}/*** 将元素压入栈顶。* @param value 要压入栈的元素。* @return 如果栈未满,则返回true;否则返回false。*/@Overridepublic boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}/*** 弹出栈顶元素。* @return 栈顶元素,如果栈为空,则返回null。*/@Overridepublic E pop() {if (isEmpty()) {return null;}E e = array[--top];array[top] = null; // help GCreturn e;}/*** 查看栈顶元素。* @return 栈顶元素,如果栈为空,则返回null。*/@Overridepublic E peek() {if (isEmpty()) {return null;}return array[top - 1];}/*** 检查栈是否为空。* @return 如果栈为空,则返回true;否则返回false。*/@Overridepublic boolean isEmpty() {return top == 0;}/*** 检查栈是否已满。* @return 如果栈已满,则返回true;否则返回false。*/@Overridepublic boolean isFull() {return top == array.length;}/*** 返回栈元素的迭代器,用于遍历栈。* @return栈元素的迭代器。*//*底 顶0 1 2 3a b c dp*/@Overridepublic Iterator<E> iterator() {return new Iterator<E>() {int p = top;@Overridepublic boolean hasNext() {return p > 0;}@Overridepublic E next() {return array[--p];}};}
}
4. 应用
模拟如下方法调用
public static void main(String[] args) {System.out.println("main1");System.out.println("main2");method1();method2();System.out.println("main3");
}public static void method1() {System.out.println("method1");method3();
}public static void method2() {System.out.println("method2");
}public static void method3() {System.out.println("method3");
}
模拟代码
package com.itheima.datastructure.stack;/*** CPU模拟类,使用栈来模拟方法的调用与返回。*/
public class CPU {/*** 方法帧类,用于存储方法的退出点。*/static class Frame {int exit;/*** 构造方法,初始化方法帧的退出点。* * @param exit 方法的退出点值。*/public Frame(int exit) {this.exit = exit;}}/*** 程序计数器,用于指示当前执行的指令位置。*/static int pc = 1;/*** 方法调用栈,用于模拟方法的调用与返回过程。*/static ArrayStack<Frame> stack = new ArrayStack<>(100);/*** 程序入口点。* * @param args 命令行参数。*/public static void main(String[] args) {// 初始化方法调用栈,压入一个表示main方法开始的帧stack.push(new Frame(-1));// 当栈不为空时,循环执行指令while (!stack.isEmpty()) {// 根据程序计数器的值执行相应的操作switch (pc) {case 1:// 执行main方法的第一段代码System.out.println("main1");pc++;break;case 2:// 执行main方法的第二段代码System.out.println("main2");pc++;break;case 3:// 调用method1方法stack.push(new Frame(pc + 1));pc = 100;break;case 4:// 调用method2方法stack.push(new Frame(pc + 1));pc = 200;break;case 5:// 方法返回,从栈中弹出方法帧,并跳转到退出点System.out.println("main3");pc = stack.pop().exit;break;case 100:// method1方法的代码段System.out.println("method1");stack.push(new Frame(pc + 1));pc = 300;break;case 101:// method1方法返回pc = stack.pop().exit;break;case 200:// method2方法的代码段System.out.println("method2");pc = stack.pop().exit;break;case 300:// method3方法的代码段System.out.println("method3");pc = stack.pop().exit;break;}}}
}
2. 习题
E01. 有效的括号-Leetcode 20
一个字符串中可能出现 [] () 和 {} 三种括号,判断该括号是否有效
有效的例子
()[]{}([{}])()
无效的例子
[)([)]([]
思路
- 遇到左括号, 把要配对的右括号放入栈顶
- 遇到右括号, 若此时栈为空, 返回 false,否则把它与栈顶元素对比
- 若相等, 栈顶元素弹出, 继续对比下一组
- 若不等, 无效括号直接返回 false
- 循环结束
- 若栈为空, 表示所有括号都配上对, 返回 true
- 若栈不为空, 表示右没配对的括号, 应返回 false
答案(用到了课堂案例中的 ArrayStack 类)
public boolean isValid(String s) {ArrayStack<Character> stack = new ArrayStack<>(s.length() / 2 + 1);for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(')');} else if (c == '[') {stack.push(']');} else if (c == '{') {stack.push('}');} else {if (!stack.isEmpty() && stack.peek() == c) {stack.pop();} else {return false;}}}return stack.isEmpty();
}
E02. 后缀表达式求值-Leetcode 120
后缀表达式也称为逆波兰表达式,即运算符写在后面
- 从左向右进行计算
- 不必考虑运算符优先级,即不用包含括号
示例
输入:tokens = ["2","1","+","3","*"]
输出:9
即:(2 + 1) * 3输入:tokens = ["4","13","5","/","+"]
输出:6
即:4 + (13 / 5)
题目假设
- 数字都视为整数
- 数字和运算符个数给定正确,不会有除零发生
代码
public int evalRPN(String[] tokens) {LinkedList<Integer> numbers = new LinkedList<>();for (String t : tokens) {switch (t) {case "+" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a + b);}case "-" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a - b);}case "*" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a * b);}case "/" -> {Integer b = numbers.pop();Integer a = numbers.pop();numbers.push(a / b);}default -> numbers.push(Integer.parseInt(t));}}return numbers.pop();
}
E03. 中缀表达式转后缀
public class E03InfixToSuffix {/*思路1. 遇到数字, 拼串2. 遇到 + - * /- 优先级高于栈顶运算符 入栈- 否则将栈中高级或平级运算符出栈拼串, 本运算符入栈3. 遍历完成, 栈中剩余运算符出栈拼串- 先出栈,意味着优先运算4. 带 ()- 左括号直接入栈- 右括号要将栈中直至左括号为止的运算符出栈拼串| || || |_____a+ba+b-ca+b*ca*b+c(a+b)*c*/public static void main(String[] args) {System.out.println(infixToSuffix("a+b"));System.out.println(infixToSuffix("a+b-c"));System.out.println(infixToSuffix("a+b*c"));System.out.println(infixToSuffix("a*b-c"));System.out.println(infixToSuffix("(a+b)*c"));System.out.println(infixToSuffix("a+b*c+(d*e+f)*g"));}/*** 将中缀表达式转换为后缀表达式。* 后缀表达式也称为逆波兰表达式,它使用栈的操作来实现运算符的优先级处理,有效地简化了计算过程。* * @param exp 中缀表达式字符串,包含数字、运算符和括号。* @return 后缀表达式字符串。*/static String infixToSuffix(String exp) {// 使用链表作为栈来存储运算符LinkedList<Character> stack = new LinkedList<>();// 使用StringBuilder来构建后缀表达式StringBuilder sb = new StringBuilder(exp.length());// 遍历中缀表达式的每个字符for (int i = 0; i < exp.length(); i++) {char c = exp.charAt(i);// 根据字符的不同类型进行处理switch (c) {case '*', '/', '+', '-' -> {// 处理运算符if (stack.isEmpty()) {stack.push(c);} else {if (priority(c) > priority(stack.peek())) {stack.push(c);} else {// 当当前运算符的优先级不高于栈顶运算符时,将栈顶运算符弹出到后缀表达式中while (!stack.isEmpty() && priority(stack.peek()) >= priority(c)) {sb.append(stack.pop());}stack.push(c);}}}case '(' -> {// 遇到左括号直接入栈stack.push(c);}case ')' -> {// 遇到右括号,将栈中的运算符依次弹出到后缀表达式中,直到遇到左括号while (!stack.isEmpty() && stack.peek() != '(') {sb.append(stack.pop());}// 弹出左括号,不加入到后缀表达式中stack.pop();}default -> {// 遇到数字直接加入到后缀表达式中sb.append(c);}}}// 将栈中剩余的运算符依次弹出到后缀表达式中while (!stack.isEmpty()) {sb.append(stack.pop());}// 返回构建好的后缀表达式return sb.toString();}/*** 计算运算符的优先级。* * @param c 运算符* @return 运算符的优先级* @throws IllegalArgumentException 如果运算符不合法,则抛出此异常*/
static int priority(char c) {// 使用switch表达式来根据运算符的类型返回对应的优先级return switch (c) {case '*' -> 2; // 乘法和除法具有相同的优先级case '/' -> 2;case '+' -> 1; // 加法和减法具有相同的优先级case '-' -> 1;case '(' -> 0; // 左括号具有最低优先级default -> throw new IllegalArgumentException("不合法的运算符:" + c);};
}}
返回结果
ab+c*
abc*+d-e*
abc+*
E04. 双栈模拟队列-Leetcode 232
给力扣题目用的自实现栈,可以定义为静态内部类
class ArrayStack<E> {private E[] array;private int top; // 栈顶指针@SuppressWarnings("all")public ArrayStack(int capacity) {this.array = (E[]) new Object[capacity];}public boolean push(E value) {if (isFull()) {return false;}array[top++] = value;return true;}public E pop() {if (isEmpty()) {return null;}return array[--top];}public E peek() {if (isEmpty()) {return null;}return array[top - 1];}public boolean isEmpty() {return top == 0;}public boolean isFull() {return top == array.length;}
}
参考解答,注意:题目已说明
- 调用 push、pop 等方法的次数最多 100
package com.itheima.datastructure.stack;/*** 双栈模拟队列** <ul>* <li>调用 push、pop 等方法的次数最多 100</li>* </ul>*/
public class E04Leetcode232 {/*队列头 队列尾b顶 底 底 顶s1 s2队列尾添加s2.push(a)s2.push(b)队列头移除先把 s2 的所有元素移动到 s1s1.pop()*/ArrayStack<Integer> s1 = new ArrayStack<>(100);ArrayStack<Integer> s2 = new ArrayStack<>(100);public void push(int x) { //向队列尾添加s2.push(x);}public int pop() { // 从对列头移除if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.pop();}public int peek() { // 从对列头获取if (s1.isEmpty()) {while (!s2.isEmpty()) {s1.push(s2.pop());}}return s1.peek();}public boolean empty() {return s1.isEmpty() && s2.isEmpty();}}
E05. 单队列模拟栈-Leetcode 225
给力扣题目用的自实现队列,可以定义为静态内部类
public class ArrayQueue3<E> {private final E[] array;int head = 0;int tail = 0;@SuppressWarnings("all")public ArrayQueue3(int c) {c -= 1;c |= c >> 1;c |= c >> 2;c |= c >> 4;c |= c >> 8;c |= c >> 16;c += 1;array = (E[]) new Object[c];}public boolean offer(E value) {if (isFull()) {return false;} array[tail & (array.length - 1)] = value;tail++;return true;}public E poll() {if (isEmpty()) {return null;}E value = array[head & (array.length - 1)];head++;return value;}public E peek() {if (isEmpty()) {return null;}return array[head & (array.length - 1)];}public boolean isEmpty() {return head == tail;}public boolean isFull() {return tail - head == array.length;}
}
参考解答,注意:题目已说明
- 调用 push、pop 等方法的次数最多 100
- 每次调用 pop 和 top 都能保证栈不为空
public class E05Leetcode225 {/*队列头 队列尾cba顶 底queue.offer(a)queue.offer(b)queue.offer(c)*/ArrayQueue3<Integer> queue = new ArrayQueue3<>(100);int size = 0;public void push(int x) {queue.offer(x);for (int i = 0; i < size; i++) {queue.offer(queue.poll());}size++;}public int pop() {size--;return queue.poll();}public int top() {return queue.peek();}public boolean empty() {return queue.isEmpty();}
}
相关文章:

java-数据结构与算法-02-数据结构-05-栈
文章目录 1. 栈1. 概述2. 链表实现3. 数组实现4. 应用 2. 习题E01. 有效的括号-Leetcode 20E02. 后缀表达式求值-Leetcode 120E03. 中缀表达式转后缀E04. 双栈模拟队列-Leetcode 232E05. 单队列模拟栈-Leetcode 225 1. 栈 1. 概述 计算机科学中,stack 是一种线性的…...

Python 管理依赖包(pip, virtualenv)
在Python编程中,管理依赖包是开发工作的重要组成部分。正确管理依赖包可以确保代码在不同环境中的一致性和可移植性,避免版本冲突和依赖地狱等问题。Python中常用的依赖包管理工具包括pip和virtualenv。 一、pip pip是Python官方推荐的包管理工具&…...

Bigdecimal 导出为excel时显示未0E-10,不是0,怎么解决
在使用 BigDecimal 导出到 Excel 时,如果遇到显示为 0E-10 而不是 0 的问题,这通常是因为 BigDecimal 对象的精度问题。0E-10 表示的是 0 乘以 10 的 -10 次方,这在数学上等同于…...

springboot项目从jdk8升级为jdk17过程记录
背景:公司有升级项目jdk的规划,计划从jdk8升级到jdk11 开始 首先配置本地的java_home 参考文档:Mac环境下切换JDK版本及不同的maven-CSDN博客 将pom.xml中jdk1.8相关的版本全部改为jdk17,主要是maven编译插件之类的,…...

list、tuple、set和dict传参机制
1、list、tuple、set和dict传参机制 # -------------list------------- def f1(my_list):print(f"②f1()my_list:{my_list} 地址是:{id(my_list)}") # ["tom","mary","hsp"] 0x1122my_list[0]"jack"print(f&quo…...

Redis快速入门基础
Redis入门 Redis是一个基于内存的 key-value 结构数据库。mysql是二维表的接口数据库 优点: 基于内存存储,读写性能高 适合存储热点数据(热点商品、资讯、新闻) 企业应用广泛 官网:https://redis.io 中文网:https://www.redis.net.cn/ Redis下载与…...

python基础介绍
这次的专题是关于python的知识点,加油! 文章目录 1 什么是计算机(1.1 哪些可以称为计算机?(以下)(1.2 计算机可以完成的工作有哪些?(1.3 一台计算机由什么构成? 2. 什么是编程(2.1 编…...

SSRF中伪协议学习
SSRF常用的伪协议 file:// 从文件系统中获取文件内容,如file:///etc/passwd dict:// 字典服务协议,访问字典资源,如 dict:///ip:6739/info: ftp:// 可用于网络端口扫描 sftp:// SSH文件传输协议或安全文件传输协议 ldap://轻量级目录访问协议 tftp:// 简单文件传输协议 gopher…...

Java | Leetcode Java题解之第284题窥视迭代器
题目: 题解: class PeekingIterator<E> implements Iterator<E> {private Iterator<E> iterator;private E nextElement;public PeekingIterator(Iterator<E> iterator) {this.iterator iterator;nextElement iterator.next(…...

哈尔滨等保定级的常见问题
一、哈尔滨等保测评定级标准理解问题 哈尔滨等保测评如何确定信息系统的安全保护等级? 信息系统的安全保护等级应根据其在国家安全、经济建设、社会生活中的重要程度,以及一旦遭到破坏后对国家安全、社会秩序、公共利益以及公民、法人和其他组织的合法权…...

springAOP理解及事务
AOP: springAOP是什么: AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程。 使用场景: 比如你想统计业务中每个方法的执行耗时,那我们最…...

Optional类的使用 java8(附代码)
🍰 个人主页:_小白不加班__ 🍞文章有不合理的地方请各位大佬指正。 🍉文章不定期持续更新,如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️ 文章目录 一、什么是Optional?二、…...

企业利用AI智能名片S2B2C商城小程序参与社区团购的风险与机遇分析
摘要 在新零售浪潮的推动下,社区团购以其独特的商业模式迅速崛起,成为连接消费者与供应商的重要桥梁。企业纷纷探索如何有效利用这一新兴渠道,以扩大市场份额、提升品牌影响力。AI智能名片S2B2C商城小程序的引入,为企业参与社区团…...

全链路追踪 性能监控,GO 应用可观测全面升级
作者:古琦 01 介绍 随着 Kubernetes 和容器化技术的普及,Go 语言不仅在云原生基础组件领域广泛应用,也在各类业务场景中占据了重要地位。如今,越来越多的新兴业务选择 Golang 作为首选编程语言。得益于丰富的 RPC 框架ÿ…...

深入探索CSS3的Media Query:打造响应式网页设计的利器
在今天的互联网世界中,随着设备种类和屏幕尺寸的多样化,响应式网页设计(Responsive Web Design, RWD)已成为不可或缺的一部分。CSS3中的Media Query正是这一设计理念的实现利器,它允许开发者根据用户的设备特性和屏幕尺…...

DDD(Domain-Driven Design)领域驱动设计
在软件开发中,DDD(Domain-Driven Design,领域驱动设计)是一种方法论,它强调在开发过程中将业务领域的知识和规则作为核心。DDD的目标是通过理解和建模业务领域来创建更好的软件系统。本文将详细讲解DDD的基本概念、原则…...

基于k8s快速搭建docker镜像服务的demo
基于k8s快速搭建docker镜像服务的demo 一、环境准备 如标题,你需要环境中有和2个平台,并且服务器上也已经安装好docker服务 接下来我来构建一个docker镜像,然后使用harbork8s来快速部署服务demo 二、部署概述 使用docker构建镜像&#x…...

“论大数据处理架构及其应用”写作框架,软考高级论文,系统架构设计师论文
论文真题 大数据处理架构是专门用于处理和分析巨量复杂数据集的软件架构。它通常包括数据收集、存储、处理、分析和可视化等多个层面,旨在从海量、多样化的数据中提取有价值的信息。Lambda架构是大数据平台里最成熟、最稳定的架构,它是一种将批处理和流…...

tarojs项目启动篇
TaroJS 是一个开放式跨端开发解决方案,使用 React 语法规范来开发多端应用(包括小程序、H5、React Native 等)。它可以帮助开发者高效地构建出在不同端上运行一致的应用。以下是启动 TaroJS 项目(本来就有的旧项目)的步…...

Maven打包时将本地 jar 加入 classpath
在使用 maven 编译项目时,我们有时候会需要引入本地的 jar 包作为依赖(不部署到本地仓库),一般会使用 scope 为 system 的标签来引入,如下所示: <dependency><groupId>com.example</groupI…...

Spring Boot打出的jar包为什么可以独立运行
闲来无事,浏览网页看到有人说jar包为什么可以独立运行,想起前端时间写的jar打包后无法正常运行处理。jar解压缩后有多个文件夹,内部存放运行所需jar包和一些配置文件,本文做一个简单介绍。 JAR包和WAR包区别 在Java开发中&#…...

“微软蓝屏”事件:网络安全与稳定性的深刻反思
🌈所属专栏:【其它】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点…...

【技术升级】Docker环境下Nacos平滑升级攻略,安全配置一步到位
目前项目当中使用的Nacos版本为2.0.2,该版本可能存在一定的安全风险。软件的安全性是一个持续关注的问题,尤其是对于像Nacos这样的服务发现与配置管理平台,它在微服务架构中扮演着核心角色。随着新版本的发布,开发团队会修复已知的…...

[题解]CF1401E.Divide Square(codeforces 05)
题目描述 There is a square of size 106106106106 on the coordinate plane with four points (0,0)(0,0) , (0,106)(0,106) , (106,0)(106,0) , and (106,106)(106,106) as its vertices. You are going to draw segments on the plane. All segments are either horizonta…...

软考高级第四版备考--第32天(新一代信息技术及应用)
1、物联网 1.1技术基础 1.1.1感知层:由各种传感器构成,包括温度传感器,二维码标签、RFID标签和读写器,摄像头,GPS等感知终端。感知层是物联网识别物体、采集信息的来源。 1.1.2网络层:由各种网络&#x…...

【RabbitMQ】MQ相关概念
一、MQ的基本概念 定义:MQ全称为Message Queue,是一种提供消息队列服务的中间件,也称为消息中间件。它允许应用程序通过读写队列中的消息来进行通信,而无需建立直接的连接。作用:主要用于分布式系统之间的通信&#x…...

【MySQL是怎样运行的 | 第二篇】MySQL三大日志文件
文章目录 2.MySQL三大日志文件2.1日志文件列表2.1.1 redo log2.1.2 bin log2.1.3 undo log 2.2redo log日志详讲2.3 binglog和redo log有什么区别?2.4一条更新语句的执行过程 2.MySQL三大日志文件 2.1日志文件列表 redo log:重做日志,记录了…...

视图、存储过程、触发器
一、视图 视图是从一个或者几个基本表(或视图)导出的表。它与基 本表不同,是一个虚表,视图只能用来从查询,不能做增删改(虚拟的表) 1.创建视图 创建视图的语法: create view 视图名【view_xxx / v_xxx】 a…...

【学习笔记】解决Serial Communication Library编译问题
【学习笔记】解决编译 Serial Communication Library 时的 Catkin 依赖问题 Serial Communication Library 是一个用 C 编写的用于连接类似 rs-232 串口的跨平台库。它提供了一个现代的 C 接口,它的工作流程设计在外观和感觉上与 PySerial 相似,但串口速…...

在 Windows 环境下实现负载均衡:提升系统性能与可靠性的关键技术
Windows 环境下的负载均衡:提升系统性能与可靠性的关键技术 负载均衡(Load Balancing)是现代网络架构中不可或缺的一部分,通过将请求分配到多台服务器上来提高系统的性能和可靠性。本文将介绍在 Windows 环境下使用负载均衡的基本…...