1. 面向对象和面向过程的区别
面向过程:
优点:性能高,类的实例化是有较大开销的,且占用更多的内存,在注重性能的开发场合,例如单片机、嵌入式开发、Linux/Unix内核等场景中一般采用面向过程开发。
缺点:代码逻辑贴近机器逻辑,不易维护;不易复用;不易扩展。
面向对象:
优点:易维护;易复用;易扩展;面向对象有封装、继承、多态的特性,可以设计出低耦合的系统。
缺点:性能比面向过程低,一般用于业务层、比如业务中间件。
2. Java语言有哪些特点?
面向对象(封装,继承,多态);
平台无关性(Java虚拟机实现平台无关性),编译与解释并存;
使用广泛,有很多可用的库
*3. 什么是字节码?采用字节码的最大好处是什么?
思路:1.先简单介绍一下Java源代码到可执行文件的过程。(谁负责编译、谁负责解释)2. 介绍一下JIT并说明其原理 3.采用字节码的好处
java中的编译器和解释器:
Java引入了虚拟机(JVM),即在机器和编译程序之间加入了一层抽象的虚拟的机器。
在不同的操作系统上,其实有不同的虚拟机,但是他们都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。这种供虚拟机理解的代码叫做字节码(Java中是扩展名为.class的文件),它不面向任何特定的处理器,只面向虚拟机。
Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释并存。

Java源代码—->编译器—->jvm可执行的Java字节码(即虚拟指令)—->jvm—->jvm中解释器—–>机器可执行的二进制机器码—->程序运行。
我们需要格外注意的是 .class->机器码 这一步。在这一步 JVM 类加载器首先加载字节码文件,然后通过解释器逐行解释执行,这种方式的执行速度会相对比较慢。而且,有些方法和代码块是经常需要被调用的(也就是所谓的热点代码),所以后面引进了 JIT 编译器,而 JIT 属于运行时编译。
JIT:Just In Time,虚拟机的一种优化手段,如果某个方法或者代码块频繁的被调用,虚拟机会把这段代码标记为“热点代码”,并将这段字节码一次性的编译为机器码,以提高运行效率。Java中的JIT是HotSpot。这也解释了我们为什么经常会说 Java 是编译与解释共存的语言。
HotSpot 采用了惰性评估(Lazy Evaluation)的做法,根据二八定律,消耗大部分系统资源的只有那一小部分的代码(热点代码),而这也就是 JIT 所需要编译的部分。JVM 会根据代码每次被执行的情况收集信息并相应地做出一些优化,因此执行的次数越多,它的速度就越快。JDK 9 引入了一种新的编译模式 AOT(Ahead of Time Compilation),它是直接将字节码编译成机器码,这样就避免了 JIT 预热等各方面的开销。JDK 支持分层编译和 AOT 协作使用。但是 ,AOT 编译器的编译质量是肯定比不上 JIT 编译器的。
采用字节码的好处:
Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。
4. 什么是JDK? 什么是JRE?
JDK: 顾名思义它是给开发者提供的开发工具箱,是给程序开发者用的。它除了包括完整的JRE(Java Runtime Environment),Java运行环境,还包含了其他供开发者使用的工具包。
JDK中包括:
1. javac:编译器
2. java:运行工具
3. jar:打包工具
4. javadoc:文档生成器
5. jdb debugger:调试工具
JRE:普通用户而只需要安装JRE(Java Runtime Environment)来 来运行Java程序。而程序开发者必须安装JDK来编译、调试程序。
5. Java环境变量PATH和CLASSPATH
PATH环境变量:
- 设定%JAVA_HOME%,并将%JAVA_HOME%/bin加入到 PATH中
- 好处:可以在任何文件夹下调用javac, java 等工具。
CLASSPATH环境变量
- java在运行字节码时,需要通过-classpath指定java类的所在位置,否则会报无法加载主类的错误
- 设定%CLASSPATH%后,可以使用这个变量用于指定-classpath参数
*6. 字符型常量和字符串常量的区别
- 形式上:字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
- 含义上:字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)
- 占内存大小:字符常量只占2个字节 字符串常量占若干个字节(java和C\C++不一样,字符串不需要\0结尾)。 (注意: char 在 Java 中占两个字节)

