ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA基础面试题

2020-02-06 10:37:43  阅读:166  来源: 互联网

标签:面试题 JAVA HashMap 对象 基础 线程 方法 变量 字节


==和equal的区别

1、 如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2、 对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象
  如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
  诸如String、Date等类对equals方法进行了重写的话,比较的是所指向 的对象的内容。

final的作用

final修饰的类为最终类,该类不能被继承
final修饰的方法不能被重写
final修饰的变量被叫做常量,常量必须初始化,初始化后就不能改变

this关键字

this:代表当前类的对象引用
this特点
每个类的每个非静态方法(没有被static修饰)都会隐含一个this引用名称,它指向调用这个方法的对象。
当在方法中使用本类的属性时,都会隐含地使用this名称,当然也可以明确指定。
this可以看作是一个变量,它的值就是当前对象的
this使用场景
当局部变量和成员变量同名时使用this关键字
this关键字可以访问本类构造函数

this和super的区别

this表示本类的引用,super可以表示为父类存储空间的标示,(可以理解为父类的引用,可以操作父类的成员)。
A:调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
B:调用构造方法
this(…) 调用本类构造方法
super(…) 调用父类构造方法
C:调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法

static关键字

static修饰的变量叫做静态变量/ 共享变量 / 类变量
特点
1. 静态变量属于某个类,而不属于某个具体的对象
2. 只有静态才能访问静态,非静态变量不能够出现静态方法中
3. 访问静态成员的格式
类名.成员变量
类名.成员方法
4 . 通过静态修饰方法最大的好处? – 方便调用 例如Math类
开发中经常会看到类似于Math类这样的工具类
以后我们也会编写自己的工具类,以后工具类的包名一般叫做 com.sxt.utils DBUtils NetUtils DBTools
5. 静态环境下不能够出现this和super关键字
6. static不仅能够修饰成员变量,成员方法,还能够修饰类,修饰类的时候必须内部类(后面讲解)
7. static还可以修饰代码块
8. 静态代码块一般都是用来初始化静态成员

访问权限修饰符

1.public修饰的成员对一切类可见
2.protected修饰的成员对子类可见
3.default修饰的成员仅对同包下可见
4.private修饰的成员仅对本类可见

JAVA中操作字符串有哪些类?它们之间的区别是什么?

操作字符串的类有:String、StringBuffer、StringBuilder

String和StringBuffer、StringBuilder的区别在于String声明的对象是不可变的,每次操作都会生成新的String对象,然后将指针指向新的String对象,而StringBuffe和StringBuilder可以在原有对象的基础上进行操作,所以要改变字符串不要使用String.

StringBuffer和StringBuilder的区别就在于,StringBuffer是安全的,StringBuilder是非安全的,但是StringBuffer相对于StringBuilder来说,效率较低,按情况来分,单线程推荐用StringBuilder,多线程用StringBuffer.

String str='i’和String str=new String(‘i’)区别?

因为内存的分配形式不一样,String str='i’是会分配在常量池中,而String str=new String(‘i’)会被分配在堆内存中。

普通类和抽象类的区别

抽象类可以有抽象方法,普通类不可以有抽象方法。
普通类可以被实例化,抽象类不可以实例化。

抽象类可以被final关键字修饰吗?

不可以,因为定义抽象类是用来继承的,而final是不能重写不能继承的,这样彼此之间就产生的矛盾。

接口和抽象类的区别?

实现:抽象类是用来extends继承的,接口是implements实现的。
构造函数:抽象类可以有构造函数,而接口不可以有。
实现数量:类可以实现多个接口,但是只能单继承。
访问权限修饰符接口的方法默认是public,而抽象类的方法是任意的访问权限修饰符。

为什么要克隆?

因为克隆的对象可能包含了修改的属性,而new出来的对象属性还是初始化的值。所以当需要一个新的对象来保存当前对象的‘状态’就需要克隆。

如何实现克隆?

实现Cloneable接口并重写Object类的clone()方法。
实现Serializable接口,通过序列化和反序列化来实现深度克隆。

深拷贝和浅拷贝的区别?

==浅拷贝:==当对象被复制时只复制它本身和所包含的对象的值类型的成员变量,而引用类型的成员变量并没有被复制。
==深克隆:==除了对象本身被复制外,对象所包含的所有成员变量也会被复制。

JAVA的IO流分几种?

==按功能分:==输入流、输出流
==按类型分:==字节流、字符流
字节流和字符流的区别:字节流按8为字节为传输单位传输数据,字符流按16位字符为传输单位传输数据

字符流和字节流有哪些,连接桥梁是?

字节流主要处理的是二进制对象或者字节,字符流主要是处理字符或者字符数字。
字符流:
Reader、Writer、BufferedReader、BuffreredWriter、fileReader、 FileWriter、InputStreamReader、OutputStreamWriter,
字节流:
InputStream、OutputStream、FileInputStream、FileOutputStream、FilterInputStream、FilterOutputStream、BufferedInputStream、BufferedOutputStream

