探索C++14新特性:更强大、更高效的编程

探索C++14新特性:更强大、更高效的编程

C++14并没有太大的改动,就连官方说明中也指出,C++14相对于C++11来说是一个比较小的改动,但是在很大程度上完善了C++11,所以可以说C++14就是在C++11标准上的查漏补缺。

C++14在2014年8月18日正式批准宣布,同年12月15日正式发布release版本。本文中将就变动部分做一个总结,有需要改进和提升的地方希望大家批评指正。

1、引言

1.1新的语言特性

  • 变量模板
  • 泛型 lambda
  • lambda 初始化捕获
  • 新建/删除省略
  • 放宽对 constexpr 函数的限制
  • 二进制文字
  • 数字分隔符
  • 函数的返回类型推导
  • 具有默认非静态成员初始值设定项的 聚合类。

1.2新库功能

  • std::make_unique

  • std::shared_timed_mutex 和 std::shared_lock

  • std::整数序列

  • 标准::交换

  • std::引用

  • 以及对现有图书馆设施的许多小改进,例如

    • 某些算法的两范围重载

    • 类型特征的类型别名版本

    • 用户定义的basic_string、持续时间和复杂的文字

    • ETC。

2、变量模板

在C++11 及之前,我们只有针对类和函数的模板。C++14 中,新增了变量模板:

template<class T>
constexpr T pi = T(3.1415926535897932385L);
template<class T>
T circular_area(T r)
{return pi<T> *r * r;
}

变量模板同样可以在类变量中使用:

template<class T>
class X {static T s;
};
template<class T>
T X<T>::s = 0;X<int> x_int;
X<float> x_float;int main() {int value_int = X<int>::s;       // 获取 int 类型的静态成员变量值float value_float = X<float>::s; // 获取 float 类型的静态成员变量值// ...return 0;
}

类似函数和类模板,当变量模板被引用时,则会发生实例化。

3、lambda 表达式的新增功能

3.1 泛化

支持在 lambda 表达式中使用 auto 定义变量类型:这一特性允许 Lambda 的形参或者内部变量的类型由编译器自动推导,而不必显式指定。

#include <iostream>
#include <algorithm>int main() {// Lambda 表达式 glambda,用于输出元素auto glambda = [](auto& a) { std::cout << a << " "; };int a[] = { 4, 2, 6, 3, 7, 5 };// 使用 for_each 算法遍历数组,并对每个元素调用 Lambda 表达式 glambdastd::for_each(a, a + sizeof(a) / sizeof(int), glambda);std::cout << std::endl;return 0;
}

3.2 对捕获的变量和引用进行初始化

include <iostream>
using namespace std;
int main()
{int x = 4;auto y = [&r = x, x = x + 1]()->int{r += 2;return x * x;}(); cout << "x = " << x << " y = " << y << endl;
}
// 输出结果:x = 6 y = 25

auto y = [&r = x, x = x + 1]() -> int { ... }(); 定义了Lambda表达式并立即调用。

  • [&r = x, x = x + 1]:捕获了变量 x,通过引用捕获了 r,同时对 x 进行了初始化,将 x 的值增加了1。
  • ()->int { r += 2; return x * x; }:Lambda表达式的主体,对捕获的变量进行操作。r 是通过引用捕获的,所以对 r 的修改会影响到外部的 x。Lambda表达式返回 x * x 的结果。

4、constexpr 函数可以包含多个语句

在 C++11 中,如果想使用 constexpr 方法,只能包含一个返回语句。

#include <iostream>
constexpr int square(int x) {return x * x;
}
int main() {constexpr int result = square(5); // 合法的 constexpr 函数调用// 在 C++11 中,下面的调用将导致编译错误// constexpr int invalidResult = []() {//     int sum = 0;//     for (int i = 1; i <= 5; ++i) {//         sum += i;//     }//     return sum;// }();std::cout << "Result: " << result << std::endl;return 0;
}

C++14 中,放宽了此要求,允许 constexpr 函数中声明变量,使用循环和条件语句等:

#include <iostream>
#include <cmath>
using namespace std;
constexpr bool isPrimitive(int number) {if (number <= 0) {return false;}for (int i = 2; i <= sqrt(number) + 1; ++i) {if (number % i == 0) {return false;}}return true;
}
int main() {cout << boolalpha << isPrimitive(102) << " " << isPrimitive(103);return 0;
}

