单页源码-三月鏖战,三年后端终获阿里腾讯offer

一、基本信息

博主是双飞易易17班毕业,主要从事Java开发,没有大厂经验。 2020年,我很快就有3年的工作经验了。 如果我不寻找机会进入大工厂继续深造,竞争力和个人的提高将更加困难。 所以,经过两年的努力,公司已经开始向大厂迈进了~这篇博客主要想分享一下我在面试过程中遇到的问题。 比较坎坷,经历了3年多了。 希望大家在找工作的过程中能够坚持下去!

2. 面试结果 3. 面试过程 3.1. 阿里-天猫超市侧

1.静态代理、动态代理

简单描述一下区别,然后引出jdk动态代理和cglib(Proxy和InitationHandler)的底层实现原理。

然后介绍Spring AOP在不同情况下采用的代理实现方法

最后举一个项目中动态代理的使用场景示例(常用日志打印)

2. 将来时(强调)

Future 用于表示异步结果。 ExecutorService.submit 和 ExecutorService.execute 的区别可以得出

如果你研究过一些框架的源码,可以谈谈Future在其中的作用(超时控制)

3.线程池的实现方法——销毁线程

这里支持需要指出Executors和ThreadPoolExecutor之间的关系

通过设置不同的输入参数,可以实现不同的线程池。 SynchronousQueue比较有趣的实现原理可以深入研究

线程池回收:传送门

4.mysql联合索引

先介绍一下什么是联合索引,索引的使用场景和失效情况,如果了解索引下推的话可以讲一下

前导联合索引和主键索引有什么区别。 然后就可以深入比较Innodb和MYISAM的区别了

画龙点睛:自己写几条sql,检查一下索引的选择规则,你会发现并不是建立了索引就走,也不是推了就一定会用索引它下来。 这会涉及到mysql的一条sql执行过程

5.Redis集群

集群的主要类型:主从集群、哨兵集群和redis集群,这些服务器集群。 像Twemproxy和Codis这样的代理实现,如果你知道的话可以讲一下。

详细问题:公司目前采用哪种方案(哨兵)以及为什么(数据量小,主从+哨兵可以支持业务场景),并介绍哨兵的工作原理。

当时我问了一个问题:如果master挂了,master选举结束了,怎么通知客户端。 客户端和哨兵之间是什么关系(是否有关系)

6.mysql分库分表

第一个问题:数据库目前容量是多少,是否有分库分表的设计。

答:目前单表数据量在5000w左右,日增长率在10w以内。 暂时没有这方面的考虑(坏处大于好处)。

重新引:分库分表有哪些方式(垂直分库、垂直/水平分表),解释一下区别。 还可以讲讲分布式自增id的实现,常见的比如雪花算法单页源码,美团Leaf

七、项目内容

项目介绍,主要是挖掘你在工作中的思考以及亮点. 后面统一介绍, 因为每轮面试基本都会说一次

双方

二面流程比较快, 没有什么特点
复制代码

总共20多分钟,感觉应该没有什么大问题。

结果

怎么这么快就出结果了,凉了~

面试后几天,我和第二个面试官沟通,我就通过了,让我准备后续的笔试

可能是性能稍差,对比被杀或者没有hc

3.2 腾讯TEG端

HashMap底层实现

介绍基本结构并比较1.7和1.8的区别

建议深入阅读1.8 resize()的源码,以及红色和黑色素转换的过程

HashMap是否线程安全,如果需要使用线程安全

比较HashMap、HashTable和CurrentHashMap的区别和使用场景

给定一个要在线程安全情况下使用的 HashMap,当前的 HashMap 通过锁定和 Collections.SynchronizedMap 进行封装

介绍一下红黑树

原理:红黑树门户

应用场景:JDK1.8 HashMap,对比B+树和跳表

为什么redis速度快?

性能瓶颈(内存、网络io)可以指出,为了解决网络IO的瓶颈,redis 6.0中提出的单主线程、多工作线程的设计可以与Memecached的多线程模型进行类比。

mysql索引简介

为什么选择b+树

介绍一下b+树和b树的区别,比较一下b+树在磁盘IO上的优势(单页可以存储更多的索引),可以提到mongodb使用的是B树索引。

可以参考:为什么MongoDB索引选择B树,而Mysql选择B+树

聚集索引和非聚集索引

参考:聚集索引与非聚集索引的分析比较

当时踩了个坑,聚集索引和聚集索引其实是一回事

默认主键索引

如果没有设置主键索引,innodb会默认添加一个隐藏列作为主键索引

为什么需要这个隐藏列,可以参考innodb的数据存储结构

如何设计主键索引:MySQL主键设计

虚拟内存和物理内存

参考:虚拟内存和物理内存的理解

简而言之:

物理内存有限, 虚拟内存通过磁盘映射的形式进行分配物理内存
从而解决多个进程同时运行的情况下内存不足的问题.
复制代码

虚假分享

虚假分享原则

可以通过结合 volatile 和 ConcurrenthashMap.countercell 来回答

