一文搞懂大端与小端:从原理到Java实践

· 1 分钟阅读 ·

之前刷面经的时候看到一个问题:大端和小端有什么区别?我突然发现对这两个词熟悉又陌生,在实际开发中似乎完全没有遇到过。带着这些疑问,我进行了简单的调查与对比,也算是温习了一下计算机组成的知识。

大端与小端

端序,又称字节序,实际指的是数据的一种排列顺序。我们知道计算机中有内存地址这一概念,内存地址有”高低”之分,也就是说内存是一个有顺序的结构。而我们的数据存储在内存中,往往也是被拆分为一个一个的字节有序进行存储的。所以,数据在内存中存储的方式,可以分为两种:

  • 大端:内存低位存储数据的高位
  • 小端:内存低位存储数据的低位

这就是大端和小端的由来。那么这两种方式各有什么作用呢?直接统一用一种方式不就好了!让我们继续慢慢看。

大端:人类阅读🧐

我们大多数人平时进行阅读,往往习惯从左向右阅读,比如数字”14”,你肯定先看1然后才是4。而计算机读取内存的数据,一般是从低到高读取的。如果我们在低位存储了”1”,在高位存储了”4”,是不是从低到高读出来就是我们想要看到的数据?所以说,大端往往对人类阅读更友好。

在网络领域,大端应用广泛。例如TCP/IP协议栈就是大端模式,UDP也是大端。HTTP、HTTPS、DNS,许多字段规定也是需要使用大端处理。

小端:机器处理💻

既然大端序这么好,为什么还存在小端序呢?问题就在于,计算机的数据往往不仅需要人类阅读,还需要计算机的处理与运算。几乎所有主流的CPU架构,X86、ARM,都采用了小端序。

你可以想一想自己是如何进行加法运算的,肯定是从数字的低位进行相加,然后进位再到高位再进行处理。计算机的很多运算也是类似的,需要从数字的低位进行处理。那么如果采用小端序,内存低位存储的就是数据的低位,读出来就是低位到高位,天然方便了CPU运算。所以小端也有自己的价值和意义。

Java与端序

平时在写Java的时候,为什么少见有人提这个大端和小端呢?

那当然是Java语言本身给你处理好了。就和C/C++的指针一样,我们写Java时几乎从来不用考虑这些东西。如果非要问的话,Java对外统一都是大端,内部可能有小端。class文件、网络相关API等,默认全是大端,直观又方便。JVM的实现层虽然没有明确规定使用什么端序,一般也是使用”本地端序”,也就是CPU喜欢什么端序我们就用什么端序处理,总之在计算方面小端也是该用就用。

当然,这也不代表Java就一定接触不到端序。以下的场景还是有可能的:

  • Netty、NIO
  • 文件解析
  • JNI/Unsafe
  • 序列化框架

总结

总的来说,大端和小端都是“存在即合理”的,各有特长。如果你有一天需要考虑运算、性能等方面的问题,或者使用Java做一些偏底层的研究,端序这方面可以考虑一下是否需要处理和优化。而如果你平时接触不到也用不上端序的时候,就老老实实享受底层的操作系统以及Java带给你又一个隐形的便利吧。