【c++】vector的增删查改

news2025/2/2 6:02:18

1.先定义一个类对象vector

为了防止和库里面发生冲突,定义一个命名空间,将类对象放在命名空间 里面

#include<iostream>
using namespace std;
namespace zjw {
 class vector {

 public:
 private:


    };
}

2.定义变量,需要一个迭代器,为了便于修改,变成任意类型的迭代器,我们使用函数模版,三个迭代器变量 _start用于指向顺序表的头,_finish指向顺序表的结尾的下一位,_end_of_storage保存总容量,在初始化列表中先设置为空

#include<iostream>
using namespace std;
namespace zjw {
    template<class T>
 class vector {
 
 public:
     typedef T * iterator;//迭代器类型
     vector()
         :_start(nullptr)
         , _finish(nullptr)
         , _end_of_storage(nullptr)
     {
     }

    private:
         iterator _start;
         iterator _finish;
         iterator _end_of_storage


    };
}

3.定义函数

1.返回指向顺序表开始的迭代器函数
2.返回指向顺序表结尾的迭代器函数
3.返回容量大小的函数
4.返回顺序表元素多少
5.判断顺序表为空地的函数
5.一个运算符重载的函数(返回给定下标下的值)

#include<iostream>
using namespace std;
namespace zjw {
    template<class T>
 class vector {
 
 public:
     typedef T * iterator;//迭代器类型
     vector()
         :_start(nullptr)
         , _finish(nullptr)
         , _end_of_storage(nullptr)
     {
     }
     iterator begin()//1
     {
         return _start;
     }
     iterator end()//2
     {
         return  _finish;
     }
     size_t capacity()//3
     {
         return _end_of_storage - _start;
     
     }
     size_t size()//4
     {
         return _finish - _start;
     
     
     }
     bool empty()//5
     {
         return _finish == _start;
     
     
     }
     T& operator[](size_t pos)//6
     {
         assert(pos < size());
         return _start[pos];
     
     
     }




    private:
         iterator _start;
         iterator _finish;
         iterator _end_of_storage;


    };
}

4.reserve函数开空间

  void reserve(size_t n)
     {
         if (n > capacity)
         {
             T* tmp = new T[n];
             if (_start)
             {
                 memcpy(tmp, _start, sizeof(T) * size());
                 delete[] _start;
             }
             _start = tmp;
             _finish = _start + size();
             _end_of_storage = _start + n;





         }
     
     
     
     
     
     
     }

5.push_back函数尾插,以及尾删函数

 void push_back(const T& x)
     {
         if (_finish == _end_of_storage)
         {

             reserve(capacity() == 0 ? 4 : capacity() * 2);





         }
         *_finish = x;
         _finish++;
     }
     void pop_back()
     {
     
         assert(!empty());
         --_finish;
     
     
     
     }

6.测试尾插,尾删,下标遍历,迭代器遍历,范围for遍历,以及运算符重载返回对应下标的元素

 void test1()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     for (int i = 0; i < v1.size(); i++)
     {
         cout << v1[i] << " ";
     }
     cout << endl;
     v1.pop_back();
     v1.pop_back();
     vector<int>::iterator it = v1.begin();
     while (it != v1.end())
     {
         cout << *it << " ";
         ++it;

     }
     cout << endl;
     v1.pop_back();
     for (auto e : v1)
     {
         cout << e << " ";


     }
     cout << endl;
 
 
 
 
 
 
 }

这里开空间的函数会发生问题
在这里插入图片描述

7.修改扩容函数

  void reserve(size_t n)
     {
         if (n > capacity)
         {   int sz=size();
             T* tmp = new T[n];
             if (_start)
             {
                 memcpy(tmp, _start, sizeof(T) * size());
                 delete[] _start;
             }
             _start = tmp;
             _finish = _start + sz;
             _end_of_storage = _start + n;





         }
     
     
     
     
     
     
     }

在这里插入图片描述

8.resize函数

参数小于容量大小,相当于缩容,参数大于容量大小,相当于扩容,超过_finish的用值初始化
在讲resize之前看看模版会不会给匿名变量初始化,内置类型是否能初始化.

 template <class T>
 void f()
 {
     T x = T();
     cout << x << endl;



 }
 void test3()
 {

     f<int>();
     f<int*>();
     f<double>();




 }

