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

AI大模型从0到1记录学习 day09

第 8 章 面向对象之类和对象
8.1 面向过程和面向对象
面向过程编程(Procedural Programming)和面向对象编程(OOP)是两种不同的编程范式,它们在软件开发中都有广泛的应用。
Python是一种混合型的语言,既支持面向过程的编程,也支持面向对象的编程。
面向过程的编程是一种以过程为中心的编程方式,主要关注解决问题的步骤,并将这些步骤写成函数或方法。
面向对象的编程是一种以对象为中心的编程方式,主要关注在解决问题的过程中涉及哪些对象以及这些对象如何交互
1)面向过程举例
想象一下,你要做一顿美味的晚餐。在面向过程编程的思维下,你会把整个做饭的过程拆分成一系列的步骤。
def buy():
print(“去超市购买食材。”)
def wash():
print(“清洗蔬菜。”)
def cut():
print(“切菜。”)
def cook():
print(“开始烹饪。”)
def serve():
print(“上菜啦!”)

buy()
wash()
cut()
cook()
serve()
上面就是一个典型的面向过程的程序,我们把整个做饭的过程分解成了一个个函数,每个函数完成一个特定的任务,然后按照顺序依次调用这些函数,就可以完成做晚餐的任务啦。这种方式非常直接,适合一些简单的任务,它注重的是程序的流程和步骤。
但是呢,当我们的程序变得越来越复杂,会出现什么问题呢?比如说,我们现在想做不同类型的菜,有些菜可能不需要洗菜,有些菜可能不需要切菜,或者你要同时做几道菜,那我们的代码就会变得越来越长,越来越乱,而且上面的代码步骤是没有通用性的。
2)面相对象举例(先感受)
用面向对象的思想实现上面的做菜功能
class Dish:
def init(self, name):
self.name = name
def prepare(self):
pass
class Salad(Dish):
def prepare(self):
print(f"为 {self.name} 购买食材。“)
print(f"清洗 {self.name} 的蔬菜。”)
print(f"切 {self.name} 的蔬菜。“)
class Stew(Dish):
def prepare(self):
print(f"为 {self.name} 购买食材。”)
print(f"切 {self.name} 的肉。“)
print(f"烹饪 {self.name}。”)
class Soup(Dish):
def prepare(self):
print(f"为 {self.name} 购买食材。“)
print(f"煮 {self.name}。”)
salad = Salad(“蔬菜沙拉”)
stew = Stew(“炖肉”)
soup = Soup(“西红柿鸡蛋汤”)

salad.prepare()
stew.prepare()
soup.prepare()
在这里,我们创建了一个 Dish 类,它就像是一个菜的模板。然后我们创建了 Salad、Stew 和 Soup 这些子类,它们都继承自 Dish 类。每个子类都有自己的 prepare 方法,这个方法描述了如何准备这道菜。
这样,我们可以看到面向对象编程的优势啦 首先,我们把相关的数据(比如菜的名字)和操作(比如准备菜的过程)都封装在了一个类里面,这叫做 “封装”。而且,不同类型的菜可以有自己独特的准备方法,我们可以根据需要去修改或扩展这些方法,而不会影响其他类。这就像是每个菜都有自己的制作过程。
还有,当我们想要添加新的菜品时,我们只需要创建一个新的子类,定义它自己的 prepare 方法就好,不需要修改原来的代码。
3)面向对象历史
对象作为编程实体最早是于1960年代由Simula 67语言引入思维。Simula这一语言是奥利-约翰·达尔和克利斯登·奈加特在奥斯陆的挪威计算中心为模拟环境而设计的。(据说,他们是为了模拟船只而设计的这种语言,并且对不同船只间属性的相互影响感兴趣。他们将不同的类型船只归纳为不同的类,而每一个对象,基于它的类,可以定义它自己的属性和行为。)这种办法是分析式程序的最早概念体现。在分析式程序中,我们将真实世界的对象映射到抽象的对象,这叫做“模拟”。Simula不仅引入了“类”的概念,还应用了实例这一思想,这可能是这些概念的最早应用。
8.2 类和对象

8.2.1 类(Class)
类描述了所创建的对象共同的属性(是什么)和方法(能做什么),属性和方法统称为类的成员。
 类是对大量对象共性的抽象
 类是创建对象的模板
 类是客观事物在人脑中的主观反映
8.2.2 对象(Object)
 在自然界中,只要是客观存在的事物都是对象
 类是抽象的,对象是类的实例(Instance),是具体的。
 一个对象有自己的状态(属性)、行为(方法)和唯一的标识(本质上指内存中所创建的对象的地址)。
8.3 定义类
1)语法
class 类名:
“”“类说明文档”“”
类体
类名一般使用大驼峰命名法。
类体中可以包含类属性(也叫类变量)、方法、实例属性(也叫实例变量)等。
2)案例
定义一个人的类,包含 init() 方法、eat() 方法和 drink() 方法。

class Person:
“”“人的类”“”

home = "earth"def __init__(self):self.age = 0def eat(self):print("eating...")def drink(self):print("drinking...")

8.4 类的操作
类支持两种操作,成员引用和实例化。
1)成员引用
(1)语法
类名.成员名
(2)案例
class Person:
“”“人的类”“”

home = "earth"def __init__(self):self.age = 0def eat(self):print("eating...")def drink(self):print("drinking...")

home = Person.home # 获取一个字符串
eat_function = Person.eat # 获取一个函数对象
doc = Person.doc # 获取类的说明文档

print(home) # earth
print(eat_function) # <function Person.eat at 0x00000232C8230F40>
print(doc) # 人的类
2)实例化
(1)语法
变量名 = 类名()
(2)案例
class Person:
“”“人的类”“”

home = "earth"def __init__(self):self.age = 0def eat(self):print("eating...")def drink(self):print("drinking...")

p = Person() # 创建一个对象
print(p.home) # earth
print(p.age) # 0
p.eat() # eating…
p.drink() # drinking…
8.5 __init()__方法
init() 方法的调用时机在实例(通过 new())被创建之后,返回调用者之前。一般用于初始化一些数据。当类定义了 init() 方法后,在类实例化的时候会自动调用 init() 方法。也可以向 init() 方法中传参。
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = name

p = Person(“张三”) # 创建一个对象
print(p.name) # 张三
8.6 self
8.6.1 self作为实例传参
self代表类的实例自身。调用实例方法时,实例对象会作为第一个参数被传入。因此,我们调用p.eat()时就相当于调用了Person.eat§。
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")def drink(self):print("drinking...")

p = Person(“张三”) # 创建一个对象
p.eat() # eating…
Person.eat§ # eating…
8.6.2 通过self在类中调用类的实例属性和实例方法
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")def drink(self):print("drinking...")def eat_and_drink(self):print(self.name)  # 在类中调用nameself.eat()  # 在类中调用eat()方法self.drink()  # 在类中调用drink()方法

p = Person(“张三”) # 创建一个对象
p.eat_and_drink()
8.7 属性
8.7.1 类属性
也叫类变量。在类中方法外定义的属性。
1)通过 类名.属性名 或 实例名.属性名 访问
class Person:
“”“人的类”“”

home = "earth"  # 定义类属性

print(Person.home) # 通过类名访问类属性

p1 = Person() # 创建一个实例对象
print(p1.home) # 通过实例名访问类属性,(如果实例没有覆盖这个类属性的值)
2)通过 类名.属性名 添加与修改类属性
class Person:
“”“人的类”“”

Person.home = “earth” # 添加类属性
print(Person.home) # earth

Person.home = “mars” # 修改类属性
print(Person.home) # mars
若使用 实例名.属性名 则会创建或修改实例属性,因此不建议类属性和实例属性同名。
class Person:
“”“人的类”“”

home = "earth"

p1 = Person()
p2 = Person()
print(Person.home) # earth
print(p1.home) # earth
print(p2.home) # earth

print(“通过 类名.属性名 修改 类属性”)
Person.home = “mars”
print(Person.home) # mars
print(p1.home) # mars
print(p2.home) # mars

print(“通过 实例名.属性名 会创建 实例属性”)
p1.home = “venus”
print(Person.home) # mars
print(p1.home) # venus
print(p2.home) # mars
3)所有该类的实例共享同一个类属性
class Person:
“”“人的类”“”

