赞
踩
一、面向对象
1、面向对象和面向过程的区别
两者的主要区别在于解决问题的方式不同:
另外,面向对象开发的程序一般更易维护、易复用、易扩展。
2、创建一个对象用什么运算符?对象实体与对象引用有何不同?
new 运算符,new 创建对象实例(对象实例在内存中),对象引用指向对象实例(对象引用存放在栈内存中)。
3、如果一个类没有声明构造方法,该程序能正确执行吗?
构造方法是一种特殊的方法,主要作用是完成对象的初始化工作。
如果一个类没有声明构造方法,也可以执行!因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。如果我们自己添加了类的构造方法(无论是否有参),Java 就不会添加默认的无参数的构造方法了。
4、构造方法有哪些特点?是否可被 override?
构造方法特点如下:
构造方法不能被 override(重写),但是可以 overload(重载),所以你可以看到一个类中有多个构造函数的情况。
5、面向对象三大特征
封装是指把一个对象的状态信息(也就是属性)隐藏在对象内部,不允许外部对象直接访问对象的内部信息。但是可以提供一些可以被外界访问的方法来操作属性。如空调
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承,可以快速地创建新的类,可以提高代码的重用,程序的可维护性,节省大量创建新类的时间 ,提高我们的开发效率。
注意:
#多态
多态,顾名思义,表示一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。
多态的特点:
在java中要实现多态,必须要满足如下几个条件,缺一不可:
1.必须在继承体系下
2.子类必须要对父类方法进行重写
3.通过父类的引用调用重写方法
6、接口和抽象类有什么共同点和区别?
共同点:
default
关键字在接口中定义默认方法)。区别:
public static final
类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值。7.深拷贝和浅拷贝区别了解吗?什么是引用拷贝?
二、object
1、Object 类是一个特殊的类,是所有类的父类。
2、== 和 equals() 的区别
==
比较的是值。==
比较的是对象的内存地址。equals()
不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。equals()
方法存在于Object
类中,而Object
类是所有类的直接或间接父类,因此所有的类都有equals()
方法。equals()
方法存在两种使用情况:
equals()
方法:通过equals()
比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是 Object
类equals()
方法。equals()
方法:一般我们都重写 equals()
方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。3、hashCode() 有什么用?
hashCode()
的作用是获取哈希码(int
整数),也称为散列码。这个哈希码的作用是确定该对象在哈希表中的索引位置。散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)
4、为什么要有 hashCode?
hashcode()可以提高加快速度
hashCode
值相等,那这两个对象不一定相等(哈希碰撞)。hashCode
值相等并且equals()
方法也返回 true
,我们才认为这两个对象相等。hashCode
值不相等,我们就可以直接认为这两个对象不相等三、String
1、String、StringBuffer、StringBuilder 的区别?
#可变性
String
是不可变的。
StringBuilder
与 StringBuffer
都继承自 AbstractStringBuilder
类,在 AbstractStringBuilder
中也是使用字符数组保存字符串,不过没有使用 final
和 private
关键字修饰,最关键的是这个 AbstractStringBuilder
类还提供了很多修改字符串的方法比如 append
方法。
#线程安全性
String
中的对象是不可变的,也就可以理解为常量,线程安全。StringBuffer
对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder
并没有对方法进行加同步锁,所以是非线程安全的。
#性能
每次对 String
类型进行改变的时候,都会生成一个新的 String
对象,然后将指针指向新的 String
对象。StringBuffer
每次都会对 StringBuffer
对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder
相比使用 StringBuffer
仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
对于三者使用的总结:
(1)操作少量的数据: 适用 String
(2)单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder
(3)多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer
2、String为什么不可变?
final
修饰且为私有的,并且String
类没有提供/暴露修改这个字符串的方法。String
类被 final
修饰导致其不能被继承,进而避免了子类破坏 String
不可变。3、String#equals() 和 Object#equals() 有何区别?
String
中的 equals
方法是被重写过的,比较的是 String 字符串的值是否相等。 Object
的 equals
方法是比较的对象的内存地址。
4、字符串常量池的作用了解吗?
字符串常量池 是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
5、final的作用
被 final
关键字修饰的类不能被继承,修饰的方法不能被重写,修饰的变量是基本数据类型则值不能改变,修饰的变量是引用类型则不能再指向其他对象。
四、异常
1、Exception 和 Error 有什么区别?
在 Java 中,所有的异常都有一个共同的祖先 java.lang
包中的 Throwable
类。Throwable
类有两个重要的子类:
Exception
:程序本身可以处理的异常,可以通过 catch
来进行捕获。Exception
又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。Error
:Error
属于程序无法处理的错误 ,catch
来进行捕获catch
捕获 。例如 Java 虚拟机运行错误(Virtual MachineError
)、虚拟机内存不够错误(OutOfMemoryError
)、类定义错误(NoClassDefFoundError
)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。2、Checked Exception 和 Unchecked Exception 有什么区别?
Checked Exception 即 受检查异常 ,Java 代码在编译过程中,如果受检查异常没有被 catch
或者throws
关键字处理的话,就没办法通过编译。除了RuntimeException
及其子类以外,其他的Exception
类及其子类都属于受检查异常 。常见的受检查异常有:IO 相关的异常、ClassNotFoundException
、SQLException
...。
Unchecked Exception 即 不受检查异常 ,Java 代码在编译过程中 ,我们即使不处理不受检查异常也可以正常通过编译。
3、try-catch-finally 如何使用?
try
块:用于捕获异常。其后可接零个或多个 catch
块,如果没有 catch
块,则必须跟一个 finally
块。catch
块:用于处理 try 捕获到的异常。finally
块:无论是否捕获或处理异常,finally
块里的语句都会被执行。当在 try
块或 catch
块中遇到 return
语句时,finally
语句块将在方法返回之前被执行。注意:不要在 finally 语句块中使用 return! 当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句会被忽略。这是因为 try 语句中的 return 返回值会先被暂存在一个本地变量中,当执行到 finally 语句中的 return 之后,这个本地变量的值就变为了 finally 语句中的 return 返回值。
4、finally 中的代码一定会执行吗?
不一定的!在某些情况下,finally 中的代码不会被执行。就比如说 finally 之前虚拟机被终止运行的话,finally 中的代码就不会被执行。另外,在以下 2 种特殊情况下,finally
块的代码也不会被执行:(1)程序所在的线程死亡。(2)关闭 CPU。
五、泛型
1、什么是泛型?有什么作用?
Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。使用泛型参数,可以增强代码的可读性以及稳定性。
2、泛型的使用方式有哪几种?
泛型一般有三种使用方式:泛型类、泛型接口、泛型方法。
六、注解
Annotation
(注解) 是 Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量,提供某些信息供程序在编译或者运行时使用。
JDK 提供了很多内置的注解(比如 @Override
、@Deprecated
),同时,我们还可以自定义注解。
注解只有被解析之后才会生效,常见的解析方法有两种:
@Override
注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。@Value
、@Component
)都是通过反射来进行处理的。反射可以让我们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利。通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。
使用 Spring 的时候 ,一个@Component
注解就声明了一个类为 Spring Bean 呢?通过一个 @Value
注解就读取到配置文件中的值
七、序列化和反序列化
1、什么是序列化?什么是反序列化?
如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。
简单来说:
对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class)
下面是序列化和反序列化常见应用场景:
序列化的主要目的是通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。
2、序列化协议对应于 TCP/IP 4 层模型的哪一层?
网络通信的双方必须要采用和遵守相同的协议。TCP/IP 四层模型如下:
(1)应用层(2)传输层(3)网络层(4)网络接口层
OSI七层模型:(1)应用层(2)表示层(3)会话层(4)传输层(5)网络层(6)数据链路层(7)物理层
OSI 七层协议模型中的应用层、表示层和会话层对应的都是 TCP/IP 四层模型中的应用层,所以序列化协议属于 TCP/IP 协议应用层的一部分
3、如果有些字段不想进行序列化怎么办?
对于不想进行序列化的变量,使用 transient
关键字修饰。
transient
关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient
修饰的变量值不会被持久化和恢复。
关于 transient
还有几点注意:
transient
只能修饰变量,不能修饰类和方法。transient
修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰 int
类型,那么反序列后结果就是 0
。static
变量因为不属于任何对象(Object),所以无论有没有 transient
关键字修饰,均不会被序列化4、常见序列化协议有哪些?
JDK 自带的序列化方式一般不会用 ,因为序列化效率低并且存在安全问题。比较常用的序列化协议有 Hessian、Kryo、Protobuf、ProtoStuff,这些都是基于二进制的序列化协议。
像 JSON 和 XML 这种属于文本类序列化方式。虽然可读性比较好,但是性能较差,一般不会选择。
补充:html与xml的区别
XML (Extensible Markup Language) 和 HTML (Hypertext Markup Language) 都是用于创建结构化文档的标记语言。
1、XML用于传输和存储数据,侧重于数据;HTML用于显示数据并关注数据的外观。2、XML区分大小写;HTML不区分大小写。3、XML强制要求使用结束标记;而HTML中没有强制要求使用结束标记。4、XML保留空格;HTML不保留空格。
八、I/O
1、Java IO 流了解吗?
IO 即 Input/Output
,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。
Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。
InputStream
/Reader
: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。OutputStream
/Writer
: 所有输出流的基类,前者是字节输出流,后者是字符输出流2、I/O 流为什么要分为字节流和字符流呢?
3、I/O设计模式
装饰器(Decorator)模式 可以在不改变原有对象的情况下拓展其功能。可以对原始类嵌套使用多个装饰器。
对于字节流来说, FilterInputStream
(对应输入流)和FilterOutputStream
(对应输出流)是装饰器模式的核心,分别用于增强 InputStream
和OutputStream
子类对象的功能。
适配器(Adapter Pattern)模式 主要用于接口互不兼容的类的协调工作。
适配器分为对象适配器和类适配器。类适配器使用继承关系来实现,对象适配器使用组合关系来实现。
工厂模式用于创建对象,NIO 中大量用到了工厂模式
观察者模式:NIO 中的文件目录监听服务使用到了观察者模式。
NIO 中的文件目录监听服务基于 WatchService
接口和 Watchable
接口。WatchService
属于观察者,Watchable
属于被观察者。
九、语法糖
语法糖(Syntactic sugar) 代指的是编程语言为了方便程序员开发程序而设计的一种特殊语法,这种语法对编程语言的功能并没有影响。实现相同的功能,基于语法糖写出来的代码往往更简单简洁且更易阅读。
不过,JVM 其实并不能识别语法糖,Java 语法糖要想被正确执行,需要先通过编译器进行解糖
Java 中最常用的语法糖主要有泛型、自动拆装箱、变长参数、枚举、内部类、增强 for 循环、try-with-resources 语法、lambda 表达式等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。