Java Web基础篇之Java基础

1、Java多线程 & 集合类 & I/O

Java Web基础篇之Java多线程
Java Web基础篇之Java集合类
Java Web基础篇之Java I/O

说明:
以上三篇文章中部分内容整理没有详尽,深入理解请仔细阅读其中的参考文章。


2、序列化与反序列化

2.1、定义

序列化:把对象转换成有序字节流,以便在网络上传输或者保存在本地文件中。传递或者保存对象时,保证对象的完整性或可传递性。
反序列化:客户端从文件中或网络上获得序列化后的对象字节流后,根据字节流中所保存的对象状态及描述信息,通过反序列化重建对象。

2.2、怎么实现

实现Serializable或Externalizable接口。

2.3、原理

序列化图示:
序列化图示
反序列化图示:
反序列化图示

2.4、相关注意事项

1、序列化时,只对对象的状态进行保存,而不管对象的方法;

2、当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

3、当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

4、并非所有的对象都可以序列化,至于为什么不可以,有很多原因了,比如:

  • 安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行RMI传输等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的;
  • 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分配,而且,也是没有必要这样实现;

5、声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态,transient代表对象的临时数据。

6、序列化运行时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号在反序列化过程中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。为它赋予明确的值。显式地定义serialVersionUID有两种用途:

  • 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
  • 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。

7、Java有很多基础类已经实现了serializable接口,比如String,Vector等。但是也有一些没有实现serializable接口的;

8、如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存!这是能用序列化解决深拷贝的重要原因

参考:
序列化和反序列化的底层实现原理是什么
序列化和反序列化


3、Object类中常用的方法,为什么wait notify会放到Object里面

3.1、Object类中常用的方法

toString()、equals()、hashCode()、wait()、notify()(随机唤醒一个线程)、notifyAll()、clone()

1 registerNatives()   //私有方法
2 getClass()    //返回此 Object 的运行类。
3 hashCode()    //用于获取对象的哈希值。
4 equals(Object obj)     //用于确认两个对象是否“相同”。
5 clone()    //创建并返回此对象的一个副本。 
6 toString()   //返回该对象的字符串表示。   
7 notify()    //唤醒在此对象监视器上等待的单个线程。   
8 notifyAll()     //唤醒在此对象监视器上等待的所有线程。   
9 wait(long timeout)    //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或        者超过指定的时间量前,导致当前线程等待。   
10 wait(long timeout, int nanos)    //在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。
11 wait()    //用于让当前线程失去操作权限,当前线程进入等待序列
12 finalize()    //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。

3.2、wait()、notify()使用

(1)Obj.wait()、Obj.notify必须要与synchronized(Obj)一起使用,也就是wait与notify是针对已经获取了Obj锁的对象来进行操作,必须在synchronized(Obj){…}语句块内。
(2)wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。

3.3、为什么wait notify会放到Object里面

因为synchronized中的这把锁可以是任意对象,所以任意对象都可以调用wait()和notify();所以wait和notify属于Object

参考:
Java wait、notify与synchronized的奇妙之处
为什么wait()和notify()属于Object类
为什么wait,notify和notifyAll要与synchronized一起使用


4、JDK提供的排序算法

4.1、Array.sort()

Array.sort()

4.2、Collections.sort()

如果环境变量LegacyMergeSort.userRequested为true的话就会使用归并排序;否则使用TimeSort算法(TimeSort是一种混合、稳定高效的排序算法,源自合并排序和插入排序,旨在很好地处理多种真实数据)

摘自:
Java提供的排序算法怎么实现的


5、基本数据类型占用空间

Java中基本数据类型占用空间

byte 1
boolean 1
char 2
short2
int 4
float 4
long 8
double 8
String占用字节数:str.getBytes().length

比特位,比特,兆等换算

8bit(位)=1Byte(字节)
1024Byte(字节)=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB

参考:
把字节数B转化为KB、MB、GB的方法

扩展

千兆网卡接收一个125M文件,1秒内能接收几个?

千兆网卡为1000Mbps(bps: bits per second(每秒位数)),1字节=8二进制位,所以千兆网卡每秒接收文件大小为1000/8 = 125M,所以1秒内理论上最多接收1个文件,再加上网络损耗等肯定不足1个。

网络带宽和下载速度间的关系(摘自百度问答)?

带宽(bandwidth)指网络上单位时间通过的位数,其单位为bps(bits per second:每秒位数)。 计算方式为:(帧中总字节数)/(此帧第一字节离开网络到最后一字节离开网络所需的时间) 电信上的ADSL速度为2M,这个M的单位是指Mbps,即兆二进制位,1Mbps=1024Kbps,Kbps是指千二进制。 而我们平时电脑上下载显示的速度是K(指KBps,即是千字节)或M(指MBps,即是兆字节)。 1字节=8二进制位,所以电脑ADSL的2M转为KBps就是,(1024Kbps x 2)/8 =256KBps。也就是说ADSL理论下载速度最大为256K。再加上电信信号损耗及不稳定因素,一般速度都会低于256K,有时也会偶尔大于256K。 两者肯定有关系,但影响下载速度的因素有好多,又不完全取决于带宽。