《Effective Java》学习笔记——积累和激励
从一个实际案例说起
国庆长假前一个礼拜,老大给我分配了这么一个bug,就是打印出来的报表数量为整数的,有的带小数位,有的不带,毫无规律。

根据短短的两个多月的工作经验以及猜测,最终把范围缩小到以下这段代码块(伪代码)
String output(double num){//double类型的参数num由DAO层提供
String result=null;
if(num等于num的整数部分)//例如12.0000等于12,13.0001不等于13
result=(将num的小数位全部删去,返回相应的字符串,例如12.0000经过处理后返回12);
else
result=(将num的小数位保留4位,返回相应的字符串,例如12.0010经过处理后返回12.0010);
return result;//字符串类型的返回值将直接输出到报表
}
double类型的传参让我想起了老大一直在向我强调说不要在存储过程中使用double类型的参数,因为可能会出现12.000000001这样的不精确数值,所以我在想问题应该是出现在这里。可是由于本地的数据没有出现这样的问题,所以我无法重现这个故障。于是就我将上面的代码做了小小的修改,问题就算是解决,更新到客户那里之后故障就再也没有出现过了。
String output(double num){//double类型的参数num由DAO层提供
String result=null;
num=(num取四位小数四舍五入返回,例如12.00000001返回12.0000)
if(num等于num的整数部分)//例如12.0000等于12,13.0001不等于13
result=(将num的小数位全部删去,返回相应的字符串,例如12.0000经过处理后返回12);
else
result=(将num的小数位保留4位,返回相应的字符串,例如12.0010经过处理后返回12.0010);
return result;//字符串类型的返回值将直接输出到报表
}
这就说明了工作经验的重要性。如果没有老大之前的提醒,我恐怕很难想到原因是出在这里(尤其是在故障无法在本地重现,用不了断点测试错误数据的情况下)。年轻人嘛,作为新手,好好积累经验,以后做起工作来就会越来越得心应手。同时,如果花了很多时间都没能解决某个问题,就要适当地问问自己的导师或者经验比自己丰富的同事,向他们求助。
过了几天任务没那么紧张闲了下来,翻开买了很久的《Effective Java》,惊奇地发现里面有这样的内容:
第48条:如果需要精确的答案,请避免使用float和double
书中写道:“float和doubble类型主要是为了科学计算和工程计算而设计的。它们执行二进制浮点运算(binary floating-point arithmetic),这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们并没有提供完全精确的结果,所以不应该被用于需要精确结果的场合。float和double类型尤其不适合用于货币计算,因为要让一个float或者double精确地表示0.1(或者10的任何其他负数次方值)是不可能的。”
假设我们口袋里有一块五,花掉三毛两分之后剩多少钱呢?写个程序试试看

