在这篇文章中,我们将带领您了解金三银四:蚂蚁金服JAVA后端面试题及答案之二面的全貌,包括蚂蚁金服java面试几轮的相关情况。同时,我们还将为您介绍有关15个java多线程面试题及答案,java面试题
在这篇文章中,我们将带领您了解金三银四:蚂蚁金服 JAVA 后端面试题及答案之二面的全貌,包括蚂蚁金服java面试几轮的相关情况。同时,我们还将为您介绍有关15个java多线程面试题及答案,java面试题分享!、2019 年 Java 篇:蚂蚁金服、拼多多、字节跳动的面试总结、2019年即将到来的金三银四所做准备,阿里Java后端研发面试题锦集、2019蚂蚁金服中高级Java工程师面试题及答案的知识,以帮助您更好地理解这个主题。
本文目录一览:- 金三银四:蚂蚁金服 JAVA 后端面试题及答案之二面(蚂蚁金服java面试几轮)
- 15个java多线程面试题及答案,java面试题分享!
- 2019 年 Java 篇:蚂蚁金服、拼多多、字节跳动的面试总结
- 2019年即将到来的金三银四所做准备,阿里Java后端研发面试题锦集
- 2019蚂蚁金服中高级Java工程师面试题及答案
金三银四:蚂蚁金服 JAVA 后端面试题及答案之二面(蚂蚁金服java面试几轮)
一面参考这篇文章:蚂蚁金服 JAVA 后端面试题及答案之一面
二面
22、你有什么问题想问我的吗?
1、自我介绍、工作经历、技术栈
2、项目中你学到了什么技术?
3、微服务划分的粒度?
4、微服务的高可用怎么保证的?
负载均衡与反向代理,隔离,限流,降级,超时与重试,回滚,压力测试与应急预案
5、常用的负载均衡,该怎么用,你能说下吗?
1、http 重定向
当 http 代理(比如浏览器)向 web 服务器请求某个 URL 后,web 服务器可以通过 http 响应头信息中的 Location 标记来返回一个新的 URL。这意味着 HTTP 代理需要继续请求这个新的 URL,完成自动跳转。
2、DNS 负载均衡
DNS 负责提供域名解析服务,当访问某个站点时,实际上首先需要通过该站点域名的 DNS 服务器来获取域名指向的 IP 地址,在这一过程中,DNS 服务器完成了域名到 IP 地址的映射,同样,这样映射也可以是一对多的,这时候,DNS 服务器便充当了负载均衡调度器,它就像 http 重定向转换策略一样,将用户的请求分散到多台服务器上,但是它的实现机制完全不同。
3、反向代理负载均衡
这个肯定大家都有所接触,因为几乎所有主流的 Web 服务器都热衷于支持基于反向代理的负载均衡。它的核心工作就是转发 HTTP 请求。
相比前面的 HTTP 重定向和 DNS 解析,反向代理的调度器扮演的是用户和实际服务器中间人的角色:
1、任何对于实际服务器的 HTTP 请求都必须经过调度器
2、调度器必须等待实际服务器的 HTTP 响应,并将它反馈给用户(前两种方式不需要经过调度反馈,是实际服务器直接发送给用户)
4、IP 负载均衡 (LVS-NAT)
因为反向代理服务器工作在 HTTP 层,其本身的开销就已经严重制约了可扩展性,从而也限制了它的性能极限。那能否在 HTTP 层面以下实现负载均衡呢?
NAT 服务器:它工作在传输层,它可以修改发送来的 IP 数据包,将数据包的目标地址修改为实际服务器地址
5、直接路由 (LVS-DR)
NAT 是工作在网络分层模型的传输层(第四层),而直接路由是工作在数据链路层(第二层),貌似更 6 些。它通过修改数据包的目标 MAC 地址(没有修改目标 IP),将数据包转发到实际服务器上,不同的是,实际服务器的响应数据包将直接发送给客户羰,而不经过调度器
6、IP 隧道 (LVS-TUN)
基于 IP 隧道的请求转发机制:将调度器收到的 IP 数据包封装在一个新的 IP 数据包中,转交给实际服务器,然后实际服务器的响应数据包可以直接到达用户端。目前 Linux 大多支持,可以用 LVS 来实现,称为 LVS-TUN,与 LVS-DR 不同的是,实际服务器可以和调度器不在同一个 WANt 网段,调度器通过 IP 隧道技术来转发请求到实际服务器,所以实际服务器也必须拥有合法的 IP 地址。
总体来说,LVS-DR 和 LVS-TUN 都适合响应和请求不对称的 Web 服务器,如何从它们中做出选择,取决于你的网络部署需要,因为 LVS-TUN 可以将实际服务器根据需要部署在不同的地域,并且根据就近访问的原则来转移请求,所以有类似这种需求的,就应该选择 LVS-TUN。
6、网关能够为后端服务带来哪些好处?
后端服务器可以专心处理业务请求,节省了大量连接管理的开销
7、Spring Bean 的生命周期
8、xml 中配置的 init、destroy 方法怎么可以做到调用具体的方法?
9、反射的机制
大家都知道,要让 Java 程序能够运行,那么就得让 Java 类要被 Java 虚拟机加载。Java 类如果不被 Java 虚拟机加载,是不能正常运行的。现在我们运行的所有的程序都是在编译期的时候就已经知道了你所需要的那个类的已经被加载了。
Java 的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射
反射机制通过 void setAccessible (boolean flag) 方法可以得到一个类的 private 的方法和属性,使用这些 private 的方法和属性
10、Object 类中的方法
1,构造函数
2,hashCode 和 equale 函数用来判断对象是否相同,
3,wait(),wait(long),wait(long,int),notify(),notifyAll()
4,toString () 和 getClass,
5,clone()
6,finalize () 用于在垃圾回收
11、hashcode 和 equals 方法常用地方
12、对象比较是否相同
equals 通常用来比较两个对象的内容是否相等,== 用来比较两个对象的地址是否相等
13、hashmap put 方法存放的时候怎么判断是否是重复的
先比较 key 的 hashCode,再比较相等或 equals 的,所以重写 hashCode () 和 equals () 方法即可实现添加重复元素。
14、Object toString 方法常用的地方,为什么要重写该方法
常用在对象模型类
因为假如 User 是一个用户的对象,如果 User.toString (); 结果是不正常的,因为 User 对象中可能有多个属性,如年龄,姓名等,这个 toString 后无法知道具体的是那个属性转换为字符串
15、Set 和 List 区别?
Set(集):集合中的对象不按特定方式排序,并且没有重复对象。它的有些实现类能对集合中的对象按特定方式排序。
List(列表):集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象。
16、ArrayList 和 LinkedList 区别
ArrayList 是实现了基于动态数组的数据结构,LinkedList 基于链表的数据结构
ArrayList 继承 AbstractList
LinkedList 继承 AbstractSequentialList
ArrayList 采用的是数组形式来保存对象的,这种方式将对象放在连续的位置中,所以最大的缺点就是插入删除时非常麻烦
LinkedList 采用的将对象存放在独立的空间中,而且在每个空间中还保存下一个链接的索引 但是缺点就是查找非常麻烦 要丛第一个索引开始
17、如果存取相同的数据,ArrayList 和 LinkedList 谁占用空间更大?
对于随机访问 get 和 set,ArrayList 觉得优于 LinkedList,因为 LinkedList 要移动指针
对于新增和删除操作 add 和 remove,LinedList 比较占优势,因为 ArrayList 要移动数据,若要从数组中删除或插入某一个对象,需要移动后段的数组元素,从而会重新调整索引顺序,调整索引顺序会消耗一定的时间,相反,LinkedList 是使用链表实现的,若要从链表中删除或插入某一个对象,只需要改变前后对象的引用即可
18、Set 存的顺序是有序的吗?
无序
Set 是 Map 的一个马甲,主要逻辑都交给 Map 实现
19、常见 Set 的实现有哪些?
HashSet
LinkedHashSet
TreeSet
20、TreeSet 对存入对数据有什么要求呢?
TreeSet 集合是用来对象元素进行排序的,同样他也可以保证元素的唯一
21、HashSet 的底层实现呢?
22、TreeSet 底层源码有看过吗?
TreeSet 的底层实现是 TreeMap
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
23、HashSet 是不是线程安全的?为什么不是线程安全的?
说白了,HashSet 就是限制了功能的 HashMap,所以了解 HashMap 的实现原理
24、Java 中有哪些线程安全的 Map?
Concurrenthashmap
25、Concurrenthashmap 是怎么做到线程安全的?
ConcurrentHashMap 的大部分操作和 HashMap 是相同的,例如初始化,扩容和链表向红黑树的转变等。但是,在 ConcurrentHashMap 中,大量使用了 U.compareAndSwapXXX
的方法,这个方法是利用一个 CAS 算法实现无锁化的修改值的操作,他可以大大降低锁代理的性能消耗。这个算法的基本思想就是不断地去比较当前内存中的变量值与你指定的
一个变量值是否相等,如果相等,则接受你指定的修改的值,否则拒绝你的操作。因为当前线程中的值已经不是最新的值,你的修改很可能会覆盖掉其他线程修改的结果。这一
点与乐观锁,SVN 的思想是比较类似的。
同时,在 ConcurrentHashMap 中还定义了三个原子操作,用于对指定位置的节点进行操作。这三种原子操作被广泛的使用在 ConcurrentHashMap 的 get 和 put 等方法中,
正是这些原子操作保证了 ConcurrentHashMap 的线程安全。
在 ConcurrentHashMap 没有出现以前,jdk 使用 hashtable 来实现线程安全,但是 hashtable 是将整个 hash 表锁住,所以效率很低下。
ConcurrentHashMap 将数据分别放到多个 Segment 中,默认 16 个,每一个 Segment 中又包含了多个 HashEntry 列表数组,
对于一个 key,需要经过三次 hash 操作,才能最终定位这个元素的位置,这三次 hash 分别为:
对于一个 key,先进行一次 hash 操作,得到 hash 值 h1,也即 h1 = hash1 (key);
将得到的 h1 的高几位进行第二次 hash,得到 hash 值 h2,也即 h2 = hash2 (h1 高几位),通过 h2 能够确定该元素的放在哪个 Segment;
将得到的 h1 进行第三次 hash,得到 hash 值 h3,也即 h3 = hash3 (h1),通过 h3 能够确定该元素放置在哪个 HashEntry。
每一个 Segment 都拥有一个锁,当进行写操作时,只需要锁定一个 Segment,而其它 Segment 中的数据是可以访问的。
26、HashTable 你了解过吗?
Hashtable 既不支持 Null key 也不支持 Null value。Hashtable 的 put () 方法的注释中有说明
Hashtable 是线程安全的,
Hashtable 是线程安全的,它的每个方法中都加入了 Synchronize 方法,效率比较低
Hashtable 默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。
Hashtable 在计算元素的位置时需要进行一次除法运算,而除法运算是比较耗时的。
27、如何保证线程安全问题?
28、synchronized、lock
synchronized 是 java 中的一个关键字,也就是说是 Java 语言内置的特性
如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)线程执行发生异常,此时 JVM 会让线程自动释放锁
那么如果这个获取锁的线程由于要等待 IO 或者其他原因(比如调用 sleep 方法)被阻塞了,但是又没有释放锁,其他线程便只能干巴巴地等待,试想一下,这多么影响程序执行效率。
因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过 Lock 就可以办到
再举个例子:当有多个线程读写文件时,读操作和写操作会发生冲突现象,写操作和写操作会发生冲突现象,但是读操作和读操作不会发生冲突现象。
但是采用 synchronized 关键字来实现同步的话,就会导致一个问题:
如果多个线程都只是进行读操作,所以当一个线程在进行读操作时,其他线程只能等待无法进行读操作。
因此就需要一种机制来使得多个线程都只是进行读操作时,线程之间不会发生冲突,通过 Lock 就可以办到。
另外,通过 Lock 可以知道线程有没有成功获取到锁。这个是 synchronized 无法办到的
29、volatile 的原子性问题?为什么 i++ 这种不支持原子性?从计算机原理的设计来讲下不能保证原子性的原因
30、happens before 原理
31、cas 操作
java.util.concurrent 包中借助 CAS 实现了区别于 synchronized 同步锁的一种乐观锁
cas 是比较并交换算法
CAS 有 3 个操作数,内存值 V,旧的预期值 A,要修改的新值 B。当且仅当预期值 A 和内存值 V 相同时,将内存值 V 修改为 B,否则什么都不做
JDK 提供了 AtomicReference 类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行 CAS 操作。
32、lock 和 synchronized 的区别?
1)Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现;
2)synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock () 去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁;
3)Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用 synchronized 时,等待的线程会一直等待下去,不能够响应中断;
4)通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
5)Lock 可以提高多个线程进行读操作的效率。
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时 Lock 的性能要远远优于 synchronized。所以说,在具体使用时要根据适当情况选择。
类别
synchronized
Lock
存在层次
Java 的关键字,在 jvm 层面上
是一个类
锁的释放
1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm 会让线程释放锁
在 finally 中必须释放锁,不然容易造成线程死锁
锁的获取
假设 A 线程获得锁,B 线程等待。如果 A 线程阻塞,B 线程会一直等待
分情况而定,Lock 有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待
锁状态
无法判断
可以判断
锁类型
可重入 不可中断 非公平
可重入 可判断 可公平(两者皆可)
性能
少量同步
大量同步
33、公平锁和非公平锁
公平和非公平锁的队列都基于锁内部维护的一个双向链表,表结点 Node 的值就是每一个请求当前锁的线程。公平锁则在于每次都是依次从队首取值
非公平锁在等待锁的过程中, 如果有任意新的线程妄图获取锁,都是有很大的几率直接获取到锁的
(在 ReentrantLock 中很明显可以看到其中同步包括两种,分别是公平的 FairSync 和非公平的 NonfairSync。公平锁的作用就是严格按照线程启动的顺序来执行的,不允许其他线程插队执行的;而非公平锁是允许插队的。
默认情况下 ReentrantLock 是通过非公平锁来进行同步的,包括 synchronized 关键字都是如此,因为这样性能会更好。因为从线程进入了 RUNNABLE 状态,可以执行开始,到实际线程执行是要比较久的时间的。而且,在一个锁释放之后,其他的线程会需要重新来获取锁。其中经历了持有锁的线程释放锁,其他线程从挂起恢复到 RUNNABLE 状态,其他线程请求锁,获得锁,线程执行,这一系列步骤。如果这个时候,存在一个线程直接请求锁,可能就避开挂起到恢复 RUNNABLE 状态的这段消耗,所以性能更优化)
34、Java 读写锁
35、读写锁设计主要解决什么问题?
多线程,
读操作可以共享,写操作是排他的,读可以有多个在读,写只有唯一个在写,同时写的时候不允许读
解决了读和读可以同时进行,读和写不能同时进行,写和写不能同时进行
36、你项目除了写 Java 代码,还有前端代码,那你知道前端有哪些框架吗?
Vue layer react element
37、MySQL 分页查询语句
LIMIT [offset,] rows
offset 指定要返回的第一行的偏移量,rows 第二个指定返回行的最大数目
38、MySQL 事务特性和隔离级别
一、事务的基本要素(ACID)
1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如 A 向 B 转账,不可能 A 扣了钱,B 却没收到。
3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如 A 正在从一张银行卡中取钱,在 A 取钱的过程结束前,B 不能向这张卡转账。
4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。
二、事务的并发问题
1、脏读:事务 A 读取了事务 B 更新的数据,然后 B 回滚操作,那么 A 读取到的数据是脏数据
2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务 A 多次读取的过程中,对数据作了更新并提交,导致事务 A 多次读取同一数据时,结果 不一致。
3、幻读:系统管理员 A 将数据库中所有学生的成绩从具体分数改为 ABCDE 等级,但是系统管理员 B 就在这个时候插入了一条具体分数的记录,当系统管理员 A 改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
MySQL 事务隔离级别
事务隔离级别
脏读
不可重复读
幻读
读未提交(read-uncommitted)
是
是
是
不可重复读(read-committed)
否
是
是
可重复读(repeatable-read)
否
否
是
串行化(serializable)
否
否
否
39、不可重复读会出现在什么场景?
40、sql having 的使用场景
如果需要对组函数的结果作为条件,那么不能使用 where 子句,必须使用 having 子句
41、前端浏览器地址的一个 http 请求到后端整个流程是怎么样?
能够说下吗?
域名解析 --> 发起 TCP 的 3 次握手 --> 建立 TCP 连接后发起 http 请求 --> 服务器响应 http 请求,浏览器得到 html 代码 --> 浏览器解析 html 代码,并请求 html 代码中的资源(如 js、css、图片等) --> 浏览器对页面进行渲染呈现给用户
42、http 默认端口,https 默认端口
HTTP 协议代理服务器常用端口号:80/8080/3128/8081/9080
HTTPS 服务器,默认的端口号为 443/tcp 443/udp
43、DNS 你知道是干嘛的吗?
DNS 是指:域名服务器 (Domain Name Server)。在 Internet 上域名与 IP 地址之间是一一对应的,域名虽然便于人们记忆,但机器之间只能互相认识 IP 地址,它们之间的转换工作称为域名解析,域名解析需要由专门的域名解析服务器来完成,DNS 就是进行域名解析的服务器
44、你们开发用的 ide 是啥?你能说下 idea 的常用几个快捷键吧?
45、代码版本管理你们用的是啥?
46、git rebase 和 merge 有什么区别?
47、你们公司加班多吗?
一面参考这篇文章:蚂蚁金服 JAVA 后端面试题及答案之一面
欢迎工作一到五年的 Java 工程师朋友们加入 Java 高级架构:867581223
群内提供免费的 Java 架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm 性能调优、Spring 源码,
MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx 等多个知识点的架构资料)
合理利用自己每一分每一秒的时间来学习提升自己,不要再用 " 没有时间 “来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
15个java多线程面试题及答案,java面试题分享!
15个java多线程面试题及答案
Java,可以说学完基础才是真正的开始,成功面试也是程序员必须经历的一步。面试答题技巧是很重要的,又快又准确的回答,能让公司对你产生好感。下面是我归纳的一些java多线程的面试题和答题思路。
1、现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。回答可以用join方法实现。
2、在Java中Lock接口比synchronized块的优势是什么?你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户写,以此来保持它的完整性,你会怎样去实现它?
lock接口在多线程和并发编程中最大的优势是它们为读和写分别提供了锁,它能满足你写像ConcurrentHashMap这样的高性能数据结构和有条件的阻塞。我建议你可以在去参加多线程的面试之前认真读一下Locks,因为当前其大量用于构建电子交易系统的客户端缓存和交易连接空间。
3、在java中wait和sleep方法的不同?
通常会在电话面试中经常被问到的Java线程面试问题。最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。
4、用Java实现阻塞队列。
这是一个相对艰难的多线程面试问题,它能达到很多的目的。第一,它可以检测侯选者是否能实际的用Java线程写程序;第二,可以检测侯选者对并发场景的理解,并且你可以根据这个问很多问题。如果他用wait()和notify()方法来实现阻塞队列,你可以要求他用最新的Java 5中的并发类来再写一次。
5、用Java写代码来解决生产者——消费者问题。
与上面的问题很类似,但这个问题更经典,有些时候面试都会问下面的问题。在Java中怎么解决生产者——消费者问题,当然有很多解决方法,我已经分享了一种用阻塞队列实现的方法。
6、用Java编程一个会导致死锁的程序,你将怎么解决?
这是我最喜欢的Java线程面试问题,因为即使死锁问题在写多线程并发程序时非常普遍,但是很多侯选者并不能写deadlock free code,他们很挣扎。只要告诉他们,你有N个资源和N个线程,并且你需要所有的资源来完成一个操作。为了简单这里的n可以替换为2,越大的数据会使问题看起来更复杂。通过避免Java中的死锁来得到关于死锁的更多信息。
7、 什么是原子操作,Java中的原子操作是什么?
非常简单的java线程面试问题,接下来的问题是你需要同步一个原子操作。
8、 Java中的Volatile关键是什么作用?怎样使用它?在Java中它跟synchronized方法有什么不同?
自从Java 5和Java内存模型改变以后,基于volatile关键字的线程问题越来越流行。应该准备好回答关于volatile变量怎样在并发环境中确保可见性、顺序性和一致性。
9、什么是竞争条件?你怎样发现和解决竞争?
这是一道出现在多线程面试的高级阶段的问题。大多数的面试官会问最近你遇到的竞争条件,以及你是怎么解决的。有些时间他们会写简单的代码,然后让你检测出代码的竞争条件。
10、你将如何使用thread dump?你将如何分析Thread dump?
在UNIX中你可以使用kill -3,然后thread dump将会打印日志,在windows中你可以使用”CTRL+Break”。非常简单和专业的线程面试问题,但是如果他问你怎样分析它,就会很棘手,需要认真考虑。
11、为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?
这是一个非常经典的java多线程面试问题。这也是我刚开始写线程程序时候的困惑。这个问题的回答应该是这样的,当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。但是如果你直接调用run()方法,它不会创建新的线程也不会执行调用线程的代码。
12、Java中你怎样唤醒一个阻塞的线程?
这是个关于线程和阻塞的棘手的问题,它有很多解决方法。如果线程遇到了IO阻塞,我并且不认为有一种方法可以中止线程。如果线程因为调用wait()、sleep()、或者join()方法而导致的阻塞,你可以中断线程,并且通过抛出InterruptedException来唤醒它。
13、在Java中CycliBarriar和CountdownLatch有什么区别?
这个线程问题主要用来检测你是否熟悉JDK5中的并发包。这两个的区别是CyclicBarrier可以重复使用已经通过的障碍,而CountdownLatch不能重复使用。
14、什么是不可变对象,它对写并发应用有什么帮助?
另一个多线程经典面试问题,并不直接跟线程有关,但间接帮助很多。这个java面试问题可以变的非常棘手,如果他要求你写一个不可变对象,或者问你为什么String是不可变的。
15、你在多线程环境中遇到的共同的问题是什么?你是怎么解决它的?
多线程和并发程序中常遇到的有Memory-interface、竞争条件、死锁、活锁和饥饿。问题是没有止境的,如果你弄错了,将很难发现和调试。这是大多数基于面试的,而不是基于实际应用的Java线程问题。
以上是一些简单的面试线程题,不全面,但是希望能帮到大家,更多面试题可以私信我获取!
2019 年 Java 篇:蚂蚁金服、拼多多、字节跳动的面试总结
上午 9 点,我还在去公司的公交上,突然收到蚂蚁的面试电话,其实算不上真正的面试。面试官只是和我聊了下他们在做的事情,说的很详细,然后和我沟通了下是否有兴趣,我表示有兴趣,后面就收到正式面试的通知,最后没选择去蚂蚁表示抱歉。
当时我自己也准备出去看看机会,顺便看看自己的实力。当时我其实挺纠结的,一方面现在部门也正需要我,还是可以有一番作为的,另一方面觉得近一年来进步缓慢,没有以前飞速进步的成就感了,而且业务和技术偏于稳定,加上自己也属于那种比较懒散的人,骨子里还是希望能够突破现状,持续在技术上有所精进。
在开始正式的总结之前,还是希望各位同仁能否听我继续发泄一会,抱拳!
目标是啥?就我而言,短期目标是深入研究某一项技术,比如最近在研究 mysql,那么深入研究一定要动手实践并且有所产出,这就够了么?还需要我们能够举一反三,结合实际开发场景想一想日常开发要注意什么,这中间有没有什么坑?可以看出,要进步真的不是一件简单的事,这种反人类的行为需要我们克服自我的弱点,逐渐形成习惯。真正牛逼的人,从不觉得认真学习是一件多么难的事,因为这已经形成了他的习惯,就和早上起床刷牙洗脸那么自然简单。
扯了那么多,开始进入正题,先后进行了蚂蚁、拼多多和字节跳动的面试。
准备过程
先说说我自己的情况,我 2016 先在蚂蚁实习了将近三个月,然后去了我现在的老东家,2.5 年工作经验,可以说毕业后就一直老老实实在老东家打怪升级,虽说有蚂蚁的实习经历,但是因为时间太短,还是有点虚的。所以面试官看到我简历第一个问题绝对是这样的。
“哇,你在蚂蚁待过,不错啊”,面试官笑嘻嘻地问到。“是的,还好”,我说。“为啥才三个月?”,面试官脸色一沉问到。“哗啦啦解释一通。。。”,我解释道。“哦,原来如此,那我们开始面试吧”,面试官一本正经说到。
尼玛,早知道不写蚂蚁的实习经历了,后面仔细一想,当初写上蚂蚁不就给简历加点料嘛。
言归正传,准备过程其实很早开始了(当然这不是说我工作时老想着跳槽,因为我明白现在的老东家并不是终点,我还需要不断提升),具体可追溯到从蚂蚁离职的时候,当时出来也面了很多公司,没啥大公司,面了大概 5 家公司,都拿到 offer 了。
工作之余常常会去额外研究自己感兴趣的技术以及工作用到的技术,力求把原理搞明白,并且会自己实践一把。此外,买了 N 多书,基本有时间就会去看,补补基础,什么操作系统、数据结构与算法、MySQL、JDK 之类的源码,基本都好好温习了(文末会列一下自己看过的书和一些好的资料)。我深知基础就像 “木桶效应” 的短板,决定了能装多少水。
此外,在正式决定看机会之前,我给自己列了一个提纲,主要包括 Java 要掌握的核心要点,有不懂的就查资料搞懂。我给自己定位还是 Java 工程师,所以 Java 体系是一定要做到心中有数的,很多东西没有常年的积累面试的时候很容易露馅,学习要对得起自己,不要骗人。
剩下的就是找平台和内推了,除了蚂蚁,头条和拼多多都是找人内推的,感谢蚂蚁面试官对我的欣赏,以后说不定会去蚂蚁咯。
平台:脉脉、GitHub、v2
蚂蚁金服
一面
一面就做了一道算法题,要求两小时内完成,给了长度为 N 的有重复元素的数组,要求输出第 10 大的数。典型的 TopK 问题,快排算法搞定。
算法题要注意的是合法性校验、边界条件以及异常的处理。另外,如果要写测试用例,一定要保证测试覆盖场景尽可能全。加上平时刷刷算法题,这种考核应该没问题的。
二面
自我介绍下呗
开源项目贡献过代码么?(Dubbo 提过一个打印 accesslog 的 bug 算么)
目前在部门做什么,业务简单介绍下,内部有哪些系统,作用和交互过程说下
Dubbo 踩过哪些坑,分别是怎么解决的?(说了异常处理时业务异常捕获的问题,自定义了一个异常拦截器)
开始进入正题,说下你对线程安全的理解(多线程访问同一个对象,如果不需要考虑额外的同步,调用对象的行为就可以获得正确的结果就是线程安全)
事务有哪些特性?(ACID)
怎么理解原子性?(同一个事务下,多个操作要么成功要么失败,不存在部分成功或者部分失败的情况)
乐观锁和悲观锁的区别?(悲观锁假定会发生冲突,访问的时候都要先获得锁,保证同一个时刻只有线程获得锁,读读也会阻塞;乐观锁假设不会发生冲突,只有在提交操作的时候检查是否有冲突)这两种锁在 Java 和 MySQL 分别是怎么实现的?(Java 乐观锁通过 CAS 实现,悲观锁通过 synchronize 实现。mysql 乐观锁通过 MVCC,也就是版本实现,悲观锁可以通过 select... for update 加上排它锁)
HashMap 为什么不是线程安全的?(多线程操作无并发控制,顺便说了在扩容的时候多线程访问时会造成死锁,会形成一个环,不过扩容时多线程操作形成环的问题再 JDK1.8 已经解决,但多线程下使用 HashMap 还会有一些其他问题比如数据丢失,所以多线程下不应该使用 HashMap,而应该使用 ConcurrentHashMap)怎么让 HashMap 变得线程安全?(Collections 的 synchronize 方法包装一个线程安全的 Map,或者直接用 ConcurrentHashMap) 两者的区别是什么?(前者直接在 put 和 get 方法加了 synchronize 同步,后者采用了分段锁以及 CAS 支持更高的并发)
jdk1.8 对 ConcurrentHashMap 做了哪些优化?(插入的时候如果数组元素使用了红黑树,取消了分段锁设计,synchronize 替代了 Lock 锁)为什么这样优化?(避免冲突严重时链表多长,提高查询效率,时间复杂度从 O (N) 提高到 O (logN))
redis 主从机制了解么?怎么实现的?
有过 GC 调优的经历么?(有点虚,答得不是很好)
有什么想问的么?
三面
简单自我介绍下
监控系统怎么做的,分为哪些模块,模块之间怎么交互的?用的什么数据库?(MySQL)使用什么存储引擎,为什么使用 InnnoDB?(支持事务、聚簇索引、MVCC)
订单表有做拆分么,怎么拆的?(垂直拆分和水平拆分)
水平拆分后查询过程描述下
如果落到某个分片的数据很大怎么办?(按照某种规则,比如哈希取模、range,将单张表拆分为多张表)
哈希取模会有什么问题么?(有的,数据分布不均,扩容缩容相对复杂)
分库分表后怎么解决读写压力?(一主多从、多主多从)
拆分后主键怎么保证惟一?(UUID、Snowflake 算法)
Snowflake 生成的 ID 是全局递增唯一么?(不是,只是全局唯一,单机递增)
怎么实现全局递增的唯一 ID?(讲了 TDDL 的一次取一批 ID,然后再本地慢慢分配的做法)
Mysql 的索引结构说下 (说了 B + 树,B + 树可以对叶子结点顺序查找,因为叶子结点存放了数据结点且有序)
主键索引和普通索引的区别 (主键索引的叶子结点存放了整行记录,普通索引的叶子结点存放了主键 ID,查询的时候需要做一次回表查询) 一定要回表查询么?(不一定,当查询的字段刚好是索引的字段或者索引的一部分,就可以不用回表,这也是索引覆盖的原理)
你们系统目前的瓶颈在哪里?
你打算怎么优化?简要说下你的优化思路
有什么想问我么?
四面
介绍下自己
为什么要做逆向?
怎么理解微服务?
服务治理怎么实现的?(说了限流、压测、监控等模块的实现)
这个不是中间件做的事么,为什么你们部门做?(当时没有单独的中间件团队,微服务刚搞不久,需要进行监控和性能优化)
说说 Spring 的生命周期吧
说说 GC 的过程 (说了 young gc 和 full gc 的触发条件和回收过程以及对象创建的过程)
CMS GC 有什么问题?(并发清除算法,浮动垃圾,短暂停顿)
怎么避免产生浮动垃圾?(记得有个 VM 参数设置可以让扫描新生代之前进行一次 young gc,但是因为 gc 是虚拟机自动调度的,所以不保证一定执行。但是还有参数可以让虚拟机强制执行一次 young gc)
强制 young gc 会有什么问题?(STW 停顿时间变长)
知道 G1 么?(了解一点)
回收过程是怎么样的?(young gc、并发阶段、混合阶段、full gc,说了 Remember Set)
你提到的 Remember Set 底层是怎么实现的?
有什么想问的么?
五面
五面是 HRBP 面的,和我提前预约了时间,主要聊了之前在蚂蚁的实习经历、部门在做的事情、职业发展、福利待遇等。阿里面试官确实是具有一票否决权的,很看重你的价值观是否 match,一般都比较喜欢皮实的候选人。HR 面一定要诚实,不要说谎,只要你说谎 HR 都会去证实,直接 cut 了。
之前蚂蚁实习三个月怎么不留下来?
实习的时候主管是谁?
实习做了哪些事情?(尼玛这种也问?)
你对技术怎么看?平时使用什么技术栈?(阿里 HR 真的是既当爹又当妈,)
最近有在研究什么东西么
你对 SRE 怎么看
对待遇有什么预期么
最后 HR 还对我说目前稳定性保障部挺缺人的,希望我尽快回复。
小结
蚂蚁面试比较重视基础,所以 Java 那些基本功一定要扎实。蚂蚁的工作环境还是挺赞的,因为我面的是稳定性保障部门,还有许多单独的小组,什么三年 1 班,很有青春的感觉。面试官基本水平都比较高,基本都 P7 以上,除了基础还问了不少架构设计方面的问题,收获还是挺大的。
拼多多
面试前
面完蚂蚁后,早就听闻拼多多这个独角兽,决定也去面一把。首先我在脉脉找了一个拼多多的 HR,加了微信聊了下,发了简历便开始我的拼多多面试之旅。这里要非常感谢拼多多 HR 小姐姐,从面试内推到 offer 确认一直都在帮我,人真的很 nice。
一面
为啥蚂蚁只待了三个月?没转正?(转正了,解释了一通。。。)
Java 中的 HashMap、TreeMap 解释下?(TreeMap 红黑树,有序,HashMap 无序,数组 + 链表)
TreeMap 查询写入的时间复杂度多少?(O (logN))
HashMap 多线程有什么问题?(线程安全,死锁) 怎么解决?( jdk1.8 用了 synchronize + CAS,扩容的时候通过 CAS 检查是否有修改,是则重试) 重试会有什么问题么?(CAS(Compare And Swap)是比较和交换,不会导致线程阻塞,但是因为重试是通过自旋实现的,所以仍然会占用 CPU 时间,还有 ABA 的问题) 怎么解决?(超时,限定自旋的次数,ABA 可以通过原理变量 AtomicStampedReference 解决,原理利用版本号进行比较) 超过重试次数如果仍然失败怎么办?(synchronize 互斥锁)
CAS 和 synchronize 有什么区别?都用 synchronize 不行么?(CAS 是乐观锁,不需要阻塞,硬件级别实现的原子性;synchronize 会阻塞,JVM 级别实现的原子性。使用场景不同,线程冲突严重时 CAS 会造成 CPU 压力过大,导致吞吐量下降,synchronize 的原理是先自旋然后阻塞,线程冲突严重仍然有较高的吞吐量,因为线程都被阻塞了,不会占用 CPU)
如果要保证线程安全怎么办?(ConcurrentHashMap)
ConcurrentHashMap 怎么实现线程安全的?(分段锁)
get 需要加锁么,为什么?(不用,volatile 关键字)
volatile 的作用是什么?(保证内存可见性)
底层怎么实现的?(说了主内存和工作内存,读写内存屏障,happen-before,并在纸上画了线程交互图)
在多核 CPU 下,可见性怎么保证?(思考了一会,总线嗅探技术)
聊项目,系统之间是怎么交互的?
系统并发多少,怎么优化?
给我一张纸,画了一个九方格,都填了数字,给一个 MN 矩阵,从 1 开始逆时针打印这 MN 个数,要求时间复杂度尽可能低(内心 OS:之前貌似碰到过这题,最优解是怎么实现来着)思考中。。。
可以先说下你的思路 (想起来了,说了什么时候要变换方向的条件,向右、向下、向左、向上,依此循环)
有什么想问我的?
二面
自我介绍下
手上还有其他 offer 么?(拿了蚂蚁的 offer)
部门组织结构是怎样的?(这轮不是技术面么,不过还是老老实实说了)
系统有哪些模块,每个模块用了哪些技术,数据怎么流转的?(面试官有点秃顶,一看级别就很高)给了我一张纸,我在上面简单画了下系统之间的流转情况
链路追踪的信息是怎么传递的?(RpcContext 的 attachment,说了 Span 的结构:parentSpanId + curSpanId)
SpanId 怎么保证唯一性?(UUID,说了下内部的定制改动)
RpcContext 是在什么维度传递的?(线程)
Dubbo 的远程调用怎么实现的?(讲了读取配置、拼装 url、创建 Invoker、服务导出、服务注册以及消费者通过动态代理、filter、获取 Invoker 列表、负载均衡等过程(哗啦啦讲了 10 多分钟),我可以喝口水么)
Spring 的单例是怎么实现的?(单例注册表)
为什么要单独实现一个服务治理框架?(说了下内部刚搞微服务不久,主要对服务进行一些监控和性能优化)
谁主导的?内部还在使用么?
逆向有想过怎么做成通用么?
有什么想问的么?
三面
二面老大面完后就直接 HR 面了,主要问了些职业发展、是否有其他 offer、以及入职意向等问题,顺便说了下公司的福利待遇等,都比较常规啦。不过要说的是手上有其他 offer 或者大厂经历会有一定加分。
小结
拼多多的面试流程就简单许多,毕竟是一个成立三年多的公司。面试难度中规中矩,只要基础扎实应该不是问题。但不得不说工作强度很大,开始面试前 HR 就提前和我确认能否接受这样强度的工作,想来的老铁还是要做好准备
字节跳动
面试前
头条的面试是三家里最专业的,每次面试前有专门的 HR 和你约时间,确定 OK 后再进行面试。每次都是通过视频面试,因为都是之前都是电话面或现场面,所以视频面试还是有点不自然。也有人觉得视频面试体验很赞,当然萝卜青菜各有所爱。最坑的二面的时候对方面试官的网络老是掉线,最后很冤枉的挂了(当然有一些点答得不好也是原因之一)。所以还是有点遗憾的。
一面
先自我介绍下
聊项目,逆向系统是什么意思
聊项目,逆向系统用了哪些技术
线程池的线程数怎么确定?
如果是 IO 操作为主怎么确定?
如果计算型操作又怎么确定?
Redis 熟悉么,了解哪些数据结构?(说了 zset) zset 底层怎么实现的?(跳表)
跳表的查询过程是怎么样的,查询和插入的时间复杂度?(说了先从第一层查找,不满足就下沉到第二层找,因为每一层都是有序的,写入和插入的时间复杂度都是 O (logN))
红黑树了解么,时间复杂度?(说了是 N 叉平衡树,O (logN))
既然两个数据结构时间复杂度都是 O (logN),zset 为什么不用红黑树 (跳表实现简单,踩坑成本低,红黑树每次插入都要通过旋转以维持平衡,实现复杂)
点了点头,说下 Dubbo 的原理?(说了服务注册与发布以及消费者调用的过程) 踩过什么坑没有?(说了 dubbo 异常处理的和打印 accesslog 的问题)
CAS 了解么?(说了 CAS 的实现)还了解其他同步机制么?(说了 synchronize 以及两者的区别,一个乐观锁,一个悲观锁)
那我们做一道题吧,数组 A,2*n 个元素,n 个奇数、n 个偶数,设计一个算法,使得数组奇数下标位置放置的都是奇数,偶数下标位置放置的都是偶数
先说下你的思路(从 0 下标开始遍历,如果是奇数下标判断该元素是否奇数,是则跳过,否则从该位置寻找下一个奇数)
下一个奇数?怎么找?(有点懵逼,思考中。。)
有思路么?(仍然是先遍历一次数组,并对下标进行判断,如果下标属性和该位置元素不匹配从当前下标的下一个遍历数组元素,然后替换)
你这样时间复杂度有点高,如果要求 O (N) 要怎么做(思考一会,答道 “定义两个指针,分别从下标 0 和 1 开始遍历,遇见奇数位是是偶数和偶数位是奇数就停下,交换内容”)
时间差不多了,先到这吧。你有什么想问我的?
二面
面试官和蔼很多,你先介绍下自己吧
你对服务治理怎么理解的?
项目中的限流怎么实现的?(Guava ratelimiter,令牌桶算法)
具体怎么实现的?(要点是固定速率且令牌数有限)
如果突然很多线程同时请求令牌,有什么问题?(导致很多请求积压,线程阻塞)
怎么解决呢?(可以把积压的请求放到消息队列,然后异步处理)
如果不用消息队列怎么解决?(说了 RateLimiter 预消费的策略)
分布式追踪的上下文是怎么存储和传递的?(ThreadLocal + spanId,当前节点的 spanId 作为下个节点的父 spanId)
Dubbo 的 RpcContext 是怎么传递的?(ThreadLocal)主线程的 ThreadLocal 怎么传递到线程池?(说了先在主线程通过 ThreadLocal 的 get 方法拿到上下文信息,在线程池创建新的 ThreadLocal 并把之前获取的上下文信息设置到 ThreadLocal 中。这里要注意的线程池创建的 ThreadLocal 要在 finally 中手动 remove,不然会有内存泄漏的问题)
你说的内存泄漏具体是怎么产生的?(说了 ThreadLocal 的结构,主要分两种场景:主线程仍然对 ThreadLocal 有引用和主线程不存在对 ThreadLocal 的引用。第一种场景因为主线程仍然在运行,所以还是有对 ThreadLocal 的引用,那么 ThreadLocal 变量的引用和 value 是不会被回收的。第二种场景虽然主线程不存在对 ThreadLocal 的引用,且该引用是弱引用,所以会在 gc 的时候被回收,但是对用的 value 不是弱引用,不会被内存回收,仍然会造成内存泄漏)
线程池的线程是不是必须手动 remove 才可以回收 value?(是的,因为线程池的核心线程是一直存在的,如果不清理,那么核心线程的 threadLocals 变量会一直持有 ThreadLocal 变量)
那你说的内存泄漏是指主线程还是线程池?(主线程 )
可是主线程不是都退出了,引用的对象不应该会主动回收么?(面试官和内存泄漏杠上了),沉默了一会。。。
那你说下 SpringMVC 不同用户登录的信息怎么保证线程安全的?(刚才解释的有点懵逼,一下没反应过来,居然回答成锁了。大脑有点晕了,此时已经一个小时过去了,感觉情况不妙。。。)
这个直接用 ThreadLocal 不就可以么,你见过 SpringMVC 有锁实现的代码么?(有点晕菜。。。)
我们聊聊 mysql 吧,说下索引结构(说了 B + 树)
为什么使用 B + 树?( 说了查询效率高,O (logN),可以充分利用磁盘预读的特性,多叉树,深度小,叶子结点有序且存储数据)
什么是索引覆盖?(忘记了。。。)
Java 为什么要设计双亲委派模型?
什么时候需要自定义类加载器?
我们做一道题吧,手写一个对象池
有什么想问我的么?(感觉我很多点都没答好,是不是挂了(结果真的是) )
小结
头条的面试确实很专业,每次面试官会提前给你发一个视频链接,然后准点开始面试,而且考察的点都比较全。
面试官都有一个特点,会抓住一个值得深入的点或者你没说清楚的点深入下去直到你把这个点讲清楚,不然面试官会觉得你并没有真正理解。二面面试官给了我一点建议,研究技术的时候一定要去研究产生的背景,弄明白在什么场景解决什么特定的问题,其实很多技术内部都是相通的。很诚恳,还是很感谢这位面试官大大。
总结
从年前开始面试到头条面完大概一个多月的时间,真的有点身心俱疲的感觉。最后拿到了拼多多、蚂蚁的 offer,还是蛮幸运的。头条的面试对我帮助很大,再次感谢面试官对我的诚恳建议,以及拼多多的 HR 对我的啰嗦的问题详细解答。
彩蛋:
本文到这里就结束了,喜欢的朋友可以帮忙转发和关注一下,感谢支持!
平时收集了很多面试的资料 也做了整理有需要的朋友可以获取:867581223
还赠送 Spring 源码分析、Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式资料
这份知识尤其适合:
1. 近期想跳槽,要面试的 Java 程序员,查漏补缺,以便尽快弥补短板;
2. 想了解 “一线互联网公司” 最新招聘需求 / 技术要求,对比找出自身的长处和弱点所在,评估自己在现有市场上的竞争力如何;
3. 还没形成系统的 Java 知识体系,缺乏清晰的提升方向和学习路径的程序员。
4. 想去一线互联网公司缺乏信心
2019年即将到来的金三银四所做准备,阿里Java后端研发面试题锦集
阿里java相关问题,都是之前通过不断优秀人才的铺垫总结的,希望对大家帮助,祝面试成功,有个更好的职业规划。
1、微信红包怎么实现。
2、海量数据分析。
3、测试职位问的线程安全和非线程安全。
4、HTTP2.0、thrift。
5、面试电话沟通可能先让自我介绍。
6、分布式事务一致性。
7、nio的底层实现。
8、jvm基础是必问的,jvm GC原理,JVM怎么回收内存。
9、Java是什么。
10、API接口与SDI接口的区别(API是提供给别人的接口)。
11、dubbo如何一条链接并发多个调用。Dubbo的原理,序列化相关问题。
12、用过哪些中间件。
13、做过工作流引擎没有。
14、以前的工作经历,自己觉得出彩的地方(钉钉)
15、线程池的一些原理,锁的机制升降级(天猫、蚂蚁)
16、从系统层面考虑,分布式从哪些纬度考虑(天猫)
17、Hadoop底层怎么实现(天猫)
18、threadLocal,线程池,hashMap/hashTable/coccurentHashMap等(天猫)
19、秒杀系统的设计(天猫)
20、虚拟机,IO相关知识点(天猫)
21、Linux的命令(天猫)
22、一个整形数组,给定一个数,在数组中找出两个数的和等于这个数,并打印出来,我写的时间复杂度高,要求O(n)。(天猫)
23、n个整数,找出连续的m个数加和是最大。(天猫)
24、更重视开源技术(蚂蚁金服上海)
25、数据库锁隐原理(蚂蚁金服网商)
26、1000个线程同时运行,怎么防止不卡(航旅)
27、并列的并发消费问题(航旅)
28、高并发量大的话怎么处理热点,数据等(蚂蚁金服)
29、如何获取一个本地服务器上可用的端口
30、流量控制相关问题(蚂蚁金服)
31、数据库TPS是多少,是否进行测试过(天猫)
32、缓存击穿有哪些方案解决(天猫)
33、Java怎么挖取回收器相关原理(财富)
34、Java的集合都有哪些,都有什么特点(信息平台)
35、分布式锁,redis缓存,spring aop,系统架构图,MySQL的特性(信息平台)
36、场景,同时给10万个人发工资,怎么样设计并发方案,能确保在1分钟内全部发完 打个比方会提出类似的场景(信息平台)
37、Java进阶之路架构群:878249276
38. 统计一个整数的二进制表示中bit为1的个数
39. jvm内存模型,java内存模型
40. 如何把java内存的数据全部dump出来
41. 如何手动触发全量回收垃圾,如何立即触发垃圾回收
42. hashmap如果只有一个写其他全读会出什么问题
43. git rebase
44. mongodb和hbase的区别
45. 如何解决并发问题
46. volatile的用途
47. java线程池(好像之前我的理解有问题)
48. mysql的binlog
49. 代理模式
50. mysql是如何实现事务的
阿里HR面试时的核心问题:
1、你为什么离职?
2、你怎么看待自己的职涯?(包括工作和家庭的分配,怎么平衡家庭和工作的关系、加班、选择一家公司时的考量、location等)
3、薪资期望(不要直接说数,绝不能表现出没到多少钱或者什么层级我就不去,这是味道问题不是能力问题)
候选人被问过的一些题目:
1、项目中遇到的最大挑战是什么?怎么解决的?
2、最有成就感的事情是?
3、你为什么选择阿里?
4、说说自己性格上的优缺点(描述一下自己的性格)
5、自己觉得自己工作上的短板/优点是什么?
6、怎么看待加班(你能接受996、997、007吗)? 如果候选人的调性符合(足够官方),可以这么回答:我觉得我们要实现梦想,一定是要付出比较多努力的,所以我已经做好了准备,也愿意和小伙伴们一起战斗 我是可以加班的,我现在加班强度就是比较大的。因为我喜欢这个事情,我想把这个事情做好。
7、可以接受降薪吗?(像蚂蚁这种你懂的) 如果候选人的调性符合(足够官方),可以这么回答:我也理解蚂蚁金服现在的薪资架构,我相信公司会根据我的能力给出一个合理的薪水方案,我相信只要把事情做好,该有的一定会有的 对于蚂蚁这样的部门,“ 我们在创造历史、我们在做一个从来没有人做过的事情,所以肯定是有难度的,肯定是要付出大量努力的 ”,面试官会特别喜欢这样的话。
技巧:
1、答非所问:感觉到答案说出来对方会不待见的时候,可以这么做:有关联性的答非所问,注意强调自己的想法,争取让面试官能够共情,比如深圳的房价可以引人共情、电商相关的大平台、稳定、有上升空间等。
2、面试的状态很重要:两个例子,上月一个成功offer的候选人,非互联网背景,公司也不是一线的,但是面试时表现出对阿里很强烈的兴趣,HR事后特地向我们提到,对这位候选人印象很深刻;另一位今天刚挂的候选人,两轮技术都是一举拿下,最后HR面挂了,HR给我们的反馈是,候选人刚从自己的创业公司离职,貌似情绪很低落,对自己也没什么想法。 综上所述,面试时既不要唯唯诺诺,过于被动,也不要过于夸张,而是在于展现自己对一个不错机会的尊重和争取,让面试官觉得你对他们,对这个岗位有很大的兴趣。
注意事项:
1、阿里比绝大部分公司更看重情怀和梦想
阿里的八字箴言:乐观、聪明、皮实、自省
2、阿里里面的HR都是懂业务的,会结合对候选人的判断和业务的把控进行筛选,不要忽悠他们.......
相信自己,没有做不到的,只有想不到的,相信自己,自信才能展现最好的你。
大家不妨留言,一起吐槽下各种面试经验(奇葩面试官、面试题、公司等)
本文分享自微信公众号 - 程序猿技术大咖(cxyjsdk)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
2019蚂蚁金服中高级Java工程师面试题及答案
面试基础
-
谈谈一致hash算法?
按照hash算法来将对应的key哈希到一个具有2^32次方个桶的空间中,即0~(2^32)-1的数字空间。将这些数字头尾相连,想象成一个闭合的环形。如果集群中加入新的机器,采用它的IP或者唯一别名计算哈希值,也映射到环中。新增key值以顺时针的方向,存储到离自己最近的机器中。
参考:https://blog.csdn.net/cb_lcl/article/details/81448570 -
说说乐观锁和悲观锁?
乐观锁:假设每次操作别人不会修改数据,当更新的时候根据版本号判断数据是否变化,适合读多写少的场景。
悲观锁:假设每次操作别人会修改数据,操作前先加上锁,后面的操作被阻塞,直至操作完毕释放锁。 -
说说对MySQL的了解,和Oracle的区别?
MySQL是一种开源关系型数据库,支持标准的SQL语言,支持多种数据引擎、事务、主从配置。广泛用于中小型互联网公司。与Oracle的区别:- 定位:Oracle是大型数据库,Mysql是中小型数据库。Oracle是付费的商业数据库,MySQL是免费开源数据库。
- 性能:Oracle有更强的并发性能,更丰富的数据管理工具。
-
说说事务四大特性?
- A(原子性):事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- C(一致性):事务前后数据的完整性必须保持一致,符合逻辑运算。
- I(隔离性):多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- D(持久性):事务一旦被提交,它对数据的改变是永久性的,即使数据库发生故障也不应该对其有影响。
-
说说事务的两阶段提交机制?
分布式事务有两个角色:事务协调者和事务参与者,两阶段提交协议是协调所有事务参与者决定提交或取消(回滚)的方式。- prepare阶段:协调者询问各个参与者是否正常执行,通知事务参与者准备提交或取消事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地作业执行成功)或取消(本地作业执行故障)。
- commit阶段:协调者利用准备阶段的结果进行决策,当且仅当所有的参与者同意提交事务协调者才通知所有的参与者提交事务,否则协调者将通知所有的参与者取消事务
-
说说数据库的索引原理,聚簇索引和非聚簇索引?
索引本质上是一种数据结构(存储结构+算法),目的是为了加快数据检索的速度。 https://www.jianshu.com/p/e1dce41a6b2b -
举例说一下索引的使用场景?
- 主键索引:给表设置主键,这个表就拥有主键索引。
- 普通索引:增加某个字段的索引,比如用户表根据用户名查询。
- 复合索引:多个字段增加索引,遵循最左原则,比如创建索引(col1 + col2 + col3),相当于创建了(col1)、(col1,col2)、(col,col2,col3)三个索引。
-
说说数据库当前读和快照读?
- 快照读:简单的
select
是快照读。 - 当前读:
select for update,insert,update,delete
是当前读。 - 原 理:在repeat read级别下,快照读是通过MVVC(多版本控制)和undo log来实现的,当前读是通过加record lock(记录锁)和gap lock(间隙锁)来实现的。
- 快照读:简单的
-
HashTable & HashMap & ConcurrentHashMap区别及优缺点?
相比HashMap,HashTable和ConcurrentHashMap都是线程安全的。HashTable在put和get操作上加上synchronize实现同步控制。而ConcurrentHashMap通过分段锁,避免锁住全哈希表,提高了同步效率。
参考:https://www.cnblogs.com/sunshinekevin/p/10625516.html -
Synchronize是可重入锁吗,实现原理?
可重入锁, 参考:https://blog.csdn.net/zc19921215/article/details/84780335 -
说说JVM类加载过程? 加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。 装载:查找和导入Class文件。 链接:把类的二进制数据合并到JRE中。 校验:检查载入Class文件数据的正确性。 准备:给类的静态变量分配存储空间。 解析:将符号引用转成直接引用。 初始化:对类的静态变量,静态代码块执行初始化操作。
-
JVM双亲委派机制及使用原因?
- 机制:将当前类的加载任务转给它的父类加载器,如果它的父类还有父类,就继续向上传递,如果父类加载器加载失败则自己加载。
- 意义:避免重复加载以及核心类的修改风险。
-
说说Java的GC机制,有哪几种GC算法?
C/C++申请内存时都要malloc进行系统调用,使用完毕后通过free释放内存。Java虚拟机是先一次性分配一块较大的空间,然后在该空间上自动进行分配和释放,一般情况下程序员不需要手动操作。GC机制就是解决自动回收,面临三个问题:怎么确定垃圾,怎么回收垃圾,什么时候回收。-
怎么确定垃圾:
- 引用计数算法:给对象添加一个引用计数器,当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是死亡的。引用计数算法很简单,判断效率也很高,但是JVM没有选用它来管理内存。原因是什么呢?主要是因为它很难解决循环引用的问题。
- 可达性分析算法:通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所有走过的路径称为“引用链”,当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。
-
怎么回收垃圾:
- 分代收集法:它根据对象的生存周期,将堆分为新生代和老年代。在新生代中,由于对象生存期短,每次回收都会有大量对象死去,那么这时就采用复制算法。老年代里的对象存活率较高,没有额外的空间进行分配担保,所以可以使用标记整理或者标记清除。
- 标记清除法:将需要回收的对象标记出来,批量清除。缺点是效率低,产生碎片。
- 标记整理法:将需要回收的对象标记出来,移动到一端再清除,避免了碎片的产生。
- 复制法:将新生代内存划分为8:1:1三部分,较大的叫Eden区,其余是两块较小的Survior区。每次都会优先使用Eden区,若Eden区满,就将对象复制到第二块内存区上,然后清除Eden区,如果此时存活的对象太多,以至于Survivor不够时,会将这些对象通过分配担保机制复制到老年代中。
-
什么时候回收:
GC有两种类型:Scavenge GC和Full GC。- Scavenge GC:一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。
- Full GC:对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC:
- 年老代(Tenured)被写满
- 持久代(Perm)被写
- System.gc()被显示调用
- 上一次GC之后Heap的各域分配策略动态变化
参考:https://blog.csdn.net/u011983531/article/details/79479972
-
-
说说线程池的核心参数和基本原理、调优策略?
- 核心参数:
corePoolSize:线程池中核心线程数量。
maximumPoolSize:线程池同时允许存在的最大线程数量。
RejectedExecutionHandler:拒绝服务策略。
keepAliveTime:当线程池中工作线程数大于corePoolSize,并且线程空闲时间超过keepAliveTime,这些线程将被终止。 - 基本原理:
参考:https://www.jianshu.com/p/896b8e18501b - 调优策略 要想合理的配置线程池,就必须首先分析任务特性,从以下几个角度来进行分析: 任务的性质:CPU密集型任务,IO密集型任务和混合型任务。 任务的优先级:高,中和低。 任务的执行时间:长,中和短。 任务的依赖性:是否依赖其他系统资源,如数据库连接。
参考:https://blog.csdn.net/chenpeng19910926/article/details/78142187
- 核心参数:
-
Collections.sort底层排序方式?排序稳定性?具体场景的排序策略? Arrays.sort和Collections.sort最终使用的都是TimSort的算法。 Timsort的核心过程:
1、数组个数小于32的情况使用二分插入排序。
2、数组大于32时,先算出一个合适的大小,在将输入按其升序和降序特点进行了分区。排序的输入的单位不是一个个单独的数字,而是一个个的块-分区。其中每一个分区叫一个run。针对这些 run 序列,每次拿一个run出来按规则进行合并。每次合并会将两个run合并成一个 run。合并的结果保存到栈中。合并直到消耗掉所有的run,这时将栈上剩余的 run合并到只剩一个 run 为止。这时这个仅剩的 run 便是排好序的结果。 3、Timsort是稳定的算法,当待排序的数组中已经有排序好的数,它的时间复杂度会小于nlogn。与其他合并排序一样,Timesort是稳定的排序算法,最坏时间复杂度是O(n log n)。在最坏情况下,Timsort算法需要的临时空间是n/2,在最好情况下,它只需要一个很小的临时存储空间 -
频繁老年代回收怎么分析解决?
参考:
https://www.cnblogs.com/justdojava/p/11198106.html
http://www.codersui.com/198.html
年轻代中经历了N次垃圾回收后仍然存活的对象,会被放到年老代中,老年代占满后触发FULL GC,一般是有对象无法回收会导致老年代频繁回收,排查步骤如下:- ps命令拿到pid:
ps -ef|grep your_application
- jstat命令查询gc情况:
jstat -gcutil 172046 1000
- 使用jmap分析对象占用内存情况,并导出到jmap.txt中:
jmap -histo 172046 > jmap.txt
- ps命令拿到pid:
-
说说Spring IOC、AOP的原理?
- IOC是控制反转的意思,用于降低代码之间的耦合度。工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。 (对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来).
- AOP意为面向切面编程,基于代理思想。对原来目标对象创建代理对象,在不修改原对象代码情况下,通过代理对象增加增强功能的代码,从而对原有业务方法进行增强。实现方式有JDK动态代理和动态字节码Cglib技术。
-
阻塞队列不用java提供的自己怎么实现,condition和wait不能用? https://blog.csdn.net/h525483481/article/details/80347485
-
拥塞窗口为什么要用慢启动?
https://www.cnblogs.com/losbyday/p/5847041.html -
说说负载均衡有几种算法以及优缺点?
- 轮询
将所有请求,依次分发到每台服务器上,适合服务器硬件相同的场景。
优点:服务器请求数目相同
缺点:服务器压力不一样,不适合服务器配置不同的情况 - 随机
请求随机分配到各台服务器上。
优点:使用简单
缺点:不适合机器配置不同的场景 - 最少链接
将请求分配到连接数最少的服务器上(目前处理请求最少的服务器)。
优点:根据服务器当前的请求处理情况动态分配
缺点:算法实现相对复杂,需要监控服务器请求连接数 - Hash(源地址散列)
根据IP地址进行Hash计算,得到IP地址。
优点:将来自同一IP地址的请求,同一会话期内,转发到相同的服务器,实现会话粘滞
缺点:目标服务器宕机后,会话会丢失 - 加权
在轮询、随机、最少链接、Hash等算法的基础上,通过加权的方式,进行负载服务器分配。
优点:根据权重,调节转发服务器的请求数目
缺点:使用相对复杂
- 轮询
-
Redis的数据一致性问题(分布式多节点环境 & 单机环境) https://blog.csdn.net/qq_27384769/article/details/79499373
-
简述docker容器?
Docker是一个容器化平台,它以容器的形式将您的应用程序及其所有依赖项打包在一起,以确保您的应用程序在任何环境中无缝运行。 -
设计模式的看法和认知,有哪些设计模式?
设计模式就是一套被反复使用,多数人知晓的代码设计经验的总结。常用的设计模式如下:
工厂模式:Spring通过工厂模式创建bean
代理模式:Spring AOP通过动态代理增强原对象的功能
责任链模式:SpringMVC的过滤器
单例模式:spring构建的对象默认是单例 -
如何实现分布式缓存?
分布式缓存系统要满足动态扩展和高可用性,通常采用Redis实现。Sentinel模式实现主从, Cluster模式实现集群。通过key做一致性哈希,实现key对应redis结点的分布。 -
多线程如何避免死锁?
- 加锁顺序(线程按照一定的顺序加锁)
- 加锁时限(线程尝试获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)
- 死锁检测(jstack -l jvm_pid)
-
简述对JVM中的Runtime?
Runtime类代表Java程序的运行时环境,每个Java程序都有一个Runtime实例,该类会被自动创建,可以通过Runtime.getRuntime()方法来获取当前程序的Runtime实例。 -
DNS解析过程?
- 查询本地hosts文件
- 查询本次DNS缓存
- 查询本地DNS服务器
- 本地DNS服务器转发请求到根DNS服务器
参考:https://www.jianshu.com/p/401f34691dcc
-
简述Htttp协议,Http和Https的区别,Https的加密方式? HTTP是一个基于TCP/IP通信协议来传递数据(HTML文件、图片等),属于客户端-服务端工作模式,浏览器作为HTTP客户端通过URL向WEB服务器发送请求。https是http和TCP之间加入的SSL层,作用是防止钓鱼和数据加密。HTTPS采用非对称加密算法协商对称加密算法,处理步骤如下:
- 服务器将携带的公钥向数字证书机构申请证书。
- 数字证书机构用自己的私钥对公钥签名颁发证书,并返回给服务器。
- 服务器将申请携带公钥的证书分发给客服端。
- 客户端验证证书,证书机构通过验证,或者用户接受不受信任的证书(非权威机构颁发的证书)。获取到公钥。到这一步,在证书保证下服务器拥有私钥,客户端拥有公钥,可进行非对称性加密。
- 使用公钥加密报文发送给服务器,其中携带随机串。其中的随机串用户传输数据时进行对称加密。
- 服务器使用私钥解密。获取报文信息及随机串。
- 解密后服务器发送握手消息给客户端。
- 客户端接受握手消息,握手结束,双方确定加密算法(使用随机串确定的对称性加密),开始传输。
- 数据传输过程使用对称性加密算法。
-
Http请求过程?
- 对网址进行DNS域名解析,得到对应的IP地址。
- 根据IP找到对应的服务器,发起TCP的三次握手。
- 建立TCP连接后发起HTTP请求。
- 服务器响应HTTP请求,浏览器得到html代码。
- 浏览器解析html代码,请求html中包含其他资源地址(如js、css图片等)。
- 浏览器对页面进行渲染呈现给用户。
-
说说TCP协议的三次握手四次挥手?
-
三次握手:
- 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
- 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
- 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
-
四次挥手:
- 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
- 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
- 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
- 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
参考:https://www.cnblogs.com/lms0755/p/9053119.html
项目经验
-
对你来说影响最大的一个项目?
-
说说自己参与的项目技术难度在哪里?哪一部分最难攻克?如何攻克?
-
为什么会想做这个项目?这个项目的idea是谁提出来的?
-
说说对项目中用到中间件的理解(Dubbo、MQ、Redis、kafka、zookeeper)?
-
服务器雪崩是怎么造成的?之前有这样的经历吗?怎么防备?
-
说说高并发架构的设计思路?
- CDN缓存静态资源
- 服务拆分和负载均衡
- 分布式缓存
- 消息队列解耦流量削峰
- 数据库集群和库表散列。
-
项目中如何实现的大数据的传输和存储?
-
如何实现何高并发下的削峰和限流?
限流算法:漏桶算法和令牌桶算法(基于Redis的分布式令牌桶实现) -
简述软件模块化的好处?
- 有利于代码复用
- 有利于分工协作
- 有利于模块化测试
- 有利于模块化部署与监控、排错
生活经历
- 生活中遇到的最大的挫折,怎么解决的?
- 生活中遇到的最有成就感的事情?
- 你的职业规划是什么?
关于金三银四:蚂蚁金服 JAVA 后端面试题及答案之二面和蚂蚁金服java面试几轮的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于15个java多线程面试题及答案,java面试题分享!、2019 年 Java 篇:蚂蚁金服、拼多多、字节跳动的面试总结、2019年即将到来的金三银四所做准备,阿里Java后端研发面试题锦集、2019蚂蚁金服中高级Java工程师面试题及答案等相关知识的信息别忘了在本站进行查找喔。
本文标签: