日常小记
1、谈谈BIO/NIO/AIO
同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO.
BIO:最初建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要对每个请求建立一堆线程等待请求,而客户端发送请求后,先咨询服务端是否有线程相应,如果没有则会一直等待或者遭到拒绝请求,如果有的话,客户端会线程会等待请求结束后才继续执行。
NIO:NIO本身是基于事件驱动思想来完成的,其主要想解决的是BIO的大并发问题。NIO基于Reactor,当socket有流可读或可写入socket时,操作系统会相应的通知引用程序进行处理,应用再将流读取到缓冲区或写入操作系统。 也就是说,这个时候,已经不是一个连接就要对应一个处理线程了,而是有效的请求,对应一个线程,当连接没有数据时,是没有工作线程来处理的。
AIO:与NIO不同,当进行读写操作时,只须直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。 即可以理解为,read/write方法都是异步的,完成后会主动调用回调函数。
对于NIO:
1)传统的IO是基于字节流的,而NIO是基于块的。它以块为基本单位处理数据。
2)为所有的原始数据类型提供(Buffer)缓存支持。
3)增加通道(Channel)对象,作为新的原始IO抽象。
4)支持锁和内存映射文件的接口。
5)提供了基于Selector的异步网络IO
2、String相关
对于 == 符号,当比较的是基本数据类型时,比较的是值;当比较的是引用数据类型时,比较的是地址。
*********************
当打印引用时,实际上会打印出引用所指对象的toString()方法的返回值。因为每个类都直接或间接的继承Object,而Object类中定义了toString(),因此每个类中都有toString()这个方法。
*********************
equals()方法:对于Object类的equals()方法来说,它是判断调用该方法的引用与传进来的引用是否一致,即这两个引用是否指向同一个对象。即对于Object类的equals()方法来说,相当于 == 。
在String类中重写了equals()方法,即对于String类的equals()方法,它是判断当前字符串与传进来的字符串的内容是否一致。
*********************
String Pool(字符串池):
String s = “aaa”;(采用字面值的方式赋值)
1)查找String Pool中是否存在aaa这个对象,若不存在,则在String Pool中创建一个aaa对象,然后将String Pool中的这个aaa对象地址返回,赋值给引用变量s,这时s会指向String Pool中的这个aaa字符串对象。
2)若存在,则不在String Pool中创建对象,直接将String Pool中的这个aaa对象地址返回来,赋给s引用。
String s = new String("aaa");(采用new关键字新建一个字符串对象)
1)JVM首先在字符串池中查找有没有"aaa"这个字符串对象,如果有,则不在池中再去创建"aaa"这个对象了,直接在堆中创建一个"aaa"字符串对象,然后将堆中的这个"aaa"对象的地址返回赋给引用s,这样,s就指向了堆中创建的这个"aaa"字符串对象。
2)如果没有,则首先在字符串池中创建一个"aaa"字符串对象,然后再在堆中创建一个"aaa"字符串对象,然后将堆中这个"aaa"字符串对象的地址返回赋给s引用,这样,s指向了堆中创建的这个"aaa"字符串对象。
3、ArrayList扩容
集合中存放的是对象的引用而不是对象的本身。
ArrayList底层采用数组实现,当使用不带参数的构造方法生成ArrayList对象时,实际上会在底层生成一个长度为10的Object类型数组。
如果增加的元素超过10个,那么ArrayList底层会生成一个数组,长度为原来数组的1.5倍+1,然后将原数组的内容复制到新数组中,并且后续增加的内容都会放到新数组中。当新数组无法容纳新元素时,重复该过程。