在这里插入图片描述
发现可以,所以我们在resize里面当n>capacity(),我们可以把顺序表外的用来初始化,自定义类型相当于调用自己的构造函数,内置函数我们在这假装理解为调用自己的构造函数.

  void resize(size_t n, T val = T())
     {
         if (n < size())
         {
             _finish = _start + n;
         }
         else
         {
             if (n > capacity())
                 reserve(n);
             while (_finish != _start + n)
             {
                 *_finish = val;
                 ++_finish;

             }





         }




     }

9.测试resize

 void test2()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     cout << v1.size() << endl;
     cout << v1.capacity() << endl;
     v1.resize(10);
     cout << v1.size() << endl;
     cout << v1.capacity() << endl;
     for (auto e : v1)
     {
         cout << e << " ";


     }
     cout << endl;
     v1.resize(3);
     for (auto e : v1)
     {
         cout << e << " ";


     }

 
 
 
 
 }


}

在这里插入图片描述

10.封装一个打印函数用于任何vector对象

 void func(const vector<int>& v)
 {
     for (int i = 0; i < v.size(); i++)//下标
     {
         cout << v[i] << " ";



     }
     cout << endl;
     vector<int>::iterator it = v.begin();//迭代器
     while (it != v.end())
     {
         cout << *it << " ";
         ++it;

     }
     cout << endl;
     for (auto e : v)//范围for
     {
         cout << e << " ";


     }
     cout << endl;







 }

因为打印不同对象的元素,为了区分是有一个this指针的,但是参数是const 无法产生this指针
在这里插入图片描述
解决方法,在这些函数后面加 const ,如果是const对象调用的话,就是权限平移,如果是非const的话,是权限缩小,都可以调用了,如果要限制别人去修改这个*it,我们可以定义一个const的迭代器

void func(const vector<int>& v)
 {
     for (int i = 0; i < v.size(); i++)//下标
     {
         cout << v[i] << " ";



     }
     cout << endl;
     vector<int>::iterator it = v.begin();//迭代器
     while (it != v.end())
     {
         cout << *it << " ";
         ++it;

     }
     cout << endl;
     for (auto e : v)//范围for
     {
         cout << e << " ";


     }
     cout << endl;







 }
 void test4()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     func(v1);
 
 
 }

11.insert函数实现

   void insert(iterator pos, const T& val)
     {
         assert(pos >= _start);
         assert(pos <= _finish);
         if (_finish == _end_of_storage)
         {
             reserve(capacity() == 0 ? 4 : capacity() * 2);




         }
         iterator end = _finish - 1;
         while (end >= pos)
         {
             *(end + 1) = *end;
             --end;


         }
         *pos = val;
         ++_finish;
     
     
     
     
     
     
     
     
     
     }

测试insert

 void test5()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
     
     if (pos != v1.end())
     {
         v1.insert(pos, 30);//3前插入30



     }
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     (*pos)++;//让3+1

     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
 
 
 
 
 }


}

在这里插入图片描述
pos保存的之前是3的地址,如果在3前插入一个30,pos所指向的位置就变成了30,*pos++,就变成了31;

如果我们不使用push_back(5)的话

 void test5()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     //v1.push_back(5);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
     
     if (pos != v1.end())
     {
         v1.insert(pos, 30);//3前插入30



     }
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     (*pos)++;//让3+1

     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
 
 
 
 
 }


}

会出现报错,到底是怎么一回事??
在这里插入图片描述
在这里插入图片描述
如何修改??
我们需要在未扩容前记录好pos距离_start的位置,拷到新空间,他与新_start也保持这个距离,更新pos

   void insert(iterator pos, const T& val)
     {
         assert(pos >= _start);
         assert(pos <= _finish);
         if (_finish == _end_of_storage)
         {
             int len=pos - _start;
             reserve(capacity() == 0 ? 4 : capacity() * 2);
             pos = _start + len;



         }
         iterator end = _finish - 1;
         while (end >= pos)
         {
             *(end + 1) = *end;
             --end;


         }
         *pos = val;
         ++_finish;
     
   
     }

在这里插入图片描述
这里的*pos里面的数据被清理,如果不清理应该是3++,应该是4,我们可以注释掉reserve中的delete看看
在这里插入图片描述
这里的问题被叫做迭代器失效

12.earse函数

 void eraase(iterator pos)
     {
             assert(pos >= _start);
             assert(pos < _finish);
             iterator start = pos + 1;
             while (start != _finish)
             {
                 *(start - 1) = *start;
                 ++start;


             }
             --_finish;
     
     
     
     
     }

