后知后觉,那些码了百万行代码后才知道的低级错误!!!

菜鸟的成长是艰辛的,是不堪的,是独自打拼的。但是请你和我一样不要放弃,先看下博主自己喜欢的这个小故事:

                   《卖油翁》宋.欧阳修陈康肃公尧咨善射,当世无双 ,公亦以此自矜。尝射于家圃,有卖油翁释担而立,睨之,久而不去。见其发矢十中八九,但微颔之。康肃问曰:”汝亦知射乎?吾射不亦精乎?”翁曰:”无他, 但手熟尔。”康肃忿然曰:”尔安敢轻吾射!”翁曰:”以我酌油知之。”乃取一葫芦置于地,以钱覆其口,徐以杓酌油沥之,自钱孔入,而钱不湿。因曰:”我亦无他,唯手熟尔。”康肃笑而遣之。此与庄生所谓解牛斫轮者何异?

这是一篇浅显的文言文,初中水平,相信大家都能看懂吧,具体意思不做详细说明,我想让你记住的是“无他,但手熟尔”。

世界上哪有那么多的天赋秉异的编码高手,每个人光鲜的背后都是努力的汗水,大学时教我java基础的老师曾在课堂上说过:“你亲自敲过的代码不会背叛你”。愿你我共勉吧。

当你亲自参与项目,并实际编码行数超过100W行时(不用追求精确啦,只是为了说明量大的泛指),你会渐渐明白并且尝试去规避一些低级错误,尽管这些错误在刚入门时觉得理所当然。

- 1.多次频繁操作字符串时,不要使用String类进行字符串的拼接

循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
说明:下例中,反编译出的字节码文件显示每次循环都会 new 出一个 StringBuilder 对象,
然后进行 append 操作,最后通过 toString 方法返回 String 对象,造成内存资源浪费。
反例:

String str = "start";
for (int i = 0; i < 100; i++) {
str = str + "hello";
}

- 2.使用集合转数组的方法,必须使用集合的 toArray(T[] array)

使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()。
说明:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配
内存空间,并返回新数组地址;如果数组元素个数大于实际所需,下标为[ list.size() ]
的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集
合元素个数一致。
正例:

List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);

反例:

直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它
类型数组将出现 ClassCastException 错误。

- 3.不要在 foreach 循环里进行元素的 remove/add 操作。remove 元素请使用 Iterator方式,如果并发操作,需要对 Iterator 对象加锁。

正例:

List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (删除元素的条件) {
iterator.remove();
}
}

反例:

for (String item : list) {
if ("1".equals(item)) {
list.remove(item);
}
}

说明:以上代码的执行结果肯定会出乎大家的意料,那么试一下把“1”换成“2”,会是同样的结果吗?

- 4.使用 entrySet 遍历 Map 类集合 KV,而不是 keySet 方式进行遍历。

说明:keySet 其实是遍历了 2 次,一次是转为 Iterator 对象,另一次是从 hashMap 中取出key 所对应的 value。而 entrySet 只是遍历了一次就把 key 和 value 都放到了 entry 中,效率更高。如果是 JDK8,使用 Map.foreach 方法。
正例:
values()返回的是 V 值集合,是一个 list 集合对象;keySet()返回的是 K 值集合,是一个 Set 集合对象;entrySet()返回的是 K-V 值组合集合。

- 5.对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁

说明:线程一需要对表 A、B、C 依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是 A、B、C,否则可能出现死锁。

- 6.在高并发场景中,避免使用”等于”判断作为中断或退出的条件。

说明:如果并发控制没有处理好,容易产生等值判断被“击穿”的情况,使用大于或小于的区间判断条件来代替。
反例:判断剩余奖品数量等于 0 时,终止发放奖品,但因为并发处理错误导致奖品数量瞬间变成了负数,这样的话,活动无法终止

- 7.代码修改的同时,注释也要进行相应的修改,尤其是参数、返回值、异常、核心逻辑等的修改

