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

c++阶梯之类与对象(中)< 续集 >

前文:

c++阶梯之类与对象(上)-CSDN博客

c++阶梯之类与对象(中)-CSDN博客


前言:

在上文中,我们学习了类的六个默认成员函数之构造,析构与拷贝构造函数,接下来我们来看看剩下的默认成员函数。 


目录

前文:

前言:

5. 赋值运算符重载

5.1 运算符重载

普通函数版 

运算符重载版 

 5. 2 赋值运算符重载

1. 赋值运算符重载格式

 2. 实例

注意: 

 5.3 特殊的运算符重载 前置++与后置++

 6. Date类的实现(多功能)

Date.h 

Date.cpp 

main.cpp 

补充知识:

7.const成员 

8. 取地址及const取地址操作符重载


5. 赋值运算符重载

5.1 运算符重载

我们知道函数重载,那么运算符重载又是什么?

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其
返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号。
函数原型:返回值类型 operator操作符(参数列表)
注意
<  > 不能通过连接其他符号来创建新的操作符:比如operator@
<  > 重载操作符必须有一个类类型参数
<  > 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义
 <  > 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
 <  >   .*  ::  sizeof  ?:  . 注意以上5个运算符不能重载。这个经常在笔试选择题中出

我们可以这样认为,运算符重载就是给运算符赋予一个新的含义,<专为自定义类型而生> 不过默认并不会改变运算符的基本逻辑。

我们来看看他在实际中的应用,我们实现两个Date类对象比较,1.是否相等 2. 是否小于

普通函数版 

我们可以看到,在这个版本里,代码编写者取名十分随意,那么当别人看到这段代码,内心的活动估计十分激昂。虽然在功能上很完美,但其代码却会让人抓耳挠腮。 

class Date
{
public:Date(int year = 2024, int month = 2, int day = 6){_year = year;_month = month;_day = day;}//Data类拷贝构造,赋值重载,析构都不需要自己实现bool compare1(const Date& d) //DateEqual {return _year == d._year&& _month == d._month&& _day == d._day;}bool compare2(const Date& d)//DateLess{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;}private:int _year;int _month;int _day;
};
int main()
{Date d1(2024, 2, 7);Date d2(1997, 1, 1);cout << d1.compare1(d2) << endl;cout << d1.compare2(d2) << endl;return 0;
}

运算符重载版 

这一版本的代码可读性大大增强,还免去了起名的麻烦,同时在调用函数的时候,自定义类型也可以像内置类型一样简单快捷的使用运算符。

class Date
{
public:Date(int year = 2024, int month = 2, int day = 6){_year = year;_month = month;_day = day;}//Data类拷贝构造,赋值重载,析构都不需要自己实现bool operator==(const Date& d){return _year == d._year&& _month == d._month&& _day == d._day;}bool operator<(const Date& d){if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;}private:int _year;int _month;int _day;
};
int main()
{Date d1(2024, 2, 7);Date d2(1997, 1, 1);return 0;
}int main()
{Date d1(2024, 2, 7);Date d2(1997, 1, 1);/*cout << d1.operator<(d2) << endl;cout << d1.operator==(d2) << endl;*/cout << (d1 < d2) << endl;//在编译器看来,等同于cout << d1.operator<(d2) << endl;cout << (d1 == d2) << endl;//在编译器看来,等同于cout << d1.operator==(d2) << endl;return 0;
}

 注意:因为 << 的运算符很高,因此在调用时需要加括号。

运算符重载并不会改变运算符的底层逻辑,因此对于双操作数运算符来说,左操作数就是函数的第一个参数,右操作数是第二个参数。

那么运算符重载能定义成全局的吗,是的可以,但是这样我们就不能访问类的私有成员。但将类成员公有化,如何保证封装性呢?

我们可以使用友元函数,或者定义成成员函数。 

 5. 2 赋值运算符重载

1. 赋值运算符重载格式

参数类型:const T&,传递引用可以提高传参效率
返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
检测是否自己给自己赋值
返回*this :要复合连续赋值的含义 

 2. 实例

我们发现,所谓的赋值重载与之前学到的拷贝构造几乎是一个模子里刻出来的,既然他们一样,那我们还有必要学他吗?

这里有一个误区,他们的实现确实一样,但有一个不同点。

<  > 拷贝构造是对并不存在的对象进行拷贝构造,既有拷贝又有构造;

<  > 赋值重载是对已经存在的对象进行赋值(拷贝)。 

