u+每日一题
1.#{ }和${ }的区别
#{ }是传入的值占位符,可以进行预编译,防止sql注入。
${ }数据库操作拼接时用的,先取值后编译,不能防止sql注入。
能用前者就要前者。
2.final、finally、finalize三者区别
- final修饰的类不能被继承,修饰的方法不能重写,修饰的变量就是一个常量,只能初始化。
- finally只在try…catch…语句块中出现,代表后面的语句不管对错,都会执行。
- finalize是Object的一个方法,表示垃圾回收器在回收垃圾的时候,会先调用finalize方法看对象是否可以回收。
3.Java中操作字符串都有哪些类?以及区别
- String、StringBuffer、StringBuilder
String是不可变序列的,是一个字符串常量。因为它是有final修饰的。每次String操作都会创建新的String对象,所以操作慢于后面两者。
StringBuffer线程是安全的,但是性能不太好。可变序列,是一个字符串变量。
StringBuilder线程是不安全的,但是性能很好。可变序列,是一个字符串变量。
4.BIO、NIO、AIO三者区别
- BIO:同步阻塞式,有多少个用户向浏览器发送请求,就会创建多少个线程。不管用户有没有响应,线程都必须等待,资源浪费严重。一个用户一个线程。
- NIO:同步非阻塞,用户和浏览器之间多了一个选择器,用户请求发送到选择器上,当有IO读写时,就会给它创建线程。一个请求一个线程。
- AIO:异步非阻塞,用户发送的请求先给操作系统处理,处理后再通知线程。一个有效请求一个线程。
5.Collection 和 Collections 区别
- Collection是一个集合接口,给集合对象提供相应操作的集合方法。List,Set都是它的子类。
- Collections是一个包装类,包含静态方法不能被实例化。也可以理解就是一个工具类。
6.接口和抽象类区别
- 抽象类是对事物本身的描述,接口是对事物行为方式的描述。 比如说哈士奇抽象类是狗,接口是溜街,吃饭。
- 一个类只能一个抽象类,一个类可以有多个接口。
所以在某个程度上,虽然接口功能弱化很多,但是它只针对某个动作的描述。但是可以多个接口,科技降低代码设计难度。
7.Java的序列化,什么时候进行
Java序列化就是对象转为字节流的过程
时候:当java对象进行网络传输或者持久化到文件中。
8.LinkedList和ArrayList区别
- LinkedList底层是双向链表,插入修改比较快,查询慢。
- ArrayList底层是数组,查询快。
但是LinkedList更占内存,因为每个节点还有两个引用,一个指向前一个(to prev),一个指向后一个(to next)。
9.动态代理是什么?有哪些应用?
当要给实现了接口的类中的方法做一些额外处理,比如:日志,事务等。
就可以给这个类做一个代理类,这个代理类不实现服务,而是直接调用被代理类的方法,并将结果封装,起到一个预处理的作用。
(经纪人和艺人的关系)
应用:
SpringAop就是一个典型的动态代理,来实现切面编程。
添加统一日志管理。
10.synchronized 底层实现原理
synchronized是java中实现同步锁的关键字
实现原理分两种情况:
- synchronized同步语句块
使用了monitorenter和monitorexit指令,前者指向同步代码块开始的地方,后者指向同步代码块结束的地方。
当执行monitorenter指令时,线程会获取锁,也就是获取monitor的持有权。当计数器为0的时候成功获取,之后将计数器变为1。
当执行monitorexit指令时,计数器设为0,表明锁被释放。如果获取对象锁失败,就会阻塞等待,直到锁被另外一个线程释放为止。
注意:为什么有两个monitorexit?
因为防止异常退出从而没有释放锁,造成死锁;第二个就是保证即使异常,我也能将锁释放出去。 - synchronized修饰方法
没有两个指令,而是acc_synchronized标识,表明是一个同步方法。JVM访问标识来辨别一个方法是否为同步方法。
11.Spring,SpringMvc,SpringBoot的区别
- Spring是一个开源的轻量型框架,配置bean以及维护bean之间的关系。
- SpringMvc其实是Spring的一个组件,极大程度降低了代码耦合。
- SpringBoot是一个微服务框架,特点就是自动配置,不需要之前繁琐的手动配置了;约定大于配置。
12.Mybatis的缓存回收的几种算法
- LRU:最近最长没有使用的。根据时间。
- LFU:最近最少没有使用的。根据频率。
- FIFO:先进先出,类似于队列。
13.runnable 和 callable 区别
- runnable没有返回值,不能throw抛出异常;
- callable有返回值,能throw抛异常;
对于callable,通过future task去获得返回值,future是接口,future task是它的实现类。
一般future作用:终端执行的任务,判断任务是否还在执行,得到执行后的结果。
14.throw和throws的区别
15.乐观锁和悲观锁
- 悲观锁:认为自己表中的数据每次操作肯定会被修改,所以每次都会上锁,只有拿到锁才能操作。java中的synchronize就是悲观锁的思想的体现。
- 乐观锁:认为自己表中的数据绝不会被修改,不会上锁。但是在更新的时候会判断别人有没有更改这个数据,可以通过版本号机制或CAS算法实现。
数据库中的version字段默认1,当修改一次,版本号加1,如果if判断和自己的不一致,就驳回请求。
16.如何获取一个接口/抽象类对象
- new接口,但是要在构造器后的{ }中实现接口中所有的抽象方法
- new子类/实现类
- 工厂模式来build。典型的就是SqlSessionFactory这种方式。