目录
String、StringBuffer、StringBuilder 的区别
Spring Bean 容器与 Spring IOC 容器的区别
BeanFactory 和 ApplicationContext 区别
计算机网络
传输层协议及适用场景
- TCP(传输控制协议)
- 特点:面向连接、可靠传输、流量控制、拥塞控制。
- 适用场景:文件传输(FTP)、网页浏览(HTTP)、邮件(SMTP)等需要可靠性的场景。
- UDP(用户数据报协议)
- 特点:无连接、不可靠、低延迟、高效率。
- 适用场景:视频流(RTP)、DNS 查询、在线游戏等实时性要求高的场景。
Java 编程
多线程
- 使用场景
- 高并发请求处理(如 Web 服务器)。
- 异步任务(如日志写入、消息队列消费)。
- 计算密集型任务(如并行计算)。
- 线程数设置
- CPU 密集型:线程数 ≈ CPU 核心数(避免过多线程导致频繁上下文切换)。
- IO 密集型:线程数 ≈ CPU 核心数 × (1 + 平均 IO 等待时间 / CPU 计算时间)。
- 判断标准
- CPU 利用率、响应时间、吞吐量、系统资源占用(内存、线程切换开销)。
线程池提交方式
execute(Runnable task)
:提交无返回值的任务。submit(Callable<T> task)
:提交有返回值的任务,返回Future<T>
。invokeAll()
/invokeAny()
:批量提交任务并等待结果。
锁的实现原理
- 悲观锁(如 synchronized)
直接加锁,认为并发冲突概率高,通过操作系统互斥量(Mutex)或 JVM 的 Monitor 实现。 - 乐观锁(如 CAS)
通过版本号或 CAS(Compare-And-Swap)原子操作实现,适合低冲突场景。 - AQS(AbstractQueuedSynchronizer)
Java 并发包(如 ReentrantLock)的底层实现,通过 CLH 队列管理线程阻塞和唤醒。
TCP 协议拥塞控制
- 作用:防止网络过载,通过动态调整发送速率避免拥塞崩溃。
- 机制
- 慢启动:初始阶段指数增长拥塞窗口(cwnd)。
- 拥塞避免:线性增长 cwnd,避免过快。
- 快速重传 / 恢复:检测丢包后快速调整。
String 类常用函数
length()
charAt(int index)
substring(int begin, int end)
equals(Object obj)
indexOf(String str)
toLowerCase()
/toUpperCase()
trim()
replace(char old, char new)
split(String regex)
concat(String str)
String、StringBuffer、StringBuilder 的区别
- 不可变性
- String 不可变(线程安全但效率低)。
- StringBuffer 可变(线程安全,同步)。
- StringBuilder 可变(非线程安全,高效)。
- Buffer 类原理:内部使用字符数组(如
char[] value
)动态扩容,避免频繁内存分配。
String 字符串的不可变
- 不可变:底层
final char[]
数组引用和内容不可变(任何修改都会生成新对象)。 - 例如:
String s = "a"; s += "b";
会创建新对象。
HTTP 协议字段
- Host:指定服务器域名。
- Content-Type:请求 / 响应的数据类型(如
application/json
)。 - User-Agent:客户端标识(如浏览器类型)。
Java 异常类
- Exception(可检查异常)
- IOException(文件操作错误)。
- SQLException(数据库错误)。
- RuntimeException(非检查异常)
- NullPointerException、ArrayIndexOutOfBoundsException。
- Error(系统错误)
- OutOfMemoryError、StackOverflowError。
Java 反射获取类信息的方式
Class.forName("全限定类名")
- 对象
.getClass()
- 类名
.class
Java 代理
- 方法
- 静态代理(手动编写代理类)。
- 动态代理(JDK Proxy、CGLib)。
- 场景
- AOP(如 Spring 事务管理)。
- RPC 框架(远程方法调用封装)。
equals () 方法
- 作用:比较对象内容是否相等(默认比较地址,需重写)。
- 注意事项
- 重写时需同时重写
hashCode()
(确保哈希一致性)。 - 满足自反性、对称性、传递性、一致性。
- 重写时需同时重写
Java 参数传递方式
- 按值传递
- 基本类型传递值副本,引用类型传递引用的副本(即 “按共享对象传递”)。
- 引用传递语言:C++(&)、C#(ref)。
Java 类初始化顺序(含继承)
- 父类静态代码块 → 子类静态代码块。
- 父类实例代码块 → 父类构造方法。
- 子类实例代码块 → 子类构造方法。
本地方法栈作用
- 存储 JVM 调用本地(Native)方法(如 C/C++ 库)的栈帧信息。
双亲委派机制
- 机制:类加载器优先委派父类加载器加载,避免重复加载和核心类被篡改。
- 作用:保证安全性(如防止自定义
java.lang.String
)。
重写(Override)和重载(Overload)的区别
- 重写:子类覆盖父类方法(相同签名)。
- 重载:同一类中方法名相同、参数不同。
子类构造方法调用父类构造方法注意事项
- 子类构造方法必须显式或隐式调用
super()
(父类无参构造)或super(参数)
,需要放在第一行,和this
不能重复。
子类实例初始化是否触发父类实例初始化
- 是:子类实例化前会先初始化父类(包括代码块和构造方法)
instanceof 关键字作用
- 用于判断一个对象是否属于某个类(或其子类、接口实现类)。
- 语法:
对象 instanceof 类/接口
- 示例:
java
运行
Object obj = "Hello"; if (obj instanceof String) { System.out.println("obj是String类型"); }
- 注意:
- 如果对象为 null,返回 false。
- 用于多态场景下的类型安全检查。
类型转换
- 基本类型转换
- 可能丢失精度(如 double 转 int 会截断小数部分)。
- 示例:
java
运行
double d = 3.14; int i = (int)d; // i=3(精度丢失)
- 引用类型转换
- 需确保对象实际类型与目标类型兼容,否则抛出
ClassCastException
。 - 示例:
java
运行
Object obj = "123"; String s = (String)obj; // 成功 Integer num = (Integer)obj; // 抛出ClassCastException
- 建议先用
instanceof
检查类型。
- 需确保对象实际类型与目标类型兼容,否则抛出
重入锁
- 重入锁(Reentrant Lock)
- 实现类:
ReentrantLock
、synchronized
(隐式重入)。
- 实现类:
- 作用
- 允许线程多次获取同一把锁(避免死锁)。
- 示例:递归调用或嵌套同步代码块中需重复加锁。
- 为什么需要:防止线程因重复获取锁而阻塞自己(如递归调用同步方法)。
指令重排序
- 优点:提高 CPU 流水线效率,优化程序性能(如乱序执行)。
- 原因
- 编译器优化:调整指令顺序以减少空转。
- CPU 乱序执行:并行执行无依赖的指令。
- 内存系统重排序:缓存一致性协议(如 MESI)导致写操作延迟。
- 注意:需通过
volatile
或内存屏障(如synchronized
)避免多线程下的可见性问题。
Arrays.sort () 内部原理
- 基本类型数组(如 int []):使用双轴快速排序(Dual-Pivot Quicksort),时间复杂度 O (n log n)。
- 对象数组(如 Object []):使用归并排序(TimSort),稳定排序,时间复杂度 O (n log n)。
- 特点:对小数组(长度 < 47)使用插入排序优化。
堆排序复杂度
- 时间复杂度
- 建堆:O (n)。
- 排序:O (n log n)(每次调整堆 O (log n),共 n 次)。
- 总复杂度:O (n log n)。
- 空间复杂度:O (1)(原地排序,无需额外空间)。
字符串哈夫曼编码存储比特数
- 步骤
- 统计字符频率(如 a:7, s:5, f:4, ...)。
- 构建哈夫曼树(频率低的字符编码长)。
- 计算总比特数:∑(字符频率 × 编码长度)。
- 示例(简化版):假设编码后平均每个字符占 3 比特,总长度≈24 字符 × 3 比特 = 72 比特。
- 实际值需根据具体哈夫曼树计算。
CPU 高速缓存优缺点
- 优点
- 减少访问内存的延迟(缓存速度远高于内存)。
- 提高数据局部性(时间局部性、空间局部性)。
- 缺点
- 缓存一致性:多核 CPU 需同步缓存(如 MESI 协议)。
- 缓存污染:频繁换入换出降低命中率。
线程安全的类
- StringBuffer:同步方法保证线程安全。
- ConcurrentHashMap:分段锁 + CAS 实现高效并发。
- Vector(已过时):所有方法用
synchronized
修饰。
LRU 算法
- 定义:Least Recently Used(最近最少使用),淘汰最久未访问的数据。
- 实现
- 数据结构:哈希表(快速查找) + 双向链表(维护访问顺序)。
- 示例:
LinkedHashMap
(通过accessOrder=true
实现 LRU)。
- 应用:缓存淘汰策略(如 Redis、页面置换算法)。
Spring 框架
Spring Bean 容器与 Spring IOC 容器的区别
- Spring Bean 容器:管理 Bean(对象)的生命周期(创建、依赖注入、销毁)。
- IOC 容器:是 Bean 容器的核心,负责控制反转(将对象创建权交给容器)。
- 区别
- Bean 容器是 IOC 容器的具体实现(如
ApplicationContext
)。 - IOC 是设计思想,Bean 容器是技术实现。
- Bean 容器是 IOC 容器的具体实现(如
Spring IOC 理解
- 定义:Inversion of Control(控制反转),将对象的创建和依赖管理交给 Spring 容器。
- 核心
- 解耦:对象间通过接口依赖,而非硬编码。
- 配置化:通过 XML 或注解定义 Bean。
Spring DI 理解
- 定义:Dependency Injection(依赖注入),IOC 的实现方式。
- 方式
- 构造器注入(推荐)。
- Setter 注入。
- 字段注入(@Autowired)。
Spring 注解配置对象作用域和延迟加载
- 作用域
java
运行
@Scope("prototype") // 多例 @Scope("singleton") // 单例(默认)
- 延迟加载
java
运行
@Lazy // 首次访问时初始化Bean
Spring 工厂底层构建 Bean 对象机制
- 机制:反射(
Class.newInstance()
) + 动态代理(AOP)。 - 释放资源
- 调用
@PreDestroy
方法或实现DisposableBean
接口。
- 调用
- 内存泄漏:对象无法被 GC 回收(如静态集合持有 Bean 引用)。
Spring MVC 处理流程及优势
- 流程
- 用户请求 →
DispatcherServlet
。 - 调用
HandlerMapping
找到 Controller。 - 执行 Controller → 返回
ModelAndView
。 - 视图渲染(
ViewResolver
)。
- 用户请求 →
- 优势
- 分层清晰(MVC)。
- 支持 RESTful、注解驱动开发。
Spring 事务处理方式及优缺点
- 方式
- 声明式事务(
@Transactional
):代码简洁,但粒度较粗。 - 编程式事务(
TransactionTemplate
):灵活,但需手动管理。
- 声明式事务(
- 缺点:声明式事务可能因异常处理不当导致事务不生效。
MyBatis 中 #与 $ 的区别
#{}
:预编译(防 SQL 注入),自动加引号(适用于参数值)。${}
:字符串替换(直接拼 SQL),适用于动态表名、列名。
MyBatis 动态 SQL 解决的问题
- 问题:根据条件拼接 SQL(避免 Java 代码中写大量 if)。
- 标签:
<if>
、<where>
、<foreach>
。
Shiro 框架认证和授权流程
- 认证(Authentication)
- 用户提交凭证(如用户名 / 密码)。
Realm
校验凭证 → 生成Subject
。
- 授权(Authorization)
Subject
调用checkPermission()
或checkRole()
。Realm
查询权限数据并验证。
BeanFactory 和 ApplicationContext 区别
特性 | BeanFactory | ApplicationContext |
---|---|---|
功能 | 基础 IOC 容器,提供 Bean 的创建和依赖注入 | 继承 BeanFactory,扩展企业级功能(AOP、事件发布、国际化等) |
加载时机 | 懒加载(首次调用getBean() 时初始化) |
预加载(启动时初始化所有单例 Bean) |
AOP 支持 | 需手动注册拦截器 | 内置 AOP 支持 |
适用场景 | 资源受限环境(如移动设备) | 大多数企业级应用 |
Spring Bean 的生命周期
- 实例化:通过反射创建 Bean 对象。
- 属性赋值:依赖注入(
@Autowired
或 XML 配置)。 - 初始化:
- 调用
InitializingBean.afterPropertiesSet()
。 - 执行自定义初始化方法(
@PostConstruct
或init-method
)。
- 调用
- 使用:Bean 准备就绪,被应用程序使用。
- 销毁:
- 调用
DisposableBean.destroy()
。 - 执行自定义销毁方法(
@PreDestroy
或destroy-method
)。
- 调用
Spring Bean 的作用域区别
作用域 | 描述 |
---|---|
singleton | 默认作用域,每个容器中只有一个实例(线程不安全需自行同步)。 |
prototype | 每次请求创建新实例(适合有状态的 Bean)。 |
request | 每个 HTTP 请求创建一个实例(Web 应用)。 |
session | 每个用户会话创建一个实例(Web 应用)。 |
application | 整个 Web 应用共享一个实例(类似 singleton,但跨 ServletContext)。 |
使用 Spring 框架的好处
- 解耦:IOC 降低组件间耦合。
- AOP 支持:统一处理日志、事务等横切关注点。
- 简化开发:集成 JDBC、ORM、Web 框架(如 MyBatis、Hibernate)。
- 模块化:Spring Boot、Spring Cloud 等生态支持。
Spring 中用到的设计模式
- 工厂模式:
BeanFactory
创建对象。 - 单例模式:默认 Bean 作用域。
- 代理模式:AOP 动态代理(JDK/CGLib)。
- 模板方法:
JdbcTemplate
封装固定流程。 - 观察者模式:事件监听(
ApplicationEvent
)。
Spring 如何保证 Controller 并发安全
- 默认情况:Controller 是单例,成员变量共享可能导致线程不安全。
- 解决方案
- 避免使用成员变量(推荐)。
- 使用
@Scope("prototype")
声明多例 Controller(性能较差)。 - 对共享变量加锁(如
synchronized
)。
在 Spring 中注入 Java 集合
- XML 配置
xml
<bean id="collectionBean"> <property name="list"> <list> <value>item1</value> <value>item2</value> </list> </property> <property name="map"> <map> <entry key="key1" value="value1"/> </map> </property> </bean>
- 注解配置
java
运行
@Autowired private List<String> list; @Autowired private Map<String, Object> map;
Spring 支持的事务管理类型
- 编程式事务:通过
TransactionTemplate
或PlatformTransactionManager
手动控制。 - 声明式事务:通过
@Transactional
注解(推荐)。
Spring 事务管理的优点
- 统一 API:支持 JDBC、JPA、Hibernate 等不同持久化技术。
- 声明式简化:通过注解配置事务边界和属性。
- 传播机制:支持 REQUIRED、REQUIRES_NEW 等复杂场景。
Spring MVC 主要组件
DispatcherServlet
:前端控制器,接收所有请求。HandlerMapping
:映射请求到 Controller。- Controller:处理业务逻辑。
ViewResolver
:解析视图名到具体页面。
SpringMVC 与 AJAX 交互
- 后端返回 JSON
java
运行
@RestController public class AjaxController { @GetMapping("/data") public Map<String, String> getData() { return Map.of("key", "value"); } }
- 前端 AJAX 调用
javascript
fetch("/data") .then(response => response.json()) .then(data => console.log(data));
MyBatis 缓存机制
- 一级缓存
- 作用域:
SqlSession
级别(默认开启)。 - 失效条件:执行 update、commit、close 操作。
- 作用域:
- 二级缓存
- 作用域:Mapper 级别(需手动配置
<cache/>
)。 - 跨
SqlSession
共享,适合读多写少场景。
- 作用域:Mapper 级别(需手动配置
SpringMVC 与 Struts2 区别
特性 | SpringMVC | Struts2 |
---|---|---|
设计思想 | 基于方法拦截(Servlet API) | 基于类拦截(Filter 分发) |
性能 | 更高(无拦截器栈) | 较低(多层拦截器) |
配置 | 注解驱动(简洁) | XML 配置(繁琐) |
社区生态 | 活跃(Spring 生态) | 逐渐被淘汰 |
MyBatis 基本工作流程
- 加载配置(
mybatis-config.xml
+ Mapper XML)。 - 创建
SqlSessionFactory
。 - 通过
SqlSession
执行 SQL(调用 Mapper 接口方法)。 - 返回结果(自动映射或手动处理)。
MyBatis 接口绑定的好处
- 定义:Mapper 接口与 XML/SQL 直接绑定。
- 好处
- 类型安全(编译时检查)。
- 无需手动写 DAO 实现类。
MyBatis 编程步骤
- 定义 Mapper 接口。
- 编写 XML/SQL 映射文件。
- 通过
SqlSession.getMapper()
获取代理对象。 - 调用接口方法执行 SQL。
JDBC 不足与 MyBatis 解决方案
JDBC 问题 | MyBatis 解决方案 |
---|---|
硬编码 SQL(维护难) | SQL 与 Java 代码分离(XML / 注解) |
手动处理结果集 | 自动映射对象(ORM) |
频繁创建 / 释放连接 | 连接池集成(如 HikariCP) |
MyBatis 优缺点
- 优点
- 灵活(SQL 可控)。
- 轻量级(无侵入性)。
- 缺点
- 需手动编写 SQL(对复杂查询不友好)。
- 缓存机制较弱(对比 Hibernate)。