home = "earth"  # 定义类属性,所有实例共享

p1 = Person() # 创建一个实例对象
p2 = Person() # 创建另一个实例对象

print(p1.home) # earth
print(p2.home) # earth
Person.home = “mars” # 修改类属性
print(p1.home) # mars
print(p2.home) # mars
8.7.2 实例属性
也叫实例变量。在类方法中定义的属性。通过 self.属性名定义。
1)通过 实例名.属性名 访问
class Person:
“”“人的类”“”

def __init__(self, name, age):self.name = name  # 定义实例属性self.age = age  # 定义实例属性

p1 = Person(“张三”, 18) # 创建一个实例对象
print(p1.name, p1.age) # 张三 18

p2 = Person(“李四”, 81) # 创建一个实例对象
print(p2.name, p2.age) # 李四 81

print(Person.name) # 报错
2)通过 实例名.属性名 添加与修改实例属性
class Person:
“”“人的类”“”

pass

p1 = Person() # 创建一个实例对象
p1.name = “张三” # 添加实例属性
p1.age = 18 # 添加实例属性
print(p1.name, p1.age) # 张三 18

p1.age = 25 # 修改实例属性
print(p1.name, p1.age) # 张三 25
3)每个实例独有一份实例属性
class Person:
“”“人的类”“”

