面试复盘 |字节跳动七面面经(提前批3轮,实习4轮)

LZ实习期间面了字节两个部门(游戏研发岗、C++客户端开发岗),每个部门2轮技术+1轮HR,第一个部门挂在HR面了,第二个部门因为方向不对口选择去另一家实习而鸽掉了。提前批面了Data后端开发岗,3轮技术+1轮HR,已还愿。现将七轮技术面面经分享出来,供备战秋招的小伙伴们参考。

收到牛客运营同学的盛情邀请,LZ决定对面试中的一些要点进行复盘,复盘部分写在文末,希望能帮到大家

提前批

一面 70min 7月27日

语言:

  • C++虚函数原理

  • 虚函数的开销

  • 子类对象的基类子对象内存布局在前还是后

  • 实习过程中用过cgo吗

  • Golang中channel的底层实现及工作原理

  • channel是如何做到协程安全的

  • channel底层为什么采用环形队列而不采用普通队列

  • channel如何阻塞和唤醒Goroutine的

操作系统:

  • epoll水平触发和边缘触发模式区别

  • 水平触发相较于边缘触发多了哪几个系统调用

  • 如何实现一个系统调用

  • epoll底层实现

  • 红黑树怎么使用的,为何epoll_wait复杂度为O(1)

  • 线程安全函数、可重入函数、信号安全函数的区别

  • 浏览器中点击+号创建新的标签页,是开启了一个新线程还是新进程,以及原因

网络:

  • TCP和UDP哪个协议有包长限制

  • IP数据分片有什么弊端

  • TCP连接两端一个突然断连,另一端如何感知

  • 什么情况下会出现半开连接,如何解决

数据库:

  • a、b字段建立联合索引,a、b、a and b、 a or b四种情况哪种会走索引

项目:

  • 难点在哪里,为什么CKV+性能优于redis

  • 服务器性能有哪些优化思路

  • 无锁编程应该怎么实现

  • CAS操作和内存屏障底层实现原理

设计题

  • 如何设计一个哈希表【可从表长、哈希碰撞、扩容时机来分析】

  • 插入、更新、删除哈希表中一个元素,底层怎么操作【相当于insert、erase、get方法的实现】

  • Redis是如何实现rehash的

算法

  • 求整数的立方根,返回结果向下取整。

  • 给定一个矩阵,和一个坐标(x,y),顺时针打印元素。【lc885,只不过面试时出界就不用再往下走了】

二面 60min 7月27日

语言+操作系统

  • C++虚函数的性能开销【两面都问了,估计是想问CPU流水线分支预测失败时的额外开销】

  • 内存池解决了什么问题

  • IO多路复用原理

  • epoll水平触发和边缘触发模式区别

网络:

  • URL输入到渲染的过程

设计题【全程围绕此设计题展开,没看过STL内存分配器和malloc实现原理就难顶了】

  • 如何实现一个内存池?

  • 为什么空闲内存要采用不同内存块大小的链表维护?

  • 内存块大小为什么都是2的幂次方?

  • 动态内存分配算法

  • 首次适应分配算法和最佳适应分配算法的实现逻辑是什么?

  • 红黑树只能保证logn复杂度,有更低复杂度方案?

  • 内存池在多线程情况下怎么保证线程安全性

  • 多个线程频繁申请分配并释放4字节块时,如何避免锁开销

  • 100M大小的数组,顺序下标访问和随机下标访问的性能区别

算法:

  • 实现memcpy函数【写了快半个小时,面试官指引下要考虑内存区间重叠情况】

三面 60min 8月2日

语言

  • C++多态

  • 基类的析构函数为什么通常定义为虚函数

  • 指针和引用的区别

  • 讲讲inline函数

  • inline函数和宏有什么区别

  • C++中volatile含义

操作系统

  • 线程安全如何保证

  • CAS操作是如何保证原子性的

  • 硬件层面有哪些原子指令

  • C++中有哪些锁?读写锁、自旋锁什么场景使用

  • 线程切换时的上下文切换具体指什么,包含哪些东西

  • 线程有哪些私有数据

  • 虚拟内存和物理内存

  • 各个进程地址空间是如何保证独立不影响的

网络

  • TCP和UDP的区别

  • TCP流量控制

  • TCP拥塞控制

  • HTTPS握手过程

  • DNS采用TCP还是UDP

