当前位置: 首页 > news >正文

C++ STL:从零开始模拟实现 list 容器

文章目录

  • 引言
  • 1. 疑难点解析
    • 1.1 迭代器类为什么设置三个模版参数?
  • 2. 完整源码
  • 3. 完整测试代码

引言

C++ 标准模板库(STL)中的 list 是一个双向链表容器,它提供了高效的插入和删除操作。本文将带领你一步步实现一个简化版的 list 容器,帮助你深入理解其底层原理和设计思想。

1. 疑难点解析

1.1 迭代器类为什么设置三个模版参数?

为了区分 listconst类普通类 ,我们都知道 const类 的变量是不能修改内部值的,就算用指针也不行。而我们的迭代器也正好是在模仿指针的行为,所以指针不能修改 const类 变量,我们的迭代器也不行。
为了区分对 const类list(只读)普通类list(可读可写)的区别,我们需要另一个能做到对容器只读不写的 const类迭代器 ,我们最好的方式便是写两个基本一样的迭代器类(一份供普通类list调用的普通迭代器类,一份供const类list调用的const类的迭代器)。
但这样既不好修改又不好调试,而在有了模版之后,我们便可以将写两份代码的工作交给编译器去实现(俗称模版实例化,根据传入参数不同,模版可以实例化为多个不同类),所以我们就多加了一个模版参数Ref,根据 list 传入的类型不同,从而区分实例化为 const类 的迭代器还是 普通类 ,而又因为我们迭代器可以用 * 和 -> 两种操作符访问,且两操作符的返回值又各不同,所以 迭代器模版 又多加一个 Ptr ,以区分 ->运算符重载函数 对 const类普通类 的访问。

2. 完整源码

#include<assert.h>namespace dza {// 惯例:当成员变量和成员函数全部是公有的时候,一般用struct// struct 与 class没有区别template<class T>struct list_node {T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& x = T()):_data(x), _next(nullptr), _prev(nullptr){}};// 单一参数的模板//template<class T>//struct list_iterator {//	typedef list_node<T> Node;//	// 定义一个迭代器Self//	typedef list_iterator<T> Self;//	Node* _node;//	list_iterator(Node* node)//		:_node(node)//	{}//	// 解引用的重载//	T& operator*()//	{//		return _node->_data;//	}//	// 公共函数。域内都可以使用//	T* operator->()//	{//		return &_node->_data;//	}//	// 迭代器的实现//	Self& operator++()//	{//		_node = _node->_next;//		return *this;//	}//	Self& operator--()//	{//		_node = _node->_prev;//		return *this;//	}//	Self operator++(int)//	{//		Self tmp(*this);//		_node = _node->_next;//		return tmp;//	}//	Self operator--(int)//	{//		Self tmp(*this);//		_node = _node->_prev;//		return tmp;//	}//	bool operator!=(const Self& s)//	{//		return _node != s._node;//	}//	bool operator==(const Self& s)//	{//		return _node == s._node;//	}//};// 模板里面的多参数template<class T,class Ref,class Ptr>struct list_iterator {typedef list_node<T> Node;// 定义一个迭代器Selftypedef list_iterator<T,Ref,Ptr> Self;Node* _node;list_iterator(Node* node):_node(node){}// 解引用的重载Ref operator*(){return _node->_data;}// 公共函数。域内都可以使用Ptr operator->(){return &_node->_data;}// 迭代器的实现Self& operator++(){_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}};template<class T>class list {typedef list_node<T> Node;public://typedef list_iterator<T> iterator;// typedef list_const_iterator<T> iterator;// 这个类要你自己实现// or// list_iterator要有三个模板参数,才能用下面的迭代器,并且const是加在后面的,而不是前面typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}const_iterator begin() const{return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}void empty_init(){_head = new Node();_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}// it2(it1) 的模拟实现list(const list<T>& It){empty_init();for (auto& e : It){push_back(e);}}// it2 = it3 的模拟实现list<T>& operator=(list<T> It){swap(It);return *this;}~list(){clear();delete _head;_head = nullptr;}void swap(list<T>& tmp){std::swap(_head, tmp._head);std::swap(_size, tmp._size);}void clear(){auto it = begin();while (it != end()){it = erase(it);// 删除链表中的所有节点// erase在删除的时候会自动+1}}// it1(3,1)的模拟实现。往list中插入3个1list(size_t n, const T& val = T()){// 清空新链表empty_init();// 依次插入for (size_t i = 0; i < n; i++){push_back(val);}}void push_back(const T& x){Node* new_node = new Node(x);// 指向待插入数据的指针Node* tail = _head->_prev;// 头结点的上一个节点。也就是链表的最后一个节点tail->_next = new_node;// 最后一个节点的 next 指向 new_nodenew_node->_prev = tail;// new_node 的 prev 指向最后一个节点new_node->_next = _head;// 由于 new_node 成为最后一个节点。所以更新链表中头结点的下一个指针_head->_prev = new_node;// 头节点的 prev 指向 new_node// // 新版本// insert(end(),x);}void push_front(const T& x){insert(begin(), x);}void pop_front(){erase(begin());}void pop_back(){erase(--end());}iterator insert(iterator pos, const T& val){// cur 需要插入新数据的节点Node* cur = pos._node;// newnode 需要插入的新数据Node* newnode = new Node(val);// 需要插入新数据节点的上一个节点Node* prev = cur->_prev;// list是链表,所以想要头插,就只需要改变上一个节点的next,下一个节点的prevprev->_next = newnode;// 上一个节点的 next 换成 newnodenewnode->_prev = prev;// 新数据指向上一个节点的指针 prev 指向上一个节点 newnode->_next = cur;// 新数据的下一个节点指向节点的原数据cur->_prev = newnode;// 原节点的 prev 指向新数据++_size;// 改变整个链表的长度// return iterator 通常表示一个函数返回一个 迭代器(iterator) 对象// 它指向某个容器(如 std::vector、std::list、std::map 等)中的特定元素。return iterator(newnode);// 返回新数据}iterator erase(iterator pos){// 先判断是不是空链表assert(pos != end());Node* del = pos._node;// 指向待删除数据的节点的指针Node* next = del->_next;// 指向待删除数据节点的下一个节点Node* prev = del->_prev;// 指向待删除数据节点的上一个节点prev->_next = next;// 上一个节点的 next 指针指向下一个节点next->_prev = prev;// 下一个节点的 prev 指针指向上一个节点delete del;// 删除当前的节点--_size;// 减小整个数组的size// 返回待删除节点的下一个节点return iterator(next);}private:Node* _head;size_t _size;};// 通用的 swap 模版。所有的类型都能用template <class T>void swap(T& a, T& b){T c(a); a = b; b = c;}// 特化的 list_swap 版本。仅适用于 list<T>类型 使用// 特化的模版函数可以提高程序的运行效率template<class T>void swap(list<T>& a, list<T>& b){a.swap(b);}
}