def __init__(self, name):self.name = name  # 定义实例属性self.age = 0  # 定义实例属性

p1 = Person(“张三”) # 创建一个实例对象
print(p1.name, p1.age) # 张三 0
p1.age = 18 # 修改p1的age属性
print(p1.name, p1.age) # 张三 18

p2 = Person(“李四”) # 创建另一个实例对象
print(p2.name, p2.age) # 李四 0
8.8 方法
Python的类中有三种方法:实例方法、静态方法、类方法。
8.8.1 实例方法
 实例方法在类中定义,第一个参数为self,代表实例本身。
 实例方法只能被实例对象调用。
 可以访问实例属性、类属性、类方法。
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef instance_method(self):print(self.name, self.home, Person.home)

p = Person(“张三”)
p.instance_method() # 张三 earth earth,此时p中没有home实例属性,会去查找home类属性
Person.home = “venus” # 修改类属性
p.home = “mars” # 定义实例属性
p.instance_method() # 张三 mars venus
8.8.2 类方法
 类方法在类中通过 @classmethod 定义,第一个参数为cls,代表类本身。
 类方法可以被类和实例对象调用。
 可以访问类属性。
 在不创建实例的情况下调用,通过类名直接调用,非常方便,适合一些和类整体相关的操作。
class Person:
“”“人的类”“”

home = "earth"  # 定义类属性@classmethod
def class_method(cls):print(cls.home)

Person.class_method() # 通过类调用类方法

p1 = Person() # 创建一个实例对象
p1.class_method() # 通过实例对象调用类方法
8.8.3 静态方法
 静态方法在类中通过 @staticmethod 定义
 不访问实例属性或类属性,只依赖于传入的参数
 可以通过类名或实例调用,但它不会访问类或实例的内部信息,更像是一个工具函数,只是为了方便组织代码,把它放在了类里面。
class Person:
“”“人的类”“”

home = "earth"  # 定义类属性@staticmethod
def static_method():print("static method")

Person.static_method() # 通过类调用静态方法

p1 = Person() # 创建一个实例对象
p1.static_method() # 通过实例对象调用静态方法
8.8.4 在类外定义方法
并非必须在类定义中进行方法定义,也可以将一个函数对象赋值给一个类内局部变量。

在类外定义的函数

def f1(self, x, y):
print(x & y)

class C:
f = f1

C().f(6, 13) # 4
8.8.5 特殊方法
方法名中有两个前缀下划线和两个后缀下划线的方法为特殊方法,也叫魔法方法。上文提到的 init() 就是一个特殊方法。这些方法会在进行特定的操作时自动被调用。
几个常见的特殊方法:
1)new()
对象实例化时第一个调用的方法。
2)init()
类的初始化方法。
3)del()
对象的销毁器,定义了当对象被垃圾回收时的行为。使用 del xxx 时不会主动调用 del() ,除非此时引用计数==0。
4)str()
定义了对类的实例调用 str() 时的行为。
5)repr()
定义对类的实例调用 repr() 时的行为。 str() 和 repr() 最主要的差别在于目标用户。 repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的Python代码),而 str() 则产生人类可读的输出。
6)getattribute()
属性访问拦截器,定义了属性被访问前的操作。
8.9 动态添加属性与方法
8.9.1 动态给对象添加属性
class Person:
def init(self, name=None):
self.name = name

p = Person(“张三”)
print(p.name) # 张三

p.age = 18
print(p.age) # 18
8.9.2 动态给类添加属性
class Person:
def init(self, name=None):
self.name = name

p = Person(“张三”)
print(p.name) # 张三

Person.age = 0
print(p.age) # 0
8.9.3 动态给对象添加方法
1)添加普通方法
class Person:
def init(self, name=None):
self.name = name

def eat():
print(“吃饭”)

