前言
当你开始开始去跳槽面试的时候,明明只是一份15K的工作,却问你会不会多线程,懂不懂高并发,火箭造得让你猝及不防,结果就是凉凉;现如今市场,多线程、高并发编程、分布式、负载均衡、集群等可以说是现在高级后端开发求职的必备技能。
早期的鸟儿有虫吃,现如今做开发的门槛越来越高
但是,术业有专攻,总有一些技术牛逼的程序员可以吊打、碾压面试官!
本人经常隔段时间就偷偷投点简历,请假出去面试几次,目的不是想跳槽,主要是为了看看市场上的技术流行趋势,顺便检验一下自己的水平,当然,如果面到了心仪的公司或者大厂,那不是更好嘛,哈哈哈!
前段时间收到了字节跳动的面试,虽然有点小震惊,但还是用平常心对待了。结果一不小心,面试的时候就吊打了面试官。
前后一个半小时的面试过程全程没卡壳,项目和算法全部搞定,甚至聊到了面试官的盲点…
结果……当然是顺利的接到了字节跳动的Offer,定级为2-2资深研发人员。
个人经历
其实我有好长一段时间没有正规的面试过了。三年前从数云换到GIO的时候,因为简历上的相关技术太过于匹配,所以基本上就和CTO聊了聊就确定过去了;后来在回数云的时候,也就和总监喝了一下咖啡就回来了。也就是大约5年的时间里面,我没有正规地接受过面试。
所以在准备投字节跳动之前,我投了几个公司做了一下热身活动。记住,这个时候其实不需要有啥心理包袱。因为本身候选人面试成功的可能性比较低,一个合适的可以面试的人选他们也很乐意看看,而且万一你确实想换工作,但是心仪的公司面不上,而热身活动的公司拿到了offer,你也可以考虑考虑去看下。并且这个时候你没有任何的心理包袱,因为反正你也就是来面试看看的,所以面试时候的发挥可能也会更好点,因此说不定最终拿的offer会比最后想去的那家更好呢?
经验分享
面试时被问到了一些并发相关的问题,看看大家能否答出来:
(1)synchronized的CPU原语级别是如何实现的?
(2)无锁、偏向锁、轻量级锁、重量级锁有什么差别,升级过程如何?
(3)线程间通信,同机器进程间通信,跨机器进程间通信,各有什么方法?
(4)下列三种业务,应该如何使用线程池:
高并发、任务执行时间短的业务
并发不高、任务执行时间长的业务
并发高、业务执行时间长的业务
(5)秒杀系统,如何能够撑住100W级别TPS(淘宝最高54万TPS)?
如果平时只有CRUD的经验,不了解多线程与高并发,面对这样面试题,大概率一头雾水。
其实,很多面试官都清楚,初级程序员对于多线程的掌握度几乎为零。但是面试环节中,很多面试官都会抱着试一试的态度去提问一两道多线程的题目。其目的不是为了难为面试者,也不是为了彰显面试的“高大上”,而是为了区分一般人才与优质人才。最后一点大家谨记:
在找工作的时候,除了做些相关面试和准备熟悉以前做的项目之外,还应该学习新的知识。毕竟,每多学一点,成功找到工作的机会就大一点。而且,IT这行,技术发展过于快速,如果没有学习新知识的动力,终究会被淘汰。
你要相信你自己,今天的你能做的没有做,明天的你也不会做的。
这段时期刷过的题&看的书,获取方式:转发和评论这篇文章,然后关注小编,后台私信【多线程】或者【面试】即可打包带走所有资料~
《多线程与高并发》《MySQL王者晋级之路》《亿级流量网站架构核心技术》《图解Java多线程设计模式》《Tomcat架构解析》《Java核心知识》《Java面试宝典》《可伸缩服务架构》、《Java编程思想》
常见的多线程面试题:
下面这些是我在不同时间不同地点喜欢问的Java线程问题。我没有提供答案,但只要可能我会给你线索,有些时候这些线索足够回答问题。
1.现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?
这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉。这个多线程问题比较简单,可以用join方法实现。
2.在Java中Lock接口比synchronized块的优势是什么?你需要实现一个高效的缓存,它允许多个用户读,但只允许一个用户些,以此来保持它的完整性,你会怎样去实现它?
lock接口在多线程和并发编程中最大的优势是它们为读和写分别提供了锁,它能满足你些像ConcurrentHashMap这样的高性能数据结构和有条件的阻塞。Java线程面试的问题越来越会根据面试者的回答来提问。我强烈建议在你去参加多线程的面试之前认真读一下Locks,因为当前其大量用于构建电子交易系统的客户端缓存和交易连接空间。
3.在java中wait和sleep方法的不同?
通常会在电话面试中经常被问到的Java线程面试问题。最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。
4.用Java写代码来解决生产者——消费者问题。
与上面的问题很类似,但这个问题更经典,有些时候面试都会问下面的问题。在Java中怎么解决生产者——消费者问题,当然有很多解决方法,我已经分享了一种用阻塞队列实现的方法。有些时候他们甚至会问怎么实现哲学家进餐问题。
5.你将如何使用thread dump?你将如何分析Thread dump?
在UNIX中你可以使用kill -3,然后thread dump将会打印日志,在windows中你可以使用”CTRL+Break”。非常简单和专业的线程面试问题,但是如果他问你怎样分析它,就会很棘手。
6.用Java编程一个会导致死锁的程序,你将怎么解决?
这是我最喜欢的Java线程面试问题,因为即使死锁问题在写多线程并发程序时非常普遍,但是很多候选者并不能写deadlock free code(无死锁代码?),他们很挣扎。只要告诉他们,你有N个资源和N个线程,并且你需要所有的资源来完成一个操作。为了简单这里的n可以替换为2,越大的数据会使问题看起来更复杂。通过避免Java中的死锁来得到关于死锁的更多信息。
7.你在多线程环境中遇到的共同的问题是什么?你是怎么解决它的?
多线程和并发程序中常遇到的有Memory-interface、竞争条件、死锁、活锁和饥饿。问题是没有止境的,如果你弄错了,将很难发现和调试。这是大多数基于面试的,而不是基于实际应用的Java线程问题。
8.为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?
这是一个非常经典的java多线程面试问题。这也是我刚开始写线程程序时候的困惑。现在这个问题通常在电话面试或者是在初中级Java面试的第一轮被问到。这个问题的回答应该是这样的,当你调用start()方法时你将创建新的线程,并且执行在run()方法里的代码。但是如果你直接调用run()方法,它不会创建新的线程也不会执行调用线程的代码。
9.Java中的volatile关键是什么作用?怎样使用它?在Java中它跟synchronized方法有什么不同?
自从Java 5和Java内存模型改变以后,基于volatile关键字的线程问题越来越流行。应该准备好回答关于volatile变量怎样在并发环境中确保可见性、顺序性和一致性。
10.什么是不可变对象,它对写并发应用有什么帮助?
另一个多线程经典面试问题,并不直接跟线程有关,但间接帮助很多。这个java面试问题可以变得非常棘手,如果他要求你写一个不可变对象,或者问你为什么String是不可变的。
多线程与高并发学习路线
需要高清大图的小伙伴只需要关注+转发,后台私信【多线程】或者【面试】即可获取
针对性的了解相关的知识
《多线程与高并发》这两大块儿是现在面试问的越来越多,也是相对一个初级的程序员向中高级迈进的必须要踏过的一个坎儿。这本书带你将多线程的知识系统化,帮助你理解多线程在CPU层级的实现,以及这些实现如何一层一层的映射到那些上亿用户,千万QPS,百万TPS的系统。
资料获取方式:转发和评论这篇文章,然后关注小编,后台私信【多线程】即可打包带走所有资料~
横扫一切关于多线程的问题,吊打所有敢于提问并发问题的面试官。
这本多线程与高并发把每个知识点解析的很深,对大家应该很有帮助,它把大部分的知识集结在一起深入的解析出来(非常建议大家看一看)
关注我后台私信回复【多线程】或者【面试】领取获取往期Java高级架构资料、源码、笔记、视频。Dubbo、Redis、设计模式、Netty、zookeeper、Spring cloud、分布式、高并发等架构技术
字节跳动面试经历
字节跳动一面
首先自我介绍,balabala……(此处省略三分钟)
1、找一个你的项目说一下,首先你的项目介绍,承担了什么职责,做了哪些工作,难点
因人而异,这就不再赘述了,balabal……(省略三分钟)
2、从你项目中看出,你使用的是mysql,mysql的int数据类型都有哪些?从小到大说一下,各占多少字节?
当时就记得tinyint和int,字节是1字节(tinyint:1,smallint:2,mediumint:3,int:4,bigint:8)
3、java中的int都有哪些?字节占多少
short,int,long,分别是:2,4,8
4、问你一个关于计算机网络的,tcp的三次握手说一下?
三次握手的话,客户端首先发起建立连接的请求,发送syn和seq,seq的话就是一个临时交互号,是自身的一个标识;之后第二次握手就是服务端收到请求后会发送一个syn,seq自身的标识,ack客户端seq+1;第三次就是客户端收到回应后发送syn和seq和sck。三次握手过程中分别进入的状态是:syn_send,syn_recv,established
5、tcp和udp的区别
tcp和udp他们都是传输层的协议;然后tcp是可靠传输,udp是尽最大努力交付,不可靠;tcp主要应用于端到端的比如电话这种服务,udp应用于广播,收音机等服务;tcp头部含有更多的如目标地址等信息,比udp头部开销更大。
6、你说你熟悉linux,我给你一个案例,搜索出log文本中出现次数最多的IP,并且给出次数
我直说了我不会,我linux是用来当操作系统进行日常开发使用,没有深入探索。面试官也没有追究
7、说下java的gc
现在是分代收集方式,首先进行垃圾对象的判断,判断的话有两种方法:引用计数和可达性分析,
引用计数就是没有一处引用了该对象就计数+1,当计数器为0时,代表没有地方引用它,可以回收,但是没法解决循环引用问题,现在主流虚拟机都不用这种办法。
可达性分析是选了一些对象作为GCROOTS,当从gcroots出发没有引用线时可回收。
垃圾回收的话就是有三种,标记清除,标记整理,复制算法。
8、说一下hashmap这个数据结构
他现在的实现方式是数组+链表+红黑树,通过计算hash,将对象存进hashmap中,当链表的长度大于8,链表进化为红黑树,链表小于6,红黑树退化为链表,这样能防止频繁的进行红黑树的转化,然后红黑树的话通过着色和旋转进行自平衡。
9、进行一次查找的话haspmap的时间复杂度是多少
O(1),这个是作为数组的查询复杂度。
10、给你一个算法你看一下,有一个无限长的整型数组,从小到大排序,非递增。那么怎么找到数组中一个key
初始想到的是使用二分,然后我说从n/2的地方进行二分,面试官说那也是无限啊,
我想了想说用双指针,一个以2为步长,一个以1为步长,然后当快的指针大于key时,往回遍历,
然后说完就想到不需要两个指针,一个指针即可,记录步长,一定在超出当前值的位置和当前位置-步长的范围内。面试官又问你步长怎么选?
我说可以模仿计算机网络的慢开始,第一次步长为2,第二次步长为4,第三次为8,持续为2的幂次,大于key时,再在当前位置和当前位置-步长范围内查找。
面试官问时间复杂度多少?我说不上来,尴尬,面试官提示后说是O(logn)
闲聊
之后就问了我最近看了哪本书,学到了什么,最近还在学的什么技术呢?问了我职业规划,兴趣爱好,还说了说公司的语言选型,我后来问了下对于我的面试表现评价,人家不方便说,又问了新人培养等问题。
字节跳动二面
自我介绍
balabla
1.然后说一说mysql的索引结构吧
mysql的索引结构是b+树,然后b+树我觉得相对于b树来说优点在于它非叶子节点不存储数据,本身每个节点的空间是有限的,这样的话他每个节点能存储的节点数就更多,层级就更低。
然后因为它非叶子节点不存储数据,这样每次查询时一定要到叶子节点,查询就更稳定
然后还有就是它叶子节点是单链表连接的,这样天然有序。
20看一道题吧,这个题怎么建立索引
mysql订单表有几个属性:订单id,用户user_id、下单日期date(精确到天)等,请问索引怎样建立
a. 查询某个用户的所有订单
b. 查询某一天的所有订单
c. 查询某一天某个用户的所有订单
综合考虑三个场景,建立尽量少的索引。
建立两个索引
第一个是日期索引,
因为b要求查询某一天
第二个是组合索引,用户user_id,订单id,下单日期date
因为c用到了三个,同时在建立索引时,将三个都建立上,另外由于索引结构中,int类型最佳,其次是date,所以将date放在后面。
看第二道题
10G文件,每一行一个 uint32 数字。有一台1G内存的机器
- A. 找出最大的 k 个数
- B. 找出重复数字
A:
使用堆排序,这里不是对所有的10G数据建堆,而是建立一个k大小的空堆,然后遍历数据,有大于根结点的值将堆根节点替换上,并调整大顶堆
B:
这里建立10G长度的hash表是不行的,内存不够,建立一个小的1000的hash表,遍历数据,求hash值,当发生hash冲突时,往前遍历,只需要往前遍历,查找是否存在重复值
第三道题
我手中有一堆扑克牌, 但是观众不知道它的顺序。
第一步, 我从牌顶拿出一张牌, 放到桌子上。
第二步, 我从牌顶再拿一张牌, 放在手上牌的底部。
第三步, 重复第一/二步的操作, 直到我手中所有的牌都放到了桌子上。
最后, 观众可以看到桌子上牌的顺序是:13\12\11\10\9\8\7\6\5\4\3\2\1 请问, 我刚开始拿在手里的牌的顺序是什么?
代码实现一下吧
importjava.util.ArrayDeque;
publicclassMain{
publicstaticvoidmain(String[] args){
int[] arr = {13,12,11,10,9,8,7,6,5,4,3,2,1};
ArrayDequedeque=newArrayDeque();
deque.addFirst(arr[0]);
intindex =1;
work(deque, arr, index);
while(!deque.isEmpty()) {
System.out.println(deque.pop());
}
}
privatestaticvoidwork(ArrayDequedeque,int[] arr,intindex){
if(index >12) {
return;
}
//每次往首部添加,添加一次将尾部提到前面
deque.addFirst(arr[index]);
index++;
int temp = deque.pollLast();
deque.addFirst(temp);
work(deque, arr, index);
}
}
字节跳动三面
这个面试官应该是一个总监级别的,说话非常的硬气,肯定是一个资深大佬,一共面了40多分钟。常规的面试基础都没问,纯怼项目和算法了。
1. 自我介绍
balbala
2. 你觉得你目前遇到的困难有哪些?项目上的难点?
balabala
3. 你的项目数据库多大?QPS多少?哪些sql比较慢?
项目上的事我就不说了……balaba
4. 那你觉得以后qps更大的话,你该怎么设计?
热点数据加缓存。
5.给你一个算法题,你来看一下思路
给定一个应该包含全部int32整数的文件,里边可能缺失了若干数字, 返回任意一个确认缺失的数字。
首先问我int32在内存中占了多少内存?
我没答出来,这换算不知道怎么算,我就想着32,,8个字节啥的了
实现的话我想了一下,首先想到hashmap,然后说了后他问我怎么实现,时间复杂度多少?空间复杂度多少?我想了想觉得不行,然后我就说hashmap不存放全部数据,定一个假设是100的hashmap(其实这里已经没有hashmap的意义了,换数组也是可以的)然后所有数对100求模,如果求得的模比100大,那么继续求,此时就是0,100,10000,1000000求得的模是一样的,最终就计算个数是不是正确如果不正确再去查找该不正确序列里那个数不存在。
然后他说那你用代码实现一下吧
过了好久我还没写完,他说时间差不多了我看你也写的差不多了,那就先这样,然后我就赶紧给他讲了讲我的代码,告诉他接下来我会怎么做也就是差不多出来了(现在暂时不想整理了,先这样)
那留两分钟咱们聊一聊,你有什么想问我的
balabala
四面(HR面,大约35分钟,主要是问个人职业规划、薪资待遇,以及对字节跳动的期许等等)
放在最后
总的来说,自己如果有想要去的大公司,一定要提升好自己,让自己的能力和素质与公司匹配的上,我也一直相信,机会永远是留给有准备的人。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
以上学习资料均免费放送,最后祝愿各位身体健康,顺利拿到心仪的offer!
转发!转发!转发!和评论这篇文章,然后关注小编,后台私信【多线程】或者【面试】即可打包带走所有资料~