Java 核心知识与主流框架面试题解析

发布于:2025-07-28 ⋅ 阅读:(18) ⋅ 点赞:(0)

1. 计算机网络传输层有哪些协议?分别适用于什么场景?

传输层主要协议有TCPUDP

  • TCP(传输控制协议):面向连接、可靠传输(通过三次握手建立连接、四次挥手断开,支持重传、流量控制、拥塞控制)。适用于对可靠性要求高的场景,如文件传输(FTP)、网页浏览(HTTP)、邮件发送(SMTP)等。
  • UDP(用户数据报协议):无连接、不可靠传输(不保证数据顺序和完整性),但传输效率高。适用于实时性要求高的场景,如视频通话、语音聊天(VoIP)、直播、DNS 查询等。

2. 多线程的使用场景有哪些?线程开启多少个合适?判断标准有哪些?

使用场景

  • 异步任务处理(如短信发送、日志记录);
  • 并发请求处理(如 Web 服务器处理多用户请求);
  • 耗时操作并行化(如大数据计算、文件批量处理);
  • 后台定时任务(如数据同步、缓存清理)。

线程数量判断标准

  • CPU 密集型任务(如计算):线程数≈CPU 核心数(避免频繁上下文切换);
  • IO 密集型任务(如网络请求、文件 IO):线程数可适当增加(通常为 CPU 核心数 ×2,或根据 IO 等待时间调整);
  • 结合系统资源(内存、句柄数)和业务响应时间要求。

3. 线程池的提交方式有哪几种?

线程池有两种主要提交方式:

  • execute(Runnable command):无返回值,无法捕获任务异常(需在任务内部处理);
  • submit(Callable<T> task) 或 submit(Runnable task, T result):返回Future<T>对象,可通过get()获取结果或异常,支持取消任务(cancel())。

4. 锁的实现原理介绍一下?

Java 中锁的实现主要有两类:

  • synchronized:底层依赖 JVM 的对象监视器(Monitor),通过对象头的 Mark Word 存储锁状态。锁升级过程:无锁 → 偏向锁 → 轻量级锁(自旋) → 重量级锁(操作系统互斥量)。
  • Lock 接口(如 ReentrantLock):基于AQS(AbstractQueuedSynchronizer) 实现,通过 volatile 变量state控制锁状态,支持公平锁 / 非公平锁、可中断、超时获取等特性。

5. TCP 协议中拥塞控制的主要作用是什么?

拥塞控制是 TCP 防止网络过载的关键机制,主要作用:

  • 避免发送方速率超过网络承载能力,防止网络拥塞;
  • 维持网络吞吐量与延迟的平衡;
  • 网络拥塞(如丢包)时,动态调整发送窗口大小,减少数据注入;
  • 常用算法:慢开始、拥塞避免、快重传、快恢复。

6. String 类的常用函数有哪些?列举十种。

  • length():返回字符串长度;
  • charAt(int index):返回指定索引的字符;
  • substring(int beginIndex, int endIndex):截取子字符串;
  • equals(Object obj):比较字符串内容是否相等;
  • equalsIgnoreCase(String anotherString):忽略大小写比较;
  • indexOf(String str):返回子字符串首次出现的索引;
  • lastIndexOf(String str):返回子字符串最后出现的索引;
  • trim():去除首尾空白字符;
  • replace(char oldChar, char newChar):替换字符;
  • split(String regex):按正则分割字符串为数组;
  • startsWith(String prefix):判断是否以指定前缀开头;
  • endsWith(String suffix):判断是否以指定后缀结尾。

7. String 和 StringBuffer、StringBuilder 的区别有哪些?所有类名包含 Buffer 的类的内部实现原理是什么?有什么优势?

区别

  • 可变性String不可变(char 数组被final修饰,修改创建新对象);StringBufferStringBuilder可变(直接修改内部数组)。
  • 线程安全String天然安全(不可变);StringBuffer安全(方法加synchronized);StringBuilder不安全(无同步,性能更高)。
  • 性能StringBuilder > StringBuffer > String(频繁修改时)。

含 Buffer 类(如 StringBuffer、ByteBuffer)的原理
通过预分配的字符 / 字节数组存储数据,容量不足时自动扩容(通常为原容量的 2 倍 + 2),减少内存分配次数。
优势:适合频繁修改场景,避免频繁创建对象导致的内存开销。

