首页 > 字节跳动 飞书PC 社招 C++
头像
穷人的代表
编辑于 2021-07-09 08:30
+ 关注

字节跳动 飞书PC 社招 C++ 内部员工回复

字节的面试简直了,问得我满头大汉 ,我亲耳听到汗滴到桌上的声音,拿得了华为OD的offer  过不了字节一面  我感觉华为OD 多少有点水吧 外包就是外包 正编就是正编😂
字节的发问形式就很不一样,问题和答案都不是一个萝卜一个坑的那种,而是开放的,设计的,系统的问题,下面的问题部分简单的给了答案,其他很长的答案 自行思考吧
1.介绍项目 20min
1.1 你用的协议是属于哪一层的  someip 是会话层的
1.2 你自认为语言 操作系统 网络 算法 调试 哪个方向是强项?
1.3 tcp和udp 介绍一下 差别是什么?
2. 一个基本的日志系统包含哪些模块?
3. 一个好的日志系统有哪些评价指标?
4. 如何设计一个大流量,高速输出的的日志系统?
5. 如何实现日志分流? 如何实现多日志器同时安全得写一个文件?用mutex做线程同步的代价?
6. 如何实现日志滚动?像行车记录仪一样 定期删除
7. 既然提到线程同步,线程还有哪些同步的方式?进程呢?
------------------------------项目聊完了开始轰炸----------------------
7. 说一下多态?
对于这种很宽泛的发问形式,一定要展现自己知识面的体系,以及在陈述问题的逻辑性,比如:
1.一定要先谈谈多态的分类,不然面对这么大的话题很容易讲成一锅粥,下面的分类都可以稍作展开讲讲
  • 重载多态(Ad-hoc Polymorphism,编译期):函数重载、运算符重载
  • 子类型多态(Subtype Polymorphism,运行期):虚函数
  • 参数多态性(Parametric Polymorphism,编译期):类模板、函数模板
  • 强制多态(Coercion Polymorphism,编译期/运行期):基本类型转换、自定义类型转换
2. 多态的重点其实在子类型多态
那么都知道是派生类调用虚函数的时候会体现多态,但是具体的对象调用具体的虚函数显然不是多态,多态有两个先决条件 (1)虚函数 ;(2) 一个基类的指针或引用指向派生类的对象;
3. 谈谈多态的用途等等
1 多态实现了一种所谓的晚绑定,在设计时可以先设计稳定不变的部分,设计中的不确定因素延迟到运行时确定。
2 设计模式里面几乎都是多态 比如策略模式 method模式等等
8. 静态多态中的函数重载问题:
8.1 函数包含哪些部分?
返回值,函数名称,形参列表
8.2 什么部分参与了函数重载的判定?
形参列表,包括个数,顺序,类型
切记返回值不能参与重载判定,函数只有调用后,编译器才会去验证返回类型,所以返回值不能作为函数重载的依据
8.3 函数圆括号后面的const算不算函数签名?参不参与重载?
8.4 函数圆括号后面的const有什么含义?
成员函数后面的const 保证不修改成员变量的值
9. 动态多态之虚函数
9.1 class A { int a, virtual void funa(); void funb();};  的内存分布?
参考现代C++对象模型
C++ 一个对象大概长这个样子 非静态数据成员会分配到具体的内存 如果有虚函数成员的话 会多一个虚表指针 指向虚表 虚表是跟类绑定的 其他的方法不占空间

假设有这样的一个对象
class A{
public:
    virtual void func1(){
        std::cout<<"func1"<<std::endl;
    }
    void func2(){
        std::cout<<"func2"<<std::endl;
    }
private:
    int a;
};

