1、基本情况

博主17届双非一本毕业, 主要是搞Java开发的, 没有大厂经验. 2021 自己也3年多工作经验了. 如果再不找找机会进大厂深造一下, 后面的竞争力和个人的提升将会更难.因此在现在公司磨砺了两年之后, 开始向大厂迈进~ 这篇博客主要是想分享一下自己在面试过程中所遇到的问题,相对比较坎坷,前后经历了3个多月.希望大家也能在找工作的过程中,坚持下来!

2、面试结果

  • 阿里-蚂蚁支付宝 P6 offer
  • 腾讯-pcg 2-3 offer
  • 字节 2面 后放弃

3、面试过程

3.1、阿里-天猫超市

一面

1、静态代理,动态代理

简单描述区别, 然后可以引出 jdk动态代理和cglib 的底层实现原理(Proxy 和 InvocationHandler).

再引入 Spring AOP 在不同情况下采用的代理实现方式

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

2、future (重点)

Future用来代表异步的结果.可以引出 ExecutorService.submit 和 ExecutorService.execute 的区别

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

3、线程池实现方式-销毁线程

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

通过设置不同的入参,实现不同的线程池. 比较有意思的 SynchronousQueue 实现原理可以深入学习一下

4、mysql 联合索引

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

引出 联合索引 和 主键索引 有什么区别. 然后可以深入对比一下 Innodb 和 MYISAM 的区别

<stron> : 自己去写几条sql 查看索引的选择规则, 你会发现并不是建立了索引就会走, 也并不是有索引下推就一定会去采用, 这就可以涉及到 mysql 一条sql 的执行过程</stron>

5、redis 集群

主要的几种集群: 主从,哨兵和redis Cluster 这几种服务端集群. 类似 Twemproxy 和 Codis这种代理实现,如果了解可以说一下.

细问: 当前公司采用哪种方案(哨兵),为什么(数据量较少,主从+哨兵能支撑业务场景),介绍哨兵的工作原理.

当时问了一个问题: 如果主挂了之后,选主结束后,怎么去通知客户端. 客户端和哨兵是什么样的关系(有无关联)

6、mysql 分库分表

先问: 目前数据库的容量大概是多少,有没有做分库分表设计.

答曰: 目前单表数据量在5000w左右, 日增长在10w以内, 暂时没有这方面的考虑(劣大于优).

再引出: 分库分表有哪些方式(垂直分库, 垂直/水平分表),讲解一下区别. 可以再说一下 分布式自增id 的实现方案,常见的比如 雪花算法, 美团-Leaf

7、项目内容

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

二面

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

  • 介绍项目和当前公司的盈利模式
  • 项目遇到最大的困难
  • 项目的方案设计等

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

结果

为啥那么快到结果呢, 就是凉了~

面试完没几天, 跟二面面试官沟通, 是通过了, 还让我准备一下后续的笔试

可能是表现稍差,对比***掉 或者 没hc 了

3.2 腾讯TEG

一面

HashMap 底层实现

介绍基本结构,对比 1.7和1.8的区别

建议深入阅读 1.8 resize()的源码, 还有红黑素转换的过程

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

对比 HashMap,HashTable 和 CurrentHashMap的区别和使用场景

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

介绍一下红黑树

原理: 红黑树传送门

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

redis 速度快是因为什么原因

  • 内存
  • 单线程
  • 数据结构
  • io多路服复用

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

mysql 索引介绍

  • 聚集索引和非聚索引的区别(InnoDb 和 MyISAM 对比)
  • 索引选择(优化器怎么选择索引)
  • 索引失效
  • 索引下推

为什么选择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 情况

为什么要使用 redis

引入中间件都是为了解决目前存在的问题. 比如 数据库访问压力比较大, 数据存储变化频繁,数据访问频率高和数据时效性低等.

可以进一步说明,引入redis 带来的问题 和如何解决的. 比如: 引入了 redis 如何确保数据一致, redis 不可用如何保证服务可用.

改善后的吞吐量,数据库的qps

这里考验的是数据敏感性, 每次改动之后要求对系统进行测评. 判断这次修改是否对服务性能进行了提升,提升了多少, 哪里还有瓶颈等

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

