面试题答案
一键面试- 使用标准序列化机制:
- Java提供了标准的
java.io.Serializable
接口和ObjectInputStream
/ObjectOutputStream
类来进行对象的序列化和反序列化。对于基本数据类型,遵循这些标准机制能最大程度保证一致性。例如:
import java.io.*; class Data implements Serializable { int num; double value; public Data(int num, double value) { this.num = num; this.value = value; } } public class SerializeDemo { public static void main(String[] args) { Data data = new Data(10, 3.14); try { FileOutputStream fileOut = new FileOutputStream("data.ser"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(data); out.close(); fileOut.close(); FileInputStream fileIn = new FileInputStream("data.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); Data deserializedData = (Data) in.readObject(); in.close(); fileIn.close(); System.out.println("Deserialized int: " + deserializedData.num); System.out.println("Deserialized double: " + deserializedData.value); } catch (IOException i) { i.printStackTrace(); } catch (ClassNotFoundException c) { System.out.println("Data class not found"); c.printStackTrace(); } } }
- Java提供了标准的
- 校验和机制:
- 在序列化时,计算基本数据类型的校验和。例如对于
int
和double
,可以使用java.util.zip.CRC32
类计算校验和。 - 序列化时:
import java.io.*; import java.util.zip.CRC32; class DataWithChecksum implements Serializable { int num; double value; long checksum; public DataWithChecksum(int num, double value) { this.num = num; this.value = value; calculateChecksum(); } private void calculateChecksum() { CRC32 crc32 = new CRC32(); crc32.update(new byte[]{(byte) (num >> 24), (byte) (num >> 16), (byte) (num >> 8), (byte) num}); long doubleBits = Double.doubleToLongBits(value); crc32.update(new byte[]{(byte) (doubleBits >> 56), (byte) (doubleBits >> 48), (byte) (doubleBits >> 40), (byte) (doubleBits >> 32), (byte) (doubleBits >> 24), (byte) (doubleBits >> 16), (byte) (doubleBits >> 8), (byte) doubleBits}); this.checksum = crc32.getValue(); } }
- 反序列化时,重新计算校验和并与序列化时保存的校验和对比。
import java.io.*; import java.util.zip.CRC32; public class DeserializeWithChecksum { public static void main(String[] args) { try { FileInputStream fileIn = new FileInputStream("dataWithChecksum.ser"); ObjectInputStream in = new ObjectInputStream(fileIn); DataWithChecksum deserializedData = (DataWithChecksum) in.readObject(); in.close(); fileIn.close(); CRC32 crc32 = new CRC32(); crc32.update(new byte[]{(byte) (deserializedData.num >> 24), (byte) (deserializedData.num >> 16), (byte) (deserializedData.num >> 8), (byte) deserializedData.num}); long doubleBits = Double.doubleToLongBits(deserializedData.value); crc32.update(new byte[]{(byte) (doubleBits >> 56), (byte) (doubleBits >> 48), (byte) (doubleBits >> 40), (byte) (doubleBits >> 32), (byte) (doubleBits >> 24), (byte) (doubleBits >> 16), (byte) (doubleBits >> 8), (byte) doubleBits}); long calculatedChecksum = crc32.getValue(); if (calculatedChecksum == deserializedData.checksum) { System.out.println("Data is consistent."); System.out.println("Deserialized int: " + deserializedData.num); System.out.println("Deserialized double: " + deserializedData.value); } else { System.out.println("Data consistency check failed."); } } catch (IOException i) { i.printStackTrace(); } catch (ClassNotFoundException c) { System.out.println("DataWithChecksum class not found"); c.printStackTrace(); } } }
- 在序列化时,计算基本数据类型的校验和。例如对于
- 版本控制:
- 在类中添加一个
serialVersionUID
字段。如果数据结构发生变化,更新这个版本号。
class DataWithVersion implements Serializable { private static final long serialVersionUID = 1L; int num; double value; public DataWithVersion(int num, double value) { this.num = num; this.value = value; } }
- 反序列化时,Java会检查类的
serialVersionUID
与序列化数据中的版本号是否匹配。如果不匹配,会抛出InvalidClassException
,防止使用不一致的数据。
- 在类中添加一个
- 数据范围检查:
- 在反序列化后,检查基本数据类型的值是否在合理的范围内。例如,
int
的范围是-2147483648
到2147483647
,double
也有其特定的取值范围。
class DataRangeCheck { int num; double value; public DataRangeCheck(int num, double value) { this.num = num; this.value = value; } public boolean isDataInRange() { return num >= Integer.MIN_VALUE && num <= Integer.MAX_VALUE && value >= Double.MIN_VALUE && value <= Double.MAX_VALUE; } }
- 反序列化后调用
isDataInRange
方法进行检查。
- 在反序列化后,检查基本数据类型的值是否在合理的范围内。例如,