【java面经整理】阿里五次面试整理,过五关斩六将

2020年8月4号
从今天开始,每天整理一篇面经;
整理采用全文字方式,模拟电话的形式,没有图解
切记分点答题,先原理后细节

这是我在知乎看到的阿里面经,很有参考价值,分享给大家
期待我的第一次面试+.+

这五次面试都是电话面;大家今年做好全程电话面试的准备

一面

答主是一位研究生

问题
  • 自我介绍
  • 你感觉比本科阶段的自己进步了多少?
  • 研究生期间最大的进步是什么?
  • 你觉得你适合从事哪个方向的开发
  • synchronized与lock的区别,使用场景。看过synchronized的源码没
  • JVM自动内存管理,Minor GC与Full GC的触发机制
  • 了解过JVM调优没,基本思路是什么
  • 如何设计存储海量数据的存储系统
  • 缓存的实现原理,设计缓存要注意什么
  • 淘宝热门商品信息在JVM哪个内存区域
  • 操作系统的页式存储
  • volatile关键字的如何保证内存可见性
  • happen-before原则
  • Lucene全文搜索的原理
  • 你觉得自己适合哪方面的开发,为什么
  • 想去哪里实习,杭州?

反问面试官:

  • 评价一下我的这次的表现
  • 应该在我的技术栈中增加什么
  • 有机会下次面试吗

看到一面……感觉自己的知识远远不够,疯狂查漏补缺,然后将问题和答案根据自己的理解整理出来……

解答
synchronized与lock的区别,使用场景。看过synchronized的源码没

答:(其实这个我之前博客整理过,但我感觉我忘了,而且这次打算用面试的语气整理)synchronized和lock的区别,我们可以从五个方面来看,
1)lock是一个接口,
而synchronized是java中的关键字,synchronized是内置的语言实现;
2)synchronized发送异常时,会自动释放线程占用的锁,所以不会发生死锁现象。
lock发生异常的时候,若没有主动释放极有可能造成死锁,所以需要在finally中调用unlock方法来释放锁
3)lock的接口下锁的加锁方式更多,
synchronized只有一种阻塞加锁的方式
4)lock可以提高多个线程进行读写操作的效率(读写锁的使用)
5)synchronized被称为重量级锁,加锁的原理很重量
lock更轻量级

使用场景:
根据需求来设计:
如果要使用特殊的加锁方式,只能使用lock
如果竞争不激烈,并且代码中没有读操作应该选用synchronized

看过源码
synchronized的加锁底层实现原理主要是靠mark work和monitor两个机制操作的。
1、Mark Word用于存储对象自身的运行时数据
2、monitor(监视器锁),可以看做一个同步机制

/**
synchronized实现的锁是存储在java对象头。所以要对synchronized深入理解,首先了解一下对象在内存中的布局:(对象头、实例数据、对齐填充)

由于synchronized修饰的方法及方法块的实现是在JVM层面的,所以我们需要从字节码聊起。
当我们反编译的时候,可以看到monitorenter和monitorexit是synchronized底层实现的关键。
每个对象都与一个监视器锁关联。一个monitor的lock只能被一个线程在同一时间获得,*/

JVM自动内存管理,Minor GC与Full GC的触发机制

答:1、JVM自动内存管理分为两部分,分配内存和回收内存
2、内存结构有线程公有的方法区、堆,线程私有的有虚拟机栈、本地方法栈、程序计数器。
我们可以从功能、是否线程共享、生命周期、抛出异常等角度来看它的分配内存
a、程序计数器(很小)的当前线程所执行的字节码的行号指示器,是每个线程都独立需要的,功能是(1)字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制。(2)多线程情况下,程序计数器用于记录当前线程执行的位置,从而当前线程被切换回来的时候能够知道上次运行的位置。生命周期是随着线程的创建而创建,随着线程的结束而死亡。抛出的异常来看是唯一一个不会出现OutOfMemoryError的内存区域
b、java虚拟栈就我们常说的堆栈的栈,功能是当每个方法(java方法)被执行的时候会产生一个栈帧,用于存储局部变量表、动态链接、操作数、方法出口等信息。从抛出的异常来看,会抛出StackOverFlowError和OutOfMemoryError异常
c、本地方法栈的功能是为虚拟机使用到的native方法服务,从抛出的异常来看和java虚拟机栈一样
d、堆 java虚拟机下所管理的最大的一块内存,是所有线程共享的一块内存区域,在虚拟机启动的时候创建。功能是存放对象实例,几乎所有的对象实例及数组都在此分配内存,也被称为GC堆
e、方法区功能是存储已被虚拟机加载的类信息、常量。静态变量,即时编译器编译后的代码与数据。此处引入一个重要概念:运行时常量池。用于存放在编译过程中产生的字面量和引用。一般来说,方法区属于持久代,java规范将其描述成堆得一个逻辑结构但不是堆

