万字干货|Java基础面试题(2022版)

作者:小牛呼噜噜 | https://xiaoniuhululu.com
计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」

概念常识

Java 语言有哪些特点?

  1. 简单易学

Java 会让你的工作变得更加轻松,使你把关注点放在主要业务逻辑上
尤其是Java语言 没有指针,并提供了 自动的垃圾回收机制,使得程序员不必为内存管理而担忧

  1. 面向对象

具有代码扩展,代码复用等功能,其三大核心概念: 封装,继承,多态
详情见:https://mp.weixin.qq.com/s/Q1hABlF4kBhcyf3vnLrtFQ

  1. 支持多平台

在一个平台上编写的任何应用程序都可以轻松移植到另一个平台上, 是Java 虚拟机实现平台无关性

  1. 安全性

Java 被编译成 字节码,由 Java 运行时环境解释。编译后会将所有的代码转换为字节码,人类无法读取。它使开发无病毒,无篡改的系统/应用成为可能

  1. 健壮性

Java 有强大的内存管理功能,在编译和运行时检查代码,它有助于消除错误。

  1. 支持多线程

多线程是指允许一个应用程序同时存在两个或两个以上的线程,用于支持事务并发和多任务处理。
C++ 语言没有内置的多线程机制,因此必须调用操作系统的多线程功能来进行多线程程序设计,而 Java 语言却提供了多线程支持
Java除了内置的多线程技术之外,还定义了一些类、方法等来建立和管理用户定义的多线程。

  1. 动态性

它具有适应不断变化的环境的能力,Java程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。它能够支持动态内存分配,从而减少了内存浪费,提高了应用程序的性能。

  1. 分布式

Java 提供的功能有助于创建分布式应用。使用 远程方法调用(RMI),程序可以通过网络调用另一个程序的方法并获取输出。您可以通过从互联网上的任何计算机上调用方法来访问文件。这是革命性的一个特点,对于当今的互联网来说太重要了。

  1. 高性能

Java 最黑的科技就是字节码编程,Java 代码编译成的字节码可以轻松转换为本地机器代码。
如果解释器速度不慢,Java可以在运行时直接将目标代码翻译成机器指令,翻译目标代码的速度与C/C++的性能没什么区别。通过 JIT 即时编译器来实现高性能。

JVM、JRE和JDK的关系

  • JVM

Java 虚拟机(JVM)是运行 Java 字节码的虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,JVM在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够”一次编译,到处运行”的原因。因此Java语言可以实现跨平台。
字节码和不同系统的 JVM 实现是 Java 语言”一次编译,随处可以运行”的关键所在。
只要满足 JVM 规范,任何公司、组织或者个人都可以开发自己的专属 JVM。

  • JRE

JRE(Java Runtime Environment)是 Java 运行时环境。包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,但是系统缺省加载这个包,不能用于创建新程序。

  • JDK

Java Development Kit是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等,它能够创建和编译程序。

万字干货|Java基础面试题(2022版)

什么是字节码?

字节码:Java源代码编译后产生的文件(即扩展名为.class的文件)。

.java源码是给人类读的,而.class字节码只面向JVM(Java虚拟机)

采用字节码的好处:

  • Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效的(但和无需GC的语言 c、c++、rust等的运行效率还是有所差距)
  • 由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。

一般Java程序运行的流程:

Java源代码—->编译器—->jvm可执行的Java字节码(即虚拟指令)—->jvm—->jvm中解释器—–>机器可执行的二进制机器码—->程序运行

万字干货|Java基础面试题(2022版)

为什么说 Java 语言是”编译与解释并存”?

由于计算机只看得懂0100011机器码,语言像C语言,是给人看的。我们通过这些语言编写出来的代码,需要先转换成机器码,然后计算机才能去执行。

  • 编译型 :先将源代码一次性转换成另一种相对来说更低级的语言(字节码,汇编,机器码…),计算机再去执行。常见的编译性语言有 C、C++、Go、Rust 等等。

注意这边的机器码 是代码对应的平台计算机的机器码

  • 解释型 :解释器动态将代码逐句解释(interpret)为机器码(编译器自身的机器码)并运行(边解释边执行)。常见的解释性语言有 Python、JavaScript、PHP 等等。

为什么经常说java是解释性语言也是编译型语言?

