进一步了解C++函数的各种参数以及重载,了解C++部分的内存模型,C++独特的引用方式,巧妙替换指针,初步了解类与对象。满满的知识,希望大家能多多支持

news2024/12/24 11:30:42

C++的编程精华,走过路过千万不要错过啊!废话少说,我们直接进入正题!!!!

函数高级

C++的函数提高

函数默认参数

在C++中,函数的形参列表中的形参是可以有默认值的。

语法返回值类型 函数名 (参数 = 默认值){}

示例

#include<iostream>
using namespace std;
​
//函数的默认参数
//如果我们自己传入数据,就用自己的数据,如果没有那就用默认值
//语法:返回值类型 函数名称(形参 = 默认值){}
int func(int a,int b = 20,int c = 30)
{
    return a + b + c;
}
​
//注意事项
//如果某个位置已经有了默认参数,那么这个位置从左往右都必须有默认值
//如果函数声明有了默认参数,函数实现就不能有默认值
//声明和实现只能有一个默认参数
int func2(int a = 10,int b = 20);
int func2(int a = 10,int b = 20)//error
{
    return a + b;
}
​
​
int main()
{
    cout << func(10) << endl;
    cout << func(30) << endl;
    return 0;
}

函数占位参数

C++中函数的形参列表里可以有占位参教,用来做占位,调用函数时必须填补该位置

语法返回值类型 函数名 (数据类型){}

在现阶段函数的占位参数存在意义不大,但是后面的课程中会用到该技术

示例

#include<iostream>
using namespace std;
//函数占位参数,占位参数也可以有默认参数
void func(int a,int )
{
    cout << "this is func" << endl;
}
​
int main()
{
    func(10,10);//占位参数必须填补
    return 0;
}

函数重载

作用:函数名可以相同,提高复用性

函数重载满足条件

  1. 同一个作用域下

  2. 函数名称相同

  3. 函数参数类型不同或者个数不同或者顺序不同

注意:函数的返回值不可以作为函数重载的条件

示例

#include<iostream>
using namespace std;
​
//函数重载
//可以让函数名相同,提高复用性
​
//函数重载满足条件
//1. 同一个作用域下
//2. 函数名称相同
//3. 函数参数类型不同或者个数不同或者顺序不同
void func()
{
    cout << "func函数的调用" << endl;
}
​
void func(int a)
{
    cout << "func(int a)函数的调用!" << endl;
}
​
void func(double a)
{
    cout << "func(double a)函数的调用!" << endl;
}
​
void func(int a, double b)
{
    cout << "func(int a, double b)函数的调用!" << endl;
}
​
void func(double a,int b)
{
    cout << "func(double a,int b)函数的调用!" << endl;
}
​
int main()
{
    func();
    func(1);
    func(3.14);
    func(1,3.14);
    func(3.14,1);
    return 0;
}
func函数的调用
func(int a)函数的调用!
func(double a)函数的调用!
func(int a, double b)函数的调用!
func(double a,int b)函数的调用!

注意

int func(double a,int b)//这个无法重载,函数重载不可以作为函数重载条件
{
    cout << "func(double a,int b)函数的调用!" << endl;
}

函数重载的注意事项

  1. 引用作为重载条件

  2. 函数重载碰到函数默认参数

示例

#include<iostream>
using namespace std;
//引用作为重载条件
void func(int &a)
{
    cout << "func(int &a)" << endl;
}
​
void func(const int &a)//const int &a = 10;这是合法的代码
{
    cout << "func(const int &a)" << endl;
}
//函数重载碰到默认参数
void func2(int a,int b = 10)
{
    cout << "func2(int a,int b)" << endl;
}
​
void func2(int a)
{
    cout << "func2(int a)" << endl;
}
​
int main()
{
    int a = 10;
    func(a);//实现的是func(int &a)的函数
    func(10);//实现的是fun(const int &a)的函数
    func2(10);//当函数重载碰到默认参数,就会出现二义性,error
    return 0;
}

内存模型

C++核心编程

主要针对C++面向对象编程技术做详细讲解,探讨C++中的核心和精髓。

内存分区模型

