java常见面试题及答案
Posted hyv587
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java常见面试题及答案相关的知识,希望对你有一定的参考价值。
https://www.cnblogs.com/java1024/p/8116327.html
(1)抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。
如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。
(2))抽象类和接口的区别有哪些?
(1)抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。
如果一个类中有了一个抽象方法,那么这个类必须声明为抽象类,否则编译通不过。
(2))抽象类和接口的区别有哪些?
答:
抽象类中可以没有抽象方法,但如果有一个抽象方法,必须声明为抽象类;接口中的方法必须是抽象方法;
抽象类中可以有普通的成员变量;接口中的变量必须是 static final 类型的,必须被初始化 , 接口中只有常量,没有变量。
抽象类只能单继承,接口可以继承多个父接口;
Java8 中接口中会有 default 方法,即方法可以被实现。
(3) 1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
抽象类中可以有普通的成员变量;接口中的变量必须是 static final 类型的,必须被初始化 , 接口中只有常量,没有变量。
抽象类只能单继承,接口可以继承多个父接口;
Java8 中接口中会有 default 方法,即方法可以被实现。
(3) 1. 抽象类不能被实例化(初学者很容易犯的错),如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象。
2. 抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
3. 抽象类中的抽象方法只是声明,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能。
4. 构造方法,类方法(用 static 修饰的方法)不能声明为抽象方法。
5. 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类。
封装、继承和多态;
封装:
(4)封装的优点
(4)封装的优点
1. 良好的封装能够减少耦合。
2. 类内部的结构可以自由修改。
3. 可以对成员变量进行更精确的控制。
4. 隐藏信息,实现细节。
public class EncapTest{
private String name;
private String idNum;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String getIdNum(){
return idNum;
}
public void setAge( int newAge){
age = newAge;
}
public void setName(String newName){
name = newName;
}
public void setIdNum( String newId){
idNum = newId;
}
}
public class EncapTest{
private String name;
private String idNum;
private int age;
public int getAge(){
return age;
}
public String getName(){
return name;
}
public String getIdNum(){
return idNum;
}
public void setAge( int newAge){
age = newAge;
}
public void setName(String newName){
name = newName;
}
public void setIdNum( String newId){
idNum = newId;
}
}
接口:
不一定,抽象类实现某个接口,可以不实现所有接口的方法,可以由它的子类实现。
不一定,抽象类实现某个接口,可以不实现所有接口的方法,可以由它的子类实现。
接口与类的区别:
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法。
接口不能包含成员变量,除了 static 和 final 变量。
接口不是被类继承了,而是要被类实现。
接口支持多继承。
抽象类和接口的区别
接口没有构造方法。
接口中所有的方法必须是抽象方法。
接口不能包含成员变量,除了 static 和 final 变量。
接口不是被类继承了,而是要被类实现。
接口支持多继承。
抽象类和接口的区别
1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
Java 数据结构
2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
Java 数据结构
Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类:
枚举(Enumeration)
位集合(BitSet)
向量(Vector)向量(Vector)类和传统数组非常相似,但是Vector的大小能根据需要动态的变化。
栈(Stack)说,最后进栈的元素最先被取出。
字典(Dictionary)
哈希表(Hashtable)
属性(Properties)
位集合(BitSet)
向量(Vector)向量(Vector)类和传统数组非常相似,但是Vector的大小能根据需要动态的变化。
栈(Stack)说,最后进栈的元素最先被取出。
字典(Dictionary)
哈希表(Hashtable)
属性(Properties)
Java 中的值传递和引用传递
反射、泛型、注解等:
Java 中常见集合
)说说常见的集合有哪些吧?
)说说常见的集合有哪些吧?
答:Map 接口和 Collection 接口是所有集合框架的父接口:
Collection 接口的子接口包括:Set 接口和 List 接口;
Map 接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;
Set 接口的实现类主要有:HashSet、TreeSet、LinkedHashSet 等;
List 接口的实现类主要有:ArrayList、LinkedList、Stack 以及 Vector 等。
HashMap 和 Hashtable 的区别有哪些?(必问)
Map 接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap 以及 Properties 等;
Set 接口的实现类主要有:HashSet、TreeSet、LinkedHashSet 等;
List 接口的实现类主要有:ArrayList、LinkedList、Stack 以及 Vector 等。
HashMap 和 Hashtable 的区别有哪些?(必问)
答:
HashMap 没有考虑同步,是线程不安全的;Hashtable 使用了 synchronized 关键字,是线程安全的;
前者允许 null 作为 Key;后者不允许 null 作为 Key。
前者允许 null 作为 Key;后者不允许 null 作为 Key。
HashMap 的底层实现你知道吗?
同步:发送一个请求,等待返回,然后再发送下一个请求
异步:发送一个请求,不等待返回,随时可以再发送下一个请求
高并发编程-JUC 包:
多线程和单线程的区别和联系:
多线程和单线程的区别和联系:
答:
在单核 CPU 中,将 CPU 分为很小的时间片,在每一时刻只能有一个线程在执行,是一种微观上轮流占用 CPU 的机制。
多线程会存在线程上下文切换,会导致程序执行速度变慢,即采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。
多线程会存在线程上下文切换,会导致程序执行速度变慢,即采用一个拥有两个线程的进程执行所需要的时间比一个线程的进程执行两次所需要的时间要多一些。
结论:即采用多线程不会提高程序的执行速度,反而会降低速度,但是对于用户来说,可以减少用户的响应时间。
)如何指定多个线程的执行顺序?
)如何指定多个线程的执行顺序?
解析:面试官会给你举个例子,如何让 10 个线程按照顺序打印 0123456789?(写代码实现)
答:
设定一个 orderNum,每个线程执行结束之后,更新 orderNum,指明下一个要执行的线程。并且唤醒所有的等待线程。
在每一个线程的开始,要 while 判断 orderNum 是否等于自己的要求值!!不是,则 wait,是则执行本线程。
在每一个线程的开始,要 while 判断 orderNum 是否等于自己的要求值!!不是,则 wait,是则执行本线程。
线程和进程的区别:(必考)
答:
进程是一个 “执行中的程序”,是系统进行资源分配和调度的一个独立单位;
线程是进程的一个实体,一个进程中拥有多个线程,线程之间共享地址空间和其它资源(所以通信和同步等操作线程比进程更加容易);
线程上下文的切换比进程上下文切换要快很多。
线程是进程的一个实体,一个进程中拥有多个线程,线程之间共享地址空间和其它资源(所以通信和同步等操作线程比进程更加容易);
线程上下文的切换比进程上下文切换要快很多。
(1)进程切换时,涉及到当前进程的 CPU 环境的保存和新被调度运行进程的 CPU 环境的设置。
(2)线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
多线程产生死锁的 4 个必要条件?
(2)线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。
多线程产生死锁的 4 个必要条件?
答:
互斥条件:一个资源每次只能被一个线程使用;
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放;
不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺;
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
如何避免死锁?(经常接着问这个问题哦~)
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放;
不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺;
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
如何避免死锁?(经常接着问这个问题哦~)
答:指定获取锁的顺序,举例如下:
比如某个线程只有获得 A 锁和 B 锁才能对某资源进行操作,在多线程条件下,如何避免死锁?
获得锁的顺序是一定的,比如规定,只有获得 A 锁的线程才有资格获取 B 锁,按顺序获取锁就可以避免死锁!!!
sleep( ) 和 wait( n)、wait( ) 的区别:
获得锁的顺序是一定的,比如规定,只有获得 A 锁的线程才有资格获取 B 锁,按顺序获取锁就可以避免死锁!!!
sleep( ) 和 wait( n)、wait( ) 的区别:
答:
sleep 方法:是 Thread 类的静态方法,当前线程将睡眠 n 毫秒,线程进入阻塞状态。当睡眠时间到了,会解除阻塞,进行可运行状态,等待 CPU 的到来。睡眠不释放锁(如果有的话);
wait 方法:是 Object 的方法,必须与 synchronized 关键字一起使用,线程进入阻塞状态,当 notify 或者 notifyall 被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,释放互斥锁。
synchronized 关键字:
wait 方法:是 Object 的方法,必须与 synchronized 关键字一起使用,线程进入阻塞状态,当 notify 或者 notifyall 被调用后,会解除阻塞。但是,只有重新占用互斥锁之后才会进入可运行状态。睡眠时,释放互斥锁。
synchronized 关键字:
答:底层实现:
进入时,执行 monitorenter,将计数器 +1,释放锁 monitorexit 时,计数器-1;
当一个线程判断到计数器为 0 时,则当前锁空闲,可以占用;反之,当前线程进入等待状态。
线程池有了解吗?(必考)
当一个线程判断到计数器为 0 时,则当前锁空闲,可以占用;反之,当前线程进入等待状态。
线程池有了解吗?(必考)
答:java.util.concurrent.ThreadPoolExecutor 类就是一个线程池。客户端调用 ThreadPoolExecutor.submit(Runnable task) 提交任务,线程池内部维护的工作者线程的数量就是该线程池的线程池大小,有 3 种形态:
当前线程池大小 :表示线程池中实际工作者线程的数量;
最大线程池大小 (maxinumPoolSize):表示线程池中允许存在的工作者线程的数量上限;
核心线程大小 (corePoolSize ):表示一个不大于最大线程池大小的工作者线程数量上限。
最大线程池大小 (maxinumPoolSize):表示线程池中允许存在的工作者线程的数量上限;
核心线程大小 (corePoolSize ):表示一个不大于最大线程池大小的工作者线程数量上限。
如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队;
如果运行的线程等于或者多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不是添加新线程;
如果无法将请求加入队列,即队列已经满了,则创建新的线程,除非创建此线程超出 maxinumPoolSize, 在这种情况下,任务将被拒绝。
Java四种线程池的使用:
如果运行的线程等于或者多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不是添加新线程;
如果无法将请求加入队列,即队列已经满了,则创建新的线程,除非创建此线程超出 maxinumPoolSize, 在这种情况下,任务将被拒绝。
Java四种线程池的使用:
Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
HTTP协议是一种应用层协议,HTTP是HyperText Transfer Protocol(超文本传输协议)的英文缩写。
HTTP可以通过传输层的TCP协议在客户端和服务器之间传输数据。
HTTP协议主要用于Web浏览器和 Web服务器之间的数据交换。
第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认。
第二次握手:服务器收到syn包,必须确认客户端的syn(ack=j+1),同时自己也发送一个syn包(syn=k), 即SYN+ACK包,此时服务器进入SYN_RECV状态
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(建立完成)状态,完成三次握手。
主动建立连接、主动断开连接、被动建立连和被动断开连接
TCP是确认包的到达,所以不丢失包(数据),顺序也是好的。
UDP不会确认包的到达,所以可能会丢失数据包,当然顺序也有可能会乱。
除了这些以外:
1. TCP是面向连接(三次握手)的,所以稳定、可靠,那相对就慢了
比如平时的:文件传输,右键,http等用的都是tcp协议
2. UDP是面向无连接的,所以不稳定,但是相对快,实时性高
数据库知识点
听说过事务吗?(必考)
答:作为单个逻辑工作单元执行的一系列操作,满足四大特性:
原子性(Atomicity):事务作为一个整体被执行 ,要么全部执行,要么全部不执行;
一致性(Consistency):保证数据库状态从一个一致状态转变为另一个一致状态;
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
持久性(Durability):一个事务一旦提交,对数据库的修改应该永久保存
)事务的并发问题有哪几种?
一致性(Consistency):保证数据库状态从一个一致状态转变为另一个一致状态;
隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行;
持久性(Durability):一个事务一旦提交,对数据库的修改应该永久保存
)事务的并发问题有哪几种?
答:丢失更新、脏读、不可重复读以及幻读。
5)数据库中的锁有哪几种?
答:独占锁、排他锁以及更新锁。
答:独占锁、排他锁以及更新锁。
6)事务的隔离级别有哪几种?
答:读未提交、读已提交、可重复读和序列化。
扩展问题:mysql 事务默认隔离级别是哪个?
答:可重复读。
数据库中 Where、group by、having 关键字:
数据库中 Where、group by、having 关键字:
答: 关键字作用:
where 子句用来筛选 from 子句中指定的操作所产生的的行;
group by 子句用来分组 where 子句的输出;
having 子句用来从分组的结果中筛选行;
group by 子句用来分组 where 子句的输出;
having 子句用来从分组的结果中筛选行;
JavaWeb 开发经典的 3 层框架:Web 层、Service 层(业务逻辑层)和 Dao 层(数据访问层)
MVC 框架相关知识点
Web 层:包含 JSP 和 Servlet 等与 Web 相关的内容;
业务层:只关心业务逻辑;
数据层:封装了对数据库的访问细节。
Spring 知识点
Web 层:包含 JSP 和 Servlet 等与 Web 相关的内容;
业务层:只关心业务逻辑;
数据层:封装了对数据库的访问细节。
Spring 知识点
1)Spring 的 IOC 和 AOP 有了解吗?
答:
IOC:控制反转,(解耦合)将对象间的依赖关系交给 Spring 容器,使用配置文件来创建所依赖的对象,由主动创建对象改为了被动方式;
AOP:面向切面编程,将功能代码从业务逻辑代码中分离出来。
AOP:面向切面编程,将功能代码从业务逻辑代码中分离出来。
2)AOP 的实现方式有哪几种?如何选择?(必考)
答:JDK 动态代理实现和 cglib 实现。
选择:
如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理实现 AOP,也可以强制使用 cglib 实现 AOP;
如果目标对象没有实现接口,必须采用 cglib 库,Spring 会自动在 JDK 动态代理和 cglib 之间转换。
如果目标对象没有实现接口,必须采用 cglib 库,Spring 会自动在 JDK 动态代理和 cglib 之间转换。
以上是关于java常见面试题及答案的主要内容,如果未能解决你的问题,请参考以下文章