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

【Python学习 / 6】面向对象编程(OOP)

文章目录

  • ⭐前言⭐
  • 一、类和对象:面向对象编程基础
    • 1. 类(Class)
      • 类的组成:
      • 例子:定义一个简单的 `Dog` 类
      • 代码解析:
    • 2. 对象(Object)
      • 对象的创建:
    • 3. 三大特性:封装、继承和多态
      • 3.1 封装(Encapsulation)
        • 封装的实现方式:
        • 示例:封装的应用
        • 解释:
      • 3.2 继承(Inheritance)
        • 继承的优点:
      • 3.3 多态(Polymorphism)
        • 示例:多态
        • 解释:
    • 4. `self` 参数
      • 示例:
      • 解释:
    • 5. 类方法、实例方法和静态方法
      • 5.1 实例方法
      • 5.2 类方法
      • 5.3 静态方法
    • 6. 访问控制
    • 7. 运算符重载
      • 示例:重载加法运算符 `+`
      • 解释:
  • 二、装饰器(Decorator)详细介绍
    • 装饰器的工作原理
    • 装饰器的基本示例
    • 带参数的装饰器
    • 装饰器返回值
    • 装饰器链
  • 三、反射(Reflection)详细介绍
    • 内置反射函数
    • 示例:反射操作
    • 动态调用方法
    • 反射的应用场景
      • 总结


⭐前言⭐

面向对象编程 (OOP) 是一种编程范式,它使用“类”和“对象”来组织代码。在 Python 中,面向对象编程通过类(Class)和对象(Object)来实现。类是对象的模板,而对象是类的实例。OOP 允许我们模拟现实世界中的事物和行为,具有封装、继承和多态等特性。

好的!我将对文章进行优化,并使内容更加详细、易于理解。以下是经过优化后的版本:


一、类和对象:面向对象编程基础

面向对象编程(OOP)是一种编程范式,它使用对象来封装数据和行为。在 OOP 中,类(Class)对象(Object) 是最基本的概念。下面我们详细讲解这两者以及如何使用它们。

1. 类(Class)

类(Class) 可以被看作是对象的“蓝图”或“模板”。它定义了对象的属性(state)和行为(methods)。通过类,可以创建多个具有相同属性和行为的对象。

类的组成:

  • 属性(Attributes):也叫成员变量或字段,是存储对象状态的数据。
  • 方法(Methods):是类定义的函数,用于描述对象的行为或操作。

例子:定义一个简单的 Dog

class Dog:def __init__(self, name, age):self.name = name  # 属性:狗的名字self.age = age    # 属性:狗的年龄def bark(self):  # 方法:狗叫的行为print(f"{self.name} is barking!")# 创建对象
my_dog = Dog("Buddy", 3)# 访问属性
print(my_dog.name)  # 输出:Buddy# 调用方法
my_dog.bark()  # 输出:Buddy is barking!

代码解析:

  1. __init__ 方法是类的构造函数,它在创建对象时自动调用,用来初始化对象的属性。
  2. self 代表对象本身,通过 self.nameself.age 可以访问对象的属性。
  3. bark 方法定义了狗的行为,让狗“叫”。
  4. 通过 my_dog = Dog("Buddy", 3) 创建了一个 Dog 对象 my_dog,并初始化了名字和年龄。

2. 对象(Object)

对象(Object) 是类的实例,是类在内存中的实际存在。每次创建一个类的实例时,都会生成一个对象。对象具有类所定义的属性和方法。

对象的创建:

通过类名创建对象,并传递必要的参数到构造函数 __init__

3. 三大特性:封装、继承和多态

面向对象编程的三大特性分别是:封装继承多态

3.1 封装(Encapsulation)

封装是指将对象的状态(属性)和行为(方法)捆绑在一起,并通过接口(方法)控制对内部数据的访问,从而隐藏实现的细节。

封装的实现方式:
  • 私有属性:通过双下划线(__)来定义,表示该属性不能被外部直接访问。
  • 公共方法:通过方法提供对私有属性的访问(getter 和 setter)。
示例:封装的应用
class Person:def __init__(self, name, age):self.name = nameself._age = age  # 私有属性# getter 方法:获取年龄def get_age(self):return self._age# setter 方法:设置年龄def set_age(self, age):if age > 0:self._age = ageelse:print("年龄不能为负")# 创建对象
person = Person("Alice", 30)
print(person.get_age())  # 使用 getter 获取年龄
person.set_age(35)  # 使用 setter 设置年龄
print(person.get_age())  # 输出 35
解释:
  • self._age 是私有属性,外部无法直接访问它。
  • 通过 get_age 方法可以获取 age,通过 set_age 方法可以设置新的年龄,但 set_age 包含验证逻辑,防止设置负值。