C++程序在执行时。将内存大方向划分为4个区域

  1. 代码区:存放函数体的二进制代码。由操作系统进行管理的。

  2. 全局区:存放全局变量和静态变量以及常量。

  3. 栈区:由编译器自动分配释放,存放函数的参数值局部变量等。

  4. 堆区:由程序员分配和释放,若程序员下释放,程序结束时由操作系统回收。

内存四区意义

不同区域存放的数据。暖予不同的生金周明,给我们更大的灵活编程

程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域 代码区:

  1. 存放CPU执行的机器指令

  2. 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可

  3. 代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:

  1. 全局变量和静态变量存放在此

  2. 全局区还包含了常量区,字符串常量和其他常量也存放在此

  3. 该区域的数据在程序结束后由操作系统释放

示例:

#include<iostream>
using namespace std;
//全局变量
int g_a = 10;
int g_b = 10;
//const修饰的全局变量
const int c_g_a = 10;
const int c_g_b = 10;
int main()
{
    //创建普通的局部变量
    int a = 10;
    int b = 10;
    cout << "局部变量a的地址为:" << (int*)&a << endl;
    cout << "局部变量b的地址为:" << (int*)&b << endl;
    
    cout << "全局变量g_a的地址为:" << (int*)&g_a << endl;
    cout << "全局变量g_b的地址为:" << (int*)&g_b << endl;
    
    //静态变量,在普通变量前面加static,属于静态变量
    static int s_a = 10;
    static int s_b = 10;
    cout << "静态变量s_a的地址为:" << (int*)&s_a <<endl;
    cout << "静态变量s_b的地址为:" << (int*)&s_b <<endl;
    
    //常量
    //字符串常量
    cout << "字符串常量的地址:" << (int*)&"hello" << endl;
    //const修饰常量
    cout << "全局常量 c_g_a的地址为:" << (int*)&c_g_a << endl;
    cout << "全局常量 c_g_b的地址为:" << (int*)&c_g_b << endl;
    //const修饰的局部变量
    const int c_l_a = 10;
    const int c_l_b = 10;
    cout << "局部变量 c_l_a的地址为:" << (int*)&c_l_a << endl;
    cout << "局部变量 c_l_b的地址为:" << (int*)&c_l_b << endl;
    return 0;
}
局部变量a的地址为:0x61fe1c
局部变量b的地址为:0x61fe18
全局变量g_a的地址为:0x403010
全局变量g_b的地址为:0x403014
静态变量s_a的地址为:0x403018
静态变量s_b的地址为:0x40301c
字符串常量的地址:0x40409f
全局常量 c_g_a的地址为:0x404004
全局常量 c_g_b的地址为:0x404008
局部变量 c_l_a的地址为:0x61fe14
局部变量 c_l_b的地址为:0x61fe10

总结:

  1. C++中在程序运行前分为全局区和代码区

  2. 代码区特点是共享和只读

  3. 全局区中存放全局变量、静志变量、常量

  4. 常量区中存放const修饰的全局常量和字符串常量

程序运行后

栈区:

  1. 由编译器自动分配程放存放函数的参数,局部变量等

  2. 注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

示例:

#include<iostream>
using namespace std;
//栈区数据注意事项,不要返回局部变量的地址
//栈区的数据由编译器管理开辟和释放
int* func(int b)//形参数据也会放在栈区
{
    b = 100;
    int a = 10;//局部变量 存放在栈区,栈区的数据在执行完后自动释放
    return &a;//返回局部变量的地址
}
int main()
{
    //接受func函数的返回值
    int* p = func();
    cout << *p << endl;//这里显示错误,error
    return 0;
}

堆区:

  1. 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收

  2. 在C++中主要利用new在堆区开辟内存

示例:

#include<iostream>
using namespace std;
int* func()
{
    //利用new关键,可以将数据开辟到堆区
    //指针 本质是一个局部变量,放在栈上,但是数据放在堆区
    int *p = new int(10);
    return p;
}
​
int main()
{
    //堆区开辟数据
    int* a = func();
    cout << *a << endl;
    return 0;
}

总结: 堆区数据由程序员管理开辟和释放 堆区数据开辟利用new关键字进行开辟内存

new操作符

C++中利用new操作符在堆区开辟数据 堆区开辟的数据,由程序员手动开辟,手动释放。 释放利用操作符delete 语法:new 数据类型 利用new创建的数据,返回该数据对应的类型的指针

