Java面试题精选

jdk
┌──────────────┬───────────────────────────────────────────────────────┐
│ │ │
├──────────────┼───────────────────────────────────────────────────────┤
│ │ │
├──────────────┼──────────┤
│ │
├──────────────┴──────────┘
┏━━┳━━━┓
┃ ┃ ┃
┣━━╋━━━┫
┗━━┻━━━┛

1. JDK 和 JRE 的区别
JDK: Java Development Kit 的简称, 提供了 Java 的开发环境和运行环境.
JRE: Java Runtime Environment 的简称, Java 运行环境, 为 Java 的运行提供所需环境.
具体来说: JDK 包含了 JRE, 同时包含了编译 Java 源码的编译器 Javac, 还包含了很多 Java 程序调试和分析的工具.
简单来说: 如果只要运行 Java 程序, 只需要安装 JRE 就可以了. 如果还需要编写 Java 程序, 就需要安装 JDK.

2. == 和 equals 的比较
== 对于基本类型是比较值, 对于引用类型是比较引用.
equals 默认情况是比较引用, 但是很多类重写了 equals 方法, 如 String、Integer 重写成了值比较.

7. String、StringBuffer 和 StringBuilder 的区别
┌──────────────┬──────────────────────────────────────────┐
│String │ 不可变的对象. 每次操作都会生成新的 │
├──────────────┼──────────────────────────────────────────┤
│StringBuffer │ 非线程安全的, 单线程使用. │
├──────────────┼──────────────────────────────────────────┤
│StringBuilder │ 线程安全, 多线程使用. │
└──────────────┴──────────────────────────────────────────┘


10. String 类的常用方法
┌──────────────┬────────────────────────┐
│ indexOf() │ 返回字符索引
├──────────────┼────────────────────────┤
│ charAt() │ 返回索引处字符
├──────────────┼────────────────────────┤
│ replace() │ 字符串替换
├──────────────┼────────────────────────┤
│ trim() │ 去除字符串两段空白
├──────────────┼────────────────────────┤
│ split() │ 分隔字符串成数组
├──────────────┼────────────────────────┤
│ getBytes() │ 返回字符串的byte数组
├──────────────┼────────────────────────┤
│ length() │
├──────────────┼────────────────────────┤
│ toLowerCase()│ 转小写字母
├──────────────┼────────────────────────┤
│ toUpperCase()│ 转大写
├──────────────┼────────────────────────┤
│ subString() │ 截取字符串
├──────────────┼────────────────────────┤
│ equals() │ 值比较(已重写)
└──────────────┴────────────────────────┘

31. 迭代器
迭代器接口提供遍历任何 Collection 的接口. 迭代器允许调用者在迭代过程中移除元素.

35. 并行(Parallel) 和 并发(Concurrent)
┌──────────────┬─────────────────────────────────────────────────┐
│Parallel │ 多个处理器或多核同时处理多个任务
├──────────────┼─────────────────────────────────────────────────┤
│Concurrent │ 多个人物在同一个 Cpu 核上, 按细分的时间片轮流交替执行.
└──────────────┴─────────────────────────────────────────────────┘

114. ORM
ORM(Object Relation Mapping) 对象关系映射, 把数据库中的关系数据映射称为程序中的对象.

167. ACID
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ Atomicity 原子性; 一个事务 如果过程中发生错误, 会 整个回滚(Rollback), 就像没有执行过一样.
├───────────────────────────────────────────────────────────────────────────────────────┤
│ Consittency 一致性; 在事务结束后, 数据库的完整性没有被破坏. 写入的数据完全符合所有的约束、触发器、级联回滚等
├───────────────────────────────────────────────────────────────────────────────────────┤
│Isolation 隔离性; 数据库允许多个并发事务同时对其数据进行读写和修改的能力, 隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致. 事务隔离可以分为不同级别: 读未提交、读提交、可重复读和串行化
├───────────────────────────────────────────────────────────────────────────────────────┤
│Durability 持久性
└───────────────────────────────────────────────────────────────────────────────────────┘


173. 事务隔离级别
配置在 mysql.ini中
┌──────────────────────────────────────────┐
│transaciton-isolation = REPEATABLE-READ │
└──────────────────────────────────────────┘
可配置的值:
a) READ-UNCOMMITTED 未提交读; 最低隔离级别,事务未提交前,就可以被其他事务读取(会出现幻读、脏读、不可重复读)
b) READ-COMMITTED 提交读; 一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)
c) REPEATEABLE-READ 可重复读; [默认级别]保证多次读同一个数据时, 其值和事务开始时的内容是一致的,禁止读取别的事务未提交的数据(会造成幻读)
d) SERIALIZABLE 序列化; 代价最高的最安全的隔离级别,可以防止脏读、不可重复读、幻读