3.2 继承(Inheritance)

继承 是面向对象编程中的一种机制,允许一个类继承另一个类的属性和方法。子类不仅能够重用父类的代码,还可以对其进行扩展或修改。

继承的优点:
  • 代码重用:子类可以继承父类的属性和方法。
  • 层次结构:类之间通过继承形成层次结构。

示例:单继承

class Animal:def speak(self):print("Animal speaks")class Dog(Animal):  # Dog 继承自 Animaldef bark(self):print("Dog barks")dog = Dog()
dog.speak()  # 调用父类方法
dog.bark()   # 调用子类方法

示例:多继承

class A:def method_a(self):print("Method A")class B:def method_b(self):print("Method B")class C(A, B):  # C 继承自 A 和 Bdef method_c(self):print("Method C")c = C()
c.method_a()  # 父类 A 的方法
c.method_b()  # 父类 B 的方法
c.method_c()  # 子类 C 的方法

3.3 多态(Polymorphism)

多态 是指同一个方法在不同对象上的表现不同。通过多态,父类和子类可以使用相同的方法名,但每个类的实现可以不同。

示例:多态
class Animal:def speak(self):print("Animal speaks")class Dog(Animal):def speak(self):print("Dog barks")class Cat(Animal):def speak(self):print("Cat meows")# 动态绑定多态
animals = [Dog(), Cat()]
for animal in animals:animal.speak()  # 根据对象类型调用不同的方法
解释:
  • speak 方法在 DogCat 中有不同的实现,表现出了多态。

4. self 参数

self 是类中方法的第一个参数,表示当前对象的引用。它使得类的方法能够访问对象的属性和方法。每个对象在调用方法时,Python 会自动将自己作为 self 传递给方法。

示例:

class Car:def __init__(self, make, model):self.make = make  # 属性self.model = model  # 属性def display(self):  # 使用 self 来访问属性print(f"Car make: {self.make}, model: {self.model}")my_car = Car("Toyota", "Camry")
my_car.display()  # 输出: Car make: Toyota, model: Camry

解释:

  • self.makeself.model 代表当前对象的属性。
  • self 在每个方法中都是必须的,它指向当前的对象。

5. 类方法、实例方法和静态方法

在 Python 中,有三种方法类型:实例方法类方法静态方法

5.1 实例方法

实例方法是最常见的方法,它操作对象的属性。实例方法的第一个参数是 self,表示当前对象。

5.2 类方法

类方法使用 @classmethod 装饰器定义,第一个参数是 cls,表示类本身。类方法可以访问类属性,并且通常用于处理与类本身相关的操作。

5.3 静态方法

静态方法使用 @staticmethod 装饰器定义,不依赖于实例或类的属性,通常用于工具函数,不访问类或实例的状态。

class MyClass:count = 0  # 类属性def __init__(self, name):self.name = name  # 实例属性MyClass.count += 1  # 修改类属性@classmethoddef get_count(cls):  # 类方法return cls.count@staticmethoddef greet():  # 静态方法print("Hello, world!")# 创建对象
obj1 = MyClass("Object 1")
obj2 = MyClass("Object 2")
print(MyClass.get_count())  # 输出:2
MyClass.greet()  # 输出:Hello, world!

6. 访问控制

Python 的访问控制不是严格的,但通过命名约定,可以实现类似于私有、受保护和公有属性的效果:

  • 公有属性和方法:可以直接访问。
  • 受保护的属性和方法:以单下划线(_)开头,表示该属性不推荐外部访问,但并不阻止访问。
  • 私有属性和方法:以双下划线(__)开头,Python 会对其进行名称重整,使得外部无法直接访问。

7. 运算符重载

运算符重载 是指通过定义特殊方法(如 __add__, __sub__ 等),使对象能够与运算符进行交互。

示例:重载加法运算符 +

class Box:def __init__(self, length):self.length = length# 重载加法运算符def __add__(self, other):if isinstance(other, Box):# 返回两个 Box 对象的长度之和return Box(self.length + other.length)return NotImplementeddef __repr__(self):return f"Box({self.length})"# 创建两个 Box 对象
box1 = Box(10)
box2 = Box(20)# 使用加法运算符
box3 = box1 + box2  # 这将调用 box1.__add__(box2)print(box3)  # 输出:Box(30)

