01-Java基础面试题第一弹

发布于:2023-01-04 ⋅ 阅读:(235) ⋅ 点赞:(0)

Java基础面试题第一弹

1. 面向对象的特征有哪些方面

  1. 抽象:抽象是将一类对象的共同特征抽离出来构造成类的过程。包括数据抽象和行为抽象两个部分,抽象只关注对象的属性和行为,并不关注行为的具体细节。【如狗都会叫,但是不同品种的狗的叫声有差异】
  2. 继承:继承是从已有类,得到继承信息并创建新类的过程。提供继承信息的类被称为父类【超类、基类】,得到继承信息的类被称为子类【派生类】。继承让变化中的系统有了一定的延续性。
  3. 封装:封装是把数据和操作数据的方法绑定在一起,对数据的访问只能通过已定义的接口。
  4. 多态:多态指的是允许不同子类型的对象对同一信息作出不同的响应。换言之就是,相同的对象引用调用相同的方法会执行不同的处理。分为编译时的多态性运行时的多态性
    1. 编译时的多态性:方法重载【overload】实现的是编译时的多态性,也称为前绑定。
    2. 运行时的多态性:方法重写【overwrite】实现的是运行时的多态性,也称为后绑定。实现运行时多态需要两步:其一,方法重写;其二,由父类引用子类对象,并调用方法。该方法会根据不同的子类实现而执行不同的代码。

2. 访问修饰符 public,private,protected,以及不写时的区别

修饰符 当前类 相同包下 子类 其他包下
public 可访问 可访问 可访问 可访问
protected 可访问 可访问 可访问 不可访问
default 可访问 可访问 不可访问 不可访问
private 可访问 不可访问 不可访问 不可访问
  1. 类的成员不写访问修饰符时默认为default。
  2. 外部类的修饰符只能是public或默认,类的成员【包括内部类】的修饰符可以是以上四种。

3. String是最基本的数据类型吗?

答:不是;Java中基本数据类型有8种:byte、short、char、int、float、double、long、boolean。Java除了基本数据类型外,剩下的都是引用类型。Java5以后引入的枚举类型也算是一种特殊的引用类型。

4. float f = 3.4; 是否正确

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

5. short s1 = 1; s1 = s1 + 1;是否有错?

答:有错,无法正确编译;由于 1 是int类型,因此s1+1运算结果也是int类型,需要强制类型转换才能赋值给short类型。如:short s1 = 1; s1 = (short) (s1 + 1);

6. short s1 = 1; s1 += 1;是否有错?

答:可以正确编译;s1+=1; 相当于s1 = (short) (s1 + 1); 其中隐含了强制类型转换。

7. Java是否有goto?

答:goto是Java的保留字,在目前Java版本中没有使用。goto 和 const 是目前无法使用的关键字,有些地方称之为保留字。

8. int 和 Integer 的区别

  1. Integer是int的包装类型,int是Java的一个基本数据类型。
  2. Integer的默认值为null,int的默认值为0。在实际编程的实体类中,一般使用Integer类型而不使用int类型。因为当Integer类型没有赋值时,为null,有特殊含义;当int类型没有赋值时,为默认值0。【如,某个系统用户的年龄为Integer类型,当该用户没有填写年龄,则该值为null,若为int类型,则默认为0,无法表明该用户是否填写了年龄】
  3. 为了能够将基本数据类型当成对象操作,Java为每一个基本数据类型引入了对应的包装类型,而int的包装类型就是Integer。
  4. 整型之间的比较:
/**
 * @author: zipeng Li
 * 2021/5/25  15:15
 */
class Test {
    public static void main(String[] args) {
        Integer a = new Integer(3);
        Integer b = 3; // 将 3 自动装箱为Integer类型
        int c = 3;
        System.out.println(a == b); // 结果为 false,这里比较的是两个引用类型的内存地址
        System.out.println(b == c); // 结果为 true,这里 b自动拆箱成int类型,比较的是值。

        Integer d = 100;
        Integer e = 100;
        System.out.println(d == e); // 结果为 true,因为 -128 - 127 之间的整数缓存在java常量池中

        Integer f = 150;
        Integer g = 150;
      // 结果为 false,因为 150 不在java常量池中,每次都会新建一个Integer对象
        System.out.println(f == g); 
    }
}

9. & 与 && 的区别

  1. & 运算符有两种用法:按位与 和 逻辑与。
  2. && 运算符是短路与运算。
  3. 逻辑与 和 短路与 的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是 true,整个表达式的值才是 true。若 && 左边的表达式为 false,则右边的表达式会被直接短路掉,不会进行运算。
  4. 例子:username != null && username.equals("")二者之间的顺序不能交换,更不能使用 & 运算符,因为第一个条件不成立,则根本不能进行字符串的equals比较,否则会抛出NullPointerException异常。
  5. | 和 || 运算符的差别也是差不多。

10. 解释内存中栈、堆和方法区的用法

  1. 通常定义的基本数据类的变量、对象的引用、函数调用的现场保存都使用JVM的栈空间;
  2. 通过关键字 new 和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域;
  3. 现在的垃圾收集器都使用分代收集算法,所以堆空间还可以细分为新生代、老生代;具体还可以细分为Eden、Survivor【From Survivor 和 To Survivor】、Tenured;
  4. 堆和方法区都是线程共享的内存区域,用于存储已被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;
  5. 程序中的字面量【如直接书写的100、“hello”】和常量都是放在常量池中,常量池是方法区的一部分;
  6. 栈空间操作起来最快但是比较小,对象通常放在堆空间内;栈和堆空间可以通过JVM的启动参数来进行调整
  7. 栈空间用完会引发StackOverflowError异常;堆和常量池空间不足会引发OutOfMemoryError异常。
String str = new String("hello");

// 1. 变量 str 放在栈上,用 new 创建出来的字符串对象放在堆上,而“hello”这个字面量放在方法区。

// 2. 补充1:较新版本的Java【从 Java 6 的某个更新开始】中,由于JIT编译器的发展和“逃逸分析”技术的逐渐成熟,栈上分配、标量替换等优化技术使得对象一定分配在堆上变得不是那么绝对了。

// 3. 补充2:运行时常量池 相当于 Class文件常量池 具有动态性,Java语言并不要求常量一定只有编译期间才能产生,运行期间也可以将新的常量放入池中,String类的 intern() 方法就是这样。

// 4. String.intern() 方法,若字符串在常量池可以找到,则返回常量池地址;否则,把该字符串保存到常量池,返回原来字符串对象地址

/**
 * @author: zipeng Li
 * 2021/5/25  15:15
 */
class Test {
    public static void main(String[] args) {
        String s1 = new StringBuilder("go").append("od").toString();
        System.out.println(s1.intern() == s1); // true  因为常量池一开始没有 "good";

        String s2 = new StringBuilder("ja").append("va").toString();
        System.out.println(s2.intern() == s2); // false 因为常量池一开始就有 "java"
    }
}



网站公告

今日签到

点亮在社区的每一天
去签到