Java基础复习DayOne:数据类型,细讲char类型与编码关系

所以针对Unsigned的整形,基本数据类型的包装类有对应的API的

这里首先要认识的一点是,只要不溢出,加法、减法和乘法都能正常计算,但除法是会出问题的

Byte.toUnsignedInt

这个API的功能是针对Unsigned的Byte的转化成Unsigned

在这里插入图片描述

从源码上看,其实就是将其强制转换成int,相当于扩大了位数,然后通过与上0xff,0xff是十六进制,转化成二进制就是11111111,这个与运算的作用其实为了限制位数,因为byte是1个字节,顶多只有8位,超过8位的那些都不要,对于Unsigned来说,应该都为0.

Integer.divideUnsigned

这个API的功能是针对Unsigned的int类型除法的

在这里插入图片描述

在这里插入图片描述

可以看到,他的处理与Byte一样,都是转化成更高位的类型,这里转化成long,然后通过与运算舍弃后面多出来的位数(其实是改为0)

Integer.remainderUnsigned

这个是用来求余数的

在这里插入图片描述

可以看到同样也是转化成更高位去处理

Long.divideUnsigned

现在Long没有更高位了怎么办呢?

下面是源码

public static long divideUnsigned(long dividend, long divisor) {

//divisor是除数

//而divident是被除数

//首先判断除数是否为Unsigned(<0就代表为unsigned,只不过将符号位看成1,变为负数)

if (divisor < 0L) { // signed comparison

// Answer must be 0 or 1 depending on relative magnitude

// of dividend and divisor.

//可以看到这里的返回值只有0和1

//这是因为除数为unsigned,根据整形的向下取整规则

//得到的结果只能为1和0(dividend大于divisor就为1,小于就为0)

//dividend不可能为divisor的两倍(因为位数不过)

return (compareUnsigned(dividend, divisor)) < 0 ? 0L :1L;

}

//如果除数不是Unsigned,那么就判断被除数

if (dividend > 0) // Both inputs non-negative

//如果被除数不是Unsigned,就直接除就好

return dividend/divisor;

else {

/*

  • For simple code, leveraging BigInteger. Longer and faster

  • code written directly in terms of operations on longs is

  • possible; see “Hacker’s Delight” for divide and remainder

  • algorithms.

*/

//如果是,那么就将除数和被除数换成更高位的BigInt型,去进行

return toUnsignedBigInteger(dividend).

divide(toUnsignedBigInteger(divisor)).longValue();

}

}

下面我们就来看看compareUnsigned方法

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

MIN_VALUE是代表长整形可以取的最小值,也就是 − 2 63 -2^{63} −263

可以看到,具体的过程就是让两个数减去最小值,然后进行比较

原理是,即使是Unsigned,只要减去了最小值,就不会超过有符号位的范围,然后通过比较减去后的大小,就可以判断除数和被除数谁大谁小,然后就返回0和1。

浮点型


浮点型有两种类型,一种为float,一种为double。

这里,我们认识一下精度损失

在两种浮点型,小数都是使用二进制表示的,比如 2 − 1 或 者 2 − 2 2{-1}或者2{-2} 2−1或者2−2,也就是0.5,0.125这些,也就是说,有一些小数是无法使用二进制表示的,只能通过后面的位数进行无限逼近,所以就会产生精度损失。

那什么是双精度和单精度呢?

这是根据double和float的位数来区分的,double为8字节,而float为4字节,所以double可以使用更多位数进行逼近,所以double会更加精确。

这里要注意的是,所有的浮点数计算都遵循IEEE754规范

对于表示溢出和出错情况,使用了三个特殊的浮点数值去表示

  • 正无穷大

  • 负无穷大

  • NaN(不是一个数字)

在这里插入图片描述

字符型


char类型本来用来表示单个字符,但如今有些Unicode字符可以用一个char表示,也就是两个字节,但有时一些Unicode字符需要用多个字节表示,也就是使用多个char表示

char类型的值可以表示为十六进制值,从\u0000~\uffff。这里是\u充当了一个转义序列的功能,同时\u转义序列是可以出现在字符常量或字符串,所以使用注释和参数的时候,要注意一下

在Java中,char类型描述了UTF-16编码中的一个代码单元

Unicode

在认识UTF-16前,我们需要认识Unicode

Unicode其实相当于一本很厚的字典,里面储存了世界上所有语言的字符,使用Unicode码点唯一地对应一个字符。

Unicode是没有规定字符对应的二进制码占用的空间是多少,那么问题来了,以“汉”字为例,它的Unicode码点为0x6c49,对应的二进制为110110001001001,也就是15位二进制,也就说明了,这个字需要用2个字节去存储这个字,那么,对于其他字体,很有可能出现3个字节,或者更多的字节去存储,对于计算机来说,计算机怎么知道这两个字节表示的是一个字符,而不是与后面的字节形成一个字符?

所以,为了解决Unicode的这个问题,新的编码方式UTF-8、UTF-16和UTF-32就出现了

UTF-8

UTF其实是Unicode Transformation Format的缩写,即统一Unicode编码转换格式

UTF-8的特点就是可变长,即对于不同长度字节的字符有很好的兼容性

编码规则如下

  • 对于单个字节的字符(也就是基本字符),也就是8位,会将第一位设为0,后面的七位会对应这个字符的Unicode码点,因此对于0~ 2 7 2^7 27号字符是完全可以的,甚至与ASCII(另一种编码方式,只不过不支持中文只有英文和符号)完全相同(这时候可能会有人说那么对于 2 8 至 2 7 28至27 28至27里面的字符呢?其实这一段被分在了使用2个字节表示)

  • 对于需要使用N个字节来表示的字符(N>1),第一个字节的前N位都设为1,第N+1位设为0(用来记录这个字符是用多少个字节来存储的,让计算机可以识别出),剩余后面的N-1个字节的前两位都要设置为10,剩下的二进制位则使用这个字符的Unicode码点来进行补充

| Unicode十六进制码点范围 | UTF-8二进制 |

| — | — |

| 0000 0000 ~ 0000 007F(注意这里只有7位) | 0xxxxxxx(对应表示码点的七位) |

| 0000 0080 ~ 0000 07FF(注意这里为11位) | 110xxxxx 10xxxxxx (对应码点11位) |

| 0000 0800 ~ 0000 FFFF(注意这里位16位) | 1110xxxx 10xxxxxx 10xxxxxx(对应码点16位) |

| 0001 0000 ~ 0010 FFFF(这里为18位) | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(虽然超过码点位数,但不影响表示) |

通过表格,可以看到UTF-8d的编码其实很简单,下面还是以"汉"为例,具体说一下如何进行UTF-8的编码和解码的

汉的编码为0x00006c49,对应在Unicode十六进制码点范围的第三行,所以对应的UTF-8二进制为 1110 x x x x 10 x x x x x x 10 x x x x x x 1110xxxx 10xxxxxx 10xxxxxx 1110xxxx10xxxxxx10xxxxxx,然后将0x0006c49变为二进制为0x0110110001001001,然后填入到x里面即可(从第最后一位开始),结果为111001101011000110001001,然后再转换成十六进制为:0xE6 0xB7 0x89

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

我个人认为,如果你想靠着背面试题来获得心仪的offer,用癞蛤蟆想吃天鹅肉形容完全不过分。想必大家能感受到面试越来越难,想找到心仪的工作也是越来越难,高薪工作羡慕不来,却又对自己目前的薪资不太满意,工作几年甚至连一个应届生的薪资都比不上,终究是错付了,错付了自己没有去提升技术。

这些面试题分享给大家的目的,其实是希望大家通过大厂面试题分析自己的技术栈,给自己梳理一个更加明确的学习方向,当你准备好去面试大厂,你心里有底,大概知道面试官会问多广,多深,避免面试的时候一问三不知。

大家可以把Java基础,JVM,并发编程,MySQL,Redis,Spring,Spring cloud等等做一个知识总结以及延伸,再去进行操作,不然光记是学不会的,这里我也提供一些脑图分享给大家:

希望你看完这篇文章后,不要犹豫,抓紧学习,复习知识,准备在明年的金三银四拿到心仪的offer,加油,打工人!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
享给大家:

[外链图片转存中…(img-fQM8RlI5-1713435248924)]

[外链图片转存中…(img-Ki7Zdjea-1713435248924)]

[外链图片转存中…(img-lSqBXt8A-1713435248924)]

希望你看完这篇文章后,不要犹豫,抓紧学习,复习知识,准备在明年的金三银四拿到心仪的offer,加油,打工人!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值