7. Java语言采用何种编码方案?有何特点?
Java语言采用Unicode编码标准,每个字符占两个字节
这里说的编码是Java代码运行时在内存中的编码,不是*.java在文件中的编码。
8. 构造器Constructor是否可被override
在讲继承的时候我们就知道父类的私有属性和构造方法并不能被继承,所以Constructor也就不能被override(子类覆盖父类的同名方法),但是可以overload(方法相同,但是参数不同),所以你可以看到一个类中有多个构造函数的情况。
override和overload的区别:
override:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类;如果父类方法访问修饰符为private则子类中就不是重写。
overload:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
*9. java 面向对象编程三大特性
封装:对象的属性或者方法,可以隐藏起来,禁止被外部访问
9. 封装:访问权限 protected friendly(什么都不写,default)
当前类 派生类 同一个package里的类 不同package里的类
public Yes Yes Yes Yes
protected Yes Yes Yes No
(default) Yes 看是否同一个package Yes No
private Yes No No No
继承:派生类可以使用基类的属性和方法(一般方法,构造方法),也可以定义自己的属性和方法
多态:动态绑定,决定调用基类的方法还是派生类的方法,由实例事实上是哪个类的实例来决定,而不是由引用的类型决定。
10. java中equals方法的用法以及==的用法
“==”比较两个变量本身的值,即两个对象在内存中的首地址。
“equals()”比较字符串中所包含的内容是否相同。
主要适用于String,原始类型的包装类
String s1,s2,s3 = "abc", s4 ="abc" ;
s1 = new String("abc");
s2 = new String("abc");
s1 == s2: false
s1.equals(s2): true
s3 == s4: true
s3.equals(s4): true
String s1 = "123";
String s2 = "123";
String s3 = "abc";
String s4 = new String("123");
String s5 = new String("123");
String s6 = new String("abc");
System.out.println(s1 == s2);//(1)true
System.out.println(s1.equals(s2));//(2)true
System.out.println(s1 == s3);//(3)flase
System.out.println(s1.equals(s3));//(4)flase
System.out.println(s4 == s5);//(5)flase
System.out.println(s4.equals(s5));//(6)true
System.out.println(s4 == s6);//(7)flase
System.out.println(s4.equals(s6));//(8)flase
System.out.println(s1 == s4);//(9)false
System.out.println(s1.equals(s4));//(10)true
特例:如果某些类没有override equals方法,那么他们使用Object.equals,这个方法也是比较地址的。
StringBuffer s5 = new StringBuffer("a");
StringBuffer s6 = new StringBuffer("a");
s5 == s6: false
s5.equals(s6): false
*11. String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?
可变性
String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[]value,这两种对象都是可变的。
线程安全性
String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
性能
每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的总结: 如果要操作少量的数据用:String;单线程操作字符串缓冲区 下操作大量数据:StringBuilder;多线程操作字符串缓冲区 下操作大量数据:StringBuffer。
12. 自动装箱与拆箱
装箱:将基本类型用它们对应的引用类型包装起来;
拆箱:将包装类型转换为基本数据类型;
Java使用自动装箱和拆箱机制,节省了常用数值的内存开销和创建对象的开销,提高了效率,由编译器来完成,编译器会在编译期根据语法决定是否进行装箱和拆箱动作。
13. 说出这段代码的运行结果:
public class aClass {
void fun() {
static int i = 0;
i++;
System.out.println(i);// 分别打印输出1
}
public static void main(String args[]) {
aClass obj = new aClass();
obj.fun();
obj.fun();
}
}
报错:注意,虽然C\C++这样写是对的,java中static不可以修饰局部变量。
14. 在一个静态方法内调用一个非静态成员为什么是非法的?
由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
15. 在Java中定义一个不做事且没有参数的构造方法的作用
Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。
*16. 接口和抽象类的区别是什么?
接口的方法默认是public,在JDK 7及以前,所有方法在接口中不能有实现,JDK 8 及以后接口中可以用default关键字实现方法,抽象类可以有非抽象的方法
接口中不能有变量,构造函数和static静态代码块,只能有常量 public static final,而抽象类没有限制
一个类可以实现多个接口,但最多只能实现一个抽象类
一个类实现接口的话要实现接口的所有方法,而抽象类不一定
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为能力的抽象,是一种行为的规范。
17. 成员变量与局部变量的区别有那些?
从语法形式上,看成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量可以被public,private,static等修饰符所修饰,而局部变量不能被访问控制修饰符及static所修饰;成员变量和局部变量都能被final所修饰;
从变量在内存中的存储方式来看,成员变量是对象的一部分,而对象存在于堆内存,局部变量存在于栈内存
从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
成员变量如果没有被赋初值,则会自动以类型的默认值而赋值(一种情况例外被final修饰但没有被static修饰的成员变量必须显示地赋值);而局部变量则不会自动赋值。
18. 创建一个对象用什么运算符?对象实体与对象引用有何不同?
new运算符,new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象;一个对象可以有n个引用指向它。
19.Java 和 C++的区别?
- 都是面向对象的语言,都支持封装、继承和多态
- Java 不提供指针来直接访问内存,程序内存更加安全
- Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
- Java 有自动内存管理机制,不需要程序员手动释放无用内存
- 在 C 语言中,字符串或字符数组最后都会有一个额外的字符‘\0’来表示结束。但是,Java 语言中没有结束符这一概念。 这是一个值得深度思考的问题,具体原因推荐看这篇文章: https://blog.csdn.net/sszgg2006/article/details/49148189