Some Java interview questions and my answers which may be correct or not

Attention:答案我自己写的,不正确的可以严肃指正,看的时候要带着怀疑的态度,不要轻信任何答案,万一有错别字呢,而且我写的比较随意

1、Java线程的状态

new:创建好线程对象之后,处于此状态

runnable、running: 调用  start() 启动线程之后进入此状态,一般是先 runnable,然后就等待操作系统分配时间片以及将其调度运行,runnable和running之间有延迟,这也是 非公平锁效率高的原因之一

wait、time_wait: 等待状态,可能的原因  除了 synchronized  之外,例如 Object.wait()、Condition.await(),Thread.sleep() 以及并发包中的会导致阻塞的工具(unsafe.park())

block: 阻塞状态,synchronized  获取不到 monitor时,进入阻塞状态

dead: 线程执行完任务后进入此状态

2、进程和线程的区别,进程间如何通讯,线程间如何通讯

操作系统中执行的基本单位是 进程,进程下可以有一个或多个线程,线程共享了进程的资源。

同一个进程内的线程间的通信通过直接读写共享内存来完成,进程间通信则 需要更具具体的协议配合序列化和反序列化来完成

3、HashMap的数据结构是什么?如何实现的。和HashTable,ConcurrentHashMap的区别

数组加链表的形式,1.8之后引入了红黑树来处理hash冲突严重的情况,不是线程安全的。

ConcurrentHashMap 是线程安全的,1.8之前是 采用 分段锁 + 数组和链表的形式,之后又变回 数组+链表的形式,但是引入了  CAS操作,可以准确的统计 当前元素的数量,同样也 引入了红黑树解决hash冲突严重的问题

4、Cookie和Session的区别

Cookie保存在浏览器中,受浏览器的限制,并且是 和 域名相对应的,安全性较差,而且每次请求都带上大量相同的Cookie 增加了外部带宽。

Session保存在服务端,受限制较少,安全性好,每次请求只需要带上一个 session id。

这两个都是为了应对 http协议的无状态特性,通常将两者结合起来使用,如果浏览器禁用了 Cookie,则可以将 session id 放在请求的url中

5、索引有什么用?如何建索引

建立合适的索引可以有效提高查询性能,但是 也会使写性能降低。

实现:索引的实现看具体的存储引擎,主流的实现都是 B+ Tree。

MySQL中,MyISAM中索引文件和数据文件分开存储,均为 非聚焦索引,主索引 额外要求了主键的唯一性;InnoDB的数据按照 存储在 聚焦索引 B+Tree的叶子节点中,其余索引中叶子节点保存的值为 聚焦索引主键的值,所以 其他索引 一般需要查询两次 B+Tree才可获取数据(例外的情况是 覆盖索引,建立多个列的组合索引,而搜索的值就在索引之中。多列索引的情况 注意最左原则,用靠右的列,会扫描整个B+Tree,效率低。可用 explain 查看数据库的执行计划)

6、ArrayList是如何实现的,ArrayList和LinkedList的区别?ArrayList如何实现扩容。

底层是数组的实现,当添加时 发现容量不够时,会 重新创建一个容量为 原来 1.5倍的数组,并将所有的元素拷贝进去。

ArrayList 底层为数据,随机的访问效率很好,但是 中间的插入和删除需要移动后面的元素,开销较大

LinkedList 底层为 双向链表,随机访问需要迭代整个列表,但是 中间的插入和删除时间复杂度为 O(1)

7、equals方法实现

其实  Object的 equals方法 就是 == ,原始类型比较值,引用类型比较对象地址

然后很多的类重写了 equals 方法,让其比较具体对象的值

8、JVM如何加载字节码文件

通过类加载器来加载,加载的时候按照 双亲委派模型,步骤分为 load、link、init

load:加载字节码,目前我们唯一可以干涉的阶段,通过实现自己的类加载器,实现其中的 findClass方法,可以按照我们自己的方式加载字节码到虚拟机中,loadClass方法实现了 双亲委派模型

link:校验、准备、解析  校验字节码,准备 为 类的域分配内存,解析 将 符号引用替换为 真实内存地址

init:clinit方法、类静态变量、静态块的初始化

9、JVM GC,GC算法

标记清除:标记有用的,清除未标记的,会产生碎片,效率低   CMS采用此方法,需要配合 cms compact

标记整理:把有用的向一端移动,整理完成后,空闲的内存空间是连续的    HotSpot 虚拟机 堆的老年代其他GC采用此方法

标记复制:留出一部分空间,将有用的迁移至对应空间中,清除 另一个空间  HotSpot虚拟机新生代采用此方法,因为新生代对象朝生夕死

10、什么情况会出现Full GC,什么情况会出现Yong GC

Full GC:老年代空间不够(CMS只在老年代GC,不触发FullGC)、元数据空间空间不够、CMS失败、新生代晋升时,评估到历次平均晋升大小超过了老年代的剩余空间

Yong GC:Eden区申请不到足够的空间

11、对象晋升条件

经历了一定的 GC次数(maxTenuringThreshold)、超过一定大小的对象直接到老年代、Young GC 后  survivor放不下,多余的部分存到老年代

12、JVM内存模型

共享:堆、元数据空间   私有:PC、虚拟机栈、native栈 (HotSpot实现了一个混合栈)

13、事务的实现原理

呃,我的理解是  事务保证了 ACID,那么阐释清楚ACID通过什么方式来保证即可

A:原子性,一起成功或者一起失败,undo log

C:一致性,两阶段协议

I:隔离性,应对并发事务的场景,可通过 悲观锁(select for update)、乐观锁(update set version where  version)、MVVC(多版本并发控制,基于最新确定的数据版本进行操作,完成后和 最新版本进行合并,若 修改了同一个地方则冲突回滚)

D:持久性,redo log

14、CopyOnWriteArrayList实现原理

内部仍然是数组实现,数组的引用声明为 volatile,读的时候不加锁,写的时候加锁,并创建一个新的数组,将原有内容和新内容添加到新数组中,然后替换引用为 新数组,因为 数组的引用声明为 volatile,保证了可见性

适用于  读多写少的场景, 写多的情况下性能很差

15、深克隆和浅克隆

区别在于,类型为 引用的域  是 引用的复制,还是整个对象的复制

深克隆 引用域对应的对象也会克隆出一个新的对象来,简单的方式为  序列化和反序列化

16、事务隔离级别

read_uncommitted、read_committed、repeatable_read、serializable

问题: 脏读、不可重复读、幻读

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值