【C++】stack和queue的使用

news2024/11/26 4:37:22

文章目录

  • Stack
      • stack容器的定义方式:
      • 接口函数
  • queue
      • queue容器的定义方式
      • 接口函数
  • 栈OJ题目
      • 最小栈
      • 栈的压入,弹出序列
      • 逆波兰表达式求值(后缀表达式)
        • 中缀表达式->后缀表达式
      • 用两个栈实现队列
  • 队列OJ题
      • 用队列实现栈
        • 使用两个队列实现栈
        • 使用一个队列实现栈
      • 二叉树的层序遍历I
      • 二叉树的层序遍历II

栈和队列都不支持迭代器,因为不支持访问任意位置,否则就违反了栈和队列的特性

Stack

stack文档介绍

  1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作,
  2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容器,并提供一组特定的成员函数来访问其元素,将特定类作为其底层的,元素特定容器的尾部(即栈顶)被压入和弹出,
  3. stack的底层容器可以是任何标准的容器类模板或者一些其他特定的容器类,这些容器类应该支持以下操作
  • empty:判空操作
  • back:获取尾部元素操作
  • push_back:尾部插入元素操作
  • pop_back:尾部删除元素操作

4.标准容器vector、deque、list均符合这些需求,默认情况下,如果没有为stack指定特定的底层容器,默认情况下使用deque,


image-20220221160307904


stack容器的定义方式:

方式1:使用默认的容器适配器定义 -> 注意:stack的默认容器适配器是deque双端队列

stack<int> st;

方式2:使用特定的容器适配器定义

stack<char, list<char>> st2;//使用list作为容器适配器
stack<int, vector<int>> st3;//使用vector作为容器适配器

接口函数

成员函数功能
empty判断栈是否为空
size获取栈中元素个数
top获取栈顶元素
push元素入栈
pop元素出栈
swap交换两个栈中的数据
stack()构造一个空栈

实例:

int main()
{
	stack<int> st;
	st.push(1);
	st.push(2);
	st.push(3);
	st.push(4);
	st.pop();
	while (!st.empty())
	{
		cout << st.top() << " ";//3 2 1
		st.pop();
	}
	cout << endl;
	return 0;
}

queue

queue文档介绍

  1. 队列是一种容器适配器,专门用于在FIFO上下文(先进先出)中操作,其中从容器一端插入元素,另一端获取元素,

  2. 队列作为容器适配器实现,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素,元素从队尾入队列,从队头出队列,

  3. queue的底层容器可以是标准容器类模板之一,也可以是其他专门设计的容器类,该底层容器至少支持以下操作:

  • empty:检测队列是否为空
  • size:返回队列中有效元素的个数
  • front:返回队头元素的引用
  • back:返回队尾元素的引用
  • push_back:在队列尾部入队列
  • pop_front:在队列头部出队列

  1. 标准容器类deque和list满足了这些要求,默认情况下,如果没有为queue实例化指定容器类,则使用标准容器deque,

image-20220221190243742

queue容器的定义方式

方式1:使用默认的容器适配器定义 -> 注意:queue的默认容器适配器是deque双端队列

queue<int> q1;

方式2:使用特定的容器适配器定义

queue<int, vector<int>> q2;//err 不可以使用vector作为queue的容器适配器
queue<int, list<int>> q3;

image-20220221185349873


接口函数

成员函数功能
empty判断队列是否为空
size获取队列中有效元素个数
front获取队头元素
back获取队尾元素
push队尾入队列
pop队头出队列
swap交换两个队列中的数据
queue()构造一个空队列

实例

int main()
{
    queue<int> q;
    q.push(1);
    q.push(2);
    q.push(3);
    q.pop();
    cout << q.size() << endl;//2
    q.push(1);
    while (!q.empty())
    {
        cout << q.front() << " ";//2 3 1
        q.pop();
    }
    return 0;
}

栈OJ题目

最小栈

