本篇答案为个人搜集,欢迎指正
一、Java基础
1、Java基本数据类型
四种整数类型(byte、short、int、long),两种浮点数类型(float、double),一种字符类型(char),一种布尔类型(boolean)
8位:Byte(字节型)
16位:short(短整型)、char(字符型)
32位:int(整型)、float(单精度型/浮点型)
64位:long(长整型)、double(双精度型)
2、原始数据类型(值类型)和封装类(引用类型)的区别
Java中包含三种引用类型:数组,类,接口
值类型的变量存放在栈里;引用类型的地址保存在栈中,数据保存在堆中。
引用类型的缺省值为null,原始数据类型的与类型有关
byte int short 为0 long为0L
float 0.0f double 0.0d
注意 Integer创建的数值如果在[-128,127]之间,将不会创建新对象
所以
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1==i2);//true
3、String、StringBuffer、StringBuilder区别
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,
即String对象一旦创建之后该对象是不可更改的,
但后两者的对象是变量,是可以更改的。
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
4、运行时异常和非运行时异常区别
所谓的异常就是阻止当前程序或方法继续执行的问题。
java异常分为两种:运行时异常(RuntimeException)和非运行时异常(CheckedException)也叫检查式异常。
运行时异常都是RuntimeException类及其子类异常,比较常见的有:
NullPointerException(空指针异常)、
IndexOutOfBoundsException(下标越界异常)
ArrayIndexOutOfBoundsException (数组下标越界异常)
ArithmeticException (算术运算异常)
非运行时异常,常见的有:
IOException、FileNotFoundExcetion 和SQLException
区别:
1.运行时异常是不需要捕获的,程序员可以不去处理,当异常出现时,虚拟机会处理。
2.非运行时异常就必须得捕获了,否则编译不过去,java编译器要求程序员必须对这种异常进行catch,Java认为Checked异常都是可以被处理(修复)的异常,所以Java程序必须显式处理Checked异常。
5、简述一下面向对象的特征,并举例说明你对面向对象的理解
1)继承:继承是从已有类得到继承信息创建新类的过程,提供继承信息的类为父类(超类),得到继承信息的类被称为子类(派生类),提高了软件的可重用性和可扩展性。
2)封装: 封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,
在面向对象的编程语言中,对象是封装的最基本单位,面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同一个对象中的属性。
3)多态性:允许不同的子类对同一消息做出不同的响应.分为编译时多态和运行时多态.
方法重载overload为编译时的多态(前绑定) 不同的参数列表 相同的方法名
方法重写override为运行时的多态(后绑定) 相同的参数列表和方法名,不同的方法体
4)抽象是将一类对象的共同特征总结出来构造类的过程,数据抽象,行为抽象
6、正则表达式的用法
太复杂了,列举几个常用的:
//用户名正则,4到16位(字母,数字,下划线,减号)
^[a-zA-Z0-9_-]{4,16}$
//密码正则,以字母开头,长度在6~18之间,只能包含字符、数字和下划线
^[a-zA-Z]\w{5,17}$
7、Java 语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别代表什么意义?
finally代码是在return之后还是之前执行?
throw是语句抛出一个异常。
语法:throw (异常对象);
throw e;
throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}
public void doA(int a) throws Exception1,Exception3{......}
try的代码块如果产生了对应的catch()内声明的异常,则执行catch内代码块作为异常的处理,
finally代码块表示无论是否发生异常,一定会执行,并且是在return之前执行.
8、abstract class和interface有什么区别?接口可以继承接口吗?接口可以继承抽象类吗,为什么?
abstract class抽象类和interface接口的区别是:
抽象类中可以写实现的方法,接口中不可以写实现方法.
接口可以继承接口,不可以继承抽象类
因为抽象类中可能有已经实现的方法.
9、构造器(constructor)是否可被重写(override)?
Constructor(构造器)不能被继承,所以不能被override(重写),但是可以被overloading(重载)。
构造器就是构造方法,能够被重载(同类中不同参数列表),不能够被重写(子类使用super方法可以调用)。并且子类的构造方法第一行默认调用父类构造方法.
10、是否可以继承String类?
不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。
11、Java 中的final关键字有哪些用法?
总体上来说,final指"不可变"
1 变量 final变量意味着它是一个常量,只能赋值一次,赋值后不再改变.可以先声明后赋值
如果是基本类型变量的话,值不可变,如果是引用类型变量的话,它的地址是不可变的,但是地址指向的值可变
2.修饰方法参数
传入方法的参数可以用final修饰,尤其是当我们写匿名内部类时,形参必须加final,因为匿名内部类的生命周期有可能是比外部类长的(当一个生命周期很长的类调用了它之后),此时传入的形参就有可能不存在,所以加上final之后,这个变量被保存了一份,避免了拷贝后产生不一致的问题.jdk1.8解决了这个问题,不再需要加final
3.修饰方法
它表示该方法不能被覆盖。这种使用方式主要是从设计的角度考虑,即明确告诉其他可能会继承该类的程序员,不希望他们去覆盖这个方法。
private修饰的方法默认final
另外,如果父类内部有 private final的方法,子类是可以写同名同列表的方法的,此时不是方法复写,因为两个类互相不知道对方有这个方法.
4.修饰类
用final修饰的类是无法被继承的。
用final修饰方法和类的情况比较少,因为这样阻碍了程序的拓展
12、try{}里有一个return语句,那么紧跟在这个try后的finally{}里的代码会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行
13、阐述final、finally、finalize的区别。
final
用于修饰类、成员变量和成员方法。final修饰的类,不能被继承(String、StrngBuilder、StringBuffer、Math,不可变类),其中所有的方法都不能被重写,所有不能同时用abstract和final修饰(abstract修饰的是抽象类,抽象类是用于被子类继承的,和final起相反的作用);final修饰的方法不能被重写,但是子类可以用父类中final修饰的方法;final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象中的内容是允许改变的。
finally
finally是对Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
finalize
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
14、如何通过反射创建对象?
通过反射来生成对象有两种方式:
1、通过Class对象的newInstance()方法来创建Class对象对应类的实例。这个方法是使用Class对象对应类的默认构造器创建对象,这就要求Class对象对应类必须要有默认构造器。
Class c=Class.forName("java.lang.String");
String s=(String)c.newInstance();
2、使用Class对象获取指定的Constructor对象,调用Constructor对象的newInstance()方法来创建Class对象对应类的实例。这个方法可以使用Class对象对应类的任意指定的构造器来创建实例。
通过类对象的getConstructor()或getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象,例如:String.class.getConstructor(String.class).newInstance("Hello");
15、Java 8的新特性
一、Lambda表达式
二、接口的默认方法与静态方法
三、方法引用
四、重复注解
五、扩展注解的支持
六、Optional
七、Stream
八、Date/Time API (JSR 310)
九、JavaScript引擎Nashorn
十、Base64
16、Java数组和链表的两种结构的操作效率
数组一旦初始化,长度就不能改变。链表长度可以改变,可以动态的增加节点数据,操作比较灵活;
数组是可以有一维二维三维。。。属于非线性结构,链表是线性结构;
数组访问元素依靠下角标,时间复杂度是O(1)。链表访问元素得从头开始依次查找,根据引用找到下一个节点,时间复杂度是O(n);
数组增删中间数据比较麻烦,时间复杂度是O(n)。链表增删比较方便,时间复杂度是O(1);
数组在栈内存中存储引用,在堆内存中存储对象。链表存储在堆内存中,由于存储在堆内存中,需要手动分配内存;
数组在内存中是连续存储的,链表不是连续的
17、Java的引用类型有哪几种
引用类型分为:数组,类,接口,字符串。
数组:其实就是一个容器,存储同一种数据类型的集合;如 int[] a = {1,2,3,4}
类:对象是对事物的抽象,而类是对对象的抽象和归纳;如 public class Person{ ......}
接口:使用interface来定义一个接口,只能定义方法,不能有方法的实现;如public interface personImpl{......}
字符串:是存放数据区(静态区)以Unicode编码的字符集合,如 String a="你好"