1,JDK,JRE,JVM有什么区别?
JDK:Java Development Kit,
Java开发工具包,提供了Java的开发环境和运行环境。包含了编译Java源文件的编译器Javac,还有调试和分析的工具。
JRE:Java Runtime Environment,Java运行环境,包含Java虚拟机及一些基础类库
JVM:Java Virtual Machine,Java虚拟机,提供执行字节码文件的能力
所以,如果只是运行Java程序,只需要安装JRE即可。
另外注意,JVM是实现Java跨平台的核心,但JVM本身并不是跨平台的,
不同的平台需要安装不同的JVM
2,Java的基本数据类型有哪些?
3,==和equals的区别
==
比较基本数据类型比较的是数值,比较引用数据类型比较的是指向的内存地址
equals
左右两边变量所在类没有重写equals方法比较的是内存地址
左右两边变量所在类重写了equals方法那么比较的是两个变量的数值
注意(String类重写了Object类的equals方法,String类的变量调用equals方法比较的是值)
字符串相加会创建一个新的对象,地址指向变化
String s1 = new String("zs");
String s2 = new String("zs");
System.out.println(s1 == s2); //false
String s3 = "zs";
String s4 = "zs";
System.out.println(s3 == s4); //true
System.out.println(s3 == s1); //false
String s5 = "zszs";
String s6 = s3+s4;
System.out.println(s5 == s6); //false
final String s7 = "zs";
final String s8 = "zs";
String s9 = s7+s8;
System.out.println(s5 == s9); //true
final String s10 = s3+s4;
System.out.println(s5 == s10); //false
4,final的作用
final修饰类,表示类不可变,不可继承
比如,String,不可变性
final修饰方法,表示该方法不可重写
比如模板方法,可以固定我们的算法
final修饰变量,这个变量就是常量
注意:
修饰的是基本数据类型,这个值本身不能修改
修饰的是引用类型,引用的指向不能修改
比如下面的代码是可以的
final Student student = new Student(1,"Andy");
student.setAge(18);//注意,这个是可以的!
5,String s = "java"与String s = new String("java")
String s = "java";
String s = new String("java");
这两者的内存分配方式是不一样的。
第一种方式,JVM会将其分配到常量池,而第二种方式是分配到堆内存
6,String,StringBuffer,StringBuilder区别
String 跟其他两个类的区别是
String是final类型,每次声明的都是不可变的对象,
所以每次操作都会产生新的String对象,然后将指针指向新的String对象。
StringBuffer,StringBuilder都是在原有对象上进行操作
前者是线程安全的,后者是线程不安全的。
线程不安全性能更高,所以在开发中,优先采用StringBuilder.
StringBuilder > StringBuffer > String
注意:Stringbuffer的方法都加了 synchronize关键字修饰,每个线程访问独有的StringBuilder就不会有线程安全问题
7,接口和抽象类的区别
8,算法题-求N的阶乘
这道算法题一般考查的递归的编程技能,那么我们回顾下递归程序的特点:
1,什么是递归?
递归,就是方法内部调用方法自身
递归的注意事项:
找到规律,编写递归公式
找到出口(边界值),让递归有结束边界
注意:如果递归太多层,或者没有正确结束递归,则会出现“栈内存溢出Error”!
问题:为什么会出现栈内存溢出,而不是堆内存溢出?
因为每个方法在执行的时候都会创建一个栈帧,方法不断进栈不出栈,栈内存不足
所以必须明确限定条件,限制递归次数,在达到临界点之前结束递归
规律:N!=(n-1)!*n;
出口:n==1或n==0 return 1;
public static int getResult(int n){
if(n<0){
throw new ValidateException("非法参数");
}
if(n==1 || n==0){
return 1;
}
return getResult(n-1)*n;
}
9,什么是向上转型?什么是向下转型?
这道题目一般出现在(笔试-选择题)
举例说明即可:
向上转型:Person person = new Student(); 安全的
向下转型:Teacher teacher = (Teacher)person; 不安全的
10,Int和Integer的区别(重点)
1,来,先来一道考题,你看做对了吗?
Integer i1 = new Integer(12);
Integer i2 = new Integer(12);
System.out.println(i1 == i2); //false
Integer i3 = 126;
Integer i4 = 126;
int i5 = 126;
System.out.println(i3 == i4); //true
System.out.println(i3 == i5); //true
Integer i6 = 128;
Integer i7 = 128;
int i8 = 128;
System.out.println(i6 == i7); //false
System.out.println(i6 == i8); //true
分情况来比较
都定义为Integer的比较:
new:
一旦new,就是开辟一块新内存,结果肯定是false
不new
看范围,Integer做了缓存,-128至127,当你取值在这个范围的时候,会采用缓存的对象,所以会相等
当不在这个范围,内部创建新的对象,此时不相等
Integer和int的比较:
实际比较的是数值,Integer会做拆箱的动作,来跟基本数据类型做比较
此时跟是否在缓存范围内或是否new都没关系
源码分析
//当我们写Integer i = 126,实际上做了自动装箱:Integer i = Integer.valueOf(126);
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//IntegerCache是Integer的内部类
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;