C++入门篇

news2024/11/15 11:15:17

入门C++

  • 命名空间
    • 命名空间定义
    • 命名空间的使用
  • C++输入,输出
  • 缺省参数
    • 缺省参数概念
    • 缺省参数分类
  • 函数重载
    • 函数重载概念
    • C++支持函数重载的原因
  • 引用
    • 引用概念
    • 引用特性
    • 具体应用
    • const修饰的常量进行引用(常引用)
    • 传值,传引用的效率
    • 引用和指针的区别
  • 内敛函数
    • 概念
    • 特性
  • auto关键字
    • 类型别名思考
    • auto简介
    • auto的使用规则
    • auto不能推导的场景
  • 空指针

命名空间

#include<stdio.h>
#include<stdlib.h>
int rand = 1;
int main()
{
	printf("%d\n", rand);
	return 0;
}

在C语言的编译环境下,头文件 #include<stdlib.h>展开之后会包含rand()函数,编译默认的查找成员方式是:先局部,后全局。所以当函数rand()和变量rand同时出现在全局时,程序便会报错

在这里插入图片描述

此类情况是不可避免的,尤其是在工程中,命名冲突在所难免,不容小觑。

C++编译系统,为此提供一个解决办法,命名空间

对标识符名称进行本地化,避免命名冲突(名字冲突)
命名空间就类似于在成员与外界之间设置一个围墙,如果想要访问其中的成员,要么通过专属的通道(作用域限定符),要么将围墙进行拆除。

将变量rand放在命名空间namespace M中,按照查找规则,在全局中找到rand()函数;通过域作用限定符,在命名空间中找到变量rand,由此避免了命名冲突

#include<stdio.h>
#include<stdlib.h>
namespace M
{
	int rand = 1;
}

int main()
{
	printf("%p\n", rand);
	//::  域作用限定符
	printf("%d\n", M::rand);
	return 0;
}

在这里插入图片描述

命名空间定义

命名空间的定义,需要使用关键字namespace,实例如下

namespace  name //name是命名空间的名称
{
    member //命名空间的成员
}

举例如下

namespace M
{
	int m = 'm';
	int n = 'n';
}

与C语言中的结构体类似,命名空间同样也可以嵌套定义

namespace M
{
    member;
	namespace N
	{
		member;
	}
}

举例如下

namespace M
{
	int m = 'm';
	int n = 'n';
	namespace N
	{
		int i = 'i';
		int j = 'j';
	}
}

命名空间定义了新的作用域,命名空间中所有的成员生命周期仅局限于命名空间

命名空间的使用

  1. 加命名空间名称及作用域限定符
int main()
{
	printf("%d", M::m);
	return 0;
}
  1. 使用using将命名空间中某个成员引入

using作用就类似于打开围墙的专属通道,可以直接访问成员m,但对于成员n的访问还是需要使用作用域限定符

using M::m;
int main()
{
	printf("%d\n", m);
	printf("%d\n", M::n);
	return 0;
}
  1. 使用using namespace 命名空间名称引入

using namespace的作用就类似于,直接将围墙进行拆除,可以直接访问所有成员

using namespace M;
int main()
{
	printf("%d\n", m);
	printf("%d\n", n);
	return 0;
}

C++输入,输出

std是C++标准库的命名空间名,C++将标准库的定义实现全部都放在其中

#include<iostream>
using namespace std;
int main()
{
	cout << "hello crush" << endl;
	return 0;
}

在这里插入图片描述

  1. 使用cout标准输出对象cin标准输入对象时,需要包含 <iostream>头文件以及按命名空间使用的方式使用 std
  2. cout和cin时全局的流对象,endl时特殊的C++符号,表示换行输出,类似于C语言中的'\n',全部都包含在<iostream>头文件中
  3. <<是流插入运算符,>>是流提取运算符
  4. C++的输入输出可以自动识别变量类型

举例如下

#include<iostream>
using namespace std;
int main()
{
	char c = 'c';
	int i;
	//输入变量i的数值
	cin >> i;
	//打印输出变量 i,c
	cout << i << endl;
	cout << c << endl;
	return 0;
}

在这里插入图片描述

缺省参数

缺省参数概念

缺省参数是声明(定义)函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参