155. 最小栈 - 力扣(LeetCode) (leetcode-cn.com)

image-20220221190801290

不可取方法:用一个变量记录当前最小值


正确方法:使用两个栈,一个栈存储数据,一个辅助栈存储当前的最小值

  • 如果当前入栈的值 比 辅助栈的栈顶元素小 || 辅助栈为空
    • 压入当前入栈的值 否则:重复压入当前辅助栈的栈顶元素
  • 获取最小值:即获取当前辅助栈的栈顶元素
class MinStack {
public:
    //构造函数和析构函数都不需要我们自己写,因为成员变量stack是自定义类型,会调用它自己的默认构造函数初始化
    MinStack() {
    }
    
    void push(int val) {
        stackPush.push(val);
        //最小栈为空 || 最小栈的栈顶元素>当前入栈数 
        if( stackMin.empty() || stackMin.top() > val)
        {
            stackMin.push(val);//压入当前数
        }
        else
        {
            stackMin.push(stackMin.top());//重复压入最小栈的栈顶元素
        }
    }
    
    void pop() {
        //两个栈都要出栈顶元素
        stackPush.pop();
        stackMin.pop();
    }
    
    int top() {
       return  stackPush.top();
    }
    
    int getMin() {
        return stackMin.top();
    }

    stack<int> stackPush;
    stack<int> stackMin;
}

优化:不存储大量重复值,

  • 压入栈的时候:如果最小栈为空 || 当前压入元素 <=最小栈的栈顶元素

    • 才压入当前元素 (注意:等于的时候也要压入) 其它情况不压入
  • 弹出的时候: 如果此时数据栈pop的值和最小栈栈顶的值一样 ->弹出最小栈的栈顶元素

class MinStack {
public:
    //构造函数和析构函数都不需要我们自己写,因为成员变量stack是自定义类型,会调用它自己的默认构造函数初始化
    MinStack() {
    }
    
    void push(int val) {
        stackPush.push(val);
        //最小栈为空 || 当前压入元素<=最小栈的栈顶元素
        if( stackMin.empty() || stackMin.top()>= val)
        {
            stackMin.push(val);
        }
    }
    
    void pop() {
        //数据栈pop的值和最小栈栈顶的值一样
        if(stackPush.top() == stackMin.top())
        {
            stackMin.pop();
        }
        stackPush.pop();
    }
    
    int top() {
       return  stackPush.top();
    }
    
    int getMin() {
        return stackMin.top();
    }

    stack<int> stackPush;
    stack<int> stackMin;
};

栈的压入,弹出序列

栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)

image-20220221190815149

使用栈的入栈和出栈来模拟这个出栈顺序,如果能模拟出来,就说明是合法的,否则就是非法的!

方法:

  • 1.先把push数组中的值进栈
  • 2.pop数组的值依次和栈里面的数据比较
    • 如果相等,则pop数组往后走,然后出栈顶数据
    • 如果栈顶数据和此时pop数组指向数据不相等 或者 栈为空–>重复第一步
      • 注意此时用的是&&结构,只要有一个不满足就重复第一步
  • 循环结束条件: push数组走完了
  • 是否匹配:
    • 如果pop数组也走完了 -> 匹配
    • 如果pop数组没有走完 ->不匹配

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        stack<int> st;
        int i =0;
        int j = 0;
        //循环结束条件: push数组走完了 
        while(i<pushV.size())
        {
            st.push(pushV[i]);//先把push数组中的值进栈
            ++i;
            //如果数据不相等&&栈为空-->第一步
            while(!st.empty() &&st.top()==popV[j])
            {
                j++;
                st.pop();
            }
        }
        //是否匹配
        return j == popV.size();
    }
};