此处补充一个在JVM内存管理之外的一个内存区:直接内存。在JDK1.4中新加入类NIO类,引入了一种基于通道与缓冲区的I/O方式,它可以使用Native函数库直接分配堆外内存,即我们所说的直接内存,这样在某些场景中会提高程序的性能。
3、内存回收
当我们内存被占用的越来越多的时候,则需要垃圾回收(堆和方法区需要进行)
垃圾回收算法:(1)标记清除算法(2)复制算法(3)标记整理算法(4)分代回收算法
(1)标记清除算法顾名思义就和它的名字一样,分为标记和清除两个阶段,首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象
标记阶段:标记阶段就是可达性分析算法的过程,对从GCRoot对象可达的对象都打上一个标识,将其标记为可达对象。
清除阶段:对堆中内存进行遍历,如果发现哪个对象没有被标记为可达对象,将其回收
缺点:(1)效率问题,两个阶段都需要遍历,而且GC时需要停止应用程序
(2)空间问题:会导致内存碎片化,当我们需要一块整块内存时,由于碎片化问题,不得不提前触发GC

(2)复制算法
复制算法对整个半区进行内存回收,将存活对象按地址复制到保留区域存储
优点:(1)减少了遍历时间直接清空整个区域(2)解决内存碎片化
缺点:(1)将内存缩小了一半,代价太高
(2)假设对象都存活,那么我们需要把所有对象复制一遍,耗费的时间代价也是不可忽视的

(3)标记整理算法
标记过程和标记清除算法相同;
整理:让所有存活的对象都移向一端,然后直接清理掉端边线以外的内存。

优点:当我们给对象分配内存时,jvm只需要持有内存的起始地址即可。弥补了标记整理算法存在的内存碎片问题,同时消除了复制算法内存减半的高额代价。

缺点:效率低,不仅要标记存活的对象,还要整理出所有存活对象的引用地址,在效率上不如复制算法
(4)分代回收算法
按对象的存活周期不同将内存划为几块,一般是把java堆分为新生代和老年代,这样就可以根据各个带的特点进行回收了
新生代特点:朝生夕灭,存活时间短,采用复制算法来收集(付出少量对象的复制成本就可以完成)
老年代特点:经过多次Minor GC而存活下来,存活周期长。采用标记清理算法或标记整理算法来收集老年代(存活率高不适合复制法)

触发条件:*JVM会先首先检查老年代连续空间是否大于新生代对象总大小或历次晋升的平均大小,如果条件成立,则进行Minor GC,否则进行Full GC(让老年代腾出更多空间)。

内存分配的策略:
1、对象优先分配在eden区
2、大对象直接进入老年代
3、长期存活的对象将进入老年代
4、动态对象年龄判定

这两道题简简单单写了三千字。。。。
明天继续整理。。。

了解过JVM调优没,基本思路是什么

答:了解过;(我之前写过一篇博客讲的就是JVM调优是详细步骤,这里因为人家问的是基本思路,所以我就提炼一些重点)基本思路就是(1)首先监控GC的状态,使用工具来查看日志分享参数(2)分析结果,判断是否需要优化,如果各项参数设置合理,系统没有超时日志出现、GC效率不高,GC耗时不高,那么就没有必要进行优化(如MinorGC执行时间不到50ms,MinorGC执行不频繁,约10秒一次;Full GC执行时间不到1sFullGC执行频率不算频繁,不低于10分钟一次);如果GC时间超过1-3秒,或者频繁GC,则必须优化(3)调整GC类型和内存分配参数(4)不断的分析调整(5)全面应用参数

如何设计存储海量数据的存储系统

这个问题之前没遇到过,在网上搜的答案;
问题:1、数据库容量有限2、并行取数困难 3、JDBC访问效率太低4、数据库并发访问量太多,会导致IO瓶颈和数据库的计算负担太重,甚至还会出现内存溢出崩溃等现象
理想的解决方案是把大数据存到分布式文件系统中(如Lustre、HDFS、MogileFS、FastDFS、NFS)
1、只要增加机器和硬盘则容量不限,理论上可以无限增大
2、并行取数容易。由于文件可以根据字节数来访问
3、不存在IO瓶颈,由于分布式文件系统是把数据存储在不同的机器上,并发,并行数据时,分别从不同的机器读数
4、避开了JDBC
5、数据计算可以使用单独的计算引擎

另一种回答:
海量数据的解决方案:

页面上:使用缓存;页面静态化技术;

数据库层面: 分离数据库中活跃的数据;批量读取和延迟修改;读写分离;使用NoSQL和Hadoop等技术; 分布式部署数据库;应用服务和数据服务分离;

其他方面: 使用搜索引擎搜索数据库中的数据;进行业务的拆分;

高并发情况下的解决方案:应用程序和静态资源文件进行分离,静态资源可以使用CDN;

集群与分布式;使用Nginx反向代理;

淘宝热门商品信息在JVM哪个内存区域

应该在缓存中,然后落地在数据库中

我发现这个面经被整理的好多啊而且是2016年,我决定换一个
添加链接描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值