JavaSE面试题解(37题)

前言

本章主要带来的是JavaSE的面试题,里面包含了大部分Java基础面试能碰到的问题,如果有什么遗漏,或者写的有问题的希望各位兄弟们能在评论区指出

如果有想了解Spring框架面试题的兄弟们博主这里也是为大家准备了一篇,里面涵盖了Spring、Springmvc、SpringBoot总共31题

Spring面试题合集

1.基本数据类型(8种)

byte、short、int、long整数类型默认类型是int、其余需要强转
float、double浮点数类型默认类型是double,如果是float类型后面需要写F
char字符类型默认值为空,字符类型用单引号表示字符,
boolean布尔类型默认值false true、false这两个不是关键字

2.修饰符作用域

访问修饰符当前类同一包下其他类其它包内子类其它包内非子类
private可以访问
default(默认的修饰符)可以访问可以访问
protected可以访问可以访问可以访问
public可以访问可以访问可以访问可以访问

3、对面向对象的理解

面向对象即OOP是一种编程思想,对象在我们生活中处处都存在,比如说一只小狗就是一个对象,在面向对象编程中,对象是有很多特征的,比如说品种、颜色、体型等等都是对象的属性,对象还会有一些能力,比如跑、跳、打滚,这就可以理解成对象所封装的方法,简单来说就是将功能封装到对象里,我们面向对象,让对象去完成这些功能,在java中万物皆对象

4、面向对象的三大特征

封装:将不同的功能抽取出来方便调用,减少大量代码的冗余
继承:减少了类的冗余代码,让子父类之间产生关系,为多态打下基础
多态:一个接口,多个方法。通过继承实现不同的对象调用相同的方法,进而有不同的行为

5.抽象类接口的区别

接口

public interface a{}

抽象类

abstract class a{}
接口抽象类
不能定义构造器可以定义构造器
接口中所有成员都是public static final可以有抽象方法和具体方法
成员变量都是常量抽象类中的成员可以是任何类型
接口可以多继承类只能单继承

注意点:
抽象类如果是内部类可以使用static ,外部类不行

抽象类不能使用final修饰,因为使用后就不能被继承了,就失去了抽象类存在的意义了

注:抽象类中不一定有抽象方法,有抽象方法这个类一定是一个抽象类

6.在使用时接口、抽象类该如何选择

抽象类:描述现实中具体的事务可以使用抽象类
接口:描述某些行为特征时可以使用接口

7.普通类和抽象类的区别

普通类抽象类
不能包含抽象方法可以包含抽象方法
能直接实例化(new)不能直接实例化(需要继承重写抽象方法)

8.静态变量和实例变量的区别

静态变量:被static修饰符修饰的变量,也被称为类变量,它是属于类的,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝
实例变量:必须依存于某一个实例,需要先创建对象然后通过对象才能访问到它。实例变量可以实现让多个对象共享内存

9.重写和重载的区别

重写:发生在子类和父类之间,当子类继承父类时,子类中的方法与父类方法的名称,参数个数,参数类型完全一致时,称为子类重写父类方法,子类的访问修饰符必须大于等于父类的访问修饰符
重载:一个类中的多个方法的方法名称相同,参数个数或者形参类型不同,则称为方法重载,与返回值是无关的

补充:
1.final修饰的不能重写,但是能重载
2.无论重载重写,必须保证方法名相同

10.构造器Constructor是否可以被override

构造器Constructor是不能被继承的,因此不能被重写Overriding,但可以被重载Overloading

public 类名(){}

补充:
1、构造函数是不能被继承的,构造方法只能被隐式调用
2、构造函数是不能有返回值类型的

11.包装类和基本数据类型的区别

基本数据类型包装类
shortShort
intInterger
byteByte
longLong
charCharacter
doubleDouble
floatFloat
booleanBoolean

初始值不同:基本数据类型初始值int为0,boolean为false,double为0.0,包装类型的默认值都为null
使用方式不同:基本数据类型不能用于泛型,包装类可以作用于泛型

12.基本数据类型和包装类的使用标准

  1. 所有的POJO类属性必须使用包装数据类型
  2. 所有RPC方法的返回值和参数必须使用包装数据类型
  3. 所有的局部变量使用基本数据类型

说明:POJO类属性没有初始值是提醒使用者在需要使用时,必须自己显示地进行赋值,任何NPE(NullPointerException)问题,或者入库检查,都由使用者来保证

数据查询的结果可能是null,因为自动拆箱,用基本数据类型接收有NPE风险

13.包装类拆箱装箱

装箱:将基本类型转换成引用类型的过程叫做装箱(将栈中的基本数据类型放到堆里面去从而转换成一个引用类型)

int i1 =1;
Integer i2 = new Integer(i1);

自动装箱

int t =11;
Integer t2 =t;

拆箱:将包装类型转换成引用数据类型的过程叫拆箱(将栈中的基本数据类型放到堆里面去从而转换成一个引用类型)

Integer i=new Integer(1);
int i2=i.intValue();

自动拆箱

int t =11;
Integer t2 =t;
int t3 =t2.intValue();

