1 String.split(String regex), 传入的参数是正则表达式,有一些特殊字符(比如.[]()\| 等)需要转义。

2  关于枚举类型,一般用作常量,理想情况下,枚举中的属性字段是私有的,并在私有构造函数中赋值,没有对应的 Setter 方法,最好加上 final 修饰符。

public enum PersonSex2 {
MALE("", "man"),
FEMALE("", "female"); // value/description用final,因为一般枚举类型被用作常量,不可以修改
private final String value; // value可以是其他类型,一般用int
private final String description; // description 一般用String。 // 构造函数用private,是因为不想在外部被实例化。
private PersonSex2(String value, String description) {
this.value = value;
this.description = description;
} // 只有get方法,没有set方法,是因为不会setter。
public String getValue() {
return value;
} public String getDescription() {
return description;
}
}

3 返回空数组和空集合而不是 null

  返回 null ,需要调用方强制检测 null ,否则就会抛出空指针异常。返回空数组或空集合,有效地避免了调用方因为未检测 null 而抛出空指针异常,还可以删除调用方检测 null 的语句使代码更简洁。

    public static List<String> getResults() {
return new ArrayList<>(0);
} public static List<String> getResultList() {
return Collections.emptyList();
} public static Map<String, String> getResultMap() {
return Collections.emptyMap();
}

禁止使用构造方法 BigDecimal(double)

  浮点数进行计算,有精度损失,不准确,如下(Java中float的精度为6-7位有效数字。double的精度为15-16位):

System.out.println(0.05 + 0.01);
System.out.println(1.0 - 0.42);
System.out.println(4.015 * 100);
System.out.println(123.3 / 100); 0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999
很有可能造成我们手中有0.06元,却无法购买一个0.05元和一个0.01元的商品。因为如上所示,他们两个的总和为0.060000000000000005。这无疑是一个很严重的问题,尤其是当电商网站的并发量上去的时候,出现的问题将是巨大的。可能会导致无法下单,或者对账出现问题
 
在《Effective Java》中提到一个原则,那就是float和double只能用来作科学计算或者是工程计算,但在商业计算中我们要用java.math.BigDecimal,通过使用BigDecimal类我们可以解决上述问题。
 
我们在使用BigDecimal时,使用它的BigDecimal(String)构造器创建对象才有意义。其他的如BigDecimal b = new BigDecimal(1)这种,还是会发生精度丢失的问题 BigDecimal a = new BigDecimal(1.01);
 BigDecimal b = new BigDecimal(1.02);
BigDecimal c = new BigDecimal("1.01");
BigDecimal d = new BigDecimal("1.02");

System.out.println(a.add(b)); // a和b是用float构造的,也有精度损失
System.out.println(c.add(d)); // c和d是用String 类型构造的,没有精度损失 2.0300000000000000266453525910037569701671600341796875
2.03
long可以准确存储19位数字,而double只能准备存储16位数字。double由于有exp位(次方),可以存16位以上的数字,但是需要以低位的不精确作为代价。如果需要高于19位数字的精确存储,则必须用BigInteger来保存,当然会牺牲一些性能。所以我们一般使用BigDecimal来解决商业运算上丢失精度的问题的时候,声明BigDecimal对象的时候一定要使用它构造参数为String的类型的构造器。
  float和double只能用来做科学计算和工程计算。商业运算中我们要使用BigDecimal
     
用BigDecimal value = BigDecimal.valueOf(0.1D)代替BigDecimal value = new BigDecimal(0.1D);
在实际中,DB中存储的一般是float和doubel类型的,需要转换成为String再用,所以这里从网上抄袭了一个工具类,仅供参考:
/**
* @author: Ji YongGuang.
* @date: 19:50 2017/12/14.
*/
public class BigDecimalUtil { private BigDecimalUtil() { } public static BigDecimal add(double v1, double v2) {// v1 + v2
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2);
} public static BigDecimal sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2);
} public static BigDecimal mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2);
} public static BigDecimal div(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
// 2 = 保留小数点后两位 ROUND_HALF_UP = 四舍五入
return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);// 应对除不尽的情况
}
}

5 过时代码添加 @Deprecated 注解

不要用NullPointerException判断空

  空指针异常应该用代码规避(比如检测不为空),而不是用捕获异常的方式处理。