JVM的类加载器首先加载字节码文件,然后通过解释器逐行解释执行,每次执行都需要加载、解析,速度慢,还有热点代码重复加载问题。所以引进了JIT编译器(运行时编译),JIT完成一次编译后会将字节码对应的机器码保存下来,下次直接执行。

解释和编译都只是程序从源码到运行时的一种动作,跟语言本身无关,所以我们无需过于纠结这个问题!

Oracle JDK 和OpenJDK的区别

Java最早由SUN公司(Sun Microsystems,发起于美国斯坦福大学,SUN是Stanford University Network的缩写)发明,2006年SUN公司将Java开源,此时的JDK即为OpenJDK。
OpenJDK是Java SE的开源实现,他由SUN和Java社区提供支持,2009年Oracle收购了Sun公司,自此Java的维护方之一的SUN也变成了Oracle。
大多数JDK都是在OpenJDK的基础上编写实现的,比如IBM J9,Azul Zulu,Azul Zing和Oracle JDK。几乎现有的所有JDK都派生自OpenJDK,
他们之间不同的是许可证:

  • OpenJDK根据许可证GPL v2发布。
  • Oracle JDK根据Oracle二进制代码许可协议获得许可。

Oracle JDK 比 OpenJDK 更稳定。在响应性和JVM性能方面,Oracle JDK与OpenJDK相比提供了更好的性能
OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。

OpenJDK 是一个参考模型并且是完全开源的,
但是Oracle JDK是OpenJDK的一个实现, 并不是完全开源的

Java 和 C++ 的区别?

Java 和 C++ 都是面向对象的语言,都支持封装、继承和多态,但是它们还是有挺多不相同:

  • Java 不提供指针来直接访问内存,程序内存更加安全
  • Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承。
  • Java 有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存。
  • 等等

什么是JIT?

JIT是just in time的缩写,也就是 即时编译。通过JIT技术,能够做到Java程序执行速度的加速。

Java通过编译器javac先将源程序编译成与平台无关的Java字节码文件(.class),再由JVM解释执行字节码文件,从而做到平台无关。 但是,有利必有弊。对字节码的解释执行过程实质为:JVM先将字节码翻译为对应的机器指令,然后执行机器指令。很显然,这样经过解释执行,其执行速度必然不如直接执行二进制字节码文件。

而为了提高执行速度,便引入了 JIT 技术。当JVM发现某个方法或代码块运行特别频繁的时候,就会认为这是”热点代码”(Hot Spot Code)。然后JIT会把部分”热点代码”编译成本地机器相关的机器码,并进行优化,然后再把编译后的机器码缓存起来,以备下次使用。

Java关键字

final finally finalize区别

final可以修饰类、变量、方法

  • 修饰类表示该类不能被继承
  • 修饰方法表示该方法不能被重写
  • 修饰变量表示该变量是一个常量,不可变,在编译阶段会存入常量池中

finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块
中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。

finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调
用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的
最后判断。

聊聊this、super和static关键字

  1. this关键字

this表示当前对象的引用:
this.属性 区别成员变量和局部变量
this.() 调用本类的某个方法
this() 表示调用本类构造方法,只能用在构造方法的第一行语句。
this关键字只能出现在非static修饰的代码中

public class Member {
    String name;
    public void setName(String name) {
        this.name = name;
    }
}
  1. super关键字

super可以理解为是指向自己超(父)类对象的一个”指针”,而这个超类指的是离自己最近的一个父类。:
super.属性 表示父类对象中的成员变量
super.方法()表示父类对象中定义的方法
super() 表示调用父类构造方法
可以指定参数,比如super(“Nanjin”);
任何一个构造方法的第一行默认是super();
可以写上,如果未写,会隐式调用super();
super()只能在构造方法的第一行使用。
this()和super()都只能在构造的第一行出现,所以只能选择其一。
写了this()就不会隐式调用super()。
super 关键字在子类中显式调用父类中被覆盖的非静态成员方法和成员变量

class Father {

  void message() {
    System.out.println("This is Father");
  }

}

class Son extends Father {
  void message() {
    System.out.println("This is son");
  }

  void display() {
    message();
    super.message();
  }

}

class Main {
  public static void main(String args[]) {
    Son s = new Son();
    s.display();
  }

}

结果:

This is son
This is father

  1. static关键字

