zoukankan      html  css  js  c++  java
  • java基础很重要

    前言

    上一篇博文已经是3个月以前的了,最近比较忙没有时间整理技术文档。在空闲的时间把《Java解惑》这本书读了一遍,感觉里面的挺有意思的,推荐一下。其实里面也没有什么高难度的东西,都是比较基础而又常常被忽略的知识点。在项目中可能用到的时候不多,但是对于分析问题却有很大的帮助。突然觉得自己的java基础很弱。下面收集了一些问题,希望和大家交流。

    1、《Java解惑》中的一个问题。

    这类问题基本上都是数值精度方面的。书中有这样一个例子:

    复制代码
    public class Main2 {
    
    public static void main(String[] args) {
    
    System.out.println(2.00-1.10);
    
    }
    
    }
    复制代码


     不经过分析就直接认为输出:0.9。最关键的不是结果是多少,而是过程。我意识到需要看看double的数据是如何存储的,当然也复习一下十进制转二进制。这些都太过于底层,但是必须了解才能正确地分析问题。

     书中的解释:“1.1不能被精确的表述为一个double”。

    这样的解释我觉得不好,如果这么解释的话,那么2.00+1.10是不是也可以这么解释呢?那为何结果又是精确的呢?那么2.00f-1.10f为何又没有问题,1.10f也不能精确被精确表述为一个float?网上也没有看到合理的解释,再看看基础吧。

     

    2、技术群里面的一个问题。

    考查synchronized 基础。

    复制代码
    public class Main3 extends Thread {
    
    public static int ticket = 10000;
    
     
    
    public static void main(String[] args) {
    
    while (ticket > 0) {
    
    Thread thread = new Main3();
    
    thread.start();
    
    }
    
    }
    
     
    
    @Override
    
    public void run() {
    
    subTicket();
    
    }
    
     
    
    private synchronized void subTicket() {
    
    if (ticket > 0) {
    
    System.out.print(ticket-- + "\t");
    
    }
    
    if (ticket % 10 == 0) {
    
    System.out.println();
    
    }
    
    }
    
    }
    复制代码

     

    看上去感觉是线程安全的,但实际却不是线程安全的,打印结果可以说明这个问题。仔细分析以后发现subTicket()方法确实不是同步的,虽然用了synchronized关键字。原因很简单他只是对对象进行了同步,但是方法里面却访问了类变量,所以这个方法应该改成对类进行同步,就这么简单。我总结了一下这个问题分析错误主要是因为对synchronized关键字不熟悉,说穿了就是基础不扎实,更主要的是太粗心,尤其是看到简单的问题就更粗心了。

     

    3、《深入理解java虚拟机》中的一个错误。

    下面是书中的程序。

    复制代码
    public class Main2 {
    
     
    
    static {
    
    if (true) {
    
    System.out.println(Thread.currentThread() + " init");
    
    while (true) {
    
    }
    
    }
    
    }
    
     
    
    public static void main(String[] args) {
    
     
    
    Runnable runnable = new Runnable() {
    
     
    
    @Override
    
    public void run() {
    
    System.out.println(Thread.currentThread() + " start");
    
    Main2 main2 = new Main2();
    
    System.out.println(Thread.currentThread() + " over");
    
    }
    
    };
    
    Thread r1 = new Thread(runnable);
    
    Thread r2 = new Thread(runnable);
    
     
    
    r1.start();
    
    r2.start();
    
    }
    
    }
    复制代码

    我分析以后的打印结果是:Thread[main,5,main] init。但是书中并不是这么说的,反正是错的。我在群里咨询、在网上也找了很久确定书中的分析的确是错的,而且这程序跑起来也验证了我的想法。当遇到这类很深奥的书籍时,即使它描述错了也不敢怀疑,总是找自己的问题。教训就是“尽信书不如无书”。其实信书不信自己的根本就是基础弱。提高基础刻不容缓啊。

     

    4、OOM问题的根源。

     

    了解了JVM的垃圾回收机制以后觉得以前对这一块的了解太粗略了,更大程度上还有些理解是不正确的,如果要分析OOM这类问题,那么需要先对垃圾回收机制进行全面深入了解。不同的虚拟机的垃圾回收不尽相同。由于本人做Android开发,但是很可惜的是google上面并没有说明Android使用是何种虚拟机(可能是我没有找到,有知道的朋友希望给个提示)。以前的程序有过OOM问题,当然是因为没有正确理解到垃圾回收,甚至是根本就没有这个概念。所以再次强调基础。

     

    总结:基础很重要。再高层的开发最终都是通过这些基础实现的,不外乎用了一些设计模式。深入理解基础才是硬道理,当然深入JVM理解也是有必要的。除了具备基础以外,细心是程序员应该具备的素养。进一步提高自己吧。

     PS:文中有不妥的地方请读者指出,欢迎交流。

     
    分类: Android
  • 相关阅读:
    HTML5
    HTML5
    HTML5
    HTML5
    HTML5
    HTML5
    HTML5
    HTML5
    HTML5
    53.Maximum Subarray
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2815086.html
Copyright © 2011-2022 走看看