C++感受9-Hello Object 生死版•上

你好对象!

  1. 认识C++中基础中的基础类型;
  2. 创建用户自定义的复合类型;
  3. 创建新类型的对象;
  4. 定制新类型对象的生死过程

零、面向对象启蒙

之前我们一直在问候世界,从这节课开始,我们的问候对象就是“对象(Object)”了。
今天是这个系列的第一节:《Hello Object 生死版.上》。

今天这节课,我们要学习如何创建物种以及如何创造对象,展开讲,包括:

  1. 在C++代码中创建一个新物种;
  2. 为这个新物种创造一个对象;
  3. 定制新创建的物种对象出生与对象死亡的过程。

这里提到了两个关键概念:物种和对象,大家能理解二者的区别吗?

“物种”就是一种生物的类型,而“对象”,是属于这种生物类型的,一只活生生的实体。比如,作为物种,恐龙(物种)是存在的,但是,今天的这个世界里,已经不存在,具体的某一只恐龙(对象)了。

之所以要把“对象”设定为后面许多课的重要学习对象,是因为有一种重要的编程思想叫作“面向对象编程”;英文是 Object Oriented Programming,简称OOP——面向对象编程。

直译的话就是“以对象为导向的方法来编程”,也可以理解为:围绕对象来设计、组织你的代码结构。

新知识通常需要以旧知识作为基础。之前我们已经写过至少6个版本的“问候”程序。比如:函数版、交互版、分支版、循环版等等。当时我们所使用的,是什么编程思想呢?有没有一种可能,我们一直都在写“没有思想”的代码呢?

当然不是。之前我们一直在使用“面向过程” (Procedure Oriented Programming)的思想在编写代码。

面向过程是一种特别自然而然的思想,因为在生活中我们就是这样处理事情的:

面向过程思想:把做一件大事情拆解为做几件比较小的过程。如有必要,再把一个小的过程拆成更小更小的过程。

面向过程就是一种典型的“大事化小,小事化了”的思路体现。

把“过程”对应到“函数”,大家是不是马上就能够认同:之前我们写的问候程序采用的是“面向过程”的方法。在 Hello World 例程的第一个版本,也就是第五节,《逐字逐句深入理解C++最小例程》,我们就讲过:

“把程序理解成是在做一件大事,那么,这件大事对应的就是main主函数”

而后的课程,在需求的不断增加与实现版本的不断演化的过程中,我们慢慢的把 “上班路上问候同事”这件事情(对应 main() 主函数)拆成两个小过程(函数):

  • Input() 函数:用来模拟实现遇到同事;
  • Hello() 函数:用来模拟实现问候同事。

“大事化小,小事化了”,“面向过程”的编程思路确实是非常地自然而然,但是,如果一件复杂的事情大到一定程度的时候,就会出现事情仿佛千头万绪,我们甚至不知道如何开始的情况。

举个例子:假设2030年,国家又要承办一场奥运会,而你突然被全国人民推到该届奥运总负责人的岗位,此时,你觉得自己应该如何开始?

正确的方法应该是:找人,找人才,找各项事情的总负责人。开幕式、场地、安全保障,经济收入、来宾接待,传播以及赛事自身,等一大堆事,你不可能样样擅长——你甚至一样都不擅长,因此你必须为每类事情,都找一个总负责人。

为不同类型的事情,找一个具备处理此类事情的方法的负责人。这里面有四个关键字:类型、事情、方法、负责人。其中“事情”还是对应到“函数”,而类型、方法、负责人对应C++代码中的什么呢?
答案如下:

现实世界代码世界备注
事情普通函数已学
类型数据类型,特别是用户自定义复合类型-
方法和类型紧绑定的函数:成员函数也经常就被称为:方法

小结一下: 当问题慢慢变复杂,作为解决者,我们所考虑的,将慢慢地从具体某一件事情要如何解决,转成为某一类事件,找一个具备处理方法人才;这就是面向过程到面向对象的转换的最初原因。

