1.计算机网络传输层有哪些协议?分别适用于什么场景?
TCP:面向连接、可靠传输(重传机制),适用于对数据完整性要求高的场景,如文件传输 (FTP)、HTTP 通信、邮件发送(SMTP)。
UDP:无连接、不可靠传输,适用于实时性要求高的场景,如视频流、语音通话、DNS 查询
2.多线程的使用场景有哪些?线程开启多少个合适?判断标准有哪些?
使用场景:并发任务处理(如服务器多客户端请求)、耗时操作异步执行(如文件 IO、网络请求)、后台定时任务(如日志清理)。
线程数量:无固定值,需结合任务类型判断。
判断标准:CPU 密集型任务(线程数≈CPU 核心数)、IO 密集型任务(线程数可适当增加,如 CPU 核心数 ×2);避免线程过多导致上下文切换开销过大。
3.线程池的提交方式有哪几种?
execute(Runnable)
:无返回值,提交 Runnable 任务。
submit(Runnable)
:返回 Future 对象,可判断任务是否完成。
submit(Callable<T>)
:返回 Future<T>,可获取任务执行结果。
4.锁的实现原理介绍一下?
锁通过控制多线程对共享资源的访问顺序实现同步。
底层依赖 CPU 指令(如 CAS 原子操作)和操作系统互斥机制(如 pthread_mutex)。
Java 中:synchronized 基于对象头的监视器锁(monitor)实现;ReentrantLock 基于 AQS(抽象队列同步器)的 state 状态控制。
5.TCP 协议中拥塞控制的主要作用是什么?
防止网络因数据量过大导致拥塞崩溃,通过动态调整发送窗口大小,避免数据包丢失和网络过载。
6.String 类的常用函数有哪些?列举十种。
length()
、charAt(int)
、substring(int, int)
、equals(Object)
、equalsIgnoreCase(String)
、indexOf(String)
、lastIndexOf(String)
、trim()
、replace(char, char)
、split(String)
、startsWith(String)
、endsWith(String)
7.String 和 StringBuffer、StringBuilder 的区别有哪些?所有类名包含 Buffer 的类的内部实现原理是什么?有什么优势?
- 区别:
- String:不可变,每次修改创建新对象。
- StringBuffer:可变,线程安全(方法加 synchronized)。
- StringBuilder:可变,线程不安全,效率高于 StringBuffer。
- Buffer 类(如 ByteBuffer)原理:基于内部字节数组存储数据,通过 position、limit、capacity 指针控制数据读写,减少内存复制,提升 IO 操作效率。
- 优势:适合频繁修改数据场景,减少内存开销。
8.String 字符串的不可变是指哪里不可变?
指字符串底层的字符数组(char[]
)不可变,一旦创建,数组长度和内容无法修改;任何修改操作(如 substring
、concat
)都会创建新的 String 对象。
9.HTTP 协议有哪些字段,列举 3 个就可以
请求头字段:Host
(服务器域名)、User-Agent
(客户端信息)、Content-Type
(数据类型);
响应头字段:Status
(状态码)、Content-Length
(数据长度)
10.Java 异常类有哪些?分别管理什么异常?
Throwable
:所有异常的父类,分两类:Error
:严重错误(如 OutOfMemoryError
),程序无法处理。
Exception
:可处理的异常,分:非受检异常(如 NullPointerException
):运行时异常,继承自 RuntimeException
,可不必显式处理。
受检异常(如 IOException
):编译期检查,必须捕获或声明抛出。
11.Java 反射获取类信息的方式有哪几种?分别是什么?
三种方式:
Class.forName("全类名")
:通过类路径加载类。
类名.class
:通过类字面量获取。
对象.getClass()
:通过实例对象获取。
12.Java 代理的主要方法有哪几种?列举代理的使用场景 2 个。
主要方法:静态代理、动态代理(JDK 动态代理、CGLIB 代理)。
使用场景:日志记录(代理方法前后打印日志)、权限控制(代理方法执行前校验权限)。
13.equals () 方法的作用是什么?重写 equals 需要注意哪些事项?为什么?
作用:判断两个对象的内容是否相等(默认与 ==
一致,比较地址)。
注意事项:
自反性:x.equals(x)
必须为 true。
对称性:x.equals(y)
与 y.equals(x)
结果一致。
传递性:若 x.equals(y)
和 y.equals(z)
为 true,则 x.equals(z)
必为 true。
一致性:多次调用结果一致。非空性:x.equals(null)
必为 false。
原因:违反上述规则可能导致集合(如 HashMap)中对象查找异常(如 contains
方法失效)。
14.Java 是按值传递还是按引用传递?什么是引用传递,什么是值传递,哪些语言支持引用传递?
Java 只有按值传递。
值传递:传递参数的副本(基本类型传递值的副本,引用类型传递地址的副本)。
引用传递:传递参数的内存地址,修改形参会影响实参(如 C++ 的引用 &)。
支持引用传递的语言:C++(通过引用符 &)、Python(部分场景)。
15.描述 java 的类初始化顺序?如果存在继承,初始化顺序会如何?
类初始化(静态资源)顺序:静态变量 → 静态代码块。
实例初始化顺序:非静态变量 → 非静态代码块 → 构造方法。
继承场景:先初始化父类静态资源 → 子类静态资源 → 父类实例资源 → 父类构造方法 → 子类实例资源 → 子类构造方法。
16.本地方法栈有什么作用?
用于执行 native 方法(Java 调用非 Java 代码,如 C/C++ 方法),存储本地方法的局部变量、操作数栈等。
17.描述 Java 的双亲委派机制,为什么要用到双亲委派机制?
机制:类加载时,先委托父类加载器加载,父类无法加载时再由子类加载器加载(Bootstrap → Extension → Application)。
作用:防止类重复加载,保证核心类(如 java.lang.String
)的安全性(避免自定义类篡改核心类)。
18.重写和重载的区别是什么?
区别 | 重写(Override) | 重载(Overload) |
---|---|---|
范围 | 父子类之间 | 同一类中 |
方法名 | 相同 | 相同 |
参数列表 | 必须相同 | 必须不同(个数 / 类型 / 顺序) |
返回值 | 子类返回值需与父类兼容(更小范围) | 无限制 |
访问修饰符 | 子类不能比父类更严格 | 无限制 |
19.子类构造方法调用父类构造方法的注意事项有哪些?
子类构造方法默认调用父类无参构造(通过 super()
),若父类无无参构造,子类必须显式调用父类有参构造(super(参数)
),且需放在子类构造方法第一行。
20.子类实例初始化是否触发父类实例初始化?
是。子类实例化时,需先初始化父类实例(执行父类非静态代码块和构造方法)。
21.instanceof 关键字的作用是什么?
判断对象是否为某个类(或接口)的实例,返回 boolean 值(如 obj instanceof String
)
22.基本类型的强制类型转换是否会丢失精度?引用类型的强制类型转换需要注意什么?
基本类型:可能丢失精度(如 double → int
会截断小数)。
引用类型:需确保对象实际类型与目标类型兼容,否则抛 ClassCastException
;建议转换前用 instanceof
判断。
23.重入锁有哪些?为什么要有重入锁?
重入锁:synchronized
、ReentrantLock
。
作用:允许同一线程多次获取同一把锁(如递归调用同步方法时,避免死锁)。
24.指令重排序的优点是什么?由什么原因导致的?
优点:提高 CPU 执行效率(调整指令顺序,充分利用 CPU 资源)。
原因:CPU 流水线优化、编译器优化、内存系统重排序。
25.Arrays.sort () 的内部原理介绍一下?
针对不同数据类型采用不同算法:
基本类型(如 int):双轴快速排序(Dual-Pivot QuickSort)。
对象类型:TimSort(归并排序与插入排序结合,稳定性好)。
26.堆排序的时间复杂度是多少,空间复杂度是多少?
时间复杂度:O (n log n)(最好 / 最坏 / 平均一致)。
空间复杂度:O (1)(原地排序)。
27.字符串 “asdasjkfkasgfgshaahsfaf” 经过哈夫曼编码之后存储比特数是多少?
字符串 “asdasjkfkasgfgshaahsfaf” 经过哈夫曼编码之后存储比特数是多少?-CSDN博客
28.CPU 高速缓存的优点和缺点有哪些?
优点:减少 CPU 访问内存的时间,提高处理速度(缓存速度远快于内存)。
缺点:存在缓存一致性问题(多核心缓存数据不一致);缓存容量小,可能出现缓存未命中(需访问内存,增加延迟)。
29.线程安全的类有哪些?列举 2 个以上就可以。
Vector
、Hashtable
、ConcurrentHashMap
、AtomicInteger
。
30.什么是 LRU 算法?
最近最少使用算法(Least Recently Used),用于缓存淘汰:当缓存满时,移除最久未使用的数据,保留最近常用数据。
31.何为 Spring Bean 容器?Spring Bean 容器与 Spring IOC 容器有什么不同吗?
Spring Bean 容器:管理 Spring Bean 的创建、配置、生命周期的容器,负责 Bean 的实例化和依赖管理。
区别:Spring IOC 容器是更宽泛的概念,Bean 容器是 IOC 容器的核心实现。IOC 容器通过依赖注入(DI)实现控制反转,而 Bean 容器是 IOC 容器中具体管理 Bean 的组件,二者本质上是包含关系(IOC 容器包含 Bean 容器的功能)。
32.Spring IOC 如何理解?
IOC(控制反转)是一种设计思想:将对象的创建、依赖注入的控制权从代码中转移到 Spring 容器,由容器统一管理。开发者无需手动new
对象,而是通过配置(XML / 注解)声明对象依赖,容器自动组装,降低代码耦合度。
33.Spring DI 如何理解?
DI(依赖注入)是 IOC 的具体实现方式:容器在创建 Bean 时,自动将其依赖的其他 Bean 注入到当前 Bean 中(如通过构造方法、setter 方法)。例如,Service 依赖 Dao,容器会自动将 Dao 实例注入到 Service 中。
34.Spring 中基于注解如何配置对象作用域?以及如何配置延迟加载机制?
作用域配置:用@Scope
注解,如@Scope("singleton")
(默认,单例)、@Scope("prototype")
(多例)、@Scope("request")
(请求域)等。
延迟加载:单例 Bean 默认预加载,添加@Lazy
注解可实现延迟加载(首次使用时才实例化)。
35.Spring 工厂底层构建 Bean 对象借助什么机制?当对象不使用了要释放资源,目的是什么?何为内存泄漏?
构建机制:反射机制(通过Class.forName()
加载类,newInstance()
实例化对象)。
释放资源目的:避免资源占用(如数据库连接、文件流),防止内存泄漏。
内存泄漏:不再使用的对象因被引用而未被 GC 回收,导致内存占用持续增加。
36.描述 Spring MVC 处理流程及应用优势?
流程:
客户端请求被DispatcherServlet
(前端控制器)接收;
调用HandlerMapping
找到对应Controller
;
Controller
处理请求,返回ModelAndView
;ViewResolver
解析视图,渲染后响应客户端。
优势:分层清晰(MVC 架构)、灵活易扩展、与 Spring 无缝集成、支持 RESTful 风格。
37.Spring 中的事务处理方式及优缺点
编程式事务:通过TransactionTemplate
手动控制事务(如begin()
、commit()
、rollback()
)。优点:细粒度控制;缺点:代码侵入性强,冗余。
声明式事务:通过@Transactional
注解或 XML 配置声明事务,无需手动编码。优点:无代码侵入,配置简单;缺点:粒度较粗(基于方法 / 类)。
38.MyBatis 应用中 #与 $ 有什么异同点?
相同点:均用于在 SQL 中插入参数
不同点:
#
:参数占位符,会预编译为?
,自动处理 SQL 注入(安全),如WHERE id = #{id}
。
$
:字符串拼接,直接替换参数(不安全,可能 SQL 注入),适用于动态表名 / 排序字段,如ORDER BY ${column}
。
39.MyBatis 应用动态 SQL 解决了什么问题?
解决 SQL 语句中因条件变化导致的拼接繁琐问题。通过<if>
、<where>
、<foreach>
等标签,动态生成 SQL(如多条件查询时自动拼接AND
),避免手动拼接字符串的错误(如多余逗号、WHERE
后无条件)。
40.Shiro 框架权限管理时的认证和授权流程描述?
认证(登录):
1.用户提交账号密码;
2.Shiro 通过Subject.login(token)
验证;
3.调用Realm
的doGetAuthenticationInfo
方法比对用户信息,验证通过则登录成功。
授权(权限校验):
1.认证通过后,Shiro 调用Realm
的doGetAuthorizationInfo
获取用户角色 / 权限;
2.通过Subject.hasRole()
或@RequiresPermissions
注解校验权限,无权限则抛出异常。
41.BeanFactory 和 ApplicationContext 有什么区别?
对比项 | BeanFactory | ApplicationContext |
---|---|---|
加载时机 | 懒加载(getBean 时才实例化) | 预加载(启动时实例化单例 Bean) |
功能 | 基础 Bean 管理 | 继承 BeanFactory,新增国际化、事件机制等 |
常用实现类 | DefaultListableBeanFactory | ClassPathXmlApplicationContext |
42.请解释 Spring Bean 的生命周期?
- 实例化(通过构造方法创建对象);
- 属性注入(通过 setter 方法注入依赖);
- 初始化前(调用
BeanNameAware
、BeanFactoryAware
等接口方法); - 初始化(执行
@PostConstruct
注解方法或<init-method>
配置的方法); - 就绪(Bean 可被使用);
- 销毁前(调用
@PreDestroy
注解方法或<destroy-method>
配置的方法); - 销毁(容器关闭时回收资源)。
43. Spring Bean 的作用域之间有什么区别?
singleton:默认,单例,容器中只有一个实例,所有请求共享。
prototype:多例,每次getBean()
创建新实例。
request:每个 HTTP 请求创建一个实例,仅在当前请求有效。
session:每个会话创建一个实例,会话内共享。
globalSession:用于 Portlet 环境,全局会话共享。
44. 使用 Spring 框架的好处是什么?
降低耦合:IOC 容器管理对象依赖,减少硬编码;
简化开发:AOP 封装横切逻辑(如事务、日志);
事务管理:声明式事务简化配置;
集成性:无缝整合 MyBatis、Hibernate 等框架;
可扩展性:支持自定义 Bean、工厂等。
45.Spring 中用到了哪些设计模式?
工厂模式(BeanFactory 创建 Bean);
单例模式(默认 Bean 为单例);
代理模式(AOP 的动态代理);
模板方法模式(JdbcTemplate);
观察者模式(事件监听机制)。
46.Spring 如何保证 Controller 并发的安全?
Controller 默认单例,若存在成员变量,多线程并发可能不安全。
解决方案:
避免在 Controller 中定义成员变量(推荐);
若需共享数据,使用ThreadLocal
隔离线程;
将 Controller 作用域设为prototype
(多例,消耗略高)。
47.在 Spring 中如何注入一个 java 集合?
通过 XML 配置或注解注入,例如:
<bean id="myBean" class="com.example.MyBean"><property name="list"><list><value>1</value><value>2</value></list></property><property name="map"><map><entry key="name" value="test"/></map></property>
</bean>
48.Spring 支持的事务管理类型?
编程式事务:通过TransactionTemplate
手动控制事务;
声明式事务:通过@Transactional
注解或 XML 配置,无需代码侵入,更常用。
49.Spring 框架的事务管理有哪些优点?
- 简化配置:声明式事务无需手动编写
begin/commit/rollback
; - 一致性:统一管理事务边界,避免遗漏;
- 灵活性:支持不同隔离级别(如 READ_COMMITTED)和传播行为(如 REQUIRED);
- 集成性:兼容 JDBC、Hibernate 等持久层框架。
50. Spring MVC 的主要组件?
DispatcherServlet
:前端控制器,接收所有请求并分发;HandlerMapping
:映射请求到对应的 Controller;Controller
:处理请求的业务逻辑;ModelAndView
:封装处理结果和视图名;ViewResolver
:解析视图名,生成 View 对象;HandlerAdapter
:适配不同 Controller 方法(如注解式、接口式)。
51.SpringMvc 怎么和 AJAX 相互调用的?
Controller 方法返回 JSON 数据(用@ResponseBody
注解);
前端 AJAX 通过$.ajax()
发送请求,指定dataType: "json"
;
52.mybatis 的缓存机制,一级、二级介绍一下?
一级缓存:默认开启,作用于SqlSession
级别,缓存当前会话中查询的结果,会话关闭后失效。
二级缓存:作用于namespace
(Mapper 接口)级别,多个SqlSession
共享,需在 Mapper.xml 中配置<cache/>
开启。查询时先查二级缓存,再查一级缓存,最后查数据库。
53.SpringMVC 与 Struts2 的区别?
对比项 | SpringMVC | Struts2 |
---|---|---|
核心控制器 | DispatcherServlet | FilterDispatcher |
线程安全 | 单例(无成员变量则安全) | 多例(每次请求创建 Action) |
灵活性 | 注解驱动,配置简洁 | 依赖 XML 配置较多 |
集成性 | 与 Spring 无缝集成 |
54. mybatis 的基本工作流程?
- 加载 MyBatis 配置文件(mybatis-config.xml)和 Mapper 映射文件;
- 创建
SqlSessionFactory
(通过SqlSessionFactoryBuilder
); - 由
SqlSessionFactory
创建SqlSession
; - 通过
SqlSession
获取 Mapper 接口代理对象; - 调用 Mapper 方法执行 SQL,底层通过
Executor
和StatementHandler
操作数据库; - 提交事务(
sqlSession.commit()
),关闭SqlSession
。
55.什么是 MyBatis 的接口绑定,有什么好处?
接口绑定:将 Mapper 接口与 Mapper.xml 文件绑定,通过接口方法名匹配 XML 中的id
,无需实现类即可调用 SQL。
好处:简化代码(无需手动实现接口),类型安全(编译期校验方法名),便于维护。
56.MyBatis 的编程步骤?
- 编写实体类(POJO);
- 编写 Mapper 接口(定义方法);
- 编写 Mapper.xml(配置 SQL,与接口方法绑定);
- 配置 mybatis-config.xml(数据源、Mapper 扫描);
- 通过
SqlSession
获取 Mapper 接口,调用方法执行 SQL。
57. JDBC 编程有哪些不足之处,MyBatis 是如何解决这些问题的?
JDBC 不足:频繁创建 / 关闭连接,资源浪费;
SQL 与 Java 代码耦合,维护困难;
手动处理结果集映射,代码繁琐。
MyBatis 解决:
集成连接池(如 Druid)管理连接;
SQL 写在 XML 中,与代码分离;
自动映射结果集到 POJO(通过resultType
/resultMap
)。
58.Mybatis的优缺点
优点:
(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(4)能够与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
缺点:
(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。