public String getUserName(User user) {
if (Objects.isNull(user)) {
return null;
}
return user.getName();
}

 在JDK7版本的时候,Java引入了java.util.Objects工具类,用于封装一些平时使用频度很高或容易出错的操作,这些操作形成了Objects的各个方法,下来我们来看看这些方法。

equals()

public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

有别于Object.equals()这个方法可以避免空指针异常。

deepEquals()

Object.equals()用于比较两个对象的引用是否相同,而deepEquals()却扩展成了可以支持数组

toString()

归根结底,其内部最终调用了对象的toString()方法。额外多了空指针判断

compare()

用于比较两个对象。

requireNonNull()

在对象为空指针时,抛出特定message的空指针异常

isNull() 和 nonNull()

这两个方法用于判断对象为null和对象不为null。通常情况下,我们不会直接使用这两个方法,而是使用比较操作符==!=。这两个方法主要用在jdk8开始支持的流计算里面。

7 公有静态常量应该通过类访问

  而不是用实例去访问,因为容易让人误解,以为每一个实例有一个静态常量。

8 用 catch 语句捕获异常后,什么也不进行处理,就让异常重新抛出,这跟不捕获异常的效果一样(因为如果异常不捕获,就会一直往上层函数抛),可以删除这块代码或添加别的处理。

工具类应该屏蔽构造函数

  工具类是一堆静态字段和函数的集合,不应该被实例化。但是,Java 为每个没有明确定义构造函数的类添加了一个隐式公有构造函数。所以,为了避免 java "小白"使用有误,应该显式定义私有构造函数来屏蔽这个隐式公有构造函数。

10 建议使用 try-with-resources 语句更优雅的关闭资源

传统的关闭资源的方式:在finally中判断,如果资源句柄不是NULL,关闭,而且还有再catch exception

private void handle(String fileName) {
BufferedReader reader = null;
try {
String line;
reader = new BufferedReader(new FileReader(fileName));
while ((line = reader.readLine()) != null) {
...
}
} catch (Exception e) {
...
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
...
}
}
}
}

java 1.7后,如果关闭的资源实现了AutoCloseable接口,就可以使用更简洁的try-with-resources 

   public interface Closeable extends AutoCloseable
private void handle(String fileName) {
try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = reader.readLine()) != null) {
...
}
} catch (Exception e) {
...
}
}

11 频繁调用 Collection.contains 方法请使用 Set代替List,效率更高。

12 List 的随机访问

  大家都知道数组和链表的区别:数组的随机访问效率更高。当调用方法获取到 List 后,如果想随机访问其中的数据,并不知道该数组内部实现是链表还是数组,怎么办呢?可以判断它是否实现* RandomAccess *接口。

13 字符串拼接使用 StringBuilder  

   String: 拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有影响。

   StringBuilder: 一般的字符串拼接在编译期 java 会进行优化,但是在循环中字符串拼接, java 编译期无法做到优化,所以需要使用 StringBuilder 进行替换。性能好,但是线程不安全。

StringBuffer: 提供append和add方法,可以将字符串添加到已有序列的末尾或指定位置,它的本质是一个线程安全的可修改的字符序列,把所有修改数据的方法都加上了synchronized。但是保证了线程安全是需要性能的代价的

14 集合初始化尽量指定大小

  集合也是有大小限制的。每次扩容的时间复杂度很有可能是 O(n) ,所以尽量指定可预知的集合大小,能减少集合的扩容次数。

15 需要 Map 的主键和取值时,应该迭代 entrySet()

  当循环中只需要 Map 的主键时,迭代 keySet() 是正确的。但是,当需要主键和取值时,迭代 entrySet() 才是更高效的做法,比先迭代 keySet() 后再去 get 取值性能更佳。(经过测试,后一种比前一种是快)

       for (String key : map.keySet()) {
String value = map.get(key);
} for (Map.Entry<String, String> entry : map.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
}