class Date
{
public:Date(int year = 2024, int month = 2, int day = 6){_year = year;_month = month;_day = day;}Date(Date& d){_year = d._year;_month = d._month;_day = d._day;}bool operator==(const Date& d){return _year == d._year&& _month == d._month&& _day == d._day;}bool operator<(const Date& d){if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;}bool operator!=(const Date& d){return !(*this == d);}Date& operator=(const Date& d){if (*this != d){_year = d._year;_month = d._month;_day = d._day;}return *this;}private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 2, 7);Date d2(1997, 1, 1);int a = 10;int b = 20;Date d3 = d1;//拷贝构造,即Date d3(d1);Date d4;d4 = d1;//赋值重载return 0;
}

我们在汇编视角可以看的更加清晰。 

  

注意: 

赋值重载只能定义成类的成员函数,不能定义成全局函数。

<  > 编译器不支持定义为全局函数,如果定义成全局会报错。

<  > 定义成全局函数,那么类中没有实现,作为默认成员函数之一,编译器会自动生成一个默认赋值重载,那么当调用的时候就会产生冲突。

<  > 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝。注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值

我们不写,编译器会自动生成,那么我们还需要写吗?

视情况而定,值拷贝对于Date类来说很适用,那么对于我们之前写的Stack类呢?他会造成不小的麻烦 。关于这一点,在c++阶梯之类与对象(中)-CSDN博客中的拷贝构造函数一节有详细讲解,感兴趣的宝子可以去看看。

 5.3 特殊的运算符重载 前置++与后置++

前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确重载
C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器
自动传递

Date operator++(int)//后置++,后置++使用后加1,因此返回的结果是自己本身,返回之后自身+1
{Date tmp = *this;_day+=1;return tmp;
}Date& operator++()//前置++,前置++使用前++,前置++返回的结果是自身+1
{_day++;return *this;
}

 6. Date类的实现(多功能)

在Date类实现常用运算符的重载,日期计算器,两日期的间隔等功能。

Date.h 

#include<iostream>
using namespace std;
class Date
{
public:// 获取某年某月的天数int GetMonthDay(int year, int month);// 全缺省的构造函数Date(int year , int month , int day );// 拷贝构造函数Date(const Date& d);// 赋值运算符重载Date& operator=(const Date& d);// 析构函数~Date();// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day);// 日期-天数Date operator-(int day);// 日期-=天数Date& operator-=(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();// >运算符重载bool operator>(const Date& d);// ==运算符重载bool operator==(const Date& d);// >=运算符重载bool operator >= (const Date& d);// <运算符重载bool operator < (const Date& d);// <=运算符重载bool operator <= (const Date& d);// !=运算符重载bool operator != (const Date& d);// 日期-日期 返回天数int operator-(const Date& d);//打印void Print();private:int _year;int _month;int _day;};

Date.cpp 

#include"Date.h"
//获取每个月的天数
int Date::GetMonthDay(int year, int month)
{int monthDays[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if ((month == 2) && ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)){return 29;}return monthDays[month];
}
//全缺省构造函数
Date::Date(int year = 1997, int month = 1, int day = 1)
{_year = year;_month = month;_day = day;
}//拷贝构造
Date::Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}//赋值运算符重载
Date& Date::operator=(const Date& d)
{if (*this != d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}//析构
Date::~Date()
{;
}//日期+=天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}//日期+天数
Date Date::operator+(int day)
{Date tmp = *this;tmp += day;return tmp;
}//日期-=天数
Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){_day += GetMonthDay(_year, _month);_month--;if (_month == 0){_year--;_month = 12;}}return *this;
}//日期-天数
Date Date::operator-(int day)
{Date tmp = *this;//拷贝构造tmp -= day;return tmp;}//后置++
Date Date::operator++(int)//后置++,后置++使用后加1,因此返回的结果是自己本身,返回之后自身+1
{Date tmp = *this;_day++;return tmp;
}//前置++
Date& Date::operator++()//前置++,前置++使用前++,前置++返回的结果是自身+1
{_day++;return *this;
}//后置--
Date Date::operator--(int)
{Date tmp = *this;_day --;return tmp;
}//前置--
Date& Date::operator--()
{_day--;return *this;
}//重载==
bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}//重载!=
bool Date::operator!=(const Date& d)
{return !(*this == d);
}//重载<
bool Date::operator<(const Date& d)
{if (_year < d._year){return true;}else if (_year == d._year){if (_month < d._month){return true;}else if (_month == d._month){return _day < d._day;}}return false;
}//重载<=
bool Date::operator<=(const Date& d)
{return (*this < d) || (*this == d);
}//重载>
bool Date::operator>(const Date& d)
{return !(*this <= d);
}//重载>=
bool Date::operator>=(const Date& d)
{return !(*this < d);
}//日期-日期=天数
int Date::operator-(const Date& d)
{Date max = *this, min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){min += 1;n++;}return n * flag;	
}//打印
void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}

main.cpp 