说明:代码与注释更新不同步,就像路网与导航软件更新不同步一样,如果导航软件严重滞后,就失去了导航的意义。

- 8.注意 Math.random() 这个方法返回是 double 类型,注意取值的范围 0≤x<1(能够取到零值,注意除零异常),如果想获取整数类型的随机数,不要将 x 放大 10 的若干倍然后取整,直接使用 Random 对象的 nextInt 或者 nextLong 方法。

- 9.获取当前毫秒数 System.currentTimeMillis(); 而不是newDate().getTime();

说明:如果想获取更加精确的纳秒级时间值,使用 System.nanoTime()的方式。在 JDK8 中,针对统计时间等场景,推荐使用 Instant 类。

- 10.catch 时请分清稳定代码和非稳定代码,稳定代码指的是无论如何不会出错的代码。对于非稳定代码的 catch 尽可能进行区分异常类型,再做对应的异常处理。

说明:对大段代码进行 try-catch,使程序无法根据不同的异常做出正确的应激反应,也不利于定位问题,这是一种不负责任的表现。
正例:用户注册的场景中,如果用户输入非法字符,或用户名称已存在,或用户输入密码过于简单,在程序上作出分门别类的判断,并提示给用户。

- 11.不要在 finally 块中使用 return。

说明:finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句。

- 12.避免出现重复的代码(Don’t Repeat Yourself),即 DRY 原则。

说明:随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是组件化。

正例:一个类中有多个 public 方法,都需要进行数行相同的参数校验操作,这个时候请抽取:
private boolean checkParam(DTO dto) {...}

- 13.不要使用 count(列名)或 count(常量)来替代 count(),count()是 SQL92 定义的标准统计行数的语法,跟数据库无关,跟 NULL 和非 NULL 无关

说明:count(*)会统计值为 NULL 的行,而 count(列名)不会统计此列为 NULL 值的行。

- 14.使用 ISNULL()来判断是否为 NULL 值。

说明:NULL 与任何值的直接比较都为 NULL。
1) NULL<>NULL 的返回结果是 NULL,而不是 false。
2) NULL=NULL 的返回结果是 NULL,而不是 true。
3) NULL<>1 的返回结果是 NULL,而不是 true。

- 15.在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。

说明:
1)增加查询分析器解析成本。
2)增减字段容易与 resultMap 配置不一致。
3)无用字段增加网络消耗,尤其是 text 类型的字段。

