Java校招复习-Java基础篇

165 阅读16分钟

JDK 和 JRE 有什么区别

JDK包含了JRE、java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具,是Java程序开发和运行的环境。

JRE是Java程序的运行环境。

== 和 equals 的区别是什么

== 对于基本类型比较的是值相等,对于引用类型比较的是在内存中的真实地址。

equals() 方法默认就是==,对于String、Integer类型因为重写了 equals() 方法所以比较的是值。只能用于引用类型不能用于基本类型。

两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

  1. 如果重写了equals()方法就和hashCode()没关系
  2. hashCode()相等即两个键值对的哈希值相等,然而哈希值相等,并不一定能得出键值对相等。

final 在 java 中有什么作用?

  1. 修饰类代表这个类不能被继承
  2. 修饰方法表示方法不能被重写
  3. 修饰属性表示属性只能被初始化一次,以后不能被修改

String 属于基础的数据类型吗?

不属于,基础的数据类型包括:byte,short,int,long,double,float,boolean,char 属于引用类型。

java 中操作字符串都有哪些类?它们之间有什么区别?

  1. String:不能修改value值,底层修改String的值方法是通过new一个StringBuffer,做修改,然后再返回一个新的String对象。
  2. StringBuffer:可以修改value值,线程安全,性能高,推荐用在单线程
  3. StringBuilder:可以修改value值,线程不安全,性能差,推荐用在多线程。

String str="i"与 String str=new String("i")一样吗?

不一样,第一个创建了一个对象,在字符串常量。第二个创建了二个对象,在字符串常量池和堆。

如何将字符串反转?

直接通过StringBuilder或者StringBuffer的reverse()方法。

String 类的常用方法都有那些

  1. charAt():返回指定索引的字符。
  2. subString()
  3. indexOf():返回指定字符的索引。
  4. length()
  5. replace():替换
  6. split():分割

抽象类必须要有抽象方法吗?

不需要,抽象类不一定非要有抽象方法。

普通类和抽象类有哪些区别

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

抽象类能使用 final 修饰吗

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类,编辑器也会提示错误信息。

接口和抽象类有什么区别

实现:抽象类的子类使用 extends 来继承;接口必须使用 implements 来实现接口。

构造函数:抽象类可以有构造函数;接口不能有。

接口中的所有方法都要被子类重写,子类只需要重写抽象类中的抽象方法。

实现数量:类可以实现很多个接口;但是只能继承一个抽象类。

访问修饰符:接口中的方法默认使用 public 修饰;抽象类中的方法可以是任意访问修饰符。

java 中 IO 流分为几种?

按功能来分:输入流(input)、输出流(output)。

按类型来分:字节流和字符流。

字节流和字符流的区别是:字节流按 8 位传输以字节为单位输入输出数据,字符流按 16 位传输以字符为单位输入输出数据。

BIO、NIO、AIO 有什么区别?

BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。

NIO:New IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。

AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

Files的常用方法都有哪些?

  1. Files.exists():检测文件路径是否存在。
  2. Files.createFile():创建文件。
  3. Files.createDirectory():创建文件夹。
  4. Files.delete():删除一个文件或目录。
  5. Files.copy():复制文件。
  6. Files.move():移动文件。
  7. Files.size():查看文件个数。
  8. Files.read():读取文件。
  9. Files.write():写入文件。

java 常用的容器都有哪些

ArrayList、Vector、LinkedList、PriorityQueue、LinkedSet、HashSet、TreeSet、TreeMap、HashMap。

Collection 和 Collections 有什么区别?

Collection他是一个集合,它提供了对集合对象进行基本操作的通用接口方法。

Collections是一个工具类,它提供了静态方法操作集合,比如排序、数组的转换等等。

List、Set、Map 之间的区别是什么?

List 存储的数据有序,元素可重复,实现了Collection接口

Set 存储的数据无序,元素不可重复,实现了Collection接口

Map 按照key查询数据,key不可重复,单独的顶层接口

Properities

Properities实现了Map接口,用于i/o接收数据

HashMap 和 Hashtable 有什么区别?

HashMap线程不安全不支持多线程并发,允许key = null。

Hashtable线程安全,对于每个方法使用了synchronized。不允许key = null。

对于线程并发的操作更建议使用 CurrentHashMap。

如何决定使用 HashMap 还是 TreeMap?

TreeMap直接通过红黑树来存储,Entrt中保存了key、value、父节点、左节点、右节点。 根据的key的hash值来排序,支持顺序遍历。对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。

说一下 HashMap 的实现原理?

HashMap是基于哈希表的Map接口的非同步实现。

