java面试题-Java基础部分-基础语法 41-50

14 篇文章 0 订阅

基础语法 41-50

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

42 、error  和 exception  有什么区别?

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

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

45 、JAVA  语言如何进行异常处理,关键字:throws,throw,try,catch,finally 分 分别代表什么意义?在 别代表什么意义?在 try  块中可以抛出异常吗?

46、 、java  中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和  suspend() 方法为何不推荐使用?

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

48 、同步和异步有何异同,在什么情况下分别使用他们?举例说明。

49.  synchronized 线程安全示例

50 、多线程有几种实现方法? 同步有几种实现方法?


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


异常表示程序运行过程中可能出现的非正常状态,

运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。

java 编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。


42 、error  和 exception  有什么区别?

异常:程序运行过程发生的不正常的事件,将终端程序运行。
error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指
望程序能处理这样的情况。

exception 表示一种设计或实现问题。,需要抛出或捕获异常。

Exception runtimeException 可以不做处理。


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


异常是指 java 程序运行时(非编译)所发生的非正常情况或错误,Java 使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java 对异常进行了分类,不同类型的异常分别用不同的 Java 类表示,所有异常的根类为java.lang.Throwable,Throwable 下面又派生了两个子类:Error 和 Exception,

Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception 表示程序还能够克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件本身缺陷所导致的问题,也就是软件开发人员考虑不周所导致的问题,软件使用者无法克服和恢复这种问题,但在这种问题下还可以让软件系统继续运行或
者让软件死掉,

例如,

  1. 数组脚本越界(ArrayIndexOutOfBoundsException),
  2. 空指针异常(NullPointerException)、
  3. 类转换异常(ClassCastException);

普通异常是运行环境的变化或异常所导致的问题,是用户能够克服的问题,

例如,网络断线,硬盘空间不够,发生这样的异常后,程序不应该死掉。


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

  1. 虚拟机必须宕机的错误,
  2. 程序可以死掉也可以不死掉的错误,
  3. 程序不应该死掉的错误;


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

参考:https://blog.csdn.net/lingyiwin/article/details/91302010

算术异常类:ArithmeticExecption

空指针异常类:NullPointerException

类型强制转换异常:ClassCastException

数组负下标异常:NegativeArrayException

数组下标越界异常:ArrayIndexOutOfBoundsException

违背安全原则异常:SecturityException

文件已结束异常:EOFException

文件未找到异常:FileNotFoundException

字符串转换为数字异常:NumberFormatException


45 、JAVA  语言如何进行异常处理,关键字:throws,throw,try,catch,finally 分 分别代表什么意义?在 别代表什么意义?在 try  块中可以抛出异常吗?


throws 捕获并向外抛出异常
throw 抛出异常
try catch 是内部捕获异常并做自定义处理
finally 是无论是否有异常都会被处理的语句,除非在 finally 前存在被执行的
System.exit(int i)时除外


46、 、java  中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和  suspend() 方法为何不推荐使用?

三种:

  • 继承 extends java.lang.Thread或其子类
  1. 创建多线程 继承Thread
  2. 重写Run()方法
  3. 使用线程 创建Thread的子类对象
  4. 调用子类对象的start()方法

缺点:Java单继承特性,如果已经继承其他类,则不能再继承Thread类。


/**
 * 创建多线程:继承Thread 重写run()
 */
public class ThreadTest extends Thread{
	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println("i:"+i);
		}
	}
}

public class TestMain {
	public static void main(String[] args) {
		ThreadTest ts=new ThreadTest(); //创建子类对象
		ts.start();//调用start()
	}
}
  • 通过实现Runnable接口 实现多线程。
  1. 实现Runnable接口
  2. 重写Run()方法
  3. 使用Start()方法

优点:可以同时实现继承。

//实现了java.lang.Runnable接口
public class MyRunnable implements Runnable {
   public void run(){
    System.out.println("MyRunnable running");
   }
}

//为了使线程能够执行run()方法,需要在Thread类的构造函数中传入 MyRunnable的实例对象
Thread thread = new Thread(new MyRunnable());
thread.start();

//当创建一个线程的时候,可以给线程起一个名字.
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());

//得到当前线程的引用
Thread.currentThread();
//得到当前线程的名字
String threadName = Thread.currentThread().getName();

//输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。

public class ThreadExample {
  public static void main(String[] args){
     System.out.println(Thread.currentThread().getName());
      for(int i=0; i<10; i++){
         new Thread("" + i){
            public void run(){
             System.out.println("Thread: " + getName() + "running");
            }
         }.start();
      }
  }
}

  • 通过实现callable接口 实现多线程。
  1. 创建callable实现类+重写call
  2. 借助执行调度服务 ExecutorService 获取Future对象                                                                                               ExecutorService ser=Executors.newFixedThreadPool(2);                                                                                             Future future =ser.submit(task:实现类对象);
  3. 获取值 future.get();
  4. 停止服务 ser.shutdownNow();

