Java SE总感觉自己掌握了,可是一些基本的问题却答不上来?
特地针对此类情况,整理了今年【2020】大厂面试题Java SE的部分的常问点,在此分享出来!
【这十个问题是比较基础的】
0x01.问:==和Equals 有何区别?
答:
(1)==:
- 如果比较的是基本数据类型,那么比较的是变量的值 。
- 如果比较的是引用数据类型,那么比较的是地址值。
(2)equals:
- 如果没重写
equals
方法,比较的是两个对象的地址值 。 - 如果重写了
equals
方法,往往比较对象中的属性的内容。 equals
方法是从Object
类中继承的,默认的实现就是使用== 。
0x02.问:ArrarList 和LinkedList 有何区别?
答:
(1)从实现方式上:
- ArrayList 是实现了基于动态数组的数据结构。
- LinkedList 基于链表的数据结构。
(2)从随机访问角度:
- ArrayList 优于 LinkedList。
- ArrayList只需使用索引访问,而 LinkedList 需要移动指针。
(3)从数据增删角度:
- 若只对单条数据插入或删除, ArrayList 的速度优于 LinkedList。【易忽略的地方】
- 是批量随机的插入删除数据,LinkedList 的速度大大优于 ArrayList.。因为 ArrayList 每插入一条数据,要移动插入点及之后的所有数据。
0x03.HashMap 和HashTable 有何区别?
- 关于HashMap会有一篇完整的文章介绍,这里主要是HashMap 和HashTable 的区别。
答:
(1)从线程安全性角度:
- HashMap 是线程不安全的,使用 HashMap 时必须自己增加同步处理。
- HashTable 是线程安全的,其中的方法是Synchronize 的,在多线程并发的情况下,可以直接使用HashTable。
(2)从key 和value 的角度:
- HashMap 中,null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。
- HashTable 中,key 和 value 都不允许出现null 值。
(3)从初始化容量的角度:
- HashTable 在不指定容量的情况下的默认容量为11。HashMap 为16。
- Hashtable 不要求底层数组的容量一定要为 2 的整数次幂。HashMap 则要求一定为2 的整数次幂。
(4)从扩容机制的角度:
- Hashtable 扩容时,将容量变为原来的2 倍加 1。
- HashMap 扩容时,将容量变为原来的2 倍。
(5)基础方法的角度:(contains)【可选】
- HashMap 关于contains 的只有containsValue 和containsKey 方法。
- HashTable 关于contains 的有contains、containsKey 和 containsValue 三个方法。其中 contains 和containsValue 方法功能相同。
0x04.String buffer 和String build 有何区别 ?
答:
(1)相同点:(方法和功能角度)
- StringBuffer 与 StringBuilder 中的方法和功能完全是等价的。
(2)不同点:(线程安全角度)
- StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的。
- StringBuilder 没有这个修饰,可以被认为是线程不安全的。
0x05.Final、Finally、Finalize 有何区别?
答:
(1)final:
-
修饰符(关键字)有三种用法:修饰类、变量和方法。
- 修饰类时,意味着它不能再派生出新的子类,即不能被继承。【和abstract 是反义词】
- 修饰变量时,该变量使用中不被改变,必须在声明时给定初值,在引用中只能读取不可修改。【也就是常量】。
- 修饰方法时,同样只能使用,不能在子类中被重写。
(2)finally:
- 通常放在
try…catch
的后面构造最终执行代码块,意味着程序无论正常执行还是发生异常,这里的代码只要JVM 不关闭都能执行。 - 一般将释放外部资源的代码写在
finally
块中。
(3)finalize:
- Object 类中定义的方法,Java 中允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
- 这个方法是由垃圾收集器在销毁对象时调用的,通过重写finalize() 方法可以整理系统资源或者执行其他清理工作。 、
0x06.简要谈谈你对反射的理解
答:
(1)从概念上:【反射是什么?】
-
反射机制就是 java 语言在运行时拥有一项自观的能力
-
通过这种能力可以彻底的了解自身的情况为下一步的动作做准备
-
通俗的语言:
- Java 反射机制在程序运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种 动态的获取信息 以及 动态调用对象的方法 的功能称为 java 的反射机制。
(2)实现的方式:【如何实现反射?】
-
Java 的反射机制的实现要借助于4 个类:class,Constructor,Field,Method;
-
通过这四个对象我们可以粗略的看到一个类的各个组成部分。:
- class - 类对象。
- Constructor-类的构造器对象。
- Field-类的属性对象,
- Method-类的方法对象。
(3)反射的作用:【反射能干什么?】
- 在Java 运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。
- 对于任意一个对象,可以调用它的任意一个方法。
0x07.产生死锁的基本条件 是什么?
答:
(1)产生死锁的四个必要条件:
- 1.互斥条件:一个资源每次只能被一个进程使用。
- 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 3.不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
- 4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立。
只要上述条件之一不满足,就不会发生死锁。
(2)常见产生死锁的可能原因:【可选】
- 系统资源不足。
- 资源分配不当。
- 进程运行推进的顺序不合适。
0x08.简单谈谈对线程池的理解
答:
(1)从概念上:【什么是线程池】
- 线程池就是事先将多个线程对象放到一个容器中,当使用的时候就不用 new 线程,而是直接去池中拿线程。
(2)优点:
- 1.降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 2.提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 3.提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
0x09.线程有哪些状态?
答:
(1)新建状态(New) :
- 线程对象被创建后,就进入了新建状态。
(2)就绪状态(Runnable):
- 线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。
- 也被称为“可执行状态”。
(3)运行状态(Running):
- 线程获取CPU 权限进行执行。
- 线程只能从就绪状态进入到运行状态。 【注意点】
(4)阻塞状态(Blocked):
-
阻塞状态是线程因为某种原因放弃 CPU 使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。
-
阻塞的情况分三种:
- 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
- 同步阻塞 – 线程在获取synchronized 同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
- 其他阻塞 – 通过调用线程的 sleep()或 join()或发出了 I/O 请求时,线程会进入到阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者I/O 处理完毕时,线程重新转入就绪状态。
0x0A. java 序列化是什么?
答:
(1)序列化的概念;
- 序列化就是一种用来处理对象流的机制。【对象流就是将对象的内容进行流化】。
- 序列化可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。
- 序列化是为了解决在对对象流进行读写操作时所引发的问题。
(2)实现方式:
-
将需要被序列化的类实现 Serializable 接口。
- 该接口没有需要实现的方法。 实现接口只是为了标注该对象是可被序列化的。
-
使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream(对象流)对象,然后使用ObjectOutputStream 对象的 writeObject(Object obj)方法就可以将参数为 obj 的对象写出(即保存其状态),要恢复的话则使用输入流。
文章若有错误,欢迎各位评论区中指出。