1 String 、StringBuilder 、StringBuffer 的区别?
1,String是只读字符串,引用的字符串内容是不能被改变的。
2,StringBuilder和StringBuffer表示的字符串对象可以直接被修改,StringBuilder单线程环境下使用,效率要比StringBuffer要高,StringBuffer加锁了,更加线程安全
2 equals() 与 == 的区别?
1.==可一判断基本类型,也可以判断引用类型
判断基本类型比较的是值
判断引用类型比较的是地址值,即判断的是否为同一个对象
2.equals判断两个对象是否相等
如果重写了equals方法,比较的是两个对象得到内容是否相等
如果没有重写equals方法,比较的是地址值是否相等
3 是否可以继承String类? 为什么用final修饰?
不能,String是final修饰的类,不能被继承
为了效率和安全
1.只有字符串是不可变的,字符串池才有可能实现
2.只有字符串是不可变的,所以多线程是安全的,同一个字符串实例可以被多个线程共享
3.因为字符串是不可变的,所以他在被创建的时候就已经被hashcode缓存了,不需要重新计算,使得字符串很适合做map中的键
4.如果字符串是可变的,会引起线程安全问题
4.什么是面向编程
面向编程是一种程序设计思想,该思想侧重于,考虑程序中有那些不同的对象,不同对象有那些属性和行为,以及对象之间的关系,面向过程,更加注重实现功能的步骤和顺序
面向对象的三大特征
继承,封装,多态
继承:子类继承父类可以使子类拥有父类所有属性和行为,还可以追加行为和属性,继承只支持单继承,不支持多继承,但支持多层继承。
封装:将事务的行为和属性抽取出来封装成一个类,从而提高了复用性
多态:父类引用指向子类实现,实现多态的前提条件,必须要继承重写向上转型三个条件
5.JDK JRE,JVM
JDK:开发者工具包,包含了JRE,JVM
JRE:开发环境,包含JVM和核心类库
JVM :虚拟机
6.Java基本数据类型
四类八种
整数型:byte short int long
浮点型:float double
布尔型:boolean
字符型:char
7什么是方法签名
答:方法的名称和参数列表组成 称为方法签名
8.Java中的访问修饰符
private default protected pubic
9.final有什么用?和finally,finalize有什么区别?
final是一个关键字,是最终的意思,可以修饰类,方法,变量,被final修饰的类不能被继承,被final的方法不能被重写,被final修饰的变量为常量,不能被重新赋值
finaliy:一般用于try-catch结构中,不管是否出现异常,finally的代码块都会被执行
finalsize:是object类中的方法,一般用在垃圾回收器中
10.this和super的区别
this:指对象本身
super:指自己最近的父类对象 又称为超类对象
this()调用的是本类的其他构造方法
super()调用的是父类的构造方法
面向对象的深刻理解
面向对象是一种编程思想,它侧重于考虑程序中有哪些对象,不同的对象有哪些不同的属性和行为,以及对象之间的关系,面向过程中,更加注重实现过程中步骤和顺序,面向对象有三大特征,继承,封装,多态
继承:子类继承父类,子类拥有父类所有的属性和方法,还可以追加属性和方法,继承只能单继承不能多继承,但可以多层继承,
封装:将事务的属性和方法抽取出来封装到类中,提高高代码的复用性
多态:父类应用指向子类对象,实现多态的 前提的三个条件,继承,重写,向上转型
JRE、JDK、JVM区别?
JDK 开发工具 JRE开发环境 JVM虚拟机
JDK1.8之前和JDK1.8之后定义接口不同?
JDK1.8之前接口可以定义抽象方法和静态常量
JDK1.8之后可以定义defaul方法和静态方法
接口和抽象类有何不同?
接口用interfase修饰,接口不能 实例化, 接口没有构造函数,,接口中没有main方法,一个类可以实现多个接口
抽象类用abstract修饰,抽象类不能被实例化,抽象类有构造函数,抽象类中可有使用main方法,一个类只能继承一个抽象类
final、finally、finalize区别,什么作用?
final 是一个关键字,是最终的意思,可以用来修饰类,方法,常态变量,被修饰的类不能被继承,被修饰的方法不能被重写,被修饰的常量不能被重新赋值,
finally用于异常处理,被finally包裹的代码块都会被执行
finalize是object中定义的方法,常用于垃圾回收器
局部变量和成员变量区别?
定义位置:局部变量定义在方法中,成员变量定义在类中方法外
作用范围不一样:局部变量自己能在本类中调用,成员变量分为静态变量和实例变量,静态变量所有的静态方法中都可以使用,实例变量在所有非静态方法中使用
生命周期不一样:局部变量随着方法的进栈而进栈,随着方法的结束而消失
成员变量分为实例变量和静态变量:
实例变量随着对象创建而生成,随着对象的消失而消失
静态变量随着类的加载而生成,随着类的加载结束而消失
值传递和引⽤传递区别?
基本数据类型存储的是数据本身,所以是值传递
包装数据类型存储的是对象地址,所以是引用传递
==和equals区别?
==是运算符,equals是方法,返回值都是duoble类型
== 可以判断基本数据类型也可以判断引用数据类型
判断基本数据类型,比较的时数据本身
判断引用数据类型,比较的时地址值
equals 默认比较的时地址值,如果重写的话比较的是数据本身
hashcode和equals的区别?
hashcode和equals都是object中的方法
hashcode是用来生成对象的哈希值的,不同的对象哈希值可能回相同
equals是用来比较两个对象是否相同的,不同对象的equals返回false
equals为true是哈希值一定相同,equals为false是有可能相同
重载和重写区别?
重载:在一个类中定义多个方法名相同,参数列表不同的方法
重写:在子类中声明父类的方法,参数列表都相同的方法
Java数据类型
四类八种
整数:byte short int long
浮点型:float double
字符:char
布尔类型:boolean
引用类型:类,接口、枚举、数据、注解
包装类和基本数据类型区别
概念:包装类是对基本数据类型的封装
1.声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间;
2、存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用;
3、初始值不同,基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null
4、使用方式不同,基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到。
5、包装类都是继承Number 接口实现Compareble 接口的
为什么要提供包装类
包装类可以通过该对象调用方法,可以拥有诸多的操作,而基本类无法调用方法,功能太弱
包装类和基本类型怎么转换
基本类型转化包装类型==装箱
包装类型转换为基本类型==拆箱
JDK1.5以后提供了自动的包装类和基本类型的转化,不需要调用上面的2个方法,自动装箱和拆箱
构造器代码块、局部代码块、静态代码块执⾏顺序和执⾏次数?
执行顺序
构造器代码块:对象被创建之前执行,优先于构造方法,如果类中有多个构造代码块,按照书写顺序执行
局部代码块:方法执行的时候执行,如果类中有多个局部代码块,按照书写顺序执行
静态代码块:当类加载的时候执行,如果类中有多个静态代码块,按照书写顺序执行
执行次数
构造器代码块:每次创建对象都会执行
局部代码块:每次调用方法都会执行
静态代码块:只执行一次
构造代码块的作用
用于抽取出构造方法中的公共部分、减少重复代码
Integer String 是否可以被继承?为什么?
不能,因为他们被final修饰
18.Integer缓存区间?什么时候触发缓存区间?
在integer类中定义了一个内部类,在IntegerCache中维护了一个Integer数组这个数组的范围是-128--127,自动装箱的时候会触发缓存区间
19.String str = "abc" 和 String str = new String("abc")区别?
如果常量池中没有 "abc",在常量池创建abc
new String则会在堆中创建一个对象,将常量池中的值复制过来
20.String、StringBuffer、StringBuilder区别?是否线程安全?怎么做的到线程安全?
String是只读字符串,并且被final修饰,不能被改变,StringBuffer和StringBuilder的字符串对象可以对字符串内容进行修改,在修改后的内存地址不会发生改变
String是不可变的字符串,线程安全,StringBuffer所有的方法都使用synchronized进行修饰,线程安全;
21.包装类型、Math,String类常⽤的⽅法有哪些?
Integer、Long、Byte、Short、Float、Double、Character…
Math:ceil、floor、abs、max、min、round
22.&和&& | || 区别是什么?
& | 即可以作为逻辑运算符又可以作为位运算符
&& ||只能作为逻辑运算符
22.JDK1.8之后有哪些新特性?
Lambda表达式 stream流, 接口增强 , 并行数组排序 Optional 新的时间和日期的API 可重复注解
23.Java中深克隆和浅克隆的区别?怎么实现?
浅克隆:是把原型对像中成员变量为值类型的属性都复制给克隆对象,把原型对象中成员变量为引用类型的引用地址也复制给克隆对象,原型对象中如果有成员变量为引用对象,则此引用对象的地址是共享给原型对象和克隆对象的,浅克隆只会复制原型对象,但不会复制它所引用的对象,
深克隆:是将原型对象中的所有类型,无论是值类型还是引用类型,都会复制一份给克隆对象,也就是说深克隆会把原型对象和原型对象所引用的对象,都复制一份给克隆对象,
24.Comparable 和Comparator的区别,分别说出使⽤场景?
Comparable排序逻辑必须在待排序元素的类中,也称为自然排序
Comparator排序的逻辑在另一个类中实现,也称为比较器排序
Comparable接口所在的包是lang 包,Comparator接口所在的包是util包
25.Object类和范型的区别,说出范型的执⾏机制,为什么要使⽤范型?
Objec是类,泛型是一种约束机制,确保在编译时不会出现类型错误,
不需要做强制类型转换
26.Error 和Exception 有什么区别?
Error 和Exception都是Throwable的子类
Error是程序无法处理的异常,Exception是程序可以处理的异常
27。什么是反射
反射是指在程序运行过程中动态的获取某一个类或对象的字节码,通过字节码的解析可以动态的获取该类或对象的详细信息,创建该类的对象,也可以修改某一个对象的属性信息
集合
Java中的常用容器有哪些
collection: List Set Queue
List: Vector ArrayList LinekdList
Set: Hashset Treeset
Queue: PriorityQueue ArrayDeque LinekdList
Map
HashMap TreeMap HashTable
Collection和Collections的区别
Collection是单列集合的顶层接口
Collections是这些集合的工具类,提供了操作这些集合的方法
HashMap是安全的吗?,如何得到一个线程安全的Map
不安全,调用Collection中的synchronizedMap方法
List和set的区别
List:元素有序,可以通过索引获取元素,允许有重复,底层是通过数组和链表实现
set:元素无序,不能通过索引获取元素,不允许重复,底层是通过二叉树和hash表实现
HashMap和HashTable的区别
HashMap线程是不安全的,HashTable线程是安全的
HashMap允许有Null键和Null值,HashTable没有
ArrayList和LinkedList的区别
ArrayList是动态数组数据结构实现的,查询快
LinkedList是双链表数据结构实现的,增删快
HashSet的实现原理
HashSet底层是HashMap,用key储存元素,value统一都是PRESENT
如何实现数组和List之间的转化
List转化为数组:调用Arrays中的toArray方法进行转换
数组转化为List:调用Arrays中的asList方法进行转换
ArrayList和Vector的区别
Vector线程是安全的,ArrayList不安全
ArrayList扩容是1.5倍,Vector默认扩容是2倍
Queue中的peek()和poll()方法有什么区别
peek()是查看头部队列,poll()是出队
Iterator和ListIterator的区别
ListIterator继承Iterator
ListIterator的方法比Iterator的方法多
ListIterator只能迭代List和其子类,Iterator可以迭代所有集合
HashMap底层数据结构是什么?1.7和1.8有什么区别?
1.8之前是数组+链表
1.8之后是数组加链表+红黑树
多了个红黑树
HashMap的resize过程是什么样的
采用hash表结构和链表,1.8之后引入了红黑树的数据结构,初始化数组长度为16,当数组长度到0.75时扩容,链表长度大于8时转为红黑树,红黑树的长度小于6时转为链表,数组中元素容量超过了阙值得0.75就会抽发扩容长度
HashMap的扩容机制
resize方法是在Hashmap中的键值对大于0.75 时或者初始化时,就调用resize方法进行扩容,每次扩容的时候,都是扩展2倍,扩展后Node对象的位置要么在原位置,妖魔移动到远偏移量两倍的位置
TreeSet怎么对集合中的元素进行排序?
TreeSet的底层时二叉树,
让元素本身具有比较性,让元素实现comparable接口
让集合自身具备比较性,需要定义一个比较器进行排序
什么时链表,链表的优缺点
链表是可以将物理地址上不连续的数据连接起来,通过指针来对物理地址进行操作,实现增删改查等功能
优点:增删速度快,内存利用率高,拓展灵活
缺点:查找效率低
什么是红黑树
红黑树是一种含有红黑节点并能自平衡的二叉查找树,
1.每个节点要么是黑色,要么是红色
2.根节点是黑色
3.每个叶子节点是黑色
4.每个红色节点的两个子节点一定是黑色
5.任意一节点到每个叶子节点的 路径都包含数量相同的黑节点
遍历一个list有哪些方法
for循环遍历,迭代器遍历, foreach循环遍历
HashSet如何检查重复?HashSet是如何保证数据不可重复的?
向HashSet中添加元素是,判断元素是否存在,不仅要比较Hash值,同时还要结合equles方法比较
HashSet中添加数据的方法会使用HashMap的put方法,
HashMap的key是唯一的在HashMap中如果k/v相同时,会用新的v覆盖旧的v,然后返回旧的V,所以不会重复
HashMap的实现原理
HashMap是基于hash算法实现的
当我们往HashMap中put元素时,利用key的hashCode重新hash计算出当前对 象的元素在数组中的下标 。计算key时,有可能会先两种情况,一是key之前 是存在的,则覆盖原始值;第二是key不同则将当前的key-value放入链表中
获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值
HashMap如何解决hash冲突
核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。 需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,数据长度低于6之后会退化为链表
为什么HashMap的初始长度是16
因为长度太小很容易导致map扩容影响性能,如果分配的太大的话又会浪费资源,所以就使用16作为初始大小
Mybatis
Mybatis中${} 和#{}有什么区别?
#{}事预编译处理,${}是字符串替换,没有预编译处理,
#{}可以有效防止sql注入,提高系统安全性,${}不能防止sql注入
#{} 的变量替换是在数据库系统中; ${} 的变量替换是在 数据库系统外
Mybatis如何执行批量插入?
循环插入
foreach插入
ExecutorType.BATCH插入
Mybatis如何在插⼊后获得主键 ?
在insert标签中设置三个属性
eGeneratedKeys="true" keyProperty="id" keyColumn="id"
Mybatis中resultmap是做什么的?、
对查询的结果进行自定义映射
它主要解决字段名称和程序中的属性名不同的情况,可使用 resultMap 配置映射;
⼀对⼀和⼀对多关系可以使用 resultMap 映射并查询数据
Mybatis中resulttype和resultmap区别?
如果查询结果只是返回一个简单类型,比如返回String或int,那么可以使用resultType
如果数据库表的字段名和实体对象的属性名不一样时,可可以使用resultmap;
如果使用resultType,需要给表字段起别名
mybatis都有哪些 Executor 执行器?它们之间的区别是什么?
SimpleExecutor,ReuseExecutor,BatchExecutor
mybatis⼀级缓存和二级缓存?
一级缓存基于 HashMap 本地缓存,其作用域为Session,默认是开启的
二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的语句,多个SqlSession可以公用二级缓存,二级缓存与一级缓存其机制相同,默认也是采用 HashMap 存储,其作用域是Mapper,需要手动开启
动态sql的常⽤标签,动态sql的执⾏原理 ?
Mybatis提供了9种动态sql标签
trim |where |set oreach |if |choose |when |otherwise |bind
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此 来完成动态sql的功能。
Mybatis是否支持延迟加载,延迟加载的原理是什么?
mybatis仅支持关联对象一对一查询和一对多查询得延迟加载
使用CGLIB为目标对象建立代理对象,当调用目标对象的方法时进入拦截器方法
分页插件的原理是什么 & Mybatis如何编写一个自定义插件?
可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件, 在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
Spring
什么是Spring框架
Spring是一个基于Java开发得框架,用于简化Java开发,有三个核心组件,IOC AOP DI
对IOC的理解
IOC控制反转,将对象得创建权反转,让spring帮我们创建对象,并存到容器中
对Aop的理解
AOP 面向切面编程,在不改变原始的代码的基础对方法进行功能增强
切⼊点、通知、连接点、切⾯是什么
连接点:可以进行功能增强的方法
切入点:已经进行了功能增强的方法
通知:共性功能
通知类:通知所在的类
切面:切入点+通知就是通知
springAOP代理方式有几种,怎么配置,实现原理是什么
JDK动态代理:目标类必须实现一个接口
CGLIB动态代理:目标类不能是最终类
spring常用的注解
定义bean: @Component @Controller @Service @Repository
依赖注入:@Autowired @Qualifier @Resource @Value
定义第三方bean:@Bean
配置类注解:@Configuration @Import @PropertySource @ComponentScan
bean的作用范围和生命周期:@Scope @PostConstruct @PreDestroy
@Autowied和@Qualifier,@Resource区别
@Autowied是按类型注入
@Autowied和@Qualifier是根据id加入
@Resource=@Autowied+@Qualifier
BeanFactory和ApplicationContext有什么区别
BeanFactory是顶层接口,ApplicationContext是派生接口
BeanFactory是懒加载,用的时候才会创建bean,内存不足时,可以使用BeanFactory
ApplicationContext默认实在容器初始化的时候就加载所有的bean
spring BeanFactory和FactoryBean区别
BeanFactory是Sping的容器,FactoryBean是一个特殊的bean,用于创建bean,创建出来的bean都会放到容器中
简述spring bean的生命周期(简版)
BeanDefinition -> 实例化 -> 依赖注入 -> 初始化 -> 放到容器中使用 -> 销毁
1. 先通过配置文件或者注解拿到所有的BeanDefinition,并放到BeanDefinitionMap中
2. 从BeanDefinitionMap中拿到bean定义并进行实例化 new
3. 依赖注入,给容器中bean中的属性赋值
4. 初始化,给属性赋值
5. 初始化完成后,bean真正创建完成,就可以把bean放到Spring容器中,ConcurrentHashMap,我们使用的时候就可以通过getBean来获取bean
6. 容器销毁的时候,bean也会跟着销毁
spring支持的bean作用域
singleton:单例模式,在整个Spring IoC容器中,使用 singleton 定义的 bean 只有一个实例
prototype:原型模式,每次通过容器的getbean方法获取 prototype 定义的 bean 时,都产生一个新的 bean 实例
Spring框架中的单例Bean是线程安全的么
不安全。但是Spring中的bean是无状态的,也就是不存储数据,所以某种程度上来讲是线程安全的。
怎么解决线程安全问题?
1.把bean的作用域改为非单例 prototype
2.把共享变量放到ThreadLocal中,ThreadLocal是线程私有变量,线程间隔离,也可以解决线程安全问题
spring如何保证⾼并发下Controller线程安全