查漏补缺

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了查漏补缺相关的知识,希望对你有一定的参考价值。

摘自《老马说编程

 

计算机程序的思维逻辑 (4) - 整数的二进制表示与位运算

Java中不支持直接写二进制常量,比如,想写二进制形式的11001,Java中不能直接写,可以在前面补0,补足8位,为00011001,然后用16进制表示,即 0x19。

计算不精确,怎么办呢?大部分情况下,我们不需要那么高的精度,可以四舍五入,或者在输出的时候只保留固定个数的小数位。

如果真的需要比较高的精度,一种方法是将小数转化为整数进行运算,运算结束后再转化为小数,另外的方法一般是使用十进制的数据类型,这个没有统一的规范,在Java中是BigDecimal,运算更准确,但效率比较低,本节就不详细说了。

 

在Java中,可以方便的使用Integer和Long的方法查看整数的二进制和十六进制表示,例如:

int a = 25;

Integer.toBinaryString(a); //二进制
Integer.toHexString(a); //十六进制
Long.toBinaryString(a); //二进制
Long.toHexString(a); //十六进制

 

 

计算机程序的思维逻辑 (5) - 小数计算为什么会出错?

如果你想查看浮点数的具体二进制形式,在Java中,可以使用如下代码:

Integer.toBinaryString(Float.floatToIntBits(value))
Long.toBinaryString(Double.doubleToLongBits(value));

 

java中处理字符串的类有String,String中有我们需要的两个重要方法:

public byte[] getBytes(String charsetName),这个方法可以获取一个字符串的给定编码格式的二进制形式
public String(byte bytes[], String charsetName),这个构造方法以给定的二进制数组bytes按照编码格式charsetName解读为一个字符串。

 

 

计算机程序的思维逻辑 (6) - 如何从乱码中恢复 (上)?

Ascii码是基础,一个字节表示,最高位设为0,其他7位表示128个字符。其他编码都是兼容Ascii的,最高位使用1来进行区分。

西欧主要使用Windows-1252,使用一个字节,增加了额外128个字符。

中文大陆地区的三个主要编码GB2312,GBK,GB18030,有时间先后关系,表示的字符数越来越多,且后面的兼容前面的,GB2312和GBK都是用两个字节表示,而GB18030则使用两个或四个字节表示。

香港台湾地区的主要编码是Big5。

如果文本里的字符都是Ascii码字符,那么采用以上所说的任一编码方式都是一一样的。

UTF- 32/UTF-16/UTF-8都在做一件事,就是把Unicode编号对应到二进制形式,其对应方法不同而已。UTF-32使用4个字节,UTF-16 大部分是两个字节,少部分是四个字节,它们都不兼容Ascii编码,都有字节顺序的问题。UTF-8使用1到4个字节表示,兼容Ascii编码,英文字符 使用1个字节,中文字符大多用3个字节。

 

 

计算机程序的思维逻辑 (8) - char的真正含义
在 Java内部进行字符处理时,采用的都是Unicode,具体编码格式是UTF-16BE。简单回顾一下,UTF-16使用两个或四个字节表示一个字 符,Unicode编号范围在65536以内的占两个字节,超出范围的占四个字节,BE (Big Endian)就是先输出高位字节,再输出低位字节,这与整数的内存表示是一致的。

char本质上是一个固定占用两个字节的无符号正整数,这个正整数对应于Unicode编号,用于表示那个Unicode编号对应的字符。

由于固定占用两个字节,char只能表示Unicode编号在65536以内的字符,而不能表示超出范围的字符。

 

 

计算机程序的思维逻辑 (9) - 条件执行的本质

switch的转换和具体系统实现有关,如果分支比较少,可能会转换为跳转指令。但如果分支比较多,使用条件跳转会进行很多次的比较运算,效率比较低,可能会使用一种更为高效的方式,叫跳转表。跳转表是一个映射表,存储了可能的值以及要跳转到的地址,形如:

值1 代码块1的地址
值2 代码块2的地址
...
值n 代码块n的地址
跳转表为什么会更为高效呢?因为,其中的值必须为整数,且按大小顺序排序。按大小排序的整数可以使用高效的二分查找,即先与中间的值比,如果小于中间的值则在开始和中间值之间找,否则在中间值和末尾值之间找,每找一次缩小一倍查找范围。如果值是连续的,则跳转表还会进行特殊优化,优化为一个数组,连找都不用找了,值就是数组的下标索引,直接根据值就可以找到跳转的地址。即使值不是连续的,但数字比较密集,差的不多,编译器也可能会优化为一个数组型的跳转表,没有的值指向default分支。

程序源代码中的case值排列不要求是排序的,编译器会自动排序。之前说switch值的类型可以是byte, short, int, char, 枚举和String。其中byte/short/int本来就是整数,在上节我们也说过,char本质上也是整数,而枚举类型也有对应的整 数,String用于switch时也会转换为整数(通过hashCode方法,后文介绍),为什么不可以使用long呢?跳转表值的存储空间一般为32位,容纳不下long。

以上是关于查漏补缺的主要内容,如果未能解决你的问题,请参考以下文章

查漏补缺——java多态

js知识查漏补缺

2019/5/12 查漏补缺

《CSS权威指南》基础复习+查漏补缺

第八周查漏补缺

Java面试查漏补缺