Java面试实际面试题目,持续更新
版本 | 更新说明 | 时间 |
---|---|---|
1.0 | 编写本博客 | 2020/10/23 |
1.1 | 增加第二节第3条,来自深圳久胜和科技面试题 | 2020/10/24 |
1.2 | 增加第五节第3条,来自汕头创美药业面试题 | 2020/11/2 |
文章目录
一、面向对象
1. 一大两小两同
一大:访问权限: S o n ≥ F a t h e r Son \ge Father Son≥Father
如果子类的访问权限比父类访问权限小的话,会对多态性一个打击,一个子类实现接口后把权限改为private那么就无法通过这个接口多态调用,那么这个接口也就没有意义了.
两小: S o n ≤ F a t h e r Son \le Father Son≤Father
- 返回类型
- 抛出异常
两同: S o n = F a t h e r Son = Father Son=Father
- 方法名
- 参数列表
2. 多态性
多态性是指向不同对象发送同一个消息,不同对象在接受到消息时产生不同的行为。
多态性的优点有
- 灵活性
- 可扩展性
- 可复用性
多态的具体表现
- 重写 Overriding,子类和父类多态的体现
- 重载 Overloading,同一个类中多态的体现
3. 向上转型和向下转型
向上转型:父类引用指向一个子类对象,安全
子类对象在创建的时候首先先创建父类对象,然后再加上子类的属性和方法,就构成了子类对象
向下转型:只有当父类引用原本是向上转型而来的,这是再向上转型才是允许的,其他会抛ClassCastException
异常
// 直接向上转型:异常
Father father = new Father();
Son son = (Son) father;
son.speak();
son.play();
//间接向上转型: 安全
Father father = new Son();
Son son = (Son) father;
son.speak();
son.play();
二、JAVA SE
1. 什么是反射?反射的实现原理?
- 反射:程序在运行时,对于任意一个类,可以知道它的所有属性和方法,对于任意一个对象,都能够动态调用它的所有方法和属性。
- 反射的实现原理:类在运行时会编译成.class字节码文件,通过获取其字节码,就能够得到类的类名、属性、方法等全部信息。反射的实现主要借助四个类
Class
、Constructor
、Method
、Field
2. |=
|=
和+=
一样,a|=b
等价于a = a | b
public static void main(String[] args) {
System.out.println(a(666));
}
static int a(int tab){
int n = tab - 1;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
return n;
}
答案为1023
3. 接口和抽象类在应用场景下的区别
接口和抽象类的区别
- 接口定义了一组动作
抽象类是类的抽象(包括属性和方法) - 接口多继承
抽象类单继承 - 接口中不能有方法的具体实现(除了默认方法)
抽象类可以有方法的具体实现 - 接口的属性默认为
public static final
,接口的方法默认是public abstract
,JDK1.9之后,接口可以有private方法和default方法,但不能有protected方法
抽象类的方法和属性可以被任意修饰符修饰
interface I {
public abstract void test();
void test1();
private void test2() {
System.out.println("Hello!");
}
//protected void test3(); 报错
default void test4(){
System.out.println("Hello");
}
}
三、框架
1. Spring中IoC底层实现
IoC是一种设计思想,从传统的程序new一个对象到由IoC容器对对象实例化、定位、配置的统一管理,从而实现了松耦合。
Spring中用反射+XML实现的。
- 初始化容器
- 扫描XML文件
- 获取并解析包下面所有类信息
- 根据注解将这些类封装到bean容器中
- 利用反射实例化类的对象
- 初始化完毕
2. Spring中AOP底层实现
Spring中AOP主要使用动态代理实现,主要有两种方式,一是JDK动态代理,一种是CGLIB动态代理
- JDK动态代理
- 代理类和代理对象都要实现同一个接口
- 首选
- CGLIB动态代理
- 生成被代理类的子类对象
- 备选
四、数据库
1. 主键、普通索引、唯一索引的区别
名称 | 独一性 | 唯一性 |
---|---|---|
主键 | √ \surd √ | √ \surd √ |
唯一索引 | √ \surd √ | |
普通索引 |
五、网络
1. 浏览器输入URL到可以看见页面的过程
- DNS
- 创建TCP连接
- 浏览器发送HTTP请求(附在三报文握手的第三个报文中)
- 服务器处理请求
- 服务器响应HTTP请求
- 浏览器接受并解析渲染请求
- 关闭TCP连接
2. 为什么TCP是一个可靠的协议
- 检验(UDP检验一样)
- 序号
- 确认
- 重传(超时和冗余ACK)
TCP的任务是在IP层不可靠的、尽力而为服务的基础上建立一种可靠数据传输服务。TCP提供的可靠数据服务保证接收方进程从缓存区读出的字节流与发送方发出的字节流完全一致。
3. Get和Post的区别
直接区别
Get请求
- Get请求能够被缓存
- Get会被保存在浏览器记录里
- 以Get请求的URL可以保存在浏览器书签里
- Get传送的数据量较小,不能大于2KB
- Get请求主要用于获取数据
- Get请求只产生一个数据包
Post请求
- Post请求不能被缓存
- Post请求不会被保存在浏览器记录里
- 以Post请求的URL不可以保存在浏览器书签里
- Post传送的数据量可以不受限制
- Post请求主要用于传输数据
- Post请求产生两个数据包(Firefox例外只产生一个数据包)
本质区别:
Get请求和Post请求都是HTTP协议中发送请求的方法,HTTP请求又基于TCP/IP协议,所以本质上两者是一样的,有所区别是为了更好的适配不同的场景
六、设计模式
1. 手写单例模式实现代码
- 懒汉式,线程不安全
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
- 懒汉式,线程安全
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
public static synchronized Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
- 饿汉式,线程安全
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(){
}
public static Singleton getSingleton(){
return singleton;
}
}
- 双重校验锁,线程安全且性能高
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
public static Singleton getSingleton(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
- 登记/静态内部类,线程安全
public class Singleton {
private static class SingletonHolder{
private static final Singleton SINGLETON = new Singleton();
}
private Singleton(){
}
public static final Singleton getSingleton(){
return SingletonHolder.SINGLETON;
}
}