TCP如何保证可靠传输

拥塞控制

计算机网络这部分的内容相对来说比较考验背诵理解.
需要你用自己的语言表达出来

项目设计

后续补充

有没有用过kafka/es?

你知道redis最新版本吗(支持多线程)

笔问题

笔试题较多,包括编程题、算法题以及程序运行结果的选择题等。

双方

项目遇到最大问题(OOM)——会更长

个人分析步骤,有兴趣的可以参考一下。 分析主要是建立在理论基础上,然后逐步考察。

1、jvm oom排查 (Java heap space)
排查过程:
1、分析oom 的原因: 主要分为内存泄漏和内存溢出
内存泄漏: 对象分配了内存, 在方法调用结束之后没有进行回收,直接进入了老年代中
内存溢出: 我们的内存容量不够,导致内存分配不足
主要从这两方面进行排查
首先排查的是内存溢出:我们机器的配置是 2核4g 的机器, 堆内存分配的是3G,按照1:2的比例进行分配
这里通过
jmap -heap 可以查看到我们的堆内存使用情况.
然后根据 jstat -gc 查看我们的gc 次数, 可以粗略的查看到我们的系统gc 情况
当时通过分析 gc.log 文件看到fgc的次数相对来说还是比较少的, 因此可以暂时排除我们内存溢出导致的oom 的可能性.
其次就是排查内存泄漏了.这里使用到了 -XX:HeapDumpOnOutOfMemoryError 命令来保存 oom 时产生的堆栈信息.
通过 MAT 工具来进行分析 内存使用情况.
当时分析看到占用比较多内存的是 java.util.map 对象比较多. 通过 MAT 工具的 leak suspects 进行分析内存泄漏可能存在的原因.
当时定位到的是我们的一个学生作业报告的接口的方法. 
然后查看了一下 这个接口的调用情况,发现一天的调用量在20万次左右,平均响应时间是在400毫秒.
根据分析到的有效信息, 初步排查就是由于这个接口调用量比较多,然后导致生成比较多的一些聚合数据(主要通过map 来进行聚合), 然后由于响应时间比较长,可能会导致在ygc 的时候,根据可达性分析(gc root)判断这个对象还是存活的,然后分配到了老年代,当方法调用结束了, 就会导致这部分对象会一只存活在老年代,直到触发fgc.
如果是正常情况下, 应该会在fgc 的时候就会触发垃圾回收, 而不是发生oom. 这里是根据查看我们ygc 产生的剩余对象占用内存来进行分析的, 即如果ygc 产生了大量的存活对象,而oldgc 没有足够的内存存放这部分对象,就会导致oom.
优化过程:
1、jvm 的优化,主要有做了, 一个是增加内存,调整新生代和老年代的比例(修改成1:1),修改垃圾回收器
2、代码上面进行优化处理: 
减少聚合数据对象的创建, 这个可以通过提前生成相应的报告数据
减少接口耗时

为什么使用redis

中间件的引入就是为了解决现有的问题。 例如数据库访问压力较大、数据存储变化频繁、数据访问频率高、数据时效性低等。

可以进一步说明引入redis带来的问题以及如何解决。 比如:引入redis时如何保证数据一致性,redis不可用时如何保证服务可用。

提高数据库的吞吐量、qps

这里测试的是数据敏感性。 每次修改后,都需要对系统进行评估。 判断修改是否提高了服务性能、提高了多少、哪里存在瓶颈等。

数据库事务、innodb索引实现原理

事务隔离级别及其实现方式。

这块怎么实现需要了解mvcc

io复用

select、poll 和 epoll 的比较

我遇到过关于epoll事件通知如何实现的深入问题。

推荐:Linux IO模式及select、poll、epoll详解

性能瓶颈,如何重新优化

分析主要围绕这三点:

rpc调用流程,(为什么要看dubbo源码)

关于rpc调用流程的问题还蛮多的,可以参考dubbo的架构设计,然后按照源码一步一步去理解。

为什么阅读:提高你的编码能力和设计能力(带着疑问阅读源码单页源码,否则很容易忘记)

团队内的工作职责

三边

工作内容

重构(想法、实施)

建议阅读:《重构——改进现有代码的设计》

性能优化的作用是什么

jvm调优、sql优化/索引重建、MQ解耦

同步和异步的区别

Linux io 多路复用/aio

参考上面采访2

Linux选择通知

B+树和红黑树

HashMap红黑树

进程间通信方式

系统性能瓶颈

分析主要围绕这三点:

结果

TEG的面试也是N

3.3 腾讯PCG端

RocketMQ如何保证消息可靠性

从生产、MQ、消费三方面分析

消息队列技术选型

比较常见的RabbitMQ、RockerMQ和Kafka的技术特点,结合公司实际场景做出选择。

RocketMQ 半消息

介绍半消息,失败如何回调等。

RocketMQ消费失败

如何解决消费失败的问题,以及消费失败可能导致的n+1问题

