头条每次面试前会有 HR 约时间,并提早发一个 zoom 地址过来,三场技术面与一场 HR 面全都是视频面试。不得不说视频面试体验比电话面试好不少(尤为是对我这种很关注面试官反应的),假若有 HR 同窗看到这篇文章,推荐考虑一下用视频面试取代电话面试,效率会更高。程序员
头条的三场技术面风格都很相似:golang
- 问项目,抓出一些你擅长的领域或场景
- 问系统设计题,每题都会不断深化需求让你应变和权衡
- 问一道算法题(不难不偏),先看思路,再要求写一下伪代码看边界条件能不能一次过
这个面试流程我本身也一直在用,尤为是系统设计加上不断的需求变动,能比较全面地考察后端的基本功和工程思惟。所以头条的面试套路很对我胃口,甚至好多相似的问题我本身也都问过候选人。面试
一面
- 介绍一下本身, 为何选择出来看看机会
- 聊项目, 警报怎么作的, 统一接入监控项怎么作的
- 聊项目, 配置中心项目, 问实时配置推送怎么作
- 讨论为何选择全部的组件依赖放在配置中心中控制
- 我如今要作一个限流功能, 怎么作?
- 这个限流要作成分布式的, 怎么作?
- 令牌桶维护到 Redis 里,每一个实例起一个线程抢锁,抢到锁的负责定时放令牌
- 怎么抢锁?
- 锁怎么释放?
- 抢到锁后设置过时时间,线程自己退出时主动释放锁,假如线程卡住了,锁过时那么其它线程能够继续抢占
- 加了超时以后有没有可能在没有释放的状况下, 被人抢走锁
- 怎么解决?
- 不用 zk 的心跳, 能够怎么解决这个问题呢?
- 每次更新过时时间时,Redis 用 MULTI 作 check-and-set 检查更新时间是否被其余线程修改了,假如被修改了,说明锁已经被抢走,放弃这把锁
- 假如这个限流但愿作成可配置的, 须要有一个后台管理系统随意对某个 api 配置全局流量, 怎么作?
- 在 Redis 里存储每一个 API 的令牌桶 key,假如存在这个 key,则须要按上述逻辑进行限流
- 某一个业务中如今须要生成全局惟一的递增 ID, 并发量很是大, 怎么作
- snowflake (这个其实答得很差,snowflake 没法实现全局递增,只能实现全局惟一,单机递增,面试结束后就想到了相似 TDDL 那样一次取一个 ID 段,放在本地慢慢分配的策略)
- 算法题, M*N 横向纵向均递增的矩阵找指定数
- 只想到 O(M+N)的解法 补充: 这几天刷 leetcode 碰到这题了, 240. Search a 2D Matrix II. 办法是从左下角或右下角开始查找.
- 有什么想问个人?
限流,分布式锁,UUID 都属于后端的经典面试题,这轮面试的参考价值挺大的。算法
二面
- 平时用的工具链和技术栈是什么
- golang 踩过坑吗?
- for-range 里的 go-routine 闭包捕获问题
- 这段 golang 代码有没有 bug(仍是一个 for-range 的坑)
- 有 bug,for-range 的 value 引用拷贝问题
- Java 中 HashMap 的存储, 冲突, 扩容, 并发访问分别是怎么解决的
- Hash 表,拉链法(长度大于8变形为红黑树),扩容*2 rehash,并发访问不安全
- 拉链法中链表过长时变形为红黑树有什么优缺点?
- 优势:O(LogN) 的读取速度更快;缺点:插入时有 Overhead,O(LogN) 插入,旋转维护平衡
- HashMap 的并发不安全体如今哪?
- 拉链法解决冲突,插入链表时不安全,并发操做可能致使另外一个插入失效
- HashMap 在扩容时, 对读写操做有什么特殊处理?
- ConcurrentHashMap 是怎么作到并发安全的?
- Java 有哪些锁机制, 分别有什么特色?
- 知道 CAS 吗? Java 中 CAS 是怎么实现的?
- Compare and Swap,一种乐观锁的实现,能够称为”无锁”(lock-free),CAS 因为要保证原子性没法由 JVM 自己实现,须要调用对应 OS 的指令(这块其实我不了解细节)
- MySQL 的存储引擎用的是什么?(InnoDB)为何选 InnoDB?
- 几乎全部公司用 MySQL 都用 InnoDB,下降踩坑成本;聚簇索引,MVCC
- MySQL 的聚簇索引和非聚簇索引有什么区别?
- 聚簇索引的叶子节点是数据节点(好比定义了主键时的主键索引),非聚簇索引叶子节点是指向数据块的指针
- B+树和二叉树有什么区别和优劣?
- B+树是多叉树,深度更小,B+树能够对叶子节点进行顺序遍历,B+树可以更好地利用磁盘扇区;二叉树:实现简单
- 针对一个场景设计索引,具体场景忘记了,反正考察的是联合索引与列选择性的知识
- 现有一个新的查询场景, 要怎么解决?
- 假如要查 A in () AND B in (), 怎么建索引?
- 只给选择性高的一列建索引,这里由于两个都是范围查询因此另外一个是走不到索引的(这里答的很差,其实也能够建联合索引而后用 (A,B) in ((1,2),(3,4)) 的方式去查)
- 查 A in () AND B in () 时, MySQL 是怎么利用索引的?
- 先走一个非聚簇索引,查询出行数据后再用另外一列回表作筛选
- 假如查询 A in (), MySQL 是针对 N 个值分别查一次索引, 仍是有更好的操做?
- 不知道,有了解的同窗能够留言 (补充, @BillyLu 贴出了文档 equality-range-optimization, 大意是对非惟一索引 MySQL 会使用 index dive 的方式估算这个 range index 涉及的行数, 结合where optimization 中说明的在走 index 时假如涉及行数过多会走 full table scan, 那么假如 estimation 认为此次 IN 不够好, 是会走全表扫描的. 不知道除此以外, 面试官还有没有想考察的点)
- 用过 Redis 的哪几种数据结构? (都用过) ZSET 是怎么实现的?
- zrange start, stop, 总长度为 n, 复杂度是多少?
- O(logN) (答得很差,实际是 O(M+log(N)), M 是结果集基数 stop-start)
- Kafka 的消费者如何作消息去重?
- MySQL 去重、Redis 去重、假如场景量极大且容许误判,布隆过滤器也能够
- 介绍一下 Kafka 的 ConsumerGroup
- Kubernetes 和 Docker 用得怎么样? (我:在公司推行布道)
- 给它们贡献过代码吗?(我:没有…)
- 时序型数据库的存储结构是怎么样的?
- 讲了 prometheus 1.x 和 2.x 的存储结构
- LSM 树了解吗? 是一种什么存储结构?
- Log-Structured Merge Tree,牺牲读性能换取性能,RocksDB、HBase、Cassandra 都在用,结构有点忘了,只说了先写 memtable 再刷盘成 sstable
- 在生产中用过 Cassandra 和 RocksDB 吗? 量有多大?
- 用过,Cassandra 存调用链,RocksDB 作 flink 和 Kafka Stream 的本地状态存储
- Cassandra 的墓碑机制是什么?
二面问了好多中间件的基础知识,最后都没有时间问算法了。面完以后内心就想:头条的面试真是耿直啊,Java 的 HashMap、锁机制、CAS 到 MySQL 的索引,Redis 的 zset,再到 LSM 树,全都是后端或中间件相关的热门面试题。固然这些问题热门也是有缘由的,即便候选人准备过,多扣一点细节也能很快就能看出来候选人是真的理解仍是仅仅只是看了相关资料。数据库
三面
- 聊项目和工做经验
- 用 Kubernetes 的过程当中踩过哪些坑?
- 考虑一个业务场景: 头条的文章的评论量很是大, 好比说一篇热门文章就有几百万的评论, 设计一个后端服务, 实现评论的时序展现与分页
- 我: 需不须要支持页码直接跳转?
- 面试官: 支持和不支持两种场景都考虑一下
- 我: 不须要支持页码翻页就传评论 id 用 offset 翻页
- 假如用 id 翻页的方式, 数据库表如何设计? 索引如何设计?
- (文章id, 评论id) 建联合索引,评论 id 需递增
- 假如量很大, 你以为须要分库分表吗? 怎么分?
- 须要分,分表有个权衡,按文章 id 分表,读逻辑简单,但写有热点问题;按评论 id 分表,读逻辑复杂,但写压力就平均了。写是要首先保证的,而读老是有缓存等方案来折中,所以按评论 id 分表好。
- 分库分表后怎么查询分页?
- 每张表查 N 条数据由 client 或 proxy merge
- 分库分表后怎么保证主键仍然是递增的?
- 讲了 TDDL 的办法:有一张专门用于分配主键的表,每次用乐观锁的方式尝试去取一批主键过来分配,假如乐观锁失败就重试
- 如今须要支持深分页, 页码直接跳转, 怎么实现?
- 不能作精准深分页,不然压力太大,找产品进行妥协,在50或100页后数据分页是否能够不彻底精确,假如能够,那么缓存深页码的起始评论 id
- 瞬时写入量很大可能会打挂存储, 怎么保护?
- 断路器内部怎么实现的?
- 断路器会形成写入失败, 假如咱们不容许写入失败呢?
- 算法题: N 场演唱会, 以 [{startTime, endTime}…] 的形式给出, 计算出最多能听几场演唱会
- 先讲了思路, 按 endTime 升序排列,再顺序取最多场次
- (讲完思路以后)屏幕共享给我, 用你最熟悉的语言把这个算法实现
- 你用了贪心法, 贪心可能会存在什么问题?
- 局部最优,在这个问题里,只能找到一个可能解,没法找到全部排列方式
我以为三面这个架构设计问得还不错,一个问题把后端的工程能力考的很全面了。后端
HR 面
大同小异,问经历,问离职缘由,问职业规划,问待遇,问指望。api
小结
- 面试难度:正常
- 面试体验:挺好
- 问题偏向:架构设计,算法
头条面试流程很专业:每轮都会提早约好时间,面试时长都在40~50分钟,按时开始面,每轮以后发反馈短信邀请候选人评价面试,精准地过两天再约下一轮。整个像一台精密运做的机器。头条的面试我我的挺欣赏的,考察得比较全面,面试官会抓住你没有说清楚的地方来深刻或者变换场景让你应变,你们能够试试看去面一下,即便不打算去也能够做为一次免费的能力评定。缓存
再说说面试官,每位面试官都听得出来是在一线写代码的,并且很认真地在听我说话(这当中有视频的功劳,我能够看到面试官在认真听),感受工做中也都会是好相处好合做的类型。安全
总结
回头看面试的过程,有好多不尽如人意的地方,不过最后可以拿到三家的 offer 仍是很幸运。最后再作一些补充性的小结:数据结构
一些经验:
- 简历里写了的项目,以及熟练程度在”掌握”以上的领域与中间件要好好准备,当面试官问你一个偏门的问题时,他心里其实也没但愿你能答上来。而当面试官问你简历上涉及的问题时,假如你答不上来,那面试官就以为这我的要么是眼界过低,会了一点就以为本身掌握了,要么是简历造假在胡吹,这两种都很是不利;
- 在上一条的基础上,能够准备一个最得意的项目,在简历上和面试过程当中引导面试官往这块聊;
- 面试前内心能够准备一个方法论:明确面试官想招怎样的人有哪些特质,在面试过程当中努力表现出这些特质。这听起来是句正确的废话,但面试的过程不可控因素太多,有一个清晰的目标在脑子里能帮你在手足无措时想到说什么。举个例子,有一轮中面试官问我有什么问题时,我就问贵司的对应岗位会面临哪些技术挑战(固然要先说清楚这不是在质疑他们没有挑战,只是本身渴望挑战);
最后:
我把学习资料都整理在网盘了,获取方式:点击连接《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式: 我把学习资料都整理在网盘了,获取方式:点击连接《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。