p = Person(“张三”)
p.eat = eat
p.eat() # 吃饭
2)添加实例方法
给对象添加的实例方法只绑定在当前对象上,不对其他对象生效,而且需要传入 self 参数。需要使用 types.MethodType(方法名,实例对象) 来添加实例方法。
import types

class Person:
def init(self, name=None):
self.name = name

def eat(self):
print(f"{self.name}在吃饭")

p = Person(“张三”)
p.eat = types.MethodType(eat, p)
p.eat() # 张三在吃饭
8.9.4 动态给类添加方法
给类添加的方法对它的所有对象都生效,添加类方法需要传入 cls 参数,添加静态方法则不需要。
class Person:
home = “earth”

def __init__(self, name=None):self.name = name

定义类方法

@classmethod
def come_from(cls):
print(f"来自{cls.home}")

定义静态方法

@staticmethod
def static_function():
print(“static function”)

Person.come_from = come_from
Person.come_from() # 来自earth

Person.static_function = static_function
Person.static_function() # static function
8.9.5 动态删除属性与方法
 del 对象.属性名
 delattr(对象,属性名)
8.9.6 __slots__限制实例属性与实例方法
Python允许在定义类的时候,定义一个特殊的 slots 变量,来限制该类的实例能添加的属性。使用 slots 可以限制添加实例属性和实例方法,但类属性、类方法和静态方法还可以添加。__slots__仅对当前类生效,对其子类无效。
import types

class Person:
slots = (“name”, “age”, “eat”)

def __init__(self, name=None):self.name = name

def eat(self):
print(f"{self.name}在吃饭")

def drink(self):
print(f"{self.name}在喝水")

p = Person(“张三”)

添加实例属性

p.age = 10
print(p.age) # 10

添加实例方法

p.eat = types.MethodType(eat, p)
p.eat() # 张三在吃饭

添加实例属性

p.weight = 100 # AttributeError: ‘Person’ object has no attribute ‘weight’

添加实例方法

p.drink = type.MethodType(drink, p) # AttributeError: type object ‘type’ has no attribute ‘MethodType’
第 9 章 面向对象之三大特性
9.1 封装
将变量和函数写入类中的操作即为封装,即类中封装了属性和方法。
通过封装,我们可以将一些细节隐藏起来(私有),只暴露出必要的接口供调用者使用。
9.1.1 私有化
有时为了限制属性和方法只能在类内访问,外部无法访问;或父类中某些属性和方法不希望被子类继承。可以将其私有化。
1)单下划线:非公开API
大多数Python代码都遵循这样一个约定:有一个前缀下划线的变量或方法应被视为非公开的API,例如 _var1。这种约定不具有强制力。
2)双下划线:名称改写
有两个前缀下划线,并至多一个后缀下划线的标识符,例如 __x,会被改写为 _类名__x。只有在类内部可以通过 __x 访问,其他地方无法访问或只能通过 _类名__x 访问。
9.1.2 私有属性
通过双下划线定义私有属性。
class Person:

def __init__(self, name):self.__name = namedef get_name(self):return self.__name

p = Person(“张三”)
print(p.get_name()) # 张三
print(p._Person__name) # 张三
print(p.__name) # 报错
9.1.3 私有方法
通过双下划线定义私有属性。
class Person:

# 定义私有方法
def __private_method(self):print("private method")# 定义实例方法,调用私有方法
def do_something(self):self.__private_method()

p = Person()
p.do_something() # private method
p._Person__private_method() # private method
p.__private_method() # 报错
9.1.4 property
1)方法转换为属性
可通过@property装饰器将一个方法转换为属性来调用。转换后可直接使用 .方法名 来使用,而无需使用 .方法名() 。
class Person:

def __init__(self, name):self.name = name@property
def eat(self):print(f"{self.name} is eating...")

p = Person(“张三”)
p.eat # 张三 is eating…
2)只读属性
将方法名设置为去掉双下划线的私有属性名,方法中返回私有属性。
class Person:

def __init__(self, name):self.__name = name@property
def name(self):return self.__name

p = Person(“张三”)
print(p.name) # 张三
p.name = “李四” # 报错
3)读写属性
将方法名设置为去掉双下划线的私有属性名,使用 属性名.setter 装饰。
class Person:

def __init__(self, name):self.__name = name@property
def name(self):return self.__name@name.setter
def name(self, name):self.__name = name

p = Person(“张三”)
print(p.name) # 张三

p.name = “李四”
print(p.name) # 李四
也可以在写方法中设置一些拦截条件来规范私有属性的写入。
class Person:

def __init__(self, name):self.__name = name@property
def name(self):return self.__name@name.setter
def name(self, name):if name == "李四":print("不许叫李四")else:self.__name = name

p = Person(“张三”)
print(p.name) # 张三

p.name = “李四” # 提示 “不许叫李四”
print(p.name) # 张三

p.name = “王五”
print(p.name) # 王五
4)注意
@property装饰的方法不要和变量重名,否则可能导致无限递归。
class Person:

@property
def name(self):return self.name

p = Person()
p.name # 报错:RecursionError: maximum recursion depth exceeded
9.2 继承
子类(派生类)继承父类(基类)中的属性和方法,实现代码重用。子类可以新增自己特有的方法,也可以重写父类的方法。
子类不能继承父类的私有属性和私有方法,因为存在名称改写。
9.2.1 单继承
1)语法
class 类名(父类):
类体
在类名后括号内指定要继承的父类。
2)案例
class Person:
“”“人的类”“”

home = "earth"  # 定义类属性def __init__(self, name):self.name = name  # 定义实例属性def eat(self):print("eating...")

class YellowRace(Person):
“”“黄种人”“”

color = "yellow"  # 定义类属性

class WhiteRace(Person):
“”“白种人”“”

color = "white"  # 定义类属性

class BlackRace(Person):
“”“黑种人”“”

color = "black"  # 定义类属性

y1 = YellowRace(“张三”)
print(y1.home) # earth
print(y1.color) # yellow
print(y1.name) # 张三
y1.eat() # eating…

w1 = WhiteRace(“李四”)
print(w1.home) # earth
print(w1.color) # white
print(w1.name) # 李四
w1.eat() # eating…

b1 = BlackRace(“王五”)
print(b1.home) # earth
print(b1.color) # black
print(b1.name) # 王五
b1.eat() # eating…
9.2.2 多继承
调用方法时先在子类中查找,若不存在则从左到右依次查找父类中是否包含方法。
1)语法
class 类名(父类1, 父类2, …):
类体
2)案例
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")

class YellowRace(Person):
“”“黄种人”“”

color = "yellow"def run(self):print("runing...")

class Student(Person):
“”“学生”“”

def __init__(self, name, grade):self.name = nameself.grade = gradedef study(self):print("studying...")

class ChineseStudent(Student, YellowRace): # 继承了Student和YellowRace
“”“中国学生”“”

country = "中国"

y1 = ChineseStudent(“张三”, “三年级”)
print(y1.home, y1.color, y1.country, y1.name, y1.grade)
y1.eat()
y1.run()
y1.study()
9.2.3 复用父类方法
子类可以在类中使用 super().方法名() 或 父类名.方法名() 来调用父类的方法。
1)super().方法名()
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")

class YellowRace(Person):
“”“黄种人”“”

color = "yellow"def run(self):print("runing...")

class Student(Person):
“”“学生”“”

def __init__(self, name, grade):self.name = nameself.grade = gradedef study(self):print("先吃再学")super().eat()  # 子类中调用父类的方法print("studying...")

class ChineseStudent(Student, YellowRace): # 继承了Student和YellowRace
“”“中国学生”“”

country = "中国"

y1 = ChineseStudent(“张三”, “三年级”)
print(y1.home, y1.color, y1.country, y1.name, y1.grade)
y1.study()
2)父类名.方法名()
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")

class YellowRace(Person):
“”“黄种人”“”

color = "yellow"def run(self):print("runing...")

class Student(Person):
“”“学生”“”

def __init__(self, name, grade):self.name = nameself.grade = gradedef study(self):print("先吃再学")Person.eat(self)  # 子类中调用父类的方法print("studying...")

class ChineseStudent(Student, YellowRace): # 继承了Student和YellowRace
“”“中国学生”“”

country = "中国"

y1 = ChineseStudent(“张三”, “三年级”)
print(y1.home, y1.color, y1.country, y1.name, y1.grade)
y1.study()
9.2.4 方法解析顺序
方法解析顺序(mro—Method Resolution Order)。可使用 类名.mro 访问类的继承链来查看方法解析顺序。
class Person:
“”“人的类”“”

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")

class YellowRace(Person):
“”“黄种人”“”

color = "yellow"def run(self):print("runing...")

class Student(Person):
“”“学生”“”

def __init__(self, name, grade):self.name = nameself.grade = gradedef study(self):print("先吃再学")Person.eat(self)print("studying...")

class ChineseStudent(Student, YellowRace):
“”“中国学生”“”

country = "中国"