使用callable 创建线程比较繁琐。

Runnable和Callable的区别是:

  1. Callable规定的方法是call(),Runnable规定的方法是run()。其中Runnable可以提交给Thread来包装下,直接启动一个线程来执行,而Callable则一般都是提交给ExecuteService来执行。 
  2. Callable的任务执行后可返回值,而Runnable的任务是不能返回值得 
  3. call方法可以抛出异常,run方法不可以 
  4. 运行Callable任务可以拿到一个Future对象,c表示异步计算的结果。


用 synchronized 关键字修饰同步方法。
反对使用 stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。

suspend()方法容易发生死锁。调用 suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用 suspend(),而应在自己的 Thread 类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()命其进入等待状态。若标志指出线程应当恢复,则用一个 notify()重新启动线程。


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

sleep指定休眠时间,当这个时间达到之后,线程再次唤醒。

wait是等待状态,时间多久不清楚,由另一个线程将其唤醒。


sleep 就是正在执行的线程主动让出 cpu,cpu 去执行其他线程,在 sleep 指定的时间过后,cpu 才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep 方法并不会释放锁,即使当前线程使用 sleep 方法让出了 cpu,但其他被同步锁挡住了的线程也无法得到执行。

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

package com.huawei.interview;
publicclass MultiThread {

    public static voidmain(String[] args) {
        // TODO Auto-generated method stub
        new Thread(newThread1()).start();
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
        // TODO Auto-generated catchblock
            e.printStackTrace();
        }
        new Thread(newThread2()).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("enterthread1...");
            System.out.println("thread1is waiting");
            try {
//释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了 synchronized 关键字管辖的代码范围,另一种方式就是在 synchronized 关键字管辖的代码内部调用监视器对象的 wait 方法。这里,使用 wait 方法释放锁。
                MultiThread.class.wait();
            } catch(InterruptedException e) {
                // TODO Auto-generatedcatch block
                e.printStackTrace();
            }
             System.out.println("thread1is going on...");
            System.out.println("thread1is being over!");
        }
    }
}
    private static class Thread2 implements Runnable{
        @Override
        public void run() {
            // TODO Auto-generated methodstub
            synchronized (MultiThread.class){
            System.out.println("enterthread2...");
            System.out.println("thread2notify other thread can release wait status..");
//由于 notify 方法并不释放锁,即使 thread2调用下面的 sleep 方法休息了10毫秒,但 thread1仍然不会执行,因为 thread2没有释放锁,所以 Thread1无法得不到锁。
            MultiThread.class.notify();
            System.out.println("thread2is sleeping ten millisecond...");
            try {
                Thread.sleep(10);
            } catch (InterruptedExceptione) {
                // TODO Auto-generatedcatch block
                e.printStackTrace();
            }
            System.out.println("thread2is going on...");
            System.out.println("thread2is being over!");
        }
      }
   }
}


48 、同步和异步有何异同,在什么情况下分别使用他们?举例说明。


如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。


当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。


49.  synchronized 线程安全示例


 

public class SynDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//真实角色
		Web12306 web= new Web12306();
		//代理
		Thread t1 =new Thread(web,"路人甲");
		Thread t2 =new Thread(web,"黄牛已");
		Thread t3 =new Thread(web,"攻城师");
		//启动线程
		t1.start();
		t2.start();
		t3.start();
		
		
		
		
	}

}

/**
 * 线程安全的类
 * @author Administrator
 *
 */
class Web12306 implements Runnable {
	private int num =10;
	private boolean flag =true;
	@Override
	public void run() {
		while(flag){
			test5();
		}
	}
	
	public void test6(){
	   	
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		 //a  b  c 	
		synchronized(this){
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	//线程不安全  锁定资源不正确
	public void test5(){
		//a  b  c
		synchronized((Integer)num){
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	
	
	//锁定范围不正确 线程不安全
	public void test4(){
		//   c  1
		synchronized(this){
			//b
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
		}
		// b
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}//a -->1
	
	
	
	//线程安全  锁定正确
	public void test3(){
		//a  b  c
		synchronized(this){
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	//线程安全  锁定正确
	public synchronized void test2(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
	
	
	//线程不安全
	public void test1(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
}


50 、多线程有几种实现方法? 同步有几种实现方法?


多线程有三种实现方法(callable在此不介绍),分别是继承 Thread 类与实现 Runnable 接口
同步的实现方面有两种,分别是 synchronized,wait 与 notify
wait():使一个线程处于等待状态,并且释放所持有的对象的 lock。
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException(中断异常)异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级。
Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EngineerForSoul

你的鼓励是我孜孜不倦的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值