earse函数测试

void test6()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 2);
     if (pos != v1.end())
     {
         v1.erase(pos);//删除2
     }
     (*pos)++;2位置上的元素++
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }






 }

在这里插入图片描述
这里2删除后2的地址上存的就是3,然后给3++;在std中这个也算迭代器失效,由于这里是自己写的,所以没报错.

 void test6()
 {
     std::vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 2);
     if (pos != v1.end())
     {
         v1.erase(pos);
     }
     (*pos)++;
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }






 }


}

上面会调用vector里面的函数
在这里插入图片描述
在不同编译器下有不同的处理情况。在vs中std我们认为迭代器失效,如果删除的是4的话,以我们实现的earse后,–_finish ;4那里的值没有被清理,所以后面的(*pos)++也不会出错,但在vs中我们使用vector里面的实现认为迭代器失效.
我们可以将代码拷过去在linux下试一下g++是怎么回事??
在这里插入图片描述

在g++中使用库中的vector函数删除数据4没有报错,对于迭代器失效,不同编译器也有不同处理.

13.整体代码

#include<iostream>
#include<assert.h>
#include<vector>
using namespace std;
namespace zjw {
    template<class T>
 class vector {
 
 public:
     typedef T * iterator;//迭代器类型
     typedef T* const_iterator;//迭代器类型
     vector()
         :_start(nullptr)
         , _finish(nullptr)
         , _end_of_storage(nullptr)
     {
     }
     iterator begin()const 
     {
         return _start;
     }
     iterator end()  const
     {
         return  _finish;
     }
     size_t capacity()
     {
         return _end_of_storage - _start;
     
     }
     size_t size()  const
     {
         return _finish - _start;
     
     
     }
     bool empty()
     {
         return _finish == _start;
     
     
     }
      T& operator[](size_t pos)  const
     {
          assert(pos < size());
             return _start[pos];
     
     
     }
     void reserve(size_t n)
     {
        int sz = size();
         if (n > capacity())
         {
             T* tmp = new T[n];
             if (_start)
             {
                 memcpy(tmp, _start, sizeof(T) * size());
                 delete[] _start;
             }
             _start = tmp;
             _finish = _start + sz;
             _end_of_storage = _start + n;





         }
     
     
     
     
     
     
     }
     void push_back(const T& x)
     {
         if (_finish == _end_of_storage)
         {

             reserve(capacity() == 0 ? 4 : capacity() * 2);





         }
         *_finish = x;
         _finish++;
     }
     void pop_back()
     {
     
         assert(!empty());
         --_finish;
     
     
     
     }
     void resize(size_t n, T val = T())
     {
         if (n < size())
         {
             _finish = _start + n;
         }
         else
         {
             if (n > capacity())
                 reserve(n);
             while (_finish != _start + n)
             {
                 *_finish = val;
                 ++_finish;

             }





         }




     }
     void insert(iterator pos, const T& val)
     {
         assert(pos >= _start);
         assert(pos <= _finish);
         if (_finish == _end_of_storage)
         {
             int len=pos - _start;
             reserve(capacity() == 0 ? 4 : capacity() * 2);
             pos = _start + len;



         }
         iterator end = _finish - 1;
         while (end >= pos)
         {
             *(end + 1) = *end;
             --end;


         }
         *pos = val;
         ++_finish;
     
     
     
     
     
     
     
     
     
     }

     void erase(iterator pos)
     {
             assert(pos >= _start);
             assert(pos < _finish);
             iterator start = pos + 1;
             while (start != _finish)
             {
                 *(start - 1) = *start;
                 ++start;


             }
             --_finish;
     
     
     
     
     }











   