static的主要意义是在于创建独立于具体对象的域变量或者方法。 以致于即使没有创建对象,也能使用属性和调用方法
static修饰的变量称之为静态变量
被static修饰的变量或者方法是独立于该类的任何对象,即这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享。
static修饰的方法称之为静态方法
静态方法属于class而不属于实例,因此,静态方法内部,无法访问this变量,也无法访问实例字段,它只能访问静态字段
static修饰的代码块叫做静态代码块。

被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。用法:”类.静态变量”

  1. 能否在static环境中访问非static变量?
不能, static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员和静态方法,因为当static方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。同理,static方法也不能访问非static类型的变量。
  1. this与super关键字的区别

  2. this 表示当前对象的引用,可以理解为指向对象本身的一个”指针”,但是JAVA中是没有指针这个概念的。

  3. super 表示自己超(父)类对象的引用,可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。
  4. super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
  5. this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

相同点:

super()和this()均需放在构造方法内第一行。
this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

拓展:https://mp.weixin.qq.com/s/tsbDfyYLqr3ctzwHirQ8UQ

Java 有没有 goto

goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。

基础语法

Java 中的基本数据类型有哪些?

Java 中有 8 种基本数据类型,分别为:

基本类型 位数 字节 默认值 包装类 取值范围 byte 8 1 0 Byte -128 ~ 127 short 16 2 0 Short -32768 ~ 32767 int 32 4 0 Integer -2147483648 ~ 2147483647 long 64 8
0L

Long -9223372036854775808 ~ 9223372036854775807 char 16 2 ‘u0000’ Character 0 ~ 65535 float 32 4
0f

Float 1.4E-45 ~ 3.4028235E38 double 64 8
0d

Double 4.9E-324 ~ 1.7976931348623157E308 boolean 1

false Boolean true、false

其中:

char a = ‘hello’; 单引号
String a = “hello” ;双引号

包装类型的缓存机制

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能:
Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,如果 超出对应范围仍然 会去创建新的对象
另外两种浮点数类型的包装类 Float,Double 并没有实现缓存机制。

Integer i1 = 10;
Integer i2 = 10;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1 == i2);// 输出 true
System.out.println(i3 == i4);// 输出 false

什么是自动类型转换、强制类型转换?

Java 数值型变量经常需要进行相互转换,当把⼀个表数 范围⼩的数值或变量直接赋给另⼀个表 数 范围⼤的变量时,可以进⾏ ⾃动类型转换,即 隐式转换

long l = 100;

int i = 200;
long ll = i;

反之,需要 强制类型转换(显式转换)

short s = 199;
int i = s;// 199

double d = 10.24;
long ll = (long) d;// 10, 精度丢失

自动类型转换规则如下:

  • 数值型数据的转换:byte→short→int→long→float→double。
  • 字符型转换为整型:char→int。

一些常见的易错题:

  1. float f=3.4; 程序正确吗?

3.4 是单精度数,将双精度型(double)赋值给浮点型(float)属于下转型会造成精度损失,因此需要强制类型转换 float f =(float)3.4; 或 者写成 float f =3.4F;

  1. 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. int count = 100000000; int price = 1999; long totalPrice = count * price;正确吗?

不正确,编译没任何问题,但结果却输出的是负数,这是因为两个 int 相乘得到的结果是 int, 相乘的结果超出了 int 的代表范围。这种情况,一般把第一个数据转换成范围大的数据类型再和其他的数据进行运算。

Math.round(11.5) 等于多少?Math.round(-11.5)等于多少

四舍五入的原理是在参数上加 0.5 然后进行下取整。

  1. Math.round(11.5)的返回值是 12
  2. Math.round(-11.5)的返回值是-11

用最有效率的方法计算 2 乘以 8

2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。

运算符 | 和 ||,& 和 && 的区别

|& 定义为位运算符。
||&& 定义为逻辑运算符,

& 按位与操作,按二进制位进行” “运算。运算规则:(有 0 则为 0)
| 按位或运算符,按二进制位进行” “运算。运算规则:(有 1 则为 1)