方法介绍:
intValue()是吧Integer对象类型变成int的基本数据类型

parseInt()是吧String转化成int类型

Valueof()是把String转化成Integer类型

14.String、StringBuffer、StringBuilder区别

String

String:不可变字符序列,底层是一个数组不可扩容
StringBuffer、StringBuilder:可变字符序列,底层是可扩容的数组,底层会有一个value 和 count,当需要追加数据时,底层的数组长度不够时,它会再创建一个扩容后的新数组,然后将原来的数据复制过去,然后再在新数组后面追加

StringBuffer:是JDK1.0的时候的,线程安全
StringBuilder:是JDK1.5的时候的,线程不安全

三者的效率区别:StringBuilder>StringBuffer>String

15.说出5个String类的方法

.equals()
.substring()
.length()
.indexOf()
.toUpperCase()
还有很多自行了解:String类常用API

16. ==和equals()的区别

equals()和==最大的区别一个是方法,一个是运算符

==:如果对象时基本数据类型,则比较的是数值是否相等;如果是引用数据类型,比较的则是对象的地址值是否相等
equals():用来比较方法两个对象的内容是否相等

17.请说出5个异常类型

ArrayIndexOutOfBoundsException 数组下标越界
NullPointerException 空指针异常
ClassCastException 类转换异常
SQLException SQL异常
IllegalArgumentException 方法传参错误

18.异常处理方式

try{
    可能出现异常的代码
}catch{
    捕获到的异常与catch中的异常类型进行匹配,执行里面的逻辑
        可能有多重判断
}finally{
    进行资源的关闭
}

19.throws和throw区别

throw

  1. 在方法体内,表示抛出异常,由方法体内的语句处理
  2. 是具体向外抛出异常的动作,所以它抛出的是一个异常实例,执行 throw 一
    定是抛出了某种异常。

throws

  1. 在方法签名后面,表示如果抛出异常,由该方法的调用者来进行异常处理
  2. 主要是声明这个方法会抛出某种类型的异常,让它的使用者要知道需要捕获的异常的类型
  3. 表示出现异常的一种可能性,并不一定会发生这种异常。

20.final、finally、finalize区别

其实说到底这三者并没有关联关系,不过面试题还是会考,可能因为它们长得像吧

final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可被继承
finally:异常处理语句结构的一部分,表示不管抛不拋异常都执行
finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的
此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。该方法无需我们调用

21.流的分类

流的方向:输入流,输出流
流的类型:字节流,字符流

字符流字节流
输入流ReaderinputStream
输出流writeroutputStream

22.字符流、字节流的区别

处理数据不同

字节流处理的数据类型:图片、MP3、视频文件、文本数据
字符流处理的数据类型:纯文本数据
如果是文本数据优先选择字符流,除此之外都是字节流

流的读取单位不同

字节流主要操作的数据类型是byte类型数据,以byte数组为准

字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串
字节流处理单元为 1 个字节,操作字节和字节数组

23.集合与数组的区别

数组集合
数组的大小在创建之初就规定了,后面不能更改集合的大小是不固定的,底层会自动扩容
数组存放的类型在创建是就规定了,只能有一种集合在不添加泛型时数据类型并不是一种,是Object类型

24.java容器(集合)介绍

1.超级接口Iterable

2.起始接口collection继承Iterable接口

3.下面就分为三大接口

  • Set:Set继承Collection 集合 无序,不可重复的,元素进入集合的顺序是没有先后差别的
  • Queue:Queue继承Collection
  • List:List继承Cillection 有序的序列,允许插入重复的数据

4.Map在集合框架中跟collection是并列存在的

第一代安全集合类

Vector Hashtable

核心代码使用synchronized修饰符

第二代线程非安全集合类

ArrayList HashMap

线程不安全但是性能好,用来替代第一代

要变成线程安全,使用工具类Conllections,底层也是使用synchronized代码块锁,但是相比第一代性能稍有提升

25.List、Set、Map的区别

  1. List和Set都是继承Collection 接口的集合,是存储单列元素的集合,Map是存储k-v键值对双列数据的集合
  2. List中存储的数据有序,允许重复 ;Set中存储的数据无序,不允许重复,但是元素的位置是由元素的hashCode决定的

26.Map集合详解

Map接口 使用键值对存储(k-v),不能有重复的key,value可以重复,键要保证唯一性,键和值存在映射关系

集合名存值数据结构
Hashtable不可以存入null键,null值哈希表
HashMap允许null值和null键JDK1.7 数组+链表 JDK1.8 数组+链表+红黑树
LinkedHashMap允许null值和null键哈希表+双向链表
TreeMapkey不可以为null,值可以为null红黑树
HashMap是Map实现类

在这里插入图片描述
在这里插入图片描述
如果需要保证键的唯一性需要覆写hashCode方法,和equals方法

HashTable是Map实现类

在这里插入图片描述

LinkedHashMap继承HashMap实现Map接口

在这里插入图片描述
如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现

TreeMap实现Map接口

在这里插入图片描述
能够把它保存的记录根据键排序,默认是键值的升序排序

27.TreeSet和HashSet的区别

TreeSet

TreeSet底层实际使用的存储容器是TreeMap

