面向对象面试题集合

前言

记录面向对象面试题相关内容,方便复习及查漏补缺

题1.简述面向对象?主要特征是什么?

面向对象编程(Object-Oriented Programming,简称OOP)是一种以“对象”为核心的编程范式,通过将现实世界的实体抽象为“类”和“对象”,将属性和行为封装在一起,模拟实体间的交互。

其核心思想是通过模块化、代码复用和灵活扩展来实现软件的可维护性和可扩展性

主要特征:

  1. 封装(Encapsulation):将属性和行为封装在类中,隐藏内部的实现细节,对外提供公开的接口和对象进行交互,其内部状态不能直接访问。其作用可用增强数据的安全性(例如通过访问修饰符限制直接访问),降低模块间的耦合度,简化代码的使用
  2. 继承(Inheritance):子类可以继承父类的属性和方法,并在此基础上通过扩展或重新功能。其作用实现代码复用,构建层次化的类结构,支持逻辑分类和功能呢扩展
  3. 多态(Polymorphism):同一方法作用于不同的对象时,可能产生不同的行为。实现方式:通过方法重写(子类覆盖父类方法)和接口/抽象类来实现。作用提高代码灵活性,列入通过统一的接口处理多种对象类型,简化逻辑设计。
  4. 抽象(Abstraction)【补充说明】:抽象常被视为面向对象的基础概念,通过隐藏复杂的实现细节,只暴露必要的功能给用户,抽象类和接口是实现抽象的重要工具,它定义了一组方法签名,但不需要提供具体的实现。

题2.面向对象编程的优点

  1. 模块化:代码可用被分割成多个独立的对象,便于维护和扩展。
  2. 可重用性:通过继承和组合,代码可以在不同的场景下重复使用。
  3. 可扩展性:新功能可以通过添加新的类和对象来实现,而不需要修改现有代码。
  4. 易维护性:由于封装的存在,代码的内部实现可用随时修改,而不会影响外部调用。

题3.简述继承的原则?

继承是面向对象编程中的核心机制,其核心原则旨在确保代码的健壮性、可维护性和灵活性。

继承的主要原则:

  1. 里氏替换原则:子类必须能够完全替换父类,且不影响程序的正确性。子类不应改变父类原有功能的行为,子类可以扩展父类的功能,但不可破坏父类对外的“契约”(如前置条件、后置条件、不变量)
  2. 组合优于继承:优先使用组合(对象持有其他类的实例)而非继承,以降低耦合度。当需要复用功能但不存在逻辑上的“is-a”关系时,需要运行时动态切换行为时
  3. 避免深度继承层次:继承层次不宜过深,否则会增加复杂性。通过组合、接口或设计模式(如装饰器模式)替代多层次继承,扁平化类结构,拆分为更小的职责单元。
  4. 单一职责原则:父类和子类都应该专注于单一职责。若父类承担过多职责,子类可能被迫继承冗余功能,需通过拆分父类解决。子类应仅扩展与自身职责相关的功能。
  5. 开闭原则:对扩展开放,对修改关闭。通过继承扩展新功能(如子类添加新方法),而非修改父类现有代码。父类应设计为可扩展(如使用抽象类或者虚方法)
  6. 明确的“is-a”关系:继承应该严格表示逻辑上的“is-a”关系。反例:子类“企鹅”继承了父类“鸟”,父类中存在“飞”方法,但是企鹅不会飞,则违反逻辑,需要重新设计
  7. 接口隔离原则:避免子类被迫依赖不需要的接口。若父类包含子类不需要的方法,应拆分父类为更小颗粒的接口或者抽象类。
  8. 合理使用抽象与封装:父类应隐藏实现细节,仅暴露必要接口。父类通过“protected”或“public”方法提供扩展点,避免子类依赖内部状态。子类应通过父类接口操作数据,而非直接访问私有字段。

