你必须会的Java基础题

2,276 阅读7分钟

前言

你的Java基础怎么样?不少同学会说:“我Java基础还不错!”你的基础真的可以吗?不妨试着看看我文章中的题,如果你都能答对,那我只能对你说:同学,你的基础确实不错,给你点赞!前几天翻阅资料看到了不少之前看过的Java基础题,虽然确实很基础,但也有不少的“坑”,接下来,我们进入主题,会做的同学们就当是巩固知识点,不会的同学们要认真学习,这些可是最基础的知识!

float f=3.4;是否正确?

答:不正确。因为3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4f;

short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

答:对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,因此需要强制转换类型才能赋值给 short 型;而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。

你知道运算符&和&&、|和||的区别吗?

答:& 按位与操作运算符,只有对应的两个二进制数为1时,结果位才为1。例如:1&1 = 1、1&0 = 0、0&1 = 0、0&0 = 0。 | 按位或操作运算符,有一个为1的时候,结果位就为1。例如: 1|1 = 1、1|0 = 1、0|1 = 1、 0|0 = 0。

& 和 && 都可以实现与操作。区别:& 是两边都运算,而 && 先算 &&的 左侧,若左侧为false 那么右侧就不运算,判断语句中推荐使用 &&,效率更高。

​| 和 || 都可以实现或操作,区别:||只要满足第一个条件,后面的条件就不再判断,而|要对所有的条件进行判断。

​&&和||称之为短路运算符

了解位运算吗?用最有效率的方法计算 2 乘以 8

答:2<<3 原理:将一个数左移n位,相当于乘以2的n次方,位运算是CPU直接支持的,所以效率高。

常见的JDK源码里面HashMap的默认容量16 int DEFAULT_INITIAL_CAPACITY = 1 << 4; ​ 直接是二进制操作,表示1左移4位,变成10000,转为10进制也就是16, 直接以二进制形式去运行,效率会更高。

Java的基础数据类型有哪些?

答:八大基础数据类型:byte、short、int、long、float、double、char、boolean

== 和equals的区别是什么?

答:当对基本数据类型进行比较时,要用 == 判断是否相等。 当对引用数据类型数据进行比较时: ==比较的是内存地址是否一样,不同对象的内存地址不一样;equals比较的是具体的内容。

String str = new String("abc"); 创建了几个对象?

答:可以答创建了一个对象,也可以答创建了两个对象,需要分情况讨论。

创建一个对象:当常量池存在时,则直接new一个对象。 创建两个对象:当常量池不存在时,则在常量池创建一个对象,也在堆中创建一个对象。

关于内存地址比较例题

String str1= new String("abc"); String str2= "abc"; String str3= "abc"; System.out.println(str1 == str2) //false System.out.println(str2 == str3) //true

答: 第一个是false: new 创建新的对象会开辟新的空间,所以地址不一样。 第二个是true:都是从常量池里面获取,"abc" 存在于常量池中。

String、StringBuffer与StringBuilder的区别?它们的使用场景是什么?

答:三者都是final,不允许被继承,在本质都是char[]字符数组实现。String、StringBuffer与StringBuilder中,String是不可变对象,StringBuffer与StringBuilder是可变的。StringBuilder 效率更快,因为它不需要加锁,不具备多线程安全,StringBuffer里面操作方法用synchronized ,效率相对更低,是线程安全的; ​ 使用场景:

  • 操作少量的数据用String,但是常改变内容且操作数据多情况下最好不要用 String ,因为每次生成中间对象性能会降低。 ​
  • 单线程下操作大量的字符串用StringBuilder,虽然线程不安全但是不影响 。
  • 多线程下操作大量的字符串,且需要保证线程安全 则用StringBuffer。

final 有什么用?

答: 用于修饰类、属性和方法;

  • 被final修饰的类不可以被继承
  • 被final修饰的方法不可以被重写
  • 被final修饰的变量不可以被改变,
  • 被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的

final finally finalize区别是什么?

答:

  • final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
  • finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
  • finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。

面向对象的四大特性是什么?

答:抽象、封装、继承、多态

抽象:关键词abstract声明的类叫作抽象类,abstract声明的⽅法叫抽象⽅法。如果⼀个类⾥包含了⼀个或多个抽象⽅法,则该类就必须指定成抽象类,抽象⽅法属于⼀种特殊⽅法,只含有⼀个声明,没有⽅法体。

封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口即⽅法,在java中通过关键字private,protected和public实现封装。封装把对象的所有组成部分组合在⼀起,封装定义程序如何引⽤对象的数据,封装实际上使⽤⽅法将类的数据隐藏起来,控制⽤户对类的修改和访问数据的程度。 适当的封装可以让代码更容易理解和维护,也加强了代码的安全性。常见有类封装与⽅法封装。

继承:⼦类继承⽗类的特征和⾏为,使得⼦类对象具有⽗类的⽅法和属性,⽗类也叫基类。

多态:同⼀个⾏为具有多个不同表现形式的能⼒。 优点:减少耦合、灵活可拓展,⼀般是继承类或者重写⽅法实现。

Overload和Override的区别?

答: 重载Overload:表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同,参数个数或类型不同。 重写Override:重写父类中的方法,表示子类中的方法可以与父类中的某个方法的名称和参数完全相同。

接口是否可以继承接口?接口是否支持多继承?类是否支持多继承?

答:

  • 接⼝⾥可以有静态⽅法和⽅法体
  • 接⼝中所有的⽅法必须是抽象⽅法(JDK8之后就不是)
  • 接⼝不是被类继承了,⽽是要被类实现
  • 接⼝⽀持多继承,类不⽀持多个类继承

写一个方法来传递两个非0的int数值进去,实现变量交换的方式,有几种方式?

答:以下列举三种方式: 第一种(最常见):

 public static void swap(int a, int b){
	System.out.printf("a=%d, b=%d",a,b);
        int temp;
        temp=a ;
        a = b;
        b=temp;
        System.out.printf("\na=%d, b=%d",a,b);
}

第二种:

  public static void swap(int a, int b){
        System.out.printf("a=%d, b=%d",a,b);
        a = a + b;
        b = a - b ;
        a = a - b;
        System.out.printf("\na=%d, b=%d",a,b);
}

第三种(异或运算,一个数与另一个数异或两次是其本身, 一个数和自身异或结果是0):

 public static void swap2(int a, int b){
     System.out.printf("a=%d, b=%d",a,b);
     a = a^b; 
     b = b^a;   
     a = a^b;   
     System.out.printf("\na=%d, b=%d",a,b);

}

结语

当然以上部分只是Java基础题的冰山一角,仅仅会这些是远远不够的,如果想要继续提升那就要不断学习、刷题。 注:如果题有疑问,欢迎留言指正!