资讯专栏INFORMATION COLUMN

面试问你java中的序列化怎么答?

liuyix / 513人阅读

摘要:序列化对象要保留充分的信息,用来恢复数据对象,但是为了节约存储空间和网络带宽,序列化出的二进制流要尽可能小。序列化序列化是一种支持动态类型跨语言基于对象传输的网络协议,对象序列化后的二进制流,可以被其他语言反序列化。

记得很久以前写代码的时候,每次新建一个实体都会下意识的继承Serializable接口,大部分人都知道这是对对象的序列化,可是你们真的知道序列化吗?这篇文章就简单的说下java中的序列化,让你更多的理解java这门语言。

关于上篇文章说的,在应用登录前使用第三方的人机验证,如果第三方的产品突然出现故障,无法使用,这种状况我们应该怎么应对,在团队中我们也讨论过这种情况,我们的方案就是客户端不直接的请求第三方,而是由后端服务器充当一个中介的角色,起转发作用,这样在第三方出现问题,我们服务器端会做处理,这也是不把鸡蛋放在同一个篮子里的思想。

接下来,简单的说下序列化,

将数据对象转换为二进制流的过程就称为对象的序列化(Serialization),反过来,将二进制流转换为对象就是反序列化(Deserializable)。序列化的用处是什么呢?共两点:

1、数据持久化:在很多应用中,需要对好多对象进行序列化,存到物理硬盘,较长时间的保存,比如,Session对象,当有数万用户并发访问的时候,就会有数万的Session对象,内存会承受很大的压力,这个时候,就会把一些对象先序列化到硬盘中,需要使用的时候再还原到内存中。序列化对象要保留充分的信息,用来恢复数据对象,但是为了节约存储空间和网络带宽,序列化出的二进制流要尽可能小。

2、网络传输:当两个进程在互相通信的时候,就会进行数据传输,不管是何种类型的数据,都必须要转成二进制流来传输,接受方收到后再转为数据对象。

重点来了,序列化在代码中是怎么实现的呢?以下介绍三种:

1、java原生序列化:java类通过实现Serializable接口来实现。这个接口没有任何方法,只是标识,java序列化保留了对象的元数据,以及对象数据,兼容性最好,但是不支持跨语言,性能也一般。

public class BaseEntity implements Serializable {

private static final long serialVersionUID = -7333816285916354999L;
private Long id;
public BaseEntity() {
}
public Long getId() {
    return this.id;
}
public void setId(Long id) {
    this.id = id;
}

}
实现这个接口,idea会给你一个警告,它会建议你设置一个serialVersionUID,如果你不设置,编译器会根据类的内部实现,包括类名、接口名、方法和属性来自动生成serialVersionUID 如果类的源码有修改,重新编译后这个值也会变化。

在修改类的时候,我们要根据兼容性来决定是否修改serialVersionUID,如果是兼容性质的升级,不建议修改,因为可能会反序列化失败。如果是不兼容的,就需要修改,避免反序列化变得混乱。

java原生序列化,在反序列化的时候不会调用类的无参构造方法,而是调用native方法将属性赋值为对应类型的初始值。

最后,基于性能及兼容性,不推荐使用。

2、Hessian序列化:Hessian序列化是一种支持动态类型、跨语言、基于对象传输的网络协议,java对象序列化后的二进制流,可以被其他语言反序列化。它的特性:

自描述序列化类型,不依赖外部描述文件或接口定义,用一个字节表示常用的基础类型,极大缩短二进制流;

语言无关,支持脚本语言。

协议简单,比java原生的要高效。

需要注意一点:Hessian会把复杂对象所有属性存储在一个Map中进行序列化,所以在父类和子类含有相同字段的情况下,先序列化子类,后序列化父类,这样的结果是子类的同名属性会被父类覆盖掉。

以下是代码实现

/**

 * Hessian实现序列化
 *
 * @param TestClass
 * @return
 * @throws IOException
 */