题4.列举面向对象OOD访问修饰符?

  1. public(公有):成员可以被任何类访问。暴露类的核心功能或者接口,供外部直接调用。
  2. private(私有):成员仅能在“定义它的类内部”访问,其他类无法直接访问。隐藏实现细节,保护敏感数据或内部逻辑。
  3. protected(受保护):成员在“本类内部”、“同一包/命名空间的类”以及“子类”中可用访问。支持继承体系中的功能扩展,允许子类复用或重写父类逻辑。
  4. internal:成员在同一程序集内可用访问。

题5.简述抽象类和接口的理解?

  1. 抽象类:抽象类是一种特殊的类,不能直接被实例化。抽象类可用包含抽象方法和普通方法,以及属性和事件成员。其主要目的是作为其他类的基类,提供部分实现的功能和一些共享的属性或方法。抽象类可以包含字段、构造函数、析构函数、静态成员和常量等,但不能被密封
  2. 接口:接口是一种引用类型,也不能被实例化。接口定义了一组方法、属性、事件或者索引器的契约,但不提供任何实现。接口主要是定义一组行为规范,这些行为规范可被任何实现该接口的类所共享。接口的成员(方法、属性、事件)都是公开的,并且接口可用包含多个成员。
  3. 区别和联系:(1)继承限制:抽象类只能被一个类继承,而接口可用被多个类实现。一个类可以有多个接口,但只能继承一个抽象类(C#中不支持多继承)。(2)成员类型:接口只能包含方法、属性、事件和索引器的声明,不能包含字段或已实现的方法;而抽象类可以包含这些成员。(3)用途:抽象类主要用于定义一系列紧密相关的类的共同特征和行为,而接口则用于定义一组不相关的类共同遵守的行为规范。接口通常用于定义松散的相关类,这些类实现某一功能。(4)接口中的成员默认是公开的,不能使用访问修饰符;而抽象类中的成员可用有不同的访问修饰符
  4. 实际应用场景:(1)抽象类:适用于那些需要被继承的场景,特别是当子类需要共享父类的某些实现时。例如,定义一个动物作为抽象类,然后让猫、狗等继承这个抽象类,并实现各自的具体行为。(2)接口:适用于定义一组不相关的类需要遵守的行为规范。例如,定义一个飞行接口,让鸟、飞机等实现这个接口代表他们都有飞行的能力

题6.死锁的必要条件?怎么解决?

死锁的必要条件包含下面四个:

  1. 互斥条件:资源只能被一个线程占用。例如,资源X和Y只能由一个线程持有。
  2. 请求并保持条件:一个线程持有A资源,同时等待B资源,而不释放已占用的A资源。
  3. 不可剥夺条件:线程获取的资源不能被强行剥夺,只能由线程自己释放。
  4. 循环等待条件:多个线程形成环状等待关系。例如A等B,B等C,C等A

解决死锁的方法包括以下几种:

  1. 预防死锁:通过设置某些限定条件来破坏死锁的四个必要条件中的一个或者多个,以确保系统不会进入不安全状态。这种方法实现简单,但可能导致系统资源的利用率和系统的吞吐量下降
  2. 避免死锁:在为进程分配资源之前,采用特殊算法检测并防止系统进入不安全状态。这种方法不需要设定严格的限定条件,但需要预知资源需求,计算开销较大。
  3. 检测与解除死锁:允许系统产生死锁,但设置特定的检测机构及时检测并解除死锁。这种方法资源利用率高,但恢复过程复杂。

避免死锁的策略:

  1. 一次性申请所需要的资源:尽量一次性申请所需要的资源,而不是分次申请,以避免因持部分资源而产生等待。
  2. 允许线程主动释放资源:允许线程在申请其他资源失败时,主动释放其已占有的资源,以减少死锁发生的机会。
  3. 按序申请资源:为每个资源指定一个线性顺序,线程在申请资源时必须按顺序申请,先申请序号小的资源,后申请序号大的资源,以避免循环等待的情况

题7.接口是否可以继承接口?抽象类是否可用实现接口?抽象类是否可用继承实体类?

  1. 接口可以继承接口:一个接口可以继承一个或多个其他接口。这叫“接口继承”。当一个接口继承另外一个接口时,他继承了父接口的所有成员(方法、属性、事件、索引器)声明,但是不继承任何实现,因为接口本身没有实现,子接口可用添加自己的新成员声明。目的:扩展契约。子接口表示一种更具体或功能更丰富的契约,它包含了父接口的所有要求,并添加了新的要求
    interface IShape
    {double CalculateArea();void Draw();
    }abstract class AbstractShape : IShape
    {// 为 Draw 提供通用实现(假设所有形状都用相同方式绘制轮廓)public void Draw(){Console.WriteLine("Drawing shape outline...");}// 将 CalculateArea 声明为抽象,强制子类提供具体计算逻辑public abstract double CalculateArea();
    }class Circle : AbstractShape
    {public double Radius { get; set; }// 必须实现抽象基类 AbstractShape 要求的 CalculateAreapublic override double CalculateArea(){return Math.PI * Radius * Radius;}// Draw 方法已由 AbstractShape 实现,Circle 可以直接使用或选择重写(override)
    }
  2. 抽象类可以实现接口:抽象类可用声明它实现一个或多个接口。实现方式:(1)提供具体实现:抽象类可用选择为接口的所有成员提供具体的实现代码。(2)将成员标记为抽象:抽象类可以将接口的成员声明为abstract。这意味着抽象类本身不提供这些成员的具体实现,而是强制要求任何继承该抽象类的非抽象具体子类必须提供这些实现。(3)混合实现:抽象类可用为部分接口成员提供具体实现,而将另外一些成员声明为abstract,留给子类实现。目的:抽象类实现接口是为了定义与该契约相关的一部分通用行为(提供具体实现),同时强制子类完成契约的特定部分(通过抽象成员)。
    interface IShape
    {double CalculateArea();void Draw();
    }abstract class AbstractShape : IShape
    {// 为 Draw 提供通用实现(假设所有形状都用相同方式绘制轮廓)public void Draw(){Console.WriteLine("Drawing shape outline...");}// 将 CalculateArea 声明为抽象,强制子类提供具体计算逻辑public abstract double CalculateArea();
    }class Circle : AbstractShape
    {public double Radius { get; set; }// 必须实现抽象基类 AbstractShape 要求的 CalculateAreapublic override double CalculateArea(){return Math.PI * Radius * Radius;}// Draw 方法已由 AbstractShape 实现,Circle 可以直接使用或选择重写(override)
    }
  3. 抽象类可以继承实体类:抽象类可以继承自一个非抽象类(即具体类、实体类)。当抽象类继承具体类时:(1)它继承了该具体类的所有成员(字段、属性、方法、事件等)。(2)他可以像普通派生类一样添加新的成员(具体或抽象的)。(3)它不能重写基类中非virtual或非abstract的方法(除非使用new关键字进行隐藏,但这通常不是好的实践)。目的:复用基类(具体类)中已有的功能,并在此基础上构建更抽象、更通用的概念。抽象类可用扩展基类的功能,同时定义一些需要子类实现的抽象操作。
    class Vehicle // 具体类(实体类)
    {public string Make { get; set; }public string Model { get; set; }public void StartEngine(){Console.WriteLine("Engine started.");}
    }abstract class FlyingVehicle : Vehicle // 抽象类继承具体类 Vehicle
    {// 继承自 Vehicle: Make, Model, StartEngine// 添加抽象成员,强制飞行器子类实现public abstract void TakeOff();public abstract void Land();// 可以添加新的具体成员public int MaxAltitude { get; set; }
    }class Helicopter : FlyingVehicle
    {// 必须实现 FlyingVehicle 的抽象方法public override void TakeOff() { Console.WriteLine("Helicopter taking off vertically."); }public override void Land() { Console.WriteLine("Helicopter landing vertically."); }// 继承自 FlyingVehicle: MaxAltitude// 继承自 Vehicle: Make, Model, StartEngine
    }

题8.简述封装具有的特性?

  1. 数据隐藏:将对象内部状态(字段/属性)设为private或protected。外部代码不能直接访问或修改对象的内部数据
  2. 访问控制:通过公共方法(public methods)或属性(properties)提供受控的访问通道,可添加验证逻辑确保数据有效性。
  3. 实现隔离:隐藏内部实现细节。外部只要知道“做什么”,无需知道“怎么做”
  4. 状态完整性:确保对象始终处于有效状态。通过封装防止非法状态转换。
  5. 变更保护:内部实现修改不影响外部调用者。
  6. 模块化:将相关数据和行为组织在独立单元(类)中。降低系统复杂度,提高内聚性。

核心价值:

  1. 安全性:防止非法访问和意外修改
  2. 灵活性:内部实现可自由变更
  3. 可维护性:错误局部化,便于调试
  4. 抽象简化:降低使用复杂度

题9.简述什么时候应用带参构造函数?

  1. 强制初始化必要数据
  2. 依赖注入(DI)
  3. 创建不可变对象
  4. 参数验证
  5. 简化对象配置
  6. 继承链初始化

关键选择原则:

  1. 必需依赖:类正常工作必须的依赖项 → 使用带参构造器强制提供
  2. 不变性要求:需要创建不可变对象时 → 通过构造器初始化只读成员
  3. 强验证需求:需要严格验证初始状态时 → 在构造器中实现验证逻辑
  4. 明确依赖关系:遵循显式依赖原则(Explicit Dependencies Principle)

最佳实践:

当参数超过 3-4 个时,考虑使用 Builder 模式 或 参数对象 替代长参数列表:

// 使用参数对象
public class EmployeeConfig {public string Name { get; set; }public int Age { get; set; }public string Department { get; set; }
}public class Employee {public Employee(EmployeeConfig config) { ... }
}

题10.简述内部类的好处?

  1. 增强封装性:访问私有成员:内部类可直接访问外部类的 private 成员(字段、方法、属性),无需通过公有接口暴露细节。隐藏实现:将只服务于外部类的辅助逻辑(如状态管理、算法实现)隐藏在内部,减少命名空间污染。
    public class Outer {private int _secret = 42;// 内部类访问外部类的私有成员private class Inner {public void RevealSecret(Outer outer) {Console.WriteLine(outer._secret); // 直接访问私有字段}}
    }
  2. 逻辑分组与代码组织:高内聚性:将紧密相关的类放在一起,提升代码可读性(如 Tree 类包含 TreeNode 内部类)。避免全局命名冲突:内部类名不会与全局类名冲突(如 Network.Packet 和 FileSystem.Packet 可共存)。
  3. 实现特定设计模式:工厂模式:外部类可通过内部类隐藏对象创建逻辑。迭代器模式:实现 IEnumerable 时常用内部类封装迭代状态(如 List<T>.Enumerator)。
    public class ProductFactory {public static IProduct Create() => new SecretProduct();private class SecretProduct : IProduct { ... } // 隐藏实现
    }
  4. 控制作用域与可见性:限制访问权限:通过 private/protected 修饰符,严格限制内部类的使用范围。减少耦合:外部代码无法直接依赖内部类,降低系统复杂性。
    public class Database {// 仅Database类可访问此连接器private class DbConnector { ... } 
    }
  5. 简化事件处理(尤其GUI开发):在 WinForms/WPF 中,常用内部类处理 UI 组件的专属事件,避免暴露回调逻辑。
    public class MainForm : Form {private Button _button;public MainForm() {_button = new Button();_button.Click += ButtonClickHandler;}// 事件处理逻辑封装在内部类private class ButtonHandler {public static void OnClick(object sender, EventArgs e) { ... }}
    }
  6. 优化资源管理:实现 IDisposable 时,可通过内部类管理非托管资源,确保外部类简洁。

题11.简述内部类的作用?

  1. 隐藏实现细节
  2. 逻辑紧密关联的辅助功能
  3. 特定模式(工厂、迭代器等)
  4. 受限作用域的场景

题12.解释方法重载与重写的区别?

在C#中,方法重载(Overloading)与方法重写(Overriding)是两种不同的多态性实现方式,主要区别如下:

  1. 方法重载(Overloading):定义:在同一个类中多个同名方法,方法参数列表必须不同(参数类型、数量、顺序不同),与返回值类型无关(仅返回值不同不能构成重载)。
    public class OverloadingClass{public int Add(int a, int b)=>a+b;public int Add(int a,int b,int c)=>a+b+c;public double Add(double a,double b)=>a+b;
    }

    核心特点。编译时多态:编译器根据调用时的参数来决定执行哪个方法。静态绑定:绑定发生在编译阶段。不需要继承关系。使用场景:提供同一功能的多种不同的实现方式。

  2. 方法重写(Overriding):定义:在子类中必须重新定义父类的方法。要求方法签名完全一致(方法名、参数列表、返回类型)必须使用virtual(父类)和override(子类)关键字
    public class Animal {public virtual void MakeSound() => Console.WriteLine("Animal sound");
    }public class Dog : Animal {public override void MakeSound() => Console.WriteLine("Bark!");
    }

  3. 核心特点。运行时多态:根据对象实际类型决定执行哪个方法。绑定发生在运行时。重点:必须有继承关系。使用场景:实现多态行为(如不同子类对同一方法的不同实现)

  4. 关键对比表

    特性方法重载 (Overloading)方法重写 (Overriding)
    发生位置同一个类中子类中
    参数要求必须不同必须相同
    返回值可以不同必须相同
    绑定时机编译时运行时
    继承关系不需要必须存在
    关键字不需要virtual + override
    多态类型编译时多态(静态)运行时多态(动态)
  5. 易混淆点:重载-隐藏(new)
    //重写示例 virtual+override
    public class Base {public virtual void Show() => Console.WriteLine("Base");
    }public class Derived : Base {// 方法隐藏(使用 new 关键字)public override void Show() => Console.WriteLine("Derived");
    }//隐藏示例 new
    public class Base {public void Show() => Console.WriteLine("Base");
    }public class Derived : Base {// 方法隐藏(使用 new 关键字)public new void Show() => Console.WriteLine("Derived");
    }

    隐藏(new字段):子类定义与父类同名方法(非重写),父类方法不需要关键字virtual,通过父类引用调用时仍执行父类方法

  6. 总结:
    场景选择
    同一类中提供不同参数实现重载(Overload)
    子类修改父类方法的行为重写(Override)
    子类定义与父类同名的新方法隐藏(new)

    关键记忆点:

    • 重载 = 同类 + 不同参数

    • 重写 = 子类 + 相同方法签名 + 多态行为


题13.简述接口隔离原则和单一原则如何理解?

在C#中,接口隔离原则(ISP)和单一职责原则(SRP)是SOLID设计原则的核心组成部分,它们的区别与联系如下:

  1. 单一职责原则(SRP),核心思想:一个类只应有一个引用变化的,即:每个类/模块只承担一种职责。关键理解:(1)职责聚焦:类应该专注于单一功能(如:UserValidator只负责验证,不负责存储),避免“上帝类”(包含太多不相干的功能类)。(2)优势:提高代码可读性、降低修改风险、简化单元测试。
    // ❌ 违反 SRP:混合用户操作和日志记录
    public class UserService {public void AddUser(User user) {// 业务逻辑...LogToFile("User added"); // 职责混杂}
    }// ✅ 遵循 SRP:分离职责
    public class UserService {private readonly ILogger _logger;public void AddUser(User user) { /* 业务逻辑 */ }
    }public class FileLogger : ILogger { /* 专职责日志 */ }
  2. 接口隔离原则(ISP),核心思想:客户端不应被迫依赖它不需要的接口方法,即:接口应小而专一,避免“胖接口”。关键理解:(1)接口粒度:将大接口拆分为多个小接口(如:IPrinter,IScanner代替IMultifunctionDevice),客户端只需要实现与其相关的方法。(2)优势:避免接口污染、提高系统灵活性、降低耦合度
  3. 原则对比表

    维度单一职责原则 (SRP)接口隔离原则 (ISP)
    作用对象类/模块接口
    核心目标职责单一化接口最小化
    解决痛点功能混杂的"上帝类"强迫实现无用方法的"胖接口"
    典型场景拆分混合业务逻辑的类为不同客户端提供定制接口
    代码表现通过类分解实现通过接口拆分实现
    关系ISP 是 SRP 在接口层面的延伸SRP 是 ISP 的实现基础
  4. 总结

    原则关键要点实践口诀
    SRP一个类只做一件事"高内聚,低耦合"
    ISP按需提供接口,拒绝强制实现"接口要精细,客户不背锅"

    二者共同目标:
    🔹 减少副作用(修改一处不影响其他)
    🔹 提升可维护性(模块化设计)
    🔹 增强扩展性(通过组合而非修改)


题14.解释finally在什么时候使用?

在C#中,finally块是异常处理机制(try-catch-finally)的核心组成部分,用于确保无论是否发生异常,特定代码都会被执行。

finally的核心使用场景:

  • 资源清理:确保非托管资源(文件句柄、数据库连接、网络连接等)在任何情况下都能被释放
    FileStream file = null;
    try {file = File.Open("data.txt", FileMode.Open);// 操作文件...
    }
    catch (IOException ex) {Console.WriteLine($"文件错误: {ex.Message}");
    }
    finally {file?.Close(); // 无论是否异常,确保文件关闭
    }
  • 状态重置:确保关键状态变量(如标志位、锁状态)总能被恢复
    bool isProcessing = true;
    try {// 执行关键操作...
    }
    finally {isProcessing = false; // 确保状态重置
    }
  • 日志记录:记录操作完成状态
    try {ProcessData();
    }
    finally {Log("数据处理操作已完成"); // 总会记录
    }
  1. finally的执行特性:(1)必执行性:finally块在以下流程中总会执行:try块正常完成时、catch块处理异常后、未捕获的异常抛出前。(2)与return的交互:即使try/catch中存在return,finally仍会在return前执行。(3)异常覆盖警告:若finally中抛出异常,会覆盖原始异常。
    try {throw new Exception("测试异常");
    }
    finally {Console.WriteLine("finally 仍会执行!");
    }
    // 输出:finally 仍会执行!
    // 随后程序崩溃:未处理异常string Test() {try {return "try 返回值";}finally {Console.WriteLine("finally 执行");}
    }
    // 输出:finally 执行
    // 返回:"try 返回值"try {throw new Exception("原始异常");
    }
    finally {throw new Exception("finally 异常"); // 此异常会覆盖原始异常
    }
  2. 替代方案:using语句。对于实现了 IDisposable 的对象,优先使用 using(本质是 try-finally 的语法糖):

  3. finally不执行的特殊情况:程序强制终止、断电或系统崩溃、无限循环阻塞、异步堆栈溢出
  4. 最佳实践总结:
    场景推荐方式
    释放非托管资源finally 或 using
    状态重置/清理finally
    必须执行的收尾操作finally
    实现 IDisposable 的对象using(优先)

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

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

