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

C++:类和对象初识

C++:类和对象初识

  • 前言
  • 类的引入与定义
    • 引入
    • 定义
    • 类的两种定义方法
      • 1. 声明和定义全部放在类体中
      • 2. 声明和定义分离式
    • 类的成员变量命名规则
  • 类的访问限定符及封装
    • 访问限定符
    • 封装
  • 类的作用域与实例化
    • 类的作用域
    • 类实例化
      • 实例化方式:
  • 类对象模型
    • 类对象的大小
    • 存储方式
  • this指针(重点)
    • 引出
    • 特性
    • 深入理解
      • 思考题?(重点中的重点)
        • 解答情形1
        • 解答情形2
    • 原因分析
  • 总结

前言

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
以我们洗衣服为例:
在这里插入图片描述

C++是基于面向对象的关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

在这里插入图片描述

在面向对象编程(OOP)中,"类"和"对象"是最核心的概念。C++作为一门面向对象的语言,通过类和对象实现了数据抽象、封装、继承和多态等特性。理解类和对象的工作机制是掌握C++面向对象编程的关键。


类的引入与定义

引入

在C语言中,我们使用结构体(struct)来组织相关数据。C++在此基础上进行了扩展,允许结构体中不仅包含数据成员,还可以包含函数成员:

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据结构中,用C语言方式实现的栈,结构体中只能定义变量现在以C++方式实现,会发现struct中也可以定义函数。

//C++兼容C语言,同时C++中struct升级成了 类(具有类的所有特性)
struct _Stack {//成员方法void Init(int defaultCapacity = 4) {base = (int*)malloc(sizeof(int) * defaultCapacity);if (base == nullptr) {perror("malloc failed\n");return;}this->size = 0;this->capacity = defaultCapacity;}void Push() {//......}void Destroy() {free(this->base);this->base = nullptr;this->top = this->capacity;}//成员变量int* base;int top;int capacity;int size;
};

C++中结构体的名字,可以当成类名来使用。C++中的结构体具有class的所有功能(包括但不限于权限管理与this指针),只是成员的默认权限不同。

  • 结构体中,所有成员的默认访问权限是public,结构体外可以直接访问
  • C++的类中,class所有成员的默认访问权限是private, 不能再类外访问。
    但更规范的C++做法是使用class关键字来定义类,它提供了更完善的访问控制机制。

定义

类定义的基本语法:

class className{// 类体:由成员函数和成员变量组成
};  // 一定要注意后面的分号
  1. class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。
  2. 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
    示例:
class Clock {
private:    // 访问限定符int hour;int minute;int second;public:void setTime(int h, int m, int s);void showTime() {cout << hour << ":" << minute << ":" << second << endl;}
};

类的两种定义方法

1. 声明和定义全部放在类体中

例如该类:

class Clock {
private:    // 访问限定符int hour;int minute;int second;public:void showTime() {cout << hour << ":" << minute << ":" << second << endl;}
};
  • 声明和定义全部放在类体中,需注意:成员函数如果在类体中定义,编译器可能会将其当成内联函数处理。(相当于在函数前加上了inline关键字,建议编译器使其称为内联函数)

2. 声明和定义分离式

//Stack.h
class Stack {
public:void Init(int defaultCapacity = 4);//在类内定义的函数,会直接建议编译器让该函数称为内联函数,void Push() {	//类内定义的函数,不管加不加 inline ,都相当于加上了 inline //.......此处省略}void Pop() {//.......}
private:int* base;int top;int capacity;
};
//Stack.cpp
//类的声明和定义分离,需要在函数名前面,加上类的作用域限定
void Stack:: Init(int defaultCapacity) {	//缺省参数一般在 函数声明 给出base = (int*)malloc(sizeof(int) * defaultCapacity);capacity = defaultCapacity;top = 0;
}

需要注意的是:声明定义分离式,如果函数有默认参数,一般要在函数声明处给出类的默认参数

一般情况下,更期望采用第二种方式, 因为我们并不希望所有的函数都称为内联函数。


