Java面试题——随机题(一),看看哪些你会哪些你不会
博客说明
文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!
请说明一下EJB的几种类型分别是什么?
会话(Session)Bean、实体(Entity)Bean 、消息驱动的(Message Driven)Bean
会话Bean又可分为有状态(Stateful)和无状态(Stateless)两种
实体Bean可分为Bean管理的持续性(BMP)和容器管理的持续性(CMP)两种。
请说明一下锁机制的作用是什么?并且简述一下Hibernate的悲观锁和乐观锁机制是什么?
锁机制的作用是保证共享资源可以进行排他性的访问
悲观锁悲观的认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。
数据库中主要是通过数据库底层的锁机制才能保证真正的数据访问排他性。
缺点:并发量不高,效率低;
乐观锁对并发事务持乐观态度(认为对数据的并发操作不会经常性的发生),通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的严重影响。最常见的乐观锁是通过数据版本标识来实现的
redis为什么是单线程?
多线程不一定比单线程效率高,多线程的本质就是CPU通过轮换时间片执行不同的线程,看似多个线程一起执行,但是却承担线程上下文切换的代价。
而对于Redis这样的内存数据库来说,没有上下文的切换的单线程效率是最高的。Redis用单个CPU绑定一块内存的数据,然后针对这块内存的数据进行多次读写操作都是在一个CPU上完成的。
请你谈谈Java中线程如何实现,以及如何实现多线程,线程安全在Java中是如何实现的,线程的工作区是哪里
Java多线程有三种实现方式
(1)继承Thread类,重写run函数
(2)实现Runnable接口,重写run函数
开启线程:Thread t = new Thread(对象) //创建线程对象
t.start()
(3)实现Callable接口,重写call函数
Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
Callable和Runnable有几点不同:
①Callable规定的方法是call(),而Runnable规定的方法是run()
②Callable的任务执行后可返回值,而Runnable的任务是不能返回值的
③call()方法可抛出异常,而run()方法是不能抛出异常的。
④运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果
线程不安全的原因:
在操作系统中,线程是不拥有资源的,进程是拥有资源的。而线程是由进程创建的,一个进程可以创建多个线程,这些线程共享着进程中的资源。所以,当线程一起并发运行时,同时对一个数据进行修改,就可能会造成数据的不一致性
线程安全的解决机制:
加锁。
锁能使其保护的代码以串行的形式来访问,当给一个复合操作加锁后,能使其成为原子操作。一种错误的思想是只要对写数据的方法加锁,其实这是错的,对数据进行操作的所有方法都需加锁,不管是读还是写。
加锁时需要考虑性能问题,不能总是一味地给整个方法加锁synchronized就了事了,应该将方法中不影响共享状态且执行时间比较长的代码分离出去。
加锁的含义不仅仅局限于互斥,还包括可见性。为了确保所有线程都能看见最新值,读操作和写操作必须使用同样的锁对象。
不共享状态
无状态对象: 无状态对象一定是线程安全的,因为不会影响到其他线程。
线程关闭: 仅在单线程环境下使用。
不可变对象
可以使用final修饰的对象保证线程安全,由于final修饰的引用型变量(除String外)不可变是指引用不可变,但其指向的对象是可变的,所以此类必须安全发布,也即不能对外提供可以修改final对象的接口。
线程的工作区
Java内存模型分为主内存,和工作内存。主内存是所有的线程所共享的,工作内存是每个线程自己有一个,不是共享的。
每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用到的变量的主内存副本拷贝。线程对变量的所有操作(读取、赋值),都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成
感谢
牛客网
万能的网络
以及勤劳的自己