最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化

File file = new File(“./tmp.txt”);
inputStream = new FileInputStream(file);
// use the inputStream to read a file
// do NOT do this
inputStream.close();
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
}
上述代码在没有任何exception的时候运行是没有问题的。但是当try块中的语句抛出异常或者自己实现的代码抛出异常,那么就不会执行最后的关闭语句,从而资源也无法释放。
合理的做法则是将所有清理的代码都放到finally块中或者使用try-with-resource语句。
public void closeResourceInFinally() {
FileInputStream inputStream = null;
try {
File file = new File(“./tmp.txt”);
inputStream = new FileInputStream(file);
// use the inputStream to read a file
} catch (FileNotFoundException e) {
log.error(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
log.error(e);
}
}
}
}
public void automaticallyCloseResource() {
File file = new File(“./tmp.txt”);
try (FileInputStream inputStream = new FileInputStream(file)😉 {
// use the inputStream to read a file
} catch (FileNotFoundException e) {
log.error(e);
} catch (IOException e) {
log.error(e);
}
}
二、指定具体的异常
=========
尽可能的使用最具体的异常来声明方法,这样才能使得代码更容易理解。
public void doNotDoThis() throws Exception {
…
}
public void doThis() throws NumberFormatException {
…
}
如上,NumberFormatException字面上即可以看出是数字格式化错误。
三、对异常进行文档说明
===========
当在方法上声明抛出异常时,也需要进行文档说明。和前面的一点一样,都是为了给调用者提供尽可能多的信息,从而可以更好地避免/处理异常。异常处理的 10 个最佳实践,这篇也推荐看下。
在Javadoc中加入throws声明,并且描述抛出异常的场景。
/**
* This method does something extremely useful …
* @param input
* @throws MyBusinessException if … happens
*/
public void doSomething(String input) throws MyBusinessException {
…
}
四、抛出异常的时候包含描述信息
===============
在抛出异常时,需要尽可能精确地描述问题和相关信息,这样无论是打印到日志中还是监控工具中,都能够更容易被人阅读,从而可以更好地定位具体错误信息、错误的严重程度等。
但这里并不是说要对错误信息长篇大论,因为本来Exception的类名就能够反映错误的原因,因此只需要用一到两句话描述即可。
try {
new Long(“xyz”);
} catch (NumberFormatException e) {
log.error(e);
}
NumberFormatException即告诉了这个异常是格式化错误,异常的额外信息只需要提供这个错误字符串即可。当异常的名称不够明显的时候,则需要提供尽可能具体的错误信息。
五、首先捕获最具体的异常
============
现在很多IDE都能智能提示这个最佳实践,当你试图首先捕获最笼统的异常时,会提示不能达到的代码。当有多个catch块中,按照捕获顺序只有第一个匹配到的catch块才能执行。因此,如果先捕获IllegalArgumentException,那么则无法运行到对NumberFormatException的捕获。
public void catchMostSpecificExceptionFirst() {
try {
doSomething(“A message”);
} catch (NumberFormatException e) {
log.error(e);
} catch (IllegalArgumentException e) {
log.error(e)
}
}
六、不要捕获Throwable
===============
Throwable是所有异常和错误的父类。你可以在catch语句中捕获,但是永远不要这么做。如果catch了throwable,那么不仅仅会捕获所有exception,还会捕获error。而error是表明无法恢复的jvm错误。因此除非绝对肯定能够处理或者被要求处理error,不要捕获throwable。
public void doNotCatchThrowable() {
try {
// do something
} catch (Throwable t) {
// don’t do this!
}
}
七、不要忽略异常
========
很多时候,开发者很有自信不会抛出异常,因此写了一个catch块,但是没有做任何处理或者记录日志。
public void doNotIgnoreExceptions() {
try {
// do something
} catch (NumberFormatException e) {
// this will never happen
}
}
但现实是经常会出现无法预料的异常或者无法确定这里的代码未来是不是会改动(删除了阻止异常抛出的代码),而此时由于异常被捕获,使得无法拿到足够的错误信息来定位问题。合理的做法是至少要记录异常的信息。
public void logAnException() {
try {
// do something
} catch (NumberFormatException e) {
log.error("This should never happen: " + e);
}
}
八、不要记录并抛出异常
===========
写在最后
为了这次面试,也收集了很多的面试题!
以下是部分面试题截图

}
八、不要记录并抛出异常
===========
写在最后
为了这次面试,也收集了很多的面试题!
以下是部分面试题截图
[外链图片转存中…(img-9JSmuXV0-1715287229412)]

被折叠的 条评论
为什么被折叠?



