Java基础面试题(最热门)
1.什么是编程?
为了使计算机能够了解人的意图,解决生活中的一些需求,人们利用编程语言进行计算机与人进行交流的方式。
2.Java到底是什么?
Java是一种可以撰写跨平台应用程序的、面向对象的程序设计语言。简单说,Java就是一种语言,不过是一种针对jvm的语言,Java编译后是字节码,而jvm会把这些字节码解释成机器码,然后做出相应的动作。
3.java的语言特性
java属于面向对象语言,具备封装,继承,多态三大特性。
封装:每个类不对外暴露其构造和实现,只展示自身的功能与作用
继承:同一父类的子类共同持有父类的公有(非private)资源
多态:同一父类的子类对于父类公有方法或资源,可以具备不同的表达方式
4.Java语言的平台分类
- Java SE:标准版,是为开发普通桌面和上午应用提供的解决方案,该技术体系是其他两者的基础,可以完成一些桌面应用程序的开发。
- Java ME:小型版,是为开发电子消费产品和嵌入式设备提供的解决方案。
- Java EE:企业版,是为开发企业环境下的应用程序提供的一套解决方案,该技术体系中包含的技术如Servlet、Jsp等,主要针对于Web应用程序开发。
5.什么是跨平台?
平台:指的是操作系统
跨平台:Java程序可以在任意操作系统上运行,一次编写到处运行
原理:不同的编译器对于不同平台,获取后的class文件在相同JVM中运行
6.JDK、JRE、JVM的内容在第一篇博客
7.什么是字节码?
Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,
只面向虚拟机,实现了跨平台(也就是0101这些数字)。
8.java注释是什么?
• 单行注释 格式: // 注释文字
• 多行注释 格式: /* 注释文字 */
• 文档注释 格式:/* 注释文字 */
9.==和equals的区别
1、功能不同
"=="是判断两个变量或实例是不是指向 同一个内存空间。(地址)
比较运算符,返回的就是一个布尔值
基本数据类型:比较的是值;
引用数据类型:比较的是两个对象的地址值;
"equals"是判断两个变量或实例所指向的 内存空间的值是不是相同。(内容)
2、定义不同
"equals"在JAVA中是一个方法。
"=="在JAVA中只是一个运算符号
3. 运行速度不同
equals():没有==运行速度快。
==:运行速度比equals()快,因为==只是比较引用。
10.Object类种常用的方法:toString 和 equals
只有对toString方法进行 重写 之后才能打印出对象的属性,如果不重写,则打印出地址值;
toString重写前:打印的是包名类名@地址值
重写后:打印的是对象中的属性值
equals : 判断两个对象是否相等(内容)。注意区分大小写。
重写前:比较的是对象的地址值
重写后:比较的是对象中的属性值
11.String类 , StringBuilder类 ,StringBuffer类的区别
(1)字符修改上的区别(主要)
String:不可变字符串;
因为字符串的底层是一个被final修饰的数组,不能改变,是一个常量。
StringBuffer:可变字符串、效率低、线程安全、多线程;
StringBuffer类中的方法都添加了synchronized关键字,也就是给这个方法添加了一个锁,用来保证线程安全。
StringBuilder:可变字符序列、效率高、线程不安全、单线程;
因为String对象是不可改变的,所以可以共享。
底层也是一个(byte类型的数组)数组,但是没有被final修饰,可以改变长度。
在内存中始终是一个数组,占用空间少,效率高,如果超出了StringBuilder的容量,会自动扩容。
(2)初始化上的区别,String可以空赋值,后者不行,报错
小结:(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder(推荐使用)。
String-->StringBuilder:可以使用StringBuilder的构造方法
StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容
StringBuilder-->String:可以使用StringBuilder的toString方法
12.StringBuilder的常用方法
append方法:添加任意类型数据的字符串形式,并返回当前对象自身
toString: 将当前StringBuilder对象转换为String对象
reverse:反转内容----->可以将java反转为avaj.
13.&与&&区别
&&是短路运算,如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。 导致结果单方面的侧向前面的运算结果.
&位与位的关系,表示and的作用,如果一边为false依旧执行&后的表达式
14.String类可以被继承吗?
不可以,因为String类底层是字符数组,被final修饰,不能继承。
15.构造方法
- 构造方法是一种特殊的方法,它是一个与类同名的方法。【方法名与类名相同】
- 构造方法和其他方法一样也【可以重载】
- 构造方法的名字必须与定义他的类名完全相同,【没有返回类型】,甚至连void也没有。
- 主要完成对象的初始化工作,构造方法的调用是在创建一个对象时使用new操作进行的。
- 不能被static、final、synchronized、abstract和native修饰。
- 构造方法【不能被子类继承】
16.创建对象的几种方法:
1.用new语句创建对象,这是最常用的创建对象的方式。
2.运用反射手段,调用Java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法。
3.调用对象的clone()方法。
4.运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法.
17.java中的控制语句:顺序结构、选择结构、循环结构
选择结构:if 和 switch;
循环结构:for循环 、 while循环 、 do...while循环
控制循环结束语句:break语句 (表示结束当前所在的循环)
continue语句:( 表示跳过当前循环,继而进行下一次循环)
return语句:(表示结束循环所在的方法,方法都结束了,循环结构自然也就结束了)
18.java程序的运行步骤
a. 编写:是指在 Java 开发环境中进行程序【代码的输入】,最终形成后缀名为【 .java】 的 Java 源文件。
b. 编译:是指使用 Java 【编译器】对源文件进行错误排査的过程,编译后将生成后缀名为【 .class 的字节码文件】,不像C语言那样生成可执行文件。
c. 运行:是指使用 Java 解释器【将字节码文件翻译成机器代码】,执行并显示结果。(Java解释器是JVM虚拟机的实现)
我们编写好的.java文件,通过编译器编译成.class的字节码文件,JVM负责加载解释字节码文件,并生成系统可识别的代码执行 (系统可识别的代码就是0101这种数字)
19.Java序列化
是指把Java对象转换为字节序列的过程;
20. 抽象类和接口的区别:
抽象类可以实现接口
1.抽象类可以有构造方法,接口中不能有构造方法。(因为接口不能被实例化)
2.抽象类中可以有普通成员变量,接口中没有普通成员变量
3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型),但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
5. 抽象类中可以包含静态方法,接口中不能包含静态方法(静态方法static,而接口为public abstract)
6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,
但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
7. 一个类可以实现多个接口,但只能继承一个抽象类。
8. 抽象类可以被继承,不能被实例化,也就是new,接口可以被继承
总之:
a.实现: 抽象类子类使用extends来继承
接口必须使用implements来实现
b.构造函数:
抽象类可以有
接口没有
c.Main方法:
抽象类可以有并能运行
接口没有
d.实现数量:
类可以实现很多个接口,但只能继承一个抽象类
e.访问修饰符:
抽象类可以任意访问修饰符
接口 方法中默认 使用public修饰
21.类的实例化顺序 【 先静态、先父后子】
先静态:父静态 > 子静态 。
优先级:父类 > 子类 , 静态代码块 > 非静态代码块 > 构造函数。
22.静态变量,静态方法,静态代码块的区别
1. 静态成员变量
声明为static关键词修饰的变量叫做静态成员变量,也叫作全局变量。被static修饰的成员变量和成员方法独立于该类的任何对象。
也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内找到他们。
因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
2. 静态代码块
static 代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,
JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,
每个代码块只会被执行一次。在静态方法里面只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。
因为对于非静态的方法和变量,需要先创建类的实例对象后方可使用,而静态方法在使用前不用创建任何对象。
声明方式:
static
{
//do something
}
3. 非静态代码块
非静态代码块的执行顺序在构造方法执行之前,类每new一次都会执行。
声明方式:不加任何修饰符
{
//do something
}
4. 静态方法
静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,
不能直接访问所属类的实例变量和实例方法 (就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。
因为类所属的实例变量和实例方法需要对象创建之后才会存在。
声明方式:
public static void dosomething()
{
//do something
}
23.final关键字
可以修饰一个类,一个方法,一个局部变量,一个成员变量
a. final修饰一个类时,当前这个类不能有任何子类,并且其中所有的成员方法都【无法进行覆盖重写】(因为没有子类),当用final修饰一个类时,表明这个类【不能被继承】
b. final修饰一个方法时,这个方法就是最终方法,也就是不能被覆盖重写。并且abstract关键字和final关键字不能同时使用,因为矛盾。
c. final修饰一个局部变量时,一旦使用final修饰局部变量,那么这个变量就不能进行更改。【“一次赋值,终生不变”】。
对于基本类型来说,不可变的是变量当中的数据不可改变,不可重新赋值。
对于引用类型来说,不可变的是变量当中的地址值不可变,重新赋值后数据可以改变。
d. final修饰一个成员变量时,由于成员变量具有默认值,所以用了final之后必须手动赋值,不会再给默认值了;
对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值;
必须保证类当中所有重载的构造方法,都最终会对final的成员变量进行赋值。
24.局部变量运行的步骤:
a. 局部变量是跟着方法走的,在栈内存当中;
b. 方法运行结束后,立刻出栈,局部变量就会立刻消失;
c. 但是new出来的对象会在堆当中持续存在,直到垃圾回收消失。
25.包装类
概念:基本数据类型的数据,使用起来非常方便,但是没有对应的方法来操作这些数据,
所以我们可以使用一个类,把基本数据类型的数据包装起来,这个类叫做包装类
在包装类中可以定义一些方法,用来操作基本数据类型的数据。
注意:int----->Integer char----->Character
ArrayList集合无法直接存储整数,但可以存储Integer包装类
·包装类中的装箱:(把基本数据类型的数据包装在那个类中) 从基本数据类型转换为对应的包装类对象 int----->Integer
可以使用构造方法 : Integer(int value) 构造一个新分配的 Integer对象,该对象表示指定的 int值。
Integer(String s) 构造一个新分配 Integer对象,表示 int由指示值 String参数。
传递的字符串必须是基本数据据类型,否则抛出异常
可以使用静态方法 : public static Integer valueOf(String s) 返回一个Integer物体保持在指定的值String 。
public static Integer valueOf(int i) 返回一个Integer指定的int值的Integer实例。
·包装类中的拆箱:(打开那个箱子,取出基本数据类型) 从包装类对象转换为对应的基本类型 Integer----->int
可以使用成员方法 : int intValue() 以 int 类型返回Integer的值
· 自动装箱:把基本数据类型转换为包装类类型。 int类型自动转换为Integer包装类
Integer in=1;--------->就相当于Integer in=new Integer(1);
· 自动拆箱:把包装类类型转换为基本数据类型。Integer包装类自动转换为int类型
in+2;就相当于in.intValue() + 3=3;
in=in+2;就相当于in=new Integer(3) 自动装箱
26.基本类型与字符串之间的转换
基本类型----->字符串
a.基本类型数据的值+"" (最简单)
b.使用包装类中的静态方法 toString()
c.使用String类的静态方法 valueOf()
字符串----->基本类型
a.使用包装类中的静态方法parseXXX(“字符串”)
public static byte parseByte(String s):将字符串参数转换为对应的byte基本类型。
public static short parseShort(String s):将字符串参数转换为对应的short基本类型。
......
b.使用包装类中的 valueOf() 方法
27.API是什么?
可以理解为Java自己提供的标准类库,开发人员可直接使用其方法,而不用进行源码实现。
如常用的打印方法:System.out.println();,这是Java自己提供的东西。
官方解释:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,
目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
Java中常用的API有哪些:System类 StringBuffer&StringBuilder类 Math数学类 日历时间格式 Runtime类 包装类
28.迭代器 (对集合进行遍历)(通用的取出元素中集合的方法)
迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样)
原理:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,
如果还有就再取出来,一直把集合中的所有元素全部取出。
使用迭代器遍历集合的时候,不能对集合直接进行操作,比如add、remove等等,这是因为迭代器是
在进行遍历操作之前创建的,如果一边迭代一边操作集合本身,则会造成集合和迭代器不同步,JVM
会报异常,如果要删除元素,则可以使用迭代器的remove()方法而不是集合的remove()方法。
Iterator迭代器,是一个接口,无法直接使用,需要使用Iterator接口的实现类对象,获去实现类
的方式比较特殊, Iterator<E> iterator() 返回在此collection的元素上进行迭代的迭代器
迭代器的使用步骤:a.使用集合中的方法iterator()获取迭代器的实现类对象,并且把指针(索引)指向集合的-1索引 Iterator<String> it=coll.iterator();
b.使用iterator接口中的方法hasNext判断还有没有下一个元素 boolean b = it.hasNext(); 或者 while (it.hasNext()){
c.使用iterator接口中的方法.next取出集合中的下一个元素 String s = it.next();
29.增强for循环 (只用来遍历)
专门用来遍历数组和集合的。内部其实是一个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作
格式: for(数组/集合的数据类型 变量名:数组名/集合名){
sout(变量名);
}
30.泛型
是一种未知的数据类型,当不知道使用什么数据类型的时候,可以使用泛型
泛型也可以看成是一个变量,用来接收数据类型 例如:E e :Element元素 T t :Type类型
好处:a.避免了类型转换的麻烦,存储的是什么类型,取出的就是什么类型
b.把运行期异常(代码运行之后会抛出的异常),提升到了编译期(写代码的时候会报错)
弊端:泛型是什么类型,只能存储什么类型的数据
不使用泛型的好处:集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
弊端:不安全,会引发异常
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用“?” ,?表示未知通配符(可以接收任意类型)。
此时只能接受数据,不能往该集合中存储数据
泛型的上限限定:? extends E 代表使用的泛型只能是E的子类或者本身
泛型的下限限定:? super E 代表使用的泛型只能是E的父类或者本身
31.静态方法怎么被调用
a. 类名.方法名
b.对象名.方法名
32.数据存储的常用结构有:栈,队列,数组,链表,红黑树。
栈 【先进后出】
先存进去的元素要在它后面存进去的元素依次取出后,才能取出该元素
先进后出原因:入口和出口都是在栈的顶端位置
队列【先进先出】
存进去的元素要在它前面的元素依次取出后,才能取出该元素
先进先出的原因:队列的入口和出口各占一侧
数组【查询快,增删慢】
数组是在内存中开辟一段连续的空间,并在此空间存放元素
特点:查询快(数组的地址是连续的,可以通过数组的首地址找到数组,通过索引,可以快速访问指定位置的元素 )
增删慢(数组的长度是固定的,要增加或删除一个元素,必须创建一个新数组,把源数组的数据复制过来)
(在堆内存中,频繁的创建数组,复制数组中的元素,销毁数组,效率低下)
链表 【查询慢,增删快】
链表:链表是相同类型的若干个【结构体】用其自身携带的指【针按】照一定【顺序串联】成的一个链。
有一系列结点node(链表中每一个元素成为结点)组成,节点可以在运行时动态生成,每个结点包括
一个结点包含一个是存储数据元素的数据域,另一个是存储本节点地址的指针域和下一个结点地址的指针域。
查询慢:链表中的地址不是连续的,每次查询元素,都必须从头开始查询
增删快:链表结构增加或删除一个元素,对链表的整体结构没有影响,所以增删快
链表结构有单向链表和双向链表
单向链表:链表中只有一条链子,不能保证元素的顺序(存储元素和取出元素的顺序可能不一致)
双向链表:链表中有两条链子,有一条链子是专门记录元素的顺序,是一个有序的集合
红黑树 【查询快】
红黑树是一种自平衡的二叉查找树,是一种高效的查找树。
a. 二叉树:是每个结点不超过2的有序树(每个结点上都最多只能有两个子结点) 顶上的叫根节点,两边被称作“左子树”和“右子树”。
b. 排序树(查找树):在二叉树的基础上,元素是有大小顺序的,左子树小,右子树大
c. 平衡树:左孩子和右孩子相等
d. 不平衡树:左孩子!=右孩子
红黑树特点:趋近于平衡树,查询速度非常快,查询叶子结点最大次数和最小次数不能超过2倍
红黑树约束: 节点是红色或者黑色
根节点是黑色
叶子结点(空节点)是黑色的
每个红色的节点的子节点都是黑色的
任何一个节点到其每一个叶子结点的所有路径上的黑色节点数相同
33.每个类里都会默认继承一个Object类,还会默认有一个无参构造方法
因为要实例化
34.类与类之间的关系:
继承关系:继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力
实现关系: 实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系
35.创建字符串的方法
1)通过引用【字符数组】来创建字符串
char a[]={'A','b','c','E'};
String str1=new String(a);
System.out.println(str1);
2)【先定义后赋值】
String str2;
str2="this is a book";
System.out.println(str2);
3)通过【截取字符数组的一部分】来创建字符串
char a3[]={'a','b','c','D','6','p'};
String str3=new String(a3,2,4);
System.out.println(str3);
4)通过类的【实例化对象】方法实例化一串字符来创建字符串
String str4=new String("this is a book");
System.out.println(str4);
36.直接使用 .toString 方法只会打印出数组的地址,用 Arrays.toString 方法才会打印出数组
37.String s=new String(“xyz”)创建了几个对象
创建了一个或两个
当常量池中没有其对象时创建两个一个在常量池中,另一个放在堆内存中
如果常量池中有则创建一个在堆内存中
38.什么是字符串常量池
字符串常量池位于堆内存中,专门用于存储字符常量,提高内存使用率,在创建字符串时jvm会先检查字符串常量池,
如果字符串已经存在池中则返回他的引用,如果不存在则实例 化一个字符串放到池中,返回其引用
***jdk1.6常量池在方法区
***jdk1.7常量池在堆里面
39.成员变量和局部变量
a.在类中的位置不同
成员变量:在类中,方法外;
局部变量:在方法中;
b.作用范围不同
成员变量:类中;
局部变量:方法中;
c.在内存中的位置不同
成员变量:堆内存;
局部变量:栈内存;
d.初始值不同
成员变量:有默认值;
局部变量:没有默认值,必须定义,赋值,最后使用。
e.生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失;
局部变量:随着方法的调用而存在,随着方法的调用完毕而结束;
40.this关键字用法
1.直接引用
2.形参与成员名字重名可以区分 (this.name = name)
3.引用本类的构造函数 (在一个多参数的构造方法中,调用参数少的构造方法)
41.super关键字用法
1.直接引用
2.子类中的成员变量或者方法与父类中的成员变量或方法同名时,用super区分
3.引用父类构造函数
42.构造器是否可以被重写?
构造器不能被继承,因此不能被重写但是可以被重载
43…内部类的种类
成员内部类;局部内部类;静态内部类;匿名内部类。
文章到此就结束了。
喜欢的可以点赞关注哦,也可以在评论区留下宝贵的意见呐❥❥~**
不足之处,欢迎雅正留言!