面试题目类型
笔试
print 函数内执行 i++
int i=1;
System.out.println("num is "+ ++i);
- 上面代码输出的结果是 2.
PS 当 ➕ 的顺序为 + + + i 时,i 就为 1
String 是 final 类吗,final 类可以继承吗
是,final 类不能继承,具体 String 的详细内容可看另外一篇文章
%
与_
在 sql 中各自代表了什么
前者任意数量任意字符,后者单指一个任意字符
存放对象常量的对象
字符串
String 和 StringBuffer,其中前者不可变,后者可变
字符型
Character 的包装类
数组存储
Vector 与 ArrayList 类似,实现了 list 接口,都通过数组实现,区别在于 Vector 支持线程的同步,避免多线程引起的不一致性
常见 Java 文件格式
字节码
Java 文件经过 Jvm 编译生成了字节码文件,即.class 文件,在不同操作系统的虚拟机执行时,会由操作系统再将字节码编译为机器码文件。[跨平台]
JAR
Java Archive File. Java 的文档形式,类似于 ZIP 文件,也称为文件包。唯一区别呢在于在 JAR 文件中,包含了一个 META-INF/MANIFEST.MF 文件,生成 JAR 文件的时候自动创建。
默认参数类型
整数
int
带小数
double
构造函数
调用方式
- 类内部使用 this.constructor()调用
- 子类中通过 super.constructor()调用
- 反射机制可以知道类的所有属性和方法,包括了构造函数
数组
复制速度
System.arraycopy>Clone>Arrays.copyOf>for循环
- System 调用的是 native 方法,本地方法速度最快
- clone 复制引用,或者调用底层函数
- 底层也是调了 System.arraycopy,只是额外做了 Math.min 函数
- for 速度之所以慢,是因为下标表示法每次都是从起点开始寻位到指定下标处(后续编译器有优化为指针形式),此外每次循环时都要判断是否达到数组最大长度和进行一次额外记录下标值的加法运算
类定义
局部变量
局部变量如果使用到就必须要初始化。
成员变量
成员变量才会在类加载时会有初始化赋值
volatile 与 synchronized
volatile | synchronized |
---|---|
告诉当前变量在寄存器是不稳定的,要从主存读取 | 锁定当前变量,只有当前线程读取变量,其他线程阻塞 |
在变量级别 | 可用于变量、方法 |
实现变量的修改可见性,没有原子性 | 可保证变量的修改可见性和原子性 |
不会造成线程的阻塞 | 可能导致线程阻塞 |
标记的变量不会被编译器优化 | 可以被编译器优化[存在指令重排导致读不到完全初始化的变量情况] |
public
- 一个类只能出现一个
多态
- 子类继承父类的所有成员,包括 private 权限的成员变量,但是继承的子类具有私有变量的拥有权但没有使用权
抽象类
- 抽象类中可以构造方法
- 可以存在普通属性、方法,静态属性,方法以及抽象方法
- 如果有一个抽象方法,那么一定为抽象类,另外抽象类不一定要有抽象方法
- 子类必须实现父类的抽象方法,不然也是抽象的
接口
- 只有方法的声明,没有方法体(Jdk8 default 另说)
- 只有常量 public static final
- 方法修饰符永远是 public
- 接口没有构造方法,也不能实例接口对象
- 接口可以实现多继承
- 接口的方法必须都有实现类来实现,不然只能定义为抽象类
J2EE
Web 容器
给处于其中的应用程序组件(JSP、SERVLET)提供一个环境,使得直接交互,而无需关注系统问题,比如 TOMCAT、WEBLOGIC、WEBSPHERE 等,一般这种容器都严格遵守 J2EE 规范的 WEB APPLICATION 标准
EJB 容器
Enterprise Java Bean。给运行的 EJB 各种管理功能,被容器高效管理,可以通过现有接口获得系统级别的服务。Eg:邮件服务、事务管理
JNDI
Java Naming & Directory Interface。Java 命名目录服务。主要功能是提供目录系,让其他应用在上面留下自己的索引,便于快速查找和定位分布式应用程序的功能
JTA
Java Transaction API。Java 事务服务
JAF
Java Action FrameWork. Java 安全认证框架
RMI/IIOP
Remote Method Invocation/internal 对象请求中介协议,主要用于远程调用服务
协议:采取 TCP/IP 协议
进阶版:RPC 等慢慢取缔
流
节点流
向特定地方(节点)读写数据,比如 FileReader
常用节点流
- 文件 FileInputStream
- 字符串 StringReader
- 数组 ByteArrayInputStream
- 管道 PipedInputStream
处理流
对已存在的流连接和封装,通过封装流的功能实现数据读写。比如 BufferedReader 处理流构造方法总需要带一个其他的流对象做参数。
常用处理流
- 缓冲流 BufferedInputStream
- 转换流 InputStreamReader 实现字节流和字符流之间的转换
- 数据流 DataInputStream 将数据类型写入到文件中
exception
classDiagram
class Serializable{
<<可序列化接口>>
}
class Throwable{
}
Serializable <|..Throwable: 实现使得可序列化
class Exception{
<<程序可处理的异常>>
}
class Error{
<<非检查异常 程序无法处理的>>
<<OutOfMemoryError>>
}
Throwable <|-- Exception: 继承实现
Throwable <|-- Error: 继承实现
class RuntimeException{
<<非检查异常>>
<<NullPointerException>>
}
class SpecificException{
<<具体异常>>
<<IOException>>
}
Exception <|-- RuntimeException: 继承实现
Exception <|-- SpecificException: 继承实现
异常的处理范围
可以将异常抛给上级方法(即方法调用者)进行处理
Statement
Exception
try-catch-finally 规则
- 只能在 try 后添加 catch 或 finally 块
- 按照顺序往下与 catch 块进行匹配
- 如果匹配了一个 catch,如没有继续 throw,则整个语句退出
- 除了下列情况,总将 finally 作为结束:**JVM 过早终止(调用
System.exit(int)
);在 finally 块抛出一个未处理的异常;计算机宕机
Thread
start
开启多线程,由 JVM 执行相应的线程,线程执行情况由线程调度器决定
run
定义执行体,等同于线程处理任务逻辑的入口方法
JavaWeb
常见类
HttpSessionAttributeListener:可以实现此侦听器接口获取此web应用程序中会话属性列表更改的通知;
HttpSessionBindingListener:当该对象从一个会话中被绑定或者解绑时通知该对象,这个对象由HttpSessionBindingEvent对象通知。这可能是servlet程序显式地从会话中解绑定属性的结果,可能是由于会话无效,也可能是由于会话超时;
HttpSessionObjectListener:没有该接口API;
HttpSessionListener:当web应用程序中的活动会话列表发生更改时通知该接口的实现类,为了接收该通知事件,必须在web应用程序的部署描述符中配置实现类;
HttpSessionActivationListener:绑定到会话的对象可以侦听容器事件,通知它们会话将被钝化,会话将被激活。需要一个在虚拟机之间迁移会话或持久会话的容器来通知所有绑定到实现该接口会话的属性。
内存
分配情况
graph TD;
Permanent[持久代]
Permanent-->Java类定义信息
Permanent-->Method
Heap[Heap space]
Heap-->|年轻代| NEW
NEW --> | 针对年轻代的回收成为Young GC| Heap
OLD --> | 针对年轻代的回收成为FULL GC| Heap
Heap-->|老年代| OLD
NEW -->|大部分对象在Eden区创建| Eden
Eden --> |Eden区满时,还存活的对象复制到survivor区_from or to中 | from
Eden --> |Eden区满时,还存活的对象复制到survivor区_from or to中 | to
from --> |如果survivor也满了,尝试复制到另外一个survivor| to
to --> |如果两个survivor都满了,则可能将对象复制到年老代 | OLD
title[堆内存图]
内存申请过程
graph TD;
JVM-->|尝试在Eden区初始化内存区域| tryEden
tryEden-->|够| End
tryEden-->|如果空间不够,尝试释放Eden不活跃对象| tryYoungGC
tryYoungGC-->|够| End(如果空间足够,则直接结束)
tryYoungGC-->|尝试将Eden对象放到survivor区| trySurvivor
trySurvivor-->|够|End
trySurvivor-->|尝试将存活一定次数的对象移到年老代|tryOld
tryOld-->|够|End
tryOld-->|尝试Full GC| tryFullGC
tryFullGC-->|够|End
tryFullGC-->|出现OOM Out of Memory 异常| OOM
title[内存申请流程]
OOM 异常原因
- 年老代溢出 Javaheapspace
设置内存参数 Xmx 过小 or 程序的内存泄漏 or 使用不当
1. 循环上万次字符串操作
1. 创建千万对象
1. 在代码里申请上百M甚至上G的内存 - 持久代溢出 PermGenSpace
可以设置-XX:MaxPermSize 调大 or 将 Java 类迁移到容器共享类中
1. 持久代设置过小
1. 动态加载大量Java类导致溢出
错题记录
import
import java.util.*
// 会引用子目录吗?
// 不会,只会引用当前目录的所有
ArrayList.remove
iterator.remove();
// 使用迭代器安全删除,搭配it.hasNext();