int main(){
    A a;
    A b;
    std::cout<<sizeof(A)<<std:endl;
    std::cout<<&a<<" "<<&b<<std::endl;
}
程序输出
16
0x7ffe9af23e00 0x7ffe9af23e10
推荐阅读  g++ 下的对象模型:https://www.cnblogs.com/eskylin/p/6491256.html
9.2 class B : public A{}; 有哪些东西被继承下来了?
继承是全盘继承,所有的数据成员,函数都继承了 ,只是对于不同的继承类型 ,会涉及到函数的调用权的差别
待补充(虚表的问题)
9.3 B b;  b.funa(); 的调用过程说一下?
查表 调用派生类的虚函数
9.4 虚表和虚表指针说一下? 虚表保存了哪些内容
9.5 虚表指针是保存在哪里的?
编译器为每一个类维护一个虚函数表,每个对象的首地址保存着该虚函数表的指针,同一个类的不同对象实际上指向同一张虚函数表
10. 模板的概念说一下?
模板的出现将C++带上了一个全新的境界 ---元编程
在这个层面上编程可以忽略类型之间的差异,从而专注算法的本身实现
可以说没有模(mú)板技术就没有STL这么强大的组件
10.1 模板的全特化? 举例说明
10.2 模板的偏特化? 举例说明
//比如有这样的一个模板函数
template<typename T1,typename T2 >
void fun(T1 t1,T2 t2) {
    //do_something
}
//全特化
void fun(int a,double b) {

}
//偏特化(类型范围上的偏)第一模板参数接受指针类型
template<typename T1, typename T2 >
void fun(T1* tp1,T2 t2 ) {

}
//偏特化(类型个数上的偏)固定部分模板参数
template<typename T1, typename T2 >
void fun(T1 a, double b) {

}
10.3 类型萃取说一下?如何消除const的特性?
这个话题挺吊的 具体可以参考侯捷大佬的讲解
11. 挑一个你用的最熟的容器
----vector
11.1 vector是用什么做的
----原始数组
11.2 vector的扩容原理?
---- 两倍扩容   (虽然可以是1.5 倍 3倍 ,4倍,但是各家编译器都做成了两倍 ,以我用的vs来说,确实是两倍)
//举例来说 当通过push_back向vector中添加一个元素时 假设此时capacity是50 size也是50 我要放第51元素进去
_CONSTEXPR20_CONTAINER void push_back(const _Ty& _Val) { // insert element at end, provide strong guarantee
    //调用 emplace_back
    emplace_back(_Val);  
 }
|
---> //继续调用
template <class... _Valty>
    _CONSTEXPR20_CONTAINER decltype(auto) emplace_back(_Valty&&... _Val) {
        // insert by perfectly forwarding into element at end, provide strong guarantee
        auto& _My_data   = _Mypair._Myval2;
        pointer& _Mylast = _My_data._Mylast;
        //没到当前的最大容量 插入成功
        if (_Mylast != _My_data._Myend) {
            return _Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...);
        }
        // 到达极限容量 重新分配
        _Ty& _Result = *_Emplace_reallocate(_Mylast, _STD forward<_Valty>(_Val)...);
    ...
}
//*****************在这里会发生很重要的扩容*****************************
//**********************************************************************

template <class... _Valty>
_CONSTEXPR20_CONTAINER pointer _Emplace_reallocate(const pointer _Whereptr, _Valty&&... _Val) 
{
    //新的size等于老的size+1 插入一个元素  size==51
    const size_type _Newsize     = _Oldsize + 1;
    // 新的容量等于以原来的大小生长一倍 从而完成所谓的两倍扩容  capacity==100
    const size_type _Newcapacity = _Calculate_growth(_Newsize);
}



11.3 设计一个新的vector? 要求扩容的时候不会产生大规模的拷贝构造?
---- 答 用链表去串,追完:如何保留随机访问的性质?  我母鸡啊  这个到底要怎么做???
真的不知道 想了好几天了 哈哈
11.4 从vector中间删除一个对象会发生什么?
元素的析构以及元素的拷贝构造
11.5 迭代器失效的问题? 迭代器是用什么做的? 如何避免迭代器失效?

迭代器失效分三种情况考虑,也是分三种数据结构考虑,分别为数组型,链表型,树型数据结构。

数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除掉之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后在iter++,是没有意义的。解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter);

链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器.解决办法两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效;删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。

----------
12. Linux有哪些调试手段?
13. 描述你用gdb调试的一般过程?
14. 如何定位内存泄漏的问题?有哪些工具?

算法:13亿的电话号码 如何快速确认一个号码存不存在  返回true or false
综合考虑存储和效率
字典树存储 +多叉树寻路
//伪码
int main(){
    string s;
    while(cin>>s){
        for(char c:s){
            //存入字典树
        }
    }
    
    //查询
    //一个多叉树寻路的问题
    
}
后来发现这是面试中的老演员了
解决办法还有位图  布隆过滤器

反问 聊天
我是不是你面试过的人当中比较菜的?
面试官笑了笑
我还要往哪个方向去发力?
:从你身上看到了我当年的影子 ,我也是非科班转码的,建议你多看看 网络编程 数据库编程 算法 你的知识面太窄
总共聊了一个小时五十分钟


不用多说 肯定是凉的透透的  字节的面试高标准高要求  我是很欣赏的,也很佩服能通过字节面试的同学
不过这次面试下来发现自己的不足还是很明显的,和大厂还有很大的差距,
嗐 再接再励吧 还年轻

全部评论

(6) 回帖
加载中...
话题 回帖

推荐话题

相关热帖

历年真题 真题热练榜 24小时
技术(软件)/信息技术类
查看全部

热门推荐