字节流和字符流的连接桥梁是: InputStreamReader
字节流继承自 InputStream和OutputStream
字符流继承自 InputSteamReader和OutputStreamWriter

字节流和字符流哪个好?怎么选择?

缓大多数情况下使用字节流会更好,因为字节流是字符流的包装,而大多数时候 IO 操作都是直接操作磁盘文件,所以这些流在传输时都是以字节的方式进行的(图片等都是按字节存储的)

如果对于操作需要通过 IO 在内存中频繁处理字符串的情况使用字符流会好些,因为字符流具备缓冲区,提高了性能

什么是缓冲区?有什么作用?

缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性。
对于 Java 字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用 flush() 方法操作。

字符流和字节流有什么区别?

字符流和字节流的使用非常相似,但是实际上字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件

什么是Java序列化,如何实现Java序列化?

序列化就是一种用来处理对象流的机制,将对象的内容进行流化。可以对流化后的对象进行读写操作,可以将流化后的对象传输于网络之间。序列化是为了解决在对象流读写操作时所引发的问题

序列化的实现:将需要被序列化的类实现Serialize接口,没有需要实现的方法,此接口只是为了标注对象可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,再使用ObjectOutputStream对象的write(Object obj)方法就可以将参数obj的对象写出

什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?

节点流: 直接与数据源相连,用于输入或者输出
处理流: 在节点流的基础上对之进行加工,进行一些功能的扩展
处理流的构造器必须要 传入节点流的子类

集合:Collection和Collections区别?

Collection是一个集合,提供了对集合对象的基本操作的通用接口方法,所有集合都是它的子类,列如:List、Set等。
Collections是一个包装类,包含了很多的静态方法,不能被实例化,就像一个工具类,比如提供的排序方法:Collections.sort(list)。

List、Set、Map区别是什么?

在这里插入图片描述

HashMap和Hashtable的区别?

存储: HashMap运行key和value为null,Hashtable不能为null
线程安全: HashMap线程是非安全的,Hashtable线程是安全的

如何决定使用HashMap还是TreeMap?

对于在Map中插入、删除、定位一个元素这类操作。HashMap是最好的选择,因为相对而言HashMap的插入会更快,但如果你要对一个key集合进行有序的遍历,那TreeMap是更好的选择。

ArrayList和LinkedList区别?

数据结构实现: ArrayList是动态数组结构实现,而LinkedList是双向链表数据结构实现。
访问效率: ArrayList比LinkedList在随机访问时的效率要高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
==增加和删除效率:==在非首尾的增加和删除操作,LinkedList要比Array List效率要高,因为ArrayList增删操作会影响数组内的其它数据的下标。

综合来说,在需要频繁读取集合的元素时,更推荐ArrayLis,而在插入和删除操作较多时,推荐使用LinkedList。

ArrayList和Vector的区别?

线程安全: Vector使用了Synchronized来实现线程同步,是线程安全的,而ArrayList是非线程安全的。
性能: ArrayList在性能方面是优于Vector的。
扩容: ArrayList和Vector都会根据实际需要的动态的调整容量,只不过Vector每次扩容1倍,而ArrayList只会增加50%。

Array和ArrayList区别?

Array可以存储基本类型和对象,ArrayList只能存储对象
Array是可以指定固定大小的,而ArrayList大小是自动扩展的
Array内置方法没有ArrayList多,比如addAll、Iteration等方法只有ArrayList有

迭代器Iteration是什么?

Iteration接口提供遍历Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代Java集合框架中的Enunciation。迭代器允许调用者在迭代过程中移除元素

Iterator和ListIterator区别?

Iterator可以遍历Set和List集合,而ListIterator只能遍历List
Iterator只能单向遍历,而ListIterator可以双向遍历
ListIterator从Iterator接口继承,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置

HashMap的实现原理

HashMap基于hashing原理,我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。 HashMap在每个链表节点中储存键值对对象。

HashMap和HashSet区别

HashMap实现了Map接口,HashSet实现了Set接口

HashMap存储键值对,HashSet存储对象

HashMap调用put()向map中添加元素,HashSet调用add()像set中添加元素

HashMap使用Key计算hasncode,HashSet使用成员计算Hashcode

HashSet实现原理

HashSet是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,因此HashSet的实现比较简单,相关HashSet的操作,基本都是直接调用HashMap的想关方法完成,HashSet不允许重复的值

并行和并发的区别?

并行: 多个处理器或者多核处理器同时处理多个任务
并发: 多个任务在同一个CPU上,按细分的时间片轮流执行,从逻辑上来看那些任务是同时执行的。

什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位

线程和进程的区别?

线程是进程的子集,一个进程可以有很多线程,每条线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享一片相同的内存空间。(一个程序至少有一个进程,一个进程至少包含一个线程)

守护线程是什么?

