挑战4道Java试题

四道Java基础题,你能对几道?

一、==符的使用
首先看一段比较有意思的代码

Integer a = 1000,b=1000;
Integer c = 100,d=100;  public void mRun(final String name){
    new Runnable() { 

      public void run() {
        System.out.println(name);
      }
    };
  } 

System.out.println(a==b);
System.out.println(c==d);

如果这道题你能得出正确答案,并能了解其中的原理的话。说明你基础还可以。如果你的答案 是 true 和true的话,你的基础就有所欠缺了。
首先公布下答案, 运行代码,我们会得到 false  true。我们知道==比较的是两个对象的引用,这里的abcd都是新建出来的对象,按理说都应该输入false才对。这就是这道题的有趣之处,无论是面试题还是论坛讨论区,这道题的出场率都很高。原理其实很简单,我们去看下Integer.java这个类就了然了。

public static Integer valueOf(int i) {
   return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
 } 

 /**
  * A cache of instances used by {@link Integer#valueOf(int)} and auto-boxing
  */
 private static final Integer[] SMALL_VALUES = new Integer[256]; 

 static {
   for (int i = -128; i < 128; i++) {
     SMALL_VALUES[i + 128] = new Integer(i);
   }
 }

当我们声明一个Integer c = 100;的时候。此时会进行自动装箱操作,简单点说,也就是把基本数据类型转换成Integer对象,而转换成Integer对象正是调用的valueOf方法,可以看到,Integer中把-128-127 缓存了下来。官方解释是小的数字使用的频率比较高,所以为了优化性能,把这之间的数缓存了下来。这就是为什么这道题的答案回事false和ture了。当声明的Integer对象的值在-128-127之间的时候,引用的是同一个对象,所以结果是true。
二、String
接着看代码

String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);

大家又来猜一猜这道题的答案是什么?
       按照==的语法来看, 首先s1、s2、s3是三个不同的对象,常理来说,输出都会是false。然而程序的运行结果确实true、false。第二个输出false可以理解,第一个输出true就又让人费解了。我们知道一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,而堆内存中则存放new 出来的对象和数组。然而除此之外还有一块区域叫做常量池。像我们通常想String s1 = "abc"; 这样申明的字符串对象,其值就是存储在常量池中。当我们创建String s1 = "abc"这样一个对象之后,"abc"就存储到了常量池(也可叫做字符串池)中,当我们创建引用String s2  = "abc" 的时候,Java底层会优先在常量池中查找是否存在"abc",如果存在则让s2指向这个值,不会重新创建,如果常量池中没有则创建并添加的池中。这就是为什么答案是true 和false的原因。

三、final关键字
还是来看一段代码

 public void mRun(final String name){
    new Runnable() { 

      public void run() {
              try {
               Thread.sleep(1000);
              } catch (InterruptedException e) {
               // TODO Auto-generated catch block
              e.printStackTrace();
              }
              System.out.println(name);
      }
    }.start();
  }

这种代码相信大家写过很多,当内部类访问局部变量的时候,需要在局部变量前加final修饰符,不然编译器就会报错。通常我们也是这么干的。好的,第二个问题来了,为什么要加final修饰符?相信大多数小伙伴都没有思考过这个问题,但凡使用的时候,直接加上就得了,从来没去深究过其中的原理。这对于一个优秀的程序员来说是不可取,我们不仅要知其然还要知其所以然。
      现在我们来分析一下,为什么要加final关键字。首先内部类的生命周期是成员级别的,而局部变量的生命周期实在方法体之类。也就是说会出现这样一种情况,当mRun方法执行,new 的线程运行,新线程里面会睡一秒。主线程会继续执行,mRun执行完毕,name属性生命周期结束。1秒之后,Syetem.out.printh(name)执行。然而此时name已经寿终正寝,不在内存中了。Java就是为了杜绝这种错误,严格要求内部类中方位局部变量,必须使用final关键字修饰。局部变量被final修饰之后,此时会在内存中保有一份局部变得的复制品,当内部类访问的时候其实访问的是这个复制品。这就好像是把局部变量的生命周期变长了。说到底还是Java工程师提前把这个坑给我们填了,不然不知道又会有多少小伙伴会为了内部类局部变量而发愁了。
四、Integer与int那些事
看下面代码