写法2:

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV)
    {
        //先做特殊性判定
        if(pushV.empty() || popV.empty() || popV.size() != pushV.size())
        {
            return false;
        }
        //遍历入栈序列
        stack<int> st;
        int j = 0;
        for(int i = 0;i<pushV.size();i++)
        {
            st.push(pushV[i]);//把当前入栈序列元素入栈
            //模拟栈的入栈和出栈序列
            //如果栈不为空 && 当前栈顶元素==出栈元素,就一直往后比较出栈序列的元素
            //如果该条件不满足,就要一直入栈
            //如果该条件满足,就要一直出栈
            //pushV代表对应的入栈逻辑,popV代表对应的出栈逻辑
            while(!st.empty() && st.top() == popV[j])
            {
                j++;
                st.pop();//去掉栈顶元素,比较下一个元素
            }
        }
        //如果最后栈为空,说明第二个序列是该栈的弹出顺序
        return st.empty();
    }
};

逆波兰表达式求值(后缀表达式)

150. 逆波兰表达式求值 - 力扣(LeetCode) (leetcode-cn.com)

image-20220221190835548

思路:

遍历整个字符串:

1.遇到操作数 ->入栈

2.遇到操作符 ->拿栈顶的两个数据出来运算, 然后把运算结果放到栈中

  • 要注意弹出顺序,先拿到的是右操作数,然后才是左操作数 因为栈的特性:先进后出

Bug代码:switch(str)

因为容器tokens存放的是字符串集合, str:字符串 str[0] :字符串的第一个字符

  • switch(str[0])->OK char类型也是整形家族的一个成员

做法:

判断每个字符串到底是操作数还是操作符 如果是操作符就拿到两个操作数,然后根据该操作符是什么,进行计算,然后压到栈中

C语言的atoi == C++中的stoi函数 将字符串转为整数 to_string函数:将各种类型转为字符串

image-20220222181703282
class Solution {
public:
    //得到两个操作数  left和right是引用 栈也是引用
    void  getNum(stack<int>&st,int& left,int& right)
    {
        //先出的是右操作数 
        right = st.top();
        st.pop();
        left = st.top();
        st.pop();
    }
    int evalRPN(vector<string>& tokens) {
        stack<int> st;//存放结果
        for(auto& str: tokens)//遍历字符串
        {
            int left,right;
            switch(str[0])
            {
                case '+':
                    getNum(st,left,right);
                    st.push(left+right);
                    break;
                case '-':
                    getNum(st,left,right);
                    st.push(left-right);
                    break; 
                case '*':
                    getNum(st,left,right);
                    st.push(left*right);
                    break; 
                case '/':
                    getNum(st,left,right);
                    st.push(left/right);
                    break; 
                default:
                    st.push(stoi(str)); 
                    break;
            }
        }
        return st.top();
    }
};

image-20220222180221267

不能通过判断字符串的第一个字符是+ - * / 来判断这个是操作数还是操作符, 因为可能存在负数,被误判成操作符


修改:对 -操作符进行特判:到底是操作数还是操作符, 如果此时字符串只有一个字符->说明就是操作符,否则就是操作数

class Solution {
public:
    //得到两个操作数
    void  getNum(stack<int>&st,int& left,int& right)
    {
        right = st.top(); //先出的是右操作数
        st.pop();
        left = st.top();
        st.pop();
    }
    int evalRPN(vector<string>& tokens) {
        stack<int> st;//存放结果
        for(auto& str: tokens)//遍历字符串
        {
            int left,right;
            switch(str[0])
            {
                case '+':
                    getNum(st,left,right);//得到两个操作数
                    st.push(left+right);//把计算结果压到栈中
                    break;
                case '-':
                    //操作符
                    if(str.size() == 1)
                    {
                        getNum(st,left,right);//得到两个操作数
                        st.push(left-right);//把计算结果压到栈中
                        break; 
                    }
                    //操作数
                    else
                    {
                        st.push(stoi(str));//转为整数压到栈中
                        break;
                    }
                case '*':
                    getNum(st,left,right);//得到两个操作数//得到两个操作数
                    st.push(left*right);
                    break; 
                case '/':
                    getNum(st,left,right);//得到两个操作数
                    st.push(left/right);//把计算结果压到栈中
                    break; 
                default: //普通的数字
                    st.push(stoi(str));//转为整数压到栈中
                    break;
            }
        }
        return st.top();//返回栈顶数据就是最后的结果
    }
};