守护线程是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序

创建线程的三种方式

继承Thread重写run方法
实现Runnable接口
实现Callable接口

线程有哪些状态?

NEW 尚未启动
RUNNABLE 正在执行中
BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
WAITING 永久等待状态
TIMED_WAITING 等待指定时间被唤醒的状态
TERMINATED 执行完成

sleep ()和wait()区别?

类的不同: sleep()来自Thread,wait()来自object
释放锁: sleep()不释放锁;wait()释放锁
用法不同: sleep()到指定时间就会自动恢复,wait()可以使用 notify()/notifyAll()直接唤醒。

notify()和notifyAll()区别?

notifyAll()是唤醒所有的线程,notify()是唤醒单个线程,notifyAll()调用后,会把所有的线程从等待池移动到锁池中,然后参与锁的竞争,竞争成功则会继续执行,如果不成功会继续留在锁池中等待锁的释放再次参与竞争,而notify()只会唤醒一个线程,具体唤醒哪个线程由虚拟机自己决定。

线程的run()和start()区别?

start()用于启动线程,run()方法用于执行线程的运行时代码。run()可以重复调用,而start()只能调用一次。

runnable和callable区别?

runnable没有返回值,callable可以拿到返回值,callable可以看作是runnable的补充

什么时候用Runnable和Thread

Java不支持类的多重继承,但允许你调用多个接口。所以如果你要继承其他类,当然是调用Runnable接口好了

什么是线程池,为什么要使用它

线程池就是提前创建若干个线程,如果有任务需要处理,线程池里的线程就会处理任务,处理完之后线程并不会被销毁,而是等待下一个任务。

创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时 候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。

线程池有哪几种状态?

RUNNING: 这是最正常的状态,接受新的任务,处理等待队列的任

SHUTDOWN: 不接受新的任务提交,但是会继续处理等待队列的任务
STOP: 不接受新的任务提交,也不处理等待队列的任务,中断正在处理的任务
TIDYING: 所有的任务都会销毁,workCount为0,线程池的状态在转换为TIDYING状态时,会使用钩子方法terminated()
TERMINATE: terminated()方法结束后,就会变成这个

线程池中的submit()和execute()的区别?

execute() 只执行Runnable类型的任务
submit() 可以执行Runnable和callable类型的任务

创建线程池有哪几种方式?

1、ThreadPoolExecutor是线程池的真正实现,
他通过构造方法的一系列参数,来构成不同配置的线程池。
2、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
案例演示:
3、newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
4、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
5、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

在JAVA中如何保证多线程的安全?

1、使用安全类,比如Java.util.concurrent下的类。
2、使用自动锁synchronizd。
3、使用手动锁Lock。

什么时死锁?

当线程A持有锁a,线程B持有锁b,线程A尝试占用锁b,线程B尝试占用锁b,互相不释放锁,就会产生阻塞,就会产生死锁。

如何防止死锁?

1.鸵鸟算法。
2. 检测死锁并恢复。
3.仔细的对资源进行动态的分配,以避免思索;
通过破除死锁四个必要条件之一,来防止死锁

死锁产生的原因

  1. 系统资源的竞争
    系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁。
  2. 进程运行推进顺序不合适
    进程在运行过程中,请求和释放资源的顺序不当,会导致死锁。

死锁产生的4个必要条件

1.互斥条件:资源不能被共享,只能由一个进程使用。
2.请求与保持条件:已经得到资源的进程可以再次申请新的资源。
3.非剥夺条件:已经分配的资源不能从相应的进程中被强制的剥夺。
4.循环等待条件:系统中若干进程组成环路,该环路中的每一个进程都在等待相邻进程正占用的资源。

多线程中的synchronized锁升级的原理

synchronized锁升级原理:在锁对象的对象里头有一个threadid字段,在第一次访问的时候threadid为空,jvm让其持有偏向锁,并将threadid设置为其线程id,再次进入的时候会就会判断threadid是否和线程id一致,如果一致就直接调用此对象,不一致就会转化为轻量级锁,如何循环一定次数获取锁,如果还没有正常获取到要使用的锁,轻量级锁机会转化为重量级锁,这样就是synchronizd升级的原理

锁升级的目的:锁升级为了减低锁带来的性能消耗。

synchronized底层的实现原理

synchronized是由一对monitorenter/monitorexit指令实现的

synchronized和volatile的区别?

volatile是变量修饰符,synchronized是修饰类、方法、代码块。
volatile仅能实现变量的修改可见性,不能保证原子性,而synchronized可以保证变量的可见性和原子性
volatile不会造成线程的阻塞,而synchronized可能会造成线程的阻塞

大猪崽子 发布了2 篇原创文章 · 获赞 1 · 访问量 19 私信 关注

标签:面试题,JAVA,HashMap,对象,基础,线程,方法,变量,字节
来源: https://blog.csdn.net/weixin_45338899/article/details/104105395

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有