共计 4453 个字符,预计需要花费 12 分钟才能阅读完成。
本文首发于 cartoon 的博客
转载请注明出处:https://cartoonyu.github.io/c…
JAVA 基础
抽象类和接口的区别
类层面上
- 抽象类与接口都不能被实例化
- 抽象类只能继承一个直接父类,实现多个接口;接口能继承多个接口
- 抽象类大多用作模板类使用,接口用于规范模块间的行为
方法
- 抽象类可以用有抽象方法,静态方法以及普通方法;接口只能是抽象方法
- 抽象类中方法作用域跟普通类没有区别;接口方法只能是公共的
- 抽象类中可以通过方法间的相互引用实现自身逻辑,接口只能通过子类实现逻辑
- 抽象类可以拥有构造器,接口没有构造器
变量
- 抽象类可以有成员变量与静态变量,接口只能有 final 的静态变量
Object 类有哪些成员方法
- wait/notify
- clone
- hashCode/equals
- getClass
- finalize
克隆有哪些方法
- 实现 Cloneable 重写 clone 方法
- 实现 Serialize 接口
Collections 有哪些方法
返回线程安全类
- synchronizedXxx
返回不可变集合
- emptyXxx
- singletonXxx
- unmotifitableXxx
- 集合间的转换
对集合内元素进行操作
添加元素到集合中
- addAll
- copy
查找元素
- binarySearch
- frequency
- indexOfSubList
- shuffle
替换
- fill
- replaceAll
改变元素位置
- sort
- swap
- rotate
- reverse
元素对比
- min/max
- disJoint
java 常见异常类
系统级
- IllegalAccessException
- OutOfMemoryException
类级
- ClassNotFoundException
- ClassDefFoundException
对象级
- NullPointerException
- ClassCastException
- CloneNotSupportedException
- NoSuchFieldException
- InstantiationException
方法级
- IllegalArgumentException
- NoSuchMethodException
操作级
数字
- ArithmeticException
- NumberFormatException
数组
- ArrayStoreException
- IndexOutOfBoundException
IO
- IOException
- FileNotFoundException
- EOFException
数据库
- SQLException
线程
- InterruptedException
类加载机制是怎么样的
步骤
- 加载
- 校验
- 准备
- 解析
- 初始化
- 使用
- 卸载
双亲委派模型工作原理
类加载器
- BootstrapClassLoader
- ExtensionClassLoader
- ApplicationClassLoader
- UserClassLoader
- 当类被加载到内存时,逐层向上询问父加载器是否能加载,如果所有父加载器都不能加载,则由当前类加载器负责加载
- 这样做的原因能有效保证类的唯一性
HashMap 的扩容机制
- HashMap 的扩容机制主要依赖于三个元素:capacity(默认为 16),loadFactory 负载因子,size 当前元素个数
- 当前元素个数大于 8 时,内部数组自动转换为红黑树进行存储
- 当前元素个数大于初始容量 x 负载因子时,数组扩容两倍,且内部元素的位置重新进行哈希
- 当前元素个数小于初始容量的 0.1 倍时,数组缩小一半,同样元素位置需要重新哈希
ArrayList 扩容机制
- ArrayList 扩容主要依赖于 size(当前元素个数)以及 capacity(默认 10)的对比
- 当元素填满当前数组(capacity=size),将 capacity 扩容到现在的 1.5 倍,若计算后元素大于 Integer.MAX_VALUE 时,抛出 OOM
ArrayList 与 LinkedList 区别
- ArrayList 内部为数组,LinkedList 内部为双向链表
新增元素
- ArrayList 涉及到数组扩容(或者伴随着 arrayCopy)
- LinkedList 修改指针指向(或者伴随着遍历操作)
删除元素
- ArrayList 需要进行 arrayCopy
- LinkedList 遍历链表并修改指针指向
- ArrayList 大小受 Integer.MAX_VALUE 影响,LinkedList 大小理论上无限(受 JVM 调用最大内存影响)
- ArrayList 在插入元素时需要考虑当前容量以及进行 arrayCopy 操作,LinkedList 插入不需要有额外操作
Array 与 ArrayList 区别
存储类型
- Array: 基本数据类型以及对象
- ArrayList: 只能对象
大小限制
- Array: 在定义时指定,无法增大或缩小
- ArrayList: 定义时可不指定(初始为 10),可以扩容
插入元素
- Array: 插入基本数据类型元素不涉及装拆箱操作
- ArrayList: 涉及装拆箱操作
Queue 中 poll 与 remove 区别
- poll 与 remove 都是取出队头元素
- 队列不为空时,两个方法结果是一样的
队列为空
- poll 返回 null
- remove 抛出 NoSuchElementException
线程不同步集合如何转换成线程同步集合
通过 Collections 工具类返回
- 锁为读写锁,锁的粒度为对象级
通过 java.util.Concurrent 进行包装
- 锁为写锁,锁的粒度为元素级
- 通常都是用 Concurrent 进行包装
JVM
垃圾回收算法
标记 - 清除
- 标记不清理对象,清理未标记对象
- 速度快,但是会造成内存碎片
复制
- 将内存划分两块区域: 清理区与存活区
- 将不清理对象移到存活区,删除清理区的所有对象
- 空间浪费大
标记 - 整理
- 标记不清理对象,清理未标记对象
- 移动整理存活对象
- 成本高,但是有效解决内存碎片问题
G1 工作流程
初始标记(停顿线程)
- 标记 GC Root 直接关联对象
并发标记
- 从 GC Root 对堆中对象进行可达性分析
最终标记(停顿线程)
- 并行将 Remembered Set Logs 的数据合并到 Remembered Set 中
筛选回收
- 根据各 Region 的回收价值和成本进行回收计划的制定
Spring
Spring 中有哪些模块
- Spring Core(Spring 核心库)
- Spring AOP
- Spring ORM
- Spring Dao
- Spring Web
- Spring Context
- Spring Web MVC
Spring MVC 的处理流程
请求通过 DispatchServlet 处理
- 普通逻辑处理交由 Controller 处理,Controller 处理后返回 model
- 视图处理,DispatchServlet 调用 View temlate 进行视图返回
AOP 概念
- AOP 面向切面编程,它将原本纵向的程序看作成一个个切面的组合,是 OOP 的补充
- 动态插入执行逻辑到原有执行流程中
- 通知(Advice): 具体实现逻辑
- 连接点(JoinPoint): 使用通知的位置
- 切入点(PointCut): 指定使用通知的连接点位置
- 切面(Aspect): 通知与切入点集合
- 引入(introduction): 添加新方法属性到现有类中
- 目标(target): 被通知的对象
- 代理(proxy)
- 静态代理
- 动态代理
- 织入(weaving): 将切面引用到目标对象生成代理对象的过程
- Spring bean 的作用域
- singleton(默认)
- prototype
- request
- session
- globalSession
数据库
MyBatis 中 #与 $ 区别
传入数据
: 当作字符串传入 sql,相当于 PrepareStatement
- $: 直接将参数传入 sql,相当于 Statement
安全性
可以防止 sql 注入,$ 不能
事务的四个特性
一致性
- 事务执行前后都是一致的
原子性
- 事务中操作结果都是一样的
隔离性
- 事务间的操作是相互隔离的
持久性
- 事务的执行结果是永久性的
char 与 varchar 区别
- char 的长度是固定的,varchar 的长度是不固定的
- char 会用空格填充到指定长度,varchar 不会
- char 类型数据后面空格会被删除,varchar 不会
- char 的检索效率比 varchar 高
逻辑分页与物理分页
- 逻辑分页会将全部数据加载到内存中,再利用代码逻辑返回分页结果
- 物理分页是在数据库层面进行分页
MyBatis 的分页方式
- 数组分页
- sql 分页
- 拦截器分页
- RowBounds 分页
数据库三范式
第一范式
- 属性已经是不能分割的数据单位
第二范式
- 所有非主属性完全依赖于候选属性
第三范式
- 不存在传递依赖候选属性
内连接外连接区别
- 内连接只返回符合条件的共有记录
- 外连接会返回表的所有记录,插入符合条件的列
操作系统
线程与进程的区别
- 进程是操作系统分配资源时间的最小单位,线程是进程内部调用的实体
- 不同进程拥有操作系统分配的不同地址空间,同一进程的不同线程共享父进程的内存地址
- 进程的资源与空间由操作系统分配,线程资源与空间由进程分配
- 进程切换开销比线程大
- 进程崩溃不会造成对其他进程的影响;线程崩溃造成父进程的死亡
- 进程拥有一个程序运行的入口,线程依附进程生存
网络
http 方法有哪些
- 方法
- get
- post
- delete
- put
- options
- connect
- trace
- link
- unline
- head
get 与 post 的区别
幂等
- get 为幂等操作,post 为非幂等操作
数据传输
- get 的数据通过 url 进行传输,post 数据通过 http 报文传输
- get 数据大小受 url 长度限制,post 不受限制
可缓存
- get 数据可缓存,post 数据不可缓存
http 报文
- get 的报文没有实体,post 的报文有实体
forward 与 redirect 区别
行为方
- forward 是浏览器行为
- redirect 是服务器行为
url 是否改变
- forward url 不变
- redirect url 改变
资源消耗
- forward 的资源消耗比 redirect 小
数据共享
- redirect 不共享数据,forward 可以共享 request 数据
效率
- forward 高
- redirect 低
TCP 三次握手
一次握手(客户端发起)
- 创建 TCB
- 发送 SYN=1,seq=x
- 进入 SYN-SENT
二次握手(服务器发起)
- 发送 ACK=1,syn=1,ack=y+1,seq=x+1
- 进入 SYN-RCVD
三次握手(客户端发起)
- 发送 ACK=1,seq=x+1,ack=x+1
- 进入 ESTABLISHED
UDP 与 TCP 区别
- TCP 面向连接,UDP 不面向连接
- TCP 有拥塞控制,UDP 没有拥塞控制
- TCP 资源开销大,UDP 资源开销小
- TCP 只支持一对一,UDP 支持一对多
- TCP 提供可靠传输,UDP 尽可能交付
- TCP 面向字节流,UDP 面向报文
设计模式
单例模式实现的三种方法
- https://www.cnblogs.com/ngy02…
- 静态内部类
- 懒汉式
- 双重检查式
BIO NIO AIO
BIO
- 同步阻塞
- 线程阻塞进行运算后返回结果
NIO
- 同步非阻塞
- 请求共用一个线程进行处理
- 线程会直接返回结果到请求
AIO
- 异步非阻塞
- 线程处理后会通过回调返回结果
反射
- JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
- 动态代理以及静态代理