示例:

#include<iostream>
using namespace std;
//new的基本语法
int * func()
{
    //在堆区创建整型数据
    //返回该数据类型的指针
    int * p = new int(10);
    return p;
}
​
void test01()
{
    int * p = func();
    cout << *p << endl;
    //堆区的数据由程序员管理开辟,程序员管理释放
    //如果想释放堆区数据,
    delete p;
    cout << *p << endl;//非法访问,数据已释放,error,会出现乱码
}
​
//在堆区利用new开辟数据
void test02()
{
    //创建10个整型数据的数组在堆区
    int * arr = new int[10];//代表数组有10个元素
    for(int i = 0;i < 10; i++)
    {
        arr[i] = i + 100;
    }
    for(int i = 0;i < 10; i++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
    //释放堆区数组
    //释放数组的时候,要加[]才可以
    delete[] arr;
}
int main()
{
    test01();
    test02();
    return 0;
}

引用

引用C++核心编程引用的基本使用引用注意事项引用做函数参数引用函数返回值引用的本质常量引用

C++核心编程

引用的基本使用

作用:给变量起名

语法数据类型 &别名 = 原名

示例

#include<iostream>
using namespace std;
int main()
{
    int a = 10;
    int &b = a;
    b = 20;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    return 0;
}
a = 20
b = 20

引用注意事项

  1. 引用必须初始化

  2. 引用在初始化后,不可以改变

示例

#inlcude<iostream>
using namespace std;
int main()
{
    //引用必须初始化
    int a = 10;
    int &b;//error
    int &b = a;
    
    //引用初始化后,是不能更改引用的
    int c = 20;
    b = c;//error
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    return 0;
}

引用做函数参数

作用:函数传参时,可以利用引用的技术让形参修饰实参

优点:可以简化指针修改实参

示例

#include<iostream>
using namespace std;
//交换函数
//值传递
void mySwap01(int a,int b)
{
    int tmp = a;
    a = b;
    b = tmp;
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;//只在这个函数里面才有效,结束后还给系统
}
​
//指针的地址传递
void mySwap02(int* a,int* b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
​
//引用传递
void mySwap03(int &a,int &b)
{
    int tmp = a;
    a = b;
    b = tmp;
}
​
int main()
{
    int a = 10;
    int b = 20;
    mySwap01(a,b);
    mySwap02(&a,&b);
    mySwap03(a,b);//引用传递,形参会修饰实参的
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    return 0;
}

引用函数返回值

作用:引用是可以作为函数的返回值存在的

注意:不要返回局部变量引用

用法:函数调用作为左值

示例

#include<iostream>
using namespace std;
​
//不要返回局部变量的引用
int& test01()
{
    int a = 10;//局部变量存放在四区中的栈区
    return a;
}
​
//函数的调用可以作为左值
int& test02()
{
    static int a = 10;//静态变量存放在全局区,在程序结束后由系统回收
    return a;
}
​
int main()
{
    int &ref = test01();
    cout << ref << endl;//error,a的内存已经释放,属于非法访问
    int &ret = test02();
    cout << ret <<endl;
    test02() = 1000;
    cout << ret <<endl;//这里的值ret会改成1000
    return 0;
}
引用的本质

本质:引用的本质在C++内部实现是一个指针常量。

示例

#include<iostream>
using namespace std;
​
//发现是引用,转化为int* const ref = &a;
void func(int& ref)
{
    ref = 100;//ref是引用,转换为*ref = 100;
}
​
int main()
{
    int a = 10;
    
    //自动转换为int* const ref = &a;指针常量是指针指向不可改,也说明了为何引用不可更改
    int& ref = a;
    ref = 20;//内部发现ref是引用,自动帮我们转化为*ref = 20;
    
    cout << "a = " << a << endl;
    cout << "ref = " << ref << endl;
    
    func(a);
    return 0;
}

常量引用

作用:常量引用主要用来修饰形微,防止误操作

在函数形参列表中,可以加const修饰形参,防止形参改变实参

#include<iostream>
using namespace std;
​
void showValue(const int & ref)
{
    ref = 20;//error,无法改变
}
int main()
{
    //常量引用
    //使用场景:用来修饰形参,防止误操作
    int a = 10;
    //int & ref = 10;error 引用必须引用一块合法的内存空间
    const int & ref =10;//这是允许的,编译器将代码修改为 int temp = 10; const int & ref = temp;
    
    int b = 100;
    showValue(b);
    cout << b << endl;
    return 0;
}

类与对象

C++中类与对象的学习

C++面向对象的三大特性为:封装继承多态

C++认为万事万物皆为对象。对象上有其属性和行为

例如: 人可以作为对象,属性有姓名、年龄、身高、体重…… 行为有走、跑、跳、吃饭、唱歌……

车也可以作为对象,属性有轮胎、方向盘、车灯……行为有载人、放音乐、开启空调……

具有相同性质的对象,我们可以抽象称为,人属于人类,车属于车类

封装

封装的意义1

封装是C++面向对象的三大特性之一

封装的意义:

  1. 将属性和行为作为一个整体

  2. 将属性和行为加以权限控制

封装意义1:

在设计类的时候,属性和行为写在一起,表现事物

语法class 类名 { 访问权限: 属性 / 行为 };

设计一个圆类

求圆的周长

#include<iostream>
using namespace std;
​
const double PI = 3.14;
//设计一个圆类,求圆的周长
//圆求周长的公式:2 * PI * 半径
//class代表设计一个类,类后面紧跟着的就是类名称
class Circle
{
    //访问权限
    //公共权限
    public:
    
    //属性
    //半径
    int m_r;
    
    //行为
    //获取圆的周长
    double calculateZC()
    {
        return 2 * PI * m_r;
    }
    
};
​
int main()
{
    //通过圆类 创建一个具体的圆(对象)
    //实例化 (通过一个类 创建一个对象的过程)
    Circle c1;
    //对圆对象的属性进行赋值
    c1.m_r = 10;
    cout << "圆的周长" << c1.calculateZC() << endl;
    return 0;
}

设计一个学生类

属性有姓名学号,可以给姓名学号赋值,可以显示学生姓名和学号

#include<iostream>
#include<string>
using namespace std;
​
class Student
{
public:
    string m_Name;
    int m_Id;
    void showStudent()
    {
        cout << "姓名:" << m_Name << "\t" << "学号:" << m_Id << endl; 
    }
};
​
int main()
{
    //实例化对象
    Student s1;
    //s1对象进行属性赋值操作
    s1.m_Name = "zhangsan";
    s1.m_Id = 12345;
    s1.showStudent();
    
    //实例化对象
    Student s2;
    //s1对象进行属性赋值操作
    s2.m_Name = "lisi";
    s2.m_Id = 12346;
    s2.showStudent();
    return 0;
}

亦可以用下面的方式对类进行赋值操作

#include<iostream>
#include<string>
using namespace std;
​
class Student
{
public:
    //类中的属性和行为统一称为成员
    string m_Name;
    int m_Id;
public:
    void showStudent()
    {
        cout << "姓名:" << m_Name << "\t" << "学号:" << m_Id << endl; 
    }
    void setName(string name)
    {
        m_Name = name;
    }
    void setId(int id)
    {
        m_Id = id;
    }
};
​
int main()
{
    //实例化对象
    Student s1;
    //s1对象进行属性赋值操作
    s1.setName("zhangsan");
    s1.setId(12345);
    s1.showStudent();
    return 0;
}

封装的意义2

类在设计时,可以吧属性和行为放在不同的权限下,加以控制

访问权限有三种:

  1. public 公共权限

  2. protected 保护权限

  3. private 私有权限

示例

#include<iostream>
#include<string>
using namespace std;
//访问权限
//公共权限public    成员类内可以访问    类外也可以访问
//保护权限protected 成员类内可以访问    类外不可以访问
//私有权限private   成员类内可以访问    类外不可以访问
class Person
{
public:
    //公共权限
    string m_Name;
protected:
    //保护权限
    string m_Car;
private:
    //私有权限
    int m_Password;
public:
    void func()
    {
        m_Name = "zhangsan";
        m_Car = "Tractor";
        m_Password = 123456;
    }
    void func2()
    {
        cout << "1." << m_Name << "\t" << "2." << m_Car << "\t" << "3." << m_Password << endl;
    }
};
​
int main()
{
    //实例化具体对象
    Person p1;
    //p1.m_Car = "Benz";//error,保护权限内容在类外是访问不到的
    //p1.m_Password = 123;error,保护权限内容在类外是访问不到的
    p1.func();
    p1.m_Name = "Lisi";
    p1.func2();
    return 0;
}

struct和class的区别

在C++中struct和class唯一的区别就在于默认的访问权限不同 区别:

  1. struct 默认权限为公共

  2. class 默认权限为私有

#include<iostream>
using namespace std;
​
class C1
{
    int m_A;//默认权限是私有权限
};
​
struct C2
{
    int m_A;//默认权限是公共权限
};
​
int main()
{
    C1 c1;
    c1.m_A = 10;//error
    struct C2 c2;
    c2.m_A = 10;//正确的
    return 0;
}

成员属性设置为私有

优点1:将所有成员属性设置为私有,可以自己控制读写权限

优点2:对于写权限,我们可以检测数据的有效性

示例

#include<iostream>
#include<string>
//成员属性设置为私有
//可以自己控制读写权限
//对于写权限可以检测数据的有效性
using namespace std;
int main()
{
    return 0;
}

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

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

相关文章

spring cloud alibaba Sentinel(四)

服务雪崩 在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。 如果一个服务出现了问题&#xff0c;调用这个服务就会出现线程阻塞的情况&#xff0c; 此时若有大量的请求涌入&#xff0c;就会出现多条 线程阻塞等待&#xff0c;进而导致服务瘫痪。 由于服…

互联网新时代要到来了(三)什么是ChatGPT?

什么是ChatGPT? tips&#xff1a;资料来自百度百科、openAi、CSDN博主「琦在江湖飘」、Info写作社区、CSDN博主「夕小瑶」等网页资料。 1.什么是ChatGPT&#xff1f; ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;…

车载基础软件——AUTOSAR AP典型应用案例

我是穿拖鞋的汉子&#xff0c;魔都中一位坚持长期主义的工程师&#xff01; 最近不知道为何特别喜欢苏轼的一首词&#xff1a; 缺月挂疏桐&#xff0c;漏断人初静。谁见幽人独往来&#xff0c;缥缈孤鸿影。 惊起却回头&#xff0c;有恨无人省。拣尽寒枝不肯栖&#xff0c;寂寞…

Python机器学习入门笔记(1)—— Scikit-learn与特征工程

目录 机器学习算法分类 数据集工具 Scikit-learn Scikit-learn的安装 scikit-learn数据集API介绍 bunch对象 datasets模块 数据集的划分 train_test_split 代码示例 特征工程 特征提取 sklearn.feature_extraction API 字典特征提取示例 文本特征提取案例 jieba分…

无线蓝牙耳机哪个品牌音质好?性价比高音质好的蓝牙耳机排行榜

其实蓝牙耳机购买者最担忧的就是音质问题&#xff0c;怕拿到手的蓝牙耳机低频过重又闷又糊&#xff0c;听歌闷耳的问题&#xff0c;但从2021年蓝牙技术开始突飞猛进后&#xff0c;蓝牙耳机的音质、连接甚至是功能都发生了很大的变化&#xff0c;下面我分享几款性价比高音质的蓝…

运动控制器八通道PSO的视觉飞拍与精准输出

本文主要介绍正运动技术EtherCAT控制器在多通道视觉飞拍与多点精准输出上的应用&#xff0c;采用高性能ZMC408CE控制器&#xff0c;控制器内部高速FPGA实现硬件位置比较输出、精准输出功能&#xff0c;实现运动控制多通道视觉飞拍与精准输出功能。 一、硬件介绍 ZMC408CE是正…

基于微信小程序的新冠肺炎服务预约小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

OpenAI 官方api 阅读笔记

网站 API Key concepts Prompts and completions You input some text as a prompt, and the model will generate a text completion that attempts to match whatever context or pattern you gave it. Token  模型通过将文本分解成token来理解和处理, 处理token数量取…

STL讲解——模拟实现string

STL讲解——模拟实现string 经典的string类问题 大厂在面试中&#xff0c;面试官总喜欢让学生自己来模拟实现string类&#xff0c;最主要是实现string类的增、删、查、改、构造、拷贝构造、赋值运算符重载以及析构函数。大家看下自己可不可以写一个string类&#xff1f; cla…

第七章 - 聚合函数(count,avg,sum,max,min)和一些数学函数

第七章 - 聚合函数使用别名 ascount() 计数avg() 平均值sum() 求和max() 最大值min() 最小值一些数学计算函数Abs()Cos()Exp()Mod()Pi()radians()Sin()Sqrt()Power()Ceil()Floor()使用别名 as 在SQL中可以使用 as 来为一个字段或者一个值设置新的别名下面聚合函数的使用中就会…

chatgpt-api使用指南【官方泄露版】

chatgpt-api是 OpenAI ChatGPT 的非官方的 Node.js 包装器。 包括 TS 类型定义。 chatgpt-api不再需要任何浏览器破解——它使用泄露出来的OpenAI官方ChatGPT 在后台使用的模型。 &#x1f525; 推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 ✨你可以使用它开始构建…

dbeaver工具连接达梦数据库

、一 概述 DBeaver 是一个基于 Java 开发&#xff0c;免费开源的通用数据库管理和开发&#xff0c;DBeaver 采用 Eclipse 框架开发&#xff0c;支持插件扩展&#xff0c;并且提供了许多数据库管理工具&#xff1a;ER 图、数据导入/导出、数据库比较、模拟数据生成等&#xff0…

贝叶斯分析法在市场调研中的应用

一、市场调研的需求场景 在营销活动的用研调研时,我们经常会去问用户在不同平台的品类付费情况,以对比大促期间本品和竞品分别在哪些品类上具有市场优势,他们之间的差距具体在哪里、差距有多大。假如根据调研问卷结果,我们知道拼多多用户有30%的人在大促购买生鲜类,而淘宝…

7个营销人员常见的社交媒体问题以及解决方法

在如今的数字营销时代&#xff0c;许多营销人员都害怕在社交媒体上犯错。他们担心他们的社交媒体中的失误会演变成一场公关危机。面对一些常见的社交媒体问题&#xff0c;您需要知道如何避免和解决。对于数字营销人员来说&#xff0c;在现在这个信息互通&#xff0c;每时每刻都…

死锁检测组件-设想

死锁检测组件-设想 现在有三个临界资源和三把锁绑定了&#xff0c;三把锁又分别被三个线程占用。&#xff08;不用关注临界资源&#xff0c;因为锁和临界资源是绑定的&#xff09; 但现在出现这种情况&#xff1a;线程1去申请获取锁2&#xff0c;线程2申请获取锁3&#xff0c;…

【23种设计模式】行为型模式详细介绍(下)

前言 本文为 【23种设计模式】行为型模式 相关内容介绍&#xff0c;下边将对访问者模式&#xff0c;模板模式&#xff0c;策略模式&#xff0c;状态模式&#xff0c;观察者模式&#xff0c;备忘录模式&#xff0c;中介者模式&#xff0c;迭代器模式&#xff0c;解释器模式&…

面试官:熔断和降级有什么区别?

熔断和降级都是系统自我保护的一种机制&#xff0c;但二者又有所不同&#xff0c;它们的区别主要体现在以下几点&#xff1a; 概念不同触发条件不同归属关系不同 1.概念不同 1.1 熔断概念 “熔断”一词早期来自股票市场。熔断&#xff08;Circuit Breaker&#xff09;也叫自…

为SQL Server配置连接加密

前言很多客户在对数据库做安全审计时要求配置连接加密&#xff0c;本文就如何配置加密以及使用证书做一个系统的整理。连接加密首先&#xff0c;连接加密不是透明数据加密&#xff0c;很多人经常把两个概念混淆。连接加密是指客户端程序和SQL Server通信时的加密&#xff0c;保…

aws codebuild 自定义构建环境和本地构建

参考资料 Extending AWS CodeBuild with Custom Build Environments Docker in custom image sample for CodeBuild codebuild自定义构建环境 在创建codebuild项目的时候发现 构建环境是 Docker 映像&#xff0c;其中包含构建和测试项目所需的所有内容的完整文件系统 用ru…

实现一个简易koa2(一)— 基础架构

Koa 是一个新的 web 框架&#xff0c;由 Express 幕后的原班人马打造&#xff0c; 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数&#xff0c;Koa 帮你丢弃回调函数&#xff0c;并有力地增强错误处理。 Koa 并没有捆绑任…