HashMap中有一个Node集合,每个Node节点存放着数据和指向下一个节点的指针。当调用put方法时,首先会判断Node集合是否被初始化,如果没有则初始化,如果有则计算插入值的hash值,根据算法找到集合对应的位置,如果为null则封装成Node直接插入,如果不为null则通过头插法插入。还会判断集合中所有Node的个数/size长度>0.75则进行扩容,扩容的机制就是通过高低位进行数据转移。

1.7中通过数组+链表

1.8中使用数组+链表+红黑树,链表中的节点数据超过八个之后并且数组长度超过64,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)。

说一下 HashSet 的实现原理?

public HashSet() {map = new HashMap<>();},底层依旧使用的HashMap,HashSet的值存放于HashMap的key上,key不能重复,HashMap的value统一为PRESENT。

ArrayList 和 LinkedList 的区别是什么?

ArrayList数组,LinkedLis是双向链表,通过索引进行访问时,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。

如何实现数组和 List 之间的转换?

List转换成为数组:调用ArrayList.toArray()方法。

数组转换成为List:调用Arrays.asList方法。

ArrayList 和 Vector 的区别是什么?

Vector是线程安全的,而ArrayList不是。

ArrayList比Vector快。

数组 和 ArrayList 有何区别?

数组可以容纳基本类型和对象,而ArrayList只能容纳对象

数组不能被扩容,ArrayList支持扩容。

在 Queue 中 poll()和 remove()有什么区别?

poll() 是从队列头部弹出一个元素,poll() 在获取元素失败的时候会返回空,

remove(Object o) 是从队列中删除指定的元素,remove() 失败的时候会抛出异常。

哪些集合类是线程安全的?

Vector、HashTable、Stack、enumeration。

迭代器 Iterator 是什么?

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,迭代器通常被称为“轻量级”对象,因为创建它的代价小。

Iterator 怎么使用?有什么特点?

注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

(1) 调用集合的iterator()方法返回一个Iterator。

(2) 使用next()获得序列中的下一个元素。

(3) 使用hasNext()检查序列中是否还有元素。

(4) 使用remove()将迭代器新返回的元素删除。

Iterator 和 ListIterator 有什么区别?

Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。

Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引等等。

并行和并发有什么区别?

并行:多个线程在同一时刻共同执行称为并行

并发:多个线程在同一时间段交替执行称为并发

线程和进程的区别?

简而言之,进程是程序运行的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。多个进程共享一个内存空间,线程是进程的一个实体,是cpu调度和分派的基本单位,多个线程之间资源不共享。

守护线程是什么?

守护线程可以理解为服务其他线程的线程,比如说Java中的GC线程。

创建线程有哪几种方式?

  1. 集成Thread类
  2. 实现Runabble接口
  3. 通过Callable接口和Future类

说一下 runnable 和 Callable 有什么区别?

  1. runnable的run方法没有返回值,只是单纯的执行。
  2. Callable和Future配合可以拿到线程执行方法后的返回值。

线程有哪些状态?

  1. 创建:线程没有调用start方法。
  2. 就绪:线程调用了start方法,但是现在没有执行,等待CPU调度。
  3. 运行:线程正在执行run()方法。
  4. 阻塞:线程被暂停执行了(sleep、wait、suspend)。
  5. 死亡:执行完run方法或者执行了stop方法。

sleep() 和 wait() 有什么区别?

sleep()让线程进入睡眠状态,等到睡眠状态结束和其他线程一起抢占CPU,但是不会释放锁

wait()进入一个阻塞队列,只有通过调用notiyf、notifyAll才能唤醒线程抢占CPU,会释放当前线程拿到的锁

notify()和 notifyAll()有什么区别?

notify():从阻塞队列中随机唤醒一个然后抢占CPU

notifyAll():唤醒所有存在于阻塞队列的线程,然后这些线程一起抢占CPU。

如果针对于锁情况,就是从阻塞队列唤醒一个放到等待队列还是全部一起放到等待队列。

线程的 run()和 start()有什么区别?

run():方法只是单纯的调用当前线程执行一个方法

start():方法会通过 jvm 创建一个线程然后执行run方法

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

Executors.newFixedThreadPool(int nThreads)//创建线程数不可变的线程池

Executors.newCachedThreadPool(int nThreads)//创建线程数可变的线程池

Executors.newSingleThreadExecutor(int nThreads)//创建一个线程的线程池

Executors.newScheduledThreadPool(int nThreads)//创建可以延时或者定时执行的线程池

线程池都有哪些状态?

Running、ShutDown、Stop、Tidying、Terminated。

线程池中 submit()和 execute()方法有什么区别?

  1. submit可以接受Runabble和Callable的对象,execute只能接受Runabble
  2. submit有是否成功的返回值
  3. submit会继续向主线程抛异常,execute自己 try catch 解决了异常

在 java 程序中怎么保证多线程的运行安全?

三个方面进行保证

  1. 原子性:同一时刻只能有一个线程对数据进行操作
  2. 有序性:CPU为了性能,可能会对耗时比较长的指令进行重排序,(happens-before原则)
  3. 可见性:一个线程对主内存的修改可以及时地被其他线程看到

