关于异常处理,应该这么回答

近日一位小朋友遇到一个面试题:你能介绍一下你项目中的异常处理机制吗?

这位小朋友一听,很利索的就回答了try-catch-finally,再加上throw、throws。

乍一听起来这么回答也不错。但实际上面试官想听的并不是这个。

有的小朋友就说了,异常处理机制不就是这个么?如果您这么想,那就错喽,为何如此,且听我细细道来。

面试题本身问的是项目中的异常处理机制,关键就在于项目二字。项目中的异常处理可远不止如此呀,要做的事情还是挺多的。

如果面试官问你,请讲一讲Java中的异常处理,是不是答try-catch-finally,再加上throw、throws就OK了呢?

那我只能说,你最多够资格当个炮灰,去充充面试的人数。因为这么答太基础了。

那么项目中的异常处理机制应该怎么回答呢?咱得先来聊聊为什么要有异常处理机制。

相信下面两张图片程序员不会陌生:

 

 

但如果这个异常信息显示到一个普通用户的界面里面,你可以想像一下会是什么后果,用户的心里会怎么样?

我曾经的领导告诉我过,永远不把程序的异常信息让用户看到,因为这样会让用户感觉到恐慌,所以异常信息务必要处理掉。

而程序中如果要想把所有的异常信息都处理掉,永远不让用户看到,其实也不算很难,你只要把所有的代码都放在try-catch里面,然后catch块什么都不做就OK了。

那位说了这么做能行吗?

我还就告诉你,我还真见过一位这么干的主,那是2004年左右,那会儿我们做的是一个VB写的windows程序,当时的软件如果报了错误,程序是会崩溃直接挂掉的,现在很多程序也偶尔会突然出现突然闪退的情况, 那个时候,程序如果崩溃是会先弹出一大堆英文异常信息,然后再关闭程序,有可能用户使用程序干了一半的活数据就丢了,还得再搞一遍,弄不好程序员会被人骂死的。

可这位爷,人家写的代码“质量”是真好,永远不会崩溃,后来我接手他的活,去修复BUG,当时出现的问题是不知道什么原因,“有时候”程序点了没反应。碰到“有时候”程序会出问题的情况是最他喵的崩溃的,因为你不确定什么情况会出错,当时一看代码我就疯了,人家所有的代码全在try块里。如果程序处理出现错误直接catch,在catch块里什么也不处理,也没有日志,也没有提示,程序出了什么错误,谁都不知道,要想知道为什么出错,你只能想办法把错误场景还原,并且还得用编程工具去调试代码才能知道错误信息。

你要知道错误信息对于程序员找BUG是非常重要的。所以这么干是让用户爽了,但是对于程序员来说是要疯掉的。当时一看这种情况没办法,只能到现场去,于是出差400公里,到了客户现场,跟着客户一起用了一天的程序,才找到出错的原因,而改代码3分钟搞定。为此,公司多付出1000块钱的差旅成本,就为解决这么一个3分钟就搞定的BUG,而当时如果有异常信息或错误日志的话,根本不需要出这趟差。

现在你知道为什么项目中的异常处理很重要了吗?而有经验的面试官从你项目中异常处理的方法也能看出来你之前的工作中养成了什么样的工作习惯,和解决问题的思路,也能够从侧面了解到你之前的工作中的规范意识。

那么作为程序员,如何回答这个问题,才能让面试官更加青睐呢?

先别急,咱们先来聊一聊项目中的异常处理机制都要考虑什么问题。

第一:要考虑用户界面友好,不能够让用户界面出现大面积的异常信息,让用户感觉到恐慌。

第二:要方便收集错误信息,异常日志。

第三:出现异常是否需要对工作数据做出处理

第四:其它业务逻辑问题

以上四点呢,对于不喜欢卷的程序员呢,能够考虑到前两点已经比较OK了,对于比较卷的程序员呢,就要多准备一些。下面呢,咱一条一条的缕。

先看第一点,现在的系统,大部分都是WEB项目,对于页面请求的话,最简单的就是使用自定义错误页面,具体的内容的搜索tomcat自定义错误页面即可。

但是现在很多项目都是前后端分离的,用户访问的页面请求一般是不会由Java来处理的,Java处理的一般是后台接口,这种情况下就复杂一些,前端和后端都需要处理。

首先是后端的问题,一般情况下前后端分离的项目后端需要对返回的数据格式进行封装,比如当你需要返回一个user对象的时候,可以直接返回下面的Json数据:

{userName:'Tom',userId:1,gender:'male'}

而在项目中通常会返回类似这样的Json数据:

{   data:{userName:'Tom',userId:1,gender:'male'}//前端真正需要的业务数据   code:200,//项目封装的请求状态码,具体的代码表示的含义可以自己定义   errorMessage:''//出现错误的时候返回的错误信息,可以用来提示给用户,往往是比较友好的提示信息}

具体怎么实现这一点呢。大家可以搜索Java返回值封装,有很多文章可以参考。

后端异常处理怎么做呢?简单的办法呢,可以用一个全局异常处理类来解决这个问题,具体怎么实现大家可以搜索Java 全局异常处理类,这个东西解决的是项目中不论任何地方,只要出现错误,都由全局异常处理类来统一处理,可以让返回前端的数据经过人性化的处理,不再返回一大堆Java调用堆栈,让用户一看就恐惧。

还有正常情况下报错了会返回HTTP状态码500,经过全局异常处理,可以让他返回200。而具体的错误代码放在上面例子中的code里面,由前端统一来去处理。

下面来说说前端怎么处理,现在的前端技术栈有用Vue的,有用React的,有用Layui的,不管用什么前端技术,只要是前后分离,如果后端接口出错,在前端的代码中也都需要进行异常处理,但如果在每次调用接口的地方进行处理就太麻烦了。所以前端一样也可以做全局异常处理,如果后端接口出错,可以让前端弹出统一的错误提示信息。这样业务代码中就只需要处理正常的业务代码即可,开发效率也会大大提升。

那位程序员小哥说了,咱是搞Java后端开发的,需要前端也会吗?我说想,你想当个菜鸟程序员,可以不会,你想多赚点钱,还真得会。优秀的后端程序员必然也是能做前端的,你可以不精通,不知道细节,至少你得知道思路。

再来说第二点:收集错误信息和异常日志

这个呢比较简单一些的做法呢,可以在全局异常处理中可以把异常信息记录下来。存放到一个固定的异常日志文件中即可,如果出现错误,上服务器上去查异常日志即可。

当然了卷一点的同学可以思考下面一个问题:服务器上的错误日志应该不是谁都有权限查的吧,如果程序员没有查日志的权限的话,岂不是很麻烦?那怎么办呢?

如果要考虑程序员排查错误日志的因素的话,那么就可以考虑把异常信息保存到一个独立的系统中,如果出错,程序员可以登录这个系统中查看错误信息,具体的方案的有一个比较典型的就是ELK,具体的内容大家自行BAIDU。

除了要记录异常信息以外,有的时候咱还得考虑的更多一些,比如最常见的NPE错误,这种错误排查起来还是非常麻烦的,因为调用堆栈中只显示哪行代码出现错误,不会显示是哪个对象是null,在最新版的JDK新特性中貌似异常信息可以提示这个,但老版本还是不行。要想排查出来很多时候我们可能还需要记录一下请求的数据是什么,所以除了异常的信息、调用堆栈以外,为了便于排查错误,咱还可以把请求的数据,甚至于用户信息也记录下来,保存的越完整,排查起来就越方便。

下面说说第三点,出现异常是否需要对工作数据做出处理。

什么意思呢?举个简单的例子,有些请求的业务是需要做事务处理的,对于一般的项目来说,正常的使用事务即可,对于比较卷,想拿个几十K OFFER的同学,那只回答这些就比较普通了,如果你的项目能够用得上分布式事务的话,对于分布式事务的处理会稍微复杂一些。如果你点到这里的话,极有可能把面试官的兴趣点引到分布式事务那里。

继续第四点,有没有其它业务逻辑需要处理。

对于单体应用来说,出现异常情况一个事务大部分问题都解决了,而对于多系统之间的协作的话就比较麻烦了,比如最典型的支付场景,这个就涉及到自己项目和支付平台之间了,比如在支付的环节中,已经调用了支付平台,然后报了异常,支付的结果怎么样,你是不知道的。那么这时候是撤销事务,还是提交事务呢,都不能保证100%正确。而支付平台的话一般都会提供一种对帐机制,也就是如果出现异常,支付平台会提供一个接口让你查询某一笔支付请求是否成功,也有一些平台提供的是每天进行一次对帐。

对于这种异常处理,你就需要安排专门的程序来进行特殊业务的后续处理了,具体的就要具体去分析。

今天只讲了一下异常处理机制这个面试题回答思路方面的问题,具体的内容涉及的不算少,大家还需要去查阅一些其它的资料。除了这些内容之外,还有一部分内容可以讲,就是关于Java异常处理机制里面的Exception继承链的问题,以及自定义异常类在项目中的使用,面试中其实极少能问到这种程度的,所以小概率事件咱先不讲了,以后有要机会再单独开一篇文章去说。

说到这里,项目中常见的异常处理基本能覆盖到90%了,前面也说了,如果你想做一个比较卷的程序员,就得多了解一些,如果不想那么累,这个问题,你至少也要能把前两点搞明白了,那么这个问题一样可以加分不少。

最后希望大家都能找到满意的工作。

今天的卷王程序员关键词:

JDK14新特性NPE

ELK

自定义错误页面

分布式事务

文章作者:洛阳北大青鸟人力总监姚老师

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值