JAVA与C++通信之字节序

2023-11-05

  1.BIG-ENDIAN、LITTLE-ENDIAN跟多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。BIG-ENDIAN就是低位字节排放在内存的低端,高位字节排放在内存的高端。而LITTLE-ENDIAN正好相反。 
  比如 int a = 0x05060708 
  在BIG-ENDIAN的情况下存放为: 
  字节号 0 1 2 3 
  数据 05 06 07 08 
  在LITTLE-ENDIAN的情况下存放为: 
  字节号 0 1 2 3 
  数据 08 07 06 05 
  2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架构的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。 
  3.所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。 
  4.如果网络上全部是PowerPC,SPARC和Motorola CPU的主机那么不会出现任何问题,但由于实际存在大量的IA架构的CPU,所以经常出现数据传输错误。 
  5.文章开头所提出的问题,就是因为程序运行在X86架构的PC SERVER上,发送数据的一端用C实现的,接收一端是用JAVA实现的,而发送端在发送数据前未进行从主机字节序到网络字节序的转换,这样接收端接收到的是LITTLE-ENDIAN的数据,数据解释自然出错。 
  具体数据如下,实际发送的数据为23578 
  发送端发送数据: 1A 5C 
  接收端接收到数据后,按BIG-ENDIAN进行解释具体数据是多少?你们自己去计算并比较吧!
  ===============================================================================================
  Big Endian and Little Endian 
  谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。那么究竟什么是big endian,什么又是little endian呢? 
  其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB),即常说的低位在先,高位在后。 
  用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示: 
  Big Endian 
  低地址 高地址 
  -----------------------------------------> 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  | 12 | 34 | 56 | 78 | 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  Little Endian 
  低地址 高地址 
  -----------------------------------------> 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  | 78 | 56 | 34 | 12 | 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  从上面两图可以看出,采用big endian方式存储数据是符合我们人类的思维习惯的。而little endian,!@#$%^&*,见鬼去吧 -_-||| 
  为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?尤其是当你把你在微机上运算的结果运用到计算机群上去的话。在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的 0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。 

  无独有偶,所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了四个转换字节序的宏。

 

  1. /** 
  2. * 通信格式转换 
  3. * 
  4. * Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 
  5. * 高、低字节之间的转换 
  6. * windows的字节序为低字节开头 
  7. * linux,unix的字节序为高字节开头 
  8. * java则无论平台变化,都是高字节开头 
  9.   */   
  10. public class FormatTransfer {  
  11. /** 
  12.   * 将int转为低字节在前,高字节在后的byte数组 
  13.   * @param n int 
  14.   * @return byte[] 
  15.   */  
  16. public static byte[] toLH(int n) {  
  17.   byte[] b = new byte[4];  
  18.   b[0] = (byte) (n & 0xff);  
  19.   b[1] = (byte) (n >> 8 & 0xff);  
  20.   b[2] = (byte) (n >> 16 & 0xff);  
  21.   b[3] = (byte) (n >> 24 & 0xff);  
  22.   return b;  
  23. }   
  24. /** 
  25.   * 将int转为高字节在前,低字节在后的byte数组 
  26.   * @param n int 
  27.   * @return byte[] 
  28.   */  
  29. public static byte[] toHH(int n) {  
  30.   byte[] b = new byte[4];  
  31.   b[3] = (byte) (n & 0xff);  
  32.   b[2] = (byte) (n >> 8 & 0xff);  
  33.   b[1] = (byte) (n >> 16 & 0xff);  
  34.   b[0] = (byte) (n >> 24 & 0xff);  
  35.   return b;  
  36. }   
  37. /** 
  38.   * 将short转为低字节在前,高字节在后的byte数组 
  39.   * @param n short 
  40.   * @return byte[] 
  41.   */  
  42. public static byte[] toLH(short n) {  
  43.   byte[] b = new byte[2];  
  44.   b[0] = (byte) (n & 0xff);  
  45.   b[1] = (byte) (n >> 8 & 0xff);  
  46.   return b;  
  47. }   
  48. /** 
  49.   * 将short转为高字节在前,低字节在后的byte数组 
  50.   * @param n short 
  51.   * @return byte[] 
  52.   */  
  53. public static byte[] toHH(short n) {  
  54.   byte[] b = new byte[2];  
  55.   b[1] = (byte) (n & 0xff);  
  56.   b[0] = (byte) (n >> 8 & 0xff);  
  57.   return b;  
  58. }   
  59. /** 
  60.   * 将将int转为高字节在前,低字节在后的byte数组  
  61. public static byte[] toHH(int number) { 
  62.   int temp = number; 
  63.   byte[] b = new byte[4]; 
  64.   for (int i = b.length - 1; i > -1; i--) { 
  65.     b = new Integer(temp & 0xff).byteValue(); 
  66.     temp = temp >> 8; 
  67.   } 
  68.   return b; 
  69.  
  70. public static byte[] IntToByteArray(int i) { 
  71.     byte[] abyte0 = new byte[4]; 
  72.     abyte0[3] = (byte) (0xff & i); 
  73.     abyte0[2] = (byte) ((0xff00 & i) >> 8); 
  74.     abyte0[1] = (byte) ((0xff0000 & i) >> 16); 
  75.     abyte0[0] = (byte) ((0xff000000 & i) >> 24); 
  76.     return abyte0; 
  77.  
  78. */   
  79. /** 
  80.   * 将float转为低字节在前,高字节在后的byte数组 
  81.   */  
  82. public static byte[] toLH(float f) {  
  83.   return toLH(Float.floatToRawIntBits(f));  
  84. }   
  85. /** 
  86.   * 将float转为高字节在前,低字节在后的byte数组 
  87.   */  
  88. public static byte[] toHH(float f) {  
  89.   return toHH(Float.floatToRawIntBits(f));  
  90. }   
  91. /** 
  92.   * 将String转为byte数组 
  93.   */  
  94. public static byte[] stringToBytes(String s, int length) {  
  95.   while (s.getBytes().length < length) {  
  96.     s += " ";  
  97.   }  
  98.   return s.getBytes();  
  99. }   
  100. /** 
  101.   * 将字节数组转换为String 
  102.   * @param b byte[] 
  103.   * @return String 
  104.   */  
  105. public static String bytesToString(byte[] b) {  
  106.   StringBuffer result = new StringBuffer("");  
  107.   int length = b.length;  
  108.   for (int i=0; i<length; i++) {  
  109.     result.append((char)(b & 0xff));  
  110.   }  
  111.   return result.toString();  
  112. }   
  113. /** 
  114.   * 将字符串转换为byte数组 
  115.   * @param s String 
  116.   * @return byte[] 
  117.   */  
  118. public static byte[] stringToBytes(String s) {  
  119.   return s.getBytes();  
  120. }   
  121. /** 
  122.   * 将高字节数组转换为int 
  123.   * @param b byte[] 
  124.   * @return int 
  125.   */  
  126. public static int hBytesToInt(byte[] b) {  
  127.   int s = 0;  
  128.   for (int i = 0; i < 3; i++) {  
  129.     if (b >= 0) {  
  130.     s = s + b;  
  131.     } else {  
  132.     s = s + 256 + b;  
  133.     }  
  134.     s = s * 256;  
  135.   }  
  136.   if (b[3] >= 0) {  
  137.     s = s + b[3];  
  138.   } else {  
  139.     s = s + 256 + b[3];  
  140.   }  
  141.   return s;  
  142. }   
  143. /** 
  144.   * 将低字节数组转换为int 
  145.   * @param b byte[] 
  146.   * @return int 
  147.   */  
  148. public static int lBytesToInt(byte[] b) {  
  149.   int s = 0;  
  150.   for (int i = 0; i < 3; i++) {  
  151.     if (b[3-i] >= 0) {  
  152.     s = s + b[3-i];  
  153.     } else {  
  154.     s = s + 256 + b[3-i];  
  155.     }  
  156.     s = s * 256;  
  157.   }  
  158.   if (b[0] >= 0) {  
  159.     s = s + b[0];  
  160.   } else {  
  161.     s = s + 256 + b[0];  
  162.   }  
  163.   return s;  
  164. }   
  165. /** 
  166.   * 高字节数组到short的转换 
  167.   * @param b byte[] 
  168.   * @return short 
  169.   */  
  170. public static short hBytesToShort(byte[] b) {  
  171.   int s = 0;  
  172.   if (b[0] >= 0) {  
  173.     s = s + b[0];  
  174.     } else {  
  175.     s = s + 256 + b[0];  
  176.     }  
  177.     s = s * 256;  
  178.   if (b[1] >= 0) {  
  179.     s = s + b[1];  
  180.   } else {  
  181.     s = s + 256 + b[1];  
  182.   }  
  183.   short result = (short)s;  
  184.   return result;  
  185. }   
  186. /** 
  187.   * 低字节数组到short的转换 
  188.   * @param b byte[] 
  189.   * @return short 
  190.   */  
  191. public static short lBytesToShort(byte[] b) {  
  192.   int s = 0;  
  193.   if (b[1] >= 0) {  
  194.     s = s + b[1];  
  195.     } else {  
  196.     s = s + 256 + b[1];  
  197.     }  
  198.     s = s * 256;  
  199.   if (b[0] >= 0) {  
  200.     s = s + b[0];  
  201.   } else {  
  202.     s = s + 256 + b[0];  
  203.   }  
  204.   short result = (short)s;  
  205.   return result;  
  206. }   
  207. /** 
  208.   * 高字节数组转换为float 
  209.   * @param b byte[] 
  210.   * @return float 
  211.   */  
  212. public static float hBytesToFloat(byte[] b) {  
  213.   int i = 0;  
  214.   Float F = new Float(0.0);  
  215.   i = ((((b[0]&0xff)<<8 | (b[1]&0xff))<<8) | (b[2]&0xff))<<8 | (b[3]&0xff);  
  216.   return F.intBitsToFloat(i);  
  217. }   
  218. /** 
  219.   * 低字节数组转换为float 
  220.   * @param b byte[] 
  221.   * @return float 
  222.   */  
  223. public static float lBytesToFloat(byte[] b) {  
  224.   int i = 0;  
  225.   Float F = new Float(0.0);  
  226.   i = ((((b[3]&0xff)<<8 | (b[2]&0xff))<<8) | (b[1]&0xff))<<8 | (b[0]&0xff);  
  227.   return F.intBitsToFloat(i);  
  228. }   
  229. /** 
  230.   * 将byte数组中的元素倒序排列 
  231.   */  
  232. public static byte[] bytesReverseOrder(byte[] b) {  
  233.   int length = b.length;  
  234.   byte[] result = new byte[length];  
  235.   for(int i=0; i<length; i++) {  
  236.     result[length-i-1] = b;  
  237.   }  
  238.   return result;  
  239. }   
  240. /** 
  241.   * 打印byte数组 
  242.   */  
  243. public static void printBytes(byte[] bb) {  
  244.   int length = bb.length;  
  245.   for (int i=0; i<length; i++) {  
  246.     System.out.print(bb + " ");  
  247.   }  
  248.   System.out.println("");  
  249. }   
  250. public static void logBytes(byte[] bb) {  
  251.   int length = bb.length;  
  252.   String out = "";  
  253.   for (int i=0; i<length; i++) {  
  254.     out = out + bb + " ";  
  255.   }   
  256. }   
  257. /** 
  258.   * 将int类型的值转换为字节序颠倒过来对应的int值 
  259.   * @param i int 
  260.   * @return int 
  261.   */  
  262. public static int reverseInt(int i) {  
  263.   int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));  
  264.   return result;  
  265. }   
  266. /** 
  267.   * 将short类型的值转换为字节序颠倒过来对应的short值 
  268.   * @param s short 
  269.   * @return short 
  270.   */  
  271. public static short reverseShort(short s) {  
  272.   short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));  
  273.   return result;  
  274. }   
  275. /** 
  276.   * 将float类型的值转换为字节序颠倒过来对应的float值 
  277.   * @param f float 
  278.   * @return float 
  279.   */  
  280. public static float reverseFloat(float f) {  
  281.   float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));  
  282.   return result;  
  283. }   
  284. }  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA与C++通信之字节序 的相关文章

  • Java NIO 的前生今世 之一 简介

    Java NIO 是由 Java 1 4 引进的异步 IO Java NIO 由以下几个核心部分组成 Channel Buffer Selector NIO 和 IO 的对比 IO 和 NIO 的区别主要体现在三个方面 IO 基于流 Str
  • 如何实现前后端交互

    大概流程 首先我们要实现前端的页面 我们要有一个页面来让我们肉眼可以看见 JS的语法我们要掌握 1因为我们要通过JS来绑定事件 比如我们点击按钮就能发送数据给服务器 或者从服务器获取资源 2我们通过ajax请求来实现向服务器发送请求 3通过
  • 5G,上天了!卫星和基站擦出了火花?

    大家好 我是无线深海 我们好久不见 本期我们来聊聊卫星通信 以及卫星通信和地面通信的融合 非地面网络的故事 对于5G来说 这可能只是后半场的锦上添花 但对仍处于畅想中的6G来说 空天地海一体化通信则是待征服的星辰大海 那么 这就开始咯 为什
  • 天线工作原理以及如何计算天线长度

    一 题记 人们的生活离不开手机 手机离不开无线通信 在家我们可以连接路由器 在外我们可以连接基站 不可否认的是我们的手机都是通过无线电波与路由器或者基站的天线相连接 见过很多天线 有室外的 有室内的 有长的 有方的 还有圆的 天线的各种形状
  • [网络通信] NIO高性能通信实战(一)

    网络通信 NIO高性能通信实战 一 文章目录 网络通信 NIO高性能通信实战 一 NIO 三大核心 缓冲区 Buffer 通道 Channel 选择器 Selector 通道的注册 选择器的检查 零拷贝实现高性能文件传输 小结 REFERE
  • Wireshark使用详解

    文章目录 wireshark简介 抓包原理 抓包 抓包窗口介绍 封包详细信息 Packet Details Pane 过滤信息介绍 显示过滤 抓包过滤 高级功能 数据流追踪 wireshark简介 wireshark是捕获机器上的某一块网卡
  • UDP \TCP详详详详解,你想要的全都有(呕心沥血)

    前言 因特网为应用层提供了两种截然不同的可用运输层协议 一个是UDP 用户数据报协议 一个是TCP 传输控制协议 这两种协议无论是在开发过程中 还是面试问答中 都相当重要 先了解两个定义 多路分解 将运输层报文段中的数据交付到正确的套接字
  • 中兴网络设备交换机路由器查看日志命令方法

    描述 中兴网络设备交换机路由器查看日志命令方法 命令 show logfile
  • 【通原】采样频率往往高于原信号的2倍的原因

    采样信号不是理想冲激信号 在采样前 需要添加一个抗混叠滤波器以避免频谱混叠 带宽越低越难设计 因此采样频率设计为原信号的3 5倍
  • 【精华】搭建个人Web服务器_LAMP

    目录 项目名称 搭建个人Web服务器 LAMP 1 搭建模式 2 搭建步骤 3 常见问题解决方案 项目名称 搭建个人Web服务器 LAMP 1 搭建模式 LAMP 即Linux系统 Apache服务器 MySQL PHP 2 搭建步骤 第一
  • TCP实现socket通信(python)

    socket简介 UDP实现socket通信 python TCP实现socket通信 python 1 套接字工作流程 服务器端先初始化Socket 建立一个套接字 与端口绑定 bind 用 bind 函数来绑定一个端口号和 IP 地址
  • 老猿学5G专栏完结说明

    老猿学5G是因为工作原因促成的 主要目的是为了研究5G的计费架构相关内容 到今天为止 基本上达成目标 因此这个专栏基本上告一段落了 回想这2个多月的日子 从一个对5G相关知识完全不熟悉的小白 到现在基本上知道5G的主要网元和网络架构 3GP
  • 计算机网络综合选择题

    计算机网络综合选择题 TCP IP体系结构中的TCP和IP所提供的服务分别为 A 运输层服务和网络层服务 B 运输层服务和应用层服务 C 链路层服务和网络层服务 D 网络层服务和运输层服务 答案 A 2 对于无序接收的滑动窗口协议 若序号位
  • MQTT 控制报文 - PUBLISH发布消息,PUBACK,PUBREC,PUBREL,PUBCOMP - 第6章

    目录 6 1 PUBLISH 发布消息 6 1 1 固定报头 6 1 1 1 DUP重发标志 6 1 1 2 Qos服务质量等级 6 1 1 3 RETAIN保留标志 6 1 2 可变报头 6 1 3 有效载荷 6 2 PUBACK 发布确
  • 如何选择一款趁手的光纤测试仪

    光纤测试仪是一种用于物理学 电子与通信技术领域的物理性能测试仪器 于1996年11月1日启用 常用光纤测试表有 光功率计 光万用表 稳定光源 光时域反射仪 OTDR 和光故障定位仪 如何选择合适的光纤测试仪 选择光纤测试仪表 一般需考虑以下
  • MQTT 控制报文类型、功能及格式(报文结构) - 第2章

    目录 2 1 MQTT 控制报文的结构 2 2 固定报头 2 2 1 控制报文的类型 2 2 2 控制报文类型的标志位 2 2 3 剩余长度 2 3 可变报头 2 4 有效载荷 2 1 MQTT 控制报文的结构 MQTT控制报文由三部分组成
  • URI和URL、URN的作用和区别

    前言 我们都知道URL是使用Web浏览器等访问Web页面时需要输入的网页地址 而对URI URN的认识可能很少 更有甚者会像我一样 把URI与URL搞混 还以为是一个东西的不同别名 其实URI是URL与URN的超集 URI包括URL和URN
  • 对TCP/IP的深入浅出归纳【WEB开发者】腾讯认证空间

    前段时间做了一个开发 涉及到网络编程 开发过程比较顺利 但任务完成后始终觉得有一些疑惑 主要是因为对网络协议不太熟悉 对一些概念也没弄清楚 后来 我花了一些时间去了解这些网络协议 现在对TCP IP网络协议有了初步的认识 在这里总结出来 可
  • FLUKE DSX-5000 CH线缆测试仪怎么升级到新国标

    FLUKE DSX 5000 CH线缆测试仪怎么升级新标准GB T50312 2016 下面山东朗坤小编带给您FLUKE DSX 5000 CH线缆测试仪升级带有新标准软件的整体步骤 一起来学习吧 升级到5 1之后必须使用Linkware9
  • 项目3:(9)与安川控制器P3000通信模块代码

    1 common h 通信传输的IP地址 typedef struct char serverIp 16 int iPort CONNINFO 定义连接信息数据结构 定义发送数据的结构体 typedef struct double R Bo

随机推荐

  • 视频中的物理要素——提取人们产生共情的元素

    近几年油管 各种小视频的兴起 似乎在为我们打开一扇门 研究角度来看 人们为什么对小视频如此痴迷 短暂的欲望得到满足 为什么通过视觉刺激 听觉刺激可以在观看吃播的时候 观看者也可以得到同样的对食物满足的情绪刺激 很重要的原因是 我们很需要很需
  • 格式化字符串学习

    常见的格式化字符串函数 输出 函数 基本介绍 printf 输出到 stdout fprintf 输出到指定 FILE 流 vprintf 根据参数列表格式化输出到 stdout vfprintf 根据参数列表格式化输出到指定 FILE 流
  • c++ auto类型用法总结

    一 用途 auto是c 程序设计语言的关键字 用于两种情况 1 声明变量时根据初始化表达式自动推断该变量的类型 2 声明函数时函数返回值的占位符 二 简要理解 auto可以在声明变量时根据变量初始值的类型自动为此变量选择匹配的类型 举例 对
  • 安装Zookeeper和Kafka集群

    安装Zookeeper和Kafka集群 本文介绍如何安装Zookeeper和Kafka集群 为了方便 介绍的是在一台服务器上的安装 实际应该安装在多台服务器上 但步骤是一样的 安装Zookeeper集群 下载安装包 从官网上下载安装包 cu
  • LDAP 入门知识

    LDAP的基本概念 LDAP是轻量目录访问协议 Lightweight Directory Access Protocol 的缩写 是一种基于 客户机 服务器模式的目录服务访问协议 其实是一话号码簿 LDAP是一种特殊的数据库 LDAP 目
  • jpa方法名命名规则

    一 常用规则速查 1 And 并且2 Or 或3 Is Equals 等于4 Between 两者之间5 LessThan 小于6 LessThanEqual 小于等于7 GreaterThan 大于8 GreaterThanEqual 大
  • Auto.js实现i茅台自动化申购

    i茅台自动化申购 文章目录 i茅台自动化申购 前言 一 前提条件 二 代码示例 总结 前言 现在茅台行情十分火热 茅台集团推出了i茅台APP供大家申购 下面介绍使用Auto js实现自动化申购 一 前提条件 需要下载Auto js的apk
  • 40.1自定义组建el-cascader

    1 子组件
  • 51单片机模拟救护车的警报声

    include
  • React Hooks --useEffect

    再用class写组件时 经常会用到生命周期函数 来处理一些额外的事情 副作用 和函数业务主逻辑关联不大 特定时间或事件中执行的动作 比如请求后端数据 修改Dom等 在React HookS中也需要类似的生命周期函数 useEffect由此诞
  • t检验与方差分析的区别和联系

    一 t检验和方差分析的应用 1 t检验的应用 t检验主要用于比较两组数据之间的均值是否存在显著差异 例如比较两种手术方式对患者的术后疼痛程度是否有显著差异 在医学研究中 t检验可以用于比较不同手术方式或药物对患者的疗效差异 例如 我们可以采
  • kettle的下载安装以及问题点

    1 kettle下载以安装 1 kettle的官网下载地址 Pentaho from Hitachi Vantara Browse Files at SourceForge net 2 如果需要下载其他版本 直接点击对应的版本Name 8
  • 闪回数据归档+闪回数据归档区+创建闪回数据归档区+创建闪回数据归档区案例+为数据归档区添加表空间+为数据归档区删除表空间+数据归档区修改数据保留时间+删除数据归档区

    闪回数据归档 1 它将改变的数据另外存储到特定的闪回数据归档区中 从而让闪回不再受撤销数据的限制 提高数据的保留时间 2 闪回数据归档中的数据行可以保留几年甚至几一年 3 闪回数据归档并不针对所有的数据改变 它只记录update和delet
  • 小程序搭建mqtt服务器,微信小程序连接MQTT服务器实现控制Esp8266LED灯

    上一篇文章已实现Esp8266开发板与MQTT服务器连接实现控制LED灯 这篇文章记录继上篇的功能接入微信小程序实现LED灯的控制 先理解一个概念 微信小程序订阅MQTT服务器一个主题 Esp8266订阅相同的主题时 微信小程序发送给MQT
  • python raise

    当程序出现错误 python会自动引发异常 也可以通过raise显示地引发异常 一旦执行了raise语句 raise后面的语句将不能执行 演示raise用法 try s None if s is None print s 是空对象 rais
  • 各类数据类型sizeof的大小

    前言 之前总是误认为指针变量的大小和指针所指向的对象有关系 搞网络驱动时 使用kmalloc做内存申请时发现了一些端倪 先简单介绍下sizeof sizeof 是一个关键字 它是一个编译时的运算符 用于判断变量或数据类型的字节大小 size
  • UE4智慧城市开发流程梳理

    智慧城市开发流程梳理 摸索UE智慧城市相关做的总结梳理 并不是很专业 如有差错欢迎指正 1 GIS数据获取 谷歌地图 地理数据网站等中获取 或者使用第三方软件下载 水经注GIS ESRI有的ArcGIS online Cesium的ION
  • Redis连接池的介绍与使用

    一 介绍 说明 通过golang对redis操作 还可以通过redis连接池 流程如下 事先初始化一定数量的连接 放入到连接池 当go需要操作redis时 直接从redis连接池取出连接即可 这样可以节省临时获取redis连接的时间 从而提
  • Redis 分布式锁实现

    Redis 分布式锁 分布式锁 满足分布式系统或集群模式下多进程可见并且互斥的锁 特点 多线程可见 互斥 高可用 高性能 高并发 安全性 可重入性 重试机制 锁超时自动续期等 加锁之后 对整个分布式集群都有效 基于数据库 redis缓存 使
  • JAVA与C++通信之字节序

    1 BIG ENDIAN LITTLE ENDIAN跟多字节类型的数据有关的比如int short long型 而对单字节数据byte却没有影响 BIG ENDIAN就是低位字节排放在内存的低端 高位字节排放在内存的高端 而LITTLE E