解释:

  1. 我们创建了一个 Box 类,它有一个 length 属性。
  2. 重载了加法运算符 +,使得两个 Box 对象可以相加(即它们的长度相加)。
  3. __add__ 方法将返回一个新的 Box 对象,它的长度是两个 Box 对象的长度之和。
  4. 最后,我们打印出 box3,它的长度是 30。

二、装饰器(Decorator)详细介绍

装饰器是 Python 中的一种非常强大的功能,允许你在不修改函数本身代码的前提下,动态地修改或增强函数的行为。装饰器本质上是一个函数,它接受一个函数作为输入,并返回一个新的函数,这个新的函数通常会在原始函数执行前后进行一些额外的操作。

装饰器的工作原理

装饰器的基本实现模式是:

  1. 装饰器函数:一个函数,接受被装饰的目标函数作为参数。
  2. 包装函数:在装饰器函数内部,定义一个包装器函数,这个包装器函数会增强或修改目标函数的行为。
  3. 返回包装器:装饰器函数返回包装器函数,使得目标函数被包装并增强。

装饰器的基本示例

def decorator(func):def wrapper():print("Before function call")func()  # 调用原函数print("After function call")return wrapper@decorator  # 使用装饰器的语法糖
def say_hello():print("Hello!")say_hello()

输出

Before function call
Hello!
After function call

解释

  1. @decorator 是装饰器的语法糖,实际上等价于 say_hello = decorator(say_hello),它将 say_hello 函数传递给 decorator 函数。
  2. decorator(say_hello) 返回一个 wrapper 函数,这个函数在调用时会先打印 "Before function call",然后调用 say_hello,最后打印 "After function call"

带参数的装饰器

装饰器不仅可以用于没有参数的函数,还可以应用于带有参数的函数。为了让装饰器可以处理不同参数的函数,我们需要在包装函数中使用 *args**kwargs 来接受并传递所有的参数。

def decorator(func):def wrapper(*args, **kwargs):print("Before function call")result = func(*args, **kwargs)  # 传递参数并调用原函数print("After function call")return result  # 返回原函数的结果return wrapper@decorator
def greet(name):print(f"Hello, {name}!")greet("Alice")

输出

Before function call
Hello, Alice!
After function call

解释

  • wrapper(*args, **kwargs) 允许装饰器处理所有参数类型,无论是位置参数还是关键字参数。
  • result = func(*args, **kwargs) 传递参数给原始函数,并捕获它的返回值。
  • return result 确保原函数的返回值被正确传递给调用者。

装饰器返回值

如果原函数有返回值,装饰器需要处理返回值,确保它能够返回给调用者。

def decorator(func):def wrapper(*args, **kwargs):print("Before function call")result = func(*args, **kwargs)print("After function call")return result  # 返回结果return wrapper@decorator
def add(a, b):return a + bresult = add(2, 3)
print(result)  # 输出: 5

解释

  • result = func(*args, **kwargs) 调用原函数并存储返回值。
  • return result 确保装饰器不干扰原函数的返回值。

装饰器链

多个装饰器可以应用于同一个函数。多个装饰器是从下到上执行的,即最先应用的装饰器在最上面。执行时,会依次调用每一个装饰器的包装器函数。

def decorator1(func):def wrapper(*args, **kwargs):print("Decorator 1 - Before")result = func(*args, **kwargs)print("Decorator 1 - After")return resultreturn wrapperdef decorator2(func):def wrapper(*args, **kwargs):print("Decorator 2 - Before")result = func(*args, **kwargs)print("Decorator 2 - After")return resultreturn wrapper@decorator1
@decorator2
def say_hello():print("Hello!")say_hello()

输出

Decorator 1 - Before
Decorator 2 - Before
Hello!
Decorator 2 - After
Decorator 1 - After

解释

  • @decorator1 @decorator2 say_hello 相当于 say_hello = decorator1(decorator2(say_hello)),装饰器是从内到外应用的。
  • 首先应用 decorator2,然后是 decorator1

三、反射(Reflection)详细介绍

反射是指在程序运行时,动态地获取类的信息(如属性、方法),并对其进行操作。Python 提供了一些内置函数来实现这一功能,这些函数使得 Python 程序可以在运行时查看和修改对象的属性或方法。

内置反射函数

Python 提供了几个函数来实现反射:

  • getattr(object, name[, default]): 获取对象 object 的属性 name,如果属性不存在,返回 default(如果提供)。
  • setattr(object, name, value): 设置对象 object 的属性 namevalue,如果属性不存在,则会创建一个新属性。
  • hasattr(object, name): 检查对象 object 是否有属性 name
  • delattr(object, name): 删除对象 object 的属性 name

示例:反射操作

