最近面试了很多候选人,发现很多人都不太重视基础,甚至连工作十几年,项目经验十几页的老程序员,框架学了一大堆,但是很多 Java 相关的基础知识却很多都答不上来。还有很多人会回答,只知道要用,但是从来不会去看看它具体是怎么实现的。

我们都知道作为合格的程序员,基本功不扎实会导致你的程序出现许多你难以诊断的诡异问题,例如产生过大开销(频繁GC导致程序卡顿或者产生OOM),Integer 缓存机制产生的诡异现场(下面会详细说),所以就有想写一个关于面试相关系列的文章,把常见又容易采坑的面试问题总结一下,今天想站在面试官的角度去和大家聊聊一些面试的基础题目,以及尽可能指导大家如何给出一个能让面试官满意的答复

基本回答

int 是 8 个基本数据类型(boolean, byte, short, char, int, float, double, long)之一的整形类型,大小占用4字节,取值范围是正负 2 的 32(4 * 8)次幂,Java 虽然号称一切都是对象,但是基本数据类型是例外

Integr 是 int 的包装类,是 JDK 1.5 中引入,提供了字符串转换,数学运算,泛型,自动拆箱装箱等实用功能,极大简化了相关的编程难度

聊聊 Intger 的值缓存范围

下面给出一个典型例子,也是很多人踩过的坑,程序如下(建议自己在机器上实践操作下)

Integer a1 = 127,  b1 = 127;
Integer a2 = 128, b2 = 128;
System.out.println(a1 == b1);       // true
System.out.println(a2 == b2);       // false
包装类缓存机制的原因

可以思考下为什么会出现以上这种诡异的情况,然后我们下面可以看看 Integer.valueOf 的源码

// Integer.valueOf 的源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)   
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
} private static class IntegerCache {   
static final int low = -128;   
static final int high;
static final Integer cache[]; static {
int h = 127;
...
high = h;
}
}

源码之内无秘密,我们可以看出来出现以上问题的原因是原由 JDK 对 Integer 构造的改进引入缓存机制导致的,传统构造 Integer 的方式是直接调用构造器 new 一个对象,但是在考察和调研后发现大多数人使用 Integer 都集中在较小的范围,因此 JDK 为 Integer.valueOf 增强了一个缓存机制来改善构造对象的性能开销(没错,自动拆箱装箱反编译后也是调用 valueOf() 方法实现构造对象)Java 官方文档给出 Integer 缓存范围是 -128 ~ 127

这里面细节很多,我们就不一一讲述,到这里我们已经可以得出结果了,就是

  1. a1 == b1 对象的引用都是从缓存中取出,实际上是相同对象,所以结果的 true
  2. a2 == b2 是因为128已经超过了缓存值的范围,Integer 通过 new 构造的对象,因为 == 比较的对象的引用而不是对象的值,所以结果自然就为 false

通过以上案例可以我们可以举一反三,不仅仅 Integer 有缓存机制,整个包装类都有缓存机制:

  • Boolean 缓存了 true/false 实例,也就是说 Boolean 只会有 Boolean.TRUE/FALSE 两个常量实例
  • Short 缓存范围是 -128 到 127 之间
  • Byte 范围有限,全部数值都被缓存
  • 等等……

如果继续深挖缓存,例如明确会频繁使用更大范围的 Integer 值得时候,我们可以使用 JVM 提供的参数

-XX:AutoBoxCacheMax=N
Integer 用起来有什么注意事项吗?
  1. 应当避免无意的使用拆装箱

    自动拆/装箱实际上是 Java 一种编译期的优化(技巧),算是一种语法糖,只是 Java 在编译期帮你自动转化,最终生成的字节码还是和你自己转换是一样的,无意的创建十万个对象对于程序的内存开销和处理速度来说是巨大的代价
  2. 包装类应避免使用 == 运算符进行值比较
  3. 注意缓存机制的范围
总结

以上我只大概列出的典型回答,其实对于大多数面试能回答以上内容就已经算可以及格了,有的公司面试官以喜欢追问出名,直到候选人回答说不知道,才会打住,这道看似简单的题目,其实可以深挖的点还有很多,进一步考察你的基本功是否扎实,例如:

  1. 线程安全的 Integer (考察你对 java.util.concurrent 并发包的理解)
  2. 基本数据类型和引用类型的局限(考察你对 Java 泛型的理解)
  3. 对象在内存中的结构(对象头 Header,实例数据 Instance Data,对齐填充 Padding)

