1.Java中虚拟类和接口的区别
抽象类和接口是支持抽象类定义的两种机制
抽象类被关键字abstract修饰,类中有abstract修饰的方法就是抽象方法,所属类就是抽象类。
接口被关键字interface修饰,接口是抽象方法的集合,如果一个类实现了某个接口,那么他就要实现该接口的抽象方法。
使用时机:
遇到多种属性和方法复用的时候,使用抽象类,(某种属性);当定义多个方法时,使用接口 ( 某种行为)。
2.多线程
Java中线程的实现方式
在Java中多线程的实现有两中方式,一种是继承Thread类,另一种是实现Runnable接口,
3.wait和sleep区别
两个方法分别来自Object和Thread,
sleep方法没有释放锁,wait方法释放锁,使得其他线程可以使用同步控制块或者方法,
sleep必须捕获异常,wait,notify,notifyall 不需要
sleep可以在任何地方使用,wait,notify,notifyAll 需要在同步控制块或者方法中使用,
4.值传递和引用
引用传递本质上就是值传递,将引用变量的值传递给形参,因为引用变量的值存放的是地址值,所以当地址值传递给形参后,形参和实参指向同一块内存区域。
5. == 和 equals的区别
== 操作符用来比较两个变量的 值是否相等,用于比较两个所对应的内存中所存储的数值是否相等,比较两个基本类型的数据集或者两个引用变量是否相等
equals用于比较两个独立对象的内容是否相同。
6.静态变量和实例变量的区别
语法上:静态变量前需要static 关键字,实例变量则不加,
运行时:实例变量属于某个对象的属性,需要先创建实例对象,其中的实例变量才会分配空间,才能使用这个实例变量。静态变量是类变量,程序只要加载了类的字节码,静态变量就会被分配到方法区,实例变量是分配到堆中。
7.深拷贝和浅拷贝的区别是什么?
浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象,换言之,浅拷贝仅仅复制所考虑的对象,而不复制他所引用的对象。
深拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而那些引用其他对象的变量将指向被复制的新对象。而不再是原有的那些被引用的对象,换言之,深拷贝把要复制的对象所引用的对象都复制了一遍。
8.final有哪些用法?
被final修饰的类不可以被继承
被final修饰方法不可以被重写,jvm会尝试将其内联,以提高运行效率
被final修饰的变量不可以被改变,
被final修饰的常量,在编译阶段会存入常量池中。
9.基本数据类型和所占字节
Java中有八种基本数据类型,分别为:byte(1)、short(2)、int(4)、float(4)、long(8)、double(8)、char(2)、boolean(1)。
这八种基本类型都有对应的包装类,分别为:Byte、Short、Integer、Long、Float、Double、Character、Boolean。
10.TestNG 中注解的执行顺序
@BeforeSuite->@BeforeTest->@BeforeClass->{@BeforeMethod->@Test->@AfterMethod}->@AfterClass->@AfterTest->@AfterSuite
11. 封装、继承、多态 java三大特性。
封装和继承几乎都是为多态准备的。
封装
信息(属性)隐藏,把数据和基于数据的操作封装起来,使其成为一个不可分割的整体,数据隐藏在抽象数据内部,尽可能隐藏数据细节,只保留一些接口使其与外界发声联系。
封装的实现:修改属性的访问控制符,创建gettersetter方法,在gettersetter方法中加入属性控制语句。
属性(成员变量)随对象存放在堆中。
优点:将属性隔离,便于使用,提高重用性,提高安全性
缺点:增加属性访问步骤
继承
关键字 extends
多个类具有共同的属性(成员变量)与行为(成员方法)的时候,将这些共同的部分提取出来定义到一个公共的类中,其他及各类可以与这个公共的类形成继承关系,从而在多个类中不需要重复定义公共部分,这个类就是父类,也称作超类或者基类,其他的类就是子类。子类可以直接访问父类的非私有化成员变量,super.get()方法。
继承是类与类的一种从属关系。java是单继承的,也就是一个子类只有一个父类。
优点:减少代码量,提高复用率;使类与类之间存在继承关系,是实现多态操作的前提。
缺点:一个类存在多个子类的时候,如果父类发生变化,那么这些子类会跟着一同变化,造成类与类之间的“强耦合”关系。
多态
多态指的是对象的多种形态
多态有两种:引用多态和方法多态,继承是多态的实现基础。
多态的前提:
1.必须有子类和父类,具有继承或实现(继承)
2.子类必须重写父类的方法(重写)
3.父类的引用变量指向子类的对象(向上转型)
优点:
1.可替换性,多态对已存在的代码具有可替代性
2.可扩充性,增加的子类不影响已存在的类的特性的运行和操作
3.接口性,超类提供一个公共的接口,子类来完善或者覆盖它二实现的
4.灵活性,提高了使用的效率
5.简化性,对应用软件的代码的编写和修改过程,尤其在处理大量的运算和操作时,这个特点尤为突出和重要
缺点:
只能使用父类的引用访问父类成员。
12.重写,重载
重写是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能变。即外壳不变,核心重写。
好处在于子类可以根据需要,定义特定于自己的行为。子类根据需要实现父类的方法。
重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
规则: 参数列表与别重写方法的参数列表必须完全相同。
返回类型与被重写方法的返回类型可以不相同,但必须是父类返回值的派生类。
访问权限不能比父类中别重写的方法的访问权限更低。
final 声明的不能被重写
static声明的不能被重写,但是能够再次声明。
构造函数不能重写
重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
每个重载的方法(或者构造方法)都必须有一个独一无二的参数类型列表
规则: 被重载的方法必须改变参数列表,
被重载的方法可以改变返回类型,
被重载的方法可以改变访问修饰符,
方法能够在同一个类中或者在一个子类中被重载。
12.String StringBuilder StringBuffer
String StringBuilder StringBuffer 三个内部实现都是通过char[] 数组,不同的是String的char[] 数组是通过final修饰是不可变的,StringBuilder StringBuffer 是可变的
String 固定字符串, StringBuilder StringBuffer 可变字符串,都继承了AbstractStringBuilder。
StringBuilder 在扩容的时候,新的字符数组容量是原来的2倍再加2,然后通过System.arrCopy()函数复制内容到新的数组,假设两个线程同时执行了append(),就有可能
出现ArrayIndexOutOfBundsException().
StringBuffer 重写父类append(),使用synchronized 修饰 ,线程同步。
GC 垃圾回收
JVM中垃圾回收机制最基本的做法是分代回收。内存中的区域被划分成不同的世代,对象根据其存活时间被保存在对应世代的区域中。一般的实现是划分成3个世代:年轻,年老和永久代。所有新生成的对象优先放在年轻代的(大对象可能被直接分配在年老代,作为一种分配担保机制),年轻代按照统计规律被分为三个区:一个Eden区,两个Survivor区。在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此可以认为年老代中存放的都是一些生命周期较长的对象。
方法区也被称为永久代,用于存储每一个java类的结构信息:比如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容以及类,实例,接口初始化时需要使用到的特殊方法等数据根据虚拟机实现不同,GC可以选择对方法区进行回收也可以不回收。
对于不同的世代可以使用不同的垃圾回收算法。比如对于年轻代存放的对象多事朝生夕死,因此可以采用标记-复制,而对于年老代则可以采用标记-整理/清除。
Minor GC
发生在新生代的GC为Minor GC。在Minor GC时会将新生代中存活着的对象复制进一个Survivor中,然后对Eden和另一个Survivor进行清理,所以,平常可用的新生代大小为Eden的大小加一个Survivor的大小
Major GC
在年老代中的GC则为Major GC
Full GC
通常是和Major GC等价的,针对整个新生代,年老代,元空间metaspace的全局范围的GC
线程
线程创建的方式?他们有什么区别?
通过实现java.lang.Runnable 或者通过扩展 java.lang.Thread类,相比扩展Thread,实现Runnable接口可能更优,原因:
1.java不支持多继承,因此扩展Thread类就代表这个子类不能扩展其他类,而实现Runnable接口的类还可能扩展另一个类。
2.类可能只要求可执行即可,因此继承整个Thread类的开销过大
Thread类中的start()和run()方法的区别
在start()方法中最重要的是调用了Native方法start()用来启动新创建的线程,线程启动后会自动调用run()方法,如果直接调用
其run()方法就和我们调用其他方法一样,不会在新的线程中执行。
集合
1.ArrayList和Vector的区别
都实现了List接口(List继承了Collection接口)
Vector是线程安全的,它的方法之间是线程同步的,而ArrayList是线程不安全的,它的方法之间是线程不同步的。
2.HashMap和HashTable的区别
HashMap线程不安全,Hashtable线程安全
HashMap允许null值(键值可以为null),Hashtable不允许null值(键值不可以为null)。
3.List和Map的区别
List集合是单列集合,Map集合是双列集合,通过key value
List集合是有序集合,Map集合是无序集合。
List用户可以对列表中每个元素插入位置进行精确地控制。
框架
1.说说spring
spring核心是控制反转(ioc)依赖注入(DI),相当于把bean与bean之间的关系交给第三方容器spring进行管理。aop面向切面编程,允许程序模块化横向切割关注点,如日志和事务管理。
2.spring优点和缺点
spring优点:1.降低组件之间的耦合,实现软件各层间的解耦。
spring缺点:反射多,影响性能。
3. @Autowired 和 @Resource 区别
@Resource和@Autowired都是做bean的注入时使用
相同点:
两者都可以写在字段或setter方法上,如果都写在字段上,那儿就不需要再写setter方法。
不同点
@Autowired 时Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照ByType注入。
@Autowired 是按照类型装配依赖对象,默认情况下他要求依赖对象必须存在,如果允许null值,可以设置他的required属性为false,如果想用按照名称byName来装配,可以结合@Qualifier注解一起使用,
@Resource默认按照名称byName自动注入,由j2ee提供,需要导入javax.annotation.Resouce.@Resource有两个重要的属性:name和type,
注:最好是将@Resource放在setter方法上,因为这样更符合面向对象的思想,通过set get区操作属性,而不是直接区操作属性。
@Resource装配顺序:
如果同时指定name和type,则从spring上下文中找到唯一匹配的bean进行安装,找不到则抛出异常。
如果指定了name,则从上下文中查找名称匹配的bean 进行装配,找不到则抛出异常。
如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
数据库
1.Mybatis中#{}和${}区别
#{}是预设值,不会引起sql注入,${}容易被sql注入。
Http
1.http get和post的区别
get:传参是通过url传输,大小限制2kb,安全级别差
post:传参是通过form的action方式提交到服务器,基本无大小限制,安全级别高于get,隐藏提交url参数
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只会进行url编码,而POST支持多种编码方式。
GET请求会被完整保留在浏览器历史记录里,而POST的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST没有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
http协议组成
1.请求报文(请求行/请求头/请求体)
请求行 :请求方法(get/post/put/delete) url字段 和 http版本协议
例如:GET /index.html HTTP/1.1
请求头:(key-vlue形式)
User-Agent:产生请求的浏览器类型。Accept:客户端可识别的内容类型列表。Host:主机地址
请求数据:
post、put 方法中,数据已keyvalue形式发出请求
空行
2.响应报文
状态行(200,404,500)