Java-常见面试题收集(一)

一 Java 基础

1 列举 Java 的 8 大基础类型,并写出对应的占用大小

数据类型占位(字节)数据范围
byte1[ -128 , 127 ]
short2[ -32768 , 32767 ]
int4[ -231 , -231 - 1 ] ≈ [-21 亿,21 亿]
long8[ -263 , -263-1 ]
float4[-3.4x1038 , ~ 3.4x1038]
double8[-1.7x10308 , ~ 1.7x10308]
cha2[0 , 216-1]
boolean1true,false

2 说说&和&&的区别。

  &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。
  &&还具有短路的功能,即如果第一个表达式为 false,则不再计算第二个表达式。&还可以用作位运算符,当&操作符两边的表达式不是 boolean 类型时,&表示按位与操作,我们通常使用 0x0f 来与一个整数进行&运算,来获取该整数的最低 4个 bit 位,例如,0x31 & 0x0f 的结果为 0x01。

3 switch 可以作用在 byte、long 和 String 上吗?

  switch 可以用在 byte short char int 类型上,不能用在 long 类型上,JDK7 之后,可以用于 String 类型上。

二 常见 String 类

1 String 为什么是不可变的?

  String 类中使用 final 关键字修饰字符数组来保存字符串,private final char[] value,所以 String 对象是不可变的。

2 String、StringBuffer 和 StringBuilder 的区别是什么?

可变性
  String 类中使用 final 关键字修饰字符数组来保存字符串,private final charvalue[],所以 String 对象是不可变的。而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串 char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。
线程安全性
  StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
性能
  每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的总结:
  操作少量的数据: 适用 String
  单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
  多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

3 String s1 = new String(“abc”);这句话创建了几个字符串对象?

  会创建 1 或 2 个字符串对象

1、如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个
字符串对象“abc”。
String s1 = new String("abc");

2、如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个
字符串对象“abc”。
// 字符串常量池中已存在字符串对象“abc”的引用
String s1 = "abc";
// 下面这段代码只会在堆中创建 1 个字符串对象“abc”
String s2 = new String("abc");

4 如何实现字符串反转

// 方法一: 把 str 转化成字符数组
public static void demo1(String str){
	char[] chars = str.toCharArray();
	for (int i = 0,j = chars.length - 1; i < j;i++,j--){
		char temp = chars[i];
		chars[i] = chars[j];
		chars[j] = temp;
	}
	System.out.println(new String(chars));
}

// 方法二: 使用 StringBuffer 的反转方法 reverse()
public static void demo2(String str){
	StringBuffer sb = new StringBuffer(str);
	StringBuffer sb1 = sb.reverse();
	System.out.println(sb1.toString());
}

5 intern 方法的作用

  String.intern() 是一个 native(本地)方法,其作用是将指定的字符串对象的引用保存在字符串常量池中,可以简单分为两种情况:
  如果字符串常量池中保存了对应的字符串对象的引用,就直接返回该引用。
  如果字符串常量池中没有保存了对应的字符串对象的引用,那就在常量池中创建一个指向该字符串对象的引用并返回

// 在堆中创建字符串对象”Java“
// 将字符串对象”Java“的引用保存在字符串常量池中
String s1 = "Java";
// 直接返回字符串常量池中字符串对象”Java“对应的引用
String s2 = s1.intern();
// 会在堆中在单独创建一个字符串对象
String s3 = new String("Java");
// 直接返回字符串常量池中字符串对象”Java“对应的引用
String s4 = s3.intern();
// s1 和 s2 指向的是堆中的同一个对象
System.out.println(s1 == s2); // true
// s3 和 s4 指向的是堆中不同的对象
System.out.println(s3 == s4); // false
// s1 和 s4 指向的是堆中的同一个对象
System.out.println(s1 == s4); //true

三 面向对象基础

1 Java 面向对象编程三大特性

封装
  封装:把对象的字段和方法存放在一个独立的模块中(类),信息隐藏,尽可能隐藏对象的数据和功能的实现细节
  封装的好处:提高组件的重用性,把公用功能放到一个类中,谁需要该功能,直接调用即可,保证数据的安全性,防止调用者随意修改数据