#include"Date.h"int main()
{Date d1(2024, 2, 7);Date d2(1997, 5, 3);cout << (d1 - d2) << endl;d1 -= 10;d1.Print();d2 += 20;d2.Print();cout << (d1 < d2) << endl;Date d3(1, 1, 1);d1.Print();d3 = d1++;d3.Print();++d3;d3.Print();return 0;
}

Date的实现是对近期知识的总结,糅合了许多语法,并且难度也不大,值得一写。 

补充知识:

补充上述相关的简略友元与操作数顺序知识。 这里使用重载流插入操作符<< 来进行演示。

 我们根据所学的知识写了 << 的重载成员函数,但在使用的时候出现了问题。

我们之前说过, 运算符重载并不会改变运算符的底层逻辑,因此对于双操作数运算符来说,左操作数就是函数的第一个参数,右操作数是第二个参数。

因此按我们写的,应该这么使用

但很显然,这与我们预期的不符。成员函数隐含形参this,这个我们没有办法更改,因此只能将他实现为全局函数,然后更改函数参数的顺序。这里会用到友元,现在我们只需要知道友元的存在,不必深究。

虽然此时可以使用 << 输出Date类型了,但他只能输出一个,正常的 << 是可以连续流插入的。

这里的问题在于运算符的结合性,<< 是从左往右,cout<<d1 之后需要返回一个值,然后再调用 << 。我们做如下更改,

此时的流插入操作符重载和我们心目中的就一般无二了。 

7.const成员 

将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

我们知道,成员函数中隐含的参数this指针是不允许显式写出来的,因此我们要将this指针const化就只能通过上面的方法。

请思考下面的几个问题:
1. const对象可以调用非const成员函数吗?
2. 非const对象可以调用const成员函数吗?
3. const成员函数内可以调用其它的非const成员函数吗?
4. 非const成员函数内可以调用其它的const成员函数吗?

8. 取地址及const取地址操作符重载

这两个默认成员函数一般不用重新定义 ,编译器默认会生成。

class Date
{
public :
Date* operator&()
{
return this ;
}
const Date* operator&()const
{
return this ;
}
private :
int _year ; // 年
int _month ; // 月
int _day ; // 日
};

这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需
要重载,比如想让别人获取到指定的内容! 

相关文章:

c++阶梯之类与对象(中)< 续集 >

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 前言&#xff1a; 在上文中&#xff0c;我们学习了类的六个默认成员函数之构造&#xff0c;析构与拷贝构造函数&#xff0c;接下来我们来看看剩下…...

GitLag所有操作-汇总

1、MAC Git环境设置 跳转 Git通过Token拉代码&#xff1a; 跳转 Git基础操作&#xff1a;拉、put、删 跳转 Git回滚操作&#xff1a; 跳转 Git回滚操作-复杂 跳转 对于Commit但是还没有push的代码&#xff0c;如果回滚&#xff1a; 跳转...

JSch - 配置SFTP服务器SSH免密登录

文章目录 1. 什么是SFTP2. 什么是Jsch以及它的作用3. Linux中配置SSH密钥登录4. sftp服务器认证机制5. publickey和password两种方式登录sftp的API调用6. 代码可以如下改造&#xff1a; 需求&#xff1a;做一个通过ssh免密登录的需求&#xff0c;是基于原先密码登录sftp服务器的…...

RISC-V指令格式

RISC-V指令格式 1 RISC-V指令集命名规范2 RISC-V指令集组成2.1 基础整数指令集2.2 扩展指令集 3 RISC-V指令格式3.1 指令表述3.2 指令格式 本文属于《 RISC-V指令集基础系列教程》之一&#xff0c;欢迎查看其它文章。 1 RISC-V指令集命名规范 前面提到过RV32I&#xff0c;这是…...

Linux 文件比较工具

在Linux系统中&#xff0c;文件比较是一种常见的任务&#xff0c;用于比较两个文件之间的差异。文件比较可以帮助我们找出两个文件的不同之处&#xff0c;或者确定它们是否完全相同。在Linux中&#xff0c;有多种方法可以进行文件比较。 1. diff 在Linux中&#xff0c;diff命…...

【GAMES101】Lecture 17 材质

目录 材质 漫反射 镜面反射 折射-Snell’s Law Fresnel Reflection / Term&#xff08;菲涅耳项&#xff09; 微表面模型 各向同性与各向异性 BRDF的性质 测量BRDF 材质 渲染方程中的BRDF描述了物体是如何与光线作用的&#xff0c;而物体的材质决定了它看起来是怎么样…...

数模.matlab画图

一、mesh函数 上图是平常用到的方式 例题&#xff1a; 上图的meshgrid函数相当于上上图的前三个指令&#xff08;temp&#xff0c;x,y&#xff09; mash函数&#xff1a; mashc函数&#xff1a; mashz函数&#xff1a; 上图subplot函数的作用是将下标为index的图片放到对应的x&…...