java面试 (六)的更多相关文章

  1. [Java面试六]SpringMVC总结以及在面试中的一些问题.

    1.简单的谈一下SpringMVC的工作流程? 流程 1.用户发送请求至前端控制器DispatcherServlet 2.DispatcherServlet收到请求调用HandlerMapping处理 ...

  2. Java 面试知识点解析(六)——数据库篇

    前言: 在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Java 知识点进行复习和学习一番,大 ...

  3. Java面试准备十六:数据库——MySQL性能优化

    2017年04月20日 13:09:43 阅读数:6837 这里只是为了记录,由于自身水平实在不怎么样,难免错误百出,有错的地方还望大家多多指出,谢谢. 来自MySQL性能优化的最佳20+经验 为查询 ...

  4. JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结

    我是一名java开发人员,hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和 ...

  5. Java面试必备知识

    JAVA面试必备知识 第一,谈谈final, finally, finalize的区别. 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可 ...

  6. java面试和笔试大全 分类: 面试 2015-07-10 22:07 10人阅读 评论(0) 收藏

    2.String是最基本的数据类型吗? 基本数据类型包括byte.int.char.long.float.double.boolean和short. java.lang.String类是final类型 ...

  7. JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结(转)

    hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践中也应用过,现在对hibernate和mybatis做一下对比,便于大家更好的理解和学习,使自己在做项目中更加 ...

  8. java面试笔试大汇总

    java面试笔试题大汇总5 JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象:2.继承:3.封装:4. 多态性: 2.String是最基本的数据类型吗? 基本数据类型包括byte.int. ...

  9. Java 面试宝典-2017

    http://www.cnblogs.com/nelson-hu/p/7190163.html Java面试宝典-2017   Java面试宝典2017版 一. Java基础部分........... ...

  10. Java面试宝典-2017

    Java面试宝典2017版 一. Java基础部分........................................................................... ...

随机推荐

  1. 自动生成百度小程序sitemap.txt文件路径

    因为业务需要,需要在目前项目上开发一个百度小程序,百度智能小程序上线了,但是内容每天得推送,不可能一个小程序路径一个推送吧,因为小程序路径和项目路径不一致. 因为项目是用ThinkPHP开发的,在此附 ...

  2. YII2 使用curl请求,返回false

    一. 起因: 今天用yii框架,请求java接口,始终返回false. 二. 分析历程: 使用curl_error()方法打印出Peer’s Certificate issuer is not rec ...

  3. 9、Hadoop配置文件和HDFS垃圾回收

    配置文件 默认配置文件:相对应的jar包中 core-default.xml hdfs-default.xml yarn-default.xml mapred-default.xml 自定义配置文件 ...

  4. Deep Learning 简介

    机器学习算法概述参见:https://zhuanlan.zhihu.com/p/25327755 深度学习可以简单理解为NN的发展,二三十年前,NN曾经是ML领域非常火热的一个方向,后来慢慢淡出,原因 ...

  5. dinoql 支持自定义resovler了

    dinoql 当前版本0.4.0 支持自定义reovler 了,使用也比较简单 环境准备 初始化 yarn init -y 添加依赖 yarn add dinoql graphql-tag packa ...

  6. 移动端tap事件(轻击、轻触)

    一.问题 ①移动端也有click点击事件,click点击会延迟200~300ms ②因为点击的响应过慢,影响了用户体验,所以需要解决响应慢的问题 二.解决方案 ①使用tap事件:即轻击,轻敲,响应速度 ...

  7. cyyz: Day 2 线段树知识整理

    Day 2 上午的听课,哎~昏昏欲睡好吧.. 一.扫描线 知识点: 由于多边形千变万化,要想填充多边形内部的所有像素,需要找到一种合适的规则,能够沿着一个方向,一个像素不漏地把多边形内部填满,同时不污 ...

  8. NLP算法工程师(实习生)面试总结(持续更新)

    爱奇艺 1. attention<attention is all you need> 2. 相关项目 3. 逻辑回归 4. linux的指令(重命名文件,vim替换,vim指向文章最末行 ...

  9. Cocos CreatorUI系统下

    若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理. 请点赞!因为你们的赞同/鼓励是我写作的最大动力! 欢迎关注达叔小生的简书! 这是一个有质量 ...

  10. 原创:logistic regression实战(一):SGD Without lasso

    logistic regression是分类算法中非常重要的算法,也是非常基础的算法.logistic regression从整体上考虑样本预测的精度,用判别学习模型的条件似然进行参数估计,假设样本遵 ...