#include<iostream>
using namespace std;
void test(int i = 1)
{
	cout << i << endl;
}
int main()
{
	test(0);
	test();
	return 0;
}

在这里插入图片描述

缺省参数分类

全缺省参数

#include<iostream>
using namespace std;
void test(int a = 1, int b = 2, int c = 3)
{
	cout << a << " " << b << " " << c << endl;
}

int main()
{
	test();
	return 0;
}

在这里插入图片描述

半缺省参数(部分缺省)

只能从右往左连续缺省

#include<iostream>
using namespace std;
void test(int a , int b = 2, int c = 3)
{
	cout << a << " " << b << " " << c << endl;
}

注意

  1. 半缺省参数必须传递实参,且顺序从左往右,不能间隔赋值
  2. 缺省参数不能在函数声明和定义中同时出现,规定只能在声明中存在。因为如果声明和定义中同时存在缺省参数,到底以哪一个作为真正的缺省参数呢?
    在这里插入图片描述

在这里插入图片描述

头文件中声明,源文件中定义。由于同时都存在缺省参数,所以程序会报错

在这里插入图片描述

  1. 缺省值必须是常量或者全局变量

函数重载

词语具有一词多义的特点,只有通过上下文才能判断该词语的真正的含义,函数重载也是具有类似的特点

函数重载概念

函数重载:函数的一种特殊情况,允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表参数个数,类型,类型顺序不同,常用来处理实现功能类似数据类型不同的问题

形参类型不同

int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}

double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;
	return left + right;
}

在这里插入图片描述

形参个数不同

void test()
{
	cout << "test()" << endl;
}

void test(int i)
{
	cout << i << endl;
}

在这里插入图片描述

参数类型顺序不同

void test(int i, char c)
{
	cout << "void test(int i, char c)" << endl;
}

void test(char c, int i)
{
	cout << "void test(char c, int i)" << endl;
}

在这里插入图片描述

还存在一个小问题 函数重载遇上缺省参数

//构成函数重载,同时也是缺省参数
//调用存在歧义,到底该调用哪一个不清楚
void test(int a = 0, int b = 1)
{
	cout << "test(int a,int b)" << endl;
}

void test()
{
	cout << "test()" << endl;
}

int main()
{
	test();//二义性
	return 0;
}

在这里插入图片描述

C++支持函数重载的原因

C语言编译结果(简化)
函数名不同,在符号表中才能区分出来,所以不能支持重载

在这里插入图片描述

C++编译结果(简化)
C++是通过函数修饰规则在符号表中区分的,只要参数不同,修饰的出的函数名就不同,所以支持重载

在这里插入图片描述

重载的概念一直都没有提到返回值,也就是说返回值并不会构成重载原因,但是为什么呢???

int test(int a, int b)
{
	cout << "test(int a,int b)" << endl;
	return a + b;
}

char test(int a, int b)
{
	cout << "test(int a,int b)" << endl;
	return a + b;
}

int main()
{
	test(0,0);
	test(1, 1);
	return 0;
}

在函数调用时存在二义性,没有指定返回值类型,无法进行区分,并不是函数名修饰规则的原因,所以不构成重载

在这里插入图片描述

引用

引用概念

引用是给已经存在的变量另取一个名字或者说小名,但是不会为引用变量新开辟内存空间,所以变量和引用变量共用同一块内存空间

变量类型&引用变量名称=引用实体

#include<iostream>
using namespace std;
int main()
{
	int i = 1;
	int& ri = i;
	printf("%p\n", &i);
	printf("%p\n", &ri);
	return 0;
}

在这里插入图片描述

既然是对已存在的变量进行引用,当然数据类型要求是一致的

引用特性

  1. 引用在定义时必须要初始化
  2. 一个变量可以有多个引用(小名)
  3. 若引用(小名)已经引用一个变量,则不能再引用其他变量;即一个小名不能同时称呼两个人

具体应用

形式参数

#include<iostream>
using namespace std;
void Swap(int& ra, int& rb)
{
	int tmp = ra;
	ra = rb;
	rb = tmp;
}

int main()
{
	int a = 0;
	int b = 1;
	printf("%d %d\n", a, b);
	printf("%p %p\n", &a, &b);
	Swap(a, b);
	printf("%d %d\n", a, b);
	printf("%p %p\n", &a, &b);
	return 0;
}