修改办法2:取字符串的最后一个字符判断是操作数还是操作符 string中的back函数获取的就是最后一个字符或者 用size()-1也是最后一个字符

switch(str.back())  //switch(str.size()-1)

中缀表达式->后缀表达式

image-20220222182352020


用两个栈实现队列

232. 用栈实现队列 - 力扣(LeetCode) (leetcode-cn.com)

image-20220221191043879

class MyQueue {
public:
    //构造函数和析构函数都不需要我们自己写,因为成员变量stack是自定义类型,会调用它自己的默认构造函数初始化
    MyQueue() {
    }
    
    void push(int x) {
        stackPush.push(x);//只往push栈入数据
    }
    
    int pop() {
        //如果pop栈为空,就把push栈内容导过来
        if(stackPop.empty())
        {
            while(!stackPush.empty())
            {
                stackPop.push(stackPush.top());
                stackPush.pop();
            }
        }

        int tmp = stackPop.top();
        stackPop.pop();
        return tmp;
    }
    
    int peek() {
        //如果pop栈为空,就把push栈内容导过来
        if(stackPop.empty())
        {
            while(!stackPush.empty())
            {
                stackPop.push(stackPush.top());
                stackPush.pop();
            }
        }

        int tmp = stackPop.top();
        return tmp;
    }
    
    bool empty() {
       return  stackPop.empty() && stackPush.empty();
    }
    stack<int> stackPush;// 用于push数据
    stack<int> stackPop;// 用于pop数据
};

队列OJ题

用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode) (leetcode-cn.com)

image-20220221191119514
  • 入数据:往不为空的队列入数据

  • 出数据:假设一个队列不为空,然后判断该队列是不是真的不为空,否则另一个队列不为空 ,然后把不为空队列的数据导到空队列,直到不为空的队列只剩一个数据,然后pop这个数据


image-20220222185523148

所以不需要进行判空

使用两个队列实现栈

class MyStack {
public:
    //构造函数和析构函数都不需要我们自己写,因为成员变量stack是自定义类型,会调用它自己的默认构造函数初始化
    MyStack() {
    }
    
    void push(int x) {
        //往不为空的队列中入数据
        if(!q1.empty())
        {
            q1.push(x);
        }
        else
        {
            q2.push(x);
        }
    }
    
    int pop() {
        queue<int>* emptyQ = &q1;//emptyQ指向空队列
        queue<int>* noemptyQ = &q2;
        if(!q1.empty())
        {
            swap(emptyQ,noemptyQ);//交换两个指针
        }
        //把不空队列的数据导入到空队列,直到剩一个数据
        while(noemptyQ->size() > 1)
        {
                emptyQ->push(noemptyQ->front());
                noemptyQ->pop();
        }
        //返回不空队列的仅剩一个元素
        int tmp = noemptyQ->front();
        noemptyQ->pop();
        return tmp;
    }
    
    int top() {
        //哪个队列不为空,就返回哪个队列的队尾元素
        if(!q1.empty())
           return  q1.back();
        else
            return q2.back();
    }
    
    bool empty() {
        return q1.empty() && q2.empty();//两个队列都为空才是空
    }
    queue<int> q1;
    queue<int> q2;
};

emptyQ和noemptyQ是队列指针, q1和q2是队列对象

指针->方法 (通过->解引用,调用指针指向对象的方法) 对象.方法 (调用对象的方法) 方法:函数接口


使用一个队列实现栈

相当于围成一个循环圈! –size  : 循环size-1次   size-- : 循环size次

image-20220224222919411

class MyStack {
public:
    MyStack() {
    }
    
    void push(int x) {
        q.push(x);
    }
    