类的成员变量命名规则

我们看该类:

class Clock {
private:    // 访问限定符int hour;int minute;int second;public:void setTime(int hour, int minute, int second){// 这里的hour到底是成员变量,还是函数形参?hour = hour;}
};

我们的疑问如注释中所写,为了避免这样的矛盾,我们通常这样定义类的成员变量。

private:    // 访问限定符int _hour;int _minute;int _second;
public:void setTime(int hour, int minute, int second){// 这里的hour到底是成员变量,还是函数形参?_hour = hour;//这样就解决了分歧,避免了二义性。}

类的访问限定符及封装

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用
在这里插入图片描述

访问限定符

C++通过三个访问限定符实现封装:

  1. public:公有成员,类内外均可访问
  2. private:私有成员,仅类内和友元可访问
  3. protected:保护成员,介于两者之间(继承时使用)

特点:

  1. public修饰的成员在类外可以直接被访问。
  2. protectedprivate修饰的成员在类外不能直接被访问(此处protected和private是类似的)。
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止。
  4. 如果后面没有访问限定符,作用域就到}即类结束。
  5. class的默认访问权限为private,struct为public(因为struct要兼容C语言)。
  • C++需要兼容C语言,所以C++中struct可以当成结构体使用。
  • 另外C++中struct还可以用来定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类默认访问权限是private。
  • 注意:在继承和模板参数列表位置,struct和class也有区别,后序给大家介绍。

通常建议我们不要采用C++语法中的默认权限,不管是class还是struct,我们都应该手动控制访问权限

封装

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

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

封装是指将数据和操作数据的方法进行有机结合,并对外部隐藏实现细节。其优势体现在:

  1. 数据保护:通过私有化成员变量防止意外修改
  2. 接口统一:通过公有方法提供规范的操作方式
  3. 实现隔离:修改内部实现不影响外部使用

示例封装:

class BankAccount {
private:double balance;  // 私有数据public:// 公开接口void deposit(double amount) {if(amount > 0) balance += amount;}bool withdraw(double amount) {if(amount <= balance) {balance -= amount;return true;}return false;}double getBalance() const { return balance; }
};

类的作用域与实例化

类的作用域

类定义了一个独立的作用域:

  • 成员变量/函数的作用域在整个类体内(整个类内是一个整体)
  • 外部访问需通过类名::成员或对象.成员

注意点:

  • 如上文所讲,成员函数在类外定义时需要指定类域
void Clock::setTime(int h, int m, int s) {// 实现代码
}

我们可以对比一下各种作用域各有什么特点。

  1. 全局域
  2. 局部域
  3. 类作用域
  4. 命名空间域(使用时需要指定)

局部域和全局域会影响变量的生命周期, 类域和命名空间域不会影响生命周期

类实例化

用类类型创建对象的过程,称为类的实例化

  1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;
  2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
int main(){person._age = 100;	// 编译失败:error C2059: 语法错误return 0;
}

Person类是没有空间的,只有Person类实例化出的对象才有具体的年龄。

做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

在这里插入图片描述

实例化方式:

Clock myClock;          // 栈上分配
Clock* pClock = new Clock;  // 堆上分配

new关键词我们将在后续讲解。

需要注意:

  1. 类声明不分配内存,实例化时才分配实际空间
  2. 同一类的不同对象拥有独立的成员变量存储空间
  3. 成员函数被所有对象共享(代码区存储)

类对象模型

类对象的大小

计算规则:

  • 遵循结构体内存对齐原则
  • 只计算成员变量大小(包括继承的)
  • 空类大小为1字节(占位标识)

验证示例:

class Empty {};
class Data {int num;        // 4字节double value;   // 8字节char tag;       // 1字节
};// 8 + 8 + 1 = 17 → vs下实际输出24(内存对齐)int main() {cout << sizeof(Empty) << endl;;  // 输出1cout << sizeof(Data) << endl;;  // 输出24
}

在这里插入图片描述


存储方式

