java常问面试题10道,offer来碗里(二)

目录

1、如果你发现某个接口响应很慢,该怎么排查?

2.spring中Bean的生命周期

3.事务实效的场景和原因(单体应用:@Transactional)

4.Mybatis中#{}和${}的区别是什么?

5.索引是否生效,看其执行计划

6.Redis应用问题:缓存雪崩、缓存穿透、缓存击穿

7. 谈一谈volatile关键字

8.wait 和 sleep 的区别:

9.Redis的数据结构及使⽤场景

10.谈一下项目中,你遇到最深刻的困难,然后怎么解决的???


1、如果你发现某个接口响应很慢,该怎么排查?

导致接口响应慢的原因太多了:网络、应用层、数据库事务、服务器自身、慢sql等

逐个来说

  • 网络:对于单个请求来讲,网络因素影响其实很小,除非网络挂了导致请求超时才能意识到;而对于大批量请求,每个请求慢10ms,请求多了,时间也就长了,这种情况可以检查下你的应用部署机和数据库机地理位置是不是隔得很远,比如一个在华东一个在西南,地理距离也会对请求响应时间产生影响,请求量越大越明显;

  • 应用层:就是我们敲的controller、service那些代码,这一层出问题很好解决,因为代码毕竟都是我们敲的嘛,一看日志就大概知道什么原因,最多的就是出现死循环(当然一旦出现死循环也不只是响应慢那么简单了);代码逻辑写的差点其实不会太影响性能,现在的cpu执行效率你尽管放心,再怎么优化也顶不了少一次io;

  • 数据库事务:检查下你的数据库是不是卡事务了,导致锁了很多表;

  • 服务器自身:服务器是不是卡了,cpu是不是炸了,内存是不是满了;

  • 慢sql:这一层出问题的几率很大,同一组查询结果,由于sql不同,耗时能相差几百上千倍,可以通过查看sql执行计划来排查问题,详见 mysql执行计划解析

2.spring中Bean的生命周期

(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(4)bean 可以使用了(对象获取到了)
(5)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

3.事务实效的场景和原因(单体应用:@Transactional)

spring事务的原理是AOP,进行了切面增强,那么失效的根本原因是这个AOP不起作用了!

常见情况有 如下几种

1、发生自调用,类里面使用this调用本类的方法(this通常省略),此时这个this对象不是代理类,而 是UserService对象本身! 解决方法很简单,让那个this变成UserService的代理类即可! 2、方法不是public的 (如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效

3、数据库不支持事务

4、没有被spring管理

5、异常被吃掉,事务不会回滚(或者抛出的异常没有被定义,默认为RuntimeException

4.Mybatis中#{}和${}的区别是什么?

. 1.#{}是预编译处理、是占位符, ${}是字符串替换、是拼接符

2. Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调⽤ PreparedStatement 来赋值

3. Mybatis 在处理${}时, 就是把${}替换成变量的值,调⽤ Statement 来赋值

4. 使⽤#{}可以有效的防⽌SQL注⼊,提⾼系统安全性

5.索引是否生效,看其执行计划

MySQL Explain知多少?

6.Redis应用问题:缓存雪崩、缓存穿透、缓存击穿

7. 谈一谈volatile关键字

在并发领域中,存在三⼤特性:原⼦性、有序性、可⻅性。

1.volatile关键字⽤来修饰对象的属性,在并发 环境下可以保证这个属性的可⻅性,对于加了volatile关键字的属性,在对这个属性进⾏修改时,会直接 将CPU⾼级缓存中的数据写回到主内存,对这个变量的读取也会直接从主内存中读取,从⽽保证了可⻅ 性。

2.在对volatile修饰的成员变量进⾏读写时,会插⼊内存屏障,,由于使⽤了内存屏障,所以会禁⽌指令重排,所以同时 也就保证了有序性,在很多并发场景下,如果⽤好volatile关键字可以很好的提⾼执⾏效率。

8.wait 和 sleep 的区别:

1.sleep 来自 Thread 类,和 wait 来自 Object 类。

2.主要是sleep方法没有释放锁,让出cpu,而wait方法释放了 锁,使得其他线程可以使用同步控制块或者方法。  

3.wait,notify和 notifyAll 只能在同步控制方法或者同步控制块里面使用,而 sleep 可以在任何地方使用(使 用范围)  

4. sleep 必须捕获异常,而 wait , notify 和 notifyAll 不需要捕获异常

另外:

 * sleep 方法属于 Thread 类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了 sleep 方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在 sleep 的过程中过 程中有可能被其他对象调用它的 interrupt() ,产生 InterruptedException 异常,如果你的程序不捕获这个异 常,线程就会异常终止,进入 TERMINATED 状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语 句块(可能还有 finally 语句块)以及以后的代码。

注意 sleep() 方法是一个静态方法,也就是说他只对当前对象有效,通过 t.sleep() 让t对象进入 sleep ,这样 的做法是错误的,它只会是使当前线程被 sleep 而不是 t 线程

 *wait 属于 Object 的成员方法,一旦一个对象调用了wait方法,必须要采用 notify() 和 notifyAll() 方法 唤醒该进程;如果线程拥有某个或某些对象的同步锁,那么在调用了 wait() 后,这个线程就会释放它持有的所有 同步资源,而不限于这个被调用了 wait() 方法的对象。 wait() 方法也同样会在 wait 的过程中有可能被其他对 象调用 interrupt() 方法而产生 。

9.Redis的数据结构及使⽤场景

Redis的数据结构有:

1. 字符串:可以⽤来做最简单的数据缓存,可以缓存某个简单的字符串,也可以缓存某个json格式的字符 串,Redis分布式锁的实现就利⽤了这种数据结构,还包括可以实现计数器、Session共享、分布式ID

2. 哈希表:可以⽤来存储⼀些key-value对,更适合⽤来存储对象

3. 列表:Redis的列表通过命令的组合,既可以当做栈,也可以当做队列来使⽤,可以⽤来缓存类似微信 公众号、微博等消息流数据

4. 集合:和列表类似,也可以存储多个元素,但是不能重复,集合可以进⾏交集、并集、差集操作,从⽽ 可以实现类似,我和某⼈共同关注的⼈朋友圈点赞等功能

5. 有序集合:集合是⽆序的,有序集合可以设置顺序,可以⽤来实现排⾏榜功能

10.谈一下项目中,你遇到最深刻的困难,然后怎么解决的???

        自由发挥吧老铁

java常问面试题10道,offer来碗里(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

only-qi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值