【Java高频面试题】这些很常见的java面试题,你真的知道怎么回答?
因为明天还有个面试,今天把Java基础,最基础的知识在巩固一下,比较高深的知识可以不熟悉,在基础这方面一定不能出错,加油加油!
也希望您能耐心看完,是否自己对于基础掌握的很扎实。希望本文能对各位有所帮助。
文章目录
- 自增变量
- 1.i++和++i的区别
- 2.单例模式
- 3.类初始化顺序
- 4.实例初始化顺序
- 5.递归和迭代
- 6.参数的传输机制
- 7.成员变量和局部变量
- 8.位运算
- 9.冒泡排序
- 10.选择排序
- 11.插入排序
- 12.重载和重写的区别:
- 13.垃圾回收机制
- 14.为什么要有包装类?
- 15.**说明内存泄漏和内存溢出的区别和联系,结合项目经验描述**Java 程序中如何检测?如何解决?
- 16.序列化
- 17.你能想到的创建对象的方式?
- 18.问到接口和抽象类的区别
- 19.**同步代码块和同步方法有什么区别**
- 20.**静态内部类和内部类有什么区别**
- 21.**可序列化对象为什么要定义 serialversionUID 值?**
- 22.选择switch和if
- 23.基本正则
- 24.**try{}里面有一个 return 语句,那么紧跟在这个 try 后的**finally, 里面的语句在异常出现后,都会执行么?为什么?
- 25.**如何将日期类型格式化为:2013-02-18 10:53:10?**
- 26.匿名内部类是否可以继承其他类,或者实现其他接口?
- 27.**内部类可以引用它的包含类(外部类)的成员吗?有没有什么**限制?
- 28.**Java 反射技术主要实现类有哪些,作用分别是什么?**
- 29.**Class 类的作用?生成 Class 对象的方法有哪些?**
- 30.**反射的使用场合和作用、及其优缺点**
自增变量
1.i++和++i的区别
分为局部变量表和操作数栈
i++和++i的操作是直接修改的是局部变量表中的值
2.单例模式
要点:
- 一个类只能有一个实例
- 私有化构造器
- 该单例类必须自主的创建这个实例
- 该类必须有一个静态变量来保存这个实例
- 该类需要自行的向整个系统提供这个实例
- 直接暴露
- 调用静态变量的get方法
饿汉式:直接创建出这个类的单例,不管需不需要使用
- 直接实例化饿汉式(简介直观)
public class Singleton1 {
//静态变量保存这个类的单例
public static final Singleton1 INSTANCE = new Singleton1();
//私有化构造器
private Singleton1(){
}
}
- 枚举式
public enum Singleton2 {
INSTAANCE
}
- 静态代码块的方式
/**
* 使用静态代码块的方式创建单例模式
*/
public class Singleton3 {
public static final Singleton3 INSTANCE ;
static {
INSTANCE = new Singleton3();
}
private Singleton3(){
}
}
懒汉式:需要的时候再创建该类的单例,不需要就不创建
- 线程不安全的方式(适用于单线程的情况)
public class Singleton4 {
static Singleton4 INSTANCE;
private Singleton4(){
}
public static Singleton4 getInstance(){
if (INSTANCE ==null){
INSTANCE = new Singleton4();
}
return INSTANCE;
}
}
- 线程安全的方式(适用于多线程的情况)
/**
* @author 雷雨
* @date 2020/10/26 18:49
*/
public class Singleton5 {
static Singleton5 INSTANCE;
private Singleton5(){
}
public static Singleton5 getInstance(){
//为了效率
if (INSTANCE ==null){
//为了线程安全
synchronized (Singleton5.class){
if (INSTANCE ==null){
INSTANCE = new Singleton5();
}
}
}
return INSTANCE;
}
}
3.类初始化顺序
由父及子,静态先行,由上到下
- 有main方法的类优先初始化,但是如果该类是子类,那需要先初始化其父类
- 静态分为:静态变量和静态代码块,如果既有静态变量又有静态代码块,那么谁的位置靠上,谁先初始化
类初始化方法就是执行< clinit >()方法
4.实例初始化顺序
实例初始化方法就是执行< init >()方法
- < init >()方法可能重载有多个,有几个构造器就有几个< init >()方法
- < init >()方法由非静态实例变量显示赋值代码和非静态代码块,对应构造器代码组成
顺序:
- 非静态实例变量显示赋值代码和非静态代码块代码从上到下顺序执行,而对应的构造器的代码最后执行
- 每次创建实例对象,调用对用构造器,执行的就是对应的< init >()方法
- 除此之外如果该类是子类,那么父类的相关实例初始化先执行
也就是说:
子类的实例初始化方法:
- super()
- 顺序执行子类的非静态变量显示赋值语句和非静态代码块
- 子类的无参构造
影响初始化顺序的还有:重写方法
- 非静态方法前面有一个默认的对象this
- this在构造器(< init >()),它表示正在创建的对象,如果此时创建的是子类的对象,那么执行的就是子类的非静态方法
哪些方法不能被重写?
- final方法
- 静态方法
- private等子类中不可见的方法
重写和重载的区别和联系?
重写的要求
- 方法名
- 形参列表
- 返回值类型
- 抛出的异常
- 修饰符
5.递归和迭代
如何在算法题中选择是使用递归还是迭代呢?
- 递归
递归的特点其实是循环调用自身,那么之所以能够循环的调用自身的原因就是子问题有重复性
在算法题中,如果一个问题是能够被分解为子问题的,而且子问题有明显的重复性,那么就可以使用递归方法。
- 迭代
迭代实际上就是将子问题抽象,然后进行总结,观察期规律,然后生成新的状态转移方程,然后使用for loop的形式解决
使用递归的方式思考相对比较容易,不需要额外的抽象和总结,但是比较深层次的递归可能会造成栈溢出问题。
6.参数的传输机制
- 如果传输的是基本数据类型
- 传递数据值
- 实参时引用数据类型
- 传递地址值
- 特殊的类型:String的不可变性,包装类等对象的不可变性
- String不可变,可能会重新生成新的字符串,让其绑定新的地址
7.成员变量和局部变量
就进原则
总是找到离他最近的已经声明的并在作用域内的参数指向。
8.位运算
使用位运算的效率是很高的,
比如实现一个2*8最快的算法就是使用位运算 2<<3
- 左边的操作数,代表要操作的数
- 右边的操作数代表的是要二进制操作的次数
- 位运算是以二进制比特作为基本基本单位的
- 左移 数会变大 右移 数会变小
9.冒泡排序
思路:遍历数组,如果数组中相邻的元素,前一个元素的值大于后一个元素那么就交换
public static void bubbleSort(int[] arr){
//决定了趟数
for(int i = 0; i < arr.length -1; ++i){
//内层循环 决定了每趟走一次
for(int j = 0;j < arr.length - i -1;++j){
if(arr[j + 1]> arr[j]){
int temp = arr[j + 1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
}
10.选择排序
11.插入排序
12.重载和重写的区别:
这部分网上有总结的很好的,我懒得自己写表格了,直接CV了一下
13.垃圾回收机制
- GC垃圾回收回收的是堆内存的对象空间,不负责回收栈内存的对象空间。
- 对一些物理连接,GC垃圾回收机制也无能为力,比如:数据库连接,输入流输出流,Socket连接。
- 调用Object类的finalize()方法可以显式的调用垃圾回收程序,但不是立即执行,而是GC程序会选择一个适当的时机进行垃圾回收。
- 垃圾回收机制做的事情就是确定那么对象是垃圾以及回收垃圾,确定对象为垃圾一种简单的作法就是将该对象赋值为null,暗示垃圾回收机制可以回收它了。
14.为什么要有包装类?
因为基本数据类型有些地方不能满足功能的实现,比如集合的元素必须是Object,这时就需要使用包装类。
Integer和int的区别?
int的默认值是0,而Integer的默认值是null,也就是说Integer是能够准备分辨出未赋值和赋值为0的情况。
使用场景,我们可以用来区分考试成绩为0和为参加考试的同学。在编写web应用时,Integer的引入也带来了极大的方便,比如使用el表达式在文本框显示时,如果Integer作为表单数据的类型,那么如果Integer不进行赋值,那么值为空白字符串,而使用int的话就会输出0。
15.说明内存泄漏和内存溢出的区别和联系,结合项目经验描述Java 程序中如何检测?如何解决?
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存
空间供其使用,出现 out of memory;比如申请了一个 integer,但给它存了long 才能存下的数,那就是内存溢出。内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的
内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论
多少内存,迟早会被占光。
内存泄露可以分为,栈内存泄露,堆内存泄露。
栈:是因为在一个方法中执行的步数过多,或者创建的局部变量过多,常见的造成原因有:无线的递归
堆:堆内存中主要是存储着大量的对象,如果我们的对象创建的过多就可能会造成堆内存泄露。因为要及时将无用无效的对象赋值为null,提醒垃圾回收机制来回收。
16.序列化
作用:
- 将序列化之后的对象永久的存储在硬盘上
- 用于在网络上传送对象
- 不论要传输什么数据,最终传输的都是二进制的数据,而我们要做的是就是将对象转化为字节码,然后JVM再将字节码文件解释为二进制文件最终在物理媒介上实现传输。
java 中的序列化机制能够将一个实例对象(只序列化对象的属性值,而不会去序列化什么所谓的方法。)的状态信息写入到一个字节流中使其可以通过 socket 进行传输、或者持久化到存储数据库或文件系统中;然后在需要的时候通过字节流中的信息来重构一个相同的对象。一般而言,要使得一个类可以序列化,只需简单实现 java.io.Serializable 接口即可。
注意:只会序列化方法,不会序列化属性。
17.你能想到的创建对象的方式?
- new
- 反射
- clone
- 反序列化
18.问到接口和抽象类的区别
回答这个问题学会分类
- 语法方面和设计理念方面
- 语法方面:抽象方法可以含构造方法,但是不能实例化,接口没有构造方法
- 抽象方法中可以定义常量和变量,接口中只能定义全局静态变量。
- 关键字不同
- 设计理念方面:抽象类的设计理念是继承,表示子类是父类“is a”
- 接口的设计理念的:“has a” 实现类有接口的方法和特点
19.同步代码块和同步方法有什么区别
相同点:
同步方法就是在方法前加关键字 synchronized,然后被同步的方法一次只能有一个线程进入,其他线程等待。而同步代码块则是在方法内部使用大括号使得一个代码块得到同步。同步代码块会有一个同步的“目标”,使得同步块更加灵活一些(同步代码块可以通过“目标”决定需要锁定的对象)。一般情况下,如果此“目标”为 this,同步方法和代码块没有太大的区别。
区别:
同步方法直接在方法上加 synchronized 实现加锁,同步代码块则在方法内部加锁。很明显,同步方法锁的范围比较大,而同步代码块范围要小点。一般同步的范围越大,性能就越差。所以一般需要加锁进行同步的时候,范围越小越好,这样性能更好。
20.静态内部类和内部类有什么区别
答:
静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用。
静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
非静态内部类能够访问外部类的静态和非静态成员。静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员。
实例化方式不同:
-
静态内部类:不依赖于外部类的实例,直接实例化内部类对象
-
非静态内部类:通过外部类的对象实例生成内部类对象
21.可序列化对象为什么要定义 serialversionUID 值?
答:
SerialVersionUid,简言之,其目的是序列化对象版本控制,有关各版
本反序列化时是否兼容。如果在新版本中这个值修改了,新版本就不兼容旧
版本,反序列化时会抛出 InvalidClassException 异常。如果修改较小,比
如仅仅是增加了一个属性,我们希望向下兼容,老版本的数据都能保留,那
就不用修改;如果我们删除了一个属性,或者更改了类的继承关系,必然不
兼容旧数据,这时就应该手动更新版本号,即 SerialVersionUid。
22.选择switch和if
通常情况下,switch和if是可以相互转化的,但是switch不能直接表示范围(通过转化是可以表示的),因此如果是一个范围,使用if是较方便的。
23.基本正则
\d: 匹配一个数字字符。等价于[0-9]
\D: 匹配一个非数字字符。等价于[^0-9]
\s: 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
. :匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。
*:匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。
+:匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。
|:将两个匹配条件进行逻辑“或”(Or)运算
[0-9]{6}:匹配连续 6 个 0-9 之间的数字
\d+:匹配至少一个 0-9 之间的数字
24.try{}里面有一个 return 语句,那么紧跟在这个 try 后的finally, 里面的语句在异常出现后,都会执行么?为什么?
在异常处理时提供 finally 块来执行任何清除操作。
如果有 finally 的话,则不管是否发生异常,finally 语句都会被执行,包括遇到 return 语句。
finally 中语句不执行的唯一情况中执行了 System.exit(0)语句。
25.如何将日期类型格式化为:2013-02-18 10:53:10?
- 将字符串转为Date类型
- 将Date进行日期格式化
public class TestDateFormat2 {
public static void main(String[] args) throws Exception {
//第一步:将字符串(2013-02-18 10:53:10)转换成日期Date
DateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate="2013-02-18 10:53:10";
Date date=sdf.parse(sdate);
System.out.println(date);
//第二步:将日期Date转换成字符串String
DateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String sdate2=sdf2.format(date);
System.out.println(sdate2);
}
}
26.匿名内部类是否可以继承其他类,或者实现其他接口?
答案是:匿名内部类是可以继承其他类或者实现其他接口的。但是只能继承一个类或者实现一个接口
27.内部类可以引用它的包含类(外部类)的成员吗?有没有什么限制?
答:一个内部类对象可以访问创建它的外部类对象的成员,包括私有成员。如果要访问外部类的局部变量,此时局部变量必须使用 final 修饰,否则无法访问。
28.Java 反射技术主要实现类有哪些,作用分别是什么?
在 JDK 中,主要由以下类来实现 Java 反射机制,这些类都位于
java.lang.reflect 包中
1)Class 类:代表一个类
2)Field 类:代表类的成员变量(属性)
3)Method 类:代表类的成员方法
4)Constructor 类:代表类的构造方法
5)Array 类:提供了动态创建数组,以及访问数组的元素的静态方法
29.Class 类的作用?生成 Class 对象的方法有哪些?
Class 类是 Java 反射机制的起源和入口,用于获取与类相关的各种信息,提供了获取类信息的相关方法。Class 类继承自 Object 类Class 类是所有类的共同的图纸。每个类有自己的对象,好比图纸和实物的关系;每个类也可看做是一个对象,有共同的图纸 Class,存放类的 结构信息,能够通过相应方法取出相应信息:类的名字、属性、放法、构造方法、父类和接口.
30.反射的使用场合和作用、及其优缺点
1)使用场合
在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。
2)主要作用
通过反射可以使程序代码访问装载到 JVM 中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息
3)反射的优点
反射提高了 Java 程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类;反射是其它一些常用语言,如 C、C++、Fortran 或者 Pascal 等都不具备的
4) Java 反射技术应用领域很广,如软件测试等;许多流行的开源框架例如Struts、Hibernate、Spring 在实现过程中都采用了该技术
5)反射的缺点
性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此 Java 反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。使用反射会模糊程序内部逻辑:程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
每天基本上要10个多小时面对着电脑,说实话有的时候真的身体有点受不了,今天异常感觉自己的脖子很酸(哈哈哈,程序猿的生活难道提前到来了?),搞得好像有人要我这菜鸡一样,哈哈哈。脖子酸,决定明天面试完,下午一定要去打会球,让自己的身体也运动一下,在电脑面前太久了!!!
今天的心情还是很开心,收到了来自小白的礼物。
再次想到自己应该更加努力才对!!!!
加油!!!!
希望看到博客的朋友,也要注意运动,注意身体啊!天气是真的冷了。
上一篇: python面试笔试题
下一篇: 关于日常问候语一句爆笑