一、网课开始

ff12-HelloObject-生死版-上

二、类型即约束!

面向对象的编程无法一蹴而就,今天我们只需建立对“对象”的一种感性认识即可。那么,什么叫对象? 老办法,让我们还是从问题、从需求开始说起。之前我们写的问候程序,一直在使用一个人的名字叫什么来判断这个人是不是我们心目中的女神,如:

if (XXX == "志玲") { cout << "亲爱的女神!" << endl; }

这种判断方法存在重大的逻辑漏洞。天底下叫“志玲”的人多去了,但并不是叫“志玲”的人都是我闪心目中的女神。

一个数据的名字,对这个数据会有什么内容是无法保证的,即:数据的名字,对数据的内容,以及数据的外在表现,都不会有实质的约束力。

那么,什么可以约束一个数据的内容呢?
答:数据的类型!

比如,作为数据,作为对象,我们都是人,我们的类型就是“人类”,而“人类”这个类型,对人的约束,就是“要做人事”。如果有人不做人事,我们就会鄙视并痛哭他:“你真不是个人!”,这是一种伤人很深的骂法,因为,它从类型上否定了一个,相当于从根源上否定了一个人。

类似的,如果有人女生偶尔骂你 “你真是头猪”,相信你并不会太在意,因为对方通常只是在嫌你在某些事情上笨了一些。如果这个女人骂的是 “你真不是个人……”你觉得怎样?

有没有比 “你真不是个人” 更狠的呢?当然有,一会儿我们就会给出答案。

三、C++常见内置基础类型

类型是这么的重要,所以编程语言都会内置一些常用的基础类型,我们先来快速学习C++的五种基础中的基础类型,重点观察不同类型对各自数据的约束是什么?

3.1 整数类型 / int

int 是 integer的缩写。

既然是整数,肯定得能参于加(+)减(-)乘(*)除(/)等数学计算的;其中有细则,比如 0 不允许当除数。

就像网上常有的口号 “不怎样怎样,你就不是什么什么”一样,如果有个数,它无法参加加法计算,我们就可以“指责”它:“你丫的肯定不是个整数!”。

整数不带有小数的信息,因此,如果两个整数做除法,比发 7 / 2 ,将得到另一个整数:3,而不是 3.5。

int a = 7 / 2; // 得3,而非3.5

3.2 字符类型 / char

char 是 character 的缩写。

这里有一句话:“远上寒山石径斜”,请问它包含几个字?答7个。
字符就是一句话,一段文本中的一个字,或者一个标点符号,也包括空格、换行、缩进符等等。
可惜,在C/C++被发明的时候,计算机并未足够全球普及,因此,汉字并未被C/C++语言视为一个字符。因此,上面例子,只能改为:

这里有一句话:“How are you?”,请问它包含几个字符?答:12个。

计算机中,一切数据本质都是数,char 也能被无损地转成 int 类型,依情况被转换至 -128 ~ 127或者 0 ~ 255 之间的某个整数。

C/C++字符类型对数据,也就是字符的约束还有:一个字符数据只能存储在一个字节(byte)的内存里。字节是计算机程序可以单独处理的最小内存单位。有多小呢?最常见的情况,正如上一段所说的结果:小到只能存放 256 种数据——而这也正是C/C++中的字符无法存储汉字的原因,中文何止 256 个汉字!

在C/C++代码中,字符的字面表达,需要使用单引号包含,如:

char a = 'A';
char b = 'b';
char c = ',';

3.3 布尔类型 / bool

bool 是 boolean 的缩写。

现实中或许并没有非黑即白的事,但是有些事情,真就是真,假就是假。表达这种非真即假,非假即真的数据,就需要用 布尔(boolean)类型。

比如,女朋友问你:“爱我吗?”,你的答案也许可以使用 int 类型,回答她:“我爱你100”——但是,我们的专业建议是,请使用 bool 类型。

