最近有粉丝私信说被oppo的后端面试问麻了,所以明天给大家举荐一篇整顿了16道oppo面试真题答案的文章。心愿对大家有帮忙哈,一起学习,一起提高。
- 聊聊你印象最粗浅的我的项目,或者做了什么优化。
- 我的项目提到分布式锁,你们是怎么应用分布式锁的?
- 常见的分布式事务解决方案
- 你们的接口幂等是如何保障的?
- 你们的MySQL架构是怎么的?
- 常见的索引构造有?哈希表构造属于哪种场景?
- 给你ab,ac,abc字段,你是如何加索引的?
- 数据库隔离级别是否理解?你们的数据库默认隔离级别是?为什么选它?
- RR隔离级别实现原理,它是如何解决不可反复读的?
- 你们我的项目应用了RocketMQ对吧?那你晓得如何保障音讯不失落吗?
- 事务音讯是否理解?场景题:比方下单清空购物车,你是如何设计的?
- 如何疾速判断一个数是奇数还是偶数,除开对2取其余呢。
- Spring申明式事务原理?哪些场景事务会生效?
- 你们是微服务架构吗?如果你来设计一个相似淘宝的零碎,你怎么划分微服务?
- 你们是怎么分库分表的?分布式ID如何生成?
- 所有异样的独特先人是?运行时异样有哪几个?
1. 聊聊你印象最粗浅的我的项目,或者做了什么优化。
大家平时做的我的项目,如果很多知识点跟面试八股文相干的话,就能够绝对条理清晰地写到简历去。
- 比方缓存数据库相干的,查问为空,你设置了一个-1到缓存,代表数据库没记录。下次判断-1,就不查库了,以解决缓存穿透的问题。
- 又比方你设置缓存过期工夫比拟扩散,解决缓存击穿问题,都能够条理清晰写到简历去,这样面试官很可能会问你相干的问题,这时候就对答如流啦。
还有平时你做的我的项目,有一些比拟好的设计,都能够说一下哈,比方你是如何保证数据一致性的,怎么优化接口性能的。
- 如果是讲优化接口这一块的话,其实就是缓存、分批、并发调用、异步等那几个要害知识点。
- 如果是代码优化细节,你能够挑个简略的来讲,比方简单的if逻辑条件,能够调整程序,让程序更高效,这样会让面试官眼前一亮哦。
2. 你我的项目提到分布式锁,你们是怎么应用分布式锁的?
个别你讲述你做的我的项目时,面试官会依据你我的项目波及的一些面试点,而后抽他感兴趣的一两个来问。所以大家对哪些知识点相熟,讲述我的项目时,就说你用该知识点,解决了什么问题。
3. 常见分布式事务解决方案
分布式事务:就是的分布式的参与者、反对事务的服务器、资源服务器以及事务管理器别离位于不同的分布式系统的不同节点之上。简略来说,分布式事务指的就是分布式系统中的事务,它的存在就是为了保障不同数据库节点的数据一致性。
聊到分布式事务,大家记得这两个实践哈:CAP实践 和 BASE 实践
分布式事务的几种解决方案:
- 2PC(二阶段提交)计划、3PC
- TCC(Try、Confirm、Cancel)
- 本地音讯表
- 最大致力告诉
- seata
2PC(二阶段提交)计划
2PC,即两阶段提交,它将分布式事务的提交拆分为2个阶段:prepare和commit/rollback,即筹备阶段和提交执行阶段。在prepare筹备阶段须要期待所有参加子事务的反馈,因而可能造成数据库资源锁定工夫过长,不适宜并发高以及子事务生命周长较长的业务场景。并且协调者宕机的话,所有的参与者都收不到提交或回滚指令。
3PC
两阶段提交别离是:CanCommit,PreCommit 和 doCommit,这里不再详述。3PC 利用超时机制解决了 2PC 同步阻塞问题,防止资源被永恒锁定,进一步增强了整个事务过程的可靠性。然而 3PC 同样无奈应答相似的宕机问题,只不过呈现很多数据源中数据不统一问题的概率更小。
TCC
TCC 采纳了弥补机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和弥补(撤销)操作。它分为三个阶段:Try-Confirm-Cancel
- try阶段:尝试去执行,实现所有业务的一致性查看,预留必须的业务资源。
- Confirm阶段:该阶段对业务进行确认提交,不做任何查看,因为try阶段曾经查看过了,默认Confirm阶段是不会出错的。
- Cancel 阶段:若业务执行失败,则进入该阶段,它会开释try阶段占用的所有业务资源,并回滚Confirm阶段执行的所有操作。
TCC计划让利用能够自定义数据库操作的粒度,升高了锁抵触,能够晋升性能。然而利用侵入性强,try、confirm、cancel三个阶段都须要业务逻辑实现。
本地音讯表
ebay最后提出本地音讯表这个计划,来解决分布式事务问题。业界目前应用这种计划是比拟多的,它的核心思想就是将分布式事务拆分老本地事务进行解决。能够看一下根本的实现流程图:
最大致力告诉
最大致力告诉计划的指标,就是发动告诉方通过肯定的机制,最大致力将业务处理结果告诉到接管方。
seata
Saga 模式是 Seata 提供的长期事务解决方案。核心思想是将长事务拆分为多个本地短事务,由Saga事务协调器协调,如果失常完结那就失常实现,如果某个步骤失败,则依据相同程序一次调用弥补操作。
Saga的并发度高,然而一致性弱,对于转账,可能产生用户已扣款,最初转账又失败的状况。
4. 你们的接口幂等是如何保障的?
如果你调用上游接口超时了,是不是思考重试?如果重试,上游接口就须要反对幂等啦。
实现幂等个别有这8种计划:
- select+insert+主键/惟一的索引抵触
- 间接insert + 主键/惟一的索引抵触
- 状态秘密等
- 抽取防重表
- token令牌
- 乐观锁(如select for update,很少用)
- 乐观说
- 分布式锁
大家平时是用哪个计划解决幂等的,最初联合工作理论讲讲哈。
5. 你们的mySQL架构是怎么的?
大家能够联合本人公司的MySQL架构聊聊。
数据的库高可用计划
- 双机主备
- 一主一从
- 一主多从
- MariaDB同步多主机
- 数据库中间件
5.1 双机主备
- 长处:一个机器故障了能够主动切换,操作比较简单。
- 毛病:只有一个库在工作,读写压力大,未能实现读写拆散,并发也有肯定限度
5.2 一主一从
- 长处:从库反对读,分担了主库的压力,晋升了并发度。一个机器故障了能够主动切换,操作比较简单。
- 毛病:一台从库,并发反对还是不够,并且一共两台机器,还是存在同时故障的机率,不够高可用。
5.3 一主多从
- 长处:多个从库反对读,分担了主库的压力,显著晋升了读的并发度。
- 毛病:只有一台主机写,因而写的并发度不高
5.4 MariaDB同步多主机集群
- 有代理层实现负载平衡,多个数据库能够同时进行读写操作;各个数据库之间能够通过Galera Replication办法进行数据同步,每个库实践上数据是完全一致的。
- 长处:读写的并发度都显著晋升,能够任意节点读写,能够主动剔除故障节点,具备较高的可靠性。
- 毛病:数据量不反对特地大。要防止大事务卡死,如果集群节点一个变慢,其余节点也会跟着变慢。
5.5 数据库中间件
- mycat分片存储,每个分片配置一主多从的集群。
- 长处:解决高并发高数据量的高可用计划
- 毛病:保护老本比拟大。
6. 常见的索引构造有?哈希表构造属于哪种场景?
哈希表、有序数组和搜寻树。
- 哈希表这种构造实用于只有等值查问的场景
- 有序数组适宜范畴查问,用二分法疾速失去,工夫复杂度为 O(log(N))。查问还好,如果是插入,就得移动前面所有的记录,老本太高。因而它个别只实用动态存储引擎,比方保留2018年某个城市的所有人口信息。
- B+树适宜范畴查问,咱们个别建的索引构造都是B+树。
7.给你ab,ac,abc字段,你是如何加索引的?
这次要考查联结索引的最左前缀准则知识点。
- 这个最左前缀能够是联结索引的最左N个字段。比方组合索引(a,b,c)能够相当于建了(a),(a,b),(a,b,c)三个索引,大大提高了索引复用能力。
- 最左前缀也能够是字符串索引的最左M个字符。
因而给你ab,ac,abc字段,你能够间接加abc联结索引和ac联结索引即可。
8. 数据库隔离级别是否理解?你们的数据库默认隔离级别是?为什么选它?
四大数据库隔离级别,别离是读未提交,读已提交,可反复读,串行化(Serializable)。
- 读未提交:事务即便未提交,却能够被别的事务读取到的,这级别的事务隔离有脏读、反复读、幻读的问题。
- 读已提交:以后事务只能读取到其余事务提交的数据,这种事务的隔离级别解决了脏读问题,但还是会存在不可反复读、幻读问题;
- 可反复读:限度了读取数据的时候,不能够进行批改,所以解决了不可反复读的问题,然而读取范畴数据的时候,是能够插入数据,所以还会存在幻读问题。
- 串行化:事务最高的隔离级别,在该级别下,所有事务都是进行串行化程序执行的。能够防止脏读、不可反复读与幻读所有并发问题。然而这种事务隔离级别下,事务执行很耗性能。
MySQL抉择Repeatable Read(可反复读)作为默认隔离级别,咱们的数据库隔离级别选的是读已提交。
8.1 为什么MySQL的默认隔离离别是RR?
binlog的格局也有三种:statement,row,mixed。设置为statement格局,binlog记录的是SQL的原文。又因为MySQL在主从复制的过程是通过binlog进行数据同步,如果设置为读已提交(RC)隔离级别,当呈现事务乱序的时候,就会导致备库在 SQL 回放之后,后果和主库内容不统一。
比方一个表t,表中有两条记录:
CREATE TABLE t ( a int(11) DEFAULT NULL, b int(11) DEFAULT NULL, PRIMARY KEY a (a), KEY b(b) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; insert into t1 values(10,666),(20,233);
两个事务并发写操作,如下:
在读已提交(RC)隔离级别下,两个事务执行完后,数据库的两条记录就变成了(30,666)、(20,666)。这两个事务执行完后,binlog也就有两条记录,因为事务binlog用的是statement格局,事务2先提交,因而update t set b=666 where b=233优先记录,而update t set a=30 where b=666记录在前面。
当bin log同步到从库后,执行update t set b=666 where b=233和update t set a=30 where b=666记录,数据库的记录就变成(30,666)、(30,666),这时候主从数据不统一啦。
因而MySQL的默认隔离离别抉择了RR而不是RC。RR隔离级别下,更新数据的时候不仅对更新的行加行级锁,还会加间隙锁(gap lock)。事务2要执行时,因为事务1减少了间隙锁,就会导致事务2执行被卡住,只有等事务1提交或者回滚后能力继续执行。
并且,MySQL还禁止在应用statement格局的binlog的状况下,应用READ COMMITTED作为事务隔离级别。
咱们的数据库隔离级别最初选的是读已提交(RC)。
那为什么MySQL官网默认隔离级别是RR,而有些大厂抉择了RC作为默认的隔离级别呢?
- 晋升并发
RC 在加锁的过程中,不须要增加Gap Lock和 Next-Key Lock 的,只对要批改的记录增加行级锁就行了。因而RC的反对的并发度比RR高得多,
- 缩小死锁
正是因为RR隔离级别减少了Gap Lock和 Next-Key Lock 锁,因而它绝对于RC,更容易产生死锁。
9. RR隔离级别实现原理,它是如何解决不可反复读的?
9.1 什么是不可反复读
先回顾下什么是不可反复读。假如当初有两个事务A和B:
- 事务A先查问Jay的余额,查到后果是100
- 这时候事务B 对Jay的账户余额进行扣减,扣去10后,提交事务
- 事务A再去查问Jay的账户余额发现变成了90
事务A被事务B烦扰到了!在事务A范畴内,两个雷同的查问,读取同一条记录,却返回了不同的数据,这就是不可反复读。
9.2 undo log版本链 + Read View可见性规定
RR隔离级别实现原理,就是MVCC多版本并发管制,而MVCC是是通过Read View+ Undo Log实现的,Undo Log 保留了历史快照,Read View可见性规定帮忙判断以后版本的数据是否可见。
Undo Log版本链长这样:
Read view 的几个重要属性
- m_ids:以后零碎中那些沉闷(未提交)的读写事务ID, 它数据结构为一个List。
- min_limit_id:示意在生成Read View时,以后零碎中沉闷的读写事务中最小的事务id,即m_ids中的最小值。
- max_limit_id:示意生成Read View时,零碎中应该调配给下一个事务的id值。
- creator_trx_id: 创立以后Read View的事务ID
Read view 可见性规定如下:
- 如果数据事务IDtrx_id < min_limit_id,表明生成该版本的事务在生成Read View前,曾经提交(因为事务ID是递增的),所以该版本能够被以后事务拜访。
- 如果trx_id>= max_limit_id,表明生成该版本的事务在生成Read View后才生成,所以该版本不能够被以后事务拜访。
- 如果min_limit_id =<trx_id< max_limit_id,须要分3种状况探讨
3.1 如果m_ids蕴含trx_id,则代表Read View生成时刻,这个事务还未提交,然而如果数据的trx_id等于creator_trx_id的话,表明数据是本人生成的,因而是可见的。
3.2 如果m_ids蕴含trx_id,并且trx_id不等于creator_trx_id,则Read View生成时,事务未提交,并且不是本人生产的,所以以后事务也是看不见的;
3.3 如果m_ids不蕴含trx_id,则阐明你这个事务在Read View生成之前就曾经提交了,批改的后果,以后事务是能看见的。
9.3 RR 如何解决不可反复读
查问一条记录,基于MVCC,是怎么的流程
- 获取事务本人的版本号,即事务ID
- 获取Read View
- 查问失去的数据,而后Read View中的事务版本号进行比拟。
- 如果不合乎Read View的可见性规定, 即就须要Undo log中历史快照;
- 最初返回合乎规定的数据
假如存在事务A和B,SQL执行流程如下
在可反复读(RR)隔离级别下,一个事务里只会获取一次Read View,都是正本共用的,从而保障每次查问的数据都是一样的。
假如以后有一张core_user表,插入一条初始化数据,如下:
基于MVCC,咱们来看看执行流程
- A开启事务,首先失去一个事务ID为100
- B开启事务,失去事务ID为101
- 事务A生成一个Read View,read view对应的值如下
变量值m_ids100,101max_limit_id102min_limit_id100creator_trx_id100
而后回到版本链:开始从版本链中筛选可见的记录:
由图能够看出,最新版本的列name的内容是孙权,该版本的trx_id值为100。开始执行read view可见性规定校验:
min_limit_id(100)=<trx_id(100)<102;creator_trx_id = trx_id =100;
由此可得,trx_id=100的这个记录,以后事务是可见的。所以查到是name为孙权的记录。
- 事务B进行批改操作,把名字改为曹操。把原数据拷贝到undo log,而后对数据进行批改,标记事务ID和上一个数据版本在undo log的地址。
- 事务B提交事务
- 事务A再次执行查问操作,因为是RR(可反复读)隔离级别,因而会复用老的Read View正本,Read View对应的值如下
变量值m_ids100,101max_limit_id102min_limit_id100creator_trx_id100
而后再次回到版本链:从版本链中筛选可见的记录:
从图可得,最新版本的列name的内容是曹操,该版本的trx_id值为101。开始执行read view可见性规定校验:
min_limit_id(100)=<trx_id(101)<max_limit_id(102);因为m_ids{100,101}蕴含trx_id(101),并且creator_trx_id (100) 不等于trx_id(101)
所以,trx_id=101这个记录,对于以后事务是不可见的。这时候呢,版本链roll_pointer跳到下一个版本,trx_id=100这个记录,再次校验是否可见:
min_limit_id(100)=<trx_id(100)< max_limit_id(102);因为m_ids{100,101}蕴含trx_id(100),并且creator_trx_id (100) 等于trx_id(100)
所以,trx_id=100这个记录,对于以后事务是可见的,所以两次查问后果,都是name=孙权的那个记录。即在可反复读(RR)隔离级别下,复用老的Read View正本,解决了不可反复读的问题。
10. 你们我的项目应用了RocketMQ对吧?那你晓得如何保障音讯不失落吗?
一个音讯从生产者产生,到被消费者生产,次要通过这3个过程:
- 生产者产生音讯
- 音讯发送到存储端,保留下来
- 音讯推送到消费者,消费者生产完,ack应答。
因而如何保障MQ不失落音讯,能够从这三个阶段论述:
- 生产者保障不丢音讯
- 存储端不丢音讯
- 消费者不丢音讯
10.1 生产者保障不丢音讯
生产端如何保障不丢音讯呢?确保生产的音讯能顺利达到存储端。
如果是RocketMQ消息中间件的话,Producer生产者提供了三种发送音讯的形式,别离是:
- 同步发送
- 异步发送
- 单向发送
生产者要想发消息时保障音讯不失落,能够:
- 采纳同步形式发送,send音讯办法返回胜利状态,即音讯失常达到了存储端Broker。
- 如果send音讯异样或者返回非胜利状态,能够发动重试。
- 能够应用事务音讯,RocketMQ的事务音讯机制就是为了保障零失落来设计的
10.2 存储端不丢音讯
如何保障存储端的音讯不失落呢?确保音讯长久化到磁盘,那就是刷盘机制嘛。
刷盘机制分同步刷盘和异步刷盘:
- 同步刷盘:生产者音讯发过来时,只有长久化到磁盘,RocketMQ的存储端Broker才返回一个胜利的ACK响应。它保障音讯不失落,然而影响了性能。
- 异步刷盘:只有音讯写入PageCache缓存,就返回一个胜利的ACK响应。这样进步了MQ的性能,然而如果这时候机器断电了,就会失落音讯。
除了同步刷盘机制,还有一个维度须要思考。Broker个别是集群部署的,有主节点和从节点。音讯到Broker存储端,只有主节点和从节点都写入胜利,才反馈胜利的ack给生产者。这就是同步复制,它保障了音讯不失落,然而升高了零碎的吞吐量。与之对应即是异步复制,只有音讯写入主节点胜利,就返回胜利的ack,它速度快,然而会有性能问题。
10.3 生产阶段不丢音讯
消费者执行完业务逻辑,再反馈会Broker说生产胜利,这样才能够保障生产阶段不丢音讯。
11. 事务音讯是否理解?场景题:比方下单清空购物车,你是如何设计的?
事务音讯次要用来解决音讯生产者和音讯消费者的数据一致性问题。咱们先来回顾一下:一条一般的音讯队列音讯,从产生到被生产,经验的流程:
- 生产者产生音讯,发送到MQ服务器
- MQ收到音讯后,将音讯长久化到存储系统。
- MQ服务器返回ACk到生产者。
- MQ服务器把音讯push给消费者
- 消费者生产完音讯,响应ACK
- MQ服务器收到ACK,认为音讯生产胜利,即在存储中删除音讯。
音讯队列的事务音讯流程是怎么的呢?
- 生产者产生音讯,发送一条半事务音讯到MQ服务器
- MQ收到音讯后,将音讯长久化到存储系统,这条音讯的状态是待发送状态。
- MQ服务器返回ACK确认到生产者,此时MQ不会触发音讯推送事件
- 生产者执行本地事务
- 如果本地事务执行胜利,即commit执行后果到MQ服务器;如果执行失败,发送rollback。
- 如果是失常的commit,MQ服务器更新音讯状态为可发送;如果是rollback,即删除音讯。
- 如果音讯状态更新为可发送,则MQ服务器会push音讯给消费者。消费者生产完就回ACK。
- 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,而后依据查问到的后果执行最终状态。
咱们举个下订单清空购物车的例子吧。订单零碎创立完订单后,而后发消息给上游零碎购物车零碎,清空购物车。
- 生产者(订单零碎)产生音讯,发送一条半事务音讯到MQ服务器
- MQ收到音讯后,将音讯长久化到存储系统,这条音讯的状态是待发送状态。
- MQ服务器返回ACK确认到生产者,此时MQ不会触发音讯推送事件
- 生产者执行本地事务(订单创立胜利,提交事务音讯)
- 如果本地事务执行胜利,即commit执行后果到MQ服务器;如果执行失败,发送rollback。
- 如果是commit失常提交,MQ服务器更新音讯状态为可发送;如果是rollback,即删除音讯。
- 如果音讯状态更新为可发送,则MQ服务器会push音讯给消费者(购物车零碎)。消费者生产完(即拿到订单音讯,清空购物车胜利)就应答ACK。
- 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,而后依据查问到的后果(回滚操作或者从新发送音讯)执行最终状态。
有些搭档可能有纳闷,如果消费者生产失败怎么办呢?那数据是不是不统一啦?所以就须要消费者生产胜利,执行业务逻辑胜利,再反馈ack嘛。如果消费者生产失败,那就主动重试嘛,接口反对幂等即可。
12. 如何疾速判断一个数是奇数还是偶数,除开对2取余呢。
判断一个数是奇数还是偶数,咱们最容易想到的就是对2取余。
if( x % 2 )// 奇数else// 偶数
还有一种办法,就是与1相与( &1),具体实现如下:
if( x & 1 )// 奇数else// 偶数
13. Spring申明式事务原理?哪些场景事务会生效?
13.1 申明式事务原理
spring申明式事务,即@Transactional,它能够帮忙咱们把事务开启、提交或者回滚的操作,通过Aop的形式进行治理。
在spring的bean的初始化过程中,就须要对实例化的bean进行代理,并且生成代理对象。生成代理对象的代理逻辑中,进行办法调用时,须要先获取切面逻辑,@Transactional注解的切面逻辑相似于@Around,在spring中是实现一种相似代理逻辑。
13.2 spring申明式事务哪些场景会生效
- 办法的拜访权限必须是public,其余private等权限,事务生效
- 办法被定义成了final的,这样会导致事务生效。
- 在同一个类中的办法间接外部调用,会导致事务生效。
- 一个办法如果没交给spring治理,就不会生成spring事务。
- 多线程调用,两个办法不在同一个线程中,获取到的数据库连贯不一样的。
- 表的存储引擎不反对事务
- 如果本人try...catch误吞了异样,事务生效。
- 谬误的流传
14. 你们是微服务架构嘛?如果你来设计一个相似淘宝的零碎,你怎么划分微服务?
能够按业务畛域、性能、重要水平进行划分。
- 能够按业务畛域,把用户、社区、商品信息、音讯等模块等划分。
- 繁多性能职责,按性能拆分,比方订单、领取、物流、权限。
- 按重要水平划分,辨别外围和非核心性能,比方领取、订单就是外围性能。
15. 你们是怎么分库分表的?分布式ID如何生成?
如果是咱们公司的话,应用了程度分库的形式,就是一个用户注册时,就划分了属于哪个数据库,而后具体的表构造是一样的。
业界还有垂直分库,就是依照不同的零碎中的不同业务进行拆分,比方拆分成用户库、订单库、积分库、商品库,把它们部署在不同的数据库服务器。
分表的话也有程度分表和垂直分表,垂直分表就是将一些不罕用的、数据较大或者长度较长的列拆分到另外一张表,程度分表就是能够依照某种规定(如hash取模、range),把数据切分到多张表去。一张订单表,按工夫range拆分如下:
range划分利于数据迁徙,然而存在数据热点问题。hash取模划分,不会存在显著的热点问题,然而不利于扩容。能够range+hash取模联合应用。
分布式ID能够应用雪花算法生成
雪花算法是一种生成分布式全局惟一ID的算法,生成的ID称为Snowflake IDs。这种算法由Twitter创立,并用于推文的ID。
一个Snowflake ID有64位。
- 第1位:Java中long的最高位是符号位代表正负,负数是0,正数是1,个别生成ID都为负数,所以默认为0。
- 接下来前41位是工夫戳,示意了自选定的期间以来的毫秒数。
- 接下来的10位代表计算机ID,避免抵触。
- 其余12位代表每台机器上生成ID的序列号,这容许在同一毫秒内创立多个Snowflake ID。
16. 所有异样的独特的先人是?运行时异样有哪几个?
Java 异样的顶层父类是Throwable,它生了两个儿子,大儿子叫Error,二儿子叫Exception。
- Error:是程序⽆法解决的谬误,个别示意零碎谬误,例如虚拟机相干的谬误OutOfMemoryError
- Exception:程序自身能够解决的异样。它能够分为RuntimeException(运行时异样)和CheckedException(可查看的异样)。
什么是RuntimeException(运行时异样)?
运行时异样是不查看异样,程序中能够抉择捕捉解决,也能够不解决。这些异样个别是由程序逻辑谬误引起的,程序应该从逻辑角度尽可能防止这类异样的产生。
常见的RuntimeException异样:
- NullPointerException:空指针异样
- ArithmeticException:出现异常的运算条件时,抛出此异样
- IndexOutOfBoundsException:数组索引越界异样
- ClassNotFoundException:找不到类异样
- IllegalArgumentException(非法参数异样)
什么是CheckedException(可查看的异样)?
从程序语法角度讲是必须进行解决的异样,如果不解决,程序就不能编译通过。如IOException、SQLException等。
常见的 Checked Exception 异样:
- IOException:(操作输出流和输入流时可能呈现的异样)
- SQLException