首页 课程 师资 教程 报名

2020年java编程笔试题及答案

  • 2020-02-11 09:57:51
  • 5128次 动力节点


2020年java编程笔试题及答案


  1、线程与进程的区别?


  进程是操作系统分配资源的最小单元,线程是操作系统调度的最小单元。


  一个程序至少有一个进程,一个进程至少有一个线程。


  2、什么是多线程中的上下文切换?


  多线程会共同使用一组计算机上的CPU,而线程数大于给程序分配的CPU数量时,为了让各个线程都有执行的机会,就需要轮转使用CPU。不同的线程切换使用CPU发生的切换数据等就是上下文切换。


  3、死锁与活锁的区别,死锁与饥饿的区别?


  死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。


  产生死锁的必要条件:


  互斥条件:所谓互斥就是进程在某一时间内独占资源。


  请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。


  不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。


  循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。


  活锁:任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试,失败,尝试,失败。


  活锁和死锁的区别在于,处于活锁的实体是在不断的改变状态,所谓的“活”,而处于死锁的实体表现为等待;活锁有可能自行解开,死锁则不能。


  饥饿:一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行的状态。


  Java中导致饥饿的原因:


  高优先级线程吞噬所有的低优先级线程的CPU时间。


  线程被永久堵塞在一个等待进入同步块的状态,因为其他线程总是能在它之前持续地对该同步块进行访问。


  线程在等待一个本身也处于永久等待完成的对象(比如调用这个对象的wait方法),因为其他线程总是被持续地获得唤醒。


  4、什么是Executors框架?


  Executor框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。


  无限制的创建线程会引起应用程序内存溢出。所以创建一个线程池是个更好的的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用Executors框架可以非常方便的创建一个线程池。


  5、什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?


  阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。


  这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。


  阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。


  JDK7提供了7个阻塞队列。分别是:


  ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。


  LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。


  PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。


  DelayQueue:一个使用优先级队列实现的无界阻塞队列。


  SynchronousQueue:一个不存储元素的阻塞队列。


  LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。


  LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。


  Java5之前实现同步存取时,可以使用普通的一个集合,然后在使用线程的协作和线程同步可以实现生产者,消费者模式,主要的技术就是用好,wait,notify,notifyAll,sychronized这些关键字。而在java5之后,可以使用阻塞队列来实现,此方式大大简少了代码量,使得多线程编程更加容易,安全方面也有保障。


  BlockingQueue接口是Queue的子接口,它的主要用途并不是作为容器,而是作为线程同步的的工具,因此他具有一个很明显的特性,当生产者线程试图向BlockingQueue放入元素时,如果队列已满,则线程被阻塞,当消费者线程试图从中取出一个元素时,如果队列为空,则该线程会被阻塞,正是因为它所具有这个特性,所以在程序中多个线程交替向BlockingQueue中放入元素,取出元素,它可以很好的控制线程之间的通信。


  阻塞队列使用最经典的场景就是socket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。


  6、什么是Callable和Future?


  Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。


  可以认为是带有回调的Runnable。


  Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用于产生结果,Future用于获取结果。


  7、什么是FutureTask?


  使用ExecutorService启动任务。


  在Java并发程序中FutureTask表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成get方法将会阻塞。一个FutureTask对象可以对调用了Callable和Runnable的对象进行包装,由于FutureTask也是调用了Runnable接口所以它可以提交给Executor来执行。


  8、什么是竞争条件?你怎样发现和解决竞争?


  当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为这发生了竞争条件(racecondition)。


  9、为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?


  当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。


  但是如果你直接调用run()方法,它不会创建新的线程也不会执行调用线程的代码,只会把run方法当作普通方法去执行。


  10、Java中你怎样唤醒一个阻塞的线程?


  在Java发展史上曾经使用suspend()、resume()方法对于线程进行阻塞唤醒,但随之出现很多问题,比较典型的还是死锁问题。


  解决方案可以使用以对象为目标的阻塞,即利用Object类的wait()和notify()方法实现线程阻塞。


  首先,wait、notify方法是针对对象的,调用任意对象的wait()方法都将导致线程阻塞,阻塞的同时也将释放该对象的锁,相应地,调用任意对象的notify()方法则将随机解除该对象阻塞的线程,但它需要重新获取改对象的锁,直到获取成功才能往下执行;其次,wait、notify方法必须在synchronized块或方法中被调用,并且要保证同步块或方法的锁对象与调用wait、notify方法的对象是同一个,如此一来在调用wait之前当前线程就已经成功获取某对象的锁,执行wait阻塞后当前线程就将之前获取的对象锁释放。


2020年java编程笔试题及答案


      以上就是动力节点Java培训机构小编介绍的“2020年java编程笔试题及答案”的内容,希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为你服务。


相关推荐


最新最全java面试题及答案(初级到高级)


史上最全的中高级JAVA工程师面试题及答案汇总


Java高级开发工程师面试题


2019史上最全java面试题题库大全800题


哪有资深java工程师面试题


选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交