继承
  继承:不同类型的对象,相互之间经常有一定数量的共同点。
  A同学、B同学都共享学生的特性(班级、学号等)。不同的学生对象定义了额外的特性使得他们与众不同(每个人的特长)。继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承,可以快速地创建新的类,提高代码重用性,程序可维护性 ,提高开发效率。
  子类拥有父类对象所有的字段和方法(包括私有字段和私有方法),但是父类中的私有字段和方法子类是无法访问,只是拥有。子类可以拥有自己字段和方法,即子类可以对父类进行扩展。子类可以用自己的方式实现父类的方法(方法重写)。
多态
  多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。
  多态的特点:
  对象类型和引用类型之间具有继承(类)/实现(接口)的关系,引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定;多态不能调用"只在子类存在但在父类不存在"的方法;
  如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。

2 构造方法的特点以及可以重写吗?

  特点
  名字与类名相同。
  没有返回值,但不能用 void 声明构造函数。
  生成类的对象时自动执行,无需调用。
  构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。

3 类的构造器的作用是什么?

  构造方法是一种特殊的方法,主要作用是完成对象的初始化工作

4 重载和重写的区别

  重载:发生在同一个类中,方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同
  重写:是子类对父类的允许访问的方法的实现过程进行重新编写,发生在子类中,方法名、参数列表必须相同,返回值范围小于等于父类,访问修饰符范围大于等于父类,抛出的异常范围小于等于父类。另外,如果父类方法访问修饰符为private 则子类就不能重写该方法。也就是说方法提供的行为改变,而方法的外貌并没有改变。

5 接口和抽象类的区别

共同点 :
  都不能被实例化。
  都可以包含抽象方法。
  都可以有默认实现的方法(Java 8 可以用 default 关键字在接口中定义默认方法)。
区别 :
  接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。抽象类主要用于代码复用,强调的是所属关系。
  一个类只能继承一个类,但是可以实现多个接口。
  接口中的成员变量只能是 public static final 类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值。

6 调用子类构造方法之前先调用父类没有参数的构造方法的目的

  帮助子类做初始化工作,为了对象的实例化。
  子类中所有的构造器都会默认调用父类中的无参构造器,因为每一个子类构造器内的第一行都有一条隐式的 super()
  若父类中没有无参构造器,那么子类的构造器内必须通过 super 语句指定要调用的父类中的构造器
  若子类构造器中用 this 来指定调用子类自己的构造器,那么被调用的构造器也一样会调用父类中的构造器

7 == 与 equals 区别 ?

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

8 final 关键字修饰这三个地方:变量、方法、类

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

9 描述深拷贝和浅拷贝

  浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
  深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

10 当某个场景下,接口与继承这 2 种均可用时,如何判断何种更合适?

  继承,是面向对象分析与设计最常用的方式之一,在应用系统的设计过程中,得到了广泛的使用。它的主要不足是,继承后的系统需要囊括整个继承树的信息,对新系统而言,冗余部分相当大;二是子类对父类的耦合很紧密,不利用系统的扩展;
  接口,有很大的灵活性。接口的不同实现方式,对于使用接口的客户而言,只是一种抽象的耦合。改变接口的实现,对客户代码的影响很小。因此,如果某个功能的实现比较复杂,今后发生变化、引入不同不同实现方式的可能性比较大,一般采用接口的方式。如果有大量的功能,已经在父类得到实现,可以直接使用,并且,这些功能已经比较成熟,则采用继承的方式。

四 包装类

1 自动装箱与拆箱

  装箱:将基本类型用它们对应的引用类型包装起来;
  拆箱:将包装类型转换为基本数据类型;

2 请写出下列代码的运行结果

Integer a = 256;
Integer b = new Integer(256);
Integer c = 256
Integer d = 5;
Integer e = 5;
System.out.println(a==b);
System.out.println(b==c);
System.out.println(a==c);
System.out.println(d==e);
  • 18
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒疯狂展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值