    int pop() {
        int size = q.size();//记录此时的元素个数
        //把前size-1个元素重复压入到队列之后,  一边压一边出数据
        while(--size)
        {
            q.push(q.front());
            q.pop();
        }
        //此时的队头就是要弹出的元素
        int tmp = q.front();
        q.pop();
        return tmp;
    }
    
    int top() {
        return q.back();
    }
    
    bool empty() {
        return q.empty();
    }
    queue<int> q;
};

二叉树的层序遍历I

102. 二叉树的层序遍历 - 力扣(LeetCode) (leetcode-cn.com)

image-20220222190551150

核心思路:当根节点进入队列时,会把左右孩子都带进队列(有左右孩子时), 当这一层的结点出完了之后,下一层的结点都进队列了

这一层有多少个结点,就循环多少次,就出多少个结点, 每一层的数据都放到一个容器vector中

当循环结束时,把这个vector放到另一个vector中存放,相当于(二维数组), 然后再求下一层有多少个结点,再次进入循环就循环多少次

外层循环结束条件:队列为空

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;//队列存放二叉树结点指针
        int leverSize = 0;//每一层的结点个数
        //如果不是空树
        if(root)
        {
            q.push(root);
            leverSize = 1;//根节点这一层只有一个结点
        }
        vector<vector<int>> vv;//最终返回结果
        //层序遍历的思路
        while(!q.empty())
        {
            vector<int> v;//记录这一层遍历的值
            //这一层右多少个结点,遍历多少次
            for(int i = 0;i<leverSize;i++)
            {
                TreeNode* front = q.front();//得到此时结点
                q.pop();//在队列中弹出此时结点
                v.push_back(front->val);//此时结点的值放到容器
                //如果有左孩子/右孩子就放进队列
                if(front->left)
                {
                    q.push(front->left);
                }
                if(front->right)
                {
                    q.push(front->right);
                }
            }

   			 //for循环结束->上一层结点都出完了->下一层的结点都被带进队列了
            //记录此时下一层有多少个结点->即此时队列的大小
            leverSize = q.size();
            vv.push_back(v);//把这一层的得到的值放到vv中
        }
        return vv;
    }
};

二叉树的层序遍历II

107. 二叉树的层序遍历 II - 力扣(LeetCode) (leetcode-cn.com)

image-20220222190608427

方法和上面的题目一致,只不过是从最后一层存放数据 -> 最后一步把保存节点的容器vv进行逆置即可

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
            queue<TreeNode*> q;
        int leverSize = 0;//每一层的结点个数
        if(root)
        {
            q.push(root);
            leverSize = 1;//根节点这一层只有一个结点
        }
        vector<vector<int>> vv;//最终返回结果
        //层序遍历的思路
        while(!q.empty())
        {
            vector<int> v;//记录这一层遍历的值
            //这一层右多少个结点,遍历多少次
            for(int i = 0;i<leverSize;i++)
            {
                TreeNode* front = q.front();//得到此时结点
                q.pop();//在队列中弹出此时结点
                v.push_back(front->val);//此时结点的值放到容器
                //如果有左孩子/右孩子进队列
                if(front->left)
                {
                    q.push(front->left);
                }
                if(front->right)
                {
                    q.push(front->right);
                }
            }

    //上一层出完了,下一层的结点都被带进队列了,记录下一层有多少个结点->即此时队列的大小
            leverSize = q.size();
            vv.push_back(v);//把这一层的得到的值放到vv中
        }
        reverse(vv.begin(),vv.end());//使用迭代器区间,把vv的内容逆置
        return vv;
    }
};

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

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

相关文章

k8s之挂载本地磁盘到POD中

写在前面 本文一起看下如何挂载本地的磁盘到POD中。 1&#xff1a;都需要哪些API对象 现实世界中的存储设备有非常非常多的种类&#xff0c;如本文要分析的计算机磁盘&#xff0c;还包括NFS(一种网络磁盘存储协议)&#xff0c;Ceph&#xff08;一种分布式的文件存储系统&…

