面试题系列Java基础

本文次要包含Java根底及面向对象相干面试题。

1,Java科普1.1 为什么安装包要分JDK和JRE?1.2 为什么Java语言是跨平台的?1.3 为什么装置完JDK后要设置环境变量?1.4 Java和C++区别2,数据类型&变量2.1 boolean占几个字节?2.2 为什么long能够主动转换为float?2.3 包装类型和根本数据类型的区别2.4 String,StringBuffer,StringBuilder的区别2.5 String s = “Hello”;s = s + “world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?2.6 String str =“i”;和 String str = new String(“i”);有区别吗?2.7 如何将字符串反转?2.8 Java有几种变量?2.9 援用数据类型蕴含哪几种?3,运算符3.1 ==和equals的区别3.2 &和&&区别(|和||同理)4,面向对象4.1 什么是面向对象?4.2 封装相干4.3 继承相干4.4 多态相干4.5 关键词static4.6 关键词final4.7 接口和抽象类的区别?4.8 为什么重写equals必须重写hashCode?

1,Java科普

1.1 为什么安装包要分JDK和JRE?

JRE次要蕴含JVM,用于运行Java程序。
JDK蕴含了JRE,除此之外,蕴含了比方像javac等程序开发须要用到的工具。

先来说说什么是JDK,JRE。

JDK:Java Development Kit Java开发工具包【开发Java程序用】

JRE:Java Runtiome Environment Java运行环境【运行Java程序用】

【注:下载的JDK包是蕴含了JDK和JRE的,JDK和JRE是逻辑上的辨别,两者在JDK下载的包中都有】

JDK与JRE的关系:以Java代码运行为例,编写好Java代码之后,通过javac将java源文件编译成class字节码文件,而后通过java命令,运行字节码文件。那么运行字节码的环境就是JRE。(JRE的外围就是JVM)

理解完JDK和JRE是什么之后,再聊聊为什么开发者过后要把一个安装包分成两局部呢?

平时应用的软件都是一键装置的,但JDK须要装置两次。JDK的发明者不会这么无聊,成心给开发者减少麻烦。

【我想】:这应该跟生产环境的部署问题无关,对于生产环境部署JDK还是JRE始终饱受争议,具体情况依据我的项目而定。

出于对性能的思考,尽可能的使服务器轻,能少装一个软件就少装一个,这样生产环境部署JRE就OK了。【又省了资源】

除了这个方面之外,还有一种可能。JDK的开发也有可能是分团队的,JDK和JRE可能是交由不同团队开发,JDK和JRE的耦合也可能因而而减小,从而放慢JDK的迭代版本。(毕竟当初JDK一年更新两次)

1.2 为什么Java语言是跨平台的?

JVM有两个性能
– 将class字节码转换为机器码
– 兼容不同的操作系统

跨平台和Java 虚拟机无关。

JVM有两个次要的性能:

  • 适配不同的操作系统的指令集(兼容不同的操作系统)
  • 翻译字节码文件为机器码执行

(Oracle官网上下载JDK,不同操作系统的JDK是不一样的,对应不同的虚拟机)

1.3 为什么装置完JDK后要设置环境变量?

在解决这个问题之前,先来理解一些环境变量是干嘛的:

环境变量是在操作系统中一个具备特定名字的对象,它蕴含了一个或者多个应用程序所将应用到的信息。例如Windows和DOS操作系统中的path环境变量,当要求零碎运行一个程序而没有通知它程序所在的残缺门路时,零碎除了在当前目录上面寻找此程序外,还应到path中指定的门路去找。用户通过设置环境变量,来更好的运行过程。

简略来说,运行一个程序(命令),操作系统会从当前目录寻找,或者从环境变量中寻找。

换句话说,如果在java,javac的目录下执行这个两个命令,是没有问题的。然而如果更换了目录,零碎在当前目录找不到,就会去环境变量中寻找。所以设置环境变量的基本目标是在电脑的任何一个文件夹下都能够编译运行Java程序。

1.4 Java和C++区别

题外话,Java和C++有什么区别?(据说有些面试官老爱干这种事)

  • C++反对多继承,Java反对单继承
  • Java有垃圾回收机制
  • Java不反对指针,更加平安

2,数据类型&变量

2.1 boolean占几个字节?

示意变量:4个字节(转换为int存储)
示意byte数组:1个字节

2.2 为什么long能够主动转换为float?

float,double采纳指数形式存储,能示意的数比long更大

System.out.println(Long.MAX_VALUE);
System.out.println(Float.MAX_VALUE);
System.out.println(Double.MAX_VALUE);
System.out.println(Float.MAX_VALUE>Long.MAX_VALUE);


9223372036854775807
3.4028235E38
1.7976931348623157E308
true

float和double应用指数示意,取值范畴在

-3.4*10^38 – 3.4*10^38

顺便看看float和double的精度:7位和16位。

2.3 包装类型和根本数据类型的区别

初始值:包装类型的初始值为null,根本数据类型的初始值基本上是0,char是’u000′
存储形式:包装类型存在堆里,根本数据类型存在栈中

2.4 String,StringBuffer,StringBuilder的区别

