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. Python使用pip安装TensorFlow模块

    1.首先确保已经安装python,然后用pip来安装matplotlib模块. 2.进入到cmd窗口下,建议执行python -m pip install -U pip setuptools进行升级. ...

  2. Linux——查询服务器公网IP

    前言 服务器查看IP,十分简单,但是如何查看公网IP呢? 步骤 网站:http://www.cip.cc/ 命令行查询(详细): UNIX/Linux: #curl cip.cc Windows: & ...

  3. nginx和ftp搭建图片服务器

    一.需要的组件 图片服务器两个服务: Nginx(图片访问): 1.http服务:可以使用nginx做静态资源服务器.也可以使用apache.推荐使用nginx,效率更高. 2.反向代理 实现 负载均 ...

  4. js添加触摸时间,禁止页面缩放

    <meta name="viewport" content="target-densitydpi=320,width=640,user-scalable=no&qu ...

  5. django.db.models.fields.related_descriptors.RelatedObjectDoesNotExist: Course has no coursedetail.

    错误描述: 一对一反向查询失败! 前提: Course和CourseDetail    OneToOne 原因: Course数据和CourseDetail数据没有一一对应.

  6. Dubbo源码分析:设计总结

    设计原则 1.   多用组合,少用继承 2.   针对接口编程,不针对实现编程 3.   依赖抽象,不要依赖具体实现类. 设计模式 1.   策略设计模式:Dubbo扩展Spring的xml标签解析 ...

  7. L1025

    1,对于搜索,我有一个不成熟的想法,这不就是,强化版的for循环吗? 2,反正是搜索,那就先找搜索状态, n,x,n是第几次分,x是分剩下的数. 3,这个我觉得自己努力努力可能可以做出来. 4,首先要 ...

  8. 《RabbitMQ 实战》读书笔记

    MQ的好处: 1.业务上接口(系统扩展性变强) 2.性能提升(同步变异步,效率提高,还方便做负载均衡) 3.技术兼容(可以连接各种不同语言的系统,作为粘合剂) 读书笔记: 1.消息队列的应用场景:系统 ...

  9. USACO 2009 Open 干草塔 Tower of Hay

    USACO 2009 Open 干草塔 Tower of Hay Description 为了调整电灯亮度,贝西要用干草包堆出一座塔,然后爬到牛棚顶去把灯泡换掉.干草 包会从传送带上运来,共会出现N包 ...

  10. Error:(1, 1) java: 非法字符: '\ufeff'

    找到 java 文件. 使用 notepad 打开,转码,并保存即可.