对于TreeMap而言,它采用一种被称为红黑树的排序二叉树来保存Map中的每个Entry,每个Entry被当成红黑树的一个节点来对待

总结:

  • 实现TreeMap
  • 具有排序功能,有序
  • TreeSet中的元素必须实现comparable接口并重写compareTo(),TreeSet判断元素是否重复,以及确定元素的顺序,靠的就是这个方法
HashSet

HashSet的实现原理,封装了一个HashMap对象来存储所有的集合元素,不允许集合中有重复
的值,使用该方式时需要重写 equals()和 hashCode()方法

总结:

  • 实现HashMap
  • 没有排序功能,无序
  • 重写 equals()和 hashCode()方法保证数据唯一性

28.线程和进程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

一个进程可以包含多个线程

进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃,整个进程都死掉,所以多进程要比多线程健壮

29.线程的三种创建方式

接口/类方法体介绍
exteds Thread类run()
implement Runnable接口run()
implement callable接口call()方法有返回值,能够抛出异常

30.线程的5种状态

新建:new创建一个线程

就绪:.start()后,该线程处于就绪状态,只是表示可以运行,等待jvm调用

运行:线程获得cpu开始执行run()方法体

阻塞:如果其他线程抢占CPU就会阻塞,或者调用sleep()

死亡:run()、call()执行完毕,线程正常结束,或者是抛出异常、调用stop()但是容易死锁

31.线程池的四种创建方式

线程池的意义

创建线程整个过程的浪费是比较大的,而线程池的意义在于先创建线程需要的数据,当要用的时候直接去线程池中取出线程,这样节省了创建连接和关闭资源的开销

线程池创建
      ExecutorService executorService=new ThreadPoolExecutor(3,//核心线程数
                6,//最大线程数
                1L,//存活时间(多余的空闲线程的存活时间)
                TimeUnit.SECONDS,//时间单位(线程池维护线程所允许的空闲时间的单位)
                new ArrayBlockingQueue<>(3),//任务队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略

任务队列:任务队列是基于阻塞队列实现的,即采用生产者消费者模式

**线程工厂:**指创建线程的方式

**拒绝策略:**4种

AbortPolicy(默认):丢弃任务并抛出 RejectedExecutionException 异常。
CallerRunsPolicy:由调用线程处理该任务。
DiscardPolicy:丢弃任务,但是不抛出异常。可以配合这种模式进行自定义的处理方式。
DiscardOldestPolicy:丢弃队列最早的未处理任务,然后重新尝试执行任务。

线程池的四种创建方式

通过Exeutors(jdk1.5)提供的四种线程池

名称
可缓存线程池newCachedThreadPool如果线程池长度超过处理需要,可以灵活的回收线程,若无可回收,则新建线程
定长线程池newFixedThreadPool可控制线程最大并发数,超出的线程会在队列中等待
定长线程池,定时newScheduledThreadPool支持定时及周期任务执行
单线程化的线程池newSingleThreadExecutor它会用唯一的工作线程来执行任务,保证所有的任务按照指定顺序执行

32.Lock和Synchronized的区别

Lock是接口,synchronized是关键字

Lock可以选择性的获取锁,如果一段时间获取不到,可以放弃。Synchronized,会一直获取,借助这个特性可以规避死锁

synchronized在发生异常和同步代码块结束的时候,会自动释放锁,Lock必须手动释放,所以如果忘记释放锁,也会造成死锁

33.静态锁和非静态锁的区别

1.对象锁钥匙只能有一把才能互斥,才能保证共享变量的唯一性

2.在静态方法上的锁,和 实例方法上的锁,默认不是同样的,如果同步需要制定两把锁一样。

static synchronized是类锁

synchronized是对象锁

若类对象被lock,则类对象的所有同步方法(static synchronized func)全被lock。

若实例对象被lock,则该实例对象的所有同步方法(synchronized func)全被lock。

34.Synchronized、volatile

java的两种同步机制:同步块(或方法)和volatile变量

锁提供了两种主要特性:互斥和可见性

volatile

volatile关键字是一种轻量级的同步机制,只保证数据的可见性,而不保证数据的原子性。

synchronized

非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作
synchronized 是由“一个变量在同一个时刻只允许一条线程对其进行 lock 操作”这条规则获得的,此规则决定了持有同一个对象锁的两个同步块只能串行执行

Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。

35.悲观锁、乐观锁

悲观锁

在传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁、写锁等,都是在操作之前先上锁(效率低)

乐观锁

在数据上会为其加一个版本号,在操作后数据版本号会更新,如果使用数据版本号不一致,后面就不能操作了,乐观锁适用于多读的应用类型,这样可以提高吞吐量。

36.ArrayList 和LinkedList区别

List接口是Collection接口的子接口定义一个允许重复项的有序集合,可以动态的增长,最重要的是它保证维护元素特定的顺序

ArrayList 优点是随机访问元素,但插入和删除速度很慢

LinkedList 对顺序访问进行了优化,插入和删除的开销并不大,随机访问则相对较慢

37.线程安全的理解

是指在多线程环境下,每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的

  • 20
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值