Java实习面试必备:核心知识点全解析
Java实习面试全套知识点标准答案
1.1 Java基础(重中之重)
1. 数据类型、== 和 equals、String、常量池
(1)Java数据类型
分为基本数据类型和引用数据类型
- 基本类型(8种,存栈内存)
- 整数:byte(1)、short(2)、int(4)、long(8)
- 浮点:float(4)、double(8)
- 字符:char(2)
- 布尔:boolean(1)
- 引用类型(存堆,栈存地址):类、接口、数组、包装类
(2)== 和 equals 区别
==
- 基本类型:比较值是否相等
- 引用类型:比较对象内存地址是否相同
equals()
- Object原生实现等价于
==,比较地址 - String、Integer等重写后:比较对象内容值
- 自定义类如需比较内容,必须重写
equals(),配套重写hashCode()
(3)String、字符串常量池
- String特性:不可变,底层char数组(Java9后byte数组),每次修改都会生成新字符串
- 常量池作用:复用字符串,减少内存开销
String s1 = "abc":直接去常量池找,有就复用,没有新建放入池String s2 = new String("abc"):先在堆创建对象,再去常量池创建/复用,栈存堆地址
- 拼接规则:
- 常量拼接
"a"+"b":编译期优化为"ab",走常量池 - 变量拼接
s1+s2:运行时new String,不进常量池
2. 面向对象:封装、继承、多态、接口&抽象类区别
三大特性
- 封装:隐藏对象内部细节,对外暴露访问方法(private+get/set),保证数据安全
- 继承:
extends,子类复用父类代码,单继承;子类可重写父类方法,用super访问父类 - 多态:同一方法不同实现,两个前提:①父类引用指向子类对象 ②方法重写;分为编译多态(重载)、运行多态(重写)
接口 vs 抽象类
| 对比 | 抽象类 abstract class | 接口 interface |
|---|---|---|
| 继承 | 单继承 | 多实现 |
| 构造方法 | 有构造,供子类调用 | 无构造 |
| 变量 | 可普通变量、常量 | 只能public static final常量 |
| 方法 | 普通方法、抽象方法、静态方法 | Java8前只有抽象;8+有default/static;9+私有方法 |
| 关键字 | extends | implements |
| 设计思想 | 模板复用(is-a) | 行为规范(can-do) |
3. 集合:ArrayList/LinkedList、HashMap底层(数组+链表+红黑树)
(1)ArrayList vs LinkedList
- ArrayList:底层动态数组
- 优点:随机访问快
get(index)O(1);遍历快 - 缺点:中间增删需要移动元素,效率低;初始容量10,扩容1.5倍
- LinkedList:底层双向链表
- 优点:首尾增删只改指针,效率高
- 缺点:随机查找必须遍历,O(n),查询慢
(2)HashMap底层(JDK1.8)
底层:数组 + 单向链表 + 红黑树
- 存储单元:Node<K,V>,存hash、key、value、下一个节点指针
- 存储流程:
- 计算key的hash值,对数组长度取模得到数组下标
- 下标无元素:直接放入数组
- 下标有元素(哈希冲突):
- 链表长度<8:追加单向链表
- 链表长度≥8 且数组长度≥64:链表转为红黑树(查询O(logn)优化链表O(n))
- 红黑树节点<6:退化为链表
- 扩容:默认容量16,负载因子0.75;元素数量超过
容量*0.75扩容,数组翻倍,重新hash迁移元素 - 线程不安全:多线程扩容、插入会出现死链、数据丢失;并发用ConcurrentHashMap
4. 异常体系、IO、线程基础、synchronized、volatile
(1)异常体系
Throwable分两大分支:
- Error:系统级错误(OOM、栈溢出),程序无法处理
- Exception:程序可处理异常
- 受检异常(编译强制捕获/throws):IO、SQL异常等
- 运行时异常RuntimeException(无需强制捕获):空指针、数组越界、类型转换异常
(2)IO基础
分为BIO、NIO;实习掌握BIO即可
- 字节流InputStream/OutputStream:处理文件、图片等二进制
- 字符流Reader/Writer:处理文本文件,自带编码转换
- 装饰器模式:BufferedInputStream缓冲流提升读写速度
(3)创建线程4种方式
- 继承Thread类,重写run(),调用start()启动
- 实现Runnable接口,传入Thread构造器(推荐,避免单继承限制)
- 实现Callable+FutureTask,可获取线程返回值、抛异常
- 线程池Executors(生产环境推荐,复用线程,减少创建销毁开销)
(4)synchronized 同步锁
- 作用:保证原子性、可见性、有序性,解决并发竞争
- 锁对象:
- 实例方法:锁当前this对象
- 静态方法:锁类Class对象
- 代码块:手动指定锁对象
- 底层:对象头监视器锁,偏向锁→轻量级锁→重量级锁锁升级,不可降级
(5)volatile
- 核心作用:保证可见性、禁止指令重排
- 不保证原子性:不能替代锁,多线程计数场景失效
- 原理:强制变量修改立即刷入主存,其他线程缓存失效;内存屏障阻止指令重排
- 典型场景:状态标记、双重校验锁DCL单例
1.2 MySQL数据库(必考)
1. 增删改查、多表联查、子查询
基础CRUD
-- 增INSERTINTO表(字段)VALUES(值);-- 删DELETEFROM表WHERE条件;-- 改UPDATE表SET字段=值WHERE条件;-- 查SELECT字段FROM表WHERE条件;多表联查
- 内连接INNER JOIN:只返回两边匹配数据
select * from A inner join B on A.id=B.a_id - 左连接LEFT JOIN:左表全部,右表匹配不到填null
- 右连接RIGHT JOIN:右表全部,左表匹配不到填null
子查询
- 标量子查询(返回单个值):where后使用
- 表子查询(返回多行多列):from后当做临时表,必须起别名
2. 索引、B+树、联合索引最左匹配
(1)什么是索引
索引是数据库磁盘上的有序数据结构,加速查询,代价:占用存储空间、降低增删改速度(维护索引)
(2)InnoDB底层B+树
- B+树特点:
- 所有数据只存在叶子节点,非叶子只存索引键,层级更低、IO更少
- 叶子节点双向链表串联,范围查询极快
- 对比B树:B树每个节点存数据,IO次数更多,范围查询差
- InnoDB主键索引(聚簇索引):叶子存完整行数据;普通索引(二级索引)叶子存主键id,回表查询完整数据
(3)联合索引最左匹配原则
建立索引idx(a,b,c),查询条件从左到右匹配:
- 生效场景:where a=? / where a=? and b=? / where a=? and b=? and c=?
- 失效场景:跳过最左前列直接查b/c,索引断裂,后面字段失效
例:where b=? and c=? 索引完全失效;where a=? and c=? 仅a生效,c失效 - 优化:等值放前,范围查询(> < like %xx)后面字段索引失效
3. 事务四大特性、隔离级别、脏读幻读
(1)事务四大特性 ACID
- 原子性Atomic:事务全部执行成功,或全部回滚,不可分割
- 一致性Consistent:事务前后数据完整性不变
- 隔离性Isolate:多事务互不干扰,由隔离级别控制
- 持久性Durable:事务提交后数据永久写入磁盘,宕机不丢失
(2)四大隔离级别(从低到高)
- 读未提交Read Uncommitted:可读到未提交数据,存在脏读、不可重复读、幻读
- 读已提交Read Committed(Oracle默认):只能读已提交,解决脏读,存在不可重复读、幻读
- 可重复读Repeatable Read(MySQL InnoDB默认):同一事务多次读取数据一致,解决脏读、不可重复读,存在幻读;MVCC机制实现
- 串行化Serializable:最高级别,完全串行执行,所有问题都解决,并发性能极差
(3)三类并发问题
- 脏读:一个事务读到另一个事务未提交的修改数据,对方回滚后读到无效脏数据
- 不可重复读:同一事务内,两次读取同一行,中间被其他事务修改提交,两次结果不一致
- 幻读:同一事务内,范围查询,其他事务插入/删除符合条件数据,再次查询数量变化
1.3 框架 Spring + SpringBoot + MyBatis
Spring、SpringBoot 核心
1. IOC、AOP是什么
IOC 控制反转
- 传统开发:new创建对象,程序主动控制依赖
- IOC思想:反转对象控制权,Spring容器负责创建、管理对象(Bean),程序直接注入使用
- DI依赖注入是IOC实现方式:容器自动把依赖对象注入目标Bean,解耦代码
AOP 面向切面编程
- 作用:横向抽取通用公共逻辑(日志、权限、事务、接口耗时),不侵入业务代码
- 核心概念:切面、切点、通知(前置/后置/异常/环绕通知)
- 实现:JDK动态代理(实现接口)、CGLIB代理(类无接口)
2. 依赖注入、自动配置原理
三种依赖注入方式
- 构造器注入(推荐)、2. set方法注入、3. @Autowired字段注入
SpringBoot自动配置原理
核心注解@EnableAutoConfiguration:
- 启动时读取
META-INF/spring.factories配置文件 - 加载所有自动配置类
XxxAutoConfiguration - 通过
@Conditional条件注解:存在对应依赖包、不存在用户自定义Bean时,自动装配组件 application.yml/application.properties绑定配置类XxxProperties,自定义参数
3. SSM完整CRUD项目搭建流程
- 引入依赖:spring-web、spring-jdbc、mybatis、mysql驱动、spring-boot-starter-test
- 配置yml:数据库连接、MyBatis映射文件路径、实体类别名
- 实体Entity:对应数据库表
- Mapper接口:写CRUD抽象方法
- Mapper.xml映射文件:写SQL,绑定接口方法
- Service层:接口+Impl,注入Mapper,封装业务逻辑
- Controller层:注入Service,接收前端请求,返回数据
- 启动类加
@MapperScan扫描Mapper接口
MyBatis:映射文件、#{} 和 ${} 区别
#{}预编译占位符
- 底层PreparedStatement,参数加单引号,防止SQL注入
- 会自动转义字符串,适合传字段值
select*fromuserwhereid=#{id}${}字符串直接拼接
- 直接拼接文本,无预编译,存在SQL注入风险
- 不会自动加引号,适合动态表名、排序字段
select*from${tableName}orderby${sortColumn}- 开发规范:优先#{},仅动态表/列使用${}
1.4 计算机网络基础
1. HTTP/HTTPS、GET和POST区别、状态码
(1)HTTP vs HTTPS
- HTTP:明文传输,端口80,无加密,数据容易被抓包篡改
- HTTPS = HTTP + SSL/TLS加密,端口443
- 传输数据对称加密,证书非对称加密交换密钥
- 防窃听、防篡改、身份认证,更安全;性能略有损耗
(2)GET 和 POST 核心区别
- 参数位置:GET参数拼在URL;POST放请求体body
- 数据大小:GET受URL长度限制;POST无理论上限
- 缓存:GET默认浏览器缓存;POST一般不缓存
- 安全性:GET参数暴露地址,不适合传敏感数据;POST相对更安全
- 语义规范:GET用于查询(无数据修改);POST用于新增/提交数据
- 幂等:GET天然幂等(多次请求结果一致);POST非幂等(重复提交生成多条数据)
(3)常见HTTP状态码
- 2xx 成功
200 请求正常完成;201 创建资源成功 - 3xx 重定向
301永久重定向;302临时重定向;304资源未修改走缓存 - 4xx 客户端错误
400参数错误;401未登录无认证;403权限不足;404资源不存在;405请求方法不允许 - 5xx 服务端错误
500服务器内部异常;503服务不可用
2. TCP三次握手、四次挥手(简易背诵版)
三次握手(建立连接)
- 客户端 → 服务端:SYN报文,客户端请求同步,客户端进入SYN_SENT
- 服务端 → 客户端:SYN+ACK报文,同意连接+确认客户端报文,服务端SYN_RCVD
- 客户端 → 服务端:ACK报文,确认服务端同步,双方进入ESTABLISHED,连接就绪
核心目的:确认双方收发能力正常,协商初始序列号
四次挥手(断开连接)
- 客户端 → 服务端:FIN,客户端不再发数据,进入FIN_WAIT1
- 服务端 → 客户端:ACK,收到关闭请求,继续传输剩余数据,客户端FIN_WAIT2
- 服务端 → 客户端:FIN,服务端数据传输完毕,准备关闭
- 客户端 → 服务端:ACK,确认关闭;客户端等待2MSL超时彻底断开,服务端直接关闭
核心原因:TCP全双工通信,一方关闭后另一方可能还有残留数据发送,必须分两次发送FIN
