- 计算机网络传输层有哪些协议?分别适用于什么场景?
TCP协议(传输控制协议):面向连接、可靠传输,流量控制、拥塞控制。适用于要求数据完整性的场景,如文件传输、网页浏览、电子邮件等。
UDP协议**(用户数据报协议)**:无连接,不可靠但高效,无流量控制、无拥塞控制、开销小、延迟低。适用于实时性要求高的场景,如视频会议、在线游戏、DNS查询等。 - 多线程的使用场景有哪些?线程开启多少个合适?判断标准有哪些?
高并发服务器、IO密集型任务、批量数据处理、异步任务处理、GUI程序保持响应
线程数量设置:
- CPU密集型任务:线程数 ≈ CPU核心数 + 1
- IO密集型任务:线程数 ≈ CPU核心数 * (1 + IO等待时间/CPU计算时间)
- 通用建议:Runtime.getRuntime().availableProcessors()获取CPU核心数作为参考
判断标准:
- CPU使用率:保持在70%-90%之间较理想
- 任务队列长度:队列不应持续增长
- 响应时间:应在可接受范围内
- 吞吐量:达到最优值后不再随线程数增加而提升
- 系统资源:内存、文件描述符等是否充足
- 线程池的提交方式有哪几种?
- execute(Runnable command):执行无返回值的任务
- submit(Callable task):提交有返回值的任务,返回Future对象
- submit(Runnable task):提交Runnable任务,返回Future
- submit(Runnable task, T result):提交Runnable任务并指定返回结果
- 锁的实现原理介绍一下?
锁的基本实现原理: - Java对象头中的Mark Word
- 每个Java对象都有一个对象头,其中包含Mark Word
- Mark Word存储了对象的哈希码、GC分代年龄、锁状态等信息
- 锁信息就存储在Mark Word中
- 锁的升级过程(偏向锁->轻量级锁->重量级锁)
- 无锁状态:对象刚创建时的状态
- 偏向锁:只有一个线程访问时,在Mark Word中记录线程ID
- 轻量级锁:多个线程交替访问,通过CAS操作竞争锁
- 重量级锁:多线程竞争激烈时,升级为操作系统层面的互斥锁
- 同步实现
- monitorenter 和monitorexit字节码指令
- 每个对象都有一个监视器锁(monitor)
- 进入同步块时执行monitorenter,退出时执行monitorexit
- AQS (AbstractQueuedSynchronizer)
- Java并发包中锁的基础框架
- 使用一个volatile int state表示锁状态
- 通过CAS操作实现锁的获取和释放
- 维护一个FIFO队列管理等待线程
- CAS (Compare And Swap)
- 原子操作,比较并交换
- 现代CPU提供的指令级原子操作
- 是乐观锁的实现基础
- TCP协议中拥塞控制的主要作用是什么?
TCP拥塞控制的主要作用是: - 防止网络过载:通过动态调整发送速率,避免过多数据同时涌入网络导致路由器缓冲区溢出和丢包
- 公平性:确保多个TCP连接能公平共享网络带宽资源
- 提高网络利用率:在不过载的前提下尽可能充分利用可用带宽
拥塞控制算法核心机制: - 慢启动(Slow Start)
- 连接开始时,拥塞窗口(cwnd)从1个MSS开始
- 每收到一个ACK,cwnd增加1个MSS(指数增长)
- 直到达到慢启动阈值(ssthresh)或发生拥塞
- 拥塞避免(Congestion Avoidance)
- 当cwnd >= ssthresh时,进入线性增长阶段
- 每RTT时间cwnd增加1个MSS
- 快速重传(Fast Retransmit)
- 收到3个重复ACK时,立即重传丢失的报文段
- 而不必等待超时
- 快速恢复(Fast Recovery)
- 发生快速重传后,调整ssthresh和cwnd
- 避免像超时那样完全从慢启动开始
- String类的常用函数有哪些?列举十种。
length()、charAt(int index)、substring(int beginIndex)、equals(Object o) contains(String str)、indexOf(String str) toLowerCase()、toUpperCase()、trim() split(String regex)、replace(char oldChar,char newChar)、isEmpty() - String和StringBuffer,StringBuilder的区别有哪些?所有类名包含Buffer的类的内部实现原理是什么?有什么优势?
|------|----------|-----------------------|-----------------------|
| 特性 | String | StringBuffer | StringBuilder |
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | 不可变故线程安全 | 线程安全(synchronized方法) | 非线程安全 |
| 性能 | 高(因不可变) | 较低(同步开销) | 最高 |
| 使用场景 | 常量字符串 | 多线程环境字符串操作 | 单线程环境字符串操作 |
| 继承关系 | Object | AbstractStringBuilder | AbstractStringBuilder |
内部实现原理:使用字符数组实现,动态扩容机制(通常2倍)。
优势:减少内存分配和拷贝次数,提高性能
8. String字符串的不可变是指哪里不可变?
指String对象创建后其字符数组内容不可变,任何修改操作都会创建新String对象
9. HTTP协议有哪些字段,列举3个就可以。
- 通用字段(General Header Fields)
- Cache-Control:控制缓存行为
- Connection:控制连接状态(如keep-alive)
- Date:消息产生的日期时间
- 请求字段(Request Header Fields)
- Host:请求的目标主机和端口号
- User-Agent:客户端信息
- Accept:可接受的响应内容类型
- Authorization:认证信息
- 响应字段(Response Header Fields)
- Server:服务器信息
- Set-Cookie:设置Cookie
- Content-Type:响应体的MIME类型
- Content-Length:响应体长度
- 实体字段(Entity Header Fields)
- Content-Encoding:内容编码方式
- Expires:内容过期时间
- Last-Modified:最后修改时间
- Java异常类有哪些?分别管理什么异常?
Error:系统级错误,通常由JVM抛出,不建议捕获
Exception:可处理的异常 - Java反射获取类信息的方式有哪几种?分别是什么?
class.forName("全限定类名")
类名.class()
对象.getClass() - Java代理的主要方法有哪几种?列举代理的使用场景2个。
静态代理 动态代理 CGLIB代理
AOP实现(如Spring事务管理)
RPC框架调用远程服务 - equals()方法的作用是什么?重写equals需要注意哪些事项?为什么?
判断对象逻辑相等性
必须重写hashCode() 满足自反性、对称性、传递性、一致性 - Java是按值传递还是按引用传递?什么是引用传递,什么是值传递,哪些语言支持引用传递?
按值传递 :基本类型传递值副本
按引用值传递:对象传递引用副本
C++、PHP等 - 描述java的类初始化顺序?如果存在继承,初始化顺序会如何
- 父类静态变量和静态块
- 子类静态变量和静态块
- 父类实例变量和实例块
- 父类构造方法
- 子类实例变量和实例块
- 子类构造方法
- 本地方法栈有什么作用?
为JVM调用本地(Native)方法服务,存储本地方法调用的状态 - 描述Java的双亲委派机制,为什么要用到双亲委派机制
描述:类加载请求先委派给父加载器,只有父加载器无法完成时才自己加载
目的:避免重复加载 保证核心类安全 - 重写和重载的区别是什么?
重写:子类重新实现父类方法,方法签名相同
重载:同一类中同名不同参的方法 - 子类构造方法调用父类构造方法的注意事项有哪些?
必须通过super()调用父类构造方法
super()必须是构造方法的第一条语句 - 子类实例初始化是否触发发父类实例初始化?
会,创建子类实例会先初始化父类 - instanceof关键字的作用是什么?
判断对象是否是某个类或其子类的实例
返回boolean值:true表示是,false表示不是 - 基本类型的强制类型转换是否会丢失精度?引用类型的强制类型转换需要注意什么?
基本类型:大转小可能丢失精度
引用类型:需注意ClassCastException,应在转换前用instanceof检查 - 重入锁有哪些?为什么要有重入锁?
synchronized、ReentrantLock
目的:允许线程多次获取已持有的锁,避免死锁 - 指令重排序的优点是什么?由什么原因导致的?
优点:提高程序执行效率
原因:编译器优化、CPU乱序执行 - Arrays.sort()的内部原理介绍一下?
基本类型:快速排序
对象类型:TimSort(归并+插入排序优化) - 堆排序的时间复杂度是多少,空间复杂度是多少?
时间复杂度:O(nlogn)
空间复杂度:O(1) - 字符串"asdasjkfkasgfgshaahsfaf"经过哈夫曼编码之后存储比特数是多少?
- CPU高速缓存的优点和缺点有哪些?
优点:减少CPU访问内存的延迟 提高程序执行速度
缺点:缓存一致性问题 增加了硬件复杂度 - 线程安全的类有哪些?列举2个以上就可以
Vector Hashtable StringBuffer - 什么是LRU算法?
最近最少使用(Least Recently Used)缓存淘汰算法,淘汰最久未使用的数据 - 何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗?
Spring Bean容器: - 定义:
- 负责管理应用中Bean的生命周期
- 提供Bean的创建、配置、组装和管理服务
- 核心功能:
- 依赖注入
- 生命周期管理
- 作用域管理
- AOP代理创建
Spring IOC容器:
- 定义:
- 控制反转(Inversion of Control)容器
- 实现依赖注入(DI)模式的核心组件
- 主要实现:
- BeanFactory:基础IOC容器
- ApplicationContext:扩展了更多企业级功能
Bean容器与IOC容器的关系:
- 相同点:
- 都负责管理Bean对象
- 都实现依赖注入功能
- 不同点:
|------|---------------|---------------------------------|
| 特性 | Spring Bean容器 | Spring IOC容器 |
| 功能范围 | 专注于Bean生命周期管理 | 更广泛,包括资源访问、事件等 |
| 实现级别 | 概念层面 | 具体接口和实现类 |
| 使用场景 | 泛指Bean管理功能 | 特指依赖注入实现机制 |
| 典型代表 | - | BeanFactory, ApplicationContext |
总结:
- 两者在大多数情况下可以互换使用
- 严格来说,IOC容器是实现Bean容器功能的机制
- ApplicationContext是功能最完整的IOC容器实现
- Spring IOC 如何理解?
定义:
- IOC(Inversion of Control):控制反转
- 将对象的创建、依赖管理交给容器而非程序员
- 实现原理:
- 通过反射机制动态创建和管理对象
- 维护Bean之间的依赖关系
- 在适当时候注入依赖
- 核心价值:
- 解耦:减少组件间的直接依赖
- 可维护性:集中管理对象生命周期
- 可测试性:便于模拟依赖进行测试
- 灵活性:配置变更不影响代码
- 工作流程 :
- 读取配置(注解/XML)
- 创建Bean定义
- 实例化Bean
- 注入依赖
- 初始化Bean
- 提供服务
- 销毁Bean
- 主要接口:
- BeanFactory:基础IOC容器
- ApplicationContext:扩展接口,添加更多企业功能
- BeanDefinition:描述Bean的元数据
- Spring DI 如何理解?
定义:
- 依赖注入,IOC的具体实现技术
- 容器将依赖关系自动注入到组件中
- 实现方式:
- 构造器注入:通过构造方法注入
- Setter注入:通过setter方法注入
- 字段注入:直接注入字段(反射实现)
- 注入类型:
- 按类型注入:@Autowired(默认按类型)
- 按名称注入:@Qualifier指定名称
- 强制依赖:使用required=true
- 可选依赖:使用required=false
- 优势:
- 减少样板代码
- 提高可测试性
- 降低耦合度
- 配置灵活
- 相关注解:
- @Autowired:自动装配
- @Resource:JSR-250标准注解
- @Inject:JSR-330标准注解
- @Value:注入简单值
- Spring 中基于注解如何配置对象作用域?以及如何配置延迟加载机制?
- 作用域类型:
- 单例(Singleton):默认,每个容器一个实例
- 原型(Prototype):每次请求创建新实例
- 请求(Request):每个HTTP请求一个实例
- 会话(Session):每个HTTP会话一个实例
- 全局会话(Global Session):Portlet应用专用
- 配置方式:
@Scope("prototype") // 指定作用域 @Component public class MyPrototypeBean {} // 或使用常量 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Component public class AnotherPrototypeBean {}
基于注解配置延迟加载: - 延迟加载(Lazy Initialization):
- 只有第一次使用时才创建实例
- 减少应用启动时间
- 适用于不立即需要的Bean
- 配置方式:
@Lazy // 类级别延迟加载 @Component public class MyLazyBean {} @Configuration public class AppConfig { @Bean @Lazy // 方法级别延迟加载 public MyBean myBean() { return new MyBean(); } } - 组合使用示例:
@Scope("prototype") @Lazy @Component public class MyLazyPrototypeBean {} - 注意事项:
- 延迟加载的Bean在第一次访问时会有轻微性能开销
- 原型作用域的Bean通常需要配合延迟加载
- 某些Bean(如基础设施Bean)不适合延迟加载
- Spring 工厂底层构建Bean对象借助什么机制?当对象不使用了要释放资源,目的是什么?何为内存泄漏?
Spring构建Bean的机制: - 反射机制:
- Class.forName()加载类
- Constructor.newInstance()创建实例
- Field.set()注入属性
- 动态代理:
- JDK动态代理(基于接口)
- CGLIB代理(基于子类)
- 工厂模式:
- BeanFactory接口定义获取Bean的方法
- 各种实现类提供具体创建逻辑
- 生命周期管理:
- InstantiationAwareBeanPostProcessor
- BeanPostProcessor
- InitializingBean/DisposableBean接口
释放资源的目的:
- 防止资源泄漏:
- 关闭数据库连接
- 释放文件句柄
- 清理网络连接
- 避免内存泄漏:
- 移除缓存引用
- 清理监听器
- 断开对象引用链
- 优雅关闭:
- 保存状态
- 完成未完成的操作
- 记录日志
内存泄漏定义:
- 概念:
- 对象不再被使用但无法被GC回收
- 导致内存占用持续增长
- Spring中常见原因:
- 未正确实现DisposableBean
- 静态集合持有Bean引用
- 监听器未正确注销
- 线程池未关闭
- 检测方法:
- 内存分析工具(VisualVM, MAT)
- 监控内存使用情况
- 分析GC日志
- 描述Spring MVC处理流程及应用优势?
- 用户请求-DispatcherServlet
- HandlerMapping找到处理器
- 调用处理器返回ModelAndView
- 视图解析器解析视图
- 渲染视图返回响应
Spring MVC优势: - 清晰的职责分离:
- 各组件分工明确
- 易于维护和扩展
- 灵活配置:
- 支持注解驱动
- 多种视图技术集成
- 强大的数据绑定:
- 自动请求参数绑定
- 支持表单验证
- 国际化支持:
- 本地化解析
- 主题支持
- 测试友好:
- 易于单元测试
- 支持Mock测试
- 集成能力:
- 与其他Spring项目无缝集成
- 支持RESTful开发
- 扩展性强:
- 可自定义各组件实现
- 拦截器机制灵活
- Spring中的事务处理方式及优缺点?
Spring事务处理方式: - 编程式事务:
- 使用TransactionTemplate
- 通过代码显式控制事务边界
优点: - 精确控制事务范围
- 灵活处理复杂逻辑
缺点: - 代码侵入性强
- 容易遗漏提交/回滚
示例:
transactionTemplate.execute(status -> { // 业务代码 return result; });
- 声明式事务:
- 使用@Transactional注解
- 基于AOP实现
优点: - 非侵入式
- 配置简单
- 减少样板代码
缺点: - 粒度较粗(方法级别)
- 异常处理需注意
示例:
@Transactional public void businessMethod() { // 业务代码 }
事务传播行为:
|---------------|--------------------|
| 传播行为类型 | 说明 |
| REQUIRED(默认) | 当前有事务则加入,没有则新建 |
| REQUIRES_NEW | 新建事务,挂起当前事务 |
| SUPPORTS | 当前有事务则加入,没有则以非事务执行 |
| NOT_SUPPORTED | 以非事务执行,挂起当前事务 |
| MANDATORY | 必须在事务中运行,否则抛出异常 |
| NEVER | 必须在非事务中运行,否则抛出异常 |
| NESTED | 嵌套事务执行 |
隔离级别:
|------------------|-----------------|
| 隔离级别 | 说明 |
| DEFAULT | 使用数据库默认级别 |
| READ_UNCOMMITTED | 读未提交,可能脏读 |
| READ_COMMITTED | 读已提交,避免脏读 |
| REPEATABLE_READ | 可重复读,避免脏读和不可重复读 |
| SERIALIZABLE | 串行化,最高隔离级别 |
- MyBatis应用中#与有什么异同点? **#{}与{}的区别**:
|------|---------------|----------------|
| 特性 | #{} | ${} |
| 处理方式 | 预编译处理(占位符?) | 字符串替换(直接拼接SQL) |
| 安全性 | 防止SQL注入 | 有SQL注入风险 |
| 参数类型 | 自动识别并转换 | 原样输出 |
| 适用场景 | 参数值 | 表名、列名等非参数部分 |
| 日期处理 | 自动格式化为数据库兼容格式 | 需要手动处理 |
| 空值处理 | 自动处理null | 可能引发语法错误 |
使用示例:
<!-- 安全的方式 --> <select id="findUser" resultType="User"> SELECT * FROM user WHERE name = #{name} </select> <!-- 不安全但必要的情况 --> <select id="selectByTable" resultType="map"> SELECT * FROM ${tableName} WHERE id = #{id} </select>
最佳实践:
- 优先使用#{},防止SQL注入
- ${}仅用于动态表名、列名等非参数部分
- 使用${}时要确保参数值可信或经过校验
- 复杂SQL可混合使用两者
- MyBatis应用动态SQL解决了什么问题?
动态SQL解决的问题: - 条件不确定的查询:
- 根据不同条件拼接不同SQL
- 避免写多个相似的SQL语句
- 灵活的表操作:
- 动态选择表名、列名
- 适应表结构变化
- 批量操作:
- 动态生成批量插入/更新语句
- 简化批量数据处理
- 避免SQL拼接风险:
- 提供安全的动态SQL构建方式
- 减少手动拼接错误
主要动态SQL元素:
- if:条件判断
<if test="name != null"> AND name = #{name} </if> - choose/when/otherwise:多选一
<choose> <when test="id != null">AND id = #{id}</when> <when test="name != null">AND name = #{name}</when> <otherwise>AND status = 1</otherwise> </choose> - trim/where/set:处理SQL片段
<where> <if test="state != null">state = #{state}</if> </where> - foreach:循环处理
<foreach item="item" collection="list" open="(" separator="," close=")"> #{item} </foreach> - bind:创建变量
<bind name="pattern" value="'%' + name + '%'" />
应用示例:
<select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM blog <where> <if test="state != null"> AND state = #{state} </if> <if test="title != null"> AND title like #{title} </if> </where> </select> - hiro框架权限管理时的认证和授权流程描述?
Shiro认证(Authentication)流程: - 主体提交认证信息:
Subject currentUser = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("username", "password"); currentUser.login(token); - 委托Authenticator认证:
- 调用Realm的doGetAuthenticationInfo方法
- 获取认证信息(AuthenticationInfo)
- 凭证匹配:
- 使用CredentialsMatcher比较提交的和存储的凭证
- 匹配成功完成认证
- 创建已认证主体:
- 绑定主体到当前线程
- 设置认证标志
Shiro授权(Authorization)流程:
- 权限检查触发:
subject.checkPermission("user:delete"); // 或 @RequiresRoles("admin") public void deleteUser() {} - 委托Authorizer授权:
- 调用Realm的doGetAuthorizationInfo方法
- 获取授权信息(AuthorizationInfo)
- 权限验证:
- 检查角色/权限是否匹配
- 不匹配抛出UnauthorizedException
- 访问控制:
- 验证通过允许访问
- 否则拒绝访问
关键组件:
- Subject:当前操作用户
- SecurityManager:安全管理者
- Authenticator:认证器
- Authorizer:授权器
- Realm:安全数据源
- SessionManager:会话管理
配置示例:
@Bean public ShiroFilterFactoryBean shiroFilter() { ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean(); factory.setSecurityManager(securityManager()); Map<String, String> filterMap = new LinkedHashMap<>(); filterMap.put("/login", "anon"); filterMap.put("/admin/**", "authc, roles[admin]"); filterMap.put("/**", "authc"); factory.setFilterChainDefinitionMap(filterMap); return factory; } @Bean public Realm realm() { IniRealm realm = new IniRealm("classpath:shiro.ini"); return realm; } - BeanFactory和ApplicationContext有什么区别?
|-------|----------------------------|--------------------------------------------------------------------|
| 特性 | BeanFactory | ApplicationContext |
| 功能定位 | 基础IOC容器 | 企业级扩展容器 |
| 加载时机 | 延迟加载(按需初始化) | 启动时预加载所有单例Bean |
| 国际化支持 | 不支持 | 支持(MessageSource) |
| 事件发布 | 不支持 | 支持(ApplicationEventPublisher) |
| AOP支持 | 需要额外配置 | 内置支持 |
| 资源访问 | 基本支持 | 更丰富的资源访问方式(ResourceLoader) |
| 自动注册 | 不支持BeanPostProcessor自动注册 | 支持 |
| 典型实现 | DefaultListableBeanFactory | ClassPathXmlApplicationContext, AnnotationConfigApplicationContext |
| 性能 | 启动快,运行时慢 | 启动慢,运行时快 |
| 使用场景 | 资源受限环境 | 大多数企业应用 |
- 请解释Spring Bean的生命周期?
实例化-属性填充-初始化-使用-销毁 - Spring Bean的作用域之间有什么区别?
|---------------|----------------------|-------------|--------|
| 作用域 | 说明 | 适用场景 | 线程安全要求 |
| singleton(默认) | 每个容器一个实例 | 无状态服务,配置类 | 必须线程安全 |
| prototype | 每次请求创建新实例 | 有状态Bean | 通常不需要 |
| request | 每个HTTP请求一个实例 | Web请求相关数据 | 不需要 |
| session | 每个HTTP会话一个实例 | 用户会话数据 | 不需要 |
| application | 每个ServletContext一个实例 | Web应用全局数据 | 必须线程安全 |
| websocket | 每个WebSocket会话一个实例 | WebSocket通信 | 不需要 |
- 使用Spring框架的好处是什么?
Spring框架核心优势: - 轻量级:
- 非侵入式设计
- 最小化应用代码对框架的依赖
- IOC/DI:
- 松耦合
- 易于测试和维护
- AOP支持:
- 分离横切关注点
- 声明式服务(事务、安全等)
- 集成能力:
- 与各种技术栈无缝集成
- 一站式解决方案
- 模块化设计:
- 按需选择模块
- 灵活组合
- 简化开发:
- 减少样板代码
- 提高开发效率
- 强大的生态:
- Spring Boot
- Spring Cloud
- Spring Data等
- Spring 中用到了那些设计模式?
- Spring中常见的设计模式:
- 工厂模式:
- BeanFactory
- ApplicationContext
- 单例模式:
- 默认Bean作用域
- 应用上下文
- 代理模式:
- AOP实现
- @Transactional
- 模板方法:
- JdbcTemplate
- RestTemplate
- 观察者模式:
- 事件发布/监听机制
- 适配器模式:
- HandlerAdapter
- AdvisorAdapter
- 装饰者模式:
- Wrapper类
- 动态代理
- 策略模式:
- 资源访问策略
- 事务管理策略
- Spring 如何保证 Controller 并发的安全?
Spring MVC Controller线程安全保证: - 默认行为:
- Controller默认是单例
- 必须设计为无状态(避免实例变量)
- 安全实践:
- 使用局部变量而非实例变量
- 使用ThreadLocal保存请求相关状态
- 将共享状态声明为原型作用域
- 并发工具:
- 使用并发集合
- 同步关键代码块
- 作用域选择:
- 对有状态需求使用request/session作用域
- 注解支持:
- @Scope("prototype")使Controller成为原型
- 在 Spring中如何注入一个java集合?
Spring集合注入方式: - XML配置:
XML
<bean id="collectionBean" class="com.example.CollectionBean">
<property name="list">
<list>
<value>Java</value>
<ref bean="otherBean"/>
</list>
</property>
<property name="set">
<set>
<value>Spring</value>
</set>
</property>
<property name="map">
<map>
<entry key="key1" value="value1"/>
<entry key="key2" ref="otherBean"/>
</map>
</property>
</bean>
- 注解配置:
java
@Component
public class CollectionBean {
@Autowired
private List<MyInterface> implementations;
@Resource(name = "myMap")
private Map<String, Object> map;
}
@Configuration
public class AppConfig {
@Bean public List<String> stringList() {
return Arrays.asList("A", "B");
}
@Bean public Map<String, Integer> myMap() {
Map<String, Integer> map = new HashMap<>();
map.put("key1", 100); return map;
}
}
- Java Util类注入:
java
@Autowired private ResourceLoader resourceLoader;
- Spring支持的事务管理类型?
Spring事务管理类型: - 编程式事务:
- 使用TransactionTemplate
- 使用PlatformTransactionManager直接管理
- 声明式事务:
- XML配置:
- 注解驱动:@Transactional
声明式事务实现方式: - 基于AOP代理
- 基于字节码生成(ASPECTJ)
事务传播行为: - REQUIRED, REQUIRES_NEW, NESTED等
隔离级别: - DEFAULT, READ_UNCOMMITTED等
- Spring框架的事务管理有哪些优点?
Spring事务管理优势: - 一致性API:
- 统一不同持久化技术的事务API
- 切换持久化技术不影响业务代码
- 声明式支持:
- 通过配置管理事务
- 减少样板代码
- 编程式选择:
- 灵活控制事务边界
- 集成测试:
- 易于模拟和测试
- 多种实现:
- JDBC, JPA, Hibernate等支持
- AOP支持:
- 非侵入式事务管理
- Spring MVC的主要组件?
Spring MVC核心组件: - DispatcherServlet:前端控制器
- HandlerMapping:请求到处理器的映射
- Controller:处理业务逻辑
- ModelAndView:封装模型和视图
- ViewResolver:视图名称解析
- HandlerInterceptor:拦截器
- HandlerAdapter:适配不同处理器
- MultipartResolver:文件上传
- LocaleResolver:国际化
- ThemeResolver:主题解析
- SpringMvc怎么和AJAX相互调用的?
Spring MVC与AJAX交互方式: - 返回JSON:
java
@RestController
public class AjaxController {
@GetMapping("/user")
public User getUser() {
return new User("John", 30);
}
}
- @ResponseBody:
java
@Controller
public class AjaxController {
@RequestMapping("/data")
@ResponseBody
public String getData() {
return "AJAX response";
}
}
- Jackson支持:
XML
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
- 前端调用:
$.get("/user", function(data) { console.log(data.name); }); - Mybatis 中#和的区别? #{}:预编译,防止sql注入 {}:字符串替换,有注入风险
- mybatis的缓存机制,一级,二级介绍一下?
一级缓存:SqlSession级别
二级缓存:Mapper级别 - pringMVC与Struts2的区别?
|--------|--------------------|---------|
| 特性 | Spring MVC | Struts2 |
| 设计理念 | 基于方法 | 基于类 |
| 性能 | 更高 | 较低 |
| 线程安全 | 方法局部变量 | 成员变量需注意 |
| 拦截器 | HandlerInterceptor | 独立拦截器栈 |
| 视图技术 | 更灵活 | 主要JSP |
| 集成 | 与Spring生态无缝 | 需要额外集成 |
| REST支持 | 优秀 | 较弱 |
| 配置 | 注解为主 | XML配置为主 |
- mybatis的基本工作流程?
- 加载配置:mybatis-config.xml + Mapper XML
- 创建SqlSessionFactory
- 创建SqlSession
- 执行SQL:
- 获取Mapper接口代理
- 解析SQL/参数
- 执行数据库操作
- 返回结果:结果映射
- 关闭会话
- 什么是MyBatis的接口绑定,有什么好处?
通过Mapper接口与XML映射文件绑定,优点:
- 类型安全
- 避免硬编码
- IDE支持更好
- MyBatis的编程步骤?
- MyBatis开发步骤:
- 添加依赖:mybatis.jar + 数据库驱动
- 创建全局配置文件:mybatis-config.xml
- 创建实体类
- 创建Mapper接口
- 创建SQL映射文件(XML或注解)
- 获取SqlSessionFactory
- 获取SqlSession
- 获取Mapper接口实例
- 执行数据库操作
- 提交事务/关闭会话
- JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
|--------------|-------------|
| JDBC不足 | MyBatis解决方案 |
| 大量样板代码 | 自动生成/简化代码 |
| 手动处理连接/异常 | 自动管理资源 |
| SQL与Java代码混合 | SQL与代码分离 |
| 硬编码参数/结果映射 | 自动参数绑定/结果映射 |
| 手动处理事务 | 声明式事务支持 |
| 缓存支持弱 | 提供一/二级缓存 |
| 不同数据库差异处理复杂 | 方言支持 |
| 批量操作繁琐 | 提供批量执行器 |
- MyBatis的优缺点?
MyBatis优点: - SQL控制灵活
- 学习曲线平缓
- 轻量级
- 动态SQL强大
- 与Spring集成好
- 性能接近JDBC
MyBatis缺点: - SQL工作量大
- 移植性较差
- 缓存机制较简单
- 复杂映射配置较多