Web测试的各个测试点

1.什么是Web测试&#xff1f; Web测试测试Web或Web应用程序的潜在错误。它是在上线前对基于网络的应用程序进行完整的测试。 UI测试 功能测试 数据库测试 性能测试 兼容性测试 安全测试 自动化测试 2.WEB测试主要测试场景 1.UI测试 界面是否美观&#xff0c;风格、字体、…

【青训营】Go的并发编程

本文章整理自——字节跳动青年训练营&#xff08;第五届&#xff09;后端组 1.线程和协程 操作系统中有三个重要的概念&#xff0c;分别是进程、线程和协程。其中进程和线程的区别请移步操作系统专栏&#xff0c;现在主要叙述线程和协程的区别。 简单来说&#xff0c;协程又称…

看我们网络故障分析系统如何发现系统500报错

背景 汽车配件电子图册系统是某汽车集团的重要业务系统。业务部门反映&#xff0c;汽车配件电子图册调用图纸时&#xff0c;出现访问慢现象。 汽车集团总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原始流量。本次分析重点针对汽车配件电子图册…

Python学习笔记-网络爬虫基础

一、网络爬虫概述网络爬虫概述网络爬虫又称网络蜘蛛、网络机器人&#xff0c;在某社区中经常被称为网页追逐者。网络爬虫可以按照指定规则自动浏览或抓取网络中的信息&#xff0c;python可以很轻松的编写爬虫程序或脚本。网络爬虫基本工作流程&#xff1a;网络爬虫的常用技术2.…

【QT5 实现“上图下文”,带图标的按键样式-toolbutton-学习笔记-记录-基础样例】实现方式之一

【QT5 实现“上图下文”&#xff0c;带图标的按键样式-toolbutton-学习笔记-记录-基础样例】1、前言2、实验环境3、效果展示4、实验步骤第一步&#xff1a;新建工程-并运行。第二步&#xff1a;上网找图标文件第四步&#xff1a;&#xff08;非必须&#xff09;为了对比图标不同…

23种设计模式(三)——观察者模式【组件协作】

文章目录意图什么时候使用观察者使用观察者模式也有两个重点问题要解决&#xff1a;1&#xff09;广播链的问题2&#xff09;异步处理问题真实世界类比观察者模式的实现观察者模式的优缺点亦称&#xff1a;事件订阅者、监听者、Event-Subscriber、Listener、Observer 意图 在许…

mybatis之动态SQL测试环境的搭建以及if语句的使用

动态SQL&#xff1a; 动态 SQL 是 MyBatis 的强大特性之一&#xff0c;如果你使用过 JDBC 或其它类似的框架&#xff0c;你应该能理解根据不同条件拼接 SQL 语句有多痛苦&#xff0c;例如拼接时要确保不能忘记添加必要的空格&#xff0c;还要注意去掉列表最后一个列名的逗号&a…

Vue CLI

介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统&#xff0c;提供&#xff1a; 通过 vue/cli 实现的交互式的项目脚手架。 通过 vue/cli vue/cli-service-global实现的零配置原型开发。 一个运行时依赖 (vue/cli-service)&#xff0c;该依赖&#xff1a; 可升级&a…

腾讯安全发布《2022年DDoS攻击威胁报告》:DDoS威胁4年持续增长

随着全球数字化蓬勃发展&#xff0c;互联网的应用范围不断扩大&#xff0c;并逐渐普及到各行各业的生产、管理、运营等方面&#xff0c;网络设备可用带宽伴随应用需求的增加而增加&#xff0c;方便了企业业务开展的同时也扩大了安全威胁面&#xff0c;引来黑产的觊觎。DDoS攻击…

Java使用流去除集合中某个字段为空的对象

文章目录0 写在前面1 情景复刻2 解决方案3 写在最后0 写在前面 最近写了一些业务逻辑&#xff0c;调试的时候总会报空指针异常。 Java中空指针异常是危险恐怖分子&#xff0c;最好不要碰见他。所以有些时候&#xff0c;处理集合中的数据时&#xff0c;特定情况下需要略过一些数…