在这里插入图片描述

在这里插入图片描述

优点

  1. 减少拷贝,提高效率
  2. 输出型参数,在函数中修改形参,实参也随之改变

返回值

  1. 引用返回
int& Test()
{
	static int i = 0;
	i++;
	return i;
}
int main()
{
	int ret = Test();
	cout << ret << endl;
	return 0;
}

函数栈帧的使用是从上往下(高地址到低地址),当 函数int& Test()结束时,栈帧被销毁。变量i保存在静态区,所以并不会被销毁,然后返回i的别名给 ret
在这里插入图片描述

如果变量i不在静态区

int& Test()
{
	int i = 0;
	cout << &i << endl;
	i++;
	return i;
}

void test()
{
	int a = 0;
	cout << &a << endl;
}

int main()
{
	int& ret = Test();
	cout << ret << endl;
	cout << ret << endl;

	test();
	cout << ret << endl;
	cout << &ret << endl;
	return 0;
}

int& ret = Test()->int&ret = int& i
所以 ret 也就是 i 本身

由于变量i是 int& Test()内的局部变量,所以当函数栈帧销毁时,i的空间也被收回。可以继续访问,但是数据是不确定的,而且 使用cout也会调用函数的

在这里插入图片描述

当函数 test()开辟栈帧时,碰巧使用前面函数 Test()函数栈帧的空间,也就是说,当访问 ret 时,其实就是访问变量 a 本身

在这里插入图片描述

运行结果也表面,两个函数 Test(), test(),开辟栈帧使用的确实是同一块空间

第一次打印 ret 时,数据没有改变,可能是 ret 是作为参数传递给 cout,所以数值没有改变

第二次打印 ret 时,数据是随机值,也就是 cout调用函数将被收回 i 的空间数据进行了改变

在这里插入图片描述

  1. 传值返回
int Test()
{
	static int i = 0;
	i++;
	return i;
}
int main()
{
	int ret = Test();
	cout << ret << endl;
	return 0;
}

与引用返回类似,变量 i 存放在静态区,栈帧销毁不会收到影响,反而作为临时变量返回给 ret

在这里插入图片描述

如果变量i不在静态区

int Test()
{
	int i = 0;
	i++;
	return i;
}
int main()
{
	int ret = Test();
	cout << ret << endl;
	return 0;
}

由于变量i是 int& Test()内的局部变量,所以当函数栈帧销毁时,i的空间也被收回。可以继续访问,但是数据是不确定的,而且 使用cout也会调用函数

总结
出了函数作用域,返回变量不存在,不能使用引用返回,引用返回的结果是未定义的(未知的)
出了函数作用域,返回变量还存在,才能使用引用返回

int Test1()
{
	int i = 0;
	i++;
	return i;
}

int Test2()
{
	static int i = 0;
	i++;
	return 0;
}

优点

  1. 减少拷贝,提高效率
  2. 可修改返回值

变量没有被const修饰时一般是可读可写的,可读可写是权限,在程序中,权限可以缩小,平移,但是不可以扩大

int main()
{
	//a可读可写
	int a = 0;
	//ra是a的别名,同样是可读可写,权限平移
	int& ra = a;
	//rra被const修饰,只能读,权限缩小
	const int& rra = a;


	//b被const修饰,只能读
	const int b = 0;


	//rb是b的别名,可读可写,权限扩大  error
	int& rb = b;


	//rb被const修饰,只能读,权限平移
	const int& rb = b;

	return 0;
}

在这里插入图片描述

结合上面的传引用做参数,一般都是需要const修饰,否则程序会报错

void test(int& x)
{}
int main()
{
	int a = 0;
	const int& rra = a;

	test(a);
	test(rra);

	return 0;
}

在这里插入图片描述

const修饰的常量进行引用(常引用)

数据类型转换时会产生临时变量,且临时变量具有常性,不可改变

int main()
{
	double a = 1.2;
	int b = a;
	cout << b << endl;
	return 0;
}

在这里插入图片描述

在这里插入图片描述

输出的结果也不是a本身,而是类型转换后产生的临时变量

再分析下面的代码