– 可变性
String底层应用fina润饰的数组实现,是不可变的,StringBuffer和StringBuilder是可变的
– 安全性
String不可变,天然线程平安,StringBuffer应用synchronized同步锁实现线程平安,StringBuilder是线程不平安的

  • 可变性

    String是不可变的,StringBuffer和StringBuilder是可变的

    String string1 = “111”;
    string1 = “222”;
    System.out.println(string1);

    string1指向222时,创立了一个新的对象并指向它

    String 底层应用final润饰的数组实现,故是不变的

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence {

    private final char value[];

  • 安全性

    StringBuffer和String是线程平安的,,StringBuilder是线程不平安的。

    String 中的对象是不可变的,也就能够了解为常量,线程平安。

    StringBuffer 对办法加了synchronized同步锁所以是线程平安的。

  • 对于三者应用的总结

    1. 操作大量的数据: 实用String
    2. 单线程操作字符串缓冲区下操作大量数据: 实用StringBuilder
    3. 多线程操作字符串缓冲区下操作大量数据: 实用StringBuffer

2.5 String s = “Hello”;s = s + “world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?

没有,只是指向了另外一个对象。

因为String被设计成不可变(immutable)类(final润饰),所以它的所有对象都是不可变对象。

在这段代码中,s原先指向一个String对象,内容是 “Hello”,而后对s进行了+操作

这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为”Hello world!”

原来那个对象还存在于内存之中,只是s这个援用变量不再指向它了。

2.6 String str =“i”;和 String str = new String(“i”);有区别吗?

前者会被JVM调配到常量池中,常量池中没有反复的元素,如果再次创立一个字符串变量等于i的话,就会间接指向常量池中的i。

后者是new了一个对象,堆中是容许对象反复的。

前者会被JVM调配到常量池中,常量池中没有反复的元素。

String str1 =“i”;
String str2 =“i”;

str2不会从新创立一个常量,而是指向str1。

String str1 = new String(“i”);
String str2 = new String(“i”);

str1会在堆内存中创建对象

str2还是会再次创立一个新的对象

2.7 如何将字符串反转?

应用StringBuilder或者StringBuffer的reverse()办法。

StringBuffer str1 = new StringBuffer(“12345”);
StringBuffer str2 = str1.reverse();
System.out.println(str2);

54321

2.8 Java有几种变量?

  • 类变量

    独立于办法之外,必须用static润饰

  • 实例变量

    独立于办法之外,不必static润饰

  • 局部变量

    办法中的变量

2.9 援用数据类型蕴含哪几种?

  • 接口
  • 数组

3,运算符

3.1 ==和equals的区别

equals用于比拟内容是否雷同(源自Object类,通常被重写)

==对于根本数据类型比拟值雷同,对于援用数据类型比拟内存地址是否雷同(是否是同一个对象)

知乎上十分形象的一张图:

3.2 &和&&区别(|和||同理)

& : 两边都为true时才为true

|:两边有一个为false即为false

短路逻辑运算符

&&:右边为fasle间接返回flase(不计算左边)

||:右边为true间接返回true(不计算左边)

就是为了简化计算量

^示意异或,雷同为false,不同为true

4,面向对象

4.1 什么是面向对象?

如果摒弃软件开发的领域,这是一种通过明确社会分工而提高效率的办法。

在软件开发的范畴内,就是通过形象出零碎性能而实现最大化代码复用的开发模式。

4.2 封装相干

  • 什么是封装

    通过暗藏实现,裸露接口,一来实现代码解耦,二来通过拜访修饰符保障数据安全。

4.3 继承相干

  • 继承的作用?

    实现代码复用

  • 继承的规定?

    • 子类继承父类非private的属性和办法
    • 子类能够扩大本人的属性和办法
  • 结构器是否会被继承?

    • 结构器不会被继承,但子类对象初始化时会调用父类无参结构器

      【为什么。子类和父类有最根本的依赖关系,比如说数据依赖】

    • 当父类显式写了有参结构器,且没有无参结构器。子类继承父类的时候必须显式的调用父类的有参结构器。调用的形式能够应用super(a,b)来调用。
  • 子类父类的初始化程序

    准则:动态优于非动态,父类优于子类

    – 父类动态变量,动态语句块
    – 子类动态变量,动态语句块

    – 父类非动态代码块,结构器
    – 子类非动态代码块,结构器

4.4 多态相干

  • 什么是多态?

    一类事物的多种体现状态。(比方手机有各种各样的品牌,但都属于手机这一类事物)

  • 如何体现多态?

    办法重载:针对本类的不同办法而言,办法名雷同,参数不同(个数,程序)【返回类型随便】

    办法重写:针对继承而言,除了办法体能够自定义外,其余必须与父类保持一致(办法名,返回类型,参数)

  • 向上转型&向下转型

    up:子类转换为父类,目标是拜访父类的公共办法,实现代码的复用和简洁(比方100个类把公共办法写在父类中,就不须要每个类都写一遍了)

    down:父类转换为子类,据说是为了调用子类的扩大办法。(为啥不间接new一个对象,已提交知乎问答)

4.5 关键词static

  • 润饰变量

    称为动态变量,类变量,全局变量

    可间接通过类名.变量名拜访

  • 润饰办法

    称为静态方法,类办法

    可通过类名.办法名间接拜访

    • 非static办法能够拜访static办法,static办法不能拜访非static办法

4.6 关键词final

  • 润饰类不能被继承
  • 润饰办法不能被重写
  • 润饰变量则变量变为常量

4.7 接口和抽象类的区别?

  • 继承与实现

    类只能单继承,但能够实现多接口

  • 办法是否能实现

    抽象类不仅能够做办法申明,也能够做办法实现。(接口只能做办法申明)

  • 修饰符

    接口的变量都默认采纳final润饰,办法采纳public润饰。

    抽象类可自定义。

4.8 为什么重写equals必须重写hashCode?

equals和hashCode位于Object类中,所有的类都会继承Object类。

equals通常被用来比拟对象的内容是否雷同,hashCode是用来返回对象Hash值的一种办法。

如果不重写hashCode会导致,equals雷同但hashCode不雷同,equals不雷同但hashCode雷同。

重写的目标一来为了防止hash抵触,二来进步对象访问速度。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理