2024软件测试面试刷题,这个小程序(永久刷题),靠它快速找到工作了!(刷题APP的天花板)-CSDN博客文章浏览阅读2.3k次,点赞85次,收藏11次。你知不知道有这么一个软件测试面试的刷题小程序。里面包含了面试常问的软件测试基础题,web自动化测试、app自动化测试、接口测试、性能测试、自动化测试、安全测试及一些常问到的人力资源题目。最主要的是他还收集了像阿里、华为这样的大厂面试真题,还有互动交流板块……https://blog.csdn.net/AI_Green/article/details/134931243?spm=1001.2014.3001.5502之前使用chronicle进行过日志回放框架的设计,效果很不错。后面在更加深入了解过程中,发现chronicle性能优势中一个非常重要的方面,就是序列化和反序列化。chronicle提供了多个功能类,实现不同格式数据的序列化和反序列化功能。
Java序列化是一种流行的机制,用于对复杂对象图进行序列化和反序列化。丰富的功能通常伴随着性能的牺牲。如果需求不包括对这些类型的递归图进行序列化,那么可以考虑使用开源解决方案ChronicleWire。它通过简化结构并采用树状结构显著提高了性能。此外,ChronicleWire支持多种格式,而无需修改代码即可切换。本文将介绍序列化的基础知识,并讨论ChronicleWire的一些关键优势。
在Java中,序列化是将对象转换为字节流,以便将其存储在文件中或通过网络传输。然后,可以将字节流重新反序列化为对象,恢复其原始状态。然而,Java默认的序列化机制在处理包含相互引用的复杂对象图时可能导致性能问题。
ChronicleWire通过采用更为简单的树状结构来避免这些性能问题。它不仅提供了更高的效率,还减少了序列化的复杂性。此外,ChronicleWire支持多种数据格式,包括二进制、文本和 JSON,使得可以轻松切换而无需修改代码。
在实际应用中,ChronicleWire的性能提升尤为显著,特别是在处理大量数据或对低延迟要求极高的场景下。通过使用ChronicleWire,您可以更加灵活地平衡性能和复杂性,根据实际需求选择最合适的序列化方案。
本文探讨了Java序列化的基础知识,并介绍了ChronicleWire作为一个优秀的开源解决方案,可以在提高性能的同时降低序列化复杂性。这使得ChronicleWire成为处理大规模数据和对性能敏感的Java应用程序的理想选择。
序列化和反序列化
序列化涉及将Java对象编码为字节流。例如,当我们有一个保存应用程序状态的对象时,如果我们关闭应用程序,状态将丢失。为了避免这种情况,我们可以首先将应用程序的状态序列化并存储到磁盘上,将对象转换为字节形式,以便轻松存储。同样,如果我们希望通过网络发送Java对象中的数据,我们需要先将对象序列化,然后将其写入TCP/IP缓冲区。序列化的过程是将对象转换为字节流的表示形式,以便于存储或传输。
相反,反序列化是从字节开始,然后重新创建对象实例。这意味着我们可以通过读取存储的字节流或接收的网络数据,将其反序列化为原始的Java对象。这种过程允许我们在不丢失信息的情况下重新构建对象,使得数据的传输和持久化变得更为便利。
总的来说,序列化和反序列化是在Java中处理对象存储、传输和持久化的关键机制。序列化将对象转换为字节流,便于存储和传输,而反序列化允许从字节流中重新构建原始对象。这一过程在应用程序状态的保存、网络通信和数据持久化等方面发挥着重要作用。
关于Chronicle Wire
该库将序列化的实现抽象为可插入的Wire实现。其核心理念是,对象只需描述要序列化的内容,而不需要描述如何序列化。这一理念通过实现
通过采用这种抽象和接口实现,
编码
我们已经提到Java序列化将对象编码为二进制格式,而
在ChronicleWire中,数据存储在尽可能少的字节中,而不损害性能。例如,采用停止位编码来存储整数。停止位编码是一种对整数进行紧凑表示的方法,通过将整数的每个字节的最高位(stop bit)用作标志,指示是否还有下一个字节。这种方式有效地减少了整数所占的字节数,提高了存储效率。
通过在选择编码格式时权衡紧凑性和性能,ChronicleWire使得开发人员可以在不同的应用场景中取得最佳效果。其设计目标是提供一种灵活、高性能的序列化方式,同时保持与过去版本的向后兼容性。这使得ChronicleWire成为处理大规模数据、低延迟要求的应用程序的理想选择。
不同格式
ChronicleWire提供多种实现,每一种都适用于不同的场景。例如,在需要提供应用程序配置文件或创建数据驱动测试的情况下,我们通常希望将对象序列化或反序列化为人类可读的格式,如YAML或JSON。此外,ChronicleWire还支持将Java对象序列化为类型化的JSON,使得可以在应用程序的
在实际应用中,能够在不同的编码格式之间进行互操作变得非常重要。以Chronicle Queue为例,它使用ChronicleWire的紧凑二进制格式存储数据。然后,Chronicle Queue可以读取二进制数据,并以人类可读的YAML格式将记录输出到控制台。这种能力对于调试或生成符合遵从性报告非常有用,因为它允许开发人员轻松地查看存储的数据,并以易读的格式输出。
ChronicleWire的这种多格式支持和互操作性使其在处理不同应用场景和需求的同时保持灵活性。无论是需要紧凑的二进制格式用于高性能的数据存储,还是人类可读的格式用于配置文件和测试,ChronicleWire都提供了多样化的选择。这使得它成为一个强大而适应性强的序列化库。
使用案例
让我们看一个例子,ChronicleWire将数据编码为简单字符串形式。我们使用以下案例:
import net.openhft.chronicle.bytes.Bytes import net.openhft.chronicle.core.pool.ClassAliasPool import net.openhft.chronicle.wire.Marshallable import net.openhft.chronicle.wire.Wire import net.openhft.chronicle.wire.YamlWire /** * chronicle-queue,wire 案例 */ class WireDemo { static class Tester implements Marshallable { int age String name Tester(String name, int age) { this.name = name this.age = age } } static void main(String... args) { ClassAliasPool.CLASS_ALIASES.addAlias(Tester.class)//允许 YAML 引用 Tester,而不是 net.openhft.chronicle.wire.WireDemo$Tester Wire wire = new YamlWire(Bytes.allocateElasticOnHeap())//YamlWire 用于 YAML 格式的数据 wire.getValueOut().object(new Tester("FunTester", 18))//将对象写入 wire System.out.println(wire)//打印 wire } }
控制台输出:
!Tester { number: 18, driver: FunTester }
如果我们换成JSONWire,如下:
Wire wire = new JSONWire(Bytes.allocateElasticOnHeap())// 创建一个 JSONWire
如果我们希望JSON也包含Java类型,那么我们还可以如下设置:
Wire wire = new JSONWire(Bytes.allocateElasticOnHeap()).useTypes(true)// 创建一个 JSONWire,使用类型
这也将编码java类型Tester:
{"@Tester":{"age":18,"name":"FunTester"}}
二进制格式
让我们继续一个使用紧凑二进制格式的示例:
static void main(String[] args) { ClassAliasPool.CLASS_ALIASES.addAlias(Tester.class) Wire wire = WireType.FIELDLESS_BINARY.apply(Bytes.allocateElasticOnHeap()) wire.getValueOut().object(new Tester("FunTester", 18)) System.out.println(wire.bytes().toHexString()) }
其输出如下:
00000000 b6 06 54 65 73 74 65 72 82 0c 00 00 00 a1 12 e9 ··Tester ········ 00000010 46 75 6e 54 65 73 74 65 72 FunTeste r
实例反序列化
到目前为止,所有的例子都涵盖了序列化,所以当涉及到序列化时,我们可以从数据开始,例如:
{"@Car":{"number":44,"driver":"Lewis Hamilton"}}
然后我们可以将这个JSON转换回JAVA对象:
static void main(String[] args) { ClassAliasPool.CLASS_ALIASES.addAlias(Tester.class) // 注册 Tester 类的别名 Wire wire = new JSONWire().useTypes(true)// 创建 JSONWire 实例并启用类型信息 wire.bytes().append("{"@Tester":{"age":18,"name":"FunTester"}}") // 在 Wire 中追加 JSON 格式的字符串 Object object = wire.getValueIn().object()// 从 Wire 中获取对象 println object.getClass().getName() // 输出对象的类型 def tester = (Tester) object // 将对象转换为 Tester 类型 println tester.name println tester.age }
控制台输出:
com.funtest.queue.WireDemo$Tester FunTester 18
兼容性
如果字段名被编码,如果我们改变对象属性,包括
import net.openhft.chronicle.core.pool.ClassAliasPool import net.openhft.chronicle.wire.JSONWire import net.openhft.chronicle.wire.Marshallable import net.openhft.chronicle.wire.Wire /** * chronicle-queue,wire 案例 */ class WireDemo { static class Tester implements Marshallable { int age String name int height Tester(String name, int age) { this.name = name this.age = age } } static void main(String[] args) { ClassAliasPool.CLASS_ALIASES.addAlias(Tester.class) // 注册 Tester 类的别名 Wire wire = new JSONWire().useTypes(true)// 创建 JSONWire 实例并启用类型信息 wire.bytes().append("{"@Tester":{"age":18,"name":"FunTester"}}") // 在 Wire 中追加 JSON 格式的字符串 Object object = wire.getValueIn().object()// 从 Wire 中获取对象 println object.getClass().getName() // 输出对象的类型 def tester = (Tester) object // 将对象转换为 Tester 类型 println tester.name println tester.age println tester.height } }
控制台打印如下:
com.funtest.queue.WireDemo$Tester FunTester 18 0
字符串
通常,字符串使用UTF8标准编码,然而,字符串也可以使用
我们可以创建自己的基本编码,它不只是必须包含这个数量的字符。使用更少的字符,可以从更大的紧凑性中受益。如前所述,数据越紧凑,读写速度就越快。
下面是一个Chronicle Wire如何将小字符串存储在长字符串中的例子,YAML序列化器显示了字符串表示,但字符串仅使用8字节长存储在对象中,同样,二进制序列化器将使用更紧凑的8字节长表示。
static class FunText extends SelfDescribingMarshallable { transient StringBuilder temp = new StringBuilder() @LongConversion(Base64LongConverter.class) long text FunText(CharSequence text) { this.text = Base64LongConverter.INSTANCE.parse(text) } CharSequence text() { Base64LongConverter.INSTANCE.append(temp, text) return temp } } static void main(String[] args) { ClassAliasPool.CLASS_ALIASES.addAlias(FunText.class)//注册别名 Wire wire = new BinaryWire(Bytes.allocateElasticOnHeap())//创建wire,默认是二进制的 wire.getValueOut().object(new FunText("FunTester"))//序列化 System.out.println("序列化: " + wire.bytes().toHexString())//打印序列化后的字节码 System.out.println("反序列化: " + wire.getValueIn().object())//反序列化 }
控制台输出:
序列化: 00000000 b6 07 46 75 6e 54 65 78 74 82 0e 00 00 00 c4 74 ··FunTex t······t 00000010 65 78 74 a7 ec e7 b6 1f 85 be 06 00 ext····· ···· 反序列化: !FunText { text: FunTester }
结论
Chronicle Wire允许您将对象序列化为二进制格式和从二进制格式序列化对象,同时也可以将对象序列化为许多不同的格式,它具有比Java标准序列化更高的性能。
行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群: 786229024,里面有各种测试开发资料和技术可以一起交流哦。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。