go 面试题-如何获取系统是大端模式还是小端模式

详情见文章:详解大端模式和小端模式

总结来说:

  • 就是地址位在计算机存储的位置不同,例如0x12 34 56 78在不同模式存储方式不同

  • 大端模式(一般用于在通信协议中比较常见)

    0x12   0x34   0x56   0x78
  • 小端模式 (大部分操作系统本地存储方式)

    0x78   0x56    0x34    0x12

2.go语言常见字节序处理函数

导入包

"encoding/binary"

以常见tcp 网络处理为例子使用

package main
​
import (
    "encoding/binary"
    "encoding/hex"
    "fmt"
)
​
func main()  {
    var a uint64=10
    var buffer =make([]byte,8)
    binary.BigEndian.PutUint64(buffer,a)
    fmt.Println(hex.EncodeToString(buffer)) //000000000000000a
    b:=binary.BigEndian.Uint64(buffer)
    fmt.Println(b) //10
}
​
  • 首先定义一个uint64 整数,占8个字节

  • 然后将a 转为 大端存储的字节流,这时候我们用hex.EncodeToString(buffer)查看16进制为000000000000000a,如果是正常小端模式存储下那这个a肯定在前面了,为a000000000000000

3.如何获取直接获取在操作系统的字节序呢

还是以上面的例子,是不是直接将变量a的地址获取处理,转成字节数组,查看16进制,就可以看操作系统是大小端呢,肯定可以,下面来实验下。

package main
​
import (
    "encoding/hex"
    "fmt"
    "unsafe"
)
​
func main()  {
    var a uint64=10
    tmp:=*(*[8]byte)(unsafe.Pointer(&a))
    fmt.Println(hex.EncodeToString(tmp[:])) //0a00000000000000
}
​
  • 从结果来看是小端模式,我用的是win10 操作系统

  • unsafe.Pointer获取变量的地址再转成字节数组

  • 注意必须转成字节数组而不是切片

4.项目中的应用

etcd\pkg\cpuutil\endian.go

package cpuutil
​
import (
    "encoding/binary"
    "unsafe"
)
​
const intWidth int = int(unsafe.Sizeof(0))
​
var byteOrder binary.ByteOrder
​
// ByteOrder returns the byte order for the CPU's native endianness.
func ByteOrder() binary.ByteOrder { return byteOrder }
​
func init() {
    i := int(0x1)
    if v := (*[intWidth]byte)(unsafe.Pointer(&i)); v[0] == 0 {
        byteOrder = binary.BigEndian
    } else {
        byteOrder = binary.LittleEndian
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值