`java
A = 0011 1100
B = 0000 1101

Original: https://www.cnblogs.com/xiaoniuhululu/p/16469781.html
Author: 小牛呼噜噜
Title: 万字干货|Java基础面试题(2022版)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/577872/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 企业DevOps之路:jenkins 搭建

    安装 jdk8.0 下载jdk8.0 https://ftp-new-pc.pconline.com.cn/pub/download/201903/pconline15521980…

    Linux 2023年5月27日
    0112
  • 【Linux】socket通信编程

    socket通信 * – socket简介 – socket操作API函数 – 代码实现 socket简介 网络层的”ip地址&#8…

    Linux 2023年6月13日
    0100
  • 配置git环境与项目创建

    主要用于记录上课笔记,方便以后复习 acgit的地址:https://git.acwing.com/wyw/kob1/ 1. 项目模块的包含 1.1 采用前后端分离 Web端大概框…

    Linux 2023年6月6日
    0123
  • Nginx禁止ip加端口访问

    使用 iptables 限制对应端口,再利用Nginx将80端口转发到对应端口 CentOS7默认的防火墙是 firewalle,先看看服务器中有没有安装 iptables [ro…

    Linux 2023年6月14日
    0101
  • Spring cloud gateway 如何在路由时进行负载均衡

    本文为博主原创,转载请注明出处: 1.spring cloud gateway 配置路由 在网关模块的配置文件中配置路由: 其中lb表示采用了负载均衡,user-server表示服…

    Linux 2023年6月14日
    094
  • shell笔记

    shell脚本学习笔记 1.Shell入门简介 Shell是操作系统的最外层, Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程序。shell通过提示您输入,向操作…

    Linux 2023年6月7日
    078
  • 汉诺塔

    设计并实现一个游戏:汉诺塔。完成这个实验,涉及C++面向对象编程以及基本的数据结构知识(如栈和队列)但具此次实现并没有使用STL库。 1. 汉诺塔问题 汉诺塔是一个著名的数学问题。…

    Linux 2023年6月13日
    0103
  • tcpreplay重放报文,tcpdump能抓到包,应用程序收不到包

    现象: 生产环境中有两台服务器A、B,A服务器实时有报文发往B服务器。为了在测试环境测试新功能,故在现网A服务器上tcpdump抓取发往B服务器的报文,然后在测试环境tcprewr…

    Linux 2023年5月27日
    0166
  • JMeter压测出现“the target server failed to respond“的解决办法

    压测接口的时候,遇到了这个问题,在网上找到解决方案,试一下还挺管用,800并发没改前20%以上的报错率,改完800并发0.00%报错率。 感谢曲健老师的分享 解决方案如下: 修改执…

    Linux 2023年6月8日
    095
  • 常见的Redis面试”刁难”问题,值得一读

    字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。 如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog、Geo、P…

    Linux 2023年5月28日
    094
  • shell operator EOF shell 操作符 << <<<

    总结: 这些被叫做shell操作符 shell operator 主要分为 control operators和redirection operators < Origina…

    Linux 2023年5月28日
    0105
  • 【论文笔记】(模型压缩)Do Deep Nets Really Need to be Deep?

    摘要 作者通过模型压缩(model compression)使浅层的网络学习与深层网络相同的函数,以达到深层网络的准确率(accuracy)。当与深浅模型的参数量相同时,浅层模型可…

    Linux 2023年6月7日
    0113
  • redis 突然大量逐出导致读写请求block

    redis作为缓存场景使用,内存耗尽时,突然出现大量的逐出,在这个逐出的过程中阻塞正常的读写请求,导致 redis 短时间不可用; redis 中的LRU是如何实现的? 逐出qps…

    Linux 2023年5月28日
    095
  • 复古冰雪传奇H5游戏详细图文架设教程

    前言 想体验复古传奇的热血PK吗?想体验满级VIP的尊贵吗?想体验一刀99999的爽快吗?各种极品炫酷时装、坐骑、翅膀、宠物通通给你,就在复古冰雪传奇H5! 本文讲解冰雪传奇架设教…

    Linux 2023年6月7日
    0117
  • 5.6 Linux Vim撤销和恢复撤销快捷键

    使用 Vim 编辑文件内容时,经常会有如下 2 种需求: 对文件内容做了修改之后,却发现整个修改过程是错误或者没有必要的,想将文件恢复到修改之前的样子。 将文件内容恢复之后,经过仔…

    Linux 2023年6月7日
    0115
  • Java基础系列–07_String、StringBuffer和StringBuilder

    String类(1)字符串:字符串是 常量;它们的值在 创建之后不能更改,存储在堆中。如果字符串多次赋值,其实是每次重新赋值的时候程序都先在内存中寻找已开辟的空间是否存在该值;如果…

    Linux 2023年6月7日
    083
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球