private static byte[] serialize(TestClass TestClass) {
    ByteArrayOutputStream byteArrayOutputStream = null;
    HessianOutput hessianOutput = null;
    try {
        byteArrayOutputStream = new ByteArrayOutputStream();
        // Hessian的序列化
        hessianOutput = new HessianOutput(byteArrayOutputStream);
        hessianOutput.writeObject(TestClass);
        return byteArrayOutputStream.toByteArray();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            byteArrayOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            hessianOutput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}

3、JSON序列化:

JSON是一种轻量级的数据交换格式,这种序列化方式就是讲数据对象转换为JSON字符串。在序列化的过程中舍弃了类型信息。反序列化是只有在提供了类型信息的情况下才能完成。

public static  T fromJson(String json, Class type) {
    if (json != null && !json.equals("")) {
        try {
            return getObjectMapper().readValue(json, type);
        } catch (Exception var3) {
            var3.printStackTrace();
            return null;
        }
    } else {
        return null;
    }
}

相信大部分读者的公司和前端和客户端数据的交互格式都是JSON吧,因为JSON的这种格式可读性较好,而且也方便调试。

序列化通常会用于网络传输数据对象,而对象中常常会含有敏感数据,所以黑客常常会攻击这点,攻击手段通常是利用反序列化过程构造恶意代码,怎么应对这种情况呢?可以使用transient关键字来修饰这个属性,这样在反序列化之后该属性就会为空,如果一定要传递的话,可以使用对称加密或非对称加密独立传输,在数据传输的问题上,我们一定要具备安全意识。

希望看完这篇文章的你能有所收获。

分享以下自己的思考:”对于用户来说,系统太灵活是他们的负担,意味着他们要做更多的选择,对于技术人员来说,架构灵活可以应对更多的运营策略。怎样折中,是个问题。“

这样的分享我会一直持续,你的关注、转发和点赞是对我最大的支持,感谢。

题图:作者实拍

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74095.html

相关文章

  • 试官问数组和ArrayList怎么

    摘要:在反射方面来说,从运行时返回一个的实例时不需要经过强制转换然后则需要经过转换才能得到。如果对数据的数量大小已知,操作也非常简单,也不需要中的大部分方法,也是可以直接使用数组的。 showImg(https://segmentfault.com/img/bVbruTp?w=1920&h=1080); 我在想每个人在面试的时候都会被问到集合相关的问题,有好大一部分人在回答的时候并没有那么多...

    宠来也 评论0 收藏0
  • 金三银四背后,一个 Android 程序员的试心得

    摘要:到十二月份,公司开始第二波裁员,我决定主动拿赔偿走人。加一个小插曲上面的题是饿了吗面试问到的。想去的公司没有面试好,不要气馁,继续加油准备。避免打击自信心。 回顾一下自己这段时间的经历,九月份的时候,公司通知了裁员,我匆匆忙忙地出去面了几家,但最终都没有拿到offer,我感觉今年的寒冬有点冷。到十二月份,公司开始第二波裁员,我决定主动拿赔偿走人。后续的面试过程我做了一些准备,基本都能走...

    Achilles 评论0 收藏0
  • 我的春招求职经验分享(已拿阿里京东网易等 5 个 offer)

    摘要:面经因为我完全没有面试经验,从来没有经历过面试,于是想着在去这类大公司面试之前先找成都的小公司练练手,积累点面试经验。于是三月份开始就有成都的小公司开始约我面试。 前序 从我高考成绩出来那一刻开始,从我在高考志愿上填上计算机科学与技术这几个当时在心中堪称神圣的几个字开始,我就已经把进入中国互联网最高殿堂BAT作为我整个大学奋斗的目标,哪怕我就读的是一所位于内陆的双非一本大学我也认为我能...

    Winer 评论0 收藏1
  • 25k成功入职京东:拿到京东软件测试岗位offer经验分享

    前言 正逢金九银十,有很多朋友已经在考虑自己的出路了,今天给大家分享的是我一位幸运拿到京东软件测试offer的朋友的面试经历,我也闲来无事,问到了我朋友京东面试的一些真题,以及我整理的一些真题分享给大家,希望能够帮助大家冲刺金九银十,像我的朋友一样拿到自己心仪的offer。 三面京东: 一面: 你所了解的黑盒测试方法有哪些?并简单介绍下其应用场景?简述常用的bug管理或者用例管理工具,并且描述其...

    leeon 评论0 收藏0

发表评论

0条评论

liuyix

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<