1.JAVA异常处理
1.java爬出异常的核心方式
通过
java
try{}catch(){}finally{}
通过 throw 主动抛出异常 或者 throws声明方法可能抛出的异常
2. 各关键字的核心意义
| 关键字 | 核心意义 |
|---|---|
| try | 包裹可能抛出异常的代码块,是异常捕获的入口;JVM 会监控 try 块内的代码执行。 |
| catch | 紧跟 try 块,捕获并处理 try 块中抛出的指定类型异常;一个 try 可搭配多个 catch 处理不同异常。 |
| finally | 可选、紧跟 catch 块(或直接跟 try 块),无论 try 块是否抛出异常、catch 是否执行,finally 块代码一定会执行(除非 JVM 强制退出);常用于释放资源(如关闭流、数据库连接)。 |
| throw | 主动抛出 一个具体的异常对象(如 throw new NullPointerException());用于在程序逻辑不满足时手动触发异常。 |
| throws | 声明在方法签名末尾 ,表明该方法可能抛出的异常类型(不处理,交给调用方处理);可声明多个异常,用逗号分隔。 |
3. try 块中是否可以抛出异常?
可以。
- 两种抛出方式:
- 隐式抛出:try 块内执行的代码(如空指针、数组越界)自动触发 JVM 抛出的运行时异常;
- 显式抛出:在 try 块内通过
throw关键字主动抛出异常(如try { throw new Exception("自定义异常"); })。
- 注意:try 块中抛出的异常,需由后续的 catch 块捕获处理;若未捕获,需通过方法的 throws 声明交给上层调用方处理
2.Servlet、Filter、Listener各自的用途、生命周期
Servlet 是 Java Web 的核心组件,运行在服务端用于处理客户端的HTTP请求,生成动态的HTTP响应,由servlet容器管理(如Tomcat)
核心的生命周期有
init()初始化阶段
service()处理请求阶段
destroy()销毁阶段
Filter过滤器 受servlet容器管理 对请求/响应进行预处理或者后处理
Listener监听器 用于监听web容器事件,如上下文创建、会话创建 / 销毁、属性变化
Servlet 容器
- 核心定义 :是专门用于管理 Servlet 生命周期 (初始化、处理请求、销毁)、处理 HTTP 请求与响应 的软件环境;它是 Web 容器的核心子集,直接对接 Servlet 规范,负责解析 HTTP 请求、调用 Servlet 的
service()方法、返回响应结果。
Web 容器
- 核心定义 :是更广义的概念,包含 Servlet 容器,同时还支持 JSP、Filter、Listener、静态资源(HTML/CSS/JS)等所有 Web 组件的运行环境;它遵循 Java EE 的 Web 规范,提供 Servlet 容器的所有能力 + 额外的 Web 组件管理能力。
上下文创建 Web 容器启动时,为当前 Web 应用创建唯一的 ServletContext 对象,代表整个应用的全局环境,整个应用共享。
会话创建 客户端(浏览器)第一次访问服务器 时,容器为该客户端创建一个 HttpSession 对象,用于保存该用户的会话信息,每个用户独立拥有。
3.sql语句
1.现有一张表,有两个字段:ID,NAME。ID为主键。如果希望查询出所有拥有2个或更多ID的NAME,查询语句应该如何写?
sql
select name from table group by name having count(id) > 1
having 是用在 group by 后用来过滤分组结果的关键字
2.现有用户表USER,两个字段:ID、NAME,ID为主键;日志表LOG,4个字段:ID、TIME、CONTENT、USERID,ID为主键,USERID为用户表的外键,如果希望查询出某个用户最新的一条日志,查询语句应该如何写?
sql
select l.*, u.name
from log l
join user u on l.user_id = u.id
where u.name = 'zhangsan'
order by l.time desc
limit 1
4.请编写代码实现两种单例模式。
单例模式是一种设计模式,核心可以用一句话概括:
确保一个类在整个程序运行过程中,永远只有一个实例对象,并且提供一个全局的、唯一的访问入口。
- 唯一实例:无论调用多少次创建方法,始终返回同一个对象(内存地址相同);
- 私有构造方法 :禁止外部通过
new 类名()创建实例(核心!防止随意创建多个对象); - 全局访问点 :提供一个公共的静态方法(如
getInstance()),让外部获取这个唯一实例。
第一种饿汉式单例
java
class dog{
public static final dog d = new dog();
private dog(){}
public static dog retDog(){
return d;
}
}
第二种方式加了双重锁
java
/**
* 懒汉式单例(双重校验锁)------ 第二种单例实现方式
* 核心:延迟加载 + 线程安全 + 高性能
*/
public class LazySingleton {
// 1. 私有静态变量:用volatile禁止指令重排(关键!防止多线程拿到未初始化的实例)
private static volatile LazySingleton INSTANCE;
// 2. 私有构造方法:禁止外部new创建实例
private LazySingleton() {
// 可选:防止反射破坏单例
if (INSTANCE != null) {
throw new RuntimeException("禁止创建多个单例实例");
}
}
// 3. 公共静态方法:双重校验锁获取唯一实例
public static LazySingleton getInstance() {
// 第一次校验:避免每次获取实例都加锁(提升性能)
if (INSTANCE == null) {
// 加锁:保证多线程下只有一个线程进入创建逻辑
synchronized (LazySingleton.class) {
// 第二次校验:防止多个线程等待锁后重复创建实例
if (INSTANCE == null) {
INSTANCE = new LazySingleton(); // 第一次调用时才创建实例
}
}
}
return INSTANCE;
}
// 测试方法
public void sayHello() {
System.out.println("懒汉式单例(双重校验锁):这是第二种实现方式!");
}
// 多线程测试(验证线程安全)
public static void main(String[] args) {
// 线程1获取实例
new Thread(() -> {
LazySingleton s1 = LazySingleton.getInstance();
System.out.println("线程1实例地址:" + s1);
}).start();
// 线程2获取实例
new Thread(() -> {
LazySingleton s2 = LazySingleton.getInstance();
System.out.println("线程2实例地址:" + s2);
}).start();
}
}
5.谈谈你对SpringBoot和SpringMVC的认识。
SpringMVC 是遵循「MVC 设计模式」的 Web 框架,本质是Servlet 封装 (核心组件 DispatcherServlet 是一个 Servlet),专门处理 Web 层的请求分发、参数解析、视图渲染等问题,是 Spring 生态中处理 HTTP 请求的标准方案。
SpringBoot 不是替代 Spring 的框架,而是Spring 生态的 "简化版",核心设计理念是「约定大于配置」,通过自动配置(AutoConfiguration)、起步依赖(Starter)、内置容器等特性,解决 Spring 开发中 "配置繁琐、依赖冲突、启动复杂" 的问题