y1 = ChineseStudent(“张三”, “三年级”)
print(
ChineseStudent.mro
) # (<class ‘main.ChineseStudent’>, <class ‘main.Student’>, <class ‘main.YellowRace’>, <class ‘main.Person’>, <class ‘object’>)
9.2.5 方法重写
在子类中定义与父类方法重名的方法,调用时会调用子类中重写的方法。
class Person:

home = "earth"def __init__(self, name):self.name = namedef eat(self):print("eating...")

class Chinese(Person):

color = "yellow"# 重写父类方法
def eat(self):print("用筷子吃")

y1 = Chinese(“张三”)
y1.eat()
注意:子类重写 init() 并调用时,不会执行父类的 init() 方法。如有必要,需在子类 init() 中使用 super().init() 来调用父类的 init() 方法。
class Person:

def __init__(self, name):self.name = name

class Chinese(Person):

def __init__(self, name, area):super().__init__(name)  # 调用父类的__init__()self.area = area

y1 = Chinese(“张三”, “北京”)
print(y1.name, y1.area)
9.3 多态
同一事物在不同场景下呈现不同状态。
class Animal:
def go(self):
pass

class Dog(Animal):
def go(self):
print(“跑”)

class Fish(Animal):
def go(self):
print(“游”)

class Bird(Animal):
def go(self):
print(“飞”)

def go(animal):
animal.go() # 将不同的实例传入,执行不同的方法

dog = Dog()
fish = Fish()
bird = Bird()
go(dog)
go(fish)
go(bird)

相关文章:

AI大模型从0到1记录学习 day09

第 8 章 面向对象之类和对象 8.1 面向过程和面向对象 面向过程编程&#xff08;Procedural Programming&#xff09;和面向对象编程&#xff08;OOP&#xff09;是两种不同的编程范式&#xff0c;它们在软件开发中都有广泛的应用。 Python是一种混合型的语言&#xff0c;既支持…...

【FW】ADB指令分类速查清单

1. 设备管理 指令核心作用adb devices列出已连接设备adb reboot重启设备adb reboot bootloader进入Bootloader模式adb reboot recovery进入Recovery模式adb root获取Root权限&#xff08;需设备支持&#xff09;adb remount挂载系统分区为可读写 2. 应用管理 指令核心作用adb…...

Kafka中的消息是如何存储的?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka中的消息是如何存储的&#xff1f;】面试题。希望对大家有帮助&#xff1b; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#xff0c;消息是通过 日志&#xff08;Log&#xff09; 的方式进行存储的。…...

Altium Designer——同时更改多个元素的属性(名称、网络标签、字符串标识)

右键要更改的其中一个对象&#xff0c;选择查找相似… 进入到筛选界面&#xff0c;就是选择你要多选的对象的共同特点&#xff08;名字、大小等等&#xff09;&#xff0c;我这里要更改的是网络标签&#xff0c;所以我选择Text设置为一样。 点击应用就是应用该筛选调节&#…...

当模板方法模式遇上工厂模式:一道优雅的烹饪架构设计

当模板方法模式遇上工厂模式&#xff1a;一道优雅的烹饪架构设计 模式交响曲的实现模板方法模式搭建烹饪骨架&#xff08;抽象类&#xff09;具体菜品&#xff08;子类&#xff09; 工厂模式 模式协作的优势呈现扩展性演示运行时流程控制 完整代码 如果在学习 设计模式的过程中…...

c++位运算总结

在C中&#xff0c;位运算是对二进制位进行操作的运算&#xff0c;主要有以下几种&#xff1a; 1. 按位与&#xff08; & &#xff09;&#xff1a;两个操作数对应位都为1时&#xff0c;结果位才为1&#xff0c;否则为0。例如 3 & 5 &#xff0c; 3 二进制是 0000 0011…...

企业级知识库建设:自建与开源产品集成的全景解析 —— 产品经理、CTO 与 CDO 的深度对话

文章目录 一、引言二、主流产品与方案对比表三、自建方案 vs. 开源产品集成&#xff1a;技术路径对比3.1 自建方案3.2 开源产品集成方案 四、结论与个人观点 一、引言 在当今数据驱动的商业环境中&#xff0c;构建高质量的知识库已成为企业数字化转型的关键一环。本博客分别从…...

Python小练习系列 Vol.6:单词搜索(网格回溯)

&#x1f9e0; Python小练习系列 Vol.6&#xff1a;单词搜索&#xff08;网格回溯&#xff09; &#x1f50d; 本期我们来挑战一道 LeetCode 上经典的网格型回溯题 —— 单词搜索&#xff0c;考察对 DFS 状态恢复的掌握&#xff01; &#x1f9e9; 一、题目描述 给定一个 m x…...

