实战派 好教育     全国咨询热线:400-009-1906

北京 切换校区

全国24小时免费热线

400-009-1906

Java面试宝典1

时间:2018-05-17   来源:尚学堂   阅读:177
首页> Java面试宝典1

本文给大家带来的是java面试题30道第1—15题

  1、数组有没有length()这个方法? String有没有length()这个方法?

  数组没有length()这个方法,有length的属性。String有有length()这个方法。
 

  2、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";

  答:对于如下代码:

  String s1 = "a";

  String s2 = s1 + "b";

  String s3 = "a" + "b";

  System.out.println(s2 == "ab");

  System.out.println(s3 == "ab");

  第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,

  String s = "a" + "b" + "c" + "d";

  System.out.println(s == "abcd");

  最终打印的结果应该为true。
 

  3、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?

  也许你的答案是在return之前,但往更细地说,我的答案是在return中间执行,请看下面程序代码的运行结果:

  [java] view plaincopy

  public class Test {

  /**

  * @param args add by zxx ,Dec 9, 2008

  */

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  System.out.println(new Test().test());;

  }

  static int test()

  {

  int x = 1;

  try

  {

  return x;

  }

  finally

  {

  ++x;

  }

  }

  }

  ———执行结果 ———

  1

  运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。
 

  4、下面的程序代码输出的结果是多少?

  [java] view plaincopy

  public class smallT

  {

  public static void main(String args[])

  {

  smallT t = new smallT();

  int b = t.get();

  System.out.println(b);

  }

  public int get()

  {

  try

  {

  return 1 ;

  }

  finally

  {

  return 2 ;

  }

  }

  }

  返回的结果是2。

  我可以通过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。Return并不是让函数马上返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行finally语句后才真正开始返回。

  在讲解答案时可以用下面的程序来帮助分析:

  [java] view plaincopy

  public class Test {

  /**

  * @param args add by zxx ,Dec 9, 2008

  */

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  System.out.println(new Test().test());;

  }

  int test()

  {

  try

  {

  return func1();

  }

  finally

  {

  return func2();

  }

  }

  int func1()

  {

  System.out.println("func1");

  return 1;

  }

  int func2()

  {

  System.out.println("func2");

  return 2;

  }

  }

  ———–执行结果—————–

  func1

  func2

  2

  结论:finally中的代码比return 和break语句后执行
 

  5、final, finally, finalize的区别

  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 内部类要访问局部变量,局部变量必须定义成final类型,例如,一段代码……

  finally是异常处理语句结构的一部分,表示总是执行。

  finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
 

  6、运行时异常与一般异常有何异同?

  异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。
 

  7、error和exception有什么区别?

  error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。 exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
 

  8、Java中的异常处理机制的简单原理和应用

  异常是指java程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。

  Java对异常进行了分类,不同类型的异常分别用不同的Java类表示,所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。

  java为系统异常和普通异常提供了不同的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,所以普通异常也称为checked异常,而系统异常可以处理也可以不处理,所以,编译器不强制用try..catch处理或用throws声明,所以系统异常也称为unchecked异常。

  提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误;
 

  9、请写出你最常见到的5个runtime exception

  NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException、ClassNotFoundException
 

  10、sleep() 和 wait() 有什么区别?

  sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。 wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。)

  sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep方法并不会释放锁,即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在notfiy方法后增加一个等待和一些代码,看看效果),调用wait方法的线程就会解除wait状态和程序可以再次得到锁后继续向下运行。对于wait的讲解一定要配合例子代码来说明,才显得自己真明白。

  package com.huawei.interview;

  public class MultiThread {

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  new Thread(new Thread1()).start();

  try {

  Thread.sleep(10);

  } catch (InterruptedException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  new Thread(new Thread2()).start();

  }

  private static class Thread1 implements Runnable

  {

  @Override

  public void run() {

  //由于这里的Thread1和下面的Thread2内部run方法要用同一对象作为监视器,我们这里不能用this,因为在Thread2里面的this和这个Thread1的this不是同一个对象。我们用MultiThread.class这个字节码对象,当前虚拟机里引用这个变量时,指向的都是同一个对象。

  synchronized (MultiThread.class) {

  System.out.println("enter thread1…");

  System.out.println("thread1 is waiting");

  try {

  //释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁。

  MultiThread.class.wait();

  } catch (InterruptedException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  System.out.println("thread1 is going on…");

  System.out.println("thread1 is being over!");

  }

  }

  }

  private static class Thread2 implements Runnable

  {

  @Override

  public void run() {

  // TODO Auto-generated method stub

  synchronized (MultiThread.class) {

  System.out.println("enter thread2…");

  System.out.println("thread2 notify other thread can release wait status..");

  //由于notify方法并不释放锁, 即使thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。

  MultiThread.class.notify();

  System.out.println("thread2 is sleeping ten millisecond…");

  try {

  Thread.sleep(10);

  } catch (InterruptedException e) {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  System.out.println("thread2 is going on…");

  System.out.println("thread2 is being over!");

  }

  }

  }

  }
 

  11、启动一个线程是用run()还是start()?

  启动一个线程是调用start()方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run()方法是该线程所关联的执行代码。
 

  12、当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?

  分几种情况:

  1.其他方法前是否加了synchronized关键字,如果没加,则能。

  2.如果这个方法内部调用了wait,则可以进入其他synchronized方法。

  3.如果其他个方法都加了synchronized关键字,并且内部没有调用wait,则不能。

  4.如果其他方法是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
 

  13、线程的基本概念、线程的基本状态以及状态之间的关系

  一个程序中可以有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每个线程上都关联有要执行的代码,即可以有多段程序代码同时运行,每个程序至少都有一个线程,即main方法执行的那个线程。如果只是一个cpu,它怎么能够同时执行多段程序呢?这是从宏观上来看的,cpu一会执行a线索,一会执行b线索,切换时间很快,给人的感觉是a,b在同时执行,好比大家在同一个办公室上网,只有一条链接到外部网线,其实,这条网线一会为a传数据,一会为b传数据,由于切换时间很短暂,所以,大家感觉都在同时上网。

  状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。

  调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
 

  14、简述synchronized和java.util.concurrent.locks.Lock的异同 ?

  主要相同点:Lock能完成synchronized所实现的所有功能

  主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。

  举例说明(对下面的题用lock进行了改写):

  package com.huawei.interview;

  import java.util.concurrent.locks.Lock;

  import java.util.concurrent.locks.ReentrantLock;

  public class ThreadTest {

  private int j;

  private Lock lock = new ReentrantLock();

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  ThreadTest tt = new ThreadTest();

  for(int i=0;i<2;i++)

  {

  new Thread(tt.new Adder()).start();

  new Thread(tt.new Subtractor()).start();

  }

  }

  private class Subtractor implements Runnable

  {

  @Override

  public void run() {

  // TODO Auto-generated method stub

  while(true)

  {

  /*synchronized (ThreadTest.this) {

  System.out.println("j–=" + j–);

  //这里抛异常了,锁能释放吗?

  }*/

  lock.lock();

  try

  {

  System.out.println("j–=" + j–);

  }finally

  {

  lock.unlock();

  }

  }

  }

  }

  private class Adder implements Runnable

  {

  @Override

  public void run() {

  // TODO Auto-generated method stub

  while(true)

  {

  /*synchronized (ThreadTest.this) {

  System.out.println("j++=" + j++);

  }*/

  lock.lock();

  try

  {

  System.out.println("j++=" + j++);

  }finally

  {

  lock.unlock();

  }

  }

  }

  }

  }
 

  15、设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序

  public class ThreadTest1

  {

  private int j;

  public static void main(String args[]){

  ThreadTest1 tt=new ThreadTest1();

  Inc inc=tt.new Inc();

  Dec dec=tt.new Dec();

  for(int i=0;i<2;i++){

  Thread t=new Thread(inc);

  t.start();

  t=new Thread(dec);

  t.start();

  }

  }

  private synchronized void inc(){

  j++;

  System.out.println(Thread.currentThread().getName()+"-inc:"+j);

  }

  private synchronized void dec(){

  j–;

  System.out.println(Thread.currentThread().getName()+"-dec:"+j);

  }

  class Inc implements Runnable{

  public void run(){

  for(int i=0;i<100;i++){

  inc();

  }

  }

  }

  class Dec implements Runnable{

  public void run(){

  for(int i=0;i<100;i++){

  dec();

  }

  }

  }

  }
 

  
    本文给大家带来的java面试题30道第1&mdash;15题,到这里就结束了。  
 

分享:0

相关资讯

  • 北京校区
  • 山西校区
  • 郑州校区
  • 武汉校区
  • 四川校区
  • 长沙校区
  • 深圳校区
  • 上海校区
  • 广州校区

北京海淀区校区(总部):北京市海淀区西三旗街道建材城西路中腾建华商务大厦东侧二层尚学堂
北京京南校区:北京亦庄经济开发区科创十四街6号院1号楼 赛蒂国际工业园
咨询电话:400-009-1906 / 010-56233821
面授课程: JavaEE培训大数据就业班培训大数据云计算周末班培训零基础大数据连读班培训大数据云计算高手班培训人工智能周末班培训
人工智能+Python全栈培训H5+PHP全栈工程师培训视觉设计培训

山西学区地址:山西省晋中市榆次区大学城大学生活广场万科商业A1座702
咨询电话:0354-3052381 / 18903441162
面授课程: JavaEE培训大数据培训全栈工程师培训产品经理培训

郑州学区地址:金水区东风路经三路北100米注协大厦10楼
咨询电话:0371-55177956
面授课程: JavaEE培训大数据培训全栈工程师培训产品经理培训

武汉学区地址:湖北省武汉市江夏区江夏大道26号 宏信悦谷创业园4楼
咨询电话:027-87989193
面授课程: JavaEE培训大数据培训全栈工程师培训产品经理培训

四川学区地址:成都市高新区锦晖西一街99号布鲁明顿大厦2栋1003室
咨询电话:028-65176856 / 13880900114
面授课程: JavaEE培训大数据培训全栈工程师培训产品经理培训

长沙学区地址:长沙市岳麓区麓源路湖南电子商务基地5楼(公交车站:六沟垅)
咨询电话:0731-83072091
面授课程: JavaEE培训人工智能+Python全栈大数据培训全栈工程师培训产品经理培训

深圳校区地址:深圳市宝安区航城街道航城大道航城创新创业园A4栋210(固戍地铁站C出口)
咨询电话:0755-23061965 / 18898413781
面授课程: JavaEE培训人工智能+Python全栈大数据培训PHP全栈工程师培训产品经理培训

上海尚学堂松江校区地址:上海市松江区荣乐东路2369弄45号绿地伯顿大厦2层
咨询电话:021-67690939
面授课程: JavaEE培训、Python-人工智能、大数据、前端+PHP全栈

广州校区地址:广州市天河区元岗横路31号慧通产业广场B区B1栋6楼尚学堂(地铁3号线或6号线到“天河客运站”D出口,右拐直走约800米)
咨询电话:020-2989 6995
面授课程: JavaEE培训人工智能+Python全栈大数据培训云计算&大数据培训PHP培训全栈工程师培训

Copyright 2006-2018 技术支持:太原市正觉教育科技有限公司  京ICP备13018289号-19  京公网安备11010802015183  
媒体联系:18610174079 闫老师