十五天学会Autodesk Inventor,看完这一系列就够了(二),软件界面

众所周知&#xff0c;Autocad是一款用于二维绘图、详细绘制、设计文档和基本三维设计&#xff0c;现已经成为国际上广为流行的绘图工具。Autodesk Inventor软件也是美国AutoDesk公司推出的三维可视化实体模拟软件。因为很多人都熟悉Autocad&#xff0c;所以再学习Inventor&…

RK3568工业级核心板高温运行测试

Rockchip RK3568 是一款通用型MPU&#xff0c;产品集成GPU、NPU&#xff0c;支持4K、HDMI、LVDS、MIPI、PCIe3.0、USB3.0、千兆以太网、CAN-BUS、UART等丰富外设接口。 RK3568的高温工作情况如何呢&#xff1f;本文将基于万象奥科HD-RK3568-CORE 系列核心板做详细高温测试&…

接口幂等性设计

幂等性: 对于同一个操作发起一次请求或者多次请求&#xff0c;得到的结果都是一样的&#xff0c;不会因为请求多次而出现异常现象。 场景: 用户多次请求&#xff0c;比如重复点击页面上的按钮网络异常&#xff0c;右移网络原因导致在一定时间内未返回调用成功的信息&#xff…

《JavaScript 核心原理解析》学习笔记 Day 1 delete 引用与值

关于引用与值&#xff1a;在 javaScript 中一个表达式的值或者说结果&#xff0c;可能是引用 / 值。所以 x x &#xff0c;是将右侧表达式x的值赋值给左侧表达式x所指的引用。注意此处的引用并非为到具体内存地址的指向&#xff0c;而是指表达式与其值的一种关联。 这一关联即…

Android 音视频——直播推流技术指南

一、推流架构 推流SDK客户端的模块主要有三个&#xff0c;推流采集端、队列控制模块、推流端。其中每个模块的主要流程如下&#xff0c;本文的主要目的就是拆分推流流程&#xff0c; 1.1 采集端 视频采集&#xff1a;通过Camera采集视频。 音频采集&#xff1a;通过麦克风采…

SSM 05 SpringBoot yaml mybatisplus

01-SpringBoot工程入门案例开发步骤SpringBoot 是 Pivotal 团队提供的全新框架&#xff0c;设计目的是简化 Spring 应用的初始搭建以及开发过程。使用了 Spring 框架后已经简化了我们的开发。而 SpringBoot 又是对 Spring 开发进行简化的&#xff0c;可想而知 SpringBoot使用的…

linux挂载新磁盘

一、查看磁盘挂载状态&#xff1a; fdisk -l df -h 二、为其中一个磁盘创建新的分区&#xff0c;参考&#xff1a; linux用fdisk创建分区,在Linux下用fdisk创建分区_weixin_39968410的博客-CSDN博客 sudo fdisk /dev/nvme0n1 1. 创建主分区&#xff1a; -----------------…

第8章 NVS

NVS Blob块存储 1. 演示app_main任务栈溢出 2. 设置app_main任务栈大小 打开menuconfig&#xff0c;输入main&#xff0c;如下图所示 默认栈大小为3584字节&#xff0c;这里改为35840字节&#xff0c;重新编译 3. Blob存储结果 #include <stdio.h> #include <st…

使用nginx搭建HTTP FLV流媒体服务器

使用nginx搭建HTTP FLV流媒体服务器 文章目录使用nginx搭建HTTP FLV流媒体服务器1 HTTP FLV简介2 HTTP FLV流媒体服务搭建3 结果验证1 HTTP FLV简介 前文已经介绍了RTSP、RTMP、HLS的流媒体协议&#xff0c;还有一种比较常见的流媒体协议HTTP FLV&#xff0c;其兼具RTMP的实时…