算法:

  • 普通二叉树中找到第k小元素【讲思路(遍历保存节点+TopK)】

  • TopK【讲思路(堆或快速选择)】,快速选择找TopK的时间复杂度为什么是O(n)

  • 二叉搜索树找第K小元素【讲思路(中序遍历到第k小元素停止)】,时间复杂度多少(O(h+k),h为树高),空间复杂度多少(O(h))

  • K个一组翻转链表【手撕(ACM模式,写测试用例)】

Hr面 8月2日

  • 三面完半小时,收到Hr消息进行Hr面

意向书 8月3日

  • 早上收到邮件

面试感受

  • 感受:三面下来,感觉面试官首要考察的还是候选者的基础扎实度,就算问项目,也最终会引申到基础知识方面提问,所以大家一定要注重基础知识的总结;其次就是算法了,运气好的话能碰见LC或牛客题霸做过的原题,运气不好碰到新题就只能硬编码了,这个就靠大家自己平日的积累和临场发挥了。

实习

一面 50min 5月12日(游戏业务)

  • 自我介绍

  • 项目:

    • 介绍
    • 讲讲时间轮定时器,如何执行的,一个槽精度多少?
    • 如果处理器阻塞了5秒,会不会影响定时器的执行效果?
    • 非磁盘IO下,多线程和单线程的QPS差这么大,原因在哪里?
    • 讲讲项目中的线程池
    • 线程间的同步能不能不用锁?
    • 无锁队列怎么实现的?
  • C++:

    • C和C++在内存分配方面有何区别

    • 讲讲C++的多态

    • 子类对父类的非虚函数重写,通过基类指针调用的函数版本是哪版?为什么?

    • dynamic_cast讲一讲,如果指针类型是基类,转换为子类后,指针地址改变吗

    • 使用dynamic_cast进行指针类型转换的类中需定义什么?

    • vector相较于数组的优劣有哪些?

    • C++类内数据成员的初始化有哪些方式

    • 成员初始化顺序与类内声明顺序有关还是和构造函数初始化列表中的初始化顺序有关?

    • C的结构体和C++的类有哪些区别

  • 网络:

    • URL输入后的执行过程
    • TCP粘包问题,原因,如何解决?
    • HTTP协议底层基于什么协议?能不能用其他协议?
  • 数据库:

    • 讲讲关系型数据库和非关系型数据库的区别
  • 算法:

    • 二叉树的最近公共祖先
    • 建树、自己写下输入输出
    • 非递归怎么做
    • 用数组存储树节点,尝试写一下
  • 其他:

    • 如何降低游戏服务器的低延迟?
    • 大概能实习多久
    • 介绍部门业务
  • 反问环节

二面 35min 5月14日(游戏业务)

  • 自我介绍
  • 比赛:
    • 介绍
    • 服务器为何购买1.5倍?
    • 还有哪些参数是手动设置的?
    • 其他问题
  • 项目:
    • 项目来源,为什么做此项目?
    • 定时器除了时间轮以外还有其他数据结构可以实现吗
    • 讲讲堆的原理
    • 线程同步除了加锁以外,能不能不用锁?
    • 无锁队列怎么实现?
  • C++:
    • 智能指针是否用过?
    • 多线程环境下使用智能指针需要注意哪些问题?
    • 智能指针在哪些字段需要加锁?引用计数需要加锁吗?
    • 你觉得动态语言和静态语言间差别在哪里,动态语言的GC机制是怎么实现的?
  • 操作系统:
    • malloc底层实现原理
    • 分配内存时什么时候会调用brk?空闲链表的分配和维护是在用户态完成还是内核态完成?
    • 讲讲程序中的bss段
    • 讲讲程序加载运行的全过程
  • 算法:
    • TopK(快排和堆两种思路,讲堆思路)
  • 其他:
    • 为什么选择投递字节游戏部门
    • 最近在学习的技术
    • 你是非科班,计算机专业知识是如何学习的?
    • 你觉得看过的技术书籍中帮助最大的一本书是哪个?(CSAPP)
    • 能来实习多久
  • 反问环节

一面 50min 5月21日(C++客户端)

  • 自我介绍
  • 项目
    • 如果项目要实现HTTPS功能的话,有没有思路?
    • 其他问题忘掉了。
  • C++:
    • STL中容器插入元素时push_back和emplace_back的区别
    • emplace_back的参数是什么(本人回答是构造函数的参数,面试官进一步追问三个点代表什么,后来才明白问的是可变参数列表)
    • 可变参数列表的实现原理
    • 讲讲C++11智能指针有哪些,使用场景?
    • 智能指针的实现原理
  • 算法:
    • C++代码题,报输出结果(lambda表达式和std::function相关) 略难【问了10多分钟】
    • 判断链表是否有环
    • 分隔金条的最小花费(在面试官提示下做出来了,本质考数据结构—堆)【耗时10多分钟】