class Person:def __init__(self, name, age):self.name = nameself.age = age# 创建对象
person = Person("Alice", 30)# 获取属性
print(getattr(person, "name"))  # 输出: Alice# 设置属性
setattr(person, "age", 35)
print(person.age)  # 输出: 35# 检查属性是否存在
print(hasattr(person, "age"))  # 输出: True# 删除属性
delattr(person, "age")
print(hasattr(person, "age"))  # 输出: False

解释

  • getattr(person, "name") 返回对象 personname 属性的值,输出 “Alice”。
  • setattr(person, "age", 35)personage 属性修改为 35。
  • hasattr(person, "age") 检查 person 是否有 age 属性。
  • delattr(person, "age") 删除 personage 属性。

动态调用方法

反射不仅能获取和设置属性,还可以动态调用对象的方法。通过 getattr() 可以获取方法,并直接调用。

class Person:def __init__(self, name, age):self.name = nameself.age = agedef greet(self):return f"Hello, my name is {self.name}."# 创建对象
person = Person("Bob", 40)# 获取方法
greet_method = getattr(person, "greet")# 调用方法
print(greet_method())  # 输出: Hello, my name is Bob.

解释

  • greet_method = getattr(person, "greet") 获取 person 对象的 greet 方法。
  • greet_method() 调用这个方法,返回对应的字符串。

反射的应用场景

反射技术常见的应用场景包括:

  1. 动态插件系统:在不修改代码的情况下,动态加载和执行插件。
  2. 自动化框架:例如 Web 框架,通过反射来动态生成路由、处理 HTTP 请求等。
  3. 序列化和反序列化:将数据结构或对象转换为字符串或字节流,反之亦然。
  4. 单元测试:在测试过程中,可以通过反射动态地修改对象的状态。

总结

  • 装饰器:装饰器是 Python 中的一种强大工具,能够在不修改函数代码的情况下动态修改或增强函数的行为。它常用于日志记录、权限检查、缓存等场景。
  • 反射:反射允许程序在运行时动态地操作类、对象的属性和方法,Python 提供了 getattr()setattr()hasattr()delattr() 等内置函数来实现这一功能。反射广泛应用于框架、插件系统、自动化工具等高级编程场景。

相关文章:

【Python学习 / 6】面向对象编程(OOP)

文章目录 ⭐前言⭐一、类和对象:面向对象编程基础1. 类(Class)类的组成:例子:定义一个简单的 Dog 类代码解析: 2. 对象(Object)对象的创建: 3. 三大特性:封装…...

Ollama DeepSeek + AnythingLLM 实现本地私有AI知识库

Ollama DeepSeek AnythingLLM 实现本地私有AI知识库 本地部署DeepSeek-r1下载安装AnythingLLMAnythingLLM 配置LLM首选项Embedder首选项向量数据库工作区其他配置 AnythingLLM Workspace使用上传知识词嵌入知识检索 本文主要介绍了如何使用AnythingLLM结合Ollama部署的DeepSee…...

个人博客测试报告

一、项目背景 个人博客系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时将其部署到云服务器上。前端主要有四个页面构成:登录页、列表页、详情页以及编辑页,以上模拟实现了最简单的个人博客系统。其结合后…...

嵌入式八股文(四)计算机网络篇

第一章 基础概念 1. 服务 指网络中各层为紧邻的上层提供的功能调用,是垂直的。包括面向连接服务、无连接服务、可靠服务、不可靠服务。 2. 协议 是计算机⽹络相互通信的对等层实体之间交换信息时必须遵守的规则或约定的集合。⽹络协议的三个基本要素:语法、…...

基于Electron+Vue3创建桌面应用

Electron 是一个开源框架,基于 Chromium 和 Node.js,用于开发跨平台桌面应用程序。它允许开发者使用 HTML、CSS 和 JavaScript 等 Web 技术构建原生桌面应用,支持 Windows、macOS 和 Linux。Electron 以其开发便捷性、强大的功能和丰富的生态系统而广泛应用于工具类应用、媒…...

建立稳定分析模式的模式语言01

Haitham Hamza 等 著,wnb 译 摘要 一般认为,软件分析模式在减少开销和缩短软件产品生命周期等方面会起到重要的作用。然而,分析模式的巨大潜能还未被充分发掘。缺乏稳定性是当前分析模式存在的主要问题。多数情况下,为特定问题建…...

【C++游戏开发-五子棋】

