Java基础面试系列(一)
MakerStack 人气:0
## Java基础面试总结(一)
### 1. 面向对象和面向过程的区别
| | 面向过程 | 面向对象 |
| ---------------------------- | ------------ | ------------------------------------------------------------ |
| 性能 | 高于面向对象 | 类加载的时候需要实例化,比较消耗资源 |
| 三易(易维护,易复用,易扩展) | 不如面向对象 | 具有封装,继承,多态的特性,可以设计低耦合的系统,有助于系统维护,扩展,复用 |
总结:
- 面向过程
- 优点:性能比面向对象高
- 缺点:易维护,易复用,易扩展性比较差
- 案例:`Unix/Linux`系统,单片机等等操作系统之类的
- 面向对象
- 优点:系统方便扩展,维护,复用
- 缺点:性能不如面向过程,类加载的时候需要实例化,比较消耗资源
- 案例:应用类型的系统。
### 2.JAVA语言的特点
- 简单易学
- 面向对象(封装,继承,多态)
- 平台无关性(通过Java虚拟机运行)
- 可靠性
- 安全性
- 支持多线程(C++没有内置的多线程机制,需要调用操作系统的多线程功能进行多线程程序设计)
- 支持网络编程(Java语言的诞生就是为了简化网络编程而设计)
- 编译和解释并存
### 3.什么是字节码?采用字节码的最大好处是什么?
#### 3.1 Java代码的执行流程
![](https://img2020.cnblogs.com/blog/1543450/202003/1543450-20200313084337497-722154851.png)
可以到`.java`文件通过`Java`编译器(`javac.exe`)编译成为`.class`文件。这个`.class`文件就是字节码文件,它是一种提供给`JVM`解释执行的文件。每一个平台的都相同,由于通过不同的`Java`解释器解释形成不同的机器码文件,使操作系统执行。
#### 3.2 采用字节码的最大好处
- 一定程度上解决了传统解释性语言执行效率低的问题
- 不需要重新进行编译就可以多平台运行
### 4. 什么是Java虚拟机
任何一种可以解释执行Java字节码文件的软件均可以看做虚拟机(JVM)
#### 4.1 Java虚拟机基本构成
> 任何一个JVM都包含:方法区,Java堆,Java栈,本地方法栈及其隐含寄存器
### 5. 什么是Java程序的主类?
一个程序中可以拥有多个类,但仅仅只能存在一个主类。在Java程序中,拥有`main`方法的类被称为主类。
### 6. 什么是JDK?什么是JRE
- `JDK`是指`Java`开发环境,内部包含`JRE`和`java`开发工具。如:`javac.exe`,`java.exe`,`jar.exe`
- `JRE`是指`Java`运行环境,可以通过`JRE`来运行Java程序
### 7. 环境变量Path和ClassPath的作用是什么?
- 可以通过`path`环境变量指定`JAVA_HOME/bin`来直接操作`Java`命令
- 可以通过`classpath`环境变量指定生成的`.class`的存放目录
### 8.字符型常量和字符串常量的区别
- 字符型常量对应一个`ASCII`码值,它仅仅占一个字符
- 字符串常量对应的是内存中的一个地址,他可以占用多个字符
### 9. Java语言采用何种编码方案?有何特点?
Java语言采用了`Unicode`编码标准,他为每一个字符定制了一个唯一的数值,因此可以在任意的平台使用
### 10. 构造器Constructor是否可以被Override
父类的私有属性和构造方法并不能被继承,所以`Constructor`不能被重写,但是可以被重载
### 11. 重载和重写的区别
重载:发生在同一个类中,方法名相同,方法参数的个数、顺序、类型不同或者方法返回值或访问修饰符不同的时候,就称为重载
重写:发生在不同的类中,且该类之间存在继承关系。当子类的方法名字,参数完全相同且其访问修饰符大于或者等于父类方法的访问修饰符的时候称为方法的重写
### 12. Java面向对象的三大特征和五大原则
#### 12.1三大特征
- 封装
- 将客观事物抽象成类。并且将自身属性和方法进行权限修饰,使其只能让其信任的类使用
- 继承
- 通过继承实现在不修改当前类的方法功能的情况下增强方法,有点类似于动态代理
- 多态
- 允许将父对象设置为任何其子对象,通过改变子对象来更改调用的方法
#### 12.1 五大原则
- 单一职责原则(`SRP`)
- 一个类只做一种工作
- 开放封闭原则(`OCP`)
- 对象对扩展开放(如同动态代理或者继承)
- 对象对修改封闭(不能直接修改其功能)
- 里氏替换原则(`LSP`)
- 在对象为T时一个等式成立,当S为T的子类的时候,这个等式依然成立
- 对父类的调用同样适用于子类
- 依赖倒置原则(`DIP`)
- 高层次的不依赖低层次的
- 即父类不依赖子类,而是子类依赖父类
- 接口隔离原则(ISP)
- 单一接口仅做单一功能类似于单一职责
### 13. Java语言的数据类型
#### 13.1 基本数据类型
- 整形
- `byte`一个字节
- `short`两个字节
- `int`四个字节
- `long`八个字节。表示为`1234654564651L`。后面通过`L`声明为一个long类型
- 浮点型
- `float` 四个字节。表示为`12.12345646f`。后面通过`f`声明为一个Float类型
- `double`八个字节
- 布尔类型
- `boolean`仅仅存在两个值`true`或者`false`
- 字符型
- `char`一个字节
#### 13.2 引用数据类型
- `class`类型
- 系统的类,自定义的类都属于类类型
- `String`也是一个类类型,成为字符串类型
- `enum`枚举类型
### 14. this和super
| | this | super |
| -------- | ------------------------------ | --------------------------------------------- |
| 作用 | 调用本类对象的方法或者属性 | 调用父类的`public`或者`protected`方法或者属性 |
| 方法 | this(参数)调用本类中的构造方法 | super(参数)调用父类的构造方法 |
| 内存表现 | 当前类的内存地址 | 可以理解为父类的内存地址 |
### 15. 静态和非静态的区别
| | static | no static |
| -------- | ---------------------------- | -------------------------------- |
| 调用方式 | 类名调用 | 对象调用 |
| 内存表现 | 存在于方法区的静态区 | 堆中 |
| 生命周期 | 类消亡的时候消亡 | 对象消亡的时候消亡 |
| 线程安全 | 共享数据,所以会存在并发问题 | 仅仅针对一个对象,所以无并发问题 |
### 16.抽象类和接口的区别
#### 16.1 抽象类
> 为什么要有抽象类?
>
> Java将一些特性抽取形成一个抽象的模型,但是这个模型不能被实例化,因为他没有任何具体的特征,只能作为一个参考模板。它可以通过被继承获得其内部的所有的属性和方法
抽象类特点:
- 被`abstract`关键字修饰
- 有构造方法,属于类的范畴
- 内部可以存在抽象方法也可以不存在抽象方法
- 方法和成员能被`static`修饰
- 类不能被`final`修饰,因为其本身不能实例化,作用仅仅是为了让子类重写,而final作用在类上就不能继承了
- 不能被`private`修饰,修饰以后子类无法重写
- 抽象方法没有方法体
#### 16.2 接口
> 接口,相当于一个标准,只有实现了这个标准才可以做具体的事情,比如JDBC,JDK提供了一套连接数据库的接口,各大数据库厂商实现这些接口,来让Java连接他们的数据库。
接口的特点:
- 被`interface`关键字修饰
- 成员变量默认被`public static final`修饰
- 成员方法默认被`public abstract`修饰
- `JDK1.8`出现了`defalut`方法可以拥有方法体
- 支持多实现
接口的作用
- 有利于代码的规范。符合接口分离原则
- 降低程序之间的耦合。
- 将若干功能拆分,使类和接口之间按照规范进行实现和依赖。依赖倒置 原则
#### 16.3 区别
| | 抽象类 | 接口 |
| ---------------- | ------------------------------ | ------------------------------- |
| 关键字修饰 | abstract | interface |
| 是否可以被实例化 | 不可以 | 不可以 |
| 构造方法 | 存在构造方法 | 不存在构造方法 |
| 成员变量默认修饰 | 无默认修饰 | 默认被`public static final`修饰 |
| 方法 | 可以存在抽象也可存在非抽象方法 | 均为抽象方法或者默认方法 |
| 继承或实现 | 单继承 | 多实现(弥补多继承) |
| 本质 | is a 关系。从属关系 | like a 关系。强调功能 |
### 17. 在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
帮助子类做初始化工作
### 18. 一个类的构造方法的作用是什么?若一个类没有声明构造方法,该程序可以正确的执行吗?
构造方法的作用是完成类的初始化工作,没有生命也可以执行,因为类默认存在构造方法
### 19. 成员变量和局部变量的区别?
| | 成员变量 | 局部变量 |
| -------- | ------------------ | ------------ |
| 内存 | 跟随对象存放于堆中 | 存放于栈中 |
| 生命周期 | 跟随对象 | 跟随方法 |
| 初始化 | 会初始化 | 不会被初始化 |
### 20. 多态实现的机制
Java中存在两种多态机制
- 编译时多态
- 主要是方法的重载
- 运行时多态
- 动态绑定,在执行期间判断引用对象的实际类型,根据类型调用不同的属性或者方法
> JVM在运行时默认是绑定在父类的引用上的,只有在遇到非静态方法的时候才会动态绑定到子类的引用上,当执行完子类的非静态方法以后又回到父类的引用上,知道下次遇到非静态方法
### 21. Java类中各成员的加载和内存的存放位置
#### 21.1 什么时候加载类
- 创建对象
- 使用类中的静态成员
- 执行Java字节码文件
#### 21.2 类所有内容加载顺序和内存中的存放位置
> 假设一个场景:Person person = new Person()
>
> 分析其内存的实际操作
- 在`Java`栈中加载`main`函数,建立`main`函数的变量`p`
- 加载类文件。`new`对象的时候需要`person.class`文件,所以需要加载类`Person`
- 加载类文件的时候,除了非静态成员变量不会被加载,其他的属性和方法均会被加载
- 类加载以后各个成员的存放位置
- 静态成员属性和方法。存放于方法区的静态区
- 非静态方法。存放于方法区的非静态区
- 静态代码块和构造代码块存放于静态区
> 这里有一个问题:为什么会将非静态方法也放置于方法区,而不是跟随对象生存。
>
> > 非静态方法只有对象才可以调用,如果让类中的所有的静态方法都随着对象创建一次,非常占据系统资源。所以采用了让所有的对象共享这些方法,通过this关键字执行调用非静态方法的对象。
- 执行静态代码块
- 开辟空间。在堆内存中创建空间,分配内存地址
- 默认初始化。对`Person`的成员属性进行默认初始化赋值
- 显示初始化。对`Person`的成员属性进行赋值
- 构造代码块执行
- 将内存地址赋值给`p`变量
-
加载全部内容