面向对象
三大支柱
继承
私有方法
子类访问权限
字段
super②
重写的两个限制
存在两个类,B 继承 A,C 继承 B,我们能将 B 转换为 C 么? 如 C = (C) B;
this() & super()在构造方法中的区别⑤
调用super()必须写在子类构造方法的第一行, 否则编译不通过
super从子类调用父类构造, this在同一类中调用其他构造均需要放在第一行
尽管可以用this调用一个构造器, 却不能调用2个
this和super不能出现在同一个构造器中, 否则编译不通过
this()、super()都指的对象,不可以在static环境中使用
本质this指向本对象的指针。super是一个关键字
- 多态
- 封装
访问修饰符
抽象类
如何实例化
抽象类和最终类② ``` 抽象类可以没有抽象方法, 最终类可以没有最终方法
最终类不能被继承, 最终方法不能被重写(可以重载)
<a name="54ea89b4"></a>
## 接口
-
什么是接口java8之前,java8+
-
成员默认
<br /> public
-
字段默认
<br /> public static final
-
具体类是否需要实现所有接口,抽象类呢?
-
Java 中,Serializable 与 Externalizable 的区别?
Serializable 接口是一个序列化 Java 类的接口,以便于它们可以在网络上传输或者可以将它们的状态保存在磁盘上,是 JVM 内嵌的默认序列化方式,成本高、脆弱而且不安全。Externalizable 允许你控制整个序列化过程,指定特定的二进制格式,增加安全机制。
-
接口与抽象类④
一个子类只能继承一个抽象类,但能实现多个接口 抽象类可以有构造方法,接口没有构造方法 抽象类普通变量,静态变量(无限制),接口静态变量(public static final) 抽象类可以有普通方法(public、protected),静态方法(public、protected),接口只有抽象方法(public abstract)
<a name="94e0e403"></a>
## 内部类
-
静态内部类与顶级类有什么区别?
-
构造内部类和静态内部类③
静态内部类不需要有指向外部类的引用。但非静态内部类需要持有对外部类的引用 非静态内部类能够访问外部类的静态和非静态成员 静态内部类不能访问外部类的非静态成员,只能访问外部类的静态成员
<a name="185f7bf6"></a>
# 数据类型
<a name="5d961e79"></a>
## 基本类型
- 包装类型
- new Integer(123) 与 Integer.valueOf(123) 的区别
- 装箱时使用什么方法
- float和double赋值时
- Java 中应该使用什么数据类型来代表价格?
- 怎么将 byte 转换为 String?
- Java 中怎样将 bytes 转换为 long 类型?
- 我们能将 int 强制转换为 byte 类型的变量吗? 如果该值大于 byte 类型的范围,将会出现什么现象?
- 3*0.1 == 0.3 将会返回什么? true 还是 false?
- int 和 Integer 哪个会占用更多的内存?
<a name="99b90c80"></a>
## 枚举类型
- 枚举类
<a name="7df6e743"></a>
## 引用类型
<a name="cc4dd1da"></a>
# 字符串
<a name="String"></a>
## String
-
String为什么 不可变?
-
不可变的好处④
1.可以缓存 hash 值
-
三者比较:可变性,线程安全.
-
String.intern()
- String Pool位置
<a name="12984634"></a>
## 可被修改的字符串
- StringBuffer
- 使用什么同步
- StringBuilder
<a name="ea340b9d"></a>
## 方法
<a name="cf4b077b"></a>
# 流程控制
<a name="037bdbce"></a>
## 循环结构
<a name="d3e31548"></a>
## 分支结构
- switch判断语句支持什么,不支持什么
<a name="4ebeccc3"></a>
## 顺序结构
<a name="ea340b9d-1"></a>
# 方法
<a name="e3127cc1"></a>
## 格式
[] [] 返回值 方法名(参数类型 参数)
<a name="86dad07e"></a>
## 方法调用
<a name="09942702"></a>
## 递归
<a name="e503df6e"></a>
## Object通用方法
-
Object有哪些公用方法?
-
equals()
-
hasCode()
-
toString()
-
clone()
- 深浅拷贝
-
clone() 的替代方案
-
<a name="c4dd9766"></a>
# 基本语法
<a name="cfb5f18c"></a>
## 关键字
- final
- 数据
- 对引用类型
- 对基本类型
- 方法 private
- 类
- static
-
静态变量
-
静态方法
- 不能使用什么关键字.
-
静态语句块
- 什么时候执行执行几次
-
静态内部类
- 怎样创建实例
- 非静态内部类怎么创建实例.
-
静态导包
-
初始化顺序⑥
父类(静态变量、静态语句块) 子类(静态变量、静态语句块) 父类(实例变量、普通语句块) 父类(构造函数) 子类(实例变量、普通语句块) 子类(构造函数)
-
- finally④
<a name="f3c00c7e"></a>
## 标识符
<a name="9cdd4a78"></a>
## 运算符
- Java 中 ++ 操作符是线程安全的吗?
- Java移位运算符③
<a name="a53afead"></a>
## 字面量
<a name="894b94fb"></a>
## 分隔符
<a name="ddc7d28b"></a>
## 变量
- 局部变量为什么要初始化④
<a name="5710acf9"></a>
# 类加载和反射
<a name="e75d0e53"></a>
## 反射
- 是什么?
- 反射包中常用类
- Class 类重要方法.
- Constructor类及其用法(用什么调用,私有方法设置什么)
- Field类及其用法(哪种带继承,赋值,获取,final修饰)
- Method类及其用法(如何执行,返回值要干什么)
<a name="f14946d7"></a>
## 类加载
- 过程
- 加载③
- 验证①
- 准备③
- 基本数据类型static变量,全局变量和局部变量
- 常量static+final修饰,只有final修饰
- 引用数据类型默认赋值
- 数组
- ConstantValue
- 解析
- 初始化
- 变量赋值②
- 步骤③
- 类加载器
- 三种方式(区别)
- JVM类加载机制④
<a name="76b09825"></a>
## class对象
- class对象⑤
- 类加载相当于
- 类加载的方法①,返回值是什么
- 获取class对象的方法③
- 数组
- 基本类型+
- class标识的类
- Class类只存
<a name="799e53a9"></a>
## 类字节码
- 计算机运行java代码
- class文件伪结构②
- java字节码文件包含哪些类型的数据⑦
- JVM什么时候动态链接
<a name="c195df63"></a>
# 异常
- 父类不声明异常,子类
- 捕获什么异常,传递什么异常.
- try-catch(符号)③
- finally遇见如下情况不会执行④
- try-with-resource
- 优先捕获,不要捕获
- 异常表
- 异常表用在什么时候(加了finally之后呢)
- 异常是否耗时?为什么会耗时?
- Return 和finally的问题
<a name="Object"></a>
## Object
<a name="Throwable"></a>
### Throwable
<a name="Error"></a>
#### Error
<a name="Exception"></a>
#### Exception
- 受检查异常②
- 运行时异常③
<a name="cec78a4f"></a>
# 泛型/容器(集合框架)
<a name="8045759e"></a>
## 泛型
-
Java中的泛型是什么 ? 使用泛型的好处是什么?②
-
Java的泛型是如何工作的 ? 什么是类型擦除 ?
-
什么是泛型中的限定通配符和非限定通配符 ?(泛型的上下限),符号
-
如何编写一个泛型方法,让它能接受泛型参数并返回泛型类型?
-
你可以把List传递给一个接受List
-
Array中可以用泛型吗?
-
类型擦除原则④
消除类型参数声明,即删除<>及其包围的部分。 根据类型参数的上下界推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下界限定则替换为Object,如果存在上下界限定则根据子类替换原则取类型参数的最左边限定类型(即父类)。 为了保证类型安全,必要时插入强制类型转换代码。 自动产生“桥接方法”以保证擦除类型后的代码仍然具有泛型的“多态性”。
-
如何证明类型的擦除呢?通过反射添加其它类型元素
-
如何理解类型擦除后保留的原始类型
-
区分原始类型和泛型变量的类型
-
调用泛型方法时,可以指定泛型,也可以不指定泛型
-
如何理解泛型的编译期检查,这个类型检查是针对谁的呢
ArrayList<String> list1 = new ArrayList();
list1.add("1"); //编译通过
list1.add(1); //编译错误
String str1 = list1.get(0); //返回类型就是String
ArrayList list2 = new ArrayList<String>();
list2.add("1"); //编译通过
list2.add(1); //编译通过
Object object = list2.get(0); //返回类型就是Object
-
如何理解泛型的多态?泛型的桥接方法
-
如何理解基本类型不能作为泛型类型?③
-
如何理解泛型类型不能实例化?需要实例化一个泛型,应该如何做呢?
-
泛型数组:如何正确的初始化泛型数组实例?
-
如何理解泛型类中的静态方法和静态变量?(泛型方法)
-
如何异常中使用泛型③
Problem
<a name="6551862e"></a>
### 泛型类
- 格式②
<a name="a550aecf"></a>
### 泛型接口
- 接口格式
- 实现类格式
<a name="dcab57b7"></a>
### 泛型方法
- 格式
<a name="92ec403b"></a>
### 泛型数组
-
使用
比如ArrayList
<a name="Collection"></a>
## Collection
![](https://s3.bmp.ovh/imgs/2021/10/e491ced38dd622f3.png#alt=)
<a name="Collection-1"></a>
### Collection
<a name="List"></a>
#### List
-
LinkedList
-
基于什么实现,只能怎样,还可以用作
-
同时实现了
List接口和Deque接口
-
关于栈或队列,现在的首选是,次选
-
图示,当链表为空的时候`first`和`last`
-
如果需要多个线程并发访问,可以先采用什么方法对其进行包装
-
构造函数②
-
getFirst(), getLast()
返回值
-
LinkedList可存放
-
removeFirst(), removeLast(), remove(e), remove(index)
null值 unlink() 第一个元素 最后一个元素
public E remove(int index) { checkElementIndex(index); return unlink(node(index)); }
-
addAll()②
addAll(c) addAll(index, c) 1.检查索引 2.Object[] a = c.toArray(); 3.pred, succ(考虑addAll(c)) 4.遍历添加 5.连接succ和前边(考虑addAll(c))
-
add()
-
node(int index)
-
clear()
-
index()
-
get(int index) ,set(int index, E element)
-
add(int index, E element)
linkLast(element) linkBefore(element, node(index))
-
indexOf(),lastIndexOf
null元素
-
remove(int index)
unlink(node(index))
-
Queue 方法
-
peek()
-
element()
-
poll()
unlinkFirst(f)
-
remove()
removeFirst()
-
offer(E e)
-
add(e)
-
Deque 方法
-
offerFirst(E e)
addFirst(e)
-
offerLast(E e)
addLast(e)
-
peekFirst()
-
peekLast()
-
pollFirst()
unlinkFirst(f)
-
pollLast()
unlinkLast(l)
-
push(E e)
addFirst(e)
-
pop()
removeFirst()
-
removeFirstOccurrence(Object o)
remove(o)
-
removeLastOccurrence(Object o)
null元素
-
Vector
- 和什么类似,但
-
ArrayList
-
基于什么实现,支持什么操作
-
允许放入
-
构造方法③
public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }
-
自动扩容
和minExpand比较并扩容
ensureCapacity(int minCapacity)
确定扩容大小并扩容
ensureCapacityInternal(int minCapacity)
if (minCapacity - elementData.length > 0)
grow(minCapacity);
ensureExplicitCapacity(int minCapacity)
grow(int minCapacity) hugeCapacity(int minCapacity)
-
add(E e) 方法
-
add(int index, E element) 方法里用了什么方法
System.arraycopy(elementData, index, elementData, index + 1, size - index);
-
addAll(Collection<? extends E> c)
-
addAll(int index, Collection<? extends E> c)
int numMoved = size - index;
-
get方法,类型
-
set方法返回值
-
contains方法,使用了什么函数,可以判空吗?
直接调用了 indexOf 方法,若返回小于 0 则返回 false
-
根据索引remove方法,返回值,用什么方法移动元素,最后一个元素怎么操作
int numMoved = size - index - 1;
-
根据对象remove
null元素
-
clear方法③
modCount自增,当前数组长度内的所有元素赋为 null,并把 size 置 0
-
subList(int fromIndex, int toIndex)
返回当前list的部分视图
-
trimToSize方法,去除什么(包括),用什么方法
Arrays.copyOf
-
iterator方法,默认包含
默认含有外部的this指针,所以这个内部类可以调用到外部类的属性
-
Iterator 的 next方法,先检查
modCount
-
indexOf(), lastIndexOf()
null元素
<a name="Set"></a>
#### Set
- TreeSet
- 基于什么实现,支持什么操作,HashSet 查找的时间复杂度,TreeSet呢
- HashSet
- 基于什么实现,支持什么操作
- LinkedHashSet
- 具有什么的查找效率,且内部使用什么维护元素的插入顺序
<a name="Queue"></a>
#### Queue
-
LinkedList
- 用什么来实现
-
PriorityQueue
-
基于什么实现,可以用它来实现
基于堆结构实现
-
大根堆还是小根堆
-
不允许
-
底层实现,逻辑结构
-
父子节点联系
-
peek()和element
判空
-
add(), offer()
1.判空 2.扩容 3.插入(判断是否第一个,使用siftUp(i, e))
-
无参数的remove()以及poll()方法
1.判空 2.获取最后一个元素 3.替换第一个元素,调整
-
Deque
- 继承自
- offerFirst(E e)
- addFirst(e)
- offerLast(E e)
- addLast(e)
- peekFirst()
- getFirst()
- peekLast()
- getLast()
- pollFirst()
- removeFirst()
- pollLast()
- removeLast()
- push()
- pop()
- removeLastOccurrence(Object o)
- removeFirstOccurrence(Object o) ```
- LinkedList
ArrayDeque
底层通过什么实现
线程安全吗
不允许放入
图示
addFirst()
doubleCapacity()
addLast()
pollFirst()
head = (head + 1) & (elements.length - 1);//下标越界处理
-
pollLast()
-
peekFirst()
-
peekLast()
Stack
push(e)
pop()
peek()
数据结构
Queue 方法
- peek()
- element()
- poll()
- remove()
- offer(E e)
- add(e)
Deque 方法
Stack
Map
TreeMap
基于什么实现
实现了什么接口③
包装成同步的方法
get()
判空
- put()
1.判空
2.类似getEntry()方法找到节点,设置后返回
3.未找到的话,找到要插入的父节点根据大小插左边或右边
- remove()
1.删除点p的左右子树都非空
2.删除点p只有一棵子树非空
2.1父节点为空
2.2是左节点
2.3是右节点
2.4看颜色调整
3.删除点p的左右子树都为空且父节点为空
4.删除点p的左右子树都为空且父节点不为空
HashMap
基于什么实现
允许放入
同步
冲突的处理方式
Java7 HashMap处理冲突采用的是
两个参数可以影响HashMap的性能
get(Object key)
for (Entry<K,V> e = table[hash&(table.length-1)];//得到冲突链表
- put(K key, V value)
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<>(hash, key, value, e);
remove(Object key)
在 Java8 中,当链表中的元素达到了几个时,会将链表转换为红黑树
Entry 和Node中包含什么
put () ``` 1.第一次会扩容 2.找到hash对应下标位置 3.空直接放
得到相同key的位置或插入位置
4.否则看这个元素是不是要找的 5.不是看是链表还是红黑树 6.红黑树有自己的操作方法 7.链表插入到链表最后边 8.看是否要转成红黑树
9.将值赋给相同key的位置或插入位置
10.如果超过阈值则需要扩容
-
resize() 每次扩容为原来的,并且
if (oldCap > 0) if (oldCap >= MAXIMUM_CAPACITY)
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY)
else if (oldThr > 0) else {
老数组不为空 遍历 1.只有一个元素 2.红黑树 3.链表
-
get()
1.计算 key 的 hash 值,根据 hash 值找到对应数组下标: hash & (length-1) 2.判断数组该位置处的元素是否刚好就是我们要找的,如果不是,走第三步 3.判断该元素类型是否是 TreeNode,如果是,用红黑树的方法取数据,如果不是,走第四步 4.遍历链表,直到找到相等(==或equals)的 key
-
HashTable
- 和什么类似,但它怎样,它是遗留类,使用什么来代替
-
LinkedHashMap
-
使用什么来维护元素的顺序,顺序为
-
允许放入
-
直接子类
-
图示
-
两个参数可以影响LinkedHashMap的性能
-
如何包装成同步的
-
get()
-
put()②
addEntry(int hash, K key, V value, int bucketIndex) addBefore(header)
-
remove()
-
经典用法
-
WeakHashMap
-
特殊之处
-
没有显示的添加或删除任何元素,也可能发生如下情况
-
弱引用
-
GC判断某个对象是否可被回收的依据是(不包括)
-
内部是通过什么来管理`entry`的
-
将任何 _Map_包装成一个Set的方法
Collections.newSetFromMap(Map
<a name="2fbfd4c7"></a>
## 容器遍历
<a name="a72d8a4c"></a>
## 工具类
<a name="27a0f51a"></a>
## 遗留容器
- Vector
- stack
- Dictionary
- BitSet
<a name="c11db1c1"></a>
# 注解
-
什么是注解
-
用处④
-
原理
-
元注解④
-
Retention使用什么记录注解
RuntimeInvisibleAnnotations 和 RuntimeVisibleAnnotations 属性
-
注解与反射接口(父接口)
-
注解支持继承吗
<a name="fad060bd"></a>
# 类
Java 中的构造器链是什么?
<a name="6106de3d"></a>
# JDK版本
-
说出 JDK 1.7 中的三个新特性?
try-with-resource 语句 Fork-Join 池某种程度上实现 Java 版的 Map-reduce 允许 Switch 中有 String 变量和文本 菱形操作符(<>)用于泛型推断,不再需要在变量声明的右边申明泛型 允许在同一个 catch 块中捕获多个异常
<a name="c4d08df9"></a>
# 序列化
-
被什么修饰不能被序列化,反序列化需要
声明为static和transient类型的数据不能被序列化, 反序列化需要一个无参构造函数 ```