3. 完整测试代码

#define _CRT_SECURE_NO_WARNINGS 1#include<iostream>
using namespace std;
#include<list>
#include<vector>
#include<algorithm>#include"list.h"
//#include"teacher's list.h"class Pos
{
public:int _row;int _col;Pos(int row = 0, int col = 0):_row(row), _col(col){cout << "Pos(int row, int col)" << endl;}Pos(const Pos& p):_row(p._row), _col(p._col){cout << "Pos(const Pos& p)" << endl;}
};void test_list01()
{dza::list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);for (auto& e : lt1){cout << e << " ";}cout << endl;auto it1 = lt1.begin();while (it1 != lt1.end()){cout << *it1++ << " ";}cout << endl;
}void test_list02()
{dza::list<int> lt1;lt1.push_back(1);lt1.push_back(1);lt1.push_back(1);lt1.push_back(1);dza::list<int>::iterator it1 = lt1.begin();while (it1 != lt1.end()){*it1 = 2;cout << *it1 << " ";++it1;}cout << endl;for (auto e : lt1){cout << e << " ";}cout << endl;
}void test_list03()
{dza::list<Pos> lt2;// _row构造次数 == 0,_row构造次数 r1++// _col构造次数 == 0,_col构造次数 c1++Pos p1(1, 1);lt2.push_back(p1);// r1++,c1++lt2.push_back(Pos(2, 2)); // r1++,c1++// {}隐式类型转换lt2.push_back({ 3,3 });// r1++,c1++// 动用4次_row构造。4次_col构造dza::list<Pos>::iterator it2 = lt2.begin();while (it2 != lt2.end()){//cout << (*it2)._row << ":" << (*it2)._col << endl;// 为了可读性,特殊处理,省略了一个->// 两种读取方式。打印两次cout << it2->_row << ":" << it2->_col << endl;cout << it2.operator->()->_row << ":" << it2.operator->()->_col << endl;++it2;}cout << endl;
}void test_list04()
{dza::list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);for (auto& e : l1){cout << e << " ";}cout << endl;auto it1 = l1.begin();int x = 0;l1.pop_back();while (it1 != l1.end()){cout << *it1++ << " ";}cout << endl;// 头删完成之后需要更新一下it1。否则it1指向原来的位置,为空的迭代器l1.pop_front();it1 = l1.begin();while (it1 != l1.end()){cout << *it1++ << " ";}cout << endl;l1.push_front(0);l1.push_front(1);for (auto& e : l1){cout << e << " ";}cout << endl;
}void test_list05()
{dza::list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);dza::list<int> l2(l1);for (auto& e : l1){cout << e << " ";}cout << endl;for (auto& e : l2){cout << e << " ";}cout << endl;dza::list<int> l3(3,1);for (auto& e : l3){cout << e << " ";}cout << endl;l3.clear();for (auto& e : l3){cout << e << " ";}cout << endl;
}void test_list06()
{dza::list<int> l1;l1.push_back(1);l1.push_back(2);l1.push_back(3);l1.push_back(4);for (auto& e : l1){cout << e << " ";}cout << endl;auto it1 = l1.begin();it1++;it1++;l1.insert(it1, 30);for (auto& e : l1){cout << e << " ";}cout << endl;l1.erase(l1.begin());for (auto& e : l1){cout << e << " ";}cout << endl;}int main()
{test_list06();return 0;
}

