栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java面试题——2-5年经验常见面试题(四)(实际面试被问到)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java面试题——2-5年经验常见面试题(四)(实际面试被问到)

目录

1、string和stringbuffer和stringbuilder的区别

2、MyBatis防止SQL注入的方法

3、JDK动态代理和CGLIB动态代理的区别?

4、动态代理和静态代理的区别

5、Spring中的动态代理是通过什么方式实现的?

6、Lombok的原理

7、spring循环依赖以及解决办法

8、spring在哪些情况下无法解决循环依赖问题?

9、java中的锁有哪些?

 10、mysql中的锁有哪些?


1、string和stringbuffer和stringbuilder的区别
  • String是一个长度不可变的字符序列,底层是一个被final修饰的char[]数组,所以说,任何对 String 类型进行改变的操作实际上都是重新生成了一个新的String对象,然后将指针指向新的 String 对象,这样不仅效率低下,而且大量浪费有限的内存空间,所以经常改变内容的字符串最好不要用 String 。
  • StringBuilder: 可变的字符序列 , 线程不安全的,效率高,底层是 char[]数组 存储

  • StringBuffer : 可变的字符序列 , 线程安全的,效率低 ,底层是 char[]数组 存储


2、MyBatis防止SQL注入的方法

MyBatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。

使用 #{} 可以有效的防止SQL注入,提高系统安全性。


3、JDK动态代理和CGLIB动态代理的区别?
  • JDK Proxy是通过拦截器加反射的方式实现的,只能对实现了接口的类生成代理,无需通过加载第三方类实现,实现和调用起来比较简单,JDK Proxy实现动态代理的核心是实现Invocation接口。
  • CGLib是第三方提供的工具,基于ASM实现的,无需通过接口来实现,它是通过实现子类的方式来完成调用的,性能比较高

JDK Proxy是Java语言自带的功能,Java对JDK Proxy提供了稳定的支持,并且会持续的升级和更新JDK Proxy,例如Java8版本中的JDK Proxy性能相比于之前版本提升了很多

动态代理常用实现方式是反射

动态代理是一种行为方式,而反射或ASM只是它的一种实现手段而已

反射机制是指程序在运行期间可以访问、检测和修改其本身状态或行为的一种能力,使用反射我们可以调用任意一个类对象以及类对象中包含的属性及方法


4、动态代理和静态代理的区别

静态代理其实就是事先写好代理类,可以手工编写也可以使用工具生成,它的缺点是每个业务类都要对应一个代理类特别不灵活也不方便,于是就有了动态代理

动态代理的常见使用场景有RPC框架的封装、AOP(面向切面编程)的实现、JDBC的连接等


5、Spring中的动态代理是通过什么方式实现的?

Spring框架中同时使用了两种动态代理:JDK Proxy和CGLib

当Bean实现了接口时,Spring就会使用JDK Proxy

在没有实现接口时就会使用CGLib

我们也可以在配置中指定强制使用CGLib

只需要在Spring配置中添加


6、Lombok的原理

Lombok的实现和反射没有任何关系,反射是程序在运行期的一种自省(introspect)能力,Lombok的实现是在编译期就完成了


7、spring循环依赖以及解决办法

在代码中,把两个bean或多个bean相互之间去持有对方的引用就会发生循环依赖,循环依赖会导致注入啊会出现死循环,这是spring出现循环依赖的原因。

循环依赖有三种形态:

第一种是互相依赖,a依赖b,b又依赖a,他们之间形成了循环依赖;

第二种是三者间依赖,也就是a依赖b,b依赖c,c依赖a,形成了循环依赖;

第三种是自我依赖,也就是说a依赖a,形成的循环依赖;

spring设计了三级缓存去解决循环依赖问题,当我们去通过getBean()去获取一个对象实例的时候,spring会先从一级缓存去找,一级缓存没找到就去二级缓存去找,如果一二级缓存都没找到,意味着这个bean还没有实例化,然后spring容器会去实例化这个bean。而这个初始化实例的bean呢放到二级缓存,三级缓存是存储代理bean,当调用getBean()方法的时候呢,发现目标bean需要代理工厂来创建,这个时候就会把创建好的实例保存到三级缓存,最终呢也会把复制好的bean同步到一级缓存


8、spring在哪些情况下无法解决循环依赖问题?

有四种情况下的循环依赖无法被解决:

第一种是多实例bean通过setter注入的时候,不能解决缓缓依赖问题;

第二种是构造器注入的bean的情况,不能解决缓缓依赖问题;

第三种是单例的代理bean通过setter注入的时候,不能解决缓缓依赖问题;

第四种是设置@DependsOn注解的bean,不能解决缓缓依赖问题;


9、java中的锁有哪些?


 10、mysql中的锁有哪些?
  • 从锁粒度上划分为行锁和表锁
  • 从实现上又分为共享锁和排它锁
  • 从思想上又分为悲观锁和乐观锁

通过版本号来进行更新的操作属于乐观锁,共享锁 & 排它锁都是悲观锁的具象实现

悲观锁:

悲观锁在操作数据时比较悲观,每次去拿数据的时候认为别的线程也会同时修改数据,所以每次在拿数据的时候都会上锁,这样别的线程想拿这个数据就会阻塞直到它拿到锁

悲观锁适合并发写入操作多的场景,先加锁再进行写操作,能保证写操作的数据正确性

乐观锁:

乐观锁在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断一下在此期间别的线程有没有更新过这个数据。

乐观锁的实现方式:CAS实现,Version版本号机制

乐观锁适合读操作多的场景,不加锁的特点能使其读操作的性能大幅提升


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/863248.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号