字节、腾讯实习面经分享
2 月份开始复习,然后就是投递简历,陆陆续续地参加面试,现在终于告一段落。之前从牛客网得到了很多有价值的信息,因此分享一下自己的面经。
字节跳动 后端开发
一面
- 实习过程中经常用哪些数据结构(应该是想问哈希表)
- 哈希表是如何实现的(搜“Java HashMap 实现”)
- 了解 C++吗?继承的话父类、子类哪个先初始化
- 引用和指针的区别
- 堆和栈的区别,在内存中分别是位于哪个方向?
- 堆和栈从两端向中间的话,会不会相遇?(不会,搜:虚拟地址空间分配)
- 函数的参数是怎么传的(传值、传引用)
- 大端序、小端序是什么?写一段代码,判断机器用的是大端还是小端(CSAPP 书上有)
- TCP 拥塞控制的方法
- 发送端如何控制自己的发送速率
- TCP 的 TIME_WAIT 状态是干嘛的
- git rebase 和 merge 的区别
算法题:
- 实现一个LowerBound函数,搜索第一个大于等于 target 的元素(二分查找)
- 给定一个数组,求所有元素的和。数组整体的和是不会溢出的,但是其中若干个元素的和可能溢出(正数+负数绝对不会溢出,因此将数组原地分为正数区、负数区两部分,然后左右双指针求和)
二面
- Linux 哪些命令比较熟?如何查找某个目录下文件名包含某个字符串的文件?(find)
- Golang 中 map 的实现原理?map 什么时候扩容?了解过不同的 map 实现有什么区别吗?
- Golang defer、return 的执行顺序、panic、recover 的使用
- 说说 TCP 协议
- 设 TCP 使用的最大窗口为 64KB,即 64x1024 字节,而传输信道的带宽可认为是不受限制的。若报文段的平均往返时延为 20ms,问所能得到的最大吞吐量是多少?
算法题:
- 多线程交替打印奇偶数(压根没写过多线程的代码,pass 了,后来发现可以写 goroutine)
- 输入一组数,输出各个数的比例(这个题目都没搞懂,就不贴了)
三面
算法题:
- 求子集,LeetCode 78 题
- 实现一个哈希表
- 区间完全覆盖问题,POJ 1089 题
其他:
- 实习时长,对团队、工作的期望
- 个人平时开发习惯,怎么做笔记的?习惯看英文官方文档吗?
- 介绍部门情况
总结
字节的面试题目基本很少在面经里见到,大部分都贴近底层原理、实际应用,而不是单纯地背书就可以。
算法题目有可能没见过,这个时候不要慌,主动和面试官说自己的思路,得到肯定后再作答。如果实在不会,也可以和面试官要提示。不是一定需要完全做对题目才能通过面试,我的大部分面试题都只做了七八成,面试官也很耐心地指出我的错误,问我应该如何改正。
字节的效率比较高。一二面连着,一面没问题的话,会直接进入二面。过了一天约了三面。
腾讯 应用开发
一面
- TCP、UDP 区别
- 协议栈的每一层的作用分别是什么?
- 你平时开发过程中,对哪一层的理解最深?
- HTTPS 如何保证安全性?(四次握手,证书,CA 签名)
- session 和 cookie 的区别
- HTTP 有哪些方法?每个方法是做什么的?
- GET 和 POST 的区别?传输的数据量比较呢?
- JAVA、C++ 了解吗?
- 后端开发过程中用到哪些技术?
- 如果后端有许多服务器,前端的 session 该怎么存?(中间件)
- ORM 和直接写 SQL 有什么区别
- 数据库的事务、事务的隔离级别,不同隔离级别的并发问题
- 数据库的并发控制如何实现
- 数据库的引擎,有什么区别
- 数据库的索引结构?联合索引等的底层实现是什么?
算法题(这一轮是电话面试,所以问的算法题都比较简单,要求立刻说出答案):
- dfs、bfs 的非递归写法
- 链表找环
- 二进制中 1 的个数(《剑指 offer》10 题)
- 哈希实现:数组?链表?解决冲突的方法有哪些?
二面
算法题:给定一个数组的数组,将其展开。换句话说,要求在每个数组里选择一个元素,n 个数组一共选择 n 个元素,找出所有的这种组合情况。
举例:
输入: [ [1,3,4], [1], [2,4,5], ] 输出: [ [1,1,2], [1,1,4], [1,1,5], [3,1,2], [3,1,4], [3,1,5], [4,1,2], [4,1,4], [4,1,5], ]
要求:
- 不可以使用递归
- 仅可使用 O(n) 空间,n 为数组个数
- 只需要打印每种组合即可,不需要把所有结果返回
package main import ( "fmt" ) func main() { input := [][]int{ []int{1, 2}, []int{1, 3, 4}, []int{2, 4, 5}, } Print(input) fmt.Println("-------") input = [][]int{ []int{}, []int{}, []int{2, 4, 5}, } Print(input) } func Print(list [][]int) { if len(list) == 0 { return } n := len(list) // 一共有多少个数组 listLen := make([]int, n) // 保存每个 list 长度 for i := 0; i < n; i++ { listLen[i] = len(list[i]) } stack := make([]int, n) // stack[i] 表示 list[i] 下一轮迭代的起始下标 tmp := make([]int, n) // 临时保存要打印的元素 i := 0 for { // 如果回溯完所有情况,结束 if i == -1 { return } // 已经选择了 n 个元素,打印,并返回上一个链表 if i == n { fmt.Println(tmp) i-- continue } // 如果当前链表无法再往下迭代,重置当前链表下标,返回上一个链表 if stack[i] == listLen[i] { stack[i] = 0 i-- continue } // 在当前链表中选择一个元素,进入下一个迭代 tmp[i] = list[i][stack[i]] stack[i]++ i++ } }
三面
- 说一说对数据库的了解
- 自我介绍里的内容
- 做过的项目细节、以前的工作内容
- 最有成就感的一件事
总结
腾讯的面试题目和面经重合度较高。因为是校招实习,所以更重视基础课程,不会涉及太多高深技术。比如说分布式、消息队列啥的基本不会问,因为知道你大概率没深入了解过。
腾讯的面试官人都很 nice。流程相较字节略慢,大约隔两三天进行一轮面试。
实习准备
刷算法题
由于我准备投后端岗,对算法题的考察较多,因此我从 1 月开始刷 LeetCode,平均一天 3 道,在面试前做了 230+ 道。
虽然做的题不多,但是我每道题都会争取做出最优解,然后看题解,把各种解法都试一遍,然后总结自己的笔记,对比不同解法的优缺点,联系其他题目,争取举一反三。这样做下来,虽然题量不多,但是对一些经典题的印象都比较深刻。不过题目的绝对数量还是比较少,对于没见过的题不一定能想出来。
各个公司一般要求算法能力达到 Leetcode mid 以上就可以,其他就是基础知识、相关经验了。
基础知识
最重要的是操作系统、计算机网络,其次是数据库等。
我的复习方法:先把本科的教材、笔记看一遍,框架性地复习;然后根据面试题,深入了解各个专题。个人强烈推荐《CSAPP》这本书,里面是一些本科教材中不会涉及的、但是对于理解计算机系统很重要的知识,对面试也很有帮助。
面试题可以在很多渠道找到:
- 各个网站的面经、帖子
- Github 上的面试题汇总,一搜一大把
语言原理
面试官比较喜欢问语言底层的具体原理,这个主要看日常的积累,其次可以从面试题汇总中了解哪些原理经常被问,自己去深入了解。
其他
项目经验重要吗?根据面试官和之前实习的 Leader 的说法,项目经验没那么重要。因为作为校招生,你很难有大型项目的经历,此外,面试官也不知道你写过的项目的质量如何,不知道你说的是真的还是在吹牛。但是面试官会注意你做项目的过程中用了哪些技术、哪些框架,然后深入地问你原理。
框架的使用经验重要吗?这里和上面一样,作为校招生,你很少有在大型分布式环境下编写 redis、消息队列等代码的经验。所以不要为了项目经历而去 github 上照猫画虎地做一个秒杀系统。同等情况下,基础知识扎实更为重要。
当然,项目经历/框架使用属于锦上添花的内容。如果你不仅在项目中用过工程上很流行的技术/框架,并且对这些框架的原理有深入的了解,那在面试官那里一定是一个极大的加分项。
#实习##面经##腾讯##微软##字节跳动##C++工程师#