一些关于线程,线程池,异常,内部类的面试题(个人理解答案放最后)

1.java中如何实现数据共享

2.内部类的分类(要求写出依据)

3.内部类编译后是否生成class文件,如果生成那么他的命名规则是什么

4.Error与Exception的区别

5.运行时异常与非运行时的异常的区别

6.常见的运行时异常(11种)

7.如何进行异常处理

8.throw与throws的区别

9.如何自定义一个异常

10.jdk7.0前后关于多重catch的改变

11.什么是线程

12.我们为什么要使用多线程

13.线程的七大状态

14.如何实现一个线程(三种方式)

15.控制线程的方法

16.线程的常用方法(6个)

17.为什么会出现并发错误

18.如何解决并发错误

19.为什么会出现死锁

20.如何解决死锁问题

21.并发修改异常与并发错误的区别

22.如何实现两个线程交替执行

23.什么是线程池

24.IllegalMonitorStateException是如何产生的

25.第三种实现线程方式的优点是什么

26.请写出synchronized的使用方法,特点,适用的地方

27.什么是公平锁

28.shutdown方法与shutdownNow方法的异同

29.官方提供的常用的线程池三种方法

30.当我们需要自己创建线程池执行器的时候需要指定几个参数 它们分别是什么含义

1.使用静态变量,使用参数传递,使用内部类

2.内部类根据共享外部类的哪些内容进行分类,分为静态内部类,成员内部类,局部内部类,匿名内部类。其中

静态内部类:仅能共享外部类的静态方法,但是静态成员不是内部类仍能访问,因此静态内部类是用来描述类与类的归属关系的而不是共享变量的

成员内部类:可以共享外部类的所有(静态+非静态)成员(方法+属性)

局部内部类:当局部内部类处于静态方法中时,仅能共享外部类的静态成员(方法+属性)

                      当局部内部类处于非静态方法中时,能够共享外部类所有成员

                      另外,它们都能共享外部类那个方法里的局部变量,但是jdk8.0之前必须加final修饰,8.0后不需要,因为默认就是final的

匿名内部类:共享的数据根据其位置决定

3.外部类名字$内部类名字.class

4.Error是由于硬件或系统所造成的,程序员无法通过编程来解决相对较严重的问题

而Exception是程序在运行当中出现的例外情况,相对较轻的问题

5.运行时异常不要求程序在编译阶段给出相应的处理方案,编译可以直接通过,异常会在运行时体现出来,而非运行时异常要求程序员必须在编译阶段给出方案,否则不予通过。

6. ArithmeticException => 算术异常
        *: 除以0了 当你见到这个异常的时候 
            去代码当中找 / x

    NegativeArraySizeException => 负数数组大小异常
        *: 初始化数组的时候 []当中应该提供数组的元素个数
            而如果传入的是负数 将直接触发该异常
            去代码当中找 [x]

    ArrayIndexOutOfBoundsException => 数组索引值超出边界异常
        *: 访问数组元素的时候 是可以使用下标索引值的
            该下标索引值可用范围 0 到 length-1
            去代码当中找 [x]

    NullPointerException => 空指针异常
        *: null是Java当中引用数据类型的默认值
            拿它访问任何属性 调用任何方法都会导致该异常
            去代码当中找 x.

    StringIndexOutOfBoundsException => 字符串索引值超出边界异常
        *: 字符串类提供了很多实用下标操作的方法
            例如 charAt() 例如 substring()
            如果传入的下标值超过可用范围 (0 - length() -1)
            将直接触发该异常 
            去代码当中找charAt(x) substring(x)

    NumberFormatException => 数字格式异常
        *: 在将字符串转换成对应的基本数据类型的时候
            我们很可能调用 
            Integer.parseInt() or Double.parseDouble() ...
            如果当中传入的内容有不是符合格式的标准内容
            将除非该异常
            找方法的参数!            

    ClassCastException => 类型造型异常
        *: 发生在强制类型转换的时候
            要转换的对象跟想要转换成的类型没有关系
            无法转换
            找 强转的小括号
    
    IllegalArgumentException => 非法参数异常
        *: 初始化ArrayList的时候 构造方法可以指定底层
            Object数组的原始大小
            如果传入的是负数 将直接触发该异常
    
    IndexOutOfBoundsException => 索引值超出边界异常
        *: List集合提供了很多实用下标值操作元素的方法
            例如 get(int) remove(int)
            如果传入的参数超过可用范围 0-size()-1

    IllegalStateException => 非法状态异常
        *: 迭代器的状态有问题 迭代器光标没有指向元素
            就直接调用了car.remove()方法
            找remove()之前有没有足够的next();

    ConcurrentModificationException => 并发修改异常