dubbo通信流程

rpc调用流程

dubbo本地缓存地址

Dubbo底层源码

redis集群模式

redis主从同步

Spring事务传播机制

mysql 隔离级别

redis跳层数设置

上面可能有很多重复的内容,就不详细介绍了。 可以自己学一下哦~

双方

二面的过程有点像聊天,面试官跟 我前面别的部门(不是上面的TEG)的面试官认识,因此了解我的整体情况。
整个面试过程有点类似指导吧,指出我的不足,然后给我一些建议。
也有问一下比较常规的问题,也是上面有提到的一些内容。

三边

项目介绍

项目介绍主要从:
 1、业务场景
 2、性能数据
 3、问题难点
 4、性能瓶颈
这几个方面进行分析吧

1、业务场景

博主的项目是一个教育行业系统,主要描述学生在线答疑的业务场景。 大家可以根据自己的项目来整理。

2、性能数据

绩效数据对于社会招聘来说应该是一个更重要的问题。 基本上每一轮面试,面试官都会问表现怎么样。 我们需要对我们的系统有一定的了解,知道实际的数据是什么样的。 具体包括:日访问量、服务qps/tps、用户数和机器数(机器配置)等数据。

3. 困难

这里我主要关注两个地方,一是上面提到的oom问题定位处理,二是RocketMQ解耦。

上面介绍了oom,下面结合项目简单介绍一下RocketMQ的介绍。

1、为什么引入RocketMQ
通过对核心接口的压测, 发现接口 tps 相对较低,经过排查发现主流程中操作步骤相对较多。
一次写请求处理了比较多内容,导致整个请求的响应缓慢。
通过将核心的流程和辅助功能进行拆分, 通过异步的方式完成后续的工作,从而提高接口的吞吐量。
问题: 响应缓慢,吞吐量低
期望: 快速响应,提高tps
解决方式: 通过引入 RocketMQ 进行异步操作/解耦
2、为什么使用RocketMQ
技术选型: RabbitMQ,RocketMQ和Kafka 
主要从:消息堆积,响应速度,底层语言和使用场景进行分析
3、如何保证消息的可靠性
从 客户端,MQ和消费端来进行保证消息可靠。
客户端: 通过事务消息来进行保证,或者失败重试(sendResult判断)
MQ : 通过RocketMQ 集群,进行保证,主要由运维负责(可能会牵扯到MQ消息保存的问题)
消费端:1、消费幂等和2、流水表的形式 
这个问题需要结合到项目中的实际场景进行分析, 不能硬套
4、优化后的吞吐量
这个是比较核心的问题, 你优化完之后, 没有做性能的测试,凭什么说引入就好了
(引入中间件原本就会降低系统可靠性,提高复杂度)
因此需要在优化后,进行一轮的压测(注意测试场景要保持和生产或上一次测试场景一致)和消息的消费速度(避免消费过慢导致堆积)
5、优化后的性能瓶颈在哪?
主要从: cpu,内存和IO 三方面进行分析吧, 具体系统具体分析。

4. 困难

下面我们从cpu、内存、IO三个方面来分析,具体系统来分析。 不应该有没有瓶颈的系统。

小时面条

工作内容

团队身份

学习计划

职业生涯规划

个人表现

提供

经过一番努力,终于拿到了腾讯的offer。 虽然我只写了两个部门的面试内容,但我面试过至少4个部门(2个月内)。 只有这样,梦想才能成真。 配图:

3.3 阿里的蚂蚁

1.匿名类、内部类静态内部类

2.HashMap 1.7和1.8的区别

3.关于BlockingQueue的知识

4、线程池的创建形式及使用场景

5、多线程下实现计数器

6.等待并通知

7. B+树和红黑树

8. 数据库隔离级别

9、数据库如何解决幻读

10.mysql索引

11.Redis分布式锁

12.Redis哨兵集群

13.rpc调用流程

14.zookeeper服务如何发现

15.zookeeper心跳检测

总体来说面试流程和上面差不多,没有什么难度。 所以不做详细分析

双方

双面工艺也比较快,主要是因为两个问题。

项目介绍

和上面几乎是一样的

设想

用户资源权限数据库设计

三边

面试官问的三面主要是业务场景和架构相关,整体和腾讯的三面类似(其实是因为忘记问什么了,主要是和项目相关)

四边

整个过程大概10分钟左右,刚采访完今日头条有点突然。

项目难点

解决问题

团队角色

研究方法

小时面条

hr面试一共花了10分钟左右。 当时采访结束后一群人都慌了。 为什么这么快? 询问的问题主要是:

离开的原因

职业生涯规划

薪资水平

提供

最终我顺利拿到了阿里的offer,圆了自己的梦想! 今后我要和九灵一起行走江湖~~

四、总结与建议

主持人的采访过程并不顺利,他也克服了重重阻碍。 2020年并不是一个稳定的时期,每天都在发生各种变化。 只有坚持、把握、不放弃,才能实现目标。

来吧,孩子!