需要注意的是,虽然C++14对constexpr函数的要求放宽了一些,但仍然有一些限制。例如,递归和复杂的控制流结构可能仍然无法在constexpr函数中使用。

在C++11中,我们一般需要通过递归来实现相同的功能:

constexpr bool isPrimitive(int number, int currentFactor, int maxFactor) {return currentFactor == maxFactor ? true : (number % currentFactor == 0 ? false : isPrimitive(number, currentFactor + 1, maxFactor));
}
constexpr bool isPrimitive(int number) {return number <= 0 ? false : isPrimitive(number, 2, sqrt(number) + 1);
}

5、整型字面量

5.1 二进制字面量

支持使用 0b 开头的一串数字作为二进制表示的整型:

int a = 0b10101001110; // 1358

5.2 数字分隔符

支持在数字中使用单引号进行分割(便于阅读)。在编译时,这些单引号会被忽略。

int a = 123'456'789; // 123456789

6、返回类型自动推导

在 C++14 中,我们可以使用 auto 作为函数返回值并且不需要指明其返回类型的推导表达式

int x = 1;
auto f() { return x; }
/* c++11
auto f() -> decltype(x) { return x; } 
*/

这种类型推导有一些限制:

  1. 相同类型的推导: 在一个函数中,所有的返回语句必须推导出相同的类型。

    int x = 1;
    auto f() { return x; }  // 合法
    
  2. 使用 {} 包裹的数据: 对于使用 {} 包裹的数据作为返回值时,无法推导其类型。

    auto g() { return {1, 2, 3}; }  // 不合法
    
  3. 虚函数和 coroutine 不能被推导: 虚函数和协程不能使用此类型推导。

  4. 函数模板中的类型推导: 函数模板中可以使用类型推导,但显式实例化和特化版本必须使用相同的返回类型描述符。

    template <typename T>
    auto h(T value) { return value; }template auto h<int>(int);  // 合法
    

这些限制是为了保证类型推导的一致性和可靠性。虽然C++14引入了更多的自动类型推导,但在一些情况下,显式指定返回类型仍然是必要的。

7、exchange

exchange 用于移动语义,可以使用指定的新值替换掉原值,并返回原值。其定义在C++20中被简单修改如下:

template<class T, class U = T>
constexpr // since C++20
T exchange(T& obj, U&& new_value)
{T old_value = std::move(obj);obj = std::forward<U>(new_value);return old_value;
}

其使用如下:

#include <iostream>
#include <vector>
#include <utility>
using namespace std;
int main() {vector<int> v = {5, 6, 7};std::exchange(v, { 1,2,3,4 });std::copy(begin(v), end(v), ostream_iterator<int>(cout, " "));cout << endl;
}

8、quoted

该类用于字符串转义的处理。使用 out << quoted(s, delim, escape) 的形式,可以将字符串 s 的转义格式写入输出流中;

使用 in >> quoted(s, delim, escape) 可以将输入流去除转义格式后写入字符串 s 中。其中,delim 指明了需要转义的字符,escape 指明了修饰该转移字符的字符:

#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
int main() {stringstream ss;string in = "String with spaces, and embedded \"quotes\" too";string out;auto show = [&](const auto& what) {&what == &in? cout << "read in     [" << in << "]\n"<< "stored as   [" << ss.str() << "]\n": cout << "written out [" << out << "]\n\n";};ss << quoted(in); show(in);ss >> quoted(out);show(out);ss.str(""); in = "String with spaces, and embedded $quotes$ too";const char delim{ '$' };const char escape{ '%' };ss << quoted(in, delim, escape);show(in);ss >> quoted(out, delim, escape);show(out);
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

9、C++14 经常考到的知识点

9.1 C++14 引入了哪些新特性?

C++14 引入了一些新特性,包括但不限于以下内容:

  1. 通用Lambda表达式:允许在lambda函数中使用auto关键字来推导参数类型。
  2. 自动返回类型推导:允许使用auto关键字自动推导函数返回值类型。
  3. 初始化列表的泛型支持:可以使用auto关键字在初始化列表中推导元素类型。
  4. 带有二进制分隔符的整数字面量:可以在整数常量中使用单撇号作为分隔符,提高可读性。
  5. constexpr函数的扩展:constexpr函数可以包含更多操作,例如循环和条件判断。
  6. 变长参数模板(Variadic Templates)的改进:支持递归处理变长参数模板的展开。
  7. 返回void类型的lambda表达式:允许定义返回void类型的lambda函数。

9.2 C++14 中 auto 关键字的用法和限制是什么?

在 C++14 中,auto 关键字用于自动类型推导,可以根据初始化表达式的类型来确定变量的类型。它的使用和限制如下:

  1. 自动类型推导:使用 auto 关键字声明变量时,编译器会根据初始化表达式的类型自动推导出变量的类型。
    auto x = 42; // 推导为int型 auto name = “John”; // 推导为const char*型
  2. 声明时必须初始化:使用auto声明变量时,必须进行初始化。因为编译器需要根据初始化表达式来推导出变量的类型。
    auto y; // 错误,未初始化
  3. 可与引用结合使用:auto关键字可以与引用一起使用,从而推导出引用的类型。
    int a = 10; auto& ref = a; // 推导为int&型,ref是a的引用
  4. 不支持数组或函数指针:auto不能直接用于数组或函数指针的声明。但可以通过decltype结合auto来实现对数组或函数指针类型进行推导。
    int arr[] = {1, 2, 3}; auto arrRef = arr; // 错误,无法推导arr的数组类型 decltype(arr) arrType; // 使用decltype获取arr的数组类型并声明arrType void foo(); auto funcPtr = foo; // 错误,无法推导foo的函数指针类型 decltype(foo)* funcPtrType; // 使用decltype获取foo的函数指针类型并声明funcPtrType

需要注意的是,auto 在 C++14 中的用法和限制可能与之后的标准(如 C++17、C++20 等)有所不同,具体取决于编译器和所使用的标准版本。

9.3 C++14 中如何使用 Lambda 表达式?有什么改进?

在C++14中,使用Lambda表达式的语法与之前的C++版本相似。Lambda表达式是一种可以在代码中内联定义匿名函数的方式。

下面是一个使用Lambda表达式的示例:

#include <iostream>
#include <vector>
#include <algorithm>
int main() {std::vector<int> numbers = {1, 2, 3, 4, 5};// 使用Lambda表达式进行遍历打印std::for_each(numbers.begin(), numbers.end(), [](int num) {std::cout << num << " ";});return 0;
}

在 Lambda 表达式中,方括号 [] 用于捕获外部变量(可选)。小括号 ( ) 内指定参数列表(可选),箭头 -> 后面指定返回类型(可选)。

C++14 对于 Lambda 表达式有一些改进,其中最显著的改进是可以自动推导返回类型。这意味着你不需要显式地指定返回类型,编译器会根据表达式体来推断返回类型。

以下是一个示例:

auto lambda = [](int a, int b) {return a + b;
};

在上述示例中,我们没有显式指定返回类型,但编译器会自动推断出返回类型为整数(因为a和b都是整数)。

此外,在 C++14 中还引入了泛型 lambda,使得可以在 lambda 函数中使用 auto 关键字作为参数类型,更加灵活和方便。

9.4 C++14 对于 constexpr 关键字有何改进?

C++14 对于 constexpr 关键字进行了一些改进,使得其更加灵活和强大。在 C++11 中,constexpr只能用于表示常量表达式的函数和构造函数,而在 C++14 中,它还可以用于一些额外的情况。

首先,在 C++14 中,constexpr函数可以包含一些非常量表达式的逻辑,只要这部分逻辑在运行时不会执行即可。这意味着我们可以在constexpr函数内使用循环、条件语句等非常量表达式的控制流程。

其次,C++14引入了对变量模板(Variable Templates)的支持,并且允许将变量声明为constexpr。这样我们就可以定义并初始化一个编译期间可计算的常量变量。

此外,在 C++14 中,对于某些标准库类型(如数组、字符串等),它们也提供了更多的支持以便于使用在编译期间计算出来的常量值。

9.5 C++14 中提供了哪些新的标准库组件和功能?

C++14引入了一些新的标准库组件和功能,以下是其中的一些主要特性:

  1. std::make_unique:提供了在堆上创建 unique_ptr 对象的便捷方式。
  2. std::integer_sequence:支持编译时整数序列的操作,用于元编程。
  3. std::user_defined_literals:允许用户定义自己的字面量后缀,扩展了语言的表达能力。
  4. 通用 lambda 表达式:允许使用 auto 参数声明参数类型,使得 lambda 表达式更加灵活。
  5. 变长模板参数折叠(Variadic template parameter packs expansion):可以将多个参数打包传递给模板函数或类,并且可以对它们进行展开操作。
  6. std::experimental 命名空间:引入了一些实验性质的标准库组件,如 optional、any、string_view 等。

9.6 在 C++14 中,变长参数模板是如何使用的?

在 C++14 中,可以使用变长参数模板(Variadic Templates)来处理可变数量的函数参数。通过使用递归展开参数包的方式,可以灵活地处理任意数量的参数。

下面是一个示例:

#include <iostream>
// 递归终止条件:当没有剩余参数时停止递归
void printArgs() {std::cout << "All arguments have been printed." << std::endl;
}
// 可变参数模板:展开第一个参数并调用自身处理剩余参数
template<typename T, typename... Args>
void printArgs(T first, Args... args) {std::cout << "Argument: " << first << std::endl;printArgs(args...); // 递归调用自身处理剩余参数
}
int main() {printArgs(1, "Hello", 3.14, 'A');return 0;
}

输出结果:

Argument: 1
Argument: Hello
Argument: 3.14
Argument: A
All arguments have been printed.

在上述代码中,printArgs 是一个可变参数模板函数。它首先处理第一个传入的参数 first,然后递归地调用自身处理剩余的 args 参数。当所有参数都被展开并打印完毕后,最终会到达递归终止条件。

这种方式使得我们能够在编译时处理不同数量和类型的函数参数,并且可以灵活地进行操作。

9.7 在 C++14 中,是否允许在 lambda 函数内定义其他函数或类?

在 C++14 中,lambda 函数内是不允许定义其他函数或类的。Lambda 函数是一个匿名的函数对象,它通常用于简化代码,提供一种在局部范围内编写小型函数的方式。Lambda 函数本质上是一个闭包,它可以捕获外部作用域中的变量,并且具有与普通函数相似的行为。

然而,在 C++17 中引入了嵌套lambda的概念,使得在 lambda 函数内定义其他 lambda 函数成为可能。在这种情况下,内层的 lambda 函数可以访问外层 lambda 函数的变量。所以如果你想要在 C++14 中定义其他函数或类,建议将其定义在 lambda 之外的范围内。

9.8 C++14 是否支持原始字符串字面量(raw string literals)?如何使用它们?

是的,C++14 支持原始字符串字面量(raw string literals)。

原始字符串字面量可以用来表示包含特殊字符(例如转义序列和引号)的字符串,而无需使用转义符号。它们由R"delim(raw_characters)delim"的语法表示,其中delim可以是任何非空字符序列,并且在开始和结束位置上必须匹配。

以下是一个示例:

#include <iostream>
int main() {const char* str1 = R"(Hello \n World!)";std::cout << str1 << std::endl;  // 输出:Hello \n World!const char* str2 = R"###(This is a "quoted" string.)###";std::cout << str2 << std::endl;  // 输出:This is a "quoted" string.return 0;
}

在上面的示例中,我们使用了原始字符串字面量来创建包含特殊字符的字符串,而不需要使用额外的转义符号。

9.9 在 C++14 中,std::make_unique和std::make_shared这两个函数的作用是什么?

在 C++14 中,std::make_uniquestd::make_shared是用于创建智能指针的函数模板。

  • std::make_unique:用于创建一个std::unique_ptr对象,它拥有独占所有权的动态分配对象。这个函数接受参数并返回一个std::unique_ptr,它会自动管理内存释放。示例:
auto ptr = std::make_unique<int>(42);
  • std::make_shared:用于创建一个std::shared_ptr对象,它可以被多个指针共享的动态分配对象。这个函数接受参数并返回一个std::shared_ptr,它使用引用计数来管理内存释放。示例:
auto ptr = std::make_shared<int>(42);

这两个函数可以减少手动进行资源管理的工作量,并提供了更安全、更简洁的方式来处理动态分配对象。

9.10 C++14 引入了统一初始化语法(uniform initialization syntax),具体有哪些变化?

C++14 引入了统一初始化语法(uniform initialization syntax),它允许使用一种更统一和一致的方式进行初始化。具体的变化包括以下几个方面:

  1. 初始化列表(initializer list):可以使用花括号 {} 来初始化对象,无论是简单类型还是复杂类型。例如:
    int num{ 42 }; std::vector vec{ 1, 2, 3 };
  2. 自动类型推导:在使用统一初始化语法时,编译器可以自动推导出变量的类型。
    auto value{ 3.14 }; // 推导为 double 类型 auto str{ “Hello” }; // 推导为 const char[6] 类型
  3. 统一构造函数调用语法:通过统一初始化语法,可以直接调用类的构造函数进行对象的创建。
    class MyClass { public: MyClass(int value) { /* 构造函数实现 */ } // … }; MyClass obj{ 42 }; // 调用构造函数创建对象
  4. 空初始化:可以使用 {}() 进行空初始化,不再需要显式地指定默认值。
    int num{}; // 初始化为0 std::string str{}; // 初始化为空字符串

zer list):可以使用花括号 {} 来初始化对象,无论是简单类型还是复杂类型。例如:
int num{ 42 }; std::vector vec{ 1, 2, 3 };
2. 自动类型推导:在使用统一初始化语法时,编译器可以自动推导出变量的类型。
auto value{ 3.14 }; // 推导为 double 类型 auto str{ “Hello” }; // 推导为 const char[6] 类型
3. 统一构造函数调用语法:通过统一初始化语法,可以直接调用类的构造函数进行对象的创建。
class MyClass { public: MyClass(int value) { /* 构造函数实现 */ } // … }; MyClass obj{ 42 }; // 调用构造函数创建对象
4. 空初始化:可以使用 {}() 进行空初始化,不再需要显式地指定默认值。
int num{}; // 初始化为0 std::string str{}; // 初始化为空字符串

这些变化使得初始化更加灵活和一致,并且提供了更强大的类型推导能力。注意,在使用统一初始化语法时,要注意类型的精确匹配和可能的隐式转换。

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

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

相关文章

计网Lesson7 - 超网与路由概述

文章目录 一、构造超网1 概念解析2 路由聚合判断网段 3 实例演示几个配置问题&#xff1a;传输过程中的若干问题包的问题传输时丢包的问题 4 判断是子网还是超网 二、路由概述1. 路由的作用2. 多个网段进行联络3. 数据包的传输 一、构造超网 1 概念解析 与划分子网相反&#…

从0到1实现Flink 实战实时风控系统的经验总结

随着互联网金融的快速发展&#xff0c;实时风控系统成为保障业务安全和用户信任的关键。本文将分享从零开始构建Flink实时风控系统的经验&#xff0c;并提供相关示例代码。 一、搭建Flink环境 首先&#xff0c;我们需要搭建Flink环境。以下是一些基本步骤&#xff1a; 安装Ja…

创新、升级丨数据手套FOHEART Pro开启手势识别新篇章!

在人机交互领域&#xff0c;我们始终追求更加自然、逼真的体验。正如现实生活中&#xff0c;我们习惯于通过语言和表情来传达思想和情感&#xff0c;然而&#xff0c;在虚拟世界中&#xff0c;人机交互需要以更加直观、生动的方式进行操作、控制和交互。 为了更好地满足市场的…

css实现姓名两端对齐

1.1 效果 1.2 主要代码 text-align-last: justify; 1.3 html完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0&quo…

Vue 生成包含数字大小写字母的随机字符串

generateRandomID() {const characters 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ;const idLength 30; // 字符串长度 这里生成30位的let randomID ;for (let i 0; i < idLength; i) {const randomIndex Math.floor(Math.random() * characters…

数学建模-二氧化碳排放及时空分布测度

二氧化碳排放及时空分布测度 整体求解过程概述(摘要) 面临全球气候变化的巨大挑战&#xff0c;我国积极响应《巴黎协定》的号召&#xff0c;提出“2030年前碳达峰&#xff0c;2060 年前实现碳中和”的碳排放发展目标&#xff0c;并将碳中和相关工作作为 2021 年的重点任务之一…

吉客云与金蝶云星辰业财一体化数据集成

吉客云与金蝶云星辰业财一体化数据集成为例&#xff0c;探讨如何利用轻易云数据集成平台高效整合企业系统。金蝶云星辰在供应链和财务管理方面具有显著优势&#xff0c;而吉客云则专注于订单处理和发货。两者的协同运作&#xff0c;是企业数字化转型的典型案例。 二、集成总体蓝…

python-学生管理|汉罗塔

1.编写程序&#xff0c;实现学生信息管理系统。 运行程序&#xff0c;在控制台输入“1”之后的结果如下所示&#xff1a; 学生管理系统 1.添加学生信息 2.删除学生信息 3.修改学生信息 4.显示所有学生信息 0.退出系统 请选择功能&#xff1a;1 请输入新学生的姓名:小红 请输入…

排序算法:n个0~1000之间的整数,将他们从大到小排序

上榜理由&#xff1a; 如果没见过这种排序题&#xff0c;可能首先想到的就是常用的排序算法&#xff0c;比如快速排序&#xff0c;归并排序&#xff0c;那如果输入的n足够大&#xff0c;时间复杂度肯定比较高。其实题目0-1000的范围是一个题眼&#xff0c;所以一定有更优的排序…

商务助理个人简历10篇

商务助理简历模板下载&#xff08;可在线编辑制作&#xff09;&#xff1a;来幻主简历&#xff0c;做好简历&#xff01; 商务助理简历1&#xff1a; 求职意向 求职类型&#xff1a;全职 意向岗位&#xff1a;国际商务、产品助理 意向城市&#xff1a;广东广州 …

ElasticSearch篇---第一篇

系列文章目录 文章目录 系列文章目录前言一、谈谈分词与倒排索引的原理二、说说分段存储的思想三、谈谈你对段合并的策略思想的认识前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分…

【每日一题】确定两个字符串是否接近

文章目录 Tag题目来源题目解读解题思路与实现方法一&#xff1a;计数 其他语言python3 写在最后 Tag 【计数】【字符串】 题目来源 1657. 确定两个字符串是否接近 题目解读 你可以进行以下两种操作&#xff1a; 操作 1&#xff1a;交换任意两个位置的字符&#xff1b;操作 …

浪涌保护器参数指南:浪涌保护器行业选型方案

浪涌保护器&#xff08;SPD&#xff09;是一种用于限制瞬态过电压和泄放浪涌电流的器件&#xff0c;可有效降低电子设备在雷击、电源故障等情况下受到的损害。其主要作用是当系统发生浪涌时&#xff0c;将过电压、过电流泄放到大地&#xff0c;从而保护设备和人身安全。然而浪涌…

什么是Amazon Lambda(无服务器计算服务)

Lambda 在高可用性计算基础设施上运行代码&#xff0c;用于执行计算资源的所有管理工作。这包括服务器和操作系统维护、容量调配和弹性伸缩、代码和安全补丁部署以及代码监控和日志记录。您只需要提供代码。 最近亚马逊云服务提供了超多免费的云服务&#xff0c;快来领取免费套…

【设计模式】单例模式代码设计

目录 单例模式简介饿汉单例模式懒汉单例模式线程安全的懒汉单例模式 橙色 详细可参考该篇文章&#xff1a;C设计模式 - 单例模式 单例模式简介 单例模式指的是&#xff0c;无论怎么获取&#xff0c;永远只能得到该类类型的唯一一个实例对象&#xff0c;那么设计一个单例就必须…

聊聊部署在不同K8S集群上的服务如何利用nginx-ingress进行灰度发布

前言 之前有篇文章聊聊如何利用springcloud gateway实现简易版灰度路由,里面的主人公又有一个需求&#xff0c;他们有个服务是没经过网关的&#xff0c;而是直接通过nginx-ingress暴露出去&#xff0c;现在这个服务也想做灰度&#xff0c;他知道在同个集群如何利用nginx-ingre…

Git 分支合并时 Merge, Rebase, Squash 的使用场景

前言 Git 的分支设计大大提升了并行开发的能力&#xff0c;但相应的&#xff0c;也就要解决如何进行分支合并。毕竟分久必合&#xff0c;最终还是要把大家的工作合并起来&#xff0c;进行统一发布的。在合并时&#xff0c;通常有三种操作&#xff1a; Merge commitsRebaseSqu…

Vue学习计划--Vue2(二)Vue代理方式

Vue data中的两种方式 对象式 data:{}函数式 data(){return {} }示例&#xff1a; <body><div id"app">{{ name }} {{ age}} {{$options}}<input type"text" v-model"value"></div><script>let vm new Vue({el: …

Linux操作系统之wget下载软件并安装

文章目录 前言一、apt下载二、wget下载1、新建目录存放文件2、根据下载地址使用wget下载安装包3、解压包4、命令指定目录&#xff0c;让其生效如有启发&#xff0c;可点赞收藏哟~ 前言 一般安装可以直接使用apt命令&#xff0c;不过安转的不是最新版本的&#xff0c;且没法指定…

驱动开发--内核添加新功能

Ubuntu下这个文件为开发板ls命令的结果 内核的内容&#xff1a; mm&#xff1a;内存管理 fs&#xff1a;文件系统 net&#xff1a;网络协议栈 drivers&#xff1a;驱动设备 arch与init&#xff1a;跟启动相关 kernel与ipc&#xff1a;任务&#xff0c;进程相关 向内核增…