相关文章:

C++ STL:从零开始模拟实现 list 容器

文章目录 引言1. 疑难点解析1.1 迭代器类为什么设置三个模版参数&#xff1f; 2. 完整源码3. 完整测试代码 引言 C 标准模板库(STL)中的 list 是一个双向链表容器&#xff0c;它提供了高效的插入和删除操作。本文将带领你一步步实现一个简化版的 list 容器&#xff0c;帮助你深…...

Spark_SQL

Spark-SQL连接Hive 内嵌的 HIVE 外部的 HIVE 运行 Spark beeline&#xff08;了解&#xff09; Spark Thrift Server 是 Spark 社区基于 HiveServer2 实现的一个 Thrift 服务。旨在无缝兼容HiveServer2。 运行Spark-SQL CLI Spark SQL CLI 可以很方便的在本地运行 Hive 元数…...

20242817李臻《Linux⾼级编程实践》第8周

20242817李臻《Linux⾼级编程实践》第8周 一、AI对学习内容的总结 计算机网络概述 1. 计算机网络概述 计算机网络的定义&#xff1a;通过通信线路将地理位置不同的多台计算机连接起来&#xff0c;实现资源共享和信息传递。网络的组成&#xff1a; 硬件&#xff1a;计算机、…...

《Java工程师面试核心突破》专栏简介

《Java工程师面试核心突破》专栏简介 &#x1f525; 大厂Offer收割机 | 源码级技术纵深 | 90%高频考点覆盖 专栏定位 「拒绝八股文&#xff0c;直击技术本质」 本专栏专为Java中高级工程师量身定制&#xff0c;通过6大核心模块、30个硬核专题&#xff0c;系统性拆解大厂面试…...

Spark-SQL与Hive

Spark-SQL与Hive的那些事儿&#xff1a;从连接到数据处理 在大数据处理领域&#xff0c;Spark-SQL和Hive都是非常重要的工具。今天咱们就来聊聊它们之间的关系&#xff0c;以及怎么用Spark-SQL去连接Hive进行数据处理。先说说Hive&#xff0c;它是Hadoop上的SQL引擎&#xff0…...

Keil5没有stm32的芯片库

下载完重启就行了&#xff0c;我这里就不演示了&#xff0c;stm已经下载&#xff0c;随便选的一个芯片库演示一下...

Kafka 在小流量和大流量场景下的顺序消费问题

一、低流量系统 特点 消息量较少&#xff0c;吞吐量要求低。系统资源&#xff08;如 CPU、内存、网络&#xff09;相对充足。对延迟容忍度较高。 保证顺序消费的方案 单分区 单消费者 将消息发送到单个分区&#xff08;例如固定 Partition 0&#xff09;&#xff0c;由单个…...

Spark-SQL(四)