8. String 字符串的不可变是指哪里不可变?

String的不可变指内部存储字符的 char 数组被private final修饰

  • 无法通过外部修改数组引用(final修饰);
  • String类未提供修改数组元素的方法;
  • 任何修改(如拼接、替换)都会创建新String对象,原对象内容不变。

9. HTTP 协议有哪些字段,列举 3 个就可以。

  • Host:指定请求的服务器域名和端口号,用于虚拟主机区分不同网站;
  • Content-Type:表示请求 / 响应体的媒体类型,如application/jsontext/html
  • User-Agent:描述发起请求的客户端信息(浏览器 / 设备型号等),服务器可据此返回适配内容;
  • 其他常见:Cookie、Authorization、Content-Length。

10. Java 异常类有哪些?分别管理什么异常?

Java 异常体系以Throwable为根,分为两类:

  • Error:严重错误(如OutOfMemoryErrorStackOverflowError),程序无法处理,通常是 JVM 层面问题。
  • Exception:可处理的异常,分为:
    • Checked Exception(受检异常):编译期检查,必须显式处理(如IOExceptionClassNotFoundException);
    • Unchecked Exception(非受检异常):运行时异常,继承自RuntimeException(如NullPointerExceptionIndexOutOfBoundsException)。

11. Java 反射获取类信息的方式有哪几种?分别是什么?

有 3 种方式:

  • Class.forName(String className):通过类全限定名获取(如Class.forName("java.lang.String"));
  • 类名.class:直接使用类的 class 属性(如String.class);
  • 对象.getClass ():通过实例对象获取(如"abc".getClass())。

12. Java 代理的主要方法有哪几种?列举代理的使用场景 2 个。

主要方法

  • 静态代理:编译期生成代理类,手动实现与目标类相同的接口,在方法中增强逻辑;
  • 动态代理
    • JDK 动态代理:通过Proxy.newProxyInstance()在运行时生成代理类,要求目标类实现接口;
    • CGLIB 动态代理:通过继承目标类生成代理子类,无需接口(基于字节码增强)。

使用场景

  • 日志记录(在方法调用前后打印日志);
  • 事务管理(在方法执行前后开启 / 提交事务)。

13. equals () 方法的作用是什么?重写 equals 需要注意哪些事项?为什么?

作用:判断两个对象的内容是否相等(默认继承自Object,实现为==,即比较地址)。

重写注意事项

  1. 自反性x.equals(x)必为true
  2. 对称性x.equals(y)y.equals(x)结果一致;
  3. 传递性:若x.equals(y)y.equals(z)true,则x.equals(z)必为true
  4. 一致性:多次调用结果一致(对象未修改);
  5. 非空性x.equals(null)必为false
  6. 必须同时重写 hashCode ():确保equals()true的对象,hashCode()值必相等(否则 HashMap 等集合会出现逻辑错误)。

14. Java 是按值传递还是按引用传递?什么是引用传递,什么是值传递,哪些语言支持引用传递?

  • Java 只有值传递:方法参数传递的是 “值的副本”。

    • 基本类型:传递值本身的副本(修改参数不影响原变量);
    • 引用类型:传递引用地址的副本(可修改对象内容,但无法修改原引用指向)。
  • 值传递:传递变量的副本,方法内修改不影响原变量(如 Java、C)。

  • 引用传递:传递变量的引用(别名),方法内修改直接影响原变量(如 C++ 的引用、Python 的列表传递)。

15. 描述 java 的类初始化顺序?如果存在继承,初始化顺序会如何?

无继承时
静态变量 → 静态代码块 → 实例变量 → 实例代码块 → 构造方法。

有继承时(父类 A,子类 B):

  1. 父类静态变量 → 父类静态代码块;
  2. 子类静态变量 → 子类静态代码块;
  3. 父类实例变量 → 父类实例代码块 → 父类构造方法;
  4. 子类实例变量 → 子类实例代码块 → 子类构造方法。

16. 本地方法栈有什么作用?

本地方法栈(Native Method Stack)用于支持 Java 调用本地方法(如用 C/C++ 实现的方法),存储本地方法的局部变量、操作数栈等信息,与虚拟机栈类似,但服务于本地方法。