Integer a = new Integer(1000);
int b = 1000;
Integer c = new Integer(10);
Integer d = new Integer(10);
System.out.println(a == b);
System.out.println(c == d); 

这道题是继第一题的后续,如果这道题你能很快速的得出答案,那么恭喜你,==比较符你就算掌握的比较透彻了。
揭晓正确答案: true  、false
看到这个答案很多小伙伴又会不解,先来说下第二个,按第一题来说Integer不是把-128-127缓存起来了吗?这不是应该是true嘛,但是你仔细看,这里的Integer是我们自己new出来的,并不是用的缓存,所以结果是false。 现在来看第一个为啥又是true了呢? 首先这里的值为1000,肯定和我们所知的Integer缓存没有关系。既然和缓存没有关系,a是新new出来的对象,按理说输入应该是false才对。但是注意b这里是int类型。当int和Integer进行==比较的时候,Java会把Integer进行自动拆箱,也就是把Integer转成int类型,所以这里进行比较的是int类型的值,所以结果即为true。

做对了几题,快点根据自己测试的水平,进行查漏补缺吧!

(0)

相关推荐

  • Java实现栈和队列面试题

    面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min()的栈,要求min.push.pop.的时间复杂度都是O(1) (6)判断栈的push和pop序列是否一致 1.栈的创建: 我们接下来通过链表的形式来创建栈,方便扩充. 代码实现: public class Stack { public Node head; public Node current; //方法

  • Java中类的加载顺序剖析(常用于面试题)

    这其实是去年校招时我遇到的一道阿里巴巴的笔试题(承认有点久远了-.-),嗯,如果我没记错的话,当时是作为Java方向的一道选做大题.当然题意没有这么直白,题目只要求你写出程序运行后所有System.out.println的输出结果,其中程序是题目给的,而各个System.out.println的执行顺序不同会导致最后程序输出的结果也不同. 具体的题目我肯定记不清,不过我们可以换个直接的问法,如果类A和类B中有静态变量,静态语句块,非静态变量,非静态语句块,构造函数,静态方法,非静态方法,同时类A

  • java+sql2005 随机抽取试题的代码

    复制代码 代码如下: import java.awt.BorderLayout; import java.util.*; import java.awt.event.*; import java.awt.Container; import java.awt.EventQueue; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Stateme

  • JAVA实现链表面试题

    这份笔记整理了整整一个星期,每一行代码都是自己默写完成,并测试运行成功,同时也回顾了一下<剑指offer>这本书中和链表有关的讲解,希望对笔试和面试有所帮助. 本文包含链表的以下内容: 1.单链表的创建和遍历 2.求单链表中节点的个数 3.查找单链表中的倒数第k个结点(剑指offer,题15) 4.查找单链表中的中间结点 5.合并两个有序的单链表,合并之后的链表依然有序[出现频率高](剑指offer,题17) 6.单链表的反转[出现频率最高](剑指offer,题16) 7.从尾到头打印单链表(

  • 15个高级Java多线程面试题及回答

    Java 线程面试问题 在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.如果你想获得任何股票投资银行的前台资讯职位,那么你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很多令人混淆的Java线程问题.面试官只是想确信面试者有足够的Java线程与并发方面的知识,因为候选人中有很多只浮于表面.用于直接面向市场交易的高容量和低延时的电子交易系统在本质上是并发的.下面这些是我在不同时间不同地点喜欢问的Jav

  • 探讨Java中最常见的十道面试题(超经典)

    第一,谈谈final, finally, finalize的区别. final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承.因此一个类不能既被声明为 abstract的,又被声明为final的.将变量或方法声明为final,可以保证它们在使用中不被改变.被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改.被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时提供 finally 块来执行任何

  • 拉钩网java笔试题分享

    你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏.此时有100名学生在上课.游戏的规则是:1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3.5.7.2. 让所有学生拍成一队,然后按顺序报数.3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz:如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz:如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz.4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,

  • 挑战4道Java试题

    四道Java基础题,你能对几道? 一.==符的使用 首先看一段比较有意思的代码 Integer a = 1000,b=1000; Integer c = 100,d=100; public void mRun(final String name){ new Runnable() { public void run() { System.out.println(name); } }; } System.out.println(a==b); System.out.println(c==d); 如果这

  • 深入解答关于Python的11道基本面试题

    前言 本文给大家深入的解答了关于Python的11道基本面试题,通过这些面试题大家能对python进一步的了解和学习,下面话不多说,来看看详细的介绍吧. 一.单引号,双引号,三引号的区别 分别阐述3种引号用的场景和区别 1),单引号和双引号主要用来表示字符串 比如: 单引号:'python' 双引号:"python" 2).三引号 三单引号:'''python ''',也可以表示字符串一般用来输入多行文本,或者用于大段的注释 三双引号:"""python&

  • 用几道面试题来看JavaScript执行机制

    前面的话 根据JavaScript的运行环境,锁定它为单线程,任务需要排队执行,如果网站资源比较大,这样会导致浏览器加载会很慢,但实际上并没有,大家肯定立刻想到了同步和异步. 所谓的同步和异步也是在排队,只是排队的地方不同. 同步和异步 同步任务进入主线程排队,异步任务进入事件队列中排队 同步任务和异步任务进入到不同的队列中,也就是上面讲的在不同地方排队. 同步任务进入主线程,异步任务进入事件队列,主线程任务执行完毕,事件队列中有等待执行的任务进入主线程执行,直到事件队列中任务全部执行完毕. 开

  • JavaScript必看的10道面试题总结(推荐)

    1.this指向 1.谁调用指向谁 例: function foo(){ console.log("this",this); } new foo(); 2.全局指向window 例: function foo(){ console.log("this",this); } foo(); 3.构造函数的this指向构造函数实例 4.call/apply/bind 强制改变this指向 5.箭头函数的this始终指向父级上下文 2.事件模型:事件委托.代理?如何让事件先冒

  • C语言八道笔试题精讲带你掌握指针

    目录 题目一 题目二 题目三 题目四 题目五 题目六 题目七 题目八 为了题目的准确性和我们一般学习过程中的习惯,这里所有的题目代码都是在 X86 环境(32 位平台)下运行的. 题目一 #include <stdio.h> int main() { int a[5] = { 1, 2, 3, 4, 5 }; int* ptr = (int*)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); return 0; } /

  • 最有价值的50道java面试题 适用于准入职Java程序员

    下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最新版本,去掉了EJB 2.x等无用内容,补充了数据结构和算法相关的题目.经典面试编程题.大型网站技术架构.操作系统.数据库.软件测试.设计模式.UML等内容,同时还对很多知识点进行了深入的剖析,例如hashCode方法的设计.垃圾收集的堆和代.Java新的并发编程.NIO.2等,相信对准备入职的Ja

  • 50 道Java 线程面试题(经典)

    下面是 Java 线程相关的热门面试题,你可以用它来好好准备面试. 1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线程完成一个任务要 100 毫秒,那么用十个线程完成改任务只需 10 毫秒.Java 在语言层面对多线程提供了卓越的支持,它也是一个很好的卖点.欲了解更多详细信息请点击这里. 2) 线程和进程有什么区别? 线程是进程的子集,一个进程可以有很

  • java实习--每天打卡十道面试题!

    目录 1.什么是ARQ协议 停止等待ARQ协议 连续 ARQ 协议 2.HTTPS的加密.解密的过程 总结: 3.深入理解三次握手.四次挥手流程 4.Spring AOP 如何实现(实现原理) 5.摘要算法:HTTPS如何方式数据发生了篡改? 6.介绍一下JVM运行时数据区:堆与栈 7.强引用,软引用和弱引用的区别? 8.如何减少线程的上下文切换? 9.操作系统进程的调度策略 10.什么是虚拟内存? 虚拟内存的基本思想: 页面置换算法: 虚拟内存的应用与优点: 局部性原理: 总结 1.什么是AR

  • 每日几道java新手入门面试题,通往自由的道路

    目录 1.请你说一下什么是面向对象? 2.请你简述一下面向对象的三个基本特征? 3.为什么说 Java 是一种半解释半编译的程序设计语言呢? 4.请你说一下Java中的8大基本类型是那些? 5.请你讲讲抽象类和接口有什么区别? 6.请判断当一个对象被当作参数传递给一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 7.请你说一下JVM/JRE/JDK的区别? 8.请你说一下方法重载和方法重写的区别? 9.请你说一下List接口和Set接口的区别? 1

随机推荐