事务隔离级别 和 如何实现的.

如何实现这一块需要去了解一下 mvcc

io多路复用

select、poll 和epoll 对比

有遇到深入问 epoll 事件通知是如何实现的.

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

性能瓶颈,如何再优化

主要围绕这三个点进行分析:

  • cpu
  • 内存
  • io

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

rpc 调用过程这个问的挺多的, 可以参考 dubbo 的架构设计, 然后一步步跟着源码走一遍就理解了.

为什么看: 提高自己的编码能力和设计能力 (要带着问题去看源码, 不然很容易忘记)

小组内的工作职责

三面

工作内容

  • 版本开发
  • 问题处理
  • 需求分配
  • 技术评审

重构(思路,实现)

建议阅读: 《重构-改善既有代码的设计》

性能优化做了什么

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

同步和异步的区别

Linux io多路复用/aio

参考上述 面试二

linux select 通知

B+树和红黑树

HashMap 红黑树

进程间通信的方式

  • 管道
  • 匿名管道
  • 信号
  • 信号量
  • 消息队列
  • 共享内存
  • 套接字

系统性能瓶颈

主要围绕这三个点进行分析:

  • cpu
  • 内存
  • io

结果

TEG 这边的面试, 也是N 了

3.3 腾讯PCG

一面

rocketmq 如何保证消息可靠

从生产, MQ 和消费三端进行分析

消息队列技术选型

对比常见的 RabbitMQ,RockerMQ 和 Kafka 技术特点, 结合公司的实际场景抉择。

rocketmq half message

介绍 half message ,失败如何回调等

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 三方面进行分析吧, 具体系统具体分析。应该没有啥系统是没有瓶颈的。

hr面

工作内容

团队身份

学习规划

职业规划

个人绩效

offer

千辛万苦,终获腾讯offer,上面虽然只写了两个部门的面试内容,但是我至少面了4个部门了(2个月内),所以,没什么岁月安好,只有负重前行,才能实现梦想。配个图:

3.3 阿里蚂蚁

一面

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

2、HashMap 1.7和1.8区别

3、BlockingQueue 相关知识

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

5、多线程下实现一个计数器

6、wait 和notify

7、B+树和红黑树

8、数据库的隔离级别

9、数据库如何解决幻读

10、mysql 索引

11、redis 分布式锁

12、redis 哨兵集群

13、rpc 调用过程

14、zookeeper 是怎么服务发现的

15、zookeeper 心跳检测

总体来说,跟上面的面试过程也是大体上面相似,也没有什么难点的。因此也不做详细分析了~

二面

二面进行的也是比较快,主要是两个问题吧

项目介绍

也是跟上面的差不多内容

场景题

用户的资源权限数据库设计

三面

三面面试官问题主要是跟业务场景和架构方面的, 整体跟腾讯的三面差不多(实际上是因为忘记了问了啥, 主要也是跟项目相关的)

四面

整个流程下来大概10分钟左右,当时刚面完头条,有点突然。

项目难点

问题处理

团队角色

学习方法

hr面

hr面一共面了10分钟左右,当时面完也是慌的一批,咋那么快呢。 问的问题主要就是:

离职原因

职业规划

薪资水平

offer

最后也是成功拿到了ali 的offer ,完成自己的理想了吧! 以后便以 九灵 行走江湖了~~

4、总结与建议

楼主在面试过程中也不是一帆风顺,也是披荆斩棘走过来的,2021 不是一个安稳的时间, 每天在发生在各种各样的变化。只有坚持,把握,不放弃 方能达到自己的目标。

以下是我个人的一些做法,希望可以给各位提供一些帮助:

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

实战系列:Spring全家桶+Redis等

  • 其他相关的电子书:源码+调优
  • (三)刷题如何刷题?这是很多现在面试者心中的困惑,我们都知道,面试前刷题是很有必要的,毕竟很多题目都有一定的共性,刷足够题目就能够做到举一反三,甚至在面试时,被问到原题,能够侃侃而谈,那么刷题如何进行呢?建议:最好找一些历年的面试原题,分专题来对自己进行训练。以下是我私藏的面试题库: