Java面试题-说说八大基础数据类型

刚毕业那会出来面试,端端正正坐在面试官前面,微笑着看着他,面试官也微笑着看着我。

面试官:看你刚毕业,我来考考你一些Java基础问题吧。

我:好!(心中狂喜,Java基础也准备了好久)

面试官:你来写一下八大基础数据类型吧

我心想:(啥?八大基础类型?那不是我大一学的吗?都有啥来着?)

我:我凭着记忆力写下了Integer,String,Double,Float,Long....额,还有几个不记得了...

面试官还是微笑着看着我:你确定你写的这些都有吗?

我:(为了表现出自己的自信说到)这几个我还是确定的...其他的几个不记得了

面试官沉思了下说到:好的,我知道了,那今天面试就到这里了,你先回去等结果吧。

我:????(我花了两小时才过来,面试不到2分钟,就结束了?)

然后他就出去了,接着我就被人事带出了门....然后就没有然后了...

回去的路上怎么想都不对劲,回到家中查了下才发现我错的离谱,好家伙,我把学的知识都还回去了!!

于是那次面试成了我一辈子的痛!!后来整理相关资料发现里面可以深挖的点确实比较多,于是便有了今天的文章。

一、八大基础数据类型

这个知识点我要记一辈子!!!o(╥﹏╥)o

  • 整型:byte, short, int, long
  • 字符型:char
  • 浮点型:float, double
  • 布尔型:boolean

 

①、byte

二进制位数:8

包装类:java.lang.Byte

最小值:Byte.MIN_VALUE= -128(-2^7)

最大值:Byte.MAX_VALUE= 127(2^7-1)

默认值:0

 

相关测试用例:

byte a = 127;
byte b = 1;
a += b;
//a = a + b;  //强制类型提升造成直接报错
结果:a = -128
//-------------------------------
byte a = 127;
byte b = 127;
a += b;
结果:a = -2

//负数在现代计算机里一般用补码表示:最高位是符号位,其余位为数字的原码取反+1。
//1000 0000还原为原码:最高位是1,表示负数,
//剩余的各位取反 111 1111 再+1 得到 1000 0000, +128的原码,整个数为-128

“+=”是java中的一个运算符,而不是两个,所以在运算时 会进行自动类型转换,也就是低级变量可以直接转换为高级变量。所以在编译时没有报错。

 

②、short

二进制位数:16

包装类:java.lang.Short

最小值:Short.MIN_VALUE = -32768(-2^15)

最大值:Short.MAX_VALUE = 32767(2^15 - 1)

默认值:0

 

③、int

二进制位数:32

包装类:java.lang.Integer

最小值:Integer.MIN_VALUE= -2,147,483,648(-2^31)

最大值:Integer.MAX_VALUE= 2,147,483,647(2^31 - 1)

默认值:0

 

int和Integer的区别

  • Integer是int的包装类;int是基本数据类型;
  • Integer变量必须实例化后才能使用;int变量不需要;
  • Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
  • Integer的默认值是null;int的默认值是0。

④、long

二进制位数:64

包装类:java.lang.Long

最小值:Long.MIN_VALUE=-9,223,372,036,854,775,808(-2^63)

最大值:Long.MAX_VALUE=9,223,372,036,854,775,807(2^63 -1)

默认值:0L

注意:"L"理论上不分大小写,但是若写成"l"容易与数字"1"混淆,不容易分辩。所以最好大写。

 

⑤、float

二进制位数:32

包装类:java.lang.Float

最小正非零值:Float.MIN_VALUE=1.4E-45 (2^-149)(正数)

最大值:Float.MAX_VALUE=3.4028235E38 (2^128 - 1)

默认值:0.0f

 

|-------- 31 -------|------------ 30-23 ------------ |------------ 22-0 ------------|

   符号位(sign)         指数部分(exp)                       小数部分(mag)

  • sign:符号位就一位,0表示正数,1表示负数
  • exp: 指数部分,无符号正数
  • mag:小数部分,定点小数,小数点在最左边。
  • float的表达式 :  pow(-1,sign)  *  (1+mag)  * pow(2,exp-127)

 

⑥、double

二进制位数:64

包装类:java.lang.Double

最小正非零值:Double.MIN_VALUE=4.9E-324 (2^-1074)(正数)

最大值:Double.MAX_VALUE=1.7976931348623157E308 (2^1024 - 1)

默认值:0.0d

 

float 和int 都是4字节,但是最大值却比long还要大很多,因为 整数在计算机底层采用补码的形式表示,除去首位的符号位,剩余的位数即表示数值的范围,也就是位数越多,范围越大。

float和double才用的是IEEE754浮点数标准

IEEE754标准包含一组实数的二进制表示法。它有三部分组成:

  • 符号位
  • 指数位
  • 尾数位

java中常数默认是int类型的,所以一个常数不能超过Interger.MAX_VALUE,你在定义 long w=12345678901; 时会报错,是因为这个常数已经超过了Int类型能够表示的最大数,所以在定义long类型时,需要在常数后面加 l 或者 L 

 

⑦、boolean

包装类:java.lang.Boolean

默认值:false

只有两个取值:true 和 false;

boolean数据类型表示一位的信息;

 

⑧、char

二进制位数:16

包装类:java.lang.Character

最小值:\u0000(即为 0)

最小值:\uFFFF(即为65535)

char ch = 'a';
 
// Unicode 字符表示形式
char uniChar = '\u039A'; 
 
// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };

转义序列

前面有反斜杠(\)的字符代表转义字符,它对编译器来说是有特殊含义的。下面列表展示了Java的转义序列:

转义序列

描述

\t

在文中该处插入一个tab键

\b

在文中该处插入一个后退键

\n

在文中该处换行

\r

在文中该处插入回车

\f

在文中该处插入换页符

\'

在文中该处插入单引号

\"

在文中该处插入双引号

\\

在文中该处插入反斜杠

Character 有以下方法:

序号

方法与描述

1

isLetter()

是否是一个字母

2

isDigit()

是否是一个数字字符

3

isWhitespace()

是否是一个空白字符

4

isUpperCase()

是否是大写字母

5

isLowerCase()

是否是小写字母

6

toUpperCase()

指定字母的大写形式

7

toLowerCase()

指定字母的小写形式

8

toString()

返回字符的字符串形式,字符串的长度仅为1

二、包装类型

为了编程的方便引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

基本数据类型: boolean,char,byte,short,int,long,float,double
封装类类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

 

三、自动装箱和自动拆箱

①、自动装箱:将基本数据类型重新转化为对象

// 声明一个Integer对象,用到了自动的装箱:
//解析为:Integer num = Integer.valueOf(9);
Integer num = 9;

9是属于基本数据类型的,原则上它是不能直接赋值给一个对象Integer的。但jdk1.5后你就可以进行这样的声明,自动将基本数据类型转化为对应的封装类型,成为一个对象以后就可以调用对象所声明的所有的方法。

②、自动拆箱:将对象重新转化为基本数据类型

/ /声明一个Integer对象
Integer num = 9;
// 进行计算时隐含的有自动拆箱
System.out.print(num--);

因为对象是不能直接进行运算的,而是要转化为基本数据类型后才能进行加减乘除。

四、重点

①、Integer比较相关

Integer a = 127;
Integer b = 127;

Integer c = 128;
Integer d = 128;

Integer e = -128;
Integer f = -128;

Integer g = -129;
Integer h = -129;

Integer i = new Integer(1);
Integer j = new Integer(1);

System.out.println(a == b);//true
System.out.println(c == d);//false
System.out.println(e == f);//true
System.out.println(g == h);//false
System.out.println(i == j);//false

归结于java对于Integer与int的自动装箱与拆箱的设计,是一种模式:叫享元模式(flyweight)。

(1)加大对简单数字的重利用,Java定义在自动装箱时对于在-128~127之内的数值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象。

(2)而如果在-128~127之外的数,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。

 

所以Integer比较的时候尽量用对象的equals方法,因为Integer中重写了equals方法

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}

源码分析:

当给一个Integer对象赋一个int值的时候,会调用Integer类的静态方法valueOf

public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix));
}

/**
 * (1)在-128~127之内:静态常量池中cache数组是static final类型
 * cache数组对象会被存储于静态常量池中。
 * cache数组里面的元素却不是static final类型,
 * 而是cache[k] = new Integer(j++),那么这些元素是存储于堆中,
 * 只是cache数组对象存储的是指向了堆中的Integer对象(引用地址)
 * 
 * (2)在-128~127 之外:新建一个 Integer对象,并返回。
 */
public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high) {
            return IntegerCache.cache[i + (-IntegerCache.low)];
        }
        return new Integer(i);
}

/**
      * 缓存支持自动装箱的对象标识语义 -128和127(含)。
      * 缓存在第一次使用时初始化。 
      * 缓存的大小可以由-XX:AutoBoxCacheMax = <size>选项控制。
      * 在VM初始化期间,java.lang.Integer.IntegerCache.high
      * 属性可以设置并保存在私有系统属性中
     */
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++) {
                cache[k] = new Integer(j++); // 创建一个对象
            }
        }
        private IntegerCache() {}
}

 

②、计算斐波那契数列(0、1、1、2、3、5、8、13、21、34、……)第n项的值

这个数列从第3项开始,每一项都等于前两项之和。这道题当年面试的时候没有考虑到最大值的情况,直接使用int去实现,结果.......面试跪了!!😢

经我测试,当 value = 92,结果为:7540113804746346429,该值超过了long的最大值,这时可以改用BigInteger类型去实现,代码如下:

@JvmStatic
fun main(args: Array<String>) {
    println("请输入一个数:")
    val reader = BufferedReader(InputStreamReader(System.`in`))
    val num = reader.readLine().toInt()
    val answer = fibonacciTest(num)
    println("第${num}个斐波那契数为:$answer")
}

private fun fibonacciTest(value: Int): BigInteger {
    if (value < 2) return BigInteger(value.toString())
    var first = BigInteger("0")
    var second = BigInteger("1")
    var temp = BigInteger("0")
    for (i in 2..value) {
        temp = first.add(second)
        first = second
        second = temp
    }
    return temp
}

就是以上这些,待我发现新的易错的知识点再来补充~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值