# 1.什么是面相对象?
封装、继承、多态。
封装:隐藏具体的实现细节,保留对外开放的访问方式
继承:类与类之间的关系,子类继承父类的非私有成员,不继承父类构造,但可以访问无参构造。但是只能单继承,可以嵌套。
多态:事务的多种形态,让接口重用。多态前提:继承关系、方法重写、父类引用指向子类对象。
# 2.重写与重载?
重写就是父类子类一个多态表现,子类与父类中同名的名称和参数就是重写,具体代码中有@Override标签。
重载就是一个类中多态性的体现,方法名相同,但是传入参数的个数、类型、甚至顺序不同都是重载。通过重载可以改变返回值的类型。
# 3.一个类不会被继承?
1.将类的构造函数定义为private属性
2.把类用final修饰
# 4.接口和抽象类的区别?
1.接口是一种设计标准,写明子类需要实现的功能。而抽象类是一种代码简化思想,通过抽取公共功能,子类继承来达到代码优化,方便统一的修改。
2.接口可以多实现,方便拓展,默认方法被public abstract修饰。变量默认被public static final修饰,就是常来那个,没有构造方法。
3.抽象类是Java的单继承,有构造方法,通过abstract修饰并含有抽象方法。
4.接口实现是interface修饰,而类的实现是implements。
# 5.TCP的三次握手与四次挥手
客户端A,服务端B
A->发送请求B:我要来了,B回复:收到连接请求,A回复:我收到了B的连接请求。
开始数据传输
A->B请求关闭 B->A收到关闭请求 B->A已经处理完成,等待关闭 A->B 确认关闭
# 6.常用的通讯协议?
**TCP协议:**面向链接的协议,数据传输之前首先建立链接,然后再传输数据,提供了两台计算机之间的可靠传输。TCP协议中需要明确客户端与服务端,由客户端向服务端发送请求,每次链接都得进行三次握手,每次断开都要经历四次挥手。
**HTTP协议:**HTTP协议是客户端(用户)和服务器端(网站)请求和应答的标准协议。做项目都使用HTTP协议,前端到后端的请求也是使用HTTP协议,请求中会包含请求参数、请求类型、请求地址,还会在请求头中设置一些参数传递给后端。
**底层流程:**1.客户端链接到Web服务器 2.客户端发送HTTP请求到服务端 3.服务器接受请求并相应数据给客户端 4.客户端/服务端(可以通过配置都可释放),可以释放连接TCP连接。
# 7.Java中的反射机制?
Java的反射机制就是在运行状态中,对于任意一个类和对象,都能够获得这个类的所有属性和方法,反射首先是能够获取到Java中要反射的字节码。有三种方法:
1.Class.forName(类名);
2.类名.Class;
3,this.getClass().然后将字节码中的方法、变量、构造函数等映射成相应的Method成员方法、Filed成员变量,Constructor构造方法等类。
1.class.forName(全类名)
这个是字节码文件还没被加载进入内存中,调用class.forName("包名+类名"),将字节码文件加载到内存,返回class对象。
2.类名.class
当字节码文件加载到内存中,通过类名.Class直接获取
3.对象.getClass()
通过对象.getClass()获取,而这个是Object类中的方法。
开发中什么地方用到?
反射的功能很强大,允许我们在程序运行的时候动态获取对象中的方法或者参数。比如:对于List
// 利用反射机制将String类型存入Integer
List<Integer> list = Lists.newArrayList();
list.add(1);
list.add(2);
// 获取List的声明类型
Class<? extends List> aClass = list.getClass();
// 获取List的参数类型
Type type = aClass.getGenericSuperclass();
// 如果类型是一个参数化类型:就是有<>传入具体类
if (type instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) type;
// 获取参数类型
Type[] typeArguments = parameterizedType.getActualTypeArguments();
// 设置List的类型参数为Object
typeArguments[0] = Object.class;
// 重新设置List的参数类型为Object
Field elementDataField = aClass.getDeclaredField("elementData");
elementDataField.setAccessible(true);
// 获取elementData数组
Object[] elementData = (Object[]) elementDataField.get(list);
elementData[0] = "hello World!";
// 使用反射绕过泛型检查,尝试添加一个String到List<Integer>中
System.out.println("操作后的列表内容:");
for (Object item : list) {
System.out.println(item);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 8.Switch中可以用String吗?
JDK1.7之前,只支持char、byte、short、int类型的数据,JDK7之后,支持String。底层原理是调用Switch中的Strring.hashCode,将String类型转化为哈希值的int类型进行判断。其实在实际使用过程中不如使用if-else和Map等进行处理。
# 9.==与equals的区别?
操作符 vs 方法:
- == 是一个操作符,用于比较两个对象的引用是否相同,即它们是否指向内存中的同一个位置。
- equals() 是一个方法,定义在Object类中,用于比较两个对象的内容是否相等,即它们所包含的值是否相同。
比较内容 vs 比较引用:
- == 比较的是两个对象的内存地址,也就是它们是否是同一个对象的两个引用。
- equals() 比较的是对象的“内容”,即对象所封装的数据是否相等。默认情况下,equals()方法比较的是对象的内存地址(即和==相同),但是许多类会重写这个方法,以实现基于内容的比较。
重写:
- == 不能被重写,它始终比较的是引用。
- equals() 可以被重写,允许类定义自己的“相等”概念。
null 安全性:
- 使用 == 比较时,如果其中一个引用为 null,则结果为 false,但不会抛出异常。
- 使用 equals() 方法时,如果对象为 null,则会抛出 NullPointerException,除非该方法显式处理了 null 的情况。
集合框架:
- 在Java集合框架中,如HashSet、HashMap等,通常使用equals()方法来确定对象的唯一性,而不是==。
一致性:
- 一个良好的equals()实现应该满足一致性原则,即对于任何非空引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
对称性:
- equals() 方法应该是对称的,即对于任何非空引用x和y,x.equals(y)应该和y.equals(x)的返回值相同。
传递性:
- equals() 方法应该是传递的,即如果x.equals(y)和y.equals(z)都返回true,那么x.equals(z)也应该返回true。
反射性:
- equals() 方法应该是反射的,即对于任何非空引用x,x.equals(x)应该返回true。
总结来说,==用于比较两个对象是否为同一个对象,而equals()用于比较两个对象的内容是否相等。在编写类时,如果需要基于内容的比较,应该重写equals()方法,并确保它满足上述的一致性、对称性、传递性和反射性原则。
# 10.error和Exception的区别
Error是系统中的错误,不是程序员可以改变和处理的,程序编译出现的错误只能通过修改程序才能正常。一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、内存空间不足等,对于这类错误导致的程序中断紧靠程序本身无法恢复和预防。
Exception表示程序可以处理的异常,可以捕获且可能恢复。运行时异常可以try catch捕获,编译时异常RuntimeException、
# 11.throw和throws的区别
throw是具体抛出哪个异常,throws则是方法上声明可能出现的异常。
# 12.Session和Cookie的区别
**Session:**由服务器产生、保存在服务器端,作用域是一次会话,只要浏览器没关就认为session没断,所有请求共享session数据。
**Cookie:**由服务器产生,保存在浏览器中,由浏览器发送请求,携带当前所有的cookie,字符串类型,不能存储中文,一个站点存放数量不超30个。
# 13.String类的用法,String a = "Hello" String a = new String("hello")的创建流程
String a = "hello":可能创建一个对象或者不创建一个对象,如果常量池中没有“hello”字符串,会在常量池中创建一个String对象"hello",a直接引用这个常量池中的对象。
String a = new String(“hello”)
至少创建一个对象,也可能2个。因为new会从堆中创建一个a的String对象("hello")。同时,如果常量池中不存在这个String对象,则会在Java的常量池中穿件。