使用C开发五子棋游戏的详细实现方案,涵盖核心逻辑、界面设计和AI对战功能: 1. 项目结构 FiveChess/ ├── include/ │ ├── Board.h // 棋盘类 │ ├── Player.h // 玩家类 │ ├── AI.h // AI类 │ └── Game.h // 游戏主逻辑 ├── src/ …...

ubuntu20动态修改ip,springboot中yaml的内容的读取,修改,写入

文章目录 前言引入包yaml原始内容操作目标具体代码执行查看结果总结: 前言 之前有个需求,动态修改ubuntu20的ip,看了下: 本质上是修改01-netcfg.yaml文件,然后执行netplan apply就可以了。 所以,需求就变成了 如何对ya…...

tailwindcss学习02

vue中接入tailwindcss 使用cmd不要使用powershell npm create vitelatest stu02 -- --template vue cd stu02npm install --registry http://registry.npm.taobao.org npm install -D tailwindcss3.4.17 postcss autoprefixer --registry http://registry.npm.taobao.org npx t…...

千峰React:脚手架准备+JSX基础

组件化->封装性 React提供函数组件实现组件化 React和传统JS的区别就是JS需要手动管理DOM操作,React: 采用组件化开发,通过虚拟DOM提升性能。 MVC 是一种软件设计模式,全称为 Model-View-Controller(模型-视图-控制器&#x…...

【算法】快排

题目 快排 思路 如果输入为0或1直接返回;否则取一个基准值,可以取中间位置,如果输入是有序的可以避免时间过长,然后移动指针,先让i指针右移,如果小于基准值就继续右移,j指针左移同理。如果指…...

开放签电子签章工具版 2.0 正式发布,构建全场景电子签约能力、满足复杂的签章管理场景

根据近半年开源用户和市场需求反馈,开放签团队推出电子签章工具版2.0版本,主要解决复杂的签约流程集成和电子印章授权管理场景。以API接口对外提供服务和配置一套可视化后台管理系统,可与业务系统无缝集成,用户使用起来毫无“违和…...

python和pycharm 和Anaconda的关系

好的,下面我会详细说明 Python、PyCharm 和 Anaconda 三者的关系,并逐一解释它们的功能和作用。 1. Python(编程语言) 定义:Python 是一种高级编程语言,设计简洁,易于学习,且功能强…...

DeepSeek V3和R1

DeepSeek V3 和 R1 是深度求索(DeepSeek)推出的两款大模型,基于混合专家架构(MoE),但在设计目标、训练方法和应用场景上存在显著差异。以下是两者的详细对比与补充内容: DeepSeek V3和R1 一、模…...

JavaScript数组-获取数组中的元素

在JavaScript中,数组是一种非常实用的数据结构,它允许我们将多个值存储在一个单独的变量中。无论是数字、字符串还是对象,都可以作为数组的元素。获取数组中的特定元素是操作数组的基础技能之一。本文将详细介绍如何在JavaScript中获取数组中…...

SSE:用于流式传输的协议

一.什么是SSE SSE协议是一种基于http协议的单向通信协议,服务端可以向客户端发送数据,但是客户端不能向服务器发送数据。客户端通过创建一个到服务器的单向连接来监听事件。可以将一次性返回数据包改为流式返回数据。SSE协议支持断线重连,也支…...

Aseprite详细使用教程(7)——切片工具

1.名词解释 快捷键:ShiftC 切片工具功能(了解即可): (1)优化资源加载: 将较大的图像切成多个较小的切片,可减小单个文件大小,在网页或游戏等场景中,能显著提升加载速度…...

航空公司客户价值分析

目录 1 目的 2 方法 3 源代码 4 结果 5 扩展 1 目的 ①借助航空公司客户数据,对客户进行分类; ②对不同的客户类别进行特征分析,比较不同类别的客户的价值; ③针对不同价值的客户类别制定相应的营销策略,为其提供个性…...

基于开源Odoo、SKF Phoenix API与IMAX-8数采网关的圆织机设备智慧运维实施方案 ——以某纺织集团圆织机设备管理场景为例

一、方案背景与需求分析 1.1 纺织行业设备管理痛点 以某华东地区大型纺织集团为例,其圆织机设备管理面临以下挑战: 非计划停机损失高:圆织机主轴轴承故障频发,2024年单次停机损失达12万元(停机8小时导致订单延误&am…...

LLM 架构

LLM 分类 : 自编码模型 (encoder) : 代表模型 : BERT自回归模型 (decoder) : 代表模型 : GPT序列到序列模型 (encoder-decoder) : 代表模型 : T5 自编码模型 (AutoEncoder model , AE) 代表模型 : BERT (Bidirectional Encoder Representation from Transformers)特点 : Enc…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)&#xff…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...