二面 50min 5月21日(C++客户端)

  • 自我介绍
  • 项目(略过,问题和前几面大同小异)
  • C++:(C++11特性问的很广泛很深入)
    • 类内数据成员在构造函数初始化列表中赋值和在构造函数体内赋值的区别
    • 构造函数可以是虚函数吗,为什么
    • 析构函数可以是虚函数吗,为什么
    • 什么时候需要自定义拷贝构造函数
    • 类内重载运算符怎么写,写个类重载赋值运算符(撕题第一道)
    • 函数重载时返回值能否用于区分重载函数,为什么
    • 讲讲虚函数运行机制
    • 讲讲虚函数如何解析
    • extern “C” 的作用
    • 讲讲C++11或14特性
    • 左值和右值的区别
    • const左值引用可以绑定到字面值上吗?
    • 引用折叠了解吗?什么情况下会推导为右值引用?
    • 讲讲完美转发,std::forward的作用是什么?
    • 编译器的返回值优化RVO机制了解吗?
  • 操作系统:
    • 线程同步方式
    • 进程通讯方式
    • 信号量工作原理
    • 共享内存工作原理
    • 管道工作原理
    • 套接字工作原理
  • 撕题
    • C++写一个类,类内有一个int成员和int*成员,让重载operator=操作符
    • 线程安全的单例模式
    • 最长回文子串
  • 其他:
    • 能实习多久
    • C++是自学的吗

复盘

  • 1) 不要死扣问题:一千个人一千个哈姆雷特,对于同一个问题很多时候没有固定答案,因个人理解程度以及答题切入角度而异,因此大家看面经要学会从宏观角度去获取要点,不要死扣面经里的问题,而要通过面经去审视自己某一模块准备的是否全面充分,该模块都会有哪些提问形式,并形成自己的总结。
  • 2) 形成个人总结:在备战秋招过程中最好要有自己的笔记或思维导图,并不断总结完善,因为一旦进入招聘黄金季,这将是你的杀手锏。一方面复习起来高效;另一方面随着知识体系的不断完善,会增加个人面试信心。对于招聘黄金季一周数十场的高频次面试,个人总结绝对百利无一害,千万不要贪图速成而东拼西凑的去背零散知识,会很吃亏,到后期你会发现不会的还是很多。
  • 3) 学会引导面试:建议大家根据自己的知识体系,有针对性的准备几个拿手问题,面试过程中引导面试官去追问这些,而不是只背诵八股,就很容易建立个人优势。
  • 4) 针对性备战: 每个人心仪的公司不同,就可以针对公司类型去备战,而不是眉毛胡子一把抓。想去一二线互联网大厂的同学,那肯定基础和算法得过关,算法方面多下点功夫;想去离家近的普通公司,那就没必要死磕算法难题和偏难怪的知识点,有舍有得。

讨论

以后端知识体系常见问题为例,给出一些我个人觉得有价值且有区分度的面试问题,大家可以在评论区交流讨论下~
线程同步问题: 锁、条件变量、互斥量等(本质都是利用操作系统提供的同步原语进行有锁编程)【有心的朋友可以准备下无锁编程,绝对加分】
虚拟内存问题:概念、地址翻译、缺页异常、缓存淘汰、乃至红黑树等。【好好琢磨怎么串讲起来,也很加分,就这一个问题能让面试官觉得你操作系统过关了】
Redis相关问题:底层数据结构、高可用、可扩展方案不要局限于书本上的知识,redis大版本已经到6.0了,了解下它的多线程模式以及线程同步方式,也是个加分项。

这篇帖子应该不会再更了,希望大家看完后有所收获,而不是浏览了一篇什么也没记住的面经。