类对象的存储采用分治策略:

  • 成员变量:每个对象独立存储(栈区/堆区)
  • 成员函数:所有对象共享代码区的一份拷贝
  • 静态成员:存储在全局数据区
    如图所示
    在这里插入图片描述
    在这里插入图片描述
    这个模型在我们计算对象的大小时也有体现
  • 对象中只存储成员变量。
  • 成员函数存放在一个公共区域(成员函数不在对象内存储)

内存布局示例:

对象1: [成员变量区]
对象2: [成员变量区]
...
代码区: [成员函数]

结论:

  • 一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐。
  • 注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

结构体内存对齐规则

//结构体内存对齐规则
//1. 第一个成员在与结构体偏移量为0的地址处。
//2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
//注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
//VS中默认的对齐数为8
//3. 结构体总大小为:最大对齐数(所有变量类型最大者 与 默认对齐参数 取较小的那个)的整数倍。
//4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
//体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

this指针(重点)

引出

我们先定义一个日期类

class Date{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;
}int main(){Date d1, d2;d1.Init(2025,1,11);d2.Init(2024, 2, 22);d1.Print();d2.Print();return 0;
}

对于上述类,有这样的一个问题:
Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

编译器隐式添加this指针参数:

// 编译器视角下的成员函数
//编译器编译后,会对成员函数进行处理,会给成员函数加上参数this, 访问变量时,使用this访问
void Init(Date* const thisint year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}
void Print(Date* const this){cout <<this->_year<< "-" <<this->_month << "-"<< this->_day <<endl;
}int main(){Date d1, d2;//编译器视角下的函数调用,是编译器帮助我们传入的当前对象的地址d1.Init(&d1, 2025, 1, 11);d2.Init(&d2, 2024, 2, 22);d1.Print(&d1);d2.Print(&d2);return 0;
}

特性

  1. this指针的类型:className* constconst修饰指针本身,该指针不能被修改,也就是不能当左值。即成员函数中,不能给this指针赋值。
  2. 只能在“成员函数”的内部使用
  3. this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。正因如此,上文计算对象大小的时候并没有计算this指针。
  4. this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递。
  5. this指针在函数内部是要反复调用的, vs的编译器对this指针传递做了优化,对象地址放在ecx寄存器中,exc中存储this指针的值
  6. this指针是函数的形参,因此this指针存放在内存的栈区中

深入理解

思考题?(重点中的重点)

有如下类和代码,思考?

class TestThis {
public:void Print() {cout << "Print" << endl;}void PrintA() {cout << _A << endl;}
private:int _A;
};
void Test_This_1() {TestThis* p = nullptr;p->Print();
}
void Test_This_2() {TestThis* p = nullptr;p->PrintA();
}
int main(){Test_This_1();//Test_This_2();return 0;
}

思考两个函数调用的结果分别是什么?
1.编译时报错 2. 运行时崩溃 3. 正常运行

我们依次调用来看:

解答情形1

在这里插入图片描述
我们可以看到,中断打印Print, 并且提示:进程已退出,代码为0,0代表正常返回,可以看到,第一种情况的结果是:正常运行。

解答情形2

在这里插入图片描述
图2
观察两张图可看到,图一,光标一直在闪动,图二,程序结束时,退出代码为**-1073741819**,光标一直在闪动且退出代码为负数,显然是运行时崩溃。

原因分析

class TestThis {
public:void Print() {cout << Print() << endl;}void PrintA() {cout << _A << endl;}
private:int _A;
};

先看该类,挺简单的。两个成员函数:

  • Print(),打印字符串“Print”
  • PrintA(),打印成员变量_A的值

再看两个调用:

void Test_This_1() {TestThis* p = nullptr;p->Print();
}
void Test_This_2() {TestThis* p = nullptr;p->PrintA();
}

说白了讲,p是TestThis对象的空指针,通过指针p,分别调用Print()PrintA()函数

class TestThis {
public:void Print() {//this指针为空,但函数内没有对this指针解引用cout << Print() << endl;}void PrintA() {//this指针为空,但函数内访问_A,本质是this->_A//成员变量在对象内,因此发生了this指针的解引用。cout << _A << endl;}
private:int _A;
};
void Test_This_1() {TestThis* p = nullptr;//表示this指针为空p->Print();
}
void Test_This_2() {TestThis* p = nullptr;//表示this指针为空p->PrintA();
}

两种情形下,this指针都是空的。

  1. p->Print();,p调用Print, 不会发生解引用。因为,由上文得,Print的地址并不在对象中,p会作为实参传递给this指针,并没有发生空指针的解引用
  2. p->PrintA();,p调用PrintA, 不会发生解引用。但PrintA()函数内,有cout << _A << endl;,本质上是cout << this->_A << endl;,变量_A存储在对象内,因此需要去对象中找,也就发生了对象指针的解引用。此时对象指针为空,那么对空指针解引用,也就发生了运行时崩溃。

总结

  1. 类与对象关系:类是蓝图,对象是实体
  2. 访问控制:通过public/private/protected实现封装
  3. 存储模型:对象独立存储数据,共享函数代码
  4. this机制:隐式指针实现对象自治
  5. 设计原则:高内聚低耦合,合理使用访问限定符

理解类和对象的工作机制是掌握C++面向对象编程的基础,后续的继承、多态等特性都是建立在此基础之上的深入扩展。正确使用类和对象可以有效提高代码的可维护性和复用性。

今天的分享到此结束了,各位大佬多多支持。
一键三连,好运连连!

相关文章:

C++:类和对象初识

C&#xff1a;类和对象初识 前言类的引入与定义引入定义类的两种定义方法1. 声明和定义全部放在类体中2. 声明和定义分离式 类的成员变量命名规则 类的访问限定符及封装访问限定符封装 类的作用域与实例化类的作用域类实例化实例化方式&#xff1a; 类对象模型类对象的大小存储…...

伪分布式Spark3.4.4安装

参考&#xff1a;Spark2.1.0入门&#xff1a;Spark的安装和使用_厦大数据库实验室博客 我的版本&#xff1a; hadoop 3.1.3 hbase 2.2.2 java openjdk version "1.8.0_432" 问了chatgpt,建议下载Spark3.4.4&#xff0c;不适合下载Spark 2.1.0: step1 Spark下载…...

kafka服务端之控制器

文章目录 概述控制器的选举与故障恢复控制器的选举故障恢复 优雅关闭分区leader的选举 概述 在Kafka集群中会有一个或多个broker&#xff0c;其中有一个broker会被选举为控制器&#xff08;Kafka Controler&#xff09;&#xff0c;它负责管理整个集群中所有分区和副本的状态。…...

element-plus el-tree-select 修改 value 字段

element-plus el-tree-select 修改 value 字段 &#xff0c;不显示label 需要注意两个地方&#xff1a; <el-tree-select v-model"value" :data"data" multiple :render-after-expand"false" show-checkbox style"width: 240px" …...

SQL最佳实践(笔记)

写在前面&#xff1a; 之前baeldung的Java Weekly &#xfeff;Reviews里面推荐了一篇关于SQL优化的文章&#xff0c;正好最近在学习数据库相关知识&#xff0c;记一些学习笔记 原文地址&#xff1a;SQL Best Practices Every Java Engineer Must Know 1. 使用索引 使用索引…...

在 Java 中执行一个复杂的 SQL 查询(包含多表连接、子查询和聚合函数),如何确保查询的性能?请列举至少三条措施。请简要描述其工作原理?

在Java中执行复杂的SQL查询时&#xff0c;确保查询性能是非常重要的。 以下是三条关键措施&#xff0c;以及它们的详细解释、代码示例和实际开发中的注意事项。 1. 使用索引 索引是提高数据库查询性能的最基本手段之一。通过在查询条件中使用的列上创建索引&#xff0c;可以…...

java将list转成树结构

首先是实体类 public class DwdCusPtlSelectDto {//idprivate String key;//值private String value;//中文名private String title;private List<DwdCusPtlSelectDto> children;private String parentId;public void addChild(DwdCusPtlSelectDto child) {if(this.chil…...

【R语言】数据分析

一、描述性统计量 借助R语言内置的airquality数据集进行简单地演示&#xff1a; 1、集中趋势&#xff1a;均值和中位数 head(airquality) # 求集中趋势 mean(airquality$Ozone, na.rmT) # 求均值 median(airquality$Ozone, na.rmT) # 求中位数 2、众数 众数&#xff08;mod…...

传输层协议 UDP 与 TCP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; 前置复盘&#x1f98b; 传输层&#x1f98b; 再谈端口号&#x1f98b; 端口号范围划分&#x1f98b; 认识知名端口号 (Well-Know Port Number) 二&#xf…...

Linux 调用可执行程序

Linux 调用可执行程序 1. system() 函数1.1 system() 函数的声明1.2 system() 函数的不同场景返回值1.3 system() 函数的代码示例 2. exec() 函数族2.1 exec() 函数族的声明2.2 exec() 函数族执行失败的情况2.3 exec() 函数族的代码示例 3. exec() 与 system() 的区别以及使用注…...

Java/Kotlin双语革命性ORM框架Jimmer(一)——介绍与简单使用

概览 Jimmer是一个Java/Kotlin双语框架 包含一个革命性的ORM 以此ORM为基础打造了一套综合性方案解决方案&#xff0c;包括 DTO语言 更全面更强大的缓存机制&#xff0c;以及高度自动化的缓存一致性 更强大客户端文档和代码生成能力&#xff0c;包括Jimmer独创的远程异常 …...

剪辑学习整理

文章目录 1. 剪辑介绍 1. 剪辑介绍 剪辑可以干什么&#xff1f;剪辑分为哪些种类&#xff1f; https://www.bilibili.com/video/BV15r421p7aF/?spm_id_from333.337.search-card.all.click&vd_source5534adbd427e3b01c725714cd93961af 学完剪辑之后如何找工作or兼职&#…...

IDEA查看项目依赖包及其版本

一.IDEA将现有项目转换为Maven项目 在IntelliJ IDEA中,将现有项目转换为Maven项目是一个常见的需求,可以通过几种不同的方法来实现。Maven是一个强大的构建工具,它可以帮助自动化项目的构建过程,管理依赖关系,以及其他许多方面。 添加Maven支持 如果你的项目还没有pom.xm…...

centos虚拟机迁移没有ip的问题

故事背景&#xff0c;我们的centos虚拟机本来是好好的&#xff0c;但是拷贝到其他电脑上就不能分配ip&#xff0c;我个人觉得这个vmware他们软件应该搞定这个啊&#xff0c;因为这个问题是每次都会出现的。 网络选桥接 网络启动失败 service network restart Restarting netw…...

Java 大视界 -- Java 大数据在智能供应链中的应用与优化(76)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

Java中的继承及相关概念

在 Java 中&#xff0c;继承是一种允许一个类继承另一个类的特性。通过继承&#xff0c;子类可以获取父类的属性和方法&#xff0c;这有助于减少代码冗余并提高代码的可维护性。以下是关于文件内容的相关分析和知识点总结&#xff1a; 一、继承的核心概念 1.继承的语法 Java …...

赛博算命之 ”梅花易数“ 的 “JAVA“ 实现 ——从玄学到科学的探索

hello~朋友们&#xff01;好久不见&#xff01; 今天给大家带来赛博算命第三期——梅花易数的java实现 赛博算命系列文章&#xff1a; 周易六十四卦 掐指一算——小六壬 更多优质文章&#xff1a;个人主页 JAVA系列&#xff1a;JAVA 大佬们互三哦~互三必回&#xff01;&#xf…...

DNS攻击方式有哪些,应该采取哪些应对措施?

在当今数字化时代&#xff0c;网络已成为人们生活和工作不可或缺的一部分。而 DNS&#xff08;域名系统&#xff09;作为互联网的关键基础设施&#xff0c;如同电话簿一般&#xff0c;将人们易于记忆的域名转换为计算机能够识别的 IP 地址&#xff0c;让我们能够轻松访问各类网…...

即梦(Dreamina)技术浅析(六):多模态生成模型

多模态生成模型是即梦(Dreamina)的核心技术之一,旨在结合文本和图像信息,生成更符合用户需求的视觉内容。多模态生成模型通过整合不同类型的数据(如文本和图像),能够实现更丰富、更精准的生成效果。 1. 基本原理 1.1 多模态生成模型概述 多模态生成模型的目标是结合不…...

如何优化爬虫以提高搜索效率

在数据采集和网络爬虫领域&#xff0c;优化爬虫性能是提升数据采集效率的关键。随着网页结构的日益复杂和数据量的不断增长&#xff0c;高效的爬虫能够显著降低运行时间和资源成本。本文将详细介绍如何优化爬虫以提高搜索效率&#xff0c;包括选择合适的工具、优化代码逻辑、使…...

Node.js中http模块(二)

一、http模块 http 模块是 Node.js 官方提供的、用来创建 web 服务器的模块。通过 http 模块提供的 http.createServer0) 方法&#xff0c;就能方便的把一台普通的电脑&#xff0c;变成一台 Web 服务器&#xff0c;从而对外提供 Web 资源服务。 二、域名和域名服务器 尽管 I…...

android selinux 问题

参考 Android Selinux介绍&#xff0c;如何添加selinux 权限SELinux权限-总结添加Selinux 权限/常见的Selinux 权限问题为何Android普通APP可以执行私有数据中的so文件&#xff0c;而system app却不可以&#xff1f;Android SELinux权限概念和配置说明Selinux中的APP分类Andro…...

递增三元组(蓝桥杯18F)

暴力求解&#xff1a; #include<iostream> using namespace std; int main() {int N;cin >> N;int* A new int[N];int* B new int[N];int* C new int[N];for (int i 0; i < N;i) {cin >> A[i];}for (int i 0; i < N; i) {cin >> B[i];}for…...

计算机毕业设计SparkStreaming+Kafka广告推荐系统 广告预测 广告数据分析可视化 广告爬虫 大数据毕业设计 深度学习 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...

FreeCAD创建零件(系列1)

1、新建草图绘制1个矩形 2、画1个半圆弧 3、增加一个约束点 4、标注距离 5、将线段转为辅助线 将图中的线段切换为辅助线,线条颜色之后转为蓝色线。 6、离开草图...

韶音科技:消费电子行业售后服务实现数字化转型,重塑客户服务体系

韶音科技&#xff1a;消费电子行业售后服务实现数字化转型&#xff0c;重塑客户服务体系 在当今这个科技日新月异的时代&#xff0c;企业之间的竞争早已超越了单纯的产品质量比拼&#xff0c;**售后服务成为了衡量消费电子行业各品牌实力与客户满意度的关键一环。**深圳市韶音…...

mes系统对工业数字化转型起到重要作用,它的实际应用有哪些

一、生产计划与调度 在工业数字化转型中&#xff0c;MES 系统能够对生产计划进行高效的管理和调度。通过与企业资源计划&#xff08;ERP&#xff09;系统的集成&#xff0c;MES 可以获取生产订单信息&#xff0c;并根据生产设备的状态、人员安排以及物料供应情况等因素&#x…...

mongodb 使用内存过大分析

os 分析 内存使用 ps aux|head -1;ps aux|grep -v PID|sort -rn -k 4|head -10swap 使用 for i in $(ls /proc | grep "^[0-9]" | awk $0>100); do awk /Swap:/{aa$2}END{print "$i",a/1024"M"} /proc/$i/smaps;done| sort -k2nr | headmo…...

网络安全:挑战、技术与未来发展

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 在数字化时代&#xff0c;网络安全已成为全球关注的焦点。随着互联网的普及和信息技术的高速发展&#xff0c;网络攻击的…...

从零开始玩转Docker:轻松开启容器化之旅

一、什么是 Docker Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。简单来说&#xff0c;Docker 就像是一个超级 “快递箱”&#xff0c…...