一、MySQL篇
1.事务失效的场景?https://juejin.im/post/6844904096747503629
2.什么是事务?
一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。请举例说明:转账
3.事务的ACID,请具体说一说?
- 原子性:是指事务是一个不可分割的工作单位,事务的操作要么都发生,要么都不发生。
- 一致性:事务必须从一个一致性的状态变成另外一个一致性的状态
- 隔离性:一个事务的执行不能被其他事务干扰,并发的执行的各个事务之间不能相互影响
- 持久性:事务一旦提交,它数据库中数据的改变是永久的。
4.什么是脏读、不可重复读、幻读?
脏读:对于A和B两个事务,A读到了被B更新但还未提交的事务(读未提交)
不可重复读:多次读取同一个字段,前后读取不一致,A读取了一个字段,B更新了该字段后,A再次读取同一个字段,值就不同了。
幻读:A读取了表的一个字段,B在该表中插入了新的行,A再次读取时,就会多出几行,此为幻读。
5.隔离级别?
- Read Uncommited(读未提交):允许事务读取未被其他事务提交的变更,脏读、不可重复读和幻读都可能出现。
- Read Commited(读已提交):只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读、幻读仍然可能出现。
- Repeatable Read(可重复读)mysql默认的隔离级别:确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间禁止其他事务对这个字段进行更新。可以避免脏读和不可重复读,幻读仍然会出现。
- Serializable串行化:确保事务可以从一个表中读取相同的行,但这个事务持续期间,禁止其他事务对该表执行插入、更新、删除,所有并发问题均可以避免,但性能低下。
6.试着说出查询语句中涉及的所有关键字以及执行先后顺序?
from
join on
where
group by
having
select
order by
limit
7.如果需要存储货币相关的数据mysql应该用什么数据类型?Decimal
对应java的类型是什么?BigDecimal
8.谈谈你对sql调优的看法和理解?什么是索引?什么时候该创建索引?创建完索引如何保证索引不失效?
索引:索引是数据结构,排好序的快速查找数据结构。
为什么创建索引:索引的目的在于提高查询效率。
为什么可以提高效率?
什么时候该创建索引?
1.主键自动建立唯一索引
2.频繁作为查询条件的字段应该建立索引
3.查询中与其他表关联的字段,外键关系建立索引
4.查询中排序的字段,排序字段若通过索引去访问将大大提高排序效率
5.查询中统计或者分组字段
9、 count()、count(1)、count(列名)区别?
count(列名):会忽略null
count(1)和count()不会忽略null
在MySAM存储引擎下:count()效率高
在InnoDB下count()和count(1)效率差不多,但是比count(列名)高。
10、mybatis中方法是如何对应到mapper.xml文件的sql的?
方法名和mapper.xml的id一致
mapper类和mapper.xml的namespace一致
11、Mybatis中$和#的区别?
- #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”.
- $将传入的数据直接显示生成在sql中。如:order by u s e r i d user_id userid,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
- #方式能够很大程度防止sql注入。
4. 方 式 无 法 防 止 S q l 注 入 。 5. 方式无法防止Sql注入。 5. 方式无法防止Sql注入。5.方式一般用于传入数据库对象,例如传入表名.
6.一般能用#的就别用 . M y B a t i s 排 序 时 使 用 o r d e r b y 动 态 参 数 时 需 要 注 意 , 用 . MyBatis排序时使用order by 动态参数时需要注意,用 .MyBatis排序时使用orderby动态参数时需要注意,用而不是#
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。
二、java基础
1.基本数据类型
2.equals和区别?
1)对于,比较的是值是否相等
如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
3.权限修饰符及其作用域?
4.为什么为基本类型引入包装类?
因为java基本数据类型不能面向对象(没有属性和方法)
5.接口和抽象类区别?
抽象类:(有抽象方法的类一定是抽象类,抽象类未必有抽象方法)
1.可以定义构造器,而接口不行
2.有抽象方法和具体方法,接口全是抽象方法
3.可以包含静态方法,接口不能有静态方法(jdk1.8后可以有)
4.可以定义成员变量
5.抽象类中的成员可以被四种修饰符修饰,接口中的成员全是public的
相同点:
1.都不能被实例化
2.可以将抽象类和接口作为引用类型
6.静态变量、静态方法、普通变量、普通方法加载顺序?
静态变量、静态方法、普通变量、普通方法
7.hashmap底层结构?数组+链表+红黑树【底层结构转换阈值,及原理】
8.线程有几个状态?
线程新生(NEW)
线程运行(RUNABLE)
线程阻塞(BLOCKED)
线程等待(WAITING)死死的等
超时等待(TIME_WAITING)
终止(TERMINATED)
8、wait和sleep区别
1、首先他们来自不同的类
wait—》Object
sleep–》Thread
企业中,休眠,会用(java.util.current.TimeUnit这个类)
2、关于锁的释放
wait会释放锁,而sleep会持有锁(抱着锁睡觉,不会释放)
3、使用的范围不同
wait必须在同步代码块中
sleep可以在任何地方睡
4、是否需要捕获异常
wait不需要捕获异常
sleep必须要捕获异常
9、map在并发下是安全的吗?怎样变的安全?
不安全
Map<String, String> map = new ConcurrentHashMap<>();
参考:https://blog.csdn.net/qq_38616503/article/details/106559170
10、volatile关键字和synchronized关键字的区别?
(1)、volatile只能作用于变量,使用范围较小。synchronized可以用在变量、方法、类、同步代码块等,使用范围比较广。
(2)、volatile只能保证可见性和有序性,不能保证原子性。而可见性、有序性、原子性synchronized都可以包证。
(3)、volatile不会造成线程阻塞。synchronized可能会造成线程阻塞
11、写一个类时,可能需要覆写hashCode()和equals()方法,这两个方法的意义是什么,为什么要去覆写?
如果一个类不覆写Object中的hashCode方法,而直接调用该方法,得到的哈希值是由系统计算出的,返回值和对象属性之间没有直接联系。
覆写hashCode方法,可以根据对象属性的不同,返回相应的哈希值。
覆写equals方法之后,可以实现对象的自定义比较,如果不覆写此方法,默认调用Object的equals方法,等同于比较地址值
一般是为了增强自定义类的扩展性
12、谈谈对反射的理解?
java的反射首先要获取要反射类的字节码文件,获取字节码文件有三种方法:(1)Class.forName(类名)
(2)类名.class
(3)this.getClass()
然后将字节码中的方法、变量、构造函数等映射成相应的Method、Filed、Constructor等类,这些类提供了丰富的方法可以被我们使用。
13、动静代理的区别?
(1)静态代理只代理一个类,而动态代理是代理一个接口下的多个实现类
(2)静态代理首先要知道代理的是什么,而动态代理只是在运行时才知道要代理的是什么。
14、你所知道的java设计模式有哪些(GOF23)?
java一般认为有23种设计模式,建议单例模式一定要会手写。
15、创建对象的几种方式?
new
反射
clone
16、类什么时候被初始化?
(1)创建类的实例,也就是new对象
(2)访问类的静态变量,调用类的静态方法
(3)反射
(4)初始化一个类的子类
(5)JVM启动时标明的启动类,即文件名和类名相同的那个类
三、javaweb
1、statement和preparestatement区别?
最主要的一条区别是Statement容易被sql注入,而PrepareStatement传入的内容不会和sql发生任何的匹配关系。
2、get和post
1、url可见性:
get,参数url可见;
post,url参数不可见
2、数据传输上:
get,通过拼接url进行传递参数;
post,通过body体传输参数
3、缓存性:
get请求是可以缓存的
post请求不可以缓存
4、后退页面的反应
get请求页面后退时,不产生影响
post请求页面后退时,会重新提交请求
5、传输数据的大小
get一般传输数据大小不超过2k-4k(根据浏览器不同,限制不一样,但相差不大)
post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大。
6、安全性
这个也是最不好分析的,原则上post肯定要比get安全,毕竟传输参数时url不可见,但也挡不住部分人闲的没事在那抓包玩。安全性个人觉得是没多大区别的,防君子不防小人就是这个道理。对传递的参数进行加密,其实都一样。
3、cookie和session
cookie数据保存在客户端,session数据保存在服务端
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、可以考虑将登陆信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中。
四、谈谈SpringMVC运行原理?
(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。
五、Spring
1、谈谈对Spring的理解?
Spring的核心:IOC、AOP
IOC:控制反转思想,把原来的由程序员来new对象,现在交给容器来做
DI:依赖注入,spring使用javaBean对象的set方法或者带参构造为我们在创建所需对象时将其属性自动设置所需要值的过程,就是依赖注入的思想。
AOP:面向切面编程,其思想就是横切的思想,在不影响原来业务的基础下,通过横向切入实现对原来业务的动态增强,例如进行一些日志、事务权限控制的管理,此为面向切面编程的思想。
AOP底层是动态代理,如果是接口则采用jdk动态代理,如果是类就采用cglib方式实现动态代理。
2、Spring单例模式线程安全问题?
Spring框架里的bean获取实例的时候都是默认单例模式,所以在多线程开发里就有可能会出现线程不安全的问题。当多个用户同时请求一个服务器时,容器(tomcat)会给每一个请求分配一个线程,这时多个线程会并发执行该请求所对应的业务逻辑(controller里的方法),此时就要注意啦,如果controller(是单例对象)里有全局变量并且又是可以修改的,那么就需要考虑线程安全的问题。
解决方案有很多,比如设置@scope(“prototype”)为多例模式,为每个线程创建一个controller,还可以使用ThreadLocal。
ThreadLocal基本实现思路是:它会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突,因为每个线程都拥有自己的变量副本,从而也就没必要对该变量进行同步啦。
在ssh或ssm框架里的service或dao对象虽然也是单例模式,但正如上面分析的,他们没有可修改的全局变量,所以在多线程环境下也是安全的。
3、aop底层jdk动态代理和cglib区别?
JDK代理实现的三个要点:
1.通过java.lang.reflect.Proxy类来动态生成代理类
2.代理类要实现InvocationHandler接口
3.JDK代理只能基于接口进行动态代理的
CGLib采用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有的父类方法的调用,并顺势织入横切逻辑。
CGlib和JDK的原理类似,也是通过方法去反射调用目标对象的方法。
若目标对象实现了接口,spring默认使用JDK的动态代理。
优点:因为有接口,所以使系统更加松耦合
缺点:为每一个目标类创建接口
若目标对象没有实现任何接口,spring使用CGLIB进行动态代理。
优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。
缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。
六、其他
1、JPA延迟加载(懒加载)和立即加载?
默认使用的是延迟加载的形式查询的,调用(get)方法并不会立即发送查询,而是在使用关联对象的时候才会查询。(延迟加载)
延迟加载改立即加载:fetch 需要配置到多表映射关系的注解上
修改配置,将延迟加载改为立即加载:fetch=FetchType.EAGER 立即加载,fetch=FetchType.LAZY 延迟加载
2、redis缓存击穿缓存穿透?(一般只是问概念)
3、redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
redis参考:https://zhuanlan.zhihu.com/p/136796077
4、如果pom.xml文件中出现的maven依赖冲突问题怎么解决?
比如:某启动器里边自带的某jar和你引入第三方jar产生冲突
可以通过exclusions
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>要排除的依赖</exclusion>
</exclusions>
</dependency>
1、数据库设计三范式
(1)确保每一列的原子性不可拆分
(2)在第一范式的基础上,非主字段必须依赖于主字段(一个表只做一件事)
(3)在第二范式的基础上消除传递依赖