#面试复盘##面经##校招##字节跳动##C++工程师#
全部评论
大佬,计算机网络和操作系统怎么学的,上面的问题我大多打不出啊。感觉太深了
2 回复 分享
发布于 2021-08-03 23:09
老哥强呀! 扎实
1 回复 分享
发布于 2021-08-03 18:33
牛蛙
1 回复 分享
发布于 2021-08-03 18:54
3面算法题倒是不少😀
1 回复 分享
发布于 2021-08-04 17:07
大佬是320宿舍的吗
点赞 回复 分享
发布于 2021-08-03 18:33
牛啊,不愧是你
点赞 回复 分享
发布于 2021-08-03 18:37
狠的一批
点赞 回复 分享
发布于 2021-08-03 18:39
大佬具体是啥岗位 什么部门啊 base哪里啊
点赞 回复 分享
发布于 2021-08-03 19:09
大佬太强了
点赞 回复 分享
发布于 2021-08-03 23:29
佬哥,这个怎么答啊:水平触发相较于边缘触发多了哪几个系统调用
点赞 回复 分享
发布于 2021-08-04 01:03
问这么多么
点赞 回复 分享
发布于 2021-08-04 09:18
大佬,无锁队列能分享下思路吗,网上查到的资料都有点过于复杂了
点赞 回复 分享
发布于 2021-08-04 09:47
大佬,你的项目是做的高性能Webserver么?
点赞 回复 分享
发布于 2021-08-04 10:55
点赞 回复 分享
发布于 2021-08-04 11:21
太真实了,我也实习面了四次
点赞 回复 分享
发布于 2021-08-04 13:41
不错
点赞 回复 分享
发布于 2021-08-04 15:32
大佬,这个怎么回答啊?子类对象的基类子对象内存布局在前还是后
点赞 回复 分享
发布于 2021-08-04 23:51
水平触发相较于边缘触发多了哪几个系统调用?这个答案是啥啊?
点赞 回复 分享
发布于 2021-08-05 11:52
加油楼主,冲鸭,奥利给,祝楼主好运
点赞 回复 分享
发布于 2021-08-31 19:31
大佬牛啊
点赞 回复 分享
发布于 2021-09-27 15:20

相关推荐

​是的,我今天就想批判一下那些披着「设计(系统/语言)」外衣的研发工程师。设计系统(Design system)这个概念应该是从国外最先有的。它的定义是:国内的组件库只有 Antd 在推出的时候声称自己是 一个 UI 设计语言,虽然当时我还不知道什么叫做设计语言,什么是设计系统。但是从工程师的角度我知道它就是 一套组件库。一直到近两年,越来越多的前端团队以设计系统为排面推出自己的组件库的时候,我就觉得有些不对劲儿了。哪里不对劲儿了?我在想我们实际上做的事情不就是设计了一套组件库吗,为什么要把设计放在前面。这似乎传达给我们一种信号:我想并不是这样的,或者说不应该是这样的。设计 永远是最上层的,它们关注的用户的外在、外观感受,它是感性的、多变的,没有唯一标准的。你很难想象用一套设计系统满足所有人的需求对吧?因为我喜欢蓝色,你喜欢红色这是不需要解释的。工程 永远是最底层的,它关注事物内在的东西、自身属性,它是理性的、不变的,有迹可循的。所以工程层面追求的是一致、复用和效率。没人喜欢一个相同的组件在不同的实现上有不一样的 API。在「前端工程师」这个职位名字中,「前端」是个形容词,「工程师」才是名词。我们得先是工程师再是前端对吧。当我们不由自主地和设计靠拢时,思维模式也受到了影响,似乎只有设计思维才会关注到那些形容词。当我们在设计一套组件库的时候会遇到很多不一致的情况,在我的经验里面:当我们设计的组件库需要考虑到跨端情况的时候,我们的组件库应该有一套一致的 API、一致的命名规则。但是从设计角度去决策的时候这件事情变得非常困难。比如说:日期选择 这个组件,移动端通常叫做 DatePicker,这个词强调的是用户的动作(pick),在 PC 端通常叫做 Calendar,这个词强调的是组件本身的特征。还有:按钮 组件的类型属性,有的是表形的:default/info/warning/error,有的是表义的:primary/secondary/danger再一次,我们在工程实现层面不需要这种差别。它就是一个简单的按钮而已。造组件库的人没有想清楚这件事情,用组件库的人却得承受这种不一致。那什么组件库的设计者们没想清楚这件事情?因为他们的思维也被设计系统带偏了。一味的追求设计上的形式化的一致,却忽略了工程上逻辑的一致。当这股邪风吹来,没人会在意组件库的工程化设计,没人在意它好不好用,每个人都想复制粘贴快速实现一套组件库,然后再披上设计系统的外衣,为自己的似锦前程添砖加瓦...​
点赞 评论 收藏
分享
52 278 评论
分享
牛客网
牛客企业服务