java随笔

system.out.println(0.06+0.01),System.out.println(0.06+0.05)的结果

java随笔

  • 在实际的运算中,需要对更大或者更小的数进行运算和处理时,我们不能使用传统的+、-、*、/等算术运算符直接进行数学运算,而要使用用java.math.BigDecimal。BigDecimal所创建的是对象,通过调用其相对应的方法进行数学运算。使用BigDecimal可以保证运算的精度,不会发生丢失精度的现象,同时,可以在保证精度的前提下,保留指定位数的小数。

transient关键字

  • 当我们使用序列化接口的时候,有些变量是不想去被持久化的,(例如密码等敏感信息)这时候就用它修饰。
  • 它只能用于修饰变量不能修饰类与方法。
  • 静态变量存在于jvm中也不能被序列化。

Serializable/Externalizable接口

  • 前者是自动的实现序列化,后者继承前者,增加了两个方法writeExternal(),readExternal(),用于完成手动序列化。
  • 控制序列化的两种方法就是上面的的关键字transient与这里的Externalizable接口。

volatile关键字

  • 语义增强作用,直接从内存读取,而不是寄存器,增加了变量的可见性。

HashMap/HashTable/ConcurrentHashMap

  • HashMap是线程不安全的,底层是数组加链表的存储结构。
  • 想让HashMap变得线程安全有三种方法:
    • 使用线程安全的HashTable。
    • 使用Collections.synchonized(HashMap),其实HashTable的底层实现原理也是使用synchronized。
    • 使用JUC中的ConcurrentHashMap。
  • ConcurrentHashMap使用的锁分段技术,首先将数据分成一段一段的存储,然后给每一段数据配一把锁,当一个线程占用锁访问其中一个段数据的时候,其他段的数据也能被其他线程访问。因此:ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment使用可重入锁ReentrantLock扮演锁的角色,HashEntry则用于存储键值对数据。一个ConcurrentHashMap里包含一个Segment数组,Segment的结构和HashMap类似,是一种数组和链表结构, 一个Segment里包含一个HashEntry数组,每个HashEntry是一个链表结构的元素, 每个Segment守护者一个HashEntry数组里的元素,当对HashEntry数组的数据进行修改时,必须首先获得它对应的Segment锁。

BIO,NIO,AIO

  • IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。
    java随笔
  • 同步阻塞的BIO:
    java随笔
  • 伪异步IO:(使用线程池改善的BIO)
    java随笔
  • 同步非阻塞NIO:
    当IO流需要创建多个连接的时候,就需要通过多线程进行实现,因此性能不好。NIO是基于selector,channel,buffer实现的非阻塞IO操作。因此与传统的Socket编程相比效率高很多。
    • channel:双向的非阻塞通道
    • selector:采用复用与解复用的方式实现了一个线程管理多个通道,因此可以分流与合流
    • Buffer:用来保存数据,channel读取的数据,channel要发送的数据都可以保存
  • 异步非阻塞AIO:
    AIO是异步IO的缩写,虽然NIO在网络操作中,提供了非阻塞的方法,但是NIO的IO行为还是同步的。对于NIO来说,我们的业务线程是在IO操作准备好时,得到通知,接着就由这个线程自行进行IO操作,IO操作本身是同步的。
    但是对AIO来说,则更加进了一步,它不是在IO准备好时再通知线程,而是在IO操作已经完成后,再给线程发出通知。因此AIO是不会阻塞的,此时我们的业务逻辑将变成一个回调函数,等待IO操作完成后,由系统自动触发。
    与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。 在JDK1.7中,这部分内容被称作NIO.2,主要在Java.nio.channels包下增加了下面四个异步通道:
    AsynchronousSocketChannel
    AsynchronousServerSocketChannel
    AsynchronousFileChannel
    AsynchronousDatagramChannel

java中垃圾可以手动回收么?

不可以。System.gc()与System.runFinalization()方法增加了finalize方法执行的机会,但不可盲目依赖它们Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行。

java异常体系

java随笔

  • Java把异常当作对象来处理,并定义一个基类java.lang.Throwable作为所有异常的超类。 在JavaAPI中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception。其中异常类Exception又分为运行时异常(RuntimeException)和非运行时异常,这两种异常有很大的区别,也称之为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
  • 运行时异常都是RuntimeException类及其子类异常,如NullPointerException、IndexOutOfBoundsException等,
    这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,
    程序应该从逻辑角度尽可能避免这类异常的发生。 非运行时异常发生在编译器。 从程序语法角度讲是必须进行处理的异常try catch或者throws,如果不处理,程序就不能编译通过。