2024年java面试准备--java基础篇

2023-10-16 10:10:50 浏览数 (1)

java基础

这些java基础的相关知识是我准备实习期间总结一些网上java基础和自己被面试官询问到的一些知识点,供大家学习参考,有问题可私信我,后续会更新集合、spring、线程、mysql、redis等相关知识点和面试易考点~~

向上转型

向上转型:一句话总结就是“父类引用指向子类对象”

关于方法:父类引用可以调用子类和父类公用的方法(如果子类重写了父类的方法,则调用子类的方法),但子类特有的方法无法调用。

关于属性: 父类引用可以调用父类的属性,不可以调用子类的属性

向上转型的作用

  1. 减少一些重复性的代码
  2. 对象实例化的时候可以根据不同需求实例化不同的对象

自增(前)b= a可以写成a=a 1,b=a。 自增(后)b=a 可以写成b=a,a=a 1。

抽象类

  1. 使用abstract修饰的类或方法,就抽象类或者抽象方法
  2. 抽象类是不能具体的描述一个对象,不能用抽象类直接实例化对象
  3. 抽象类里面的成员变量和成员方法,都是和普通类一样的,只不过就是不能进行实例化了
  4. 当一个普通类继承这个抽象类后,那么这个普通类必须重写抽象类当中的所有的抽象方法(我们之前说过抽象类是不具体的,没有包含足够的信息来描述一个对象,所以我们需要把他补充完整)
  5. 但当一个抽象类A继承了抽象类B,这是抽象类A就可以不重写抽象类B当中的抽象方法
  6. final不能修饰抽象类和抽象方法(因为抽象类存在的最大意义就是被继承,而被final修饰的不能被继承,final和抽象,他们两个是天敌)
  7. 抽象方法不能被private修饰(抽象方法一般都是要被重写的,你被private修饰了,还怎么重写)
  8. 抽象类当中不一定有抽象方法,但如果一个类中有抽象方法,那么这个类一定是抽象类。

接口

  1. 接口中可以包含变量和方法,变量被隐式指定为 public static final,方法被隐式指定为 public abstract(JDK 1.8一个类可以同时实现多个接口,一个类实现某个接口则必须实现该接口中的抽象方法,否则该类必须被定义为抽象类
  2. 接口支持多继承,即一个接口可以继承(extends)多个接口,间接解决了 Java 中类不能多继承的问题。

抽象类和接口有什么区别

继承方面

抽象类只能单继承;而接口可以多继承

成员属性方面

抽象类中可以有普通属性,也可以有常量;

接口中的成员变量全部默认是常量,使用public static final修饰,这个可以省略不写

代码块方面

抽象类可以含初始化块;

接口不能含初始化块

构造函数方面

抽象类可以有构函数,但是这里的构造函数不是用来创建对象的,而且用来被实现类调用进行初始化操作的

接口不能有构造函数;

方法方面

接口在JDK1.8之后可以定义抽象方法(无方法体)、default修饰的默认方法(有方法体)、static修饰的静态方法(有方法体),JDK1.8以前是只能有抽象方法。

抽象类中除了静态方法和抽象方法外还可以有普通方法。

二者相同之处

接口与抽象类都不能被实例化,需要被其他进行实现或继承。

接口与抽象类里面都能包含抽象方法,实现接口或继承抽象类的子类都必须实现这些抽象方法。

设计模式

1.JDK中常用的设计模式

单例模式:用于 Runtime,Calendar 和其他的一些类中。

工厂模式:被用于各种不可变的类如 Boolean,像 Boolean.valueOf。

观察者模式:被用于 Swing 和很多的事件监听中。

装饰器模式:被用于多个 Java IO 类中。

2.Spring中常用的设计模式

工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;

单例模式:Bean默认为单例模式。

代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;

模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate。

观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。

3. 单例模式

某个类只能生成一个实例,该实例全局访问,例如Spring容器里一级缓存里的单例池。

优点

唯一访问:如生成唯一序列化的场景、或者spring默认的bean类型。

提高性能:频繁实例化创建销毁或者耗时耗资源的场景,如连接池、线程池。

缺点

不适合有状态且需变更的

实现方式

饿汉式:线程安全速度快,饿汉就是类一旦加载,就把单例初始化完成,保证getInstance的时候,单例是已经存在的了。

懒汉式:双重检测锁,第一次减少锁的开销、第二次防止重复、volatile防止重排序导致实例化未完成,而懒汉比较懒,只有当调用getInstance的时候,才回去初始化这个单例。本身是非线程安全的

静态内部类:线程安全利用率高

枚举:effictiveJAVA推荐,反射也无法破坏

4. 工厂模式

定义一个用于创建产品的接口,由子类决定生产何种产品。

优点: 解耦:提供参数即可获取产品,通过配置文件可以不修改代码增加具体产品。

缺点: 每增加一个产品就得新增一个产品类

5. 抽象工厂模式

提供一个接口,用于创建相关或者依赖对象的家族,并由此进行约束。

优点: 可以在类的内部对产品族进行约束

缺点:假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。

6.观察者模式

观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象(目标对象)的状态发生改变时,所有依赖于它的对象(观察对象)都得到通知并被自动更新。

特点:被观察者和观察者一般是一对多的关系,一个被观察者对应多个观察者,当一个被观察者的状态发生改变时,被观察者通知观察者,然后可以在观察者内部进行业务逻辑的处理。

7.装饰器模式

装饰器模式是一种结构型设计模式,用于在不修改原有对象的基础上动态地给对象添加新的功能。装饰器模式通过创建一个新的装饰器类,继承原有类的基本功能,然后扩展或覆盖原有功能。装饰器模式可以在运行时根据需要灵活地给对象添加或组合功能。

8.代理模式

给一个对象提供一种代理对象以控制对该对象的访问。 简单点理解: 目标对象:原对象,我们需要通过代理对象控制它的访问,扩展其功能。 代理对象:代理模式产生的对象,是原对象的替身,在原有基础上进行修改。 在不改变原对象代码的基础上对原对象的功能进行扩展 再简单点理解: 比如点外卖事件 你想吃麻辣烫,自己又不想去店里吃,所以你点外卖,此时的外卖小哥,可以看作为代理对象。而你又想在吃完麻辣烫后喝一杯珍珠奶茶,所以你又联系外卖小哥帮你去店里买一杯。这个过程可以理解为加的扩展功能。

什么是面向对象

Java是面向对象的编程语言,不同于C语言是面向过程的。对于面向对象和面向过程的区别,举一个简单的例子说明一下(我们以洗衣机洗衣服为例)∶

面向过程:

面向过程的编程方式,程序会将要完成的某一个任务拆解成一系列的小步骤(函数),如:。

①打开洗衣机:methodo1()

②放入要洗的衣服:method02()。

③放入洗衣粉:method03()。

④清洗: methodo4()

⑤烘干: method05()

面向对象:面向对象的编程方式,程序会将要完成的洗衣机洗衣服的任务拆分成如下两个对象:

人(Person ):Person在洗衣机洗衣服这个程序任务中有三个作用,分别是打开洗衣机、放入要洗的衣服、放入洗衣粉

洗衣机(Nachine ): Machine在洗衣机洗衣服这个程序任务中有两个作用,分别是清洗、烘干

Java对象创建的方式

  1. 使用new关键字创建对象
  2. 反射: 通过反射创建对象的方式又有两种,一是通过Class.newInstance
代码语言:javascript复制
public void aa() throws Exception{
    Class c = Student.class;
    Student student =(Student)c.newInstance();
    student.setSId(1);
    system.out.println(student.getSId());
}

二是通过调用构造器再去创建对象Constructor.newInstance

先通过反射获取类中无参构造器,然后通过newInstance()获取对象:

代码语言:javascript复制
public void aa() throws Exception{
    Class<Student> c = Student.class;
    Constructor<Student> constructor = c.getConstructor();
    Student student = constructor.newInstance();
    student.setSId(1);
    System.out.println(student.getSId( ));
}

3. Clone

通过Clone创建对象首先要在实体类中必须先实现Cloneable接口并复写Object的clone方法(因为Object的这个方法是protected的,你若不复写,外部也调用不了呀)。

代码语言:javascript复制
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student implements Cloneable {
    private int sId;
    private String sName;

    @Override
    public Student clone() throws CloneNotSupportedException {
        return (Student) super.clone();
    }
}
代码语言:javascript复制
public void aa() throws CloneNotSupportedException {
    student_student = new Student();
    Student clone = student.clone();
    clone.setSId(1);
    System.out.println(clone.getSId());
}
  1. 反序列化 序列化:指把 Java 对象转换为字节序列的过程; 反序列化:指把字节序列恢复为 Java 对象的过程; 因此我们可以通过反序列化创建对象,具体代码如下:
代码语言:javascript复制
public void aa() throws IOException,ClassNotFoundException {
    File file = new File("E:/a.txt");
    FileOutputStream fos = new FileoutputStream(file);
    objectoutputStream oos = new objectOutputStream(fos);
    Student student1 = new Student();
    oos. writeobject(student1);
    FileInputStream fis = new FileInputStream(file);
    0bjectInputStream ois = new ObjectInputStream(fis);
    Student student2 = (Student) ois.readObject();
    student2.setSId(1);
    System.out.println(student2.getSId());
}

简述面向对象的三个基本特征

继承:继承是Java中面向对象最显著的一个特征,继承是从已有的类中派生出新的类,新的类可以吸收已有的属性、行为,并扩展新的能力。Java中不支持多继承,但是接口可以支持多实现。

封装:将同一类事物的特征和功能包装在一起,只对外暴露需要调用的接口。封装也称为信息的隐藏,在Java中接口是体现封装最常用的方法,在接口中我们没有任何功能的实现(具体实现都交给实现类),只是定义了一系列抽象的方法声明用于外部调用。

多态:封装和继承都是为多态来服务的,多态是指同一个行为具有多个不同的表现形式。在Java中方法的重载和重写是实现多态的2种方式。

重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载。方法重载体现了编译时的多态性。

重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,重载对返回类型没有特殊的要求。方法重写体现了运行时的多态性。

多态的三要素:继承、重写、父类指向子类引用

Get和Post请求区别

HTTP请求:

方法

描述

GET

向特定资源发送请求,查询数据,并返回实体

POST

向服务器上传新的内容

PUT

向指定资源提交数据进行处理请求,可能会导致新的资源建立、已有资源修改

HEAD

类似GET请求,返回的响应中没有具体的内容,用于获取报头

DELETE

请求服务器删除指定标识的资源

OPTIONS

可以用来向服务器发送请求来测试服务器的功能性

TRACE

回显服务器收到的请求,用于测试或诊断

CONNECT

HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

get和Post区别:

GET

POST

可见性

数据在URL中对所有人可见

数据不会显示在URL中

安全性

与post相比,get的安全性较差,因为所 发送的数据是URL的一部分

安全,因为参数不会被保存在浏览器 历史或web服务器日志中

数据长度

受限制,最长2kb

无限制

编码类型

application/x-www-form-urlencoded

multipart/form-data

缓存

能被缓存

不能被缓存

HTTP常见响应状态码

100:Continue --- 继续。客户端应继续其请求。

200:OK --- 请求成功。一般用于GET与POST请求。

301:Moved Permanently --- 永久重定向。

302:Found --- 暂时重定向。

400:Bad Request --- 客户端请求的语法错误,服务器无法理解。

403:Forbideen --- 服务器理解请求客户端的请求,但是拒绝执行此请求。

404:Not Found --- 服务器无法根据客户端的请求找到资源(网页)。

500:Internal Server Error --- 服务器内部错误,无法完成请求。

502:Bad Gateway --- 作为网关或者代理服务器尝试执行请求时,从远程服务器接收到了无效的响应。

重定向和转发区别

重定向:redirect:

地址栏发生变化

重定向可以访问其他站点(服务器)的资源

重定向是两次请求。不能使用request对象来共享数据

转发:forward:

转发地址栏路径不变

转发只能访问当前服务器下的资源

转发是一次请求,可以使用request对象共享数据

8种基本数据类型和取值范围

基本类型

大小(位/bit)

字节数(byte)

最小值

最大值

默认值

包装器类型

boolean

-

-

false

true

false

Boolean

char

16 bits

2 bytes

Unicode 0

Unicode 2^16-1

Character

byte

8 bits

1 byte

-2^7

2^7-1

0

Byte

short

16 bits

2 bytes

-2^15

-2^15-1

0

Short

int

32 bits

4 bytes

-2^31

-2^31-1

0

Integer

long

64 bits

8 bytes

-2^63

-2^63-1

0

Long

float

32 bits

4 bytes

0.0

Float

double

64 bits

8 bytes

0.0

Double

static关键字

方便在没有创建对象的情况下来进行调用(方法/变量)

被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。(注意,只要是静态成员,方法,代码块是在类加载过程中就运行的

static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。

static变量也称为静态变量,静态变量和非静态变量的区别:

  • 静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化
  • 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响

==和equals的区别

1.对于==,比较的值是否相等

如果作用于基本数据类型的变量,则直接比较其存储的值是否相等

如果作用于引用类型的变量,则比较的是所指向的对象的地址

2.对于equals方法,注意:equals方法不能作用于基本数据类型的变量,equals继承Object类,比较的是是否是同一个对象,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;

例如String、Date等类对equals方法进行了重写的话,比较的是指向的对象的内容。

为什么要重写equals()和hashCode()方法

equals() 只是判断对象属性是否相同, hashcode() 要判断二者地址是否相同。

java中如果要判断两个对象是否相等,需要同时满足地址+属性都相同!

如果两个对象相同(即:用equals()比较返回true ),那么它们的 hashcode值一定要相同;

如果两个对象的hashcode()相同,它们并不—定相同;

(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()总是为true的。

(2)如果o1.hashCode() == o2.hashCode(),并不意味着o1.equals(o2)会为true。

final, finally, finalize的区别

  1. final用于声明属性方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 修饰变量:该属性一定要有初始值,要么在定义时马上初始化,要么在构造器中初始化。 该变量指向基本类型后该引用为常量,不能修改。 指向对象后,对象的引用不可变,但是对象的内容可变。 修饰方法:该方法无法被子类重写,但是可以被继承。 修饰类:该类无法被继承。比如java.lang.String类就是final类。 2) finaly是异常处理语句结构的一部分,表示总是执行,一定会执行。如果try里有一个return语句,会在return前执行finally中的代码。3) finalize是Object类的方法,执行gc时会调用此方法,可以覆盖此方法提供垃圾收集时其他资源的回收,比如关闭文件等。

请判断当一个对象被当作参数传递给一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

是值传递。java编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。

java中只有值传递,基本类型传递的是值的副本,引用类型传递的是引用的副本

说一下JVM/JRE/JDK区别

JVM = Java虚拟机

JRE = JVM 基础类库

JDK = JVM 基础类库 编译工具

Java异常体系

Throwable 是 Java 语言中所有错误或异常的超类。下一层分为 Error 和 Exception

Error :

是指 java 运行时系统的内部错误和资源耗尽错误。应用程序不会抛出该类对象。如果出现了这样的错误,除了告知用户,剩下的就是尽力使程序安全的终止。

Exception 包含:RuntimeException 、CheckedException

编程错误可以分成三类:语法错误、逻辑错误和运行错误。

语法错误(也称编译错误)是在编译过程中出现的错误,由编译器检查发现语法错误

逻辑错误指程序的执行结果与预期不符,可以通过调试定位并发现错误的原因

运行错误是引起程序非正常终端的错误,需要通过异常处理的方式处理运行错误

RuntimeException: 运行时异常,程序应该从逻辑角度尽可能避免这类异常的发生。

如 NullPointerException 、ClassCastException(类型强制转换异常) 、NullPointerException (空指针引用异常)、ArithmeticException(数学运算异常)、ArrayIndexOutOfBoundsException (下标越界异常)、NuberFormatException (数字格式不正常异常);

CheckedException: 受检异常,程序使用trycatch进行捕捉处理

如IOException、SQLException、NotFoundException;

0 人点赞