[word] word表格表头怎么取消重复出现? #媒体#笔记#职场发展

word表格表头怎么取消重复出现&#xff1f; word表格表头怎么取消重复出现&#xff1f;在Word中的表格如果过长的话&#xff0c;会跨行显示在另一页&#xff0c;如果想要在其它页面上也显示表头&#xff0c;更直观的查看数据。难道要一个个复制表头吗&#xff1f;当然不是&…...

vue项目开发vscode配置

配置代码片段 步骤如下&#xff1a; 文件->首选项->配置用户代码片段新增全局代码片段起全局代码片段文件名“xxx.code-snippets” 这里以配置vue2初始代码片段为例&#xff0c;配置具体代码片段 {"name": "vue-sph","version": "…...

BUUCTF-Real-[Tomcat]CVE-2017-12615

目录 漏洞描述 一、漏洞编号&#xff1a;CVE-2017-12615 二、漏洞复现 get flag 漏洞描述 CVE-2017-12615&#xff1a;远程代码执行漏洞 影响范围&#xff1a;Apache Tomcat 7.0.0 - 7.0.79 (windows环境) 当 Tomcat 运行在 Windows 操作系统时&#xff0c;且启用了 HTTP P…...

Qt应用软件【协议篇】http协议get、post示例

文章目录 QT Http的APIHTTP GET 请求示例HTTP POST 请求示例伪装chrome浏览器get请求QT Http的API QNetworkAccessManager 作用:管理所有的网络请求,是发送请求和接收响应的中心点。主要功能: 发送HTTP请求(GET, POST, PUT, DELETE等)。处理网络请求的异步回调。管理网络…...

如何选择Centos的替代者

开篇废话&#xff1a;许久许久没有更新博客了。寒假回到故土&#xff0c;大雪虽然没有封路&#xff0c;还是增加了不出门的决心&#xff0c;虽然年岁已高&#xff0c;但是不学习还是不踏实&#xff0c;那就借着写作再继续前行。 背景&#xff1a;信息化部门&#xff0c;掌管着…...

【Java数据结构】ArrayList和LinkedList的遍历

一&#xff1a;ArrayList的遍历 import java.util.ArrayList; import java.util.Iterator; import java.util.List;/*** ArrayList的遍历*/ public class Test {public static void main(String[] args) {List<Integer> list new ArrayList<>();list.add(5);list…...

springboot163美食推荐商城的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…...

[机器学习]K-means——聚类算法

一.K-means算法概念 二.代码实现 # 0. 引入依赖 import numpy as np import matplotlib.pyplot as plt # 画图依赖 from sklearn.datasets import make_blobs # 从sklearn中直接生成聚类数据# 1. 数据加载 # 生成&#xff08;n_samples&#xff1a;样本点&#xff0c;centers&…...

并发编程 java锁机制

1、什么是锁&#xff0c;为什么需要锁&#xff1f; 并发环境下&#xff0c;会存在多个线程对同一个资源进行争抢的情况&#xff0c;假设线程A对资源正在进行修改&#xff0c;此时线程B又对同一资源进行了修改&#xff0c;就会导致数据不一致的问题。为了解决这个问题&#xff…...

Onerugged三防平板厂家丨三年质保承诺丨三防平板PAD

行业领先产品——Onerugged三防平板。凭借着十年的经验&#xff0c;我们深知终端设备在各个行业中的重要性&#xff0c;因此致力于为用户提供高可靠性的解决方案。 Onerugged三防平板以其卓越的性能和全方位的保护功能&#xff0c;在市场上脱颖而出。首先&#xff0c;它拥有IP…...

Android 系统启动流程

一.Android系统启动流程基本框架 Android系统完整的启动过程&#xff0c;从系统层次角度可分为 Linux 系统层、Android 系统服务层、Zygote进程模型三个阶段&#xff1b;从开机到启动 Home Launcher 完成具体的任务细节可分为七个步骤&#xff0c;下面就从具体的细节来解读 And…...

鸿蒙学习-app.json5配置文件

官网文档参考&#xff1a;https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/app-configuration-file-0000001427584584-V3 位于AppScope下的app.json5配置文件 一、基础属性 {"app": {/*包名*/"bundleName": "com.example.dem…...

华为OD机试 - 智能成绩表( Python C C++ JavaGo JS PHP)

题目描述 小明是一名新老师&#xff0c;他需要将学生按考试总分或单科分数进行排名。学生的信息包括姓名、科目和对应的分数。帮助小明完成这个任务吧&#xff01; 输入描述 第一行包含两个整数 n 和 m&#xff0c;分别代表学生人数和科目数量。 0 < n < 1000 < m &…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...