int main()
{
	double a = 1.2;
	int i = a;
	int& ri = a;
	return 0;
}

在这里插入图片描述

在这里插入图片描述

传值,传引用的效率

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时拷贝(函数栈帧中有详解),因此用值作为参数或者返回值类型,效率比较低,当参数或者返回值类型非常大时,效率就会更低;相反传引用就更加的高效

引用和指针的区别

语法概念上引用是小名,没有新开辟的空间,与引用变量共用同一块空间
底层实现上引用实际是有空间的,引用时按照指针的方式来实现的

#include<iostream>
using namespace std;
int main()
{
	int i = 0;
	int& ri = i;
	ri = 1;

	int* pi = &i;
	*pi = 1;

	return 0;
}

引用与指针的汇编代码是一致的,所以两者实现方式是一致的
在这里插入图片描述

引用与指针的不同点

  1. 引用概念上定义变量的别名(小名),指针存储变量的地址
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在引用(修饰)一个变量之后,不能再引用(修饰)其他变量;指针可以指向任何同一类型的变量
  4. 不存在NULL引用;存在NULL指针
  5. sizeof计算的大小不同:引用的结果是引用(修饰)的变量类型的大小;指针始终是地址空间所占字节大小

内敛函数

概念

inline修饰的函数称作内联函数,程序运行时,编译器会在调用内联函数的位置展开,没有函数调用建立栈帧,内敛函数有利于提升程序运行效率

在debug模式下,需要对编译器进行设置,否则不会展开。因为在debug模式下,需要对函数进行调试

在这里插入图片描述

对比如下

int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int ret = Add(1, 1);
	return 0;
}

在这里插入图片描述

内联函数

inline int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int ret = Add(1, 1);
	return 0;
}

在这里插入图片描述

编译时,内联函数会直接展开,不会开辟空间建立栈帧

特性

  1. inline是通过空间换时间的方式。在运行时编译器如果将函数当作内敛函数处理,则在编译阶段会用函数体替换函数调用;缺点:目标文件可能会变大;优点:不需要调用函数栈帧,提高程序运行效率
  2. inline只是一个建议,不同编译器对于inline的实现方式不同,一般建议:函数规模较小,不是递归,且频繁调用的函数采用inline修饰
  3. inline不能声明和定义分离,会导致链接错误。只要函数声明被inline修饰,预处理时,函数的信息就不会在符号表中,链接阶段就会找不到从而出现错误

auto关键字

类型别名思考

随着程序越来越复杂,程序中需要使用的类型也会越加复杂,
一般体现在:

  1. 类型拼写较难
  2. 含义不明确会导致出错

auto简介

auto作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译期间推导而得

#include<iostream>
using namespace std;
int main()
{
	int i = 0;
	auto a = i;//自动识别变量a的类型为 int
	auto b = 'i';//自动识别变量b的类型为  char
	cout << i << endl;
	cout << a << endl;
	cout << b << endl;
	return 0;
}

在这里插入图片描述

auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种类型的声明,而是一个类型声明时的占位符,编译器在编译阶段会将auto替换为变量实际的类型

auto的使用规则

auto与指针和引用结合使用
用auto声明指针类型时,auto与auto*没有区别,但是auto声明引用类型时必须加上&

#include<iostream>
using namespace std;
int main()
{
	int i = 0;
	auto a = &i;//a的类型是  int* 存储变量i的地址
	auto* b = &i;//b的类型与a一致,同样存储变量i的地址
	auto& c = i;//由于&的存在 c的类型便是int& 就是变量i的引用
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
	return 0;
}

在这里插入图片描述

同一行定义多个变量
当在同一行声明多个变量时,这些变量必须时相同的类型,否则编译器便会报错,因为编译器实际上只对第一个类型进行推导,然后用推导(自动识别)的类型定义其他变量

void test()
{
	auto a = 1, b = 2;
	auto c = 3, d = 'a';
}

在这里插入图片描述

auto不能推导的场景

auto不能作为函数的参数

void test(auto i)
{

}

auto不能作为形参类型,因为编译器无法对i的实际类型进行推导(自动识别)

在这里插入图片描述

auto不能直接用来声明数组

void test()
{
	int a[] = { 1,2,3 };
	auto b[] = { 1,2,3 };
}