工作经验需要一天天得积累,急不来,就算急也没有用。但是,我们可以通过看书,照样可以一定程度上弥补作为新人工作经验不足的短处。
看书的时候做实验会很有趣
(第51条)字符串连接操作符(+,string concatenation operator)是把多个字符串合并为一个字符串的便利途径。要想产生单独一行的输出,或者构造一个字符串来表示一个较小的、大小固定的对象,使用连接操作符是非常合适的,但是它不适合运用在大规模的场景中。为连接n个字符串而重复地使用字符串连接操作符,需要n的平方级的时间。这是由于字符串不可变而导致的不幸结果。当两个字符串被连接在一起时,它们的内容都要被copy。我们先来看一段代码
private static String statement() {
String result = "";
for (int i = 0; i < 20000; i++)
result += i;
return result;
}
如果运行的场景使得运算规模更大,这个方法执行时间就难以估算了。为了保证性能,该书作者建议我们使用StringBuilder替代String,来存储建造中的字符串。我们可以做一个实验看看
package org;
public class Testing {
public static void main(String[] args) {
long startMili=System.currentTimeMillis();//开始时刻对应的毫秒数
statement();
long endMili = System.currentTimeMillis();//结束时刻对应的毫秒数
System.out.println("实验1所用的时间是:"+(endMili-startMili)+"毫秒");
long startMili2=System.currentTimeMillis();
statement2();
long endMili2 = System.currentTimeMillis();
System.out.println("实验2所用的时间是:"+(endMili2-startMili2)+"毫秒");
}
private static String statement() {
String result = "";
for (int i = 0; i < 20000; i++)
result += i;
return result;
}
private static String statement2() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < 20000; i++)
result.append(i);
return result.toString();
}
}
运行结果如下(对比相当惊人):
实验1所用的时间是:1627毫秒
实验2所用的时间是:2毫秒
想象一下,如果工作中遇到这样的问题,恰好被所学过的知识解决了,这是一件多么痛快的事情。不仅大量地节省摸索的时间,还能够激励你花更多的精力投入到自学当中去。
(如果喜欢我写的东西,那就关注我的个人微信公众账号“华工小y”。每天都有好玩有趣的内容与你分享)
《Effective Java》学习笔记——积累和激励的更多相关文章
- Effective Java 学习笔记之第七条——避免使用终结(finalizer)方法
避免使用终结方法(finalizer) 终结方法(finalizer)通常是不可预测的,也是很危险的,一般情况下是不必要的. 不要把finalizer当成C++中析构函数的对应物.java中,当对象不 ...
- Effective Java学习笔记
创建和销毁对象 第一条:考虑用静态工厂方法替代构造器 For example: public static Boolean valueOf(boolean b){ return b ? Boolean ...
- Effective Java 学习笔记之所有对象都通用的方法
一.覆盖equals时请遵守通用约定 1.满足下列任何一个条件时,不需要覆盖equals方法 a.类的每个实例本质上都是唯一的.此时就是Object中equals方法所表达的含义. b.不关心类是否提 ...
- Effective Java 学习笔记之创建和销毁对象
一.考虑用静态工厂方法代替构造器 1.此处的静态工厂方法是指返回指为类的对象的静态方法,而不是设计模式中的静态工厂方法. 2.静态工厂方法的优势有: a.使用不同的方法名称可显著地表明两个静态工厂方法 ...
- Effective Java 学习笔记----第7章 通用程序设计
第7章 通用程序设计 第29条 将局部变量的作用域最小化 使一个局部变量的作用域最小化,最有力的技术室在第一次使用它的地方声明. 第30条 了解和使用库 效率提高.如果你不知道库 ...
- effective java学习笔记之不可实例化的类
在没有显式声明一个类的构造方法时,编译器会生成默认的无参构造方法,在设计工具类时,我们通常将方法设置成静态方法,以类名.方法名的形式调用,此时这个类就没有必要创建实例,我们知道抽象类不可以被实例化,但 ...
- Effective Java学习笔记--创建和销毁对象
创建和销毁对象 一.静态工厂方法代替构造器 静态工厂方法的优缺点 优点: 1.可以自定义名称(可以将功能表述的更加清晰) 2.不必每次调用都创建新的对象(同一对象重复使用) 3.返回的类型可以是原返回 ...
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
随机推荐
- “.Net 社区虚拟大会”(dotnetConf) 2016 Day 3 Keynote: Scott Hanselman
美国时间 6月7日--9日,为期三天的微软.NET社区虚拟大会正式在 Channel9 上召开,美国时间6.9 是第三天, Scott Hanselman 做Keynote.今天主题围绕的是.NET ...
- ExtJS 4.2 Date组件扩展:添加清除按钮
ExtJS中除了提供丰富的组件外,我们还可以扩展他的组件. 在这里,我们将在Date日期组件上添加一个[清除]按钮,用于此组件已选中值的清除. 目录 1. Date组件介绍 2. 主要代码说明 3. ...
- 15个关于Chrome的开发必备小技巧[译]
谷歌Chrome,是当前最流行且被众多web开发人员使用的浏览器.最快六周就更新发布一次以及伴随着它不断强大的开发组件,使得Chrome成为你必备的开发工具.例如,在线编辑CSS,console以及d ...
- js报错: Uncaught RangeError: Invalid string length
在ajax请求后得到的json数据,遍历的时候chrome控制台报这个错误:Uncaught RangeError: Invalid string length,在stackoverflow查找答案时 ...
- RIFF和WAVE音频文件格式
RIFF file format RIFF全称为资源互换文件格式(Resources Interchange File Format),是Windows下大部分多媒体文件遵循的一种文件结构.RIFF文 ...
- VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%
1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...
- 代码的坏味道(17)——夸夸其谈未来性(Speculative Generality)
坏味道--夸夸其谈未来性(Speculative Generality) 特征 存在未被使用的类.函数.字段或参数. 问题原因 有时,代码仅仅为了支持未来的特性而产生,然而却一直未实现.结果,代码变得 ...
- OSGi规范的C#实现开源
这是大约在3-4年前完成的一个C#实现的OSGi框架,实现的过程参照了OSGi规范与与一些实现思路(感谢当时的那些资料与项目),此框架虽然仅在几个小型项目有过实际的应用,但OSGi的规范实现还是相对比 ...
- Javascript学习笔记
Javascript 2016年12月19日整理 JS基础 Chapter1 JS是一门运行在浏览器客户端的脚本编程语言,前台语言 组成部分 1. ECMAscript JS标准 2. DOM 通过J ...
- 在Centos下搭建git并可以通过windows客户端访问
亲测在本地虚拟机和远程服务器上无问题,如有不懂请留言. 注意事项:以下所有操作是在root权限下操作的.1.Centos服务器版本centos6.5 2.首先安装git,使用yum在线安装 yum i ...