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

北京JAVA基础面试30天打卡01

希望大家坚持下去,30 天只更新核心面试题 ~

1. 接口和抽象类的区别

特性接口 (Interface)抽象类 (Abstract Class)
定义使用 interface 关键字定义,JDK 8 起支持默认方法和静态方法。使用 abstract class 关键字定义,包含抽象方法或具体方法。
继承类可以实现多个接口(多实现)。类只能继承一个抽象类(单继承)。
成员变量只能定义 public static final 的常量(默认)。可以定义任意类型的成员变量(包括实例变量)。
方法JDK 8 前只能有抽象方法;JDK 8 起支持默认方法和静态方法。可以有抽象方法和具体方法。
构造方法没有构造方法。可以有构造方法,供子类调用。
访问修饰符方法默认 public,无法定义 protected 或 private 方法。方法和变量可以有任意访问修饰符。
使用场景定义行为规范,强调契约式编程,适合松耦合设计。提供部分实现,适合具有共同逻辑的类层次结构。

总结

  • 接口适合定义规范,强调“做什么”,支持多实现,灵活性高。 自上而下,规定行为。
  • 抽象类适合代码复用,强调“是什么”,提供部分实现,适合有共同行为的类。 自下而上,抽取共性,一般重构用。
    其他:
    Java8:引l入了default和static方法,使得接口不仅仅
    是方法的声明,还可以提供具体的实现。default方法允
    许在接口中添加新的方法实现,而不影响己经实现该接口
    的类。
    Java9:引l入了私有方法,允许在接口中定义私有方法,
    用于default方法的内部逻辑复用。
    Java 14:引l入了sealed接口(仅在某些子类中使用),
    进一步增强了接口的功能

2. JDK 动态代理和 CGLIB 动态代理的区别

特性JDK 动态代理CGLIB 动态代理
实现方式基于接口,使用 Java 的 java.lang.reflect.Proxy 类。基于继承,使用 ASM 字节码操作框架生成子类。
依赖目标类必须实现接口。目标类无需实现接口,但不能是 final 类或方法。
代理对象生成通过反射生成实现接口的代理类。通过字节码生成目标类的子类。
性能性能稍低(依赖反射调用)。性能较高(直接字节码操作,调用效率接近原生)。
使用场景Spring 默认使用,AOP 中目标类有接口时优先选择。Spring AOP 中目标类无接口时使用,或需要代理非接口方法。
方法调用通过 InvocationHandler 的 invoke 方法拦截。通过 MethodInterceptor 的 intercept 方法拦截。
局限性只能代理接口定义的方法,无法代理非接口方法。无法代理 final 类或 final 方法。

总结

  • JDK 动态代理:适合有接口的场景,代码简单,依赖 JDK 原生支持,但性能稍逊。
  • CGLIB 动态代理:适合无接口的场景,性能更高,但依赖第三方库(如 ASM),对 final 类无能为力。
  • Spring 中的选择:Spring AOP 默认使用 JDK 动态代理,若目标类无接口则自动切换到 CGLIB。
    其他
    1.jdk6下,在运行次数较少的情况下,jdk动态代理与
    cglib差距不明显,甚至更快一些;而当调用次数增加
    之后,cglib表现稍微更快一些
    2.jdk7下,情况发生了逆转!在运行次数较少
    (1,000,000)的情况下,jdk动态代理比cglib快了差
    不多30%;而当调用次数增加之后(50,000,000),动
    态代理比cglib快了接近1倍
    3.jdk8表现和jdk7基本一致

3. Java 的反射机制及其应用

什么是反射? Java 反射机制允许程序在运行时动态获取类的元信息(如类名、方法、字段、构造器等)并操作这些信息。核心类位于 java.lang.reflect 包,如 Class、Method、Field、Constructor。