    private:
         iterator _start;
         iterator _finish;
         iterator _end_of_storage;


 
};
 void test1()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     for (int i = 0; i < v1.size(); i++)
     {
         cout << v1[i] << " ";
     }
     cout << endl;
     v1.pop_back();
     v1.pop_back();
     vector<int>::const_iterator it = v1.begin();
     while (it != v1.end())
     {
         
         cout << *it << " ";
         
         ++it;

     }
     cout << endl;
     v1.pop_back();
     for (auto e : v1)
     {
         cout << e << " ";


     }
     cout << endl;
 
 
 
 
 
 
 }
 void test2()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     cout << v1.size() << endl;
     cout << v1.capacity() << endl;
     v1.resize(10);
     cout << v1.size() << endl;
     cout << v1.capacity() << endl;
     for (auto e : v1)
     {
         cout << e << " ";


     }
     cout << endl;
     v1.resize(3);
     for (auto e : v1)
     {
         cout << e << " ";


     }

 
 
 
 
 }
 void func(const vector<int>& v)
 {
     for (int i = 0; i < v.size(); i++)//下标
     {
         cout << v[i] << " ";



     }
     cout << endl;
     vector<int>::iterator it = v.begin();//迭代器
     while (it != v.end())
     {
         cout << *it << " ";
         ++it;

     }
     cout << endl;
     for (auto e : v)//范围for
     {
         cout << e << " ";


     }
     cout << endl;







 }
 void test4()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     v1.push_back(5);
     func(v1);
 
 
 }
 void test5()
 {
     vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
    // v1.push_back(5);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 3);//找到3的位置
     
     if (pos != v1.end())
     {
         v1.insert(pos, 30);//3前插入30



     }
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     (*pos)++;//让3+1
     cout << *pos << endl;

     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
 
 
 
 
 }
 void test6()
 {
    std:: vector<int>v1;
     v1.push_back(1);
     v1.push_back(2);
     v1.push_back(3);
     v1.push_back(4);
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }
     cout << endl;
     auto pos = find(v1.begin(), v1.end(), 4);
     if (pos != v1.end())
     {
         v1.erase(pos);
     }
     (*pos)++;
     for (auto e : v1)//范围for
     {
         cout << e << " ";


     }






 }


}



int main()
{
   // zjw::test1();
      zjw::test6();
   // zjw::test3();
}

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

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

相关文章

RK3568平台开发系列讲解(存储篇)文件描述符相关系统调用实现

🚀返回专栏总目录 文章目录 一、open 系统调用二、close 系统调用沉淀、分享、成长,让自己和他人都能有所收获!😄 一、open 系统调用 open()系统调用会分配新的文件句柄(file description),用来维护与打开文件相关的元信息(如偏移量、路径、操作方法等),并会给进程…

云计算基础-计算虚拟化-CPU虚拟化

CPU指令系统 在CPU的工作原理中&#xff0c;CPU有不同的指令集&#xff0c;如下图&#xff0c;CPU有4各指令集&#xff1a;Ring0-3&#xff0c;指令集是在服务器上运行的所有命令&#xff0c;最终都会在CPU上执行&#xff0c;但是CPU并不是说所有的命令都是一视同仁的&#xf…

一文分清OMS、CMS、PMS、TMS、IM、BI、BPMS、SCRM、DSS等B端系统

继5月22日发布一文分清OA、CRM、ERP、MES、HRM、SCM、WMS、KMS等后&#xff0c;很多老铁又给我推荐了其他系统&#xff0c;贝格前端工场这次再撰一文&#xff0c;介绍这些系统。 之前文章&#xff1a; 一文分清OA、CRM、ERP、MES、HRM、SCM、WMS、KMS等 1、OMS系统 OMS系统是…

Apache POI | Java操作Excel文件

目录 1、介绍 2、代码示例 2.1、将数据写入Excel文件 2.2、读取Excel文件中的数据 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步…

红色警戒 3 修改游戏速度

原文&#xff1a;https://blog.iyatt.com/?p13852 红警 2 是有提供游戏速度修改的&#xff0c;红警 3 没有&#xff0c;而且游戏速度似乎和 FPS 关联的&#xff0c;在配置低一些的电脑上会变慢&#xff0c;FPS 也降低&#xff0c;我电脑上开最高画质 FPS 不超过 30&#xff0c…

Confluence CVE-2023-22527利用工具

介绍 Confluence CVE 2021&#xff0c;2022&#xff0c;2023 利用工具&#xff0c;支持命令执行&#xff0c;哥斯拉&#xff0c;冰蝎 内存马注入 支持 Confluence 版本&#xff1a;CVE-2021-26084&#xff0c;CVE-2022-26134&#xff0c;CVE_2023_22515&#xff0c;CVE-2023-2…

Matplotlib plt.scatter:从入门到精通,只需一篇文章!

Matplotlib plt.scatter&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;&#x1f680; 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; 一、plt.scatter入门&#xff1a;轻松迈出第一步 &#x1f463;二、进阶探索&#xff1a;plt.scatt…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——数据库

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 4. 数据库 1. B树相对于B树的区别及优势 B树中有重复元素&#xff0c;B树没有重复元素B树种每个节点都存储了key和data&#xff0c;B树内节点去掉了其中指向数…

互联网时代的文学复兴:中文诗词大数据分析 | 开源日报 No.170

chinese-poetry/chinese-poetry Stars: 45.4k License: MIT 最全的中文诗歌古典文集数据库&#xff0c;包含 5.5 万首唐诗、26 万首宋诗、2.1 万首宋词和其他古典文集。数据来源于互联网。该开源项目旨在通过 JSON 格式分发&#xff0c;方便用户开始自己的项目&#xff0c;并借…

嵌入式内核链表list_head,如何管理不同类型节点的实现

在Linux内核中&#xff0c;提供了一个用来创建双向循环链表的结构 list_head。虽然linux内核是用C语言写的&#xff0c;但是list_head的引入&#xff0c;使得内核数据结构也可以拥有面向对象的特性&#xff0c;通过使用操作list_head 的通用接口很容易实现代码的重用&#xff0…

AAAI 2024 | Adobe提出全新上下文提示学习框架CoPL,高效提升下游性能

论文题目&#xff1a;CoPL: Contextual Prompt Learning for Vision-Language Understanding 论文链接&#xff1a;https://arxiv.org/abs/2307.00910 提示学习&#xff08;Prompt Learning&#xff09;在近几年的快速发展&#xff0c;激活了以Transformer为基础的大型语言模型…

【机器学习】数据清洗之识别重复点

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

1、若依(前后端分离)框架的使用

若依&#xff08;前后端分离&#xff09;框架的使用 0、环境1、下载若依(1) 下载并解压(2) 导入SQL语句(3) 配置Redis、MySQL 2、运行若依3、登录(1) 前端(2) 后端 4、获取用户角色、权限和动态路由(1) 获取用户角色、权限(2) 根据用户信息获取动态路由【getRouters】 5、杂6、…

每日一练:LeeCode-530、二叉搜索树的最小绝对差【二叉搜索树+pre辅助节点+DFS】

本文是力扣LeeCode-530、二叉搜索树的最小绝对差【二叉搜索树pre辅助节点DFS】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。…

面试经典150题——有效的数独

​"Strive not to be a success, but rather to be of value." - Albert Einstein 1. 题目描述 2. 题目分析与解析 2.1 暴力求解 没思路&#xff0c;老规矩&#xff0c;先来一次笨办法&#xff0c;先把步子迈出去&#xff0c;因为可能笨办法写着写着就会有更多的…

STM32 HAL库 STM32CubeMX -- IWDG(独立看门狗)

STM32 HAL库 STM32CubeMX -- IWDG 一、IWDG简介二、独立看门狗的工作原理三、驱动函数初始化函数HAL IWDG Init()初始化函数HAL IWDG Init()其他宏函数 四、超时时间计算第一种办法第二种办法&#xff08;推荐&#xff09; 一、IWDG简介 看门狗(Watchdog)就是MCU上的一种特殊的…

企业数字化转型战略规划与实践:迈向未来的关键之举

在信息技术的不断革新和全球数字化浪潮的推动下&#xff0c;企业数字化转型已经成为当今商业世界中不可或缺的一项战略规划。随着技术的进步&#xff0c;企业必须积极应对数字化转型的挑战&#xff0c;并将其作为发展的关键驱动力。本文将探讨企业数字化转型的重要性&#xff0…

JavaWeb之Servlet接口

Servlet接口 什么是Servlet&#xff1f; Servlet是一种基于Java技术的Web组件&#xff0c;用于生成动态内容&#xff0c;由容器管理&#xff0c;是平台无关的Java类组成&#xff0c;并且由Java Web服务器加载执行&#xff0c;是Web容器的最基本组成单元 什么是Servlet容器&…

浅谈电商场景中的扣除库存问题

库存 一、场景二、扣减时机1.下单时扣库存2.支付完成扣库存3.预扣除 三、库存存储方案1.数据库存储2.数据库缓存混合存储 四、整体方案1.单数据库方案2.主从数据库方案3.主从数据库缓存方案4.数据库缓存混合存储 五、其他情况1.秒杀QPS过高2.Redis QPS过高3.Master DB QPS过高4…

java生态环境评价Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java 生态环境评价管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysq…