面试常问问题
1 spring相关
(1)@Transactional失效的场景
<1> @Transactional注解默认只会回滚运行时异常(RuntimeException),如果方法中抛出了其他异常(如:编译时异常、sql数据库有异常、反射找不到类异常),则事务不会回滚(数据库数据仍然插入成功了)。
@Transactional(rollbackFor = Exception.class)
<2> 如果方法中有try catch语句,并且抛出的异常的代码被try捕获,那么方法上的@Transactional注解也会失效。
<3> 方法内调用,一个没有@Transactional注解的方法在内部调用了有@Transactional注解的方法,那么由于spring aop的代理会导致有@Transactional注解的方法的事务失效。
<4> 一个有@Transactional注解的方法中调用了@Async异步注解的方法,由于@Async是开启一个异步线程执行,和主线程不共享同一个事务,当主线程中有异常回滚后,@Async注解的方法不会回滚。
<5> 事务的方法被private和final修饰的,事务也会失效。
(2)线程池、多线程编程方法、线程池的参数
1 @Async注解 需要结合自定义线程池来使用 通常需要自己new ThreadPoolTaskExecutor 来赋值线程池中的参数
如果不使用自定义的线程池,将会采用默认的线程池:simpleAsyncTaskExecutor ,里面的核心线程数和最大线程数都是Integer的最大值,相当于可以无限创建线程。
2 ThreadPoolTaskExecutor 执行任务
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.execute(()->{runnable}
// submit是有返回值的
Future future = executor.submit(runnable或者callable);
future.get(); // 得到返回值
3 CompletableFuture
// 没有返回值 如果不显式指定线程池,它将使用ForkJoinPool.commonPool()。这个线程池是为ForkJoinPool设计的,提交的任务过多,可能会导致性能问题。
CompletableFuture.runAsync(Runnable任务);
// 推荐
CompletableFuture.runAsync(Runnable任务,Executor(指定的自定义线程池));
// 有返回值的方法 CompletableFuture.supplyAsync
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.supplyAsync(new Supplier<Object>() {
});
// 使用自定义线程池
CompletableFuture<Object> objectCompletableFuture = CompletableFuture.supplyAsync(new Supplier<Object>() {
},Executor);
4 在以上线程的基础上,可以使用CountDownLatch阻断主线程
CountDownLatch countDownLatch = new CountDownLatch(mainLists.size());
for(Map<String,Object> mainMaps : mainLists) {
//异步执行
threadPoolConfig.taskExecutor().execute(() -> {
log.error("线程:{},开始异步处理:{}",Thread.currentThread().getName(),mainMaps.get("pri_num"));
******处理逻辑
// 减一
countDownLatch.countDown();
// 调用await()方法让主线程阻塞
try {
countDownLatch.await();
} catch(InterruptedException e) {
log.error("发生异常{}",e.getMessage());
}
5 线程池的参数以及配置方法:
(1)核心线程数:始终存活的线程数。通常设置为与CPU核心数相等或略高,以处理CPU密集型任务。
(2)最大线程数:线程池中最多可以创建的线程数量。通常设置为核心线程数的2-4倍。当任务队列已满且创建的线程数小于最大线程数时,线程池会继续创建线程。
(3)空闲线程存活时间:当线程数超过核心线程数时,多余的空闲线程在空闲时间超过空闲线程存活时间后会被销毁。 有利于避免资源浪费。
(4)时间单位:空闲线程存活时间的单位 有秒和毫秒
(5)任务队列:用于保存等待执行的任务
(6)线程工厂:用户创建线程池中的线程。可以给每个创建出来的线程设置更有意义的名字。
(7)拒绝策略:当队列满时并且线程数大于等于最大线程数,如何拒绝请求执行的策略。
对于CPU密集型任务,核心线程数通常设置为CPU核心数;而对于I/O密集型任务,核心线程数可以设置为CPU核心数的2倍或更多,以处理更多的并发任务。选择合适的任务队列也很重要,例如LinkedBlockingQueue适合需要处理大量并发任务的场景,而ArrayBlockingQueue则适合需要限制任务数量的场景。
6 spring全家桶包括哪些
(1)Spring Framework:整个Spring全家桶的核心,提供了IoC容器、AOP、事务、MVC框架等基础功能。
(2)Spring Boot:基于Spring Framework的快速开发框架,简化了Spring应用的配置和部署,提供了自动配置、嵌入式服务器等功能,开发者可以更加简单高效地构建独立运行的Spring应用。
(3)Spring Data:简化数据库访问的框架,支持多种数据库技术,如关系型数据库和NoSQL数据库
(4)Spring Security:用于保护企业级应用的安全性,提供认证、授权、攻击防护等功能
(5)Spring Cloud:用于构建分布式系统的工具集,基于Spring Boot,提供了服务注册与发现、负载均衡、服务熔断等功能
(6)Spring Integration:消息传递
(7)Spring Batch:用于批处理应用的框架
(3)常见的json解析框架
jackson(一般是objectMapper) 需要new objectMapper
writeValueString (将对象转为字符串) parse(将字符串转为对象)
fastjson (JsonObject ) parseObject(将string转为jsonObject对象) toJsonString(将对象转为String 序列化)
JsonObject jsonObject = new Js