C++中,用关键字 true 表示真,false 表示假。二者都可以无损转换为 int 类型。其中 false 将被转换为 0,而 true 将被转换为 1,因此,尽管没什么意义,但是计算:

int v = false + true; 

这样代码是合法的,v 将得到 1 。

反过来,如果将 int 转换成 bool 类型数据,就是有损的了。其中 0 被转为 false,所有非 0 都被转为 true (很多信息,被弱化成一个信息,这就叫有损转换)。

bool b1 = true; bool b2 = 999; int v = b1 + b2; // v 是多少? 

上例中,v 将得到 2。

3.4 浮点类型 / float / double

带小数信息的数据,比如 3.14、2.5、99.999、100.0,在计算机中通常使用一种叫“浮点”,也就是 “float point” 的格式存储、表达。注意,当你刻意地写 “100.0”时,它就不是一个整数,而是一个正好小数位是0的浮点数。

和生活中一样,在计算机,表达、存储、计算带小数的数,代价都远大于整数(所以小学生都是先学整数的四则运算,后面才学的小数、分数)。为了避免浪费,C++将浮点数,又按能表达的精度范围的大小,分成两种:单精度浮点数和双精度浮点数,即 float 和 double。具体的精度可以将来再了解,现在只需要建立感性认识,请看例子:

float f = 3.14159265358; double d = 3.14159265358; 

例中,如果你再将 f 输出,会发现仅前面的 3.141592 是正确的,其后的小数位,可能都是错的。而 d 就没有这个问题。

3.5 标准库基础类型

除了语言内置的简单类型以外,C++标准库还提供了不少常用的基础类型,注意,它们都不是语言内置的,而且也并不算“简单”。它们被称为“标准库基础类型”,有别于前述的“内置基础类型”。

我们已经简单学习及多次使用过的标准库基础类型,这它俩:

  • std::string(标准库字符串类型)
  • std::string_view(字符串视图类型、即喜欢偷看的 “字符串观察者”)

(更多C++基础类型学习,记得到 d2school.com 站)

四、用户自定义复合类型

世间的事物这么丰富、复杂,如果我们只有语言的内置类型,什么 int、char、bool、float、double……哪怕再加上标准库提供的基础类型,也是无法表达的。比如,人,应该用什么类型表达?

之前,我们就一直使用 std::string (字符串)来表达人的姓名,这自然很好,因为姓名本来就是字符串。不好的地方,或者存在严重逻辑错误的是:我们用姓名代表一个人,并且,还用姓名叫什么,来判断一个人是不是我们心目中的女神……错大发了!

为了解决这个问题,计算机编程语言支持我们通过组织简单类型,来形成复杂类型,全称是“用户自定义复合类型”。这里的“用户”就是指程序员,也就是我们。而“复合”,则是在表明:新类型是由多个类型组合起来的。

组合过程是可递进的。比如,假设将 int、float、bool 三者组成一个新类型,称为 T1, 那么,可以将 T1 和 char、std::string 再组成又一个新类型。

int、float、bool 的组合,大家能想象一些实际用途吗?

我想了两个:

  • int : 表达年龄;
  • float:表达每月收入,且因收入不高,又仅精确到分,故float精度够用,无需double;
  • bool :是否低保户;

显然,贫穷限制了南老师的想象力,再来一个——

  • int : 表示本学期的第几次英语单元考;
  • float: 表示得分(小数部分只需有 0.0 / 0.5 );
  • bool: 是否低于本次考试全班平均分;

显然,这次限制南老师想象力的,应该是长期低学分的学渣身份。

五、实战定义新复合类型

前面举的例子,于本课的学习目标来说,都过于具体、过于细节了,无法体现本课学习的高度。我们的高度是:当代码世界中的上帝,随心所欲地创建类型。

尽管在史上真的存在过恐猪(daeodon)和恐蛇(dinilysia)物种,但是,我们将无视这一事实,自行创建我们心目中的“恐猪”和“恐蛇”类型,对应的英文名字也不一样,分别是:DinosaurPig 和 DinosaurSnake。

