面经 - 字节 广告基架实习 一面挂 240223
时间线
流程概况
240221 牛客简历初筛
…挺快,几个小时后就收到了面试邀约。
240223 一面口头过
主要聊了 C++,写了两道题。最后出了点问题,但在最后改对了(还是太紧张了),但还是给我过了。差强人意吧。
240304 感谢信
一面口头过了,但估计还因为大二以及实习只有两个月,以及面试表现不算特别突出,最后正式挂了。
一面
面试过程
首先是相互介绍,面试官先介绍了它们部门的业务,然后我介绍了一下我的技能项。
问题 | 解答情况 |
---|---|
(面试官自我介绍,我的自我介绍) | |
什么时候开始打 ACM?高中有没有代码基础? | balabala,如实回答。 |
LRU-K 是啥?我知道 LRU ,你给我大概讲讲 LRU-K 。(面试官读简历中…) |
balabala,面试官应该是真不知道。 |
Copy-on-Write 又是什么东西?(面试官读简历中…) |
balabala,面试官应该是真不知道。 |
(后面开始问 C++) | |
总结下 static 这个关键字。 |
函数中的 static ,类中的 static ,总之可以扩大生命周期。 |
追问: static 成员函数是否可以访问普通成员变量? |
答不能,然后扯一大堆。面试官应该期望可以通过某种方式能。 |
总结下 const 这个关键字。 |
常量,const 成员函数,constexpr 。这边有一部分答上来但是觉得不够完美。 |
追问: const 成员函数的本质是什么? |
在面试官一些提示下才答上来,见梳理。 |
追问: 再想想 const 还有其他方面吗? |
我提了 const & 的参数可以接受右值,应该是还有,见梳理。 |
RTTI 是什么东西? |
balabala,面试官居然不懂 RTTI 。 |
STL 里是怎么进行底层内存分配的? |
allocator ,然后讲它是干嘛的? |
追问: 是否了解它的算法? | 不了解 allocator 的实现,但清楚 STL 的实现。 |
追问: 讲一下 vector 的底层实现。 |
balabala,这个太轻松了。 |
追问: vector 什么时候会迭代器失效。 |
先犹豫了,说不知道 push_back 会不会失效。然后回忆之前遇到过迭代器失效,说 push_back 扩容时会导致迭代器失效,然后说 insert 会导致向后的迭代器失效。 |
智能指针的实现原理是什么? | 主要是 shared_ptr 和 unique_ptr ,然后我讲了一下 shared_ptr 源码是怎么做的。 |
追问: 循环引用怎么解决? | 那就是 weak_ptr ,然后讲了 shared_ptr 的引用计数由 shared 计数和 weak 计数组成。 |
追问: shared_ptr 有几种构造方式? |
shared_ptr 传入指针构造,make_shared 会将参数传入内部构造。 |
追问: 这两者有什么性能或者安全方面的区别。 | 只回答了性能方面的区别。效率方面,make_shared 可能传入内部构造,可能带来性能上的提升,但我不清楚具体有什么样的提升。(性能方面不算回答的好,安全方面复盘才听到面试官提了安全) |
(最后我们做两道题目) | |
带有过期标记的 LRU | 讲解过程遇到了问题,面试官直到先从数据结构开始讲。 |
bitmap(手搓 bitset) | 在计算值遇到了问题,出锅严重,被狠批。。。好在前面回答的都不错。 |
面试官主要和我聊了 C++,其中还是以 C Class STL
为多(除了 allocator
,shared_ptr
)。聊起 C++ 感觉面试官还不如我懂(比如 RTTI),但是它问的也有我答不上来的。
梳理没答上的问题
static 成员函数是否可以访问普通成员变量?
不能直接访问。
为什么不能? 这个问题我回答的很好,扯了一大堆。唯一的缺点是没法简短概括。
为什么能? 通过传入一个 this
指针就可以了。然后可以扯一下这其实就是类函数调用的原理,面试官应该就是想要这句话。
关于这个问题虽然我没有打上第二点,但是在讲到 const
的时候,在面试官追问下还是答上了调用原理。
const 这个成员的应用?
一个让面试官有疑惑的回答 当时我说了 const 变量是能用 const 就用 const,没解释清楚(其实就是想说给用户最小的权限),面试官 “啊?” 了一下,但是后面没追问,当时这个地方回答应该算让面试官疑惑,不如不说后半点。
const 成员函数的本质是在修饰什么? 这里直接上问答吧:
面试官:const 成员函数的本质是在修饰什么?
我:(一脸疑惑)应该是在修饰变量的每个成员吧。
面试官:那我换个问法,const 成员函数和普通成员函数是不是重载关系?
我:是的。(然后嘶… 了一会儿)我不知道是不是你想要的回答,const 成员函数本质是传入了一个 const 的 this 指针。
面试官:是的,这是我要的答案。
(感觉还可以扯一下,const * 和 * 是重载关系,* const 和 * 不是重载关系)
const 的应用还有其他什么方面?
- 我提到
const &
的参数,可以接受右值引用、字面值,然后还有一些方面在面试官追问下完成。 - 追问:
const
作为函数的返回值?答:const
的返回值没有意义,但是const &
的返回值可以减少拷贝或者移动。(这个问题我想了一段时间,还可以补充const &
的返回值需要注意这个值不能是函数内的变量) - 追问:
const
常量与#define
一个常量比有什么好处?答得不好,但面试官没说什么。应该的回答:类型安全、具有作用域、避免其他奇怪错误,然后可以回答#define
是在预处理期完成的。
智能指针相关内容
weak_ptr 为什么需要 weak 计数 这是一个我假想的问题,当时回答 weak_ptr
的时候其实心虚面试官万一追问这个问题怎么办,不过最后没有追问。weak
计数其实不是需要被使用,而是代码实现上不这么做就会出现问题。在没有 weak_ptr
时,shared_ptr
在引用计数为零时会卸载对象和计数器;而在有 weak_ptr
时,shared
计数为零时只能卸载对象,而计数器需要在 weak
计数为零时卸载计数器,如果不这么做,那么 shared_ptr
直接卸载计数器,weak_ptr
的计数器指针就会出现指针悬挂。
shared_ptr 和 make_shared 的性能差异到底体现在哪里? make_shared
一次申请计数器和对象的总内存,然后进行构造。而 shared_ptr
则是分别申请计数器和对象的内存的。但 make_shared
也有不好的地方,weak_ptr
可以使计数器存活,而对象被释放;但在 make_shared
中,计数器和对象必须同时卸载。
make_shared 比 shared_ptr 更加安全。 在使用 shared_ptr
作为参数传入时,它的构造顺序允许被编译器打乱,如果使用临时构造的对象传入 shared_ptr
就会存在安全问题。另外 make_shared
一次分配内存也会比多次分配更加安全。
面试总结
这场面试主要考察了 C++
,但是出乎意料的是,这位面试官更加注重相关基础方面的,比如 static
/ const
的内容居多。
其中,关于 const
作返回值和 const
与 #define
的区别回答的不到位,中间花在思考上的时间比较多,就是还做不到应对自如。然后是 shared_ptr
方面没有答出 make_shared
的具体优势,只回答了潜在优势。
面试官最后总结到,你的 C++ 还有需要巩固的地方,因为我们的岗位是 C++ 的,所以后期还要多准备。其实当时还觉得我对 C++ 的内容都算回答出来了,但是需要面试官一些提示,但是现在复盘了一下感觉比当时感觉的不足还是要多一些的。
最后笔试题出锅的事暂时就放一边了。面试官提到我 “小动作太多”,还说我面试的时候头甩来甩去,这个需要改正。当时想确实有问题,不过事后想想写题过程中,还有一个细思极恐小故事:
在我 LRU 快写完的时候,面试官发消息(不是口头)说去上个厕所,我到感觉压力小了点,写题反而更加轻松了。不过心里还是有点这样的想法:这个面试官怎么这样…
现在想想面试官大概率是有意不是无心。
最后面试官回复我这里算是给你过了。
感谢信
估计大二以及实习时间短占主要原因。
另外,对基本 C++ 问题的掌握有待提高,在面试中训练吧。