shell脚本--MySQL简单调用

实现功能 增 数据库的创建&#xff0c;数据表的创建已经实现 创建用户 删 删除数据库&#xff0c; 删除库下的某个表&#xff0c; 删除某个用户 改 暂无 查 查看所有的数据库&#xff0c; 查看某个库下的所有数据表&#xff0c; 查看某个表的结构&#xff0c; 查…...

vue3项目配置别名

vue3项目配置别名 src别名的配置TypeScript 编译配置如果出现/别名引入报找不到的问题 src别名的配置 在开发项目的时候文件与文件关系可能很复杂&#xff0c;因此我们需要给src文件夹配置一个别名&#xff01;&#xff01;&#xff01; // vite.config.ts import {defineCon…...

Rust 面向对象

Rust 面向对象 引言 Rust 是一种系统编程语言,以其高性能、内存安全和并发支持而受到关注。Rust 的面向对象特性是其强大功能之一,它允许开发者以面向对象的方式构建复杂的应用程序。本文将深入探讨 Rust 的面向对象编程(OOP)特性,包括类的定义、继承、封装和多态等概念…...

[ C语言 ] | 从0到1?

目录 认识计算机语言 C语言 工欲善其事必先利其器 第一个C语言代码 这一些列 [ C语言 ] &#xff0c;就来分享一下 C语言 相关的知识点~ 认识计算机语言 我们说到计算机语言&#xff0c;语言&#xff0c;就是用来沟通的工具&#xff0c;计算机语言呢&#xff1f;就是我们…...

[Mac]利用Hexo+Github Pages搭建个人博客

由于我这台Mac基本没啥环境&#xff0c;因此需要从零开始配置&#xff0c;供各位参考。 注意⚠️&#xff1a;MacBook (M4)使用/bin/zsh作为默认Shell&#xff0c;其对应的配置文件为~/.zshrc 参考文档&#xff1a; HEXO系列教程 | 使用GitHub部署静态博客HEXO | 小白向教程 文…...

pycharm与python版本

python 3.6-3.9 pycharm 2021版本搭配最好 python 3.8 pycharm 2019版本搭配最好 pycharm各版本下载...

Qt在IMX6ULL嵌入式系统中图片加载问题排查与解决

Qt在IMX6ULL嵌入式系统中图片加载问题排查与解决&#xff08;保姆级教学&#xff01;&#xff09; 在使用Qt开发IMX6ULL嵌入式系统的过程中&#xff0c;我遇到了图片加载的常见问题。本文将分享问题排查的详细过程和解决方案&#xff0c;希望能帮助遇到类似困难的开发者。 问题…...

界面控件Telerik和Kendo UI 2025 Q1亮点——AI集成与数据可视化

Telerik DevCraft包含一个完整的产品栈来构建您下一个Web、移动和桌面应用程序。它使用HTML和每个.NET平台的UI库&#xff0c;加快开发速度。Telerik DevCraft提供完整的工具箱&#xff0c;用于构建现代和面向未来的业务应用程序&#xff0c;目前提供UI for ASP.NET MVC、Kendo…...

pycharm终端操作远程服务器

pycharm项目已经连接了远程服务器&#xff0c;但是打开终端&#xff0c;却依旧显示的是本地的那个环境&#xff0c;也就是说没有操作远程的那个环境。只能再使用Xshell去操作远程环境&#xff0c;很麻烦&#xff0c;找了下教程。 来源&#xff1a;https://blog.csdn.net/maolim…...

接口测试中数据库验证,怎么解决?

在接口测试中&#xff0c;通常需要在接口调用前后查询数据库&#xff0c;以验证接口操作是否正确影响了数据库状态。​这可以通过数据库断言来实现&#xff0c;PyMySQL库常用于连接和操作MySQL数据库。​通过该库&#xff0c;可以在测试中执行SQL语句&#xff0c;查询或修改数据…...

Playwright从入门到实战:比Selenium更快的数据爬取案例实战

摘要 Playwright 是微软开源的下一代浏览器自动化工具&#xff0c;凭借其高性能、跨浏览器支持和现代化设计&#xff0c;迅速成为 Web 自动化领域的热门选择。本文将从 安装配置 开始&#xff0c;通过 实战演练 展示其核心功能&#xff0c;并与 Selenium 深度对比&#xff0c;…...

defconfig配置宏的规则