多线程锁的升级原理是什么?

无状态锁-偏向锁-轻量级锁-重量级锁

第一次升级:加锁

第二次升级:有两个线程尝试拿同一把锁

第三次升级:线程自选次数过多进入阻塞队列,阻塞队列中存在线程就会升级

什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。(多个方法使用同一把锁就会出现这种问题)

怎么防止死锁?

死锁产生的四个条件

  1. 互斥条件
  2. 请求和保持条件
  3. 环路等待条件
  4. 不可剥夺条件

防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。

ThreadLocal 是什么?有哪些使用场景?

为了解决多线程之间数据共享的问题。每一个线程都有一个存储变量的副本,线程只会对自己内部的变量进行修改,不会影响其他线程。

spring当中的bean就是用了ThreadLocal,使其属于线程级别的变量。

说一下 synchronized 底层实现原理?

可以说一些对象头关于锁信息的存储,锁的升级。Monitior监视器、阻塞队列、等待队列。

synchronized 和 volatile 的区别是什么?

两者解决的问题不同

volatile解决了多线程之间数据可见性的问题。synchronized是通过加锁的机制在同一时刻只能由一个线程执行该方法。

volatile底层比较复杂,JVM会添加一些内存屏障命令,CPU执行到该行指令就会从主存中拿数据。

synchronized 和 Lock 有什么区别?

synchronized是 JVM 层面的锁,程序员只需要加synchronized关键字即可。

Lock是接口,可以被实现被继承,程序员可以通过调用api来实现锁。

Lock相对于synchronized灵活性更好,手动拿锁、释放锁、删除等待时间过长的线程,可控性高。

synchronized 和 ReentrantLock 区别是什么?

都是支持重入的锁。其余的和上一个问题一样回答即可。

说一下 atomic 的原理?

对于并发场景使用,内部使用了 CAS 原子操作,在同一时刻只允许一个线程修改数据。

什么是反射

通过每一个类对应的Class对象,拿到这个对象的所有信息包括私有的。

什么是 java 序列化?什么情况下需要序列化

简单说就是把Java对象转换为字节序列的过程,并且可以保存对象的各种属性与方法。

  1. 需要进行i/o操作
  2. 需要在网上传输对象

动态代理是什么?有哪些应用?

动态代理是一种设计模式

可以在不改变原有类的情况下增加方法,就是创建一个新的类,这个类有着原有对象的引用,并且对原有类的方法进行了扩展,再通过调用对象的对应方法实现功能的扩展。

最典型的就是Spring的AOP。

怎么实现动态代理?

首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。

为什么要使用克隆?

像创建一个新的对象,并且想保留旧对象的属性。

如何实现对象克隆?

类继承Cloneable接口并重写Object类中的clone()方法;

调用 对象.clone()方法即可

深拷贝和浅拷贝区别是什么?

浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化。

深拷贝是创建一个新的对象然后把原来对象的值复制过来,两个对象修改其中任意的值另一个值不会改变。

throw 和 throws 的区别?

thrwos用在方法最后,如果出现了声名的异常或者子异常都会抛给调用者。

throw用在方法内部,主动抛出一个具体的异常。

try-catch-finally 中哪个部分可以省略?

finally和catch只可以省略一个。

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

会执行,在return的前面执行,如果finally中也有return,则不会执行catch中的return。

final、finally、finalize 有什么区别?

他们三者没有什么联系。

final:用来修饰类、方法和属性,分别表示不可被继承,重写和常量。

finally用:在try-catch语句块中的最后,表示一定需要执行的代码,通常用来执行关闭操作。

finalize:是Object的一个方法,和GC有关系,在GC以前都需要执行一次这个方法。

常见的异常类有哪些?

  1. NullPointerException
  2. IOException
  3. SQLException
  4. NumberFormatException
  5. ArrayIndexOutOfBoundsException
  6. NoSuchMethodException
  7. ClassNotFoundException

MVC的思想

说说Mvc的优缺点

优点bai:

1.各施其职,互du不干涉

在MVC模式中,三个层各施其职,所以如果一旦哪zhi一层的需求发生了变dao化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。

2.有利于开发中的分工

在MVC模式中,由于按层把系统分开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务层,而其它开发人员可开发控制层。

3.有利于组件的重用

分层后更有利于组件的重用。如控制层可独立成一个能用的组件,视图层也可做成通用的操作界面。

4.MVC设计模式可以说实现了分层开发。各个层都有各个层的作用。

5.降低了层与层之间的依赖,有利于代码的标准化开发

6.再用新的代码业务逻辑替换时,只需要替换相对应的层,大大降低了我们的工作量,分工明确。

缺点:

1.增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。

2.视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。