相关文章

二十一、【用户管理与权限 - 篇三】角色管理:前端角色列表与 CRUD 实现

【用户管理与权限 - 篇三】角色管理:前端角色列表与 CRUD 实现 前言准备工作第一部分:更新 API 服务以包含角色管理第二部分:添加角色管理页面的路由和侧边栏入口第三部分:实现角色列表页面第四部分:实现角色表单对话框组件第五部分:全面测试总结前言 一个完善的权限系统…

Objective-c protocol 练习

题目描述&#xff1a; 请使用 Objective-C 中的 protocol 协议机制&#xff0c;实现一个简易的门禁控制系统。 系统包含两个类&#xff1a; AccessControlSystem —— 门禁系统&#xff0c;用于执行开门操作&#xff1b;Admin —— 实现权限判断逻辑的管理员。 要求如下&am…

科技创新赋能产业创新,双轮驱动助力新疆高质量发展!

在新疆维吾尔自治区成立70周年之际&#xff0c;中国产学研合作促进会于6月14日在乌鲁木齐举办“天山对话&#xff1a;推动新疆科技创新与产业创新”盛会。多位院士、专家、学者及企业代表齐聚一堂&#xff0c;探寻推动新疆科技创新和产业创新的新路径、新动能。活动现场&#x…

C#最佳实践:推荐使用 nameof 而非硬编码名称

