《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 ...
随机推荐
- In-Memory:内存数据库
在逝去的2016后半年,由于项目需要支持数据的快速更新和多用户的高并发负载,我试水SQL Server 2016的In-Memory OLTP,创建内存数据库实现项目的负载需求,现在项目接近尾声,系统 ...
- 笔记:Binder通信机制
TODO: 待修正 Binder简介 Binder是android系统中实现的一种高效的IPC机制,平常接触到的各种XxxManager,以及绑定Service时都在使用它进行跨进程操作. 它的实现基 ...
- CRC、反码求和校验 原理分析
3月份开始从客户端转后台,算是幸运的进入全栈工程师的修炼阶段.这段时间一边是老项目的客户端加服务器两边的维护和交接,一边是新项目加加加班赶工,期间最长经历了连续工作三天只睡了四五个小时的煎熬,人生也算 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- docker for mac 学习记录
docker基本命令 docker run -d -p 80:80 --name webserver nginx 运行容器并起别名 docker ps 展示目前启动的容器 docker ps -a 展 ...
- 在 C# 里使用 F# 的 option 变量
在使用 C# 与 F# 混合编程的时候(通常是使用 C# 实现 GUI,F#负责数据处理),经常会遇到要判断一个 option 是 None 还是 Some.虽然 Option module 里有 i ...
- 数据图表插件Echarts(一)
一.引言 最近做一个智慧城市项目,项目中需要图表和报表进行数据分析,从网上找了很多,最后找到了百度开放的echarts,一个很强大的插件. 二.介绍 ECharts,缩写来自Enterprise Ch ...
- js callee,caller学习
原文地址:js callee,caller学习 /* * caller 返回一个对函数的引用,该函数调用了当前函数. * 如果函数是由顶层调用的,那么 caller包含的就是 null . * 如果在 ...
- python之最强王者(9)——函数
1.Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但 ...
- 最新的 cocoaPods 安装方法
经过努力终于发现了最新的 解决cocoaPods安装的办法: taobao Gems 源已停止维护,现由 ruby-china 提供镜像服务 第一步:安装rvm, 不管需不需要升级ruby,rvm可以 ...