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++通信之字节序 的相关文章

  • 网络数据包的抓包(解析数据包内容)

    使用原始套接字接收 recvfrom reav read等 时 可以接收到完整的数据包 数据组装 拆解过程 数字代表上层协议的类型 完整数据包为 传输数据包内容 链路层包头 网络层包头 传输层包头 应用层数据 Ethernet MAC 封包
  • 福禄克网线测试仪的使用方法

    福禄克网线测试仪是对铜缆的1 2 3 4 5 6 7 8导线逐根 或逐对 进行测试的工具 它可以测出的主要故障有 开路 短路 反接 错对和串绕 开路故障 开路是指铜缆中一根或多根导线中间有断开的地方 这通常是由机械外力造成 线对中短路故障
  • MQTT 控制报文 - SUBSCRIBE订阅报文,SUBACK,UNSUBSCRIBE,UNSUBACK - 第5章

    目录 5 1 SUBSCRIBE 订阅主题报文 5 1 1 固定报头 5 1 2 可变报头 5 1 3 有效载荷 5 2 SUBACK 订阅确认 5 2 1 固定报头 5 2 2 可变报头 5 2 3 有效载荷 5 3 UNSUBSCRIB
  • 计算机网络基础知识总结

    计算机网络学习的核心内容就是网络协议的学习 网络协议是为计算机网络中进行数据交换而建立的规则 标准或者说是约定的集合 因为不同用户的数据终端可能采取的字符集是不同的 两者需要进行通信 必须要在一定的标准上进行 一个很形象地比喻就是我们的语言
  • 中兴网络设备交换机路由器查看日志命令方法

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

    采样信号不是理想冲激信号 在采样前 需要添加一个抗混叠滤波器以避免频谱混叠 带宽越低越难设计 因此采样频率设计为原信号的3 5倍
  • 老猿学5G扫盲贴:PDU协议数据单元、PDU连接业务和PDU会话的功能详解

    专栏 Python基础教程目录 专栏 使用PyQt开发图形界面Python应用 专栏 PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一 PDU 关于PDU在百度百科是这样定义的 协议数据单元PDU Protocol Dat
  • [网络通信] 什么是零拷贝?

    什么是零拷贝 文章目录 什么是零拷贝 1 Java 实现应用缓存零拷贝 2 底层零拷贝实现机制 2 1 mmap 2 2 sendfile 2 3 splice 小结 REFERENCES 我们在写一个服务端程序时 Web Server或者
  • 计算机网络综合选择题

    计算机网络综合选择题 TCP IP体系结构中的TCP和IP所提供的服务分别为 A 运输层服务和网络层服务 B 运输层服务和应用层服务 C 链路层服务和网络层服务 D 网络层服务和运输层服务 答案 A 2 对于无序接收的滑动窗口协议 若序号位
  • 王道考研计算机网络第二章--物理层

    目录 2 1通信基础 2 1 1物理层基本概念 1物理层基本概念 2 1 2数据通信基础知识 1典型的数据通信模型 2数据通信相关术语 3三种通信方式 4两种数据传输方式 2 1 3码元 波特 速率 带宽 1码元 2速率 波特 带宽 2 1
  • 三. Netty 进阶

    Netty学习之路 一 NIO基础 二 Netty 入门 三 Netty 进阶 四 Netty 优化与源码 学完netty手写了一个rpc项目 链接 https gitee com springchuntian1 netty rpc 笔记源
  • 扩频技术详解

    扩频是什么 扩频是一种信息处理传输技术 扩频技术是利用同欲传输数据 信息 无关的码对被传输信号扩展频谱 使之占有远远超过被传送信息所必需的最小带宽 扩频技术原理 在发端输入的信息先经信息调制形成数字信号 然后由扩频码发生器产生的扩频码序列去
  • netty权威指南学习笔记二——netty入门应用

    经过了前面的NIO基础知识准备 我们已经对NIO有了较大了解 现在就进入netty的实际应用中来看看吧 重点体会整个过程 按照权威指南写程序的过程中 发现一些问题 当我们在定义handler继承ChannelHanderAdapter时候
  • UDP及TCP通信对比讲解

    概述 TCP是面向连接的协议 也就是说在通信发送数据前 必须和对方建立连接 以数据流的模式传播 传输过程中不会有数据丢失 速率上比UDP要慢不少 适用于对数据准确性要求高 速度可以相对慢的场景 如发送或接收邮件 打电话 微信消息传输等等 U
  • 前端Base64编码知识,一文打尽

    原文 https juejin cn post 6989391487200919566 作者 云的世界 掘金专栏 前端基础进阶 大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 前言 本
  • HttpClient介绍

    本文内容整理自 https blog csdn net w372426096 article details 82713315 HttpClient相比传统JDK自带的URLConnection 增加了易用性和灵活性 它不仅使客户端发送Ht
  • 关于光纤收发器的一些基本常识介绍

    光纤收发器是网络数据传输中必不可缺少的一种设备 那么 什么是光纤收发器呢 光纤收发器都有什么组成的呢 光纤收发器是怎么分类的呢 光纤收发器有哪些特点呢 光纤收发器在数据传播过程中起到什么作用呢 接下来我们就跟随飞畅科技的小编一起来详细了解下
  • 【详解】静态Web服务器搭建代码实现_Python

    目录 1 浏览器网络请求流程 2 搭建python自带静态web服务器 2 1 静态web服务器开发流程 2 2 返回指定页面 2 3 多任务版服务器 2 4 面向对象服务端 3 动态端口 1 浏览器网络请求流程 浏览器首先链接DNS服务器
  • JAVA socket编程实例

    转载文章 原作者无从考证 感谢作者的无私奉献 事实上网络编程简单的理解就是两台计算机相互通讯数据而已 对于程序员而言 去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了 Java SDK提供一些相对简单的Api来完成这些工作 Soc
  • 项目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