在这里插入图片描述

空指针

  1. 在使用nullptr表示空指针时,不需要包括头文件
  2. sizeof(nullptr)与sizeof((void*)0)所占的字节数相同
  3. 规定之后使用nullptr表示空指针

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

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

相关文章

【无标题】3 GENERIC语句 和 INTEGER类型

【VHDL】【作业】3 GENERIC语句 和 INTEGER类型 文章目录【VHDL】【作业】3 GENERIC语句 和 INTEGER类型前言什么是GENERIC语句&#xff1f;32位加法器仿真波形总结每天进步一点点 笔记仅供自学&#xff0c;用来回看复习&#xff0c;不一定适合你&#xff0c;如有错误请指出。前…

SpringBoot:概述

Spring Boot 是 Spring 开源组织下的子项目&#xff0c;是 Spring 组件一站式解决方案&#xff0c;主要是简化了使用 Spring 的难度&#xff0c;简省了繁重的配置&#xff0c;提供了各种启动器&#xff0c;开发者能快速上手。 &#xff5e; 本篇内容包括&#xff1a;Spring Boo…

[选型] 实时数仓之技术选型

数仓技术路线选型 对于已有的hive数据仓&#xff0c;怎样改造成实时数仓的要求呢&#xff1f; 2.关于实时数仓的选型 如果选择hbase&#xff0c;建议选择kudu 如果选择kudu, 还可以选择doris 如果选择doris&#xff0c;建议选择iceberg 以上三种选择&#xff0c;要配合具体…

C++实现身份证号码过滤与排序

1.描述 警察办案里检索到一批(n个)身份证号码&#xff0c;希望按出生日期对它们进行从大到小排序&#xff0c;如果有相同日期&#xff0c;则按身份证号码大小进行排序&#xff0c;如果是错误的身份证号&#xff0c;则从排序列表中删除(仅需判断前两位省级地区编码是否在下面的…

知识图谱-KGE-语义匹配-双线性模型-2016:NAM

【paper】 Probabilistic Reasoning via Deep Learning: Neural Association Models【简介】 本文是中科大和科大讯飞联合发表在 IJCAI 2016 上的工作&#xff0c;本文提出了 NAM&#xff08;Neural Association Model&#xff09;用于概率推理&#xff0c;并具体化为 DNN&…

十二月7号

一、uboot概念 1.1 uboot和bootloader关系 1.bootloader:是一系列引导加载程序的统称 boot:引导 loader&#xff1a;加载 2.uboot是引导加载程序中的一种 1.2 uboot特点 1.uboot是由德国DNEX小组进行维护的 2.uboot是一个开源分布式系统 3.uboot支持多种硬件架构平台(ARM/X8…

Blazor 部署 pdf.js 不能正确显示中文资源解决办法