int 和 Integer 的区别,这算是典型高频面试题之一,也是考察候选人基本功的题目之一,如果你基本功扎实,那么这基本算是一道送分题,目前我了解的大多数大厂和重视技术的公司都是非常重视候选人的基本功,基础决定你的上限在哪里,所以这里我也建议大家不要花太多精力在框架的使用和工具的安装配置上,多沉下心的修炼基础知识,理解基础原理不仅可以很好的满足日常开发,而且还可以帮助你走的更远

聊聊面试-int和Integer的区别的更多相关文章

  1. java int与integer的区别

    int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1.Java 中的数据类型分为基本数据类型 ...

  2. [转载]java int与integer的区别

    声明: 本篇文章属于转载文章,来源:

  3. 【转】java int与integer的区别

    java int与integer的区别 int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1 ...

  4. Java教程——int与Integer的区别

    首先说一下int和Integer的区别: int 是基本数据类型,Integer是int的包装类.注意:后者的类型是"类".例如使用泛型,List<Integer> n ...

  5. java int和Integer的区别

    今天偶然和同学讨论到int和Integer的区别是,发现自己对这个问题了解的并不是很清楚,而且有些概念还是错的,所以在这对int和Integer的区别做一个总结. int与integer的区别从大的方 ...

  6. int与integer的区别(基本数据类型与引用数据类型)

    一.先说说int与integer的区别 int 是基本数据类型,默认值为0,不需要进行实例化 integer 是引用数据类型,是int的封装类型,默认值为null,创建该类型需要进行实例化. 基本数据 ...

  7. java面试题之int和Integer的区别

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...

  8. Java进阶(三十五)java int与integer的区别

    Java进阶(三十五)java int与Integer的区别 前言 int与Integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而Integer是对象 ...

  9. int 与 Integer 的区别

    int和Integer的区别 Integer是int的包装类,int则是java的一种基本数据类型 Integer变量必须实例化后才能使用,而int变量不需要 Integer实际是对象的引用,当new ...

随机推荐

  1. 创建多线程之threading.Thread的使用

    1.threading模块 threading模块是众多多线程管理模块的其一,它能确保重要的子线程退出后进程才退出. multiprocess模块的完全模仿了threading模块的接口,二者在使用层 ...

  2. 在一个升序数组中添加最少的数字,使得从1--n之间所有的数都能用数组中几个数的和表示

    一个Java的笔试题上面遇到的题,当时没有做出来. 拆分: 序列升序 1--n所有的数都要能表示 用数组中数字的和表示 添加最少的数字 思路:这个要先从小的数开始表示,因为大的数可以用小数表示. 1- ...

  3. Yum未完成事务问题

    1.安装 yum-complete-transaction [root@linux-node1 ~]# yum -y install yum-utils 2.清除yum缓存 [root@linux-n ...

  4. SpringBoot + Jpa(Hibernate) 架构基本配置

    1.基于springboot-1.4.0.RELEASE版本测试 2.springBoot + Hibernate + Druid + Mysql + servlet(jsp) 一.maven的pom ...

  5. sql server 使用 partition by 分区函数 解决不连续数字查询问题

    sql server表中的某一列数据为不一定连续的数字,但是需求上要求按照连续数字来分段显示,如:1,2,3,4,5,6,10,11,12,13, 会要求这样显示:1~6,10~13.下面介绍如何实现 ...

  6. scrapy和scrapy-redis的区别

    scrapy是一个python爬虫框架,爬取的效率极高,具有高度的定制性,但是不支持分布式.而scrapy-redis是一套基于redis库,运行在scrapy框架之上的组件,可以让scapy支持分布 ...

  7. 工厂模式(整理自李建忠<C++设计模式>视频)

    整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...

  8. 转载:alpha测试和beta测试的区别;黑盒测试和白盒测试的区别;

    alpha测试版,有点相当于内部测试,一般开发人员在场   ,是由用户做测试,但开发人员在场,一般是请用户到开发现场去测试 beta测试版,完全交给用户,由用户做测试,返回测试报告,相当于发行前的一个 ...

  9. CF #579 (Div. 3) A.Circle of Students

    A. Circle of Students time limit per test2 seconds memory limit per test256 megabytes inputstandard ...

  10. CentOS 7上编写自定义系统审计规则

    1)简介 Linux审计系统创建审计跟踪,这是一种跟踪系统上各种信息的方法.它可以记录大量数据,如事件类型,日期和时间,用户ID,系统调用,进程,使用的文件,SELinux上下文和敏感度级别.它可以跟 ...