defconfig配置宏的规则 CONFIG_INETnCONFIG_INETy defconfig里这样配置&#xff0c;CONFIG_INET宏有效吗 在 defconfig 文件中&#xff0c;如果出现了 相同的配置项被定义多次&#xff0c;最终生效的是最后一次出现的值。 &#x1f539; 你的配置 bash复制编辑CONFIG_INE…...

day1_Flink基础

文章目录 Flink基础今日课程内容目标为什么要学Flink技术更新迭代市场需求 流式计算批量计算概念特点 批量计算的优势和弊端流式计算生活中流场景流式计算的概念 Flink简介Flink历史Flink介绍 Flink架构体系已学过的框架技术Flink架构 Flink集群搭建Flink的集群模式Standalone模…...

ctf-web: 不统一的解析 + sql注入要求输入与输出相等 -- tpctf supersqli

# 从 django.shortcuts 模块导入 render 函数&#xff0c;用于渲染模板 from django.shortcuts import render # 从 django.db 模块导入 connection 对象&#xff0c;用于数据库连接 from django.db import connection# 此模块用于创建视图函数 # 从 django.http 模块导入 Http…...

基于Java与Go的下一代DDoS防御体系构建实战

引言:混合云时代的攻防对抗新格局 2024年某金融平台遭遇峰值2.3Tbps的IPv6混合攻击,传统WAF方案在新型AI驱动攻击面前全面失效。本文将以Java与Go为技术栈,揭示如何构建具备智能决策能力的防御系统。 一、攻击防御技术矩阵重构 1.1 混合攻击特征识别 攻击类型Java检测方案…...

使用FastExcel时的单个和批量插入的问题

在我们用excel表进行插入导出的时候&#xff0c;通常使用easyexcel或者FastExcel&#xff0c;而fastexcel是easy的升级版本&#xff0c;今天我们就对使用FastExcel时往数据库插入数据的业务场景做出一个详细的剖析 场景1 现在我们数据库有一张组织表&#xff0c;组织表的字段…...

交换技术综合实验

一、实验拓扑 二、实验要求 内网IP地址使用172.16.0.0/16分配。 SW1和SW2之间互为备份。 VRRP/STP/VLAN/Eth-trunk均使用。 所有PC通过DHCP获取IP地址。 ISP只能配置IP地址。 所有电脑可以正常访问ISP路由器。 三、实验步骤 基于172.16.0.0/16进行划分 172.16.2.0/24&…...

软件工程之软件开发模型(瀑布、迭代、敏捷、DevOps)

1. 瀑布模型&#xff08;Waterfall Model&#xff09; 定义与流程 瀑布模型是线性顺序的开发流程&#xff0c;包含需求分析、设计、编码、测试、维护等阶段&#xff0c;每个阶段完成后才能进入下一阶段&#xff0c;类似“瀑布流水”逐级推进。 核心特点 严格阶段划分&#…...

Display Serializer、Camera Deserializer(Camera Des)和SerDes‌ 加解串应用

‌1. 概述&#xff1a;三者的核心定位‌ ‌(1) SerDes&#xff08;Serializer/Deserializer&#xff09;‌ ‌定义‌&#xff1a;通用高速数据传输技术&#xff0c;实现‌并行↔串行‌双向转换。‌角色‌&#xff1a;数据链路的“翻译官”&#xff0c;解决并行传输的带宽与距…...

Redis 常用数据结构及其对应的业务场景(总结)

1. String&#xff08;字符串&#xff09; 特点&#xff1a;最简单的键值对结构&#xff0c;可存储文本、数字或二进制数据&#xff08;最大 512MB&#xff09;。 适用场景&#xff1a; 缓存&#xff1a;存储用户信息、页面片段、商品详情等&#xff08;如 SET user:1 "{…...

记录Jmeter 利用BeanShell 脚本解析JSON字符串

下载org.json包(文档说明) #下载地址 https://www.json.org/ # github 地址 https://github.com/stleary/JSON-java # api 文档说明 https://resources.arcgis.com/en/help/arcobjects-java/api/arcobjects/com/esri/arcgis/server/json/JSONObject.htmlBeanShell脚本 import…...

深入解析音频:格式、同步及封装容器

物理音频和数字音频 物理音频 定义&#xff1a;物理音频就是声音在自然界中的物理表现形式&#xff0c;本质上是一种机械波&#xff0c;通过空气或其他介质传播。例如&#xff0c;当我们说话、乐器演奏或物体碰撞时&#xff0c;都会产生振动&#xff0c;这些振动会引起周围介…...