Java基础(面试复习整理)
基础知识和语法
Java语言初识
-
计算机语言发展
- 机器语言、汇编、C、C++、Java
-
Java的诞生与发展
-
1995
-
JavaSE
-
JavaME
- Android
-
JavaEE
-
-
2006(大数据)
-
Hadoop
-
Spark
- 流式计算
-
Scala
-
-
-
JDK
-
开发工具包
-
配置环境变量
-
JAVA_HOME
- D:\JDK8_211
-
path
- ;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
-
CLASSPATH
- .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
-
验证安装DOS
- java -version
-
-
-
-
JRE
- Java程序运行环境
- 包含JVM,Java程序运行
-
跨平台原理
- 在JVM上运行,无视操作系统
HelloWorld
-
javac Hello.java
- 生成class文件
-
java Hello
- 运行编译好的class文件
-
编译型和解释型语言
- Java是半编译半解释型语言
-
IDEA
- 主流开发工具
注释
-
行内
- //
-
多行
- /* */
-
文档
-
/** */
- javadoc 命令 生成帮助文档
-
标识符
-
关键字
-
语法规则
-
大小写敏感
-
类名首字母大写
-
方法名小写
-
源文件名与类名必须相同,后缀名为.java
-
一个源文件只能有一个public类,可以有多个其他类(内部类、匿名类)
-
所有程序由主方法入口开始执行
- public static void main(String[] args)
-
标识符
- 以字母、美元符、下划线开头,不能用数字开头
- 关键字不能做标识符
-
数据类型
-
基本数据类型
-
整型
-
byte
- Byte
- 8位,1字节
- -128(-2^7) ~ 127(2^7-1)
-
short
- Short
- 16位,2字节
- -32768(-2^15) ~ 32767(2^15-1)
-
int
- Integer
- 32位,4字节
- -2^31 ~ 2^31-1
- 整型变量默认为int型
-
long
- Long
- 64位,8字节
- -2^63 ~ 2^63
- 默认值:0L
-
-
浮点型
-
float
- Float
- 32位,4字节
- 默认值:0.0f
-
double
- Double
- 64位,8字节
-
浮点数
-
金融计算
- BigDecimal
-
-
-
字符型
-
char(Unicode字符)
- Character
- 16位,2字节
- 单引号,‘A’
-
字符编码
-
ASCII
-
UTF-8
-
Unicode
-
'\u0000'(转义)
-
\b
- 退格
-
\n
- 换行
-
\r
- 回车
-
\t
- 制表
-
'
-
"
-
\
-
-
-
-
布尔型
-
boolean
- Boolean
- 1字节
- true/false
- 默认值:false
-
-
-
引用数据类型
-
数组
- int[] a = {1,2,3,4};
-
类(对象)
-
class Hero;
-
栈指向堆
- 栈存放对象引用的地址
- 堆存放对象的信息,栈存放该对象的地址,所以栈指向堆
-
-
接口
- interface Hero;
-
默认值:null
-
-
== 和 equals
-
==
- 基本类型:比较的是值是否相同
- 引用类型:比较的是引用是否相同
-
equals
- equals 本质上就是 ==,但重写了String和Integer,把引用比较改成了值比较
-
-
数据类型转换
-
自动类型转换
- 转换原则:从低精度向高精度转换byte->(short、char)->int->long->float->double
- 表数范围小的自动转换为表数范围大的
- 运算有多种数据类型结果自动转换为最大的数据类型
- 字符串与任何数据类型相连都会转换为字符串类型
- 两个char型运算时,自动转换为int型;
当char与别的类型运算时,也会先自动转换为int型的,再做其它类型的自动转换 - byte和short不能和char相互转换,char值范围为0~65535,byte和short都包含负数
-
强制类型转换
-
表数大的转表数小的需要强制转换
-
运算符为(),括号里写小的数据类型
- byte b = (byte)12
-
-
-
装箱和拆箱
- 装箱:int->Integer
- 拆箱:Integer->int
-
Java包装类的缓存
-
具体的实现方式为在类中预先创建频繁使用的包装类对象,当需要使用某个包装类的对象
时,如果该对象封装的值在缓存的范围内,就返回缓存的对象,否则创建新的对象并返回 -
哪些包装类没有缓存
- float、double
-
常量
-
定义
-
final修饰常量
-
一般大写命名
- final String DEMO = "HELLO";
-
-
final
-
只允许初始化一次
-
一般与static一起使用
- 静态不可变
-
变量
-
定义
- int a = 2;
-
作用域
-
类变量
- 静态变量
- 必须声明为static类型
- 局部变量不能被声明为类变量
-
实例(成员)变量
- 非静态变量
- 类之中,方法外,可全局使用
-
局部变量
- 方法内,仅限于方法内使用
-
命名规范
- 1、见名知意
- 2、驼峰命名(变量和方法)
- 3、类,首字母大写,驼峰命名
- 4、常量,大写+下划线
- 5、不要使用拼音命令
运算符
-
算术运算符
- +、-、*、/、%、++、--
-
赋值运算符
- =
-
关系运算符
- '>'、<、>=、<=
-
逻辑运算符
- &&、||、!
-
位运算符
- &、|、^、~、>>、<<、>>>
-
扩展运算符
- +=、-=、*=、/=
-
三目运算符
- 条件?true的取值:false的取值
-
优先级
- 尽量使用 小括号,可读性更好
-
instanceof
- 检查当前对象是否是某个特定类型
包机制
- 域名倒写
- package
- import
- 为了防治命名冲突
- 用于放功能相似或相关类
JavaDoc
-
生成JDK帮助文档
-
javadoc
-
@author
- 作者
-
@Version
- 版本
-
@since
- 最早支持到哪个版本能够使用
-
@param
- 参数
-
@return
- 返回
-
@throws
- 异常
-
编译文件、生成帮助文档
-
流程控制
-
Scanner
- 用户交互 System.in
-
顺序结构
- 程序默认结构,自上而下的执行
-
选择结构
-
if 单选择结构
-
if-else 双选择结构
-
if-else if-else 多选择结构
-
switch
-
JDK7支持了String类型
-
case穿透现象,不加break 就会继续执行下一个case
-
break
-
default
- 默认,case没有就执行这个
-
-
-
循环结构
-
while
- 满足条件后执行
- 尽量避免死循环
- 一般不可计次数循环时使用
-
do...while
- 至少执行一次,先执行
-
for
- for(int i = 0; i < 100; i++)
- 一般可计次数循环时使用
-
for-each
- for(int num : nums)
- 增强型for循环
-
编程:打印九九乘法表
-
-
break & continue & return
-
break
- 跳出循环
-
continue
- 终止本次循环,进入下一次循环
-
return
- 结束方法的运行
-
数组
-
定义
-
new int[5]
- 分配好空间
-
数组存放的值必须是同一个类型
-
存储在堆上的对象,可保存多个同类型变量
-
数组初始化,内存所占空间固定,长度不可改变
-
静态初始化
- int demoArray[3] = {1,2,3};
-
动态初始化
- int demoArray[10];
-
-
-
使用
-
通过下标拿到值
-
ArrayIndexOutOfBounds
- 数组下标越界异常
-
for-each遍历
-
遍历
-
数组索引从0开始
-
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i] + " ");
} -
for each循环
- for (double element: myList) {
System.out.println(element);
}
- for (double element: myList) {
-
-
-
二维数组
- int[][]
-
Arrays
-
工具类
-
方法
-
排序
-
sort()
-
sort排序原理
- 使用了两种排序方法,快速排序和优化的归并排序
- 快速排序主要是对那些基本类型数据排序,
而归并排序用于对Object类型进行排序。
-
-
比较
- equals()
-
转为字符串
- toString()
-
-
-
排序算法
- 冒泡排序
- 选择排序
- 插入排序
- 快速排序
- 归并排序
- 希尔排序
- 堆排序
- 基数排序(桶排序)
- 笔试:要求手写
面向对象
什么是面向对象
- 一个人就是一个对象,属性:名字,方法:动作
类与对象
-
类
- 是Java最小的程序单元
- 是一个模板,描述对象的状态和行为
- 是对象的集合
- 由class定义
-
对象
-
Java中除了8个基本数据类型值外,一切都是对象
-
声明
- 由类声明
-
实例化
- new创建对象实例化
-
初始化
- 创建对象时调用构造方法进行初始化
-
属性
- 对象的状态
-
方法
- 对象的行为操作
-
new 对象
- 栈 存放引用
- 堆 存放具体对象信息
构造方法
-
构造的重载
- 默认无参构造
- 如果手动定义了有参构造就必须要手动再加一个无参构造
- 单例模式需要构造器私有,为的就是不让别人去new它,只能创建一个对象
-
new需要构造方法来创建对象
-
与类同名,无返回值无void,可以有参数,只能与new结合使用,返回的是类的实例
-
如果不显式定义构造方法,编译器会为该类隐式提供默认的构造方法
-
每个类至少一个构造方法(可以有多个),方法名与类名必须相同
方法
-
语句的集合
-
定义
-
修饰符 返回值 方法名(参数名) {
return 返回值;
}
-
-
方法调用
- 类名.方法
- 对象.方法
-
方法重载
- 名字相同,参数列表不同
-
命令行传参
- 给main方法传参
- 教程:https://www.bilibili.com/video/BV12J41137hu?p=80
- 45:22
- 必须掌握,后面JVM调优传参就是这样传,在后面传JVM参数
-
可变长参数
- ...
- 必须放在最后一个参数
-
递归
-
自己调用自己,给自己一个出口
-
时间复杂度高
-
面试常问
-
刷leetcode
- 基础题
-
-
封装
- 属性私有,提供对应get,set 方法
- 减少耦合
- 隐藏实现细节
- 容易理解
继承
-
关键字
-
extends
-
super
-
访问父类成员
- super.eat();
-
-
this
-
访问自己
- this.eat();
-
-
-
子类继承父类,继承包括非private修饰的成员变量,方法
-
减少重复代码,提高代码复用性,提高维护性
-
不支持多继承,但支持多重继承、不同类继承同一个类
-
变相多继承 implements
- 可以实现多个接口
多态
-
父类的引用指向子类的对象
-
Person person = new Student();
- 引用 person 指向 Student 对象
-
-
instanceof
- 如匹配,可以进行类型之间转换
- 返回:true / false
-
同一个行为具有多个不同的表现形式
-
例子:同一个接口,使用不同实例执行不同的操作
-
存在的必要条件
- 继承
- 重写
- 父类引用指向子类对象
-
实现
- 重写
- 接口
- 抽象类
-
编译时多态通过方法重载
-
重载只能通过不同的方法参数区分
- 参数个数不同
- 参数类型不同
-
通过指向父类的指针,来调用在不同子类中实现的方法
-
-
运行时多态通过方法重写
-
多态用到了动态绑定
- 编译时类型与运行时类型不一致就会发生运行时动态绑定(典型的就是重载)
Override、Overload
-
重载
- 一个类中,两个方法同名,但形参不同(数量,类型不同),返回值可同可不同
-
重写
- 方法名,形参和返回值必须相同
- 子类可以根据自己的需要实现父类的方法
向上转型与向下转型
-
向上转型:是子类对象由父类引用,格式:parent p = new son
-
向下转型:是父类向下强制转换到子类对象,前提是该父类对象必须是经过向上转型的对象
- 对进行过上转型的对象,进行强制下转型
Son s = (Son)p;
- 对进行过上转型的对象,进行强制下转型
修饰符
-
访问修饰符
-
private
- 同一个类内
-
defalt
- 同一个包内
-
protected
- 同一个包内和所有子类
-
public
- 所有类
-
-
非访问修饰符
-
static
- 用来修饰类方法和类变量
- 静态方法只能用静态变量(static修饰的)
-
final
-
final通常和static一起使用
-
修饰的类
- 不能被继承
-
修饰的方法
- 不能被重写
-
修饰的变量
- 不能被修改
-
-
abstract
- 唯一目的:将来对类进行扩充
- 用来创建抽象类和抽象方法
- 类有抽象方法一定要声明为抽象类(抽象类可以没有抽象方法)
-
synchronized 和 volatile
- 主要用于多线程编程
- synchronized修饰的方法只能同一时间只能被一个线程访问
- volatile
-
接口
-
interface
-
约束,只能定义方法名
-
子类实现接口必须重写其中方法
-
只有一个方法的接口叫做函数式接口,可以使用lambda表达式简化
-
抽象类
- 接口比抽象类更抽象,接口不能有实现
- 抽象类可以有具体的实现
-
一个类可以实现多个接口
抽象类
-
abstract
- 用来创建抽象类和抽象方法
-
唯一目的:将来对类进行扩充
-
不能被实例化,必须被继承才能使用,通常在设计阶段决定是否使用
-
类有抽象方法一定要声明为抽象类(抽象类可以没有抽象方法)
-
子类继承抽象类,父类有抽象方法子类必须重写抽象方法
抽象类和接口区别
- 一个类只可以继承一个抽象类,但可以实现多个接口
- 抽象类可以有构造方法,接口中不能有构造方法
- 抽象类可以有普通的成员变量,接口中不能有普通的成员变量
- 抽象类中可以包含静态方法,接口中不能包含静态方法
内部类
-
定义
- 将一个类定义在另一个类或方法中
-
分类
-
成员内部类
- 定义在一个类中
-
局部内部类
- 定义在一个方法或作用域中
-
匿名内部类
- 使用最多
- 主要编写事件监听代码
- lambda
-
静态内部类
- 定义在一个类中,static修饰
-
-
深入
- 编译器编译成多个class文件
克隆
-
浅克隆
- 浅克隆不会克隆原对象中的引用类型,仅仅拷贝了引用类型的指向
-
深克隆
- 深克隆的实现就是在引用类型所在的类实现Cloneable接口,
并使用public访问修饰符重写clone方法。
- 深克隆的实现就是在引用类型所在的类实现Cloneable接口,
序列化
- 对象中被 static 或 transient 修饰的变量,在序列化时不被保存
Enum类
-
为什么构造函数必须是私有的
- 为了保证每一个枚举类元素的唯一实例,是不会允许外部进行new的
常用API
Scanner
- 键盘输入
Random
- 生成随机数
Arrays
-
数组工具类
- 排序
- 查找
String
-
不可变性
-
final修饰
-
方法
-
构造方法
-
String(char[])
-
String(byte[],Charset)
- 字节流,编码
-
String(StringBuffer)
- 将StringBuffer转换为String
-
String(StringBuilder)
- 将StringBuilder转换为String
-
-
length()
- 长度
-
isEmpty()
- 判空
-
charAt(int index)
- 获取指定字符串
-
getBytes(String charsetName)
- String变成字节数组
-
indexOf(int ch)
- 获取指定下标
-
subString(int beginIndex)
- 截取字符串
-
concat(String str)
- 包含某个字符串
-
replace(char oldChar, char newChar)
- 替换字符串
-
replaceAll(String, String)
- 替换全部
-
split(String, int)
- 字符串分割成数组
- 常用
-
trim()
- 去掉字符串两边空格
-
StringBuilder、StringBuffer类
-
StringBuffer是线程安全的(速度慢,需要同步)
-
StringBuilder不是线程安全的(没有被synchronized(同步)修饰)
-
StringBuffer
-
可变长
-
原因:append()
- 本质:拷贝成新的再返回,还是利用的String
-
-
线程安全
-
synchronized修饰
- 效率较低
-
多线程使用
-
-
-
StringBuilder
-
可变长
-
原因:append()
- 本质:拷贝成新的再返回,还是利用的String
-
-
单线程下
-
字符串缓存区大,数据量大使用
-
数据小使用String
- 操作量较少
-
-
非线程安全
-
但效率高
- 原因:不用同步
-
-
ArrayList
-
数组列表
-
长度可变
-
类型统一
-
一般和泛型使用
- ArrayList
list = ArrayList<>();
- ArrayList
-
Math
- 数学相关工具类
Date类
-
时间日期类
-
当前日期时间
- date.toString
-
格式化日期
- SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
正则表达式
-
用字符串描述的匹配规则
-
判断年份是否是'20##' ,通过 String x = "20\d\d"; 判断
- \d,表示0~9的数
-
-
一般用于数据校验
Object
-
hashcode()
-
toString()
-
clone()
-
getClass()
-
notify()
- 通知,多线程使用
-
wait()
-
equals()
File
- 创建文件
- 查看文件
- 修改文件
- 删除文件
包装类
- 自动装箱与拆箱
- 八大基本类型不是类,不是面向对象,需要封装成类
异常处理
总接口
-
Throwable
-
Exception
-
捕获不到需要提升到Throwable,不能捕获Error
-
自定义异常
- 继承或实现Exception 接口
-
运行时异常
-
1/0
-
ClassNotFound
-
NullPoint
- 空指针
-
UnKnowType
- 未知类型
-
下标越界异常
-
文件类型异常.......
-
编译会通过,需要手动捕获处理,注意
-
出现这类异常的时候程序会由虚拟机接管
-
-
检查型异常
- 一般不管,因为编译不会通过
-
-
Error
-
AWT 错误
-
JVM 错误
-
StackOverFlow
- 栈溢出
- 递归会导致错误
-
OutOfMemory
- OOM
- Java内存溢出
- 一个数字太大,不断创建对象,内存占用满了会导致错误
-
面试常问
-
-
-
处理
-
try{}
- 尝试运行
-
catch () {}
- 捕获
- 先捕获小异常再捕获大异常
-
finally()
- 无论是否出现异常,finally中的代码都会被执行
-
throw
- 方法内部,手动抛出异常
-
throws
- 方法抛出异常