17. 描述 Java 的双亲委派机制,为什么要用到双亲委派机制?

  • 双亲委派机制:类加载时,子类加载器先委托父类加载器加载,父类无法加载时才自己加载(如AppClassLoader → ExtClassLoader → BootstrapClassLoader)。

  • 作用

    • 防止类重复加载(保证核心类唯一性,如java.lang.String不会被自定义类篡改);
    • 安全性:避免恶意类冒充核心类。

18. 重写和重载的区别是什么?

特性 重写(Override) 重载(Overload)
定义场景 子类与父类之间 同一类中
方法名 必须相同 必须相同
参数列表 必须相同 必须不同(个数 / 类型 / 顺序)
返回值 子类返回值需是父类的子类(协变) 可不同
访问修饰符 子类不能严于父类 无限制

19. 子类构造方法调用父类构造方法的注意事项有哪些?

  • 子类构造方法默认隐式调用父类无参构造(通过super());
  • 若父类无无参构造,子类必须显式调用父类有参构造(super(参数)),且必须放在子类构造方法第一行;
  • 不能同时调用super()this()(两者都需放在第一行,冲突)。

20. 子类实例初始化是否触发发父类实例初始化?

。子类实例化时,会先执行父类的实例初始化(实例变量、实例代码块、构造方法),再执行子类的实例初始化(符合继承的初始化顺序)。

21. instanceof 关键字的作用是什么?

instanceof用于判断一个对象是否是某个类(或接口、父类)的实例,返回 boolean 值。
例如:"abc" instanceof String → truenew Object() instanceof String → false

22. 基本类型的强制类型转换是否会丢失精度?引用类型的强制类型转换需要注意什么?

  • 基本类型强制转换:可能丢失精度(如doubleint会截断小数;longint可能溢出)。
  • 引用类型强制转换
    • 需确保对象实际类型与目标类型兼容(如Object o = "abc"; String s = (String)o合法);
    • 若不兼容,运行时抛出ClassCastException
    • 转换前可通过instanceof判断,避免异常。

23. 重入锁有哪些?为什么要有重入锁?

重入锁:允许同一线程多次获取同一把锁(如synchronizedReentrantLock)。

作用

  • 避免死锁(如一个同步方法调用另一个同步方法时,无需重新竞争锁);
  • 简化递归场景的锁处理(递归方法中无需手动释放锁)。

24. 指令重排序的优点是什么?由什么原因导致的?

  • 优点:编译器和 CPU 通过调整指令执行顺序,提高程序执行效率(如充分利用 CPU 流水线)。
  • 原因
    • 编译器优化(编译期重排);
    • CPU 指令级并行(运行期重排);
    • 内存系统重排(缓存导致的可见性问题)。

25. Arrays.sort () 的内部原理介绍一下?

  • 基本类型数组(如 int []、char []):使用双轴快速排序(Dual-Pivot Quicksort),效率高于传统快排;
  • 对象数组:使用TimSort(归并排序与插入排序的结合),利用数据可能的部分有序性优化性能。

26. 堆排序的时间复杂度是多少,空间复杂度是多少?

  • 时间复杂度:O (nlogn)(建堆 O (n),调整堆 O (nlogn));
  • 空间复杂度:O (1)(原地排序,无需额外空间)。

27. 字符串 “asdasjkfkasgfgshaahsfaf” 经过哈夫曼编码之后存储比特数是多少?

需按以下步骤计算:

  1. 统计字符频率:假设统计后各字符出现次数为(示例):a:5, s:6, d:2, j:1, k:2, f:4, g:2, h:2;
  2. 构建哈夫曼树:每次合并频率最小的两个节点,生成新节点(频率为两者之和),重复至只剩一个节点;
  3. 计算编码长度:从根节点到叶子节点的路径长度为编码长度(左 0 右 1 或反之);
  4. 总比特数:各字符 “频率 × 编码长度” 之和(具体数值需按实际编码计算,约为 50-70 比特)。

28. CPU 高速缓存的优点和缺点有哪些?

  • 优点
    • 速度接近 CPU 主频,大幅减少 CPU 访问内存的等待时间;
    • 缓解 CPU 与内存之间的速度差异(CPU 远快于内存);
    • 提高数据访问的局部性(时间局部性和空间局部性)。
  • 缺点
    • 容量小(通常以 MB 为单位,远小于内存);
    • 存在缓存一致性问题(多核心 CPU 中,不同核心缓存的同一数据可能不一致);
    • 增加硬件复杂度和成本。

29. 线程安全的类有哪些?列举 2 个以上就可以。

  • Vector:线程安全的动态数组(方法加synchronized);
  • Hashtable:线程安全的哈希表(方法加synchronized);
  • ConcurrentHashMap:高效的线程安全哈希表(分段锁 / CAS+ synchronized);
  • AtomicInteger:原子整数类(基于 CAS 实现线程安全)。

30. 什么是 LRU 算法?

LRU(Least Recently Used,最近最少使用)是一种缓存淘汰策略:当缓存满时,优先淘汰最长时间未被使用的缓存项。
应用场景:内存缓存(如 Redis 的 LRU 策略)、页面置换算法。

31. 何为 Spring Bean 容器?Spring Bean 容器与 Spring IOC 容器有什么不同吗?

  • Spring Bean 容器:负责 Bean 的创建、管理、依赖注入的具体实现(如BeanFactory),是 IOC 容器的基础。
  • Spring IOC 容器:更广泛的概念,包含 Bean 容器的功能,还提供依赖反转(IOC)的整体架构支持,管理对象的生命周期和依赖关系(如ApplicationContext是 IOC 容器的典型实现)。

32. Spring IOC 如何理解?

IOC(控制反转)是 Spring 的核心思想:将对象的创建、依赖管理权从代码转移到容器,反转了传统的 “开发者主动创建对象” 的控制流程,降低组件间耦合。
例如:传统方式需手动new对象,IOC 中由容器自动创建并注入依赖,开发者只需声明依赖关系。

33. Spring DI 如何理解?

DI(依赖注入)是 IOC 的具体实现方式:容器在创建对象时,自动将其依赖的对象注入(无需手动set或构造)。
常见注入方式:构造器注入、setter 注入、字段注入(@Autowired)。

34. Spring 中基于注解如何配置对象作用域?以及如何配置延迟加载机制?

  • 作用域配置:使用@Scope注解,常见值:
    • singleton:单例(默认,容器中只有一个实例);
    • prototype:原型(每次获取创建新实例);
    • request:请求域(Web 环境,每个请求一个实例)。
  • 延迟加载:使用@Lazy注解,标记 Bean 在首次被使用时才创建(默认singletonBean 在容器启动时创建)。

35. Spring 工厂底层构建 Bean 对象借助什么机制?当对象不使用了要释放资源,目的是什么?何为内存泄漏?

  • 构建 Bean 的机制:反射(通过Class.newInstance()或构造器反射创建对象)。
  • 释放资源的目的:避免资源浪费(如数据库连接、文件句柄),防止内存泄漏。
  • 内存泄漏:不再使用的对象仍被引用,导致 GC 无法回收,长期积累会耗尽内存。

36. 描述 Spring MVC 处理流程及应用优势?

处理流程

  1. 客户端请求被DispatcherServlet(前端控制器)接收;
  2. DispatcherServlet通过HandlerMapping找到处理请求的Handler
  3. HandlerAdapter调用Handler处理请求,返回ModelAndView
  4. DispatcherServlet通过ViewResolver将逻辑视图解析为物理视图;
  5. 视图渲染模型数据,返回响应给客户端。

优势

  • 分层清晰(表现层、业务层、数据层分离);
  • 灵活的视图解析机制,支持多种视图技术;
  • 强大的拦截器机制,便于统一处理(如登录验证、日志);
  • 与 Spring 生态无缝集成。

37. Spring 中的事务处理方式及优缺点?

  • 编程式事务
    • 方式:通过TransactionTemplatePlatformTransactionManager手动控制事务;
    • 优点:灵活,可精确控制事务边界;
    • 缺点:代码侵入性强,与业务逻辑耦合。
  • 声明式事务
    • 方式:通过@Transactional注解或 XML 配置,AOP 实现事务控制;
    • 优点:无代码侵入,配置简单,与业务逻辑分离;
    • 缺点:灵活性稍差,复杂场景难以精确控制。

38. MyBatis 应用中 #与 $ 有什么异同点?

  • 相同点:均可在 SQL 中嵌入参数。
  • 不同点
特性 #{} ${}
处理方式 预编译参数(? 占位符) 字符串直接替换
SQL 注入风险 无(参数被转义) 有(直接拼接 SQL)
适用场景 普通参数传递 表名、列名动态拼接

39. MyBatis 应用动态 SQL 解决了什么问题?

解决传统 JDBC 中 SQL 语句硬编码、拼接复杂(如条件判断导致的多余AND/OR)的问题。通过<if><where><foreach>等标签,动态生成 SQL,提高代码灵活性和可维护性。

40. Shiro 框架权限管理时的认证和授权流程描述?

  • 认证流程
    1. 收集用户身份(如用户名)和凭证(如密码);
    2. 调用Subject.login(token)提交认证;
    3. Shiro 委托SecurityManager处理,SecurityManager调用Realm
    4. Realm从数据库获取用户信息,比对凭证,成功则认证通过。
  • 授权流程
    1. 认证通过后,Subject.hasRole("admin")isPermitted("user:delete")检查权限;
    2. SecurityManager委托Authorizer处理,Authorizer调用Realm获取用户角色 / 权限;
    3. 比对请求的角色 / 权限,返回结果。

41. BeanFactory 和 ApplicationContext 有什么区别?

特性 BeanFactory ApplicationContext
功能 基础 Bean 管理 继承 BeanFactory,增加更多功能(事件、国际化等)
初始化时机 懒加载(getBean 时创建 Bean) 预加载(启动时创建 singleton Bean)
常见实现 DefaultListableBeanFactory ClassPathXmlApplicationContext

42. 请解释 Spring Bean 的生命周期?

  1. 实例化:容器创建 Bean 对象(调用构造方法);
  2. 属性注入:容器为 Bean 设置依赖属性(setter 方法或字段注入);
  3. 初始化前:执行BeanPostProcessorpostProcessBeforeInitialization
  4. 初始化
    • 调用InitializingBeanafterPropertiesSet()
    • 执行init-method指定的方法;
  5. 初始化后:执行BeanPostProcessorpostProcessAfterInitialization
  6. 使用:Bean 可被应用程序使用;
  7. 销毁
    • 调用DisposableBeandestroy()
    • 执行destroy-method指定的方法。

43. Spring Bean 的作用域之间有什么区别?

  • singleton:全局唯一实例,容器启动时创建(默认);
  • prototype:每次请求创建新实例,容器不管理销毁;
  • request:Web 环境中,每个 HTTP 请求一个实例;
  • session:Web 环境中,每个会话一个实例;
  • application:Web 环境中,整个应用生命周期一个实例。

44. 使用 Spring 框架的好处是什么?

  • 降低耦合(IOC 容器管理对象依赖);
  • 声明式事务简化事务管理;
  • AOP 支持横切关注点(如日志、安全);
  • 丰富的生态(与 MyBatis、Hibernate 等无缝集成);
  • 简化 Java EE 开发,提高开发效率。

45. Spring 中用到了那些设计模式?

  • 工厂模式(BeanFactory创建 Bean);
  • 单例模式(singleton作用域 Bean);
  • 代理模式(AOP、事务管理);
  • 模板方法模式(JdbcTemplate);
  • 观察者模式(事件监听机制)。

46. Spring 如何保证 Controller 并发的安全?

  • Controller 默认是单例,需避免使用成员变量(多线程共享会导致安全问题);
  • 若需状态,使用prototype作用域或 ThreadLocal 存储线程私有数据。

47. 使用 Spring 框架的好处是什么?(同 44 题,重复)

同 44 题答案。

48. 在 Spring 中如何注入一个 java 集合?

通过<list><set><map><props>标签或注解注入:

<bean id="myBean" class="com.example.MyBean">
  <property name="list">
    <list>
      <value>item1</value>
      <ref bean="otherBean"/>
    </list>
  </property>
</bean>

49. Spring 支持的事务管理类型?

  • 编程式事务(通过TransactionTemplate);
  • 声明式事务(通过@Transactional或 XML 配置)。

50. Spring 框架的事务管理有哪些优点?

  • 非侵入式(声明式事务无需修改业务代码);
  • 支持多种事务管理器(JDBC、Hibernate 等);
  • 灵活的事务属性配置(隔离级别、传播行为、超时等)。

51. Spring MVC 的主要组件?

  • DispatcherServlet:前端控制器,统一接收请求;
  • HandlerMapping:映射请求到 Handler;
  • HandlerAdapter:执行 Handler 并返回ModelAndView
  • ViewResolver:解析视图名到具体视图;
  • HandlerInterceptor:拦截器,处理请求前后逻辑。

52. SpringMvc 怎么和 AJAX 相互调用的?

  • AJAX 通过XMLHttpRequestfetch发送请求(通常为 JSON 格式);
  • Spring MVC 控制器方法用@ResponseBody注解返回 JSON(自动转换对象为 JSON);
    示例:

    java

    运行

    @PostMapping("/api/data")
    @ResponseBody
    public Result getData(@RequestBody User user) {
        return Result.success(service.process(user));
    }
    

53. Mybatis 中 #和 $ 的区别?(同 38 题,重复)

同 38 题答案。

54. mybatis 的缓存机制,一级,二级介绍一下?

  • 一级缓存
    • 作用域:SqlSession(会话级别);
    • 默认开启,无需配置;
    • 同一SqlSession内,相同 SQL 查询会缓存结果,关闭会话后失效。
  • 二级缓存
    • 作用域:Mapper(命名空间级别);
    • 需要手动开启(在 Mapper XML 中配置<cache/>);
    • 多个SqlSession共享缓存,查询结果会先放入二级缓存。

55. SpringMVC 与 Struts2 的区别?

  • 核心控制器:Spring MVC 是DispatcherServlet(单例);Struts2 是FilterDispatcher(多例 Action);
  • 线程安全:Spring MVC Controller 单例(无状态安全);Struts2 Action 多例(有状态);
  • 配置方式:Spring MVC 支持注解为主;Struts2 依赖 XML 配置较多;
  • 灵活性:Spring MVC 更轻量,与 Spring 生态整合更好。

56. mybatis 的基本工作流程?

  1. 读取 MyBatis 配置文件(mybatis-config.xml);
  2. 创建SqlSessionFactory(工厂模式);
  3. 通过SqlSessionFactory获取SqlSession
  4. SqlSession获取 Mapper 接口代理对象;
  5. 调用 Mapper 方法执行 SQL;
  6. 提交事务(增删改)或直接获取结果(查询);
  7. 关闭SqlSession

57. 什么是 MyBatis 的接口绑定,有什么好处?

  • 接口绑定:将 Mapper 接口与 XML 映射文件关联,通过接口方法名匹配 XML 中的 SQL ID,无需实现类即可调用。
  • 好处
    • 消除硬编码(无需手动调用SqlSessionselectOne等方法);
    • 类型安全(编译期检查方法参数和返回值)。

58. MyBatis 的编程步骤?

  1. 导入 MyBatis 依赖;
  2. 编写核心配置文件(数据源、映射文件等);
  3. 编写实体类(POJO);
  4. 编写 Mapper 接口和 XML 映射文件(定义 SQL);
  5. 创建SqlSessionFactorySqlSession
  6. 通过SqlSession获取 Mapper 接口,调用方法操作数据库。

59. JDBC 编程有哪些不足之处,MyBatis 是如何解决这些问题的?

  • JDBC 不足
    • 频繁创建 / 关闭连接,资源浪费(MyBatis 用连接池解决);
    • SQL 硬编码在 Java 代码中,维护困难(MyBatis 将 SQL 放在 XML / 注解中);
    • 手动设置参数和映射结果集,代码冗余(MyBatis 自动参数映射和结果映射);
    • 无缓存机制,性能差(MyBatis 提供一、二级缓存)。

60. MyBatis 的优缺点?

  • 优点
    • 简化 JDBC 代码,消除冗余操作(如连接管理、结果集处理);
    • SQL 与代码分离,便于优化和维护;
    • 支持动态 SQL,灵活应对复杂查询;
    • 缓存机制提升查询效率。
  • 缺点
    • 工作量较大(需编写大量 XML 或注解);
    • SQL 优化依赖开发者能力;
    • 对存储过程支持有限。

网站公告

今日签到

点亮在社区的每一天
去签到