原文链接 [https://www.cnblogs.com/densen2014/p/16964858.html] 在Blazor项目嵌入 pdf.js 时不能正确显示中文,浏览器F12显示如下错误 错误 l10n.js /web/locale/locale.properties not found. 我找到了解决方案。它不仅消除了上面提到的错误&#xff08;即 404 - locale.p…

nextjs13 webpack5 使用wasm报错

问题描述&#xff1a; 在next 13, webpack 5, react 18的项目中使用Rust编写的wasm报错&#xff1a; ./node_modules/image-map-path/image_map_path_bg.wasm Module parse failed: Unexpected character (1:0) The module seem to be a WebAssembly module, but module is n…

freemarker

文章目录创建项目引入依赖创建配置文件创建启动类和测试类语法listMapif运算符处理空值使用??指定缺失变量默认值内建函数集合长度数据类型布尔值时间类型数值类型字符串类型sequence序列类型hash类型常见指令assign自定义变量指令json转成对象实例list通过下标取值map取值通…

「Redis数据结构」集合对象(Set)

「Redis数据结构」集合对象&#xff08;Set&#xff09; 文章目录「Redis数据结构」集合对象&#xff08;Set&#xff09;一、概述二、结构三、编码转换四、小结一、概述 Set是Redis中的单列集合&#xff0c;其特点为不保证有序性、保证元素唯一、可以求交集、并集、差集。 从…

Python入门自学进阶-Web框架——28、DjangoAdmin项目应用-只读字段与后端表单验证

有时候&#xff0c;记录的某些字段在生成后就不允许再修改了&#xff0c;这时前端只能显示&#xff0c;不能修改。这时&#xff0c;可在AdminClass中进行设置&#xff1a;readonly_fields[字段名&#xff0c;字段名&#xff0c;。。。]&#xff0c;前端格式就显示成只显示不能修…

联想电脑怎么录屏?这3个方法,轻松解决

录屏是现在最常见的办公功能之一&#xff0c;最近有朋友问联想电脑怎么录屏。联想电脑是使用Windows系统的。如果想用联想电脑录屏&#xff0c;可以使用Windows系统自带了的录屏软件进行录屏。下面小编将详细的介绍3个方法&#xff0c;解决联想电脑怎么录屏的问题&#xff0c;感…

8086寻址方式图解

目录 1&#xff1a;立即寻址 2&#xff1a;寄存器寻址 3&#xff1a;直接寻址&#xff08;存储器直接寻址&#xff09; 4&#xff1a;寄存器间接寻址&#xff08;重点&#xff09; 5&#xff1a;基址寻址&#xff08;相对寻址&#xff09; 6&#xff1a;变址寻址 &#x…

后端程序员必备的Linux基础知识+常见命令(2023年最新版教程)

文章目录[1. 从认识操作系统开始](https://link.juejin.cn?targethttps%3A%2F%2Fsnailclimb.gitee.io%2Fjavaguide%2F%23%2Fdocs%2Foperating-system%2Flinux%3Fid%3D_1-%E4%BB%8E%E8%AE%A4%E8%AF%86%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%BC%80%E5%A7%8B)[1.1. 操作系统简…

【与达梦同行】数据库coredump的配置方式与截断测试

一、简述 Core的意思是内存, Dump的意思是扔出来, 堆出来.开发和使用Unix程序时, 有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped). 这时候可以查看一下有没有形如core.进程号的文件生成。在国产操作系统麒麟V10中运维的时候&#xff0c;经常遇见一个问…

一、OpenAI ChatGPT 注册使用

文章目录注册购买openai的官网问题今天早上在sheep公众号里面看到了关于openai 旗下研发的chatgpt的产品&#xff0c;去到chatgpt的网页&#xff0c;我们可以看到他的标语。ChatGPT: Optimizing Language Models for Dialogue 哈哈&#xff0c;我百度了一下&#xff0c;大概意…

文教资料杂志文教资料杂志社文教资料编辑部2022年第17期目录

语言文学研《文教资料》投稿&#xff1a;cn7kantougao163.com 从MRC认知模型看《释大》中的同源关系 苏楚然; 1-4 徐志摩《再别康桥》英译本对比分析——基于许渊冲诗译的“三美论” 牟逸飞;梁楚涵; 5-9 严歌苓小说“笑”书写的语言修辞学视角分析 孙婷婷; 10-12 …

得物云原生全链路追踪Trace2.0-采集篇

一、0xcc开篇 2020年3月&#xff0c;得物技术团队在三个月的时间内完成了整个交易体系的重构&#xff0c;交付了五彩石项目&#xff0c;业务系统也进入了微服务时代。系统服务拆分之后&#xff0c;虽然每个服务都会有不同的团队各司其职&#xff0c;但服务之间的依赖也变得复杂…

学1个月爬虫就月赚6000?别被骗了,老师傅告诉你爬虫的真实情况!

用爬虫赚外快的事情我也干了很多年&#xff0c;爬虫自然不在话下。 那么今天我来说说5个深入一点的爬虫问题&#xff0c;让你清楚爬虫的真实情况&#xff1a; 1.现在的爬虫接单真能1个月赚6000的快外&#xff1f; 2.初级爬虫只能接一些小单&#xff0c;怎样才算初级爬虫水平&…

Kafka ui 搭建以及使用

Kafka ui 序 kafka 本身没有自带相关的 ui 界面&#xff0c;但是很多时候没有页面意味着只有使用命令行进行相关操作如创建 topic、更改 topic 信息、重置 offset 等等。但实际使用中这种效果很差劲&#xff0c;我们一般还是会借助其他软件&#xff0c;实现对 kafka 的页面管…