如何应用反射?

  1. 获取 Class 对象

    // 三种方式Class<?> clazz1 = Class.forName("java.util.ArrayList");Class<?> clazz2 = ArrayList.class;Class<?> clazz3 = new ArrayList<>().getClass();
    
  2. 操作构造器

    Constructor<?> constructor = clazz1.getDeclaredConstructor();constructor.setAccessible(true); // 绕过访问限制Object instance = constructor.newInstance(); // 创建实例
    
  3. 操作方法

    Method method = clazz1.getDeclaredMethod("add", Object.class);method.setAccessible(true);method.invoke(instance, "test"); // 调用方法
    
  4. 操作字段

    Field field = clazz1.getDeclaredField("elementData");field.setAccessible(true);Object value = field.get(instance); // 获取字段值
    

应用场景

  • 框架开发:如 Spring(通过反射实例化 Bean)、Hibernate(动态映射实体类字段)。
  • 动态代理:JDK 动态代理依赖反射实现方法调用。
  • 序列化/反序列化:如 JSON 库(FastJSON、Gson)通过反射读写对象字段。
  • 工具类:如单元测试框架(JUnit)通过反射调用测试方法。
  • 插件化开发:动态加载未知的类或方法。

优缺点

  • 优点:灵活性高,支持运行时动态操作,适合框架和通用工具开发。
  • 缺点
    • 性能开销大(反射调用比直接调用慢)。
    • 安全性问题(绕过访问限制可能导致不可预期的行为)。
    • 代码可读性差,维护成本高。

注意事项

  • 尽量缓存 Class、Method 等对象以减少反射开销。
  • 谨慎使用 setAccessible(true),可能引发安全漏洞。
  • 在高性能场景下,优先考虑非反射方案(如字节码操作或直接调用)。

总结**:

  • 接口和抽象类在继承、方法实现和使用场景上各有侧重,接口更灵活,抽象类更适合复用。
  • JDK 动态代理依赖接口,CGLIB 基于继承,Spring 根据目标类情况自动选择
  • 反射机制是 Java 动态性的核心,广泛应用于框架开发,但需注意性能和安全问题

希望大家坚持下去,30 天只更新核心面试题 ~

http://www.lryc.cn/news/610084.html

相关文章:

  • 【多智能体cooragent】CoorAgent 系统中 5 个核心系统组件分析
  • 力扣-1.两数之和
  • 腾讯混元重磅开源:四款小尺寸模型全面发布
  • Git如何为多平台配置密钥和用户信息?
  • 互联网医院整体项目套表整理过程文档全流程分析
  • 【MySQL基础篇】:MySQL常用内置函数以及实用示例
  • Flask + HTML 项目开发思路
  • MySQL中COUNT(\*)、COUNT(1)和COUNT(column),到底用哪个?
  • 从零认识OpenFlow
  • 【SAM】Segment Anything 论文翻译笔记
  • opencv引入libavif
  • 模拟IC设计提高系列8-运算跨导放大器OTA Operational Transconduct Amplifiers
  • 家事速配西安项目启动会圆满举行,开启社区服务新篇章
  • 决策树(回归树)全解析:原理、实践与应用
  • 【动态规划 | 回文字串问题】动态规划解回文问题的核心套路
  • 打卡day28
  • Memcached缓存与Redis缓存的区别、优缺点和适用场景
  • Java 大视界 -- Java 大数据在智能交通智能停车诱导与车位共享优化中的应用(381)
  • 【C#】操作Execl和Word文件-1
  • orchestrator部署
  • 11.Linux 权限管理,控制对文件的访问(ACL)
  • git操作命令和golang编译脚本
  • 【Spring】SpringBoot 自动配置,@ComponentScan、@Import、ImportSelector接口
  • 【QT】安装与配置
  • 计量学基础 - (二)计量单位制
  • NX982NX984美光固态闪存NX992NY102
  • 高速信号设计之 PCIe6.0 篇
  • Linux之Shell脚本快速入门
  • 【2025最新】Spring Boot + Spring AI 玩转智能应用开发
  • 微服务的编程测评系统10-竞赛删除发布-用户管理-登录注册