MYSQL
1、mysql中char和varchar的区别
2、sql优化
3、事务的基本特性和隔离级别
- 原子性:一个事务中的操作要么全部成功,要么全部失败
- 一致性:数据库从一个一致性状态转换为另一个一致性状态
- 隔离性:一个事务的修改操作在未提交前,其他事务不可见
- 持久性:一个事务的提交,所作的修改永久保存在数据库中
4个隔离级别
- 读未提交:读取了一个事务还没有提交的数据,叫做脏读
- 读以提交:两次读取的结果不一样。叫做不可重复读
- 可重复度:mysql的默认级别,每一次读取的结果都一样。可能产生幻读
- 串行:给每一行加锁
脏读:前一个事务回滚,另一个事务读取的数据不正确
不可重复读:两次查询的过程中插入一个事务的更新的原有的数据
幻读:两次查询的数据笔数不一样
4、左连接、右连接、子查询?
左连接:select 字段列表 from A表 left join B 表 on A.id=B.id(关联条件)
右连接:select 字段列表 from A表 right join B 表 on A.id=B.id(关联条件)
子查询:查询在销售部工作的员工信息。select * from emp where depid =(select depid from dep where name='销售部‘);
5、having和where的区别
因为having是从前筛选的字段再筛选,而where是从数据表中的字段直接进行的筛选的。
6、mysql索引
索引是一种优化查询的数据结构
把无序的数据变成有序的查询
索引为什么快?
使用B+tree的数据结构,能够快速筛选出需要的记录,避免全表扫描
7、索引的优点和缺点
优点:
加快查询速度
加快表与表的连接
创建唯一索引,可以保证数据的唯一性
减少查询中排序和分组的时间
缺点:
创建索引和维护索引都需要时间,索引越大,时间越长
对数据的增删改,都需要维护索引
索引会占据磁盘空间
8、分页
SELECT * from user limit startIndex,pageSize;(从那条数据开启,多少条)
pagehelper插件
PageHelper.startPage(1 , 5);
List<Person> personList = personService.findPerson();
//得到分页的结果对象
PageInfo<Person> personPageInfo = new PageInfo<>(personList);
Spring Boot
1、自动装配的原理
java基础
1、string字符串反转——三种方法
2、string工具类有哪些方法
- isEmpty()
- equals()
- length()
- charAt()
- compareTo()
- getByte()
- concat()
- substring()
- trim()去掉首位空格
- toUpperCase()
- index()第一次出现的下标
3、java的基本数据类型和引用数据类型有哪些?
基本数据类型:字符型:char
布尔型:boolean
数值型:short、int、long、float、double、byte
引用数据类型:类、接口、数组
4、float和double的区别
在定义上:
例float x=123.456f,y=2e20f; 注意float型定义的数据末尾必须有"f"或"F",为了和double区别
例double x=1234567.98,y=8980.09d; 末尾可以有"d"也可以不写
5、数据交换
int a,b,temp;
temp=a;
a=b;
b=temp;
6、日期转换
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
System.out.println(simpleDateFormat.format(new Date()));
7、StringBuffer的append方法
String类和StringBuffer类都是由public final修饰,最终类,不可继承
为什么StringBuffer长度和内容可变,String不可以呢?
String源码的成员变量
/** String本质是个char数组.*/
private final char value[];
由final修饰
发现StringBuffer没有value[]成员变量,看父类AbstractStringBuilder中value[]成员变量
/**
* The value is used for character storage.
*/
char[] value;
8、静态代码块能访问非静态方法吗?
在外部调用静态方法时,可以使用”类名.方法名”的方式,也可以使用”对象名.方法名”的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制
静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块 —> 非静态代码块 —> 构造方法)。 该类不管创建多少对象,静态代码块只执行一次.
9、static关键字
静态内部类与非静态内部类之间存在一个最大的区别,我们知道非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:
它的创建是不需要依赖外围类的创建。
它不能使用任何外围类的非 static 成员变量和方法。
public class Singleton {
//声明为 private 避免调用默认构造方法创建对象
private Singleton() {
}
// 声明为 private 表明静态内部该类只能在该 Singleton 类中被访问
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getUniqueInstance() {
return SingletonHolder.INSTANCE;
}
}
当 Singleton 类加载时,静态内部类 SingletonHolder 没有被加载进内存。只有当调用 getUniqueInstance()方法从而触发 SingletonHolder.INSTANCE 时 SingletonHolder 才会被加载,此时初始化 INSTANCE 实例,并且 JVM 能确保 INSTANCE 只被实例化一次。
这种方式不仅具有延迟初始化的好处,而且由 JVM 提供了对线程安全的支持。
静态导包
格式为:import static
这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法
//将Math中的所有静态资源导入,这时候可以直接使用里面的静态方法,而不用通过类名进行调用
//如果只想导入单一某个静态方法,只需要将*换成对应的方法名即可
import static java.lang.Math.*;//换成import static java.lang.Math.max;具有一样的效果
public class Demo {
public static void main(String[] args) {
int max = max(1,2);
System.out.println(max);
}
}
10、static{}静态代码块与{}非静态代码块(构造代码块)的区别?
相同点: 都是在 JVM 加载类时且在构造方法执行之前执行,在类中都可以定义多个,定义多个时按定义的顺序执行,一般在代码块中对一些 static 变量进行赋值。
不同点: 静态代码块在非静态代码块之前执行(静态代码块 -> 非静态代码块 -> 构造方法)。静态代码块只在第一次 new 执行一次,之后不再执行,而非静态代码块在每 new 一次就执行一次。 非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。
一般情况下,如果有些代码比如一些项目最常用的变量或对象必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的。如果我们想要设计不需要创建对象就可以调用类中的方法,例如:Arrays 类,Character 类,String 类等,就需要使用静态方法, 两者的区别是 静态代码块是自动执行的而静态方法是被调用的时候才执行的.
public class Test {
public Test() {
System.out.print("默认构造方法!--");
}
//非静态代码块
{
System.out.print("非静态代码块!--");
}
//静态代码块
static {
System.out.print("静态代码块!--");
}
private static void test() {
System.out.print("静态方法中的内容! --");
{
System.out.print("静态方法中的代码块!--");
}
}
public static void main(String[] args) {
Test test = new Test();
Test.test();//静态代码块!--静态方法中的内容! --静态方法中的代码块!--
}
}
上述代码输出
静态代码块!–非静态代码块!–默认构造方法!–静态方法中的内容! --静态方法中的代码块!–
当只执行Test.test()时输出
静态代码块!–静态方法中的内容! --静态方法中的代码块!–
当只执行Test test = new Test()时输出
静态代码块!–非静态代码块!–默认构造方法!–
非静态代码块与构造函数的区别是: 非静态代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
11、final关键字
final 关键字,意思是最终的、不可修改的,最见不得变化 ,用来修饰类、方法和变量,具有以下特点:
final 修饰的类不能被继承,final 类中的所有成员方法都会被隐式的指定为 final 方法;
final 修饰的方法不能被重写;
final 修饰的变量是常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。
12、static关键字
- 修饰成员变量和成员方法: 被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享,可以并且建议通过类名调用。被 static 声明的成员变量属于静态成员变量,静态变量 存放在 Java 内存区域的方法区。调用格式:类名.静态变量名 类名.静态方法名()
- 静态代码块: 静态代码块定义在类中方法外, 静态代码块在非静态代码块之前执行(静态代码块—>非静态代码块—>构造方法)。 该类不管创建多少对象,静态代码块只执行一次.
- 静态内部类(static 修饰类的话只能修饰内部类): 静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围类,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非 static 成员变量和方法。
- 静态导包(用来导入类中的静态资源,1.5 之后的新特性): 格式为:import static 这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。
13、this关键字
this 关键字用于引用类的当前实例。 例如
class Manager {
Employees[] employees;
void manageEmployees() {
int totalEmp = this.employees.length;
System.out.println("Total employees: " + totalEmp);
this.report();
}
void report() { }
}
在上面的示例中,this 关键字用于两个地方:
this.employees.length:访问类 Manager 的当前实例的变量。
this.report():调用类 Manager 的当前实例的方法。
此关键字是可选的,这意味着如果上面的示例在不使用此关键字的情况下表现相同。 但是,使用此关键字可能会使代码更易读或易懂。
14、super关键字
super关键字用于子类访问父类的变量和方法
public class Super {
protected int number;
protected showNumber() {
System.out.println("number = " + number);
}
}
public class Sub extends Super {
void bar() {
super.number = 10;
super.showNumber();
}
}
在上面的例子中,Sub 类访问父类成员变量 number 并调用其父类 Super 的 showNumber() 方法。
使用 this 和 super 要注意的问题:
在构造器中使用 super() 调用父类中的其他构造方法时,该语句必须处于构造器的首行,否则编译器会报错。另外,this 调用本类中的其他构造方法时,也要放在首行。
this、super 不能用在 static 方法中。
简单解释一下:
被 static 修饰的成员属于类,不属于单个这个类的某个对象,被类中所有对象共享。而 this 代表对本类对象的引用,指向本类对象;而 super 代表对父类对象的引用,指向父类对象;所以, this 和 super 是属于对象范畴的东西,而静态方法是属于类范畴的东西。
15、异常常见处理方式及Spring Boot中异常处理?
- try catch
- throw
- 使用这个注解就容易了,但是只能处理使用 @ExceptionHandler 注解的方法的 Controller 的异常,对于其他 Controller 的异常就无能为力了,只能再使用同样的方法将使用 @ExceptionHandler 注解的方法写入要捕获异常的 Controller 中,所以不推荐使用。
- 使用 @ControllerAdvice + @ExceptionHandler 注解能够处理全局异常,这种方式推荐使用,可以根据不同的异常对不同的异常进行处理。
使用方式:定义一个类,使用 @ControllerAdvice 注解该类,使用 @ExceptionHandler 注解方法,这里我定义了一个 GlobalException 类表示来处理全局异常,
16、常见错误及其发生情况
-
NullpointException
使用对象的方法但是对象为空 -
ClasscastException
java.lang.ClasssCastException, 是强制类型转换时候出现异常,强制转换类型的前提是父类引用指向的对象的类型是子类的时候才可以进行强制类型转换,如果父类引用指向的对象的类型不是子类的时候就会产生java.lang.ClasssCastException异常。 -
ArrayIndexOutOfBoundsException异常
17、接口和抽象类的区别?
- 接口可以实现多个、抽象只能继承一个
- 接口的成员变量只能是public static final 抽象类可以是各种类型
- 接口的只有public abstract方法 抽象类的成员函数可以是普通成员函数
- 接口表达的是like a的关系 抽象类是is a的关系
- 关注事物的本质用抽象类,关注一个操作用接口
18、序列化
将java对象转换为字节序列的过程
作用:在传递和保存对象的时候保证对象的完整性和可传递性
19、springboot常用注解
- @Autowired:自动导入依赖的bean
- @Value导入spring boot的application.ym里面配置的属性值
- @Component组件
- @Import导入其他配置类
- @ComponentScan自动扫描组件
- @EnableAutoConfiguration自动配置
- @RequestMapping提供路由信息
- @RestController是@ResponseBody和@Controller注解之和
20、java三大特征
- 封装:属性私有化,提供getter和setter来访问属性,通过外部接口访问类的成员
- 继承:将相同的属性和方法提取出来,新建一个父类。子类重写父类的方法。代码复用
- 多态:设计时多态重载、运行时多态重写、增加代码的灵活度
21、springMvc
提供一个总的前端控制器servlet,接收请求,定义一系列路由策略(url到handel的映射)及设配执行handle,将handle结果通过视图解析器展示给前端
Mybatis
1、mybatis的优缺点
优点:很好的和spring集成
与jdbc相比,减少了代码量,不用手动开关连接
提供映射,支持对象和数据库orm字段映射
sql写在xml里,解除了sql和程序代码的耦合,提供xml标签,支持动态sql
缺点:当字段多,表联系多,sql编写工作量大
sql依赖数据库,可移植性差
2、${}和#{}的区别
spring
1、谈谈你对spring的理解?
spring是一个ioc容器,用来管理bean,通过依赖注入实现控制反转。很好的与各种框架整合。用aop解决代码重复问题。aop就是不同类的不同方法的共同处理抽取一个切面,自动注入到方法执行中,例如异常,日志。
2、BeanFactory和ApplicationContext有什么区别?
springmvc
1、springmvc的工作流程
用户发送请求,前端控制器dispatcherservlet接受请求
dispatcherservlet调用handlermapping处理器映射器通过xml或者注解找到具体的处理器和拦截器返回给dispatcherservlet
dispatcherservlet调用handleradapter处理器适配器找到具体的controller
controller执行完返回modelandview给dispatcherservlet
再通过视图解析器解析返回view
渲染返回给前端
2、谈谈你对springmvc的理解?
springmvc就是spring对web框架的一个解决方案,前端控制器接收请求,然后定义一系列路由策略url到映射及适配执行返回modelandview,通过视图解析器解析返回给用户。
spring boot
1、如何理解spring boot的starter
starter就是一个jar包,定义一个配置类,里面定义bean,然后在META-INF/spring.factories写入该配置类。springboot就会按照约定加载该配置类。
2、谈谈你对springboot的理解?
springboot就是spring提供的一个快速开发工具包,可以快速开发spring+springmvc应用,简化了配置。通过starter机制整合了一系列的解决方案。redis、es实现开箱即用。
多线程
1、并发的三大特性
- 原子性:要么全部执行,要么都不执行
- 可见性:一个线程修改了变量,其他线程能够立刻看见修改的值
- 有序性:防止指令重排。虚拟机编译时不会按照我们写的代码顺序编译,会按照不影响结果的方式编译,但是会有线程安全问题。
- synchronized关键字满足三个特性,volatile不满足原子性
2、为什么要用线程池?
- 降低资源消耗:降低创建、销毁线程的资源消耗、提高线程利用率
- 提高响应速度:不需要先创建,后执行,
- 提高线程管理性:线程时稀缺资源,使用线程池统一分配调优监控
3、解释下线程池参数
4、简述线程池处理流程