C#最佳实践:推荐使用 nameof 而非硬编码名称 在 C# 编程领域,代码的可维护性、健壮性和可读性是衡量程序质量的重要指标。在日常开发中,我们常常会遇到需要引用类型、成员或变量名称的场景,比如在抛出异常时指定错误相关的变量名、在日志记录中标记关键元素名称等。传统的…

vue3 iframe 跨域-通讯

一、基础嵌套方法 直接在 HTML 中使用 <iframe> 标签指定 src 属性&#xff1a; <iframe src"https://目标网址.com" width"800" height"600"></iframe>‌限制‌&#xff1a;若目标网站设置了 X-Frame-Options 响应头&#x…

Iceberg与Hive集成深度

一、Iceberg在Hive中的ACID事务实现与实战 1.1 传统Hive的事务局限性 Hive原生仅支持非事务表&#xff08;Non-ACID&#xff09;&#xff0c;存在以下痛点&#xff1a; 不支持行级更新/删除并发写入时数据一致性无法保证无事务回滚机制历史版本查询需手动实现 1.2 Iceberg为…

深入剖析 Celery:分布式异步任务处理的利器

本文在创作过程中借助 AI 工具辅助资料整理与内容优化。图片来源网络。 文章目录 引言一、Celery 概述1.1 Celery 的定义和作用1.2 Celery 的应用场景 二、Celery 架构分析2.1 Celery 的整体架构2.2 消息中间件&#xff08;Broker&#xff09;2.3 任务队列&#xff08;Task Que…

