部门是系统架构,这方面面经也比较少,所以给大家参考一下。
本来面的后端,面试官觉得项目和意向不合,转了流程,转成了系统工程师
因为是系统工程师,方向偏底层。所以对操作系统和linux底层的东西比较重视,奈何本人太菜。
(想做底层方向的同学可以看一看,后端的话也许不会这么问)
一面
首先自我介绍,选择计算机方向原因,项目介绍和提问。
基础环节如下:
linux相关
1)linux管理内存这块有了解过吗?
---虚拟内存和页内存管理。然后介绍了虚拟内存的背景和原理,虚拟内存到物理内存映射的一个过程。再讲到缺页中断过程。
2)页表相关,了解大页内存管理吗?页本身大一点和小一点在性能上或其他地方有什么差别?对缺页中断上面会有什么差别?
3)内存管理相关,linux有本身内部管理的内存和用户的内存管理。(属于项目延伸,先谈一谈linux怎么管理自己的内存的然后再谈一谈自己的内存管理项目是怎么进行内存管理的)
-----答: linux用的是ptmalloc2,也是基于内存池的的思想,介绍了自己的理解。然后自己的内存管理器项目,其实就是google的tcmalloc的简易版,然后进行了一个详细的介绍。然后问是否了解facebook的jemalloc?
4)场景题,字节现在想在内存分配器里面能不能做内存泄漏分析,和内存分配特征的分析?你有什么方案能够做到这两点。
------答:基础方案,回调函数,输出日志。继续提问:这种方案会特别的慢,如何提升?---只考虑考虑大内存输出日志,取一个性能均衡。
5)mov一个数到寄存器的内存里面,会遇到计算机的哪些硬件部件,可能会遇到哪些错误情况。
6)进程和线程切换效率有差别?为什么会有差别?差别主要在哪?
7)线程局部存储TLS是放在哪儿的?内核还是用户?
C++相关
1)虚表和虚指针,虚指针在派生类的情况,虚表存放在C++的内存位置?
2)智能指针相关,能不能写一下shared_ptr实例化后类的成员有哪些?
3)再介绍一些你对C++特性比较好奇,然后深挖的一些情况。
数据结构
1)快排和归并排序的复杂度一样吗?不一样是吧,那平均情况哪个更好一点?为什么?
算法
leetcode207课程表的一个变种
一面总结:
总之面试体验很好,虽然答得磕磕绊绊,但是还是感觉还是稍微体现了自己的思考,面试官也会逐渐引导,也在尽力挖掘亮点的感觉,一直在问有没有什么想补充的。
二面(透心凉)
面试官是大佬,直接被各方面质问和吊打,但事实就是这样,就是菜。
项目相关(挖的很深,不是相关的可直接忽略这部分)
1)你项目是如何进行应用的?如何在linux里面从malloc转换到你项目里的内存管理器。
----答:可以用weak做转换,weak alias进行函数入口替换。
2) 又问weak是什么,什么原理,具体说明你怎么使用的?你自己的项目,你一开始就应该想清楚要用到哪,怎么用吧。
----直接摊牌,就听说过,但是细节没有学习。
3) 你的项目主要的特点在哪,相比于linux的ptmalloc2等内存管理,优势在哪?有什么缺点?
----优势是使用线程局部缓存TLS减少了线程的同步竞争问题,缺点是占用更多的内存开销。
4) 那么从linux内存分配器切换到你自己的内存分配器,占用内存会涨,如何减小你的内存管理器的内存开销呢?有什么方法?
----想了半天,先说了几个方案都被否定。缩小内存管理器设施的一个大小,比如说减小哈希桶的桶的个数,减少最大页表缓存,减小内存管理块类型里的维护信息等。
5) 这些方法都差不多一个意思,还有呢?
----用mmap在其他进程里开辟额外共享空间之类的,好像可以缓解?
6)你这个思路完全是错的,从内存回收速度角度去想。
----就加快每一层相关回收条件的判断吧,让内存池内部的缓存块维持更少。
重点来了,面试官直接共享屏幕,打开了linux开始写代码,并提问,
代码如下(好像是C和C++混写的风格):
struct A
{
void func{printf(“%p\n”, &m}
int n;
int m
}
int main()
{
A* p=nullptr;
p->func();
printf(“mian/n”);
}
1) 这段代码输出结果是什么?是0x4?为什么?
2) 不给p赋初始值呢,又是什么结果?
3) 会发生错误吗?发生什么错误?-----结果不会发生错误,会输出随机地址?为什么?
4)不输出指针,输出具体整形值,会发生什么错误?段错误,为什么?如何调试?用GDB调试?
5)你怎么调试的?--g选项是干嘛的?你说的不对,再详细介绍一下?GDB用少是吧?
后面的没回答上来,然后修改了一下程序继续提问,如下:
struct A {
A() {printf(“%d\n”, m}
int n;
int m
}
int main()
{
return 0
}
6)这段代码输出结果是什么?为什么?
7)mian函数前加上一个全局定义A a;又是什么结果?为什么?
</di>
然后到这儿面试官知道我很菜了,直接问我主要会哪些知识------答了操作系统和计算机网络(现在觉得自己好像不怎么会)。
8)会操作系统是吧?那我问你刚才那个程序我直接编译完,./a.out之后操作系统发生了什么?
答:bash先fork一个进程,然后调用exec将程序装载执行。
9)被打断,错了,应该是shell负责不是bash,然后说这是最后面了,问我之前发生了什么?说了不会?那你说的对操作系统很熟悉呀。这块还是不清楚是吧?
10)那你到底对操作系统那一块比较熟悉?
-------说了内存管理和锁之类的。
没有继续问操作系统了(可能觉得没有问的必要了),出了一个算法题目让口述
算法
求一个字节或者说一个buffer里面到底有多少位是0,你有什么好办法。
答:首先肯定可以移位一个一个查。
问:还有更优的吗?
答:然后说了可以先数1的个数,用n&(n-1)的方式数1,然后计算得到多少个零。
然后面试官一开始可能没get到,直接说和前面一样啊,没怎么提升,我重新讲解了以后,还是觉得不太行。
问:可能比上一个方法好,但是最坏情况还是一样的复杂度,没提升。还有其他方法吗?
------想不出来了,我直接麻了
问:从空间换时间角度去想。
------我又随便掰扯了一下,说提前录入检查之类的,人已经麻了。
一些反问后直接结束,透心凉。
二面总结:
面试官是做了很久的大佬应该,全程从实际应用和一些实际编程的东西出发去考察,因为是非科班这方面还是太菜了,停留于表面。
所以大家想做系统底层方向的话,可以多动手,多做开源项目学习,遇到错误多自己去调试,慢慢积累起这方面经验。想我这种非科班转软件菜鸟,
就不是那么适合做这个方向了(当然也有很多大佬适合)。
#字节面经#
#系统工程师#