本节课学习了spark连接hive数据&#xff0c;在 spark-shell 中&#xff0c;可以看到连接成功 将依赖放进pom.xml中 运行代码 创建文件夹 spark-warehouse 为了使在 node01:50070 中查看到数据库&#xff0c;需要添加如下代码&#xff0c;就可以看到新创建的数据库 spark-sql_1…...

海外服务器安装Ubuntu 22.04图形界面并配置VNC远程访问指南

在云计算和远程工作日益普及的今天,如何高效地管理和使用海外服务器成为了一个热门话题。本文将详细介绍如何在海外的Ubuntu 22.04服务器上安装图形界面,并配置VNC服务来实现远程访问。无论您是开发者、系统管理员,还是只是想要更便捷地管理您的海外服务器,这篇指南都能为您…...

kafka 分区分散在不同服务器上的原理

目录 原理方面在 1- 5&#xff0c;如果对原理理解&#xff0c;可以直接到图例部分&#xff0c;看结果 1. 分区分配机制 2. 副本分配机制 3. 手动控制分区的分布 4.分区&#xff08;Partition&#xff09;如何分布在不同的 Broker 上&#xff1f; 5. 主分区&#xff08;Le…...

JavaScript 中的单例模式

单例模式在 JavaScript 中是一种确保类只有一个实例&#xff0c;并提供全局访问点的方式。由于 JavaScript 的语言特性&#xff08;如对象字面量、模块系统等&#xff09;&#xff0c;实现单例有多种方式。 常见实现方式 1. 对象字面量&#xff08;最简单的单例&#xff09; …...

19_大模型微调和训练之-基于LLamaFactory+LoRA微调LLama3

基于LLamaFactory微调_LLama3的LoRA微调 1. 基本概念1.1. LoRA微调的基本原理1.2. LoRA与QLoRA1.3. 什么是 GGUF 2.LLaMA-Factory介绍3. 实操3.1 实验环境3.2 基座模型3.3 安装 LLaMA-Factory 框架3.3.1 前置条件 3.4 数据准备3.5 微调和训练模型torch.cuda.OutOfMemoryError: …...

【Maven基础】

Maven&#xff1a;一个项目管理工具 前言 传统项目管理存在的问题&#xff1a; 依赖管理混乱 需要自己去网上搜 jar 包&#xff0c;找对版本很痛苦&#xff08;还容易找错&#xff09;某个库依赖另一个库&#xff08;传递依赖&#xff09;&#xff0c;你得自己挨个找齐不小心…...

衡石 ChatBI 用户手册-使用指南

产品概述​ 衡石 ChatBI 是一款融合了 AI 技术的智能数据分析工具&#xff0c;旨在为企业业务人员提供直观、高效的数据交互体验。通过自然语言处理技术&#xff0c;用户可以直接与数据进行对话&#xff0c;快速获取所需信息&#xff0c;从而为业务决策提供有力支持。此外&…...

DeepSeek+Cursor+Devbox+Sealos项目实战

黑马程序员DeepSeekCursorDevboxSealos带你零代码搞定实战项目开发部署视频教程&#xff0c;基于AI完成项目的设计、开发、测试、联调、部署全流程 原视频地址视频选的项目非常基础&#xff0c;基本就是过了个web开发流程&#xff0c;但我在实际跟着操作时&#xff0c;ai依然会…...

Unreal 如何实现一个Vehicle汽车沿着一条指定Spline路径自动驾驶

文章目录 前言准备工作驾驶原理驾驶轨迹自动驾驶油门控制科普:什么是PID?转向控制科普:点乘和叉乘最终蓝图最后前言 Unreal Engine 的 Chaos Vehicle System(原PhysX Vehicle)是一套基于物理模拟的车辆驾驶系统,支持高度可定制的车辆行为,适用于赛车、模拟驾驶等游戏类…...

开源脚本分享:用matlab处理ltspice生成的.raw双脉冲数据

Author :PNJIE DATE: 2025/04/21 V0.0 前言 该项目旨在使用Matlab处理LTspice的.raw文件&#xff0c;包括动态计算和绘图&#xff0c;部分脚本基于LTspice2Matlab项目&#xff1a; PeterFeicht/ltspice2matlab: LTspice2Matlab - 将LTspice数据导入MATLAB github地址&#x…...

聊透多线程编程-线程互斥与同步-13. C# Mutex类实现线程互斥

目录 一、什么是临界区&#xff1f; 二、Mutex类简介 三、Mutex的基本用法 解释&#xff1a; 四、Mutex的工作原理 五、使用示例1-保护共享资源 解释&#xff1a; 六、使用示例2-跨进程同步 示例场景 1. 进程A - 主进程 2. 进程B - 第二个进程 输出结果 ProcessA …...

Halcon应用:相机标定之应用

提示&#xff1a;若没有查找的算子&#xff0c;可以评论区留言&#xff0c;会尽快更新 Halcon应用&#xff1a;相机标定之应用 前言一、Halcon应用&#xff1f;二、应用实战1、如何应用标定&#xff08;快速&#xff09;2、代码讲解&#xff08;重要&#xff09;2.1 、我们还是…...

【计算机视觉】CV实战项目- CMU目标检测与跟踪系统 Object Detection Tracking for Surveillance Video

CMU 目标检测与跟踪系统&#xff08;Object Detection & Tracking for Surveillance Video&#xff09; 1. 项目概述2. 技术亮点&#xff08;1&#xff09;目标检测模型&#xff08;2&#xff09;多目标跟踪&#xff08;MOT&#xff09;&#xff08;3&#xff09;重识别&am…...

报错 | 配置 postcss 出现 报错:A `require()` style import is forbidden.

背景&#xff1a;安装 postcss&#xff0c;配置时&#xff0c;出现报错&#xff1a;A require() style import is forbidden. 翻译&#xff1a;禁止导入require&#xff08;&#xff09;样式 解决&#xff1a;前头添加 /* eslint-env node */ &#xff0c;也飘红&#xff0c…...

[Qt]双击事件导致的问题

有如下代码 #include "mymodel.h" #include <QDebug>myModel::myModel(QObject *parent) : QAbstractTableModel(parent) {status << Qt::Unchecked << Qt::Unchecked << Qt::Unchecked; }int myModel::rowCount(const QModelIndex &pa…...

[SpringBoot]配置文件

通过案例可以不难发现&#xff0c;springboot实际上就是spring的一种辅助工具&#xff0c;帮我们更快地使用spring开发。尤其是配置这块&#xff0c;注解springboot解决了很多繁琐重复的配置操作。 但在实际开发需求&#xff0c;当然不可能只用springboot已经配置好的配置信息。…...

前端框架开发编译阶段与运行时的核心内容详解Tree Shaking核心实现原理详解

前端框架开发编译阶段与运行时的核心内容详解 一、开发编译阶段 开发编译阶段是前端框架将源代码转换为浏览器可执行代码的核心过程,涉及代码转换、优化和资源整合。 模块打包与依赖管理 • 依赖图构建:工具(如Webpack、Vile)通过静态分析生成模块依赖关系图,支持按需加载…...

idea2024.1双击快捷方式打不开

idea2024.1突然双击快捷方式打不开&#xff0c;使用管理员运行也打不开 在安装的idea路径下的bin目录下双击打开idea.bat文件&#xff0c;要是打不开使用txt格式打开&#xff0c;打开后在最后一行加上pause&#xff0c;之后保存。 看看报错信息是不是有一个initializedExcept…...

鸿蒙NEXT开发LRUCache缓存工具类(单例模式)(ArkTs)