Flask应用中处理异步事件(后台线程+事件循环)的方法(2)

在上一节&#xff0c;我们讲述了最简单最基础的后线程的建立&#xff0c;现在我们将进行拓展 Flask应用中处理异步事件&#xff08;后台线程事件循环&#xff09;的方法&#xff08;1&#xff09; 在我们的实际应用当中&#xff0c;我们需要定义三个东西 一个多线程的信号旗&am…

C++(面向对象编程)

思维导图 面向对象 1.面向对象思想 概念&#xff1a;面向对象编程&#xff08;OOP&#xff09;是一种以对象为基础的编程范式&#xff0c;强调将数据和操作数据的方法封装在一起。这就是上篇文章讲过的。面向过程是以“怎么解决问题”为核心&#xff0c;而面向对象思想在于“谁…

驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接,

驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接,Error: “The server selected protocol version TLS10 is not accepted by client preferences [TLS13&#xff0c;TLS12]”. ClientConnectionId:d5fd8d69-ae88-4055-9f6d-6e8515224ce2】。 基本上就是…

【三大前端语言之一】交互:JavaScript详解

【三大前端语言之一】交互&#xff1a;JavaScript详解 在学习完HTML和CSS之后&#xff0c;最后一门前端语言——JavaScript&#xff0c;是重中之重。HTML负责页面结构&#xff0c;CSS负责页面样式&#xff0c;而JavaScript则赋予网页“生命”&#xff0c;让网页可以动起来、响…

LangChain面试内容整理-知识点12:检索器(Retriever)接口与实现

在LangChain中,检索器(Retriever)是一个抽象接口,负责根据用户查询从数据源中检索相关文档。可以把Retriever理解为“搜索工具”:给它一个未经结构化的查询文本(如用户问题),它返回一组与之相关的 Document 对象。内部可以基于向量相似度、数据库查询、甚至网络搜索。 …

LLVM前端和优化层

文章目录 LLVM ArchitectueLLVM 前端Lexical Analysis词法分析Syntactic analysis 语法分析Syntactic Analyze语义分析 LLVM 优化层Pass 基础概念Pass 依赖关系Pass API 总结 LLVM Architectue LLVM 前端 LLVM 的前端其实是把源代码也就是 C、C、Python 这些高级语言变为编译器…

工作流和Agent 的区别与联系

工作流和智能体可能让人混淆的地方就是他们都可能有大模型的加持&#xff0c;都可能有工具的加入供大模型调用&#xff0c;本文做一下对比和联系 工作流 (Workflow) 定义&#xff1a; 工作流是一系列预定义、结构化且可重复的步骤或任务&#xff0c;旨在完成特定的业务目标或解…

leetcode--用StringBulider反转字符串单词的巧妙解法

反转字符串中的单词 这道题理想中的操作方式就是先去除前导和尾随空格&#xff0c;之后设一个尾指针&#xff0c;往前检索&#xff0c;扫到一个单词就把这个单词放到字符串的第一个位置。 很明显&#xff0c;java中我们不能直接对字符串进行修改&#xff0c;而我们想实现一个一…

连锁零售行业智慧能源管理解决方案:精准管控,让每一度电创造价值

在连锁超市、便利店等业态中&#xff0c;门店分布广、用能场景复杂、管理成本高是普遍难题。传统能源管理模式依赖人工抄表与分散管理&#xff0c;存在数据滞后、响应效率低、安全隐患难排查等问题。以某全国几千家门店的连锁便利店为例&#xff0c;其面临的挑战包括&#xff1…

在 PostgreSQL 中实现 `lck`, `special`, `item` 与 `org_id` 或 `user_id` 组合唯一的约束

在 PostgreSQL 中实现 lck, special, item 与 org_id 或 user_id 组合唯一的约束 要实现 lck, special, item 这三个字段必须与 org_id 或 user_id 中的一个&#xff08;但不能同时&#xff09;组合唯一的约束&#xff0c;你需要创建以下约束&#xff1a; 方案1&#xff1a;使…

g++ a.cpp -o a ‘pkg-config --cflags --libs opencv4‘/usr/bin/ld: 找不到 没有那个文件或目录

这个错误表明 pkg-config 命令没有正确执行&#xff0c;导致编译器无法找到 OpenCV 的库文件和头文件路径。pkg-config 是一个工具&#xff0c;用于查询已安装库的编译和链接选项。如果 pkg-config 无法找到 OpenCV 的配置文件&#xff0c;就会导致这个错误。 以下是解决这个问…

定制平板在智能家居中能做些什么?全面解析其核心功能

大家有没有发现&#xff0c;现在智能家居越来越普及了&#xff0c;很多家庭都在逐步升级自己的居住体验。而在这一过程中&#xff0c;一种设备正悄悄地取代我们以前常用的开关面板和手机APP&#xff0c;成为整个家庭智能控制的核心&#xff0c;这就是——定制平板。 它可不是我…

【通俗易懂】Linux 线程调度策略详解

引言&#xff1a;CPU是厨房&#xff0c;调度器是主厨 要真正理解Linux如何处理成千上万个并发任务&#xff0c;不妨把它想象成一个繁忙的专业厨房。这个比喻不仅能让抽象概念变得具体&#xff0c;更能揭示其背后深刻的设计哲学。 厨房 (The Kitchen): 代表整个计算机系统。 厨…