脏读: 一个事务能够读取到另一个事务中还未提交的数据. 比如,某个事务尝试插入数据A, 此时该事务还未提交,然后另一个事务读取到了这个记录A.
不可重复读: 同一个事务内,多次读取同一条数据,而每次读取到的值可能不同.
幻读: 一个事务内同样的读取条件,读取到的数据个数不一样,原因是被另一个事务删除或新增了符合条件的数据.
更多 https://www.cnblogs.com/balfish/p/8298296.html

174. MySql中的引擎
a) InnoDB: 提供了对 ACID 事务的支持, 还提供了行级锁和外键约束.
由于锁的粒度小, 写操作不会锁定全表,所以在并发高的场景下会提升效率.
b) MyIASM: mysql的默认引擎,不提供事务的支持也不支持行级锁和外键.
插入和更新操作时会锁定整个表,所以会导致效率降低.
如果表的读操作远远多于写操作时,并且不需要事务支持时可以优先选择 MyIASM.

175. MySQL 的表级锁和行级锁
MyIASM 只支持表锁, InnoDB 支持表锁和行锁,默认为行锁.
a) 表级锁: 开销小,加锁快,不会出现死锁.锁的粒度大,发生锁冲突的概率最高,并发量最低.
b) 行级锁: 开销大,加锁慢,会出现死锁.锁的粒度笑,发生锁冲突的概率小,并发读最高.

176. 乐观锁和悲观锁
a)乐观锁:
每次拿数据的时候都认为别人不会修改,所以不会上锁,但提交更新的时候会判断一下期间有没有人更新这个数据.
数据库的乐观锁需要自己实现一下,在表字段中加一个version字段,每次修改成功增加1,每次修改的时候对比一下之前的version和现在的version是否一致,如果不一致就不修改了,这就是乐观锁.
b)悲观锁:
每次拿数据的时候都认为别人会修改,所以每次拿数据的时候都会上锁,这样别人想拿这个数据就会被阻止,直到这个锁被释放.

177. MySql 问题排查
a) 使用 show processlist 命令查看当前所有的连接信息
b) 使用 explain 命令查看 sql语句的执行计划
c) 开启慢查询日志


178. MySql 性能优化
a)为搜索字段创建索引
b)避免使用 select *,列出要查询的字段
c)垂直分割分表
d)选择正确的存储引擎


179. Redis 使用场景
a)记录帖子点赞数、点击数、评论数
b)缓存近期热帖
c)缓存文章详情信息
d)记录用户会话信息

180. Redis 常用功能
a)数据缓存
b)分布式锁
c)支持数据持久化
d)支持事务
e)支持消息队列

181. Redis和 MemCache的区别
a)存储方式不同:
MemCache把数据全部存在内存中,断电后会挂掉;
MemCache数据不能超过内存大小;
Redis 有部分存储在硬盘中,能保证数据的持久性.
b)数据支持类型:
MemCache对数据类型的支持相对简单;
Rdies支持的数据类型要多得多.
c)底层模型不同
d)value值大小:Redis最大可以达到1Gb; MemCache只有1Mb;

183. Redis 中的缓存穿透
a)缓存穿透:
指查询一个一定不存在的数据,由于缓存中找不到时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库中查询,造成数据库的鸭梨.
比如:查询 id 为-1的,id不会有为-1的记录.
b)解决方案:如果查询结果为空,也放入缓存中,只不过设定的缓存过期时间较短,比如设置为60秒.

183-2. Redis 中的缓存雪崩
指在某一个时间段时,缓存集中过期失效.
栗子一:
双十一零点,发生了一波抢购,在短时间内集中的把商品数据放入了缓存,并设置缓存过期时间为1小时.
凌晨一点的时候,这批商品数据就过期了,访问查询就落到了数据库上.
解决方案: 不同类商品设置不同的缓存周期.同类商品加上随机因子.这样可以尽可能的分散缓存过期时间.
栗子二:
比较致命的缓存雪崩是缓存服务器某个节点宕机或断网.对数据库造成的压力是不可预知的,很可能瞬间把数据库拖垮.

183-3. Redis 中的缓存击穿
指某一个 key 非常热点,不停的有人访问这条数据,在这个 key 过期的瞬间会击破缓存,直接请求数据库.
解决方案:
让这条缓存永不过期??

183-4. GoLang 中使用 Redis


184. Redis 支持的数据类型
string、list、hash(字典)、set(集合)、zset(sorted set -- 有续集合)
这些数据类型都支持push/pop、add/remove及取交集并集差集等操作,而且这些操作都是原子性的.

185. 保持 Redis 缓存和数据库数据一致
a)合理设置缓存的过期时间
b)新增、更改、删除数据库操作时同步更新 Redis,可使用事务机制来保持数据的一致性

186. Redis 持久化
Redis 的持久化有两种策略:
a)RDB(Redis Database) 指定的时间间隔对数据进行快照存储.
b)AOF(Append Only File) 每收到一个写命令都通过 write 函数追加到文件中.

189. Redis 实现分布式锁

猜你喜欢

转载自www.cnblogs.com/sweetXiaoma/p/10656691.html