基础概念
-
什么是JDK,JRE,JVM?
答:JVM又称为java虚拟机,可以识别.class文件,也是java可以实现跨平台性得关键
JRE又称为java运行时环境,拥有JRE就可以运行java程序
JDK又称为java开发工具包,拥有JDK你就可以写java程序
简单来说JDK=JRE+java开发的一些小工具,JRE=JVM+java类库,JVM=java虚拟机 -
java的跨平台性如何实现?
答:平台一般指的是各种操作系统,跨平台就是说java程序可以在不同操作系统上运行,而其原理就是,.java文件经过java编译器编译,就会形成.class文件,而.class文件可以在jvm上运行,jvm可以安装在不同平台上,这样就实现啦java的跨平台性 -
java语言的健壮性(这个问的比较少)
答:健壮性主要体现在以下3点:java语言是强类型语言;java语言有自动的垃圾回收机制;java语言设计啦异常处理机制 -
java8种基本数据类型及其默认值
数据类型 | 字节数及其默认值 |
---|---|
byte | 1字节,默认值0 |
short | 2字节,默认值0 |
char | 2字节,默认值空 |
int | 4字节,默认值0 |
long | 8字节,默认值0L |
float | 4字节,默认值0.0f |
double | 8字节,默认值0.0d |
boolean | 1字节或者4个字节,默认值false |
-
什么是不可变对象?
答:对象一旦被创建,状态就不能再发生改变,例如:String,Integer还有其他包装类(被final修饰的对象----不可变对象) -
一个.java文件中可以有几个类?
只能有一个被public修饰的类,其他的类可以被default修饰 -
内部类的分类和作用
成员内部类:与成员变量相似,可以访问外部类的所有成员属性和成员方法(静态和private修饰的也可以)
局部内部类:定义在一个方法或者一个作用域中,它的访问仅限于方法内或者该作用域内
匿名内部类:就是没有名字的内部类,适合用于创建那些仅需要一次使用的类
静态内部类:被static修饰的内部类,它可以访问静态成员变量和静态方法(包括被private修饰的),静态内部类属于外部类本身,但是不属于外部类的任何对象 -
instanceof方法的作用?
答:a instanceof ClassA,主要用于判断a是否是ClassA的实例,如果是返回true
面向对象
-
面向对象的特性
答:
封装:具体表现为属性私有化,方法公开化
继承:具体表现为子类继承父类非私有的属性和方法
多态:提高啦代码的扩展性,让代码有啦可替代性,降低耦合性,条件:发生在父子类之间,子类重写父类方法,父类引用指向子类对象
抽象:具体表现为抽象类和接口 -
子类是否可以重写父类的private方法?
答:子类并不能重写父类的private方法,因为子类根本看不到,但是子类可以写一个和父类一样的方法,但这不叫做重写 -
子类是否可以重写父类的static方法?
答:首先明确重写是基于对象的,而被static修饰的方法是属于类的,所以子类不能重写父类的static方法 -
重写与重载的区别
答:
一.重写发生在父子类中,重载发生在同一个类中;
二.子类重写父类的方法,子类中的方法方法名,参数列表,返回类型必须相同,重载要求方法名相同,参数列表不同(判断重载的唯一标准就是参数列表不同,与返回类型无关)
三.重写和重载都是多态的体现,重写是运行时的多态性,重载是编译时的多态性 -
重写的一些规矩
答:
访问权限应该比父类被重写的方法大或者相等
子类重写方法只能抛出比父类方法小的异常或者不抛出异常 -
如何理解java中的构造函数,以及构造函数的重载?
答:构造函数的主要作用就是初始化,使用构造方法创建对象并且可以为类中的属性赋值(实例化对象),构造函数的重载与普通方法的重载一样 -
接口和抽象类的区别
一.接口中的方法全部都是抽象方法,而抽象类中可以有非抽象方法(甚至可以没有抽象方法)
二.接口中的成员变量修饰符默认是"public static final",抽象类中的成员变量修饰符可以是任意
三.一个类可以实现多个接口,但只能继承一个抽象类
四.一个类实现一个接口后,必须重写该接口全部抽象方法;一个类继承一个抽象类,可以不重写其抽象方法,但该类必须也为抽象类 -
虚拟机是如何实现多态的?
简单来说,动态绑定技术,执行代码期间虚拟机会判断该对象的实际类型,根据实际类型调用相应的方法 -
java创建对象的方式?(一般很少问)
答:new,反射,clone,序列化机制 -
父子类中,有代码块,静态代码块,构造方法,静态变量,变量,执行顺序
答:
父类中的静态变量和静态代码块
子类中的静态变量和静态代码块
父类的变量和代码块
父类的构造方法
子类的变量和代码块
子类的构造方法
注:其中变量和代码块的顺序与声明顺序有关(静态同理)
修饰符
- public,protected,default,private
修饰符 | 作用范围 |
---|---|
public | 类内部,本包,子类,外部包 |
protected | 类内部,本包,子类 |
default | 类内部,本包 |
private | 类内部 |
-
static环境中是否可以访问非static变量?
答:不可以,被static修饰的方法,属性,代码块都属于类,随着类的加载而加载,而非static变量属于对象,在对象创建时,才被创建,所以在static环境准备就绪时,非static变量不一定被创建啦 -
final的作用?
修饰类,该类不能被继承
修饰方法,该方法不能被重写
修饰变量,如果修饰的是基本数据类型,该变量不能再改变,如果修饰的是引用类型,则在对其初始化之后便不能再让其指向另一个对象,但引用值可变
容易混淆的问题
- try语句中存在return,finally中的语句在何时执行?
答:finally中的语句是在return的过程中执行的,在执行到return语句时,将返回值存储到栈中,之后执行finally(如果finally中也有return语句,那么将返回finally中return的值),之后再执行return语句,结束方法
public class Test1 {
public void tryReturn() {
int a = 0;
try {
System.out.println("try");
return;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
}
}
public static void main(String[] args) {
Test1 test = new Test1();
test.tryReturn();
}
}
此时控制台会输出try finally,证明try中有return,finally中语句也会执行
public class Test1 {
public int tryReturn() {
int a = 0;
try {
System.out.println("try");
return a;
} catch (Exception e) {
System.out.println("catch");
} finally {
System.out.println("finally");
a = 3;
return a;
}
}
public static void main(String[] args) {
Test1 test = new Test1();
System.out.println(test.tryReturn());
}
}
此时控制台会输出 try finally 3,证明如果try,finally中都有return语句,最后返回值为finally中的
2. java中的内存结构
这里之说几种比较常见的:
一.栈:存放局部变量和对象的引用
二.堆:简单来说存放new出来的东西,比如对象的实例,还是垃圾收集器管理的主要区域
三.方法区:主要存储类的一些信息,常量,静态变量,方法区中的重要组成部分是常量池
3. java的值传递
java中只存在值传递
值传递和引用传递的区别,在于会不会创建一个副本,如果创建啦副本那就是值传递,如果没有就是引用传递
首先在传递基本类型数据时,大多数人都没有疑问,一定是值传递,但对于引用类型很多人有疑惑,认为引用类型就是引用传递,其实不是的引用类型传递的是引用的地址,并不是引用本身
这里不做详细解释,推荐一个博客吧引自程序员小灰
4.String的内存解析
public class Test2 {
public static void main(String[] args) {
String str1 = "123";
String str2 = "123";
String str3 = new String("123");
String str4 = new String("123");
Student student = new Student("123",1);
System.out.println(str1==str2);//true
System.out.println(str3==str4);//false
System.out.println(str1==str3);//false
System.out.println(str1==student.getName());//true
System.out.println(str3==student.getName());//false
}
}
下面先看一张图片:
str1==str2:在java中= =比较的是地址值,str1和str2都直接指向常量池中的“123”,所以地址值相同,true
str3==str4:str3,str4创建时都是new出来的,所以他们的实例都在堆中,str3,str4都分别指向他们的实例,false
str1==str3:str1直接指向字符串常量池中的“123”,而str3则是指向堆中的实例,实例才指向字符串常量池中的“123”,false
str1==student.getName():str1直接指向字符串常量池中的“123”,student指向堆中的实例,但是student.getName()直接指向字符串常量池中的“123”,true
str3==student.getName():student.getName()直接指向字符串常量池中的“123”,而str3则是指向堆中的实例,实例才指向字符串常量池中的“123”,false
5. “==”和equals的区别?
答:==对于基本数据类型来说,比较的是值,而对于引用类型,比较的是引用地址
equals在没有重写之前和= =是一样的,如果该类(String,Integer)重写啦equals方法,那么无论引用类型还是基本数据类型比较的都是值
6.两个对象的hashCode()相同,那么equals()也相同?
答:两个对象的hashCode()相同,equals()不一定相同
一般来说重写一个类的equals()方法,一定会重写hashCode()方法,如果两个都进行啦重写,那么是相同的,但如果只重写equals()方法,不重写hashCode()方法,会导致不相同
7.Math. round(-1. 5)和Math. round(1. 5)?
答:简单记法:正数4舍5入,负数5舍6入
8.String、StringBuffer、StringBuilder的区别?
答:每次操作String都会重新创建一个String对象,然后更改引用指向新的String对象,而StringBuffer和StringBuilder是在原有对象基础上进行修改,但StringBuffer是线程安全的,StringBuilder不是线程安全的,但StringBulider效率更高
9.switch中可以使用的数据类型?
byte,short,char,int,String,还有Enum(枚举)类型
10.会不会存在两个对象的equals相同,hashcode()不相同?
答:会存在,叫做hash冲突,一般的解决方案有以下几种:拉链法,开放定址法,双哈希法,此处对这3中方法不做详解
11.如何退出多层嵌套循环?
答:运用标识符和break;
12.深拷贝与浅拷贝
深拷贝会拷贝该对象和该对象所引用的对象,而浅拷贝只会拷贝该对象
13.String的intern()方法
String中的intern()是一个native方法,此方法会先从常量池中寻找是否存在该字符串,如果存在就直接返回该字符串的引用,如果不存在就在常量池创建,再返回其引用
14.如何解释0.1+0.1+0.1= = 0.3为false
在java中0.1默认为float类型,而float类型在计算时会有精度缺失,所以为false,同理还有0.1*3!=0.3
15.a=a+b与a+=b有什么区别?
答:区别在于a+=b会进行隐式自动类型转换,同样的问题short a =1;a=a+1;就会报错,但是a+=1就不会报错
16.泛型
一般来说泛型使用在容器上比较多,但是也可以使用在类,接口,方法上,需要注意的是泛型只在编译时有效,泛型的类型只能是引用类型,不能是基本类型,并不是泛型类中的方法就是泛型方法,泛型方法public <T> void 方法名(T t){}
,而public T 方法名(){}
并不是泛型方法,只是使用啦泛型类中的泛型而已
17.泛型的上下边界
可以使用extends来定义上界,用super来定义下界,比如:<? extends E>,<? super E>
关于泛型详情可以看一下VieLei的博客
18.如何通过空白字符串拆分字符串?
空白字符"\s"
tab制表符"\t"
换行"\n"
回车"\r"
但是,使用String中的split()方法,需要变成"\s"
String strs[] = str.split("\\s");
19.字符和ASC码互相转换
字符---->ASC :(int)‘a’
ASC---->字符:(char)97