import { util } from kit.ArkTS;/*** LRUCache缓存工具类&#xff08;单例模式&#xff09;* author 鸿蒙布道师* since 2025/04/21*/ export class LRUCacheUtil {private static instance: LRUCacheUtil;private lruCache: util.LRUCache<string, any>;/*** 私有构造函…...

开源身份和访问管理(IAM)解决方案:Keycloak

一、Keycloak介绍 1、什么是 Keycloak&#xff1f; Keycloak 是一个开源的身份和访问管理&#xff08;Identity and Access Management - IAM&#xff09;解决方案。它旨在为现代应用程序和服务提供安全保障&#xff0c;简化身份验证和授权过程。Keycloak 提供了集中式的用户…...

Latex科研入门教程

Introduction 这篇文章适合有markdown基础的人看,不会的人可以先去学一下markdown. 仅适用于科研入门. 本文使用的latex环境为overleaf Latex概况 文件格式 以.tex为结尾的文件可能有多个.tex文件最终只编译一个文件,相当于一个文件控制其他子文件. Latex 代码分为三种&…...

CSS 中实现 div 居中有以下几种常用方法

在 CSS 中实现 div 居中有以下几种常用方法&#xff0c;具体取决于需要 ​​水平居中​​、​​垂直居中​​ 还是 ​​两者兼具​​。以下是详细解决方案&#xff1a; 目录 一、水平居中&#xff08;Horizontal Centering&#xff09; 1. 行内块元素&#xff08;Inline-Blo…...

win11修改文件后缀名

一、问题描述 win11系统中&#xff0c;直接添加.py后缀后仍然是txt文本文件 二、处理方式&#xff1a; 点击上方三个小点点击“选项”按钮 点击“查看”取消“隐藏已知文件类型的扩展名”选项点击“应用” 此时&#xff0c;“.txt”文件后缀显示出来了。将txt删去&#xff0c…...

【数据结构和算法】3. 排序算法

本文根据 数据结构和算法入门 视频记录 文章目录 1. 排序算法2. 插入排序 Insertion Sort2.1 概念2.2 具体步骤2.3 Java 实现2.4 复杂度分析 3. 快排 QuickSort3.1 概念3.2 具体步骤3.3 Java实现3.4 复杂度分析 4. 归并排序 MergeSort4.1 概念4.2 递归具体步骤4.3 Java实现4.4…...

k8s之 kube-prometheus监控

Kubernetes 中的 kube-prometheus 是一个基于 Prometheus Operator 的完整监控解决方案&#xff0c;它集成了 Prometheus、Alertmanager、Grafana 以及一系列预定义的监控规则和仪表盘&#xff0c;专为 Kubernetes 集群设计。 一、核心组件介绍 Prometheus Operator &#xf…...

Docker Compose 和 Kubernetes(k8s)区别

前言&#xff1a;Docker Compose 和 Kubernetes&#xff08;k8s&#xff09;是容器化技术中两个常用的工具&#xff0c;但它们的定位、功能和适用场景有显著区别。以下是两者的核心对比&#xff1a; ​​1. 定位与目标​​ ​​特性​​ ​​Docker Compose​​ ​​Kubernet…...

【SpringBoot】HttpServletRequest获取使用及失效问题(包含@Async异步执行方案)

目录 1. 在 Controller 方法中作为参数注入 2.使用 RequestContextHolder &#xff08;1&#xff09;失效问题 &#xff08;2&#xff09;解决方案一&#xff1a; &#xff08;3&#xff09;解决方案二&#xff1a; 3、使用AutoWrite自动注入HttpServletRequest 跨线程调…...

【Easylive】为什么需要手动转换 feign.Response 到 HttpServletResponse

【Easylive】项目常见问题解答&#xff08;自用&持续更新中…&#xff09; 汇总版 为什么需要手动转换 feign.Response 到 HttpServletResponse&#xff1f; feign.Response 是 Feign 客户端调用远程服务后返回的原始 HTTP 响应对象&#xff0c;而 HttpServletResponse 是…...

C语言交换函数:为什么必须用指针传递参数?

写一个简单交换两个变量值的函数,我们要理解C语言中参数传递的机制. C语言中的函数参数默认是按值传递,也就是说,如果我写一个函数,如 void swap(int a,int b) {int tmp a;a b;b tmp; }然后在函数内部交换a,b的值,这不会影响到函数外部的变量,因为传递的是值的副本. 就像…...

C#+Visual Studio 2022为AutoCAD 2022开发插件并显示在Ribbon选项卡

1.插件功能开发 &#xff08;1&#xff09;建立C#类库项目&#xff0c;添加必要引用&#xff0c;都是autocad二次开发相关的&#xff0c;要注意对引用的库修改其“复制文件”属性为false (2)项目调试使用“属性”打开“启用外部程序”&#xff0c;指定为机器上autocad2022的a…...

全景VR是什么?全景VR有什么热门用途?

全景VR的概念与技术特点 全景VR&#xff0c;即虚拟现实全景&#xff0c;是新型的视觉展示技术。通过拍摄和构建三维模拟环境&#xff0c;使浏览者能够通过网络获得三维立体的空间感觉&#xff0c;仿佛身临其境。全景VR技术的核心在于360全景图像的捕捉和展示&#xff0c;它允许…...

美创科技20周年庆典顺利举行

2025年4月19日 美创科技成立20周年 “稳健前行二十载&#xff0c;创新共赢新未来” 美创科技周年庆典在杭州总部顺利举行 美创科技20周年庆典精彩视频回顾 &#xff08;点击查看美创科技20周年庆典精彩视频回顾&#xff09; CEO致辞 20周年再出发&#xff0c;开启新增长周期…...

学习笔记二十二—— 并发五大常见陷阱

⚠️ 并发五大常见陷阱 目录 数据竞争 (Data Race)死锁 (Deadlock)竞态条件 & 饿死现象 (Race Condition & Starvation)悬挂指针 (Dangling Pointer)重复释放 (Double Free)开发自查清单 1. 数据竞争 (Data Race) 专业定义 两个及以上线程在缺乏同步的情况下同时访问同…...

精益数据分析(10/126):深度剖析数据指标,驱动创业决策

精益数据分析&#xff08;10/126&#xff09;&#xff1a;深度剖析数据指标&#xff0c;驱动创业决策 在创业的旅程中&#xff0c;数据指标是我们把握方向的关键工具。今天&#xff0c;我想和大家一起深入学习《精益数据分析》中关于数据指标的知识&#xff0c;共同探索如何利…...

冒泡排序详解

void bubbleSort(std::vector& arr) { int n arr.size(); for (int i 0; i < n-1 ; i) { // 需要 n-1 轮 原理是 3个元素 两轮比交即可 10个元素9轮比较即可 bool swapped false; // 用于优化&#xff0c;检测是否发生交换 for (int j 0; j < n - i -1 ; j) { //…...

小刚说C语言刷题——1039 求三个数的最大数

1.题目描述 已知有三个不等的数&#xff0c;将其中的最大数找出来。 输入 输入只有一行&#xff0c;包括3个整数。之间用一个空格分开。 输出 输出只有一行&#xff08;这意味着末尾有一个回车符号&#xff09;&#xff0c;包括1个整数。 样例 输入 1 5 8 输出 8 2.…...

【日志体系】ELK Stack与云原生日志服务

IaaS日志体系&#xff1a;ELK Stack与云原生日志服务 一、技术演进的双重脉络二、架构设计的范式差异三、关键技术突破解析四、前沿发展与行业实践 当某国际电商平台在"黑色星期五"遭遇每秒百万级日志洪峰时&#xff0c;其运维团队通过混合日志架构实现全链路追踪&am…...

spark和hadoop区别联系

区别 设计理念 Hadoop&#xff1a;主要解决大规模数据的存储和处理问题&#xff0c;其核心是 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;和 MapReduce 计算模型。HDFS 用于存储大规模数据&#xff0c;MapReduce 用于处理数据&#xff0c;它将数据处理过程分为 Map 和…...

240422 leetcode exercises

240422 leetcode exercises jarringslee 文章目录 240422 leetcode exercises[237. 删除链表中的节点](https://leetcode.cn/problems/delete-node-in-a-linked-list/)&#x1f501;节点覆盖法 [392. 判断子序列](https://leetcode.cn/problems/is-subsequence/)&#x1f501;…...

【上位机——MFC】菜单类与工具栏

菜单类 CMenu&#xff0c;封装了关于菜单的各种操作成员函数&#xff0c;另外还封装了一个非常重要的成员变量m_hMenu(菜单句柄) 菜单使用 添加菜单资源加载菜单 工具栏相关类 CToolBarCtrl-》父类是CWnd&#xff0c;封装了关于工具栏控件的各种操作。 CToolBar-》父类是CC…...

Spark-SQL连接Hive总结及实验

一、核心模式与配置要点 1. 内嵌Hive 无需额外配置&#xff0c;直接使用&#xff0c;但生产环境中几乎不使用。 2. 外部Hive&#xff08;spark-shell连接&#xff09; 配置文件&#xff1a;将hive-site.xml&#xff08;修改数据库连接为node01&#xff09;、core-site.xml、…...

20.3 使用技巧9

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的 20.3.13 DataGridView使用日期选择控件 有时为了输入方便或者固定日期格式&#xff0c;可以考虑点击DataGridView中某个单元格时出现…...

逻辑回归(Logistic Regression)

逻辑回归&#xff08;Logistic Regression&#xff09; 原理 通过 Sigmoid函数&#xff08; σ ( z ) 1 1 e − z σ(z) \frac{1}{1e^{-z}} σ(z)1e−z1​&#xff09;将线性回归输出 z w T x b z w^Tx b zwTxb 映射到 [0,1] 区间输出值表示样本属于正类的概率&#…...