5.1 定义新结构类型

以 DinosaurPig 类型为例,定义一个新的复合类型的最简语法是:

struct DinosaurPig { }; 
  • 关键字 “struct” 来自 “structure 结构”,很好理解:通过组合一些成员,从而到一种新的结构类型嘛,小时候玩过积木的同学,肯定理解。

  • “struct” 之后(有至少一个空格)就是新类型的名字,此例为 DinosaurPig;

  • 名字之后需要一对花括号,这和我们之前写函数体很像,关键区别见下一点;

  • 在定义新类型最后,即 ‘}’ 之后,需要有一个分号;

请同学们自己写出恐蛇的定义。

就这样吗?这就是 “恐猪” 的结构??我们只定义了新的复合类型的名字,却没有为这种复合类型定义任何内部组成的类型及数据。比如,恐猪有没有长角?有没有獠牙?有没有翅膀?我们统统不管了,别问为什么,问就是想象力很贫乏。

结构名字之后的那对花括号内部,确实就是用来定义新类型应该有哪些类型的组成部分的——但如前所述,这些知识点对本课而言,过于具体、过于细节了,高度不够。

尽管有名无实,但我们确实定义了一种新类型,只是没有在这个类型里提出它对本类数据的约束。不过,有一种类型,它就真的无需对数据进行约束。

请思考:如果我们要为世间的万物,定一个类型,那么:

  • 第一、这个类型应该叫什么名字?
  • 第二、这个类型又该由哪些类型组合而成?

更具体一点,请你叫来一个小学生,然后问他:风、国画、牛、石油、棒棒糖的共同分类是什么?

小学生肯定要冲你翻白眼。

冲你翻白眼的小学生肯定没有学过面向对象编程,并且多半没有读过《般若波罗蜜多心经》中的“色即空、空即色”,或者《道德经》中的 “无名天地之始,有名万物之母”。

用中文表达的话,世间万事万物的共同类型,就应该叫 “事物类型”,或者 “东西类型”。因为一切都是东西。比如正在阅读本文的你,请问,为师我可以说你“不是个东西”吗?

男人女人都是人类,而狗、蛇、虫子、人都是动物类型,而 花、草、动物都是生物类型;而石油、花、人、狗、风、国画、牛、棒棒糖,它们都是“东西”。

比 “你真不是个人” 更狠的骂法也有答案了:“东西”类型远比“人类”更加根源,所以,骂“你真不是个东西”的杀伤力要远大骂“你真不是个人”。

用英文的话,世间万事万物的共同类型就是“Object”,Object即有事物、东西、对象的含义,为了让C++程序听起来高雅一些,中文世界的计算机前辈们选择了“对象”这个翻译。

原来如此,所谓的面向对象编程,原来就是面向东西编程而已……

别胡思乱想了,集中精力,来看超超超级重要的代码:东西类,也就是对象类型,应该如何定义:

struct Object
{/* 一片虚空 */
};

在某些语言里,你可能当不了“上帝”,因为那些语言会直接内置 Object 类型,你将因此而丧失实现自行定义世间万物最根源的类型的权利。

花括号中仍然只需保持一片空白即可。我们加了一句注释,是因为此刻它虚空得理直气壮:为对象类型添加任何组成成员,就是对世间的所有东西添加了某种约束——而一旦你添加了任何约束,就必然会造成世间万物中,可能会有某一种东西,正好不满足这个约束,于是这种东西就再属于“东西”……

如果你还不懂得“约束”的话,很可能是因为你还年轻,还没接受过社会的毒打,让我们改为定义爱情是什么吧……

struct Love 
{ /* 爱情需要由什么组成呢? */ 
}; 

把这个定义交给你的女朋友,相信她会抱怨:纸不够长,写不完我对爱情的定义:180平的房,1米8的身高,180万的存款……

