1. 面向对象和面向过程的区别
面向过程
优点:性能比面向对象高
缺点:消耗资源比面向过程多,且不易维护、复用、扩展
面向对象
优点:因为有封装继承多态三个特性,可以设计出低耦合的系统,所以在维护、复用、扩展方面比面向过程要做的好
缺点:性能比面向过程低
2. Java 语言有哪些特点
1.简单易学;
2.面向对象(封装,继承,多态);
3.平台无关性( Java 虚拟机实现平台无关性);
4.支持多线程;
5.支持网络编程并且很方便;
6.编译与解释并存;
7.安全性;
3. 关于 JVM JDK 和 JRE 最详细通俗的解答
JVM
Java虚拟机(JVM)是运行 Java 字节码的虚拟机。JVM有针对不同系统的特定实现(Windows,Linux,macOS),目的是使用相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。
JDK 和 JRE
JDK是Java Development Kit,它是功能齐全的Java SDK。它拥有JRE所拥有的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。
JRE 是 Java运行时环境。它是运行已编译 Java 程序所需的所有内容的集合,包括 Java虚拟机(JVM),Java类库,java命令和其他的一些基础构件。但是,它不能用于创建新程序。
4. Java和C++的区别
- 都是面向对象的语言,都支持封装、继承和多态
- Java 不提供指针来直接访问内存,程序内存更加安全
- Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
- Java 有自动内存管理机制,不需要程序员手动释放无用内存
5. 什么是 Java 程序的主类 应用程序和小程序的主类有何不同
一个程序中可以有多个类,但只能有一个类是主类。主类就是包含 main方法的类。而在 Java 小程序中,这个主类是一个继承自系统类 JApplet 或 Applet 的子类。应用程序的主类不一定要求是 public 类,但小程序的主类要求必须是 public 类。
6. Java 应用程序与小程序之间有那些差别
应用程序是从主线程启动(也就是 main方法)。applet 小程序没有main方法,主要是嵌在浏览器页面上运行(调用init()线程或者run()来启动),嵌入浏览器这点跟 flash 的小游戏类似。
7. 字符型常量和字符串常量的区别
1.形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
2.含义上: 字符常量相当于一个ASCII 值,可以参加表达式运算 字符串常量代表一个地址值
3.占内存大小 字符常量只占2个字节 字符串常量占若干个字节(至少一个字符结束标志)
8. 构造器 Constructor 是否可被 override
父类的私有属性和构造方法并不能被继承,所以 Constructor 也就不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。
9. 重载和重写的区别
重载:
发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写:
发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
10. Java 面向对象编程三大特性: 封装 继承 多态
封装
封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们可以不提供方法给外界访问。但是一个类没有提供给外界访问的方法,那么这个类也没有意义了。
继承
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
多态
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。
在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。
11. String、StringBuffer 和 StringBuilder 的区别是什么,String 为什么是不可变的
可变性
String 类中使用字符数组保存字符串,但它使用了final修饰,所以 String 对象是不可变的。而StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串,但是没有用 final 修饰,所以这两种对象都是可变的。
线程安全性
String 中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder 是 StringBuilder 和 StringBuffer 的父类,定义了一些字符串的基本操作,如 append、insert、indexOf 等方法。StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
性能
对 String 进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对自己本身进行操作。使用 StringBuilder 比使用 StringBuffer 性能略高,但却要冒多线程不安全的风险。
对于三者使用的总结:
1.操作少量的数据 = String
2.单线程操作字符串缓冲区下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区下操作大量数据 = StringBuffer
12. 自动装箱与拆箱
装箱:
将基本类型用它们对应的引用类型包装起来
拆箱:
将包装类型转换为基本数据类型
13. 在一个静态方法内调用一个非静态成员为什么是非法的
由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。
14. 在 Java 中定义一个不做事且没有参数的构造方法的作用
Java 程序在执行子类的构造方法之前,如果没有用 super() 来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用 super() 来调用父类中特定的构造方法,则编译时将发生错误。解决办法是在父类里加上一个不做事且没有参数的构造方法。
15. import java和javax有什么区别
刚开始的时候 JavaAPI 所必需的包是 java 开头的包,javax 当时只是扩展 API 包来说使用。然而随着时间的推移,javax 逐渐的扩展成为 Java API 的组成部分。但是,将扩展从 javax 包移动到 java 包将是太麻烦了,最终会破坏一堆现有的代码。因此,最终决定 javax 包将成为标准API的一部分。
实际上java和javax没有区别。这都是一个名字。
16. 接口和抽象类的区别是什么
- 接口中的实例变量默认是 final 类型的,而抽象类中则不一定
- 一个类可以实现多个接口,但最多只能实现一个抽象类
- 一个类实现接口的话要实现接口的所有方法,而抽象类不一定
- 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
17. 成员变量与局部变量的区别有那些
- 从语法形式上看,成员变量是属于类的,而局部变量是属于方法的;成员变量可以被 private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰;但是,成员变量和局部变量都能被 final 所修饰;
- 从变量在内存中的存储方式来看,如果成员变量是使用static修饰的,那么这个成员变量是属于类的,如果没有使用使用static修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量存在于栈内存
- 从变量在内存中的生存时间上看,成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
18. 对象实体与对象引用有何不同?
new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)。
19. 若一个类没有声明构造方法,该程序能正确执行吗 ?为什么?
可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
20. 构造方法有哪些特性
- 名字与类名相同
- 没有返回值,但不能用void声明
- 生成类的对象时自动执行
21. 静态方法和实例方法有何不同
- 实例方法必须要创建对象才能调用,而调用静态方法可以直接用类名调用,无需创建对象
- 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制
22.对象的相等与指向他们的引用相等,两者有什么不同?
对象的相等,指的是内容相等。而引用相等,指的是地址相等。
23. == 与 equals(重要)
== :基本数据类型==比较的是值是否相等,引用数据类型==比较的是内存地址是否相等
equals() :原生的equals比较的是对象的内存地址,但equals可以重写,用来比较其他内容。例如,String 中的 equals 方法是被重写过的,比较的是对象的值。
24. hashCode 与 equals (重要)
hashCode()介绍
hashCode() 的作用是获取哈希码(int)。哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在Object中,所以Java中的任何类都包含有hashCode()。
哈希表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了哈希码。
为什么要有 hashCode
当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。
hashCode()与equals()的相关规定
- 两个对象相等,则hashcode一定也是相同的
- 两个对象相等,对两个对象调用equals方法都返回true
- 两个对象有相同的hashcode值,它们也不一定是相等的
- 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
- hashCode() 默认是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
25. 简述线程,程序,进程的基本概念.以及他们之间关系是什么?
简单来说,一个进程就是一个执行中的程序。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
线程是进程划分成的更小的运行单位。一个进程在其执行的过程中可以产生多个线程。
线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。
例如:QQ和迅雷分别就是两个进程,QQ里的视频功能、发红包功能就是QQ里的线程。
26. 关于 final 关键字的一些总结
final关键字主要用在三个地方:变量、方法、类。
- 对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
- 当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。
- 使用final方法的原因主要是为了防止修改
27.Java序列化中如果有些字段不想进行序列化,怎么办
对于不想进行序列化的变量,使用transient关键字修饰。transient只能修饰变量,不能修饰类和方法。
28. 获取用键盘输入常用的的两种方法
方法1:通过 Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
方法2:通过 BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();