当前位置: 首页 > news >正文

每日一道面试题:Java中序列化与反序列化

写在开头

哈喽大家好,在高铁上码字的感觉是真不爽啊,小桌板又拥挤,旁边的小朋友也比较的吵闹,影响思绪,但这丝毫不影响咱学习的劲头!哈哈哈,在这喧哗的车厢中,思考着这样的一个问题,Java中的对象是如何在各个方法,或者网络中流转的呢?
通过这个问题便引出了我们今天的主人公:序列化与反序列化

序列化:所谓的序列化就是将Java对象或数据结构转为字节序列的过程,以便于存储到数据库、内存、文件系统或者网络传输。
反序列化:而反序列化就是序列化的逆向操作将字节流转为Java对象的过程。

在这里插入图片描述

序列化的基本实现(JDK)

这样一看序列化是不是非常有用?毋容置疑,这是一个无形中都会用到的知识点!那么想要在Java中实现序列化该如何做呢?继续往下看。
其实只要做到2点,就可以实现基本的序列化功能:序列流(ObjectInputStream 和 ObjectOutputStream)、实现 Serializable 接口(一个标识型接口,没有具体的方法,仅是一种通知,告诉JVM这个对象需要序列化)
在这里插入图片描述

【示例代码】

/*** 测试序列化,反序列化* @author javabuild*/
public class TestSerializable implements Serializable {private static final long serialVersionUID = 5887391604554532906L;private int id;private String name;public TestSerializable(int id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {return "TestSerializable [id=" + id + ", name=" + name + "]";}@SuppressWarnings("resource")public static void main(String[] args) throws IOException, ClassNotFoundException {//序列化ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("TestSerializable.obj"));oos.writeObject("测试序列化");oos.writeObject(618);TestSerializable test = new TestSerializable(1, "JavaBuild");oos.writeObject(test);//反序列化ObjectInputStream ois = new ObjectInputStream(new FileInputStream("TestSerializable.obj"));System.out.println((String)ois.readObject());System.out.println((Integer)ois.readObject());System.out.println((TestSerializable)ois.readObject());}
}

输出:

测试序列化
618
TestSerializable [id=1, name=JavaBuild]

这种实现方式是JDK自带的,方便好用,易于实现,代码逻辑不复杂,但它有着诸多的致命缺陷,导致很多大厂不会使用这种方式。

1、不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。
2、性能差:相比于其他序列化框架性能更低,主要原因是序列化之后的字节数组体积较大,导致传输成本加大。
3、存在安全问题:序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。

序列化的其他实现方式(Kryo)

除了JDK自带的实现方式,国内外的大厂们推出过不好的开源且好用的序列化协议,比如Hessian、Kryo、Protobuf、ProtoStuff。

Hessian
一个轻量级的,自定义描述的二进制 RPC 协议。Hessian 是一个比较老的序列化实现了,并且同样也是跨语言的。Dubbo2.x 默认启用的序列化方式是 Hessian2 ,但是,Dubbo 对 Hessian2 进行了修改,不过大体结构差别不大。

Protobuf
自于 Google,性能优秀,支持多种语言,同时还是跨平台的。就是在使用中过于繁琐,因为你需要自己定义 IDL 文件和生成对应的序列化代码。这样虽然不灵活,但是,另一方面导致 protobuf 没有序列化漏洞的风险。不过后续谷歌推出了升级版,进行了很多缺陷的优化,诞生了ProtoStuff。

Kryo

目前使用最广泛,好评诸多的就是具有高性能、高效率和易于使用和扩展等特点的Kryo, 目前像Twitter、Groupon、Yahoo 以及多个著名开源项目(如 Hive、Storm)中都在使用这款序列化工具。
【示例代码】
1、引入相应的pom依赖库

<!-- 引入 Kryo 序列化工具 -->
<dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>5.4.0</version>
</dependency>

2、通过调用方法,通过二进制实现序列化与反序列化

public class KryoDemo {public static void main(String[] args) throws FileNotFoundException {Kryo kryo = new Kryo();kryo.register(KryoParam.class);KryoParam object = new KryoParam("JavaBuild", 123);Output output = new Output(new FileOutputStream("logs/kryo.bin"));kryo.writeObject(output, object);output.close();Input input = new Input(new FileInputStream("logs/kryo.bin"));KryoParam object2 = kryo.readObject(input, KryoParam.class);System.out.println(object2);input.close();}
}class KryoParam {private String name;private int age;public KryoParam() {}public KryoParam(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "KryoParam{" +"name='" + name + '\'' +", age=" + age +'}';}
}

序列化的细节知识点!

1、一般实现序列化接口后,还会有个serialVersionUID,它有什么作用?

答:SerialVersionUid 是为了序列化对象版本控制,告诉 JVM 各版本反序列化时是否兼容
如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常
仅增加了一个属性,希望向下兼容,老版本的数据都保留,就不用修改 删除了一个属性,或更改了类的继承关系,就不能不兼容旧数据,这时应该手动更新
SerialVersionUid

2、如果有些字段不想进行序列化怎么办?

答:对于不想进行序列化的变量,可以使用 transient 关键字修饰。transient
关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。

相关文章:

每日一道面试题:Java中序列化与反序列化

写在开头 哈喽大家好&#xff0c;在高铁上码字的感觉是真不爽啊&#xff0c;小桌板又拥挤&#xff0c;旁边的小朋友也比较的吵闹&#xff0c;影响思绪&#xff0c;但这丝毫不影响咱学习的劲头&#xff01;哈哈哈&#xff0c;在这喧哗的车厢中&#xff0c;思考着这样的一个问题…...

论文阅读:Vary-toy论文阅读笔记

目录 引言整体结构图方法介绍训练vision vocabulary阶段PDF数据目标检测数据 训练Vary-toy阶段Vary-toy结构数据集情况 引言 论文&#xff1a;Small Language Model Meets with Reinforced Vision Vocabulary Paper | Github | Demo 说来也巧&#xff0c;之前在写论文阅读&…...

【Linux】开始使用 vim 吧!!!

Linux 1 what is vim &#xff1f;2 vim基本概念3 vim的基本操作 &#xff01;3.1 vim的快捷方式3.1.1 复制与粘贴3.1.2 撤销与剪切3.1.3 字符操作 3.2 vim的光标操作3.3 vim的文件操作 总结Thanks♪(&#xff65;ω&#xff65;)&#xff89;感谢阅读下一篇文章见&#xff01;…...

多线程面试合集

前言 前文介绍了JVM相关知识&#xff0c;本文将重点介绍多线程相关知识以及工作中的一些经验。 多线程面试合集 什么是多线程&#xff1f;为什么我们需要多线程&#xff1f; 多线程是指在一个进程中同时执行多个线程&#xff0c;每个线程可以执行不同的任务。多线程可以提高…...

从微服务到云原生

很多文章介绍云原生概念&#xff0c;说它包含微服务&#xff0c;又包含了其它几个方面的东西&#xff0c;还扯到文化层面、组织层面和技术层面&#xff0c;搞技术的人一听到公司文化问题和组织部门问题&#xff0c;就十分地晕眩&#xff0c;不能让我好好地坐下来写写代码、搞搞…...

bxCAN 主要特性

bxCAN 主要特性 ● 支持 2.0 A 及 2.0 B Active 版本 CAN 协议 ● 比特率高达 1 Mb/s ● 支持时间触发通信方案 发送 ● 三个发送邮箱 ● 可配置的发送优先级 ● SOF 发送时间戳 接收 ● 两个具有三级深度的接收 FIFO ● 可调整的筛选器组&#xff1a; — CAN1 和…...

武忠祥2025高等数学,基础阶段的百度网盘+视频及PDF

考研数学武忠祥基础主要学习以下几个方面的内容&#xff1a; 1.微积分:主要包括极限、连续、导数、积分等概念&#xff0c;以及它们的基本性质和运算方法。 2.线性代数:主要包括向量、向量空间、线性方程组、矩阵、行列式、特征值和特征向量等概念&#xff0c;以及它们的基本…...

用JavaFX写了一个简易的管理系统

文章目录 前言正文一、最终效果1.1 主页面1.2 动物管理页面-初始化1.3 动物管理页面-修改&新增1.4 动物管理页面-删除&批量删除 二、核心代码展示2.1 启动类2.2 数据库配置-db.setting2.3 日志文本域组件2.4 自定义表格视图组件2.5 自定义分页组件2.6 动物管理页面2.7 …...

第二百九十回

文章目录 1. 概念介绍2. 方法与细节2.1 实现方法2.2 具体细节 3. 示例代码4. 内容总结 我们在上一章回中介绍了"如何混合选择多个图片和视频文件"相关的内容&#xff0c;本章回中将介绍如何通过相机获取视频文件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. …...

bert实现完形填空简单案例

使用 bert 来实现一个完形填空的案例&#xff0c;使用预训练模型 bert-base-chinese &#xff0c;这个模型下载到跟代码同目录下即可&#xff0c;下载可参考&#xff1a;bert预训练模型下载-CSDN博客 通过这个案例来了解一下怎么使用预训练模型来完成下游任务&#xff0c;算是对…...

Jmeter 分布式测试

Jmeter单机进行压测&#xff0c;受到单台机器的性能影响&#xff0c;Jmeter支持分布式测试&#xff0c;用一个控制节点去控制多个工作节点去模拟更多的用户。 版本信息 内容版本号JDK1.8Jmeter5.6.2 分布式测试原理 jmeter 官网对分布式测试有说明&#xff0c;jmeter分布式…...

在 Ubuntu 上安装 Docker Engine

系列文章目录 前言 要在 Ubuntu 上开始使用 Docker Engine&#xff0c;请确保满足先决条件&#xff0c;然后按照安装步骤进行操作。 一、先决条件 注意事项 如果您使用 ufw 或 firewalld 管理防火墙设置&#xff0c;请注意当您使用 Docker 暴露容器端口时&#xff0c;这些端口…...

Mac安装nvm,安装多个不同版本node,指定node版本

一.安装nvm brew install nvm二。配置文件 touch ~/.zshrc echo export NVM_DIR~/.nvm >> ~/.zshrc echo source $(brew --prefix nvm)/nvm.sh >> ~/.zshrc三.查看安装版本 nvm -vnvm常用命令如下&#xff1a;nvm ls &#xff1a;列出所有已安装的 node 版本nvm…...

【开源】基于JAVA+Vue+SpringBoot的智慧家政系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…...

Python NLP深度学习进阶:自然语言处理

自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09;是人工智能领域中的一个重要分支&#xff0c;涉及到处理和理解人类语言的方法和技术。随着深度学习的快速发展&#xff0c;NLP的研究和应用也在不断进步。 在Python中&#xff0c;有许多强大的…...

STM32单片机基本原理与应用(三)

矩阵键盘工作原理 矩阵键盘由多个独立按键组成&#xff0c;按键的一端接地&#xff0c;一端接MCU的GPIO。当按键没有被按下时&#xff0c;电路其实是一个断路&#xff0c;将单片机该引脚设置成输入上拉状态&#xff0c;读到的电平为高电平。当按下按键时&#xff0c;引脚会被拉…...

Android studio布局详解

文章目录 一、Android studio布局详解二、Android studio六大布局案例三、优缺点四、热门文章 一、Android studio布局详解 Android Studio是一种用于开发Android应用程序的集成开发环境&#xff08;IDE&#xff09;,用于设计和编辑Android应用程序的用户界面布局。在Android …...

第四篇:怎么写express的路由(接口+请求)

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 &#x1f4d8; 引言&#xff1a; &#x1f4…...

算法学习记录:有关树的基础

前言&#xff1a; 算法学习记录不是算法介绍&#xff0c;本文记录的是从零开始的学习过程&#xff08;见到的例题&#xff0c;代码的理解……&#xff09;&#xff0c;所有内容按学习顺序更新&#xff0c;而且不保证正确&#xff0c;如有错误&#xff0c;请帮助指出。 学习工具…...

2. 《大数据之路:阿里巴巴大数据实践》学习笔记,持续更新ing

笔记链接(飞书)&#xff1a;https://t0s016els2a.feishu.cn/docx/JrNydGljUonH1ExcGCpcoC8unTb 密码&#xff1a;r661391 该书籍部分目录如下&#xff1a; 文章目录 第1篇 数据技术篇第2章 日志采集2.1 浏览器的页面日志采集2.1.1 页面浏览日志采集流程2.1.2 页面交互日志采集…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境&#xff1a; 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境&#xff1a; virtualenv myenv 3、激活虚拟环境&#xff08;激活环境可以在当前环境下安装包&#xff09; source myenv/bin/activate 此时&#xff0c;终端…...