7.throws Exception抛给上级

try{}catch(Exception e){}finally{}自行处理

8.throw用于方法体中,适用于在没有异常时主动制造异常

throws用于方法签名最后用于表达

本方法中出现指定种类的异常

本方法不作处理

抛还给调用的上级处理

9.

class DIY extends Exception{
    public DIYException(){
        super("这是一个DIY错误");
    }    
}

10.在JDK7.0之前 也必须要写两个相同的catch结构
     从JDK7.0开始 可以使用多重catch
     catch(类型1 | 类型2 | 类型3 e){...}

11.程序当中一条独立的执行线索

12.在大部分场景下使用多线程能提高效率,但是多线程从根本上并不是为了提高效率,而是为了让程序学会在同一时间做多个事情,同一时间接待多个客户,同一时间完成多个请求

13.新生(Born)就绪(Runnable)运行(Running)消亡(Dead)

                                        堵塞(Blocking)

堵塞又分为:普通堵塞,锁池堵塞,等待池堵塞

14.extends Thread

     implements Runnable

     implements Callable<T>

15.setPriority(int)

     sleep(long)

     yield()

     join()

16.setName,getName,setDaemon,activeCount,interrupt,currentThread

17.多个线程共享操作同一份数据,当线程体当中连续的多行操作时,有可能操作执行一部分时间片耗尽,此时另一个线程抢到时间片,将不完整的数据继续修改,从而产生并发错误

18.加锁

        synchronized(共享数据)

        使用可重入锁,ReentrantLock,java.util.concurrent.locks.ReentrantLock

19.互斥锁标记使用过多或者使用不当,就会造成多个线程相互持有对方想要申请的资源不释放的情况下,又去申请对方已经持有的资源,从而双双进入对方已经持有的资源的锁池当中,产生永久的阻塞

20.使用wait方法让线程进入等待池中等待notify或notifyAll方法唤醒

21.并发修改异常是为了防止出现并发错误而做的主动校验的机制

        并发修改异常的存在就是为了躲开并发错误

22.

public class TestSwitchThread{
	public static void main(String[] args){
		RightThread rt = new RightThread();//
		LeftThread lt = new LeftThread(rt);//
		lt.start();//
	}
}
class X{
	static Object obj = new Object();
}
class LeftThread extends Thread{
	RightThread rt;
	public LeftThread(RightThread rt){
		this.rt = rt;
	}
	@Override
	public void run(){
		synchronized(X.obj){
			rt.start();
			for(int i = 0;i<6666;i++){
				System.out.println("左脚");//1
				try{X.obj.wait();}catch(Exception e){e.printStackTrace();}//2
				X.obj.notify();//6
			}
		}
	}
}
class RightThread extends Thread{
	@Override
	public void run(){
		synchronized(X.obj){
			for(int i = 0;i<6666;i++){
				System.out.println("			右脚");//3
				X.obj.notify();
				try{X.obj.wait();}catch(Exception e){e.printStackTrace();}
			}
		}
	}
}

23.

线程池是一种标准的资源池模式。

所谓的资源池模式 能够在用户出现之前提前预留活跃资源  
从而在用户出现的第一时间 直接满足用户对资源的需求
将资源的创建和销毁都委托给资源池完成 从而优化用户体验

24.调用wait(),notify()和notifyAll()的线程在调用这些方法前必须"拥有"对象的锁。当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。

25.可以return返回值,可以抛出异常

26.可以修饰代码块,修饰整个方法

无法被子类继承

27.线程依据进来顺序排队获取锁,先进的线程先获得后进来的后获得

28.   它们都不能结束那些已经提交并且在执行中的线程
        另外 它们都能禁止新任务再提交

        它们最大的区别在于
        shutdo wn() 会允许那些已经提交但是还没开始执行的线程执行结束
        shutdownNow() 会直接将提交之后还未开始的线程 退回回去

29.       newFixedThreadPool(int)

            newSingleThreadExecutor()

            newCachedThreadPool()

30.         5个
    1.线程池当中预留的核心线程数量
    2.线程池当中最大线程数量
    3.保持活着的时间 
    4.时间单位 
    5.一个集合 一个队列 用于存放提交上来还没法执行的线程任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值