面试题——Java基础

面试题——Java基础
建议大家先看目录中的题目,自检一下,下面的解答只是自我观点,不足之处请指正。

1、面向对象和面向过程各有哪些优缺点?(※※※※)

答:

面向过程

优点:

性能要高(类调用时需要初始化,开销较大,比较消耗资源;比如嵌入式开发或者是单片机等一般采用面向过程的开发);

缺点:

不易维护、复用和扩展

面向对象

优点:

易维护、易扩展、易复用(这些特点是由于面向对象中有封装、继承、多态的特性,可以设计出低耦合的系统,使得系统更加灵活、易于维护)

缺点:

性能比较低

扩展题目

1.1 Java和C++的异同
  • 都是面向对象的语言,都支持封装、继承和多态
  • Java 不提供指针来直接访问内存,程序内存更加安全
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
  • Java 有自动内存管理机制,不需要程序员手动释放无用内存

2、Java中重载和重写的区别(※※※※)

  • 重载: 发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同,发生在编译时。
  • 重写: 发生在父子类中,方法名、参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法

3、Java(面向对象编程)的三大特性简要介绍一下(※※※※)

封装

封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

继承

继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。
关于继承如下 3 点请记住:

    1. 子类拥有父类非 private 的属性和方法。
    1. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。
    1. 子类可以用自己的方式实现父类的方法。(以后介绍)。

多态

所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。在 Java 中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。

4、接口和抽象类的区别?(※※※)

  1. 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),抽象类可以有非抽象的方法
  2. 接口中的实例变量默认是 final 类型的,而抽象类中则不一定
  3. 一个类可以实现多个接口,但最多只能实现一个抽象类
  4. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定
  5. 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

5、==和equals区别(※※※※)

== : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
 情况 1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
 情况 2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。
举个例子:

public class test1 {
	 public static void main(String[] args) {
 		String a = new String("ab"); // a 为一个引用
 		String b = new String("ab"); // b 为另一个引用,对象的内容一样
 		String aa = "ab"; // 放在常量池中
 		String bb = "ab"; // 从常量池中查找
		 if (aa == bb){ // true
			 System.out.println("aa==bb");
			 }
		 if (a == b) {// false,非同一对象
 			System.out.println("a==b");
 			}
		 if (a.equals(b)){ // true
			 System.out.println("aEQb");
			 }
		 if (42 == 42.0) { // true
		 System.out.println("true");
 }
 }
}

说明:
 String 中的 equals 方法是被重写过的,因为 object 的 equals 方法是比较的对象的内存地址,而 String 的 equals 方法比较的是对象的值。
 当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String 对象。

6、hashCode 与 equals(※※※※)

  1. 如果两个对象相等,则 hashcode 一定也是相同的
  2. 两个对象相等,对两个对象分别调用 equals 方法都返回 true
  3. 两个对象有相同的 hashcode 值,它们也不一定是相等的
  4. equals 方法被覆盖过,则 hashCode 方法也必须被覆盖
  5. hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写
    hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

7、简述一下线程、进程、程序?(※※)

线程 与进程相似,但线程是一个比进程更小的执行单位一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
程序 是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码
进程 是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如 CPU 时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 线程是进程划分成的更小的运行单位。线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。从另一角度来说,进程属于操作系统的范畴,主要是同一段时间内,可以同时执行一个以上的程序,而线程则是在同一程序内几乎同时执行一个以上的程序段。

8、Java中的异常处理(※※※※※)

Java异常此层结构图

在这里插入图片描述
Throwable: 有两个重要的子类:Exception(异常) 和 Error(错误)
Error(错误):是程序无法处理的错误。
Exception(异常):是程序本身可以处理的异常。
Exception 类有一个重要的子类 RuntimeException。RuntimeException 异常由 Java 虚拟机抛出。
NullPointerException(要访问的变量没有引用任何对象时,抛出该异常)、
ArithmeticException(算术运算异常,一个整数除以 0 时,抛出该异常)
ArrayIndexOutOfBoundsException (下标越界异常)
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。
异常处理总结

  • try 块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch块,则必须跟一个 finally 块。
  • catch 块:用于处理 try 捕获到的异常。
  • finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。
  • 当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

在以下 4 种特殊情况下,finally 块不会被执行:(※※)

  1. 在 finally 语句块中发生了异常。
  2. 在前面的代码中用了 System.exit()退出程序。
  3. 程序所在的线程死亡。
  4. 关闭 CPU。

9、final 关键字的一些总结(※※)

final 关键字主要用在三个地方:变量、方法、类。
对于一个 final 变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象
当用 final 修饰一个类时,表明这个类不能被继承。final 类中的所有成员方法都会被隐式地指定为 final 方法。
使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的 Java 实现版本中,会将final 方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的 Java 版本已经不需要使用 final 方法进行这些优化了)。类中所有的 private 方法都隐式地指定为 final

10、构造器 Constructor 是否可被 override(※※)

父类的私有属性和构造方法并不能被继承,所以Constructor 也就不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值