定义类型,就是在定义约束;因为:类型即约束。

有了类型,接下来我们可以为类型创造出对象。和平常定义变量并没有区别。事实上,对象也是变量(或常量),只是,基础类型的数据习惯称为变量,而复合类型的变量习惯称为对象

请完成以下例程:

struct Object
{ 
};struct DinosaurPig
{
};struct DinosaurSnake 
{
};int main()
{Object o;DinosaurPig pig;DinosaurSnake snake;
}

六、实战构造与析构

上面的程序运行后,屏幕输出也将“一片虚空”,尽管身为“上帝”,我们心里清楚曾经有一个东西、一头猪、一条蛇来到过主函数的世界,只是它们悄悄地来,又悄悄地走了……

要怎么才能实现肉眼可观察的,对象的生和死呢?

前面我们说过,采用面向对象的思想编程时,我们就是在为特定类型的事找特定的“人才”,那么,定义一个新的复合类型的目的,本质就是要培养出某一种“类型”的“人才”。

这就要引入“成员函数(member function)”的概念。

为了让特定类型的“人才”具备特定的功能,我们仍然需要写函数——毕竟函数代表做事情——只是,此时我们所写的函数紧密地绑定到某一种类型身上,这种函数在C++中称为类型的成员函数。在更多的面向对象语言里,通常称为“方法/method”,即类型的方法。

让我们还是费点脑细胞,为前面的 “恐猪” 类型,想象一个“方法”吧,比如说 “拱”,那么,“DinosaurPig” 就可以拥有一个方法(成员函数)叫做 “RootAround()”。注意,这个“拱”是特属于恐猪的,和家猪的“拱”是各自的拱法。

C++是个有趣的语言,除了可以给特定类型(的对象)做某事的特定的方法以外,它还允许我们为特定类型(的对象)定制生或死的过程。

定制类型的生的过程,是一种特殊的方法(成员函数),叫构造函数(Constructor),定制类型的死的过程,则是析构函数(Destructor)。

成员函数和普通函数在定义语法上,存在不同。因为成员函数和特定类型紧密相关,所以它可以直接写在类型的内部,即复合类型的那一对花括号内。

构造函数和析构函数又是特殊的成员函数,它们都不能带函数的返回值类型声明,注意,不是指函数返回 void ,而是就不能写返回值类型。

构造函数和析构函数都不能写返回值类型,这显然是一种规定。可以按如下方法,理解这个规定(尽管并不100%正确):

  • 构造函数:负责对象生的过程,其返回结果自然是类的一个新对象,因此无需写返回类型;
  • 析构函数:负责对象死的过程,过程执行后,对象就死了,还有必要有返回值吗?

语义与逻辑上看,Object 类型显然还是应该保持一片虚空才对,只是为了观察它的对象的出生与死亡过程,所以我们才为它添加了构造与析构,且二者都是往屏幕上输出点肉眼可看到的内容。

构造函数和析构函数在命名上也有特殊要求,前者必须和类型名一致,比如 Object(),后者则为类型名字前面加一波浪线,比如:~Object();

#include <iostream>struct Object
{Object(){std::cout << "Hello world!" << std::endl; //来自对象的,对世界的问候}~Object(){std::cout << "Bye-bye world!" << std::endl; // 对象对世界的告别}
}; // <--- 千万别忘记分号

“恐猪”和“恐蛇”在本课只是在陪太子读书,大家自行发挥它们的生死过程的定制吧。

完成这个程序,你的一只脚已经悄然,迈过了面向对象世界大门的门槛了

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

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

相关文章

RocketMQ快速入门:group、topic、queue、tag等基本概念(四)

0. 引言 上一节&#xff0c;我们说明了rocketmq中的4个核心组成以及他们之间的工作关系。但其中穿插的topic, queue等概念&#xff0c;如果未接触过mq的同学可能会有些迷糊&#xff0c;所以本节&#xff0c;我们重点针对rocketmq中的基本概念进行讲解&#xff0c;之前学习过其…

人工智能中两个较为常见的评估模型性能指标(EVS、MAE)

1、解释方差(EVS) 官方社区链接&#xff1a;sklearn.metrics.explained_variance_score-scikit-learn中文社区 explained_variance_score是一个用于评估回归模型性能的指标&#xff0c;它衡量的是模型预测值与实际值之间关系的密切程度。具体来说&#xff0c;解释方差分数表示…

springboot整合rabbitMQ系列10 利用插件实现延时消息

插件的安装&#xff0c;本文就不做描述了&#xff0c;插件安装后如下&#xff0c;就说明安装成功了1 添加pom依赖&#xff0c;yml配置就不讲了2 核心类&#xff0c;定义交换机的代码改成如下&#xff0c;其它的定义队列&#xff0c;设置绑定关系&#xff0c;设置死信等&#xf…

【面试经典 150 | 数组】Z 字形变换

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;二维矩阵模拟方法二&#xff1a;一次遍历 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于…

【CouchDB 与 PouchDB】

CouchDB是什么 CouchDB&#xff0c;全名为Apache CouchDB&#xff0c;是一个开源的NoSQL数据库&#xff0c;由Apache软件基金会管理。CouchDB的主要特点是使用JSON作为存储格式&#xff0c;使用JavaScript作为查询语言&#xff08;通过MapReduce函数&#xff09;&#xff0c;并…

QT中基于TCP的网络通信

QT中基于TCP的网络通信 QTcpServer公共成员函数信号 QTcpSocket公共成员函数信号 通信流程服务器端通信流程代码 客户端通信流程代码 使用Qt提供的类进行基于TCP的套接字通信需要用到两个类&#xff1a; QTcpServer&#xff1a;服务器类&#xff0c;用于监听客户端连接以及和客…

赛劲SEJINIGB零背隙滚轮齿条齿圈产品助力高精度运动平台

在高度精密化的工业时代&#xff0c;传统齿轮齿条系统所面临的背隙、摩擦粉尘、润滑等问题愈发凸显&#xff0c;这些问题不仅限制了设备的精度和稳定性&#xff0c;还对生产效率和产品质量造成严重影响。为此&#xff0c;赛劲SEJINIGB经过长期研发和技术积累&#xff0c;推出了…

消息队列 Kafka 入门篇(二) -- 安装启动与可视化工具

一、Windows 10 环境安装 1、下载与解压 首先&#xff0c;访问Apache Kafka的官方下载地址&#xff1a; https://kafka.apache.org/downloads 在本教程中&#xff0c;我们将使用kafka_2.13-2.8.1版本作为示例。下载完成后&#xff0c;解压到您的工作目录的合适位置&#xff…

如何在Windows 8/10/11上启用和禁用内置访客帐户?这里提供几种方法

你的Windows上有一个内置的guest帐户&#xff0c;可以帮助计算机上没有帐户的人登录。当然&#xff0c;你可以打开或关闭它。本文将介绍一些在Windows 8/10/11计算机中启用和禁用内置guest帐户的有用方法&#xff0c;供你更好地参考。 如何启用内置来宾帐户 在本地组策略中启…

Django中的事务

1 开启全局的事务 DATABASES {default: {ENGINE: django.db.backends.mysql, # 使用mysql数据库NAME: tracerbackend, # 要连接的数据库USER: root, # 链接数据库的用于名PASSWORD: 123456, # 链接数据库的用于名HOST: 192.168.1.200, # mysql服务监听的ipPORT: 3306, …

面向多源异质遥感影像地物分类的自监督预训练方法

源自&#xff1a;测绘学报 作者&#xff1a;薛志祥, 余旭初, 刘景正, 杨国鹏, 刘冰, 余岸竹, 周嘉男, 金上鸿 摘 要 近年来,深度学习改变了遥感图像处理的方法。由于标注高质量样本费时费力,标签样本数量不足的现实问题会严重影响深层神经网络模型的性能。为解决这一突出矛盾…

Linux防火墙相关命令以及ip白名单配置

Linux防火墙相关命令以及ip白名单配置 firewall防火墙基础命令查看防火墙的服务状态查看防火墙的状态服务的开启、关闭和重启查看防火墙规则端口的查询、开放和关闭重启防火墙 防火墙白名单配置部分参数介绍 firewall防火墙基础命令 查看防火墙的服务状态 systemctl status f…

使用 vllm 本地部署 cohere 的 command-r

使用 vllm 本地部署 cohere 的 command-r 0. 引言1. 安装 vllm2. 本地部署 cohere 的 command-r3. 使用 cohere 的 command-r 0. 引言 此文章主要介绍使用 使用 vllm 本地部署 cohere 的 command-r。 1. 安装 vllm 创建虚拟环境&#xff0c; conda create -n myvllm python…

网络安全之CSRFSSRF漏洞(上篇)(技术进阶)

目录 一&#xff0c;CSRF篇 二&#xff0c;认识什么是CSRF 三&#xff0c;实现CSRF攻击的前提 四&#xff0c;实战演练 【1】案例1 【2】案例2 【3】案例3 【4】案例4&#xff08;metinfo&#xff09; 一&#xff0c;CSRF篇 二&#xff0c;认识什么是CSRF CSRF&#x…

程序员过了35岁没人要?“这行越老越香”

程序员35岁失业&#xff1f;参加完OceanBase开发者大会&#xff0c;我又悟了&#xff01; 周六参加了OceanBase2024 开发者大会的现场&#xff0c;来之前我其实挺忐忑的&#xff0c;我觉得一个数据库产品的发布会&#xff0c;能有什么新鲜的东西&#xff1f; 踏入酒店的那一刻&…

消消乐算法总结

前言 最近在工作中遇到一个问题&#xff0c;做一个消消乐的demo项目&#xff0c;连续相同数目超过四个后就要消除。我在网上看了很多解决方案&#xff0c;有十字形&#xff0c;横向&#xff0c;纵向&#xff0c;梯形搜索。越看越迷糊。这不是用一个BFS就能解决的问题吗&#x…

ISP比普通的静态代理相比有什么优势?

ISP&#xff08;Internet Service Provider&#xff09;&#xff0c;即互联网服务提供商&#xff0c;是向广大用户综合提供互联网接入业务、信息业务、增值业务的电信运营商。而静态代理则是一个固定不变的代理IP地址&#xff0c;具有稳定性强、兼容性好和管理方便等特点。当我…

LiveNVR监控流媒体Onvif/RTSP常见问题-如何对比监控摄像头延时视频流延时支持webrtc视频流播放超低延时播放

LiveNVR如何对比监控摄像头延时视频流延时支持webrtc视频流播放超低延时播放 1、问题场景2、如何对比延时&#xff1f;3、WEBRTC延时对比4、LiveNVR支持WEBRTC输出5、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、问题场景 需要低延时的视频流监控播放&#xff0c;之前可以用rtmp…

在docker容器中编译 rk3588 ubuntu固件

文件准备 Linux SDK ---- rk3588_linux_release_20230114_v1.0.6c_0*Ubuntu根文件系统 ---- Ubuntu22.04-Xfce_RK3588_v3.11-27_20240410.img.7z 硬件环境 一个可联网的linux机器&#xff0c;并且装有docker 打包一个docker编译环境 Dockerfile内容 直接通过dockerfile构…

路由引入,过滤实验

实验拓补图 实验目的&#xff1a; 1、按照图示配置 IP 地址&#xff0c;R1&#xff0c;R3&#xff0c;R4 loopback口模拟业务网段 2、R1 和 R2 运行 RIPv2,R2&#xff0c;R3和R4运行 OSPF&#xff0c;各自协议内部互通 3、在 RIP 和 oSPF 间配置双向路由引入,要求除 R4 上的…