后知后觉,那些码了百万行代码后才知道的低级错误!!!相关推荐

  1. 押错宝!一次性将百万行代码从 Flow 迁移至 TypeScript

    作者 | Caleb Meredith,Andrew Wang 译者 | 弯月      责编 | 欧阳姝黎 出品 | CSDN(ID:CSDNnews) 以下为译文: 最近,为了紧跟时代发展的脚步, ...

  2. 如何使用事务码SMICM分析ABAP代码发起的HTTP请求的错误

    当我用CL_HTTP_CLIENT往一个外网的url发请求时,遇到错误:ICM_HTTP_SSL_PEER_CERT_UNTRUSTED 错误是从这段ABAP代码里抛出来的: CALL METHOD ...

  3. 一台微型计算机_Linux的上百万行代码,一台新的微型计算机以及Google和Microsoft的更多产品

    一台微型计算机 在本周的开源新闻摘要中,我们介绍了用于Linux的一百万行代码,来自Google和Microsoft的更多开源软件,用于教育的新型微型计算机等等! 开源新闻:2015年7月4日至7月1 ...

  4. ONAP如何将Open-O和ECOMP数百万行代码合并?

    今年2月份,Linux基金会旗下两大开源MANO工作组Open-O和ECOMP日前宣布正式合并成为一个组织,开放网络自动化平台(ONAP). 早在去年,AT&T就谋求将其生产环境中使用的ECO ...

  5. .net 本地文件管理 代码_如何在百万行代码中发现隐藏的后门

    试想一下,如果你的网站被入侵,攻击者留下隐藏的后门,你真的都可以找出来嘛?面对一个大中型的应用系统,数以百万级的代码行,是不可能做到每个文件每段代码进行手工检查的. 即使是一款拥有99.9%的Webs ...

  6. 专业程序员必知必会的技巧:驯服复杂代码

    你从入职第一天起就要应对复杂代码. 若是还未遇到过无法理解的程序,那说明你编程的年头还不够长.在行业里,要不了多久你就会碰到让人发懵的混乱代码:巨兽.面条工厂.来自地狱的遗留系统.我曾接手过一个程序, ...

  7. 重新学习计算机基础理论知识(后知后觉)

    在写了几年代码之后,才知道有软考这样的考试存在:在写了很多逻辑之后,总是对计算机如何处理程序几无所知:在大学时学的东西完全没有了印象和记忆,程序一旦开始运行就好像丢进自动贩卖机的硬币一样再也看不到它的 ...

  8. 后知后觉-观sicp

    当我看到sicp P25里计算Fibnacci的一种迭代计算方法 a<-a+b b<-a 明显是错误的,或许我们应该只领会精神就可以了? 正确的应该是 tmp <- a+b b &l ...

  9. 这个世界依聪明才智的先天高下得三种人:先知先觉的发明家,后知后觉的宣传家,不知不觉的实践家...

    这个世界依聪明才智的先天高下得三种人:先知先觉的发明家,后知后觉的宣传家,不知不觉的实践家

  10. 亲述真实经历--“人工智能培训机构”的“坑”,希望更多像我这样的人不要吃了第一次亏才后知后觉

    作为有血泪教训,经历过两次人工智能培训,想转行到AI的人,揭露业界存在的陷阱,希望大家不要像我这样第一次吃亏了才后知后觉,大家一起交流学习,不要掉坑里! 当你去咨询培训机构并询问他们是否有真正的项目时 ...

最新文章

  1. rabbitmq之partitions
  2. python嵌入html_Python odoo中嵌入html简单的分页功能
  3. T511K表之工资常量SIINS的用途
  4. Python3 透明网桥算法
  5. 获取class文件对象三种方式
  6. kaggle提交前预估本地cv和LB上的score是否相差很大
  7. sklearn.metrics.mean_absolute_error
  8. C++调用MATLAB函数
  9. JDK 11 将引入低延迟 GC,大幅度缩短 GC 暂停时长
  10. 英语句型之综合运用篇
  11. python——sort方法、sorted函数——排序
  12. ifc文件解析java_IFC标准 IFCWALLSTANDARDCASE参数说明
  13. Python 每日一题(计算数值和)
  14. [渝粤教育] 中山大学 健康评估 参考 资料
  15. 实型变量的定义和应用
  16. Mac 没有声音怎么恢复
  17. 北大中文核心期刊目录(2004年版)工业技术类
  18. 【转】完美:photoshop cs6 破解版下载[序列号+破解补丁+破解教程+官方原版]
  19. 负面营销 —— 是饮鸩止渴还是引爆流量
  20. 【odroid-xu3】 ODROID-XU3硬件连接和烧写过程

热门文章

  1. 通勤要多久?全国45个主要城市通勤报告出炉(附下载)
  2. 至少10亿元!默克宣布将新增电子科技业务在华投资;Infosys被评为全球增长最快的IT服务品牌 | 全球TMT...
  3. VsCode 配置cmd 终端
  4. PT14-48页互联网绿色年终总结汇报晋升述职数据图表PPT模板
  5. mysql查询条件不区分大小写
  6. c++入门第一课,了解c++,致敬经典 hello word
  7. 《费尔玛大定理》我之所感!(转)
  8. ODOO系统管理固定资产需要解决的六大业务操作内容
  9. 初窥Linux 之 我最常用的20条命令(转)
  10. 逃难之旅(爱思创算法三)(期中测试)