已拿offer!2024届校招抖音电商提前批面试问题及参考答案!

C语言与CPP编程 2023-09-09 08:30

r

南京夫子庙茶颜悦色店 摄于2023.8.27

大家好,我是飞宇。

今天分享一份校招面试面经问题和答案,希望对大家有所帮助!分享人是一位2024届的学弟,投递岗位为字节跳动抖音电商部门,考察语言主要为C/C++、Golang以及其余计算机基础知识等。

最近李伟老师讲了《C++ Primer 5th》这本书的视频,他是美国微软高级工程师,清华大学博士,帮忙推广一下,感兴趣的可以看看。

互联网圈有个梗就是"两大码农工厂:南华科、北北邮",就是说这两所高校的毕业生从事互联网工作的特别多,北邮虽然是211,但在互联网圈子里比很多985学校的牌子都好使,一些互联网公司甚至有北邮帮的说法,你的组长甚至leader搞不好都是你的往届学长

以前就聊过不建议普通人随便去提前批随便面试这个话题:再次认真聊一聊,为什么我建议你不要随大流去参加提前批?,但北邮本硕的学历背景 + 2段大厂实习在手,肯定不是普通人了,这个含金量还是很够的,加上后台有人私信留言问有没有提前批上岸的经验,今天就来分享一下一位师弟的提前批上岸面经。

抖音电商面试一共是三轮技术面+一轮HR面,一共超过 40 个问题,我系统整理了一遍,并将其中一些比较不错的问题,摘录到了自己开发的网站上。

InterviewGuide大厂面试真题网站:https://top.interviewguide.cn

今天把师弟的三轮技术面经按照科目分享一下其中的编程语言和算法类的问题,计算机基础知识问题考察明天再发,因为篇幅太长了,一次发估计很多人都看不完,希望这些内容能对大家有帮助。

以下是这位师弟的面经以及部分参考答案:


大家好,应大佬邀请,我来分享一下自己的面经。

简单介绍一下自己的背景,北邮计算机本硕,目前研二在读,以前本科毕业后gab过一年,工作一年后又来读研了,目前B站+百度分别实习了三个月,我本来打算在B站一直实习下去的,但后来请教了秀哥,秀哥建议我换一家体量更大的公司继续实习,两段实习还是比一家强,后来就跑去百度实习了。

自己能在提前批拿到offer也没想到,原本以为自己是直接挂的,但没想到上岸了,最开始是不打算找提前批的,但秀哥建议我去试试,不要浪费自己的学历背景+实习经历,我就像被打了鸡血一样就去试了。

可能是踩了狗屎运,居然上岸了。

下面是我的面经,我是C++/Golang双语言技术栈,其实我最开始是学习C++的,后来在B站实习时接触到Go语言,后来就学了Go语言,变成双语言技术栈了。

C++

1、问:看你又会C++又会Golang,哪门语言了解的多一些?

:主要是C++,Go是在B站实习期间学习的,当时主要是为了做业务,很多细节都没怎么用心学,后面才慢慢补上的。

2、问:如何学习C++的?看过哪些书?

:主要是《C++ Primer 5th》、《Effective C++》、《More Effective C++》、《深度探索C++对象模型》、《ST源码剖析》以及《C++并发编程实践》,主要是这几本书。

3、问:move语义了解吗?有什么作用?

:move语义是一种高效的资源转移机制,实现移动语义,可以帮助我们避免不必要的拷贝操作,提高程序性能,显著提高效率。

阿秀补充

1、std::move的使用场景

当需要将资源从一个对象转移到另一个对象时,可以使用std::move。例如,在容器中移动元素、在算法中交换数据等。需要注意的是,只有可移动的对象才能使用移动语义,否则可能导致未定义行为。

2、避免不必要的拷贝

使用移动语义可以避免不必要的拷贝操作,从而提高性能。例如,在复制一个大型对象时,如果使用移动语义,只需要进行一次内存分配和一次指针拷贝,而不需要进行多次拷贝操作。

3、以下是C++中move语义的一些关键点:

移动构造函数:std::move可以将一个左值转换为右值引用,从而实现资源的转移。例如:

class MyClass {
public:
   MyClass(int x) : data(new int(x)) {}
   // 移动构造函数
   MyClass(MyClass&& other) noexcept : data(other.data) {
       other.data = nullptr;
   }
private:
   int* data;
};

移动赋值运算符:std::move也可以用于将一个对象的资源转移到另一个对象。例如:

MyClass a(1);
MyClass b(std::move(a)); // 使用std::move实现移动赋值

4、问:说一下程序的内存分区?

:从高地址和低地址分别向中间拓展,由上而下分别是堆、栈、自由存储区、全局/静态存储区、常量存储区和代码区。

阿秀补充

:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限

:就是那些由 new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个 delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收

自由存储区:如果说堆是操作系统维护的一块内存,那么自由存储区就是C++中通过new和delete动态分配和释放对象的抽象概念。需要注意的是,自由存储区和堆比较像,但不等价。

全局/静态存储区:全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量和静态变量又分为初始化的和未初始化的,在C++里面没有这个区分了,它们共同占用同一块内存区,在该区定义的变量若没有初始化,则会被自动初始化,例如int型变量自动初始为0。

常量存储区:这是一块比较特殊的存储区,这里面存放的是常量,不允许修改

代码区:存放函数体的二进制代码

5、问:C++11中的新特性说说?

:老八股文了balabalab

阿秀补充

C++11新特性主要有:

  • nullptr替代 NULL
  • 引入了 auto 和 decltype 这两个关键字实现了类型推导
  • 基于范围的 for 循环for(auto& i : res){}
  • 类和结构体的中初始化列表
  • Lambda 表达式(匿名函数)
  • std::forward_list(单向链表)
  • 右值引用和move语义
  • 无序容器和正则表达式
  • 成员变量默认初始化
  • 智能指针等

6、问:auto是怎么实现识别自动类型的?

:不太清楚,回答了个“只知道是根据初始化表达式自动推导出变量的类型”的

阿秀补充

auto在C++11中是一种新的类型说明符,它可以根据初始化表达式自动推导出变量的类型。

auto的工作原理是:

  • 编译器看到auto,会查看初始化表达式的类型,并将该类型作为auto变量的类型。
  • 如果初始化表达式的类型可以确定,则使用该类型。如果初始化表达式包含了多个类型,则使用与初始化表达式兼容的共同类型。
  • 如果无法确定类型,则报错。

例如:

cpp auto x = 5; // x是int类型 
auto y = 1.5; // y是double类型 
auto z = x + y; // z是double类型 

std::vector<int> 
vec; auto itr = vec.begin(); // itr是std::vector<int>::iterator类型 

在上面例子中,编译器通过查看初始化表达式的类型,推导出auto变量的实际类型。

需要注意的是,auto只在声明时确定一次变量类型,之后变量类型不再改变,并且auto变量必须初始化,才能推导出类型。

7、问:模板是怎么实现转化成不同类型的?

:不懂呜呜呜

阿秀补充

模板是一种通用的编程技术,可以用于实现泛型编程,即编写一个通用的类或函数,可以适用于多种不同的数据类型。

在C++中,模板是通过模板参数来实现的。模板参数可以是一个类型、一个整数或者一个枚举类型。在使用模板时,需要为每个要使用的类型提供一个对应的模板参数。

参考代码:

template 
class MyClass {
public:
    void setValue(T value) {
        this->value = value;
    }

    T getValue() const {
        return value;
    }

private:
    T value;
};

8、问:push_back和emplace_back的区别?

:这个我知道,emplace_back通常在性能上优于push_back,可以避免不必要的复制或移动操作。

  • push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素)
  • emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

9、问:刚才你说看过C++并发编程实战,那写个题吧,很简单的,创建三个线程,依次打印1到100.

:很常见的题,用thread就可以做,5分钟搞定!

这里阿秀补充一个无序版本的线程打印

#include 
#include 
using namespace std;

void print_nums(int start, int end) {
    for (int i = start; i <= end; i++) {
        cout << i << " ";
    }
    cout << endl;
}

int main() {
    thread t1(print_nums, 1, 25); // 创建第一个线程,打印1到25
    thread t2(print_nums, 26, 50); // 创建第二个线程,打印26到50
    thread t3(print_nums, 51, 100); // 创建第三个线程,打印51到100

    t1.join(); // 等待第一个线程执行完毕
    t2.join(); // 等待第二个线程执行完毕
    t3.join(); // 等待第三个线程执行完毕

    return 0;
}

Golang

10、问:看你在B站实习用的是Go语言是吧?怎么学的?

:我是直接看的github上的go语言极简入门,后来又看了《Go语言设计与实现》

11、问:问你一个简单的问题,你应该知道map是无序的,每次迭代map的顺序可能不同。如果需要按特定顺序遍历map,应该怎么做呢?

:可以考虑借助切片来做,将键保存在切片中,然后把切片排序,最后根据排序后的顺序遍历map访问对应的值,这样可以达到目的。

阿秀补充

package main

import (
 "fmt"
 "sort"
)

func main() {
 m := map[string]int{
  "b": 2,
  "a": 1,
  "c": 3,
 }

 keys := make([]string, 0, len(m))
 for k := range m {
  keys = append(keys, k)
 }

 sort.Strings(keys)

 for _, k := range keys {
  fmt.Println(k, m[k])
 }
}

12、问:你刚才提到了排序是吧,一般用sort函数,其中的排序函数是什么排序?

:内容os:这个我还真研究过。应该是快排、插入排序、堆排这三种,具体来说sort()源码中采用的是一种叫做IntroSort内省式排序的混合式排序算法,简单来说就是数据量达到一定规模就用快排或者堆排,没达到就用插入排序,但这个规模量我记不清了,大概是这个意思;快排和堆排的取舍则是根据最新递归深度的阈值来判断的。

阿秀补充

IntroSort内省式排序的混合式排序算法,

  • 第一步,首先进行判断排序的元素个数是否大于stl_threshold,stl_threshold是一个常量值是16,意思就是说我传入的元素规模小于我们的16的时候直接采用插入排序。

(为什么用插入排序?因为插入排序在面对“几近排序”的序列时,表现更好,而快排是通过递归实现的,会为了极小的子序列产生很多的递归调用在区间长度小的时候经常不如插入排序效率高)

  • 第二步,如果说我们的元素规模大于16,那就需要去判断如果是不是能采用快速排序,怎么判断呢?快排是使用递归来实现的,如果说我们进行判断我们的递归深度有没有到达递归深度的限制阈值2*lg(n),如果递归深度没达到阈值就使用快速排序来进行排序

  • 第三步,如果说大于我们的最深递归深度阈值的话,这个时候说明快排复杂度退化了(比如很不巧基准元素多次选取到了当前区间中最小或最大的元素。这种情况下,每次划分只能将区间缩小1个元素,造成递归深度过深),就会采用我们的堆排序,堆排序是可以保证稳定O(nlogn)的时间复杂度的。

13、问:如何移除切片中的数据?你有哪些方式?

:切片的切片操作或者append都可以。

阿秀补充

append这个简单,切片的切片其实就是使用切片的切片操作将切片分为两部分,将想要移除的元素从中间移除即可,比如我想移除第三个元素:

package main

import "fmt"

func main() {
    numbers := []int{1, 2, 3, 4, 5}
    index := 2
    numbers = append(numbers[:index], numbers[index+1:]...)
    fmt.Println(numbers) // 输出: [1 2 4 5]
}

算法

一共考察了4道题,一面2道,二面2道,三面没考,有剑指offer原题,也有力扣原题和变形题,都不算难,感觉刷力扣刷 500+ 以上都能顺利做出来。

盛最多水的容器:https://top.interviewguide.cn/issue/665

输出二叉树的左视图:https://top.interviewguide.cn/issue/697

链表判断有没有环:https://top.interviewguide.cn/issue/715

二叉树转双向链表:https://top.interviewguide.cn/issue/720

实习/项目

:介绍下你的两段实习经历?

:有什么收获?

EOF

你好,我是飞宇,本硕均于某中流985 CS就读,先后于百度搜索以及字节跳动电商等部门担任Linux C/C++后端研发工程师。

同时,我也是知乎博主@韩飞宇,日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。

我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会

加个微信,打开另一扇窗

C语言与CPP编程 C语言/C++开发,C语言/C++基础知识,C语言/C++学习路线,C语言/C++进阶,数据结构;算法;python;计算机基础等
评论
  •         近日,广电计量在聚焦离子束(FIB)领域编写的专业著作《聚焦离子束:失效分析》正式出版,填补了国内聚焦离子束领域实践性专业书籍的空白,为该领域的技术发展与知识传播提供了重要助力。         随着芯片技术不断发展,芯片的集成度越来越高,结构也日益复杂。这使得传统的失效分析方法面临巨大挑战。FIB技术的出现,为芯片失效分析带来了新的解决方案。它能够在纳米尺度上对芯片进行精确加工和分析。当芯
    广电计量 2025-02-28 09:15 141浏览
  • RGB灯光无法同步?细致的动态光效设定反而成为产品客诉来源!随着科技的进步和消费者需求变化,电脑接口设备单一功能性已无法满足市场需求,因此在产品上增加「动态光效」的形式便应运而生,藉此吸引消费者目光。这种RGB灯光效果,不仅能增强电脑周边产品的视觉吸引力,还能为用户提供个性化的体验,展现独特自我风格。如今,笔记本电脑、键盘、鼠标、鼠标垫、耳机、显示器等多种电脑接口设备多数已配备动态光效。这些设备的灯光效果会随着音乐节奏、游戏情节或使用者的设置而变化。想象一个画面,当一名游戏玩家,按下电源开关,整
    百佳泰测试实验室 2025-02-27 14:15 140浏览
  • 1,微软下载免费Visual Studio Code2,安装C/C++插件,如果无法直接点击下载, 可以选择手动install from VSIX:ms-vscode.cpptools-1.23.6@win32-x64.vsix3,安装C/C++编译器MniGW (MinGW在 Windows 环境下提供类似于 Unix/Linux 环境下的开发工具,使开发者能够轻松地在 Windows 上编写和编译 C、C++ 等程序.)4,C/C++插件扩展设置中添加Include Path 5,
    黎查 2025-02-28 14:39 149浏览
  • 美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?美国加州CEC能效跟DOE能效有什么区别?CEC/DOE是什么关系?‌美国加州CEC能效认证与美国DOE能效认证在多个方面存在显著差异‌。认证范围和适用地区‌CEC能效认证‌:仅适用于在加利福尼亚州销售的电器产品。CEC认证的范围包括制冷设备、房间空调、中央空调、便携式空调、加热器、热水器、游泳池加热器、卫浴配件、光源、应急灯具、交通信号模块、灯具、洗碗机、洗衣机、干衣机、烹饪器具、电机和压缩机、变压器、外置电源、消费类电子设备
    张工nx808593 2025-02-27 18:04 128浏览
  • 一、VSM的基本原理震动样品磁强计(Vibrating Sample Magnetometer,简称VSM)是一种灵敏且高效的磁性测量仪器。其基本工作原理是利用震动样品在探测线圈中引起的变化磁场来产生感应电压,这个感应电压与样品的磁矩成正比。因此,通过测量这个感应电压,我们就能够精确地确定样品的磁矩。在VSM中,被测量的样品通常被固定在一个震动头上,并以一定的频率和振幅震动。这种震动在探测线圈中引起了变化的磁通量,从而产生了一个交流电信号。这个信号的幅度和样品的磁矩有着直接的关系。因此,通过仔细
    锦正茂科技 2025-02-28 13:30 106浏览
  • 振动样品磁强计是一种用于测量材料磁性的精密仪器,广泛应用于科研、工业检测等领域。然而,其测量准确度会受到多种因素的影响,下面我们将逐一分析这些因素。一、温度因素温度是影响振动样品磁强计测量准确度的重要因素之一。随着温度的变化,材料的磁性也会发生变化,从而影响测量结果的准确性。因此,在进行磁性测量时,应确保恒温环境,以减少温度波动对测量结果的影响。二、样品制备样品的制备过程同样会影响振动样品磁强计的测量准确度。样品的形状、尺寸和表面处理等因素都会对测量结果产生影响。为了确保测量准确度,应严格按照规
    锦正茂科技 2025-02-28 14:05 154浏览
  • 更多生命体征指标风靡的背后都只有一个原因:更多人将健康排在人生第一顺位!“AGEs,也就是晚期糖基化终末产物,英文名Advanced Glycation End-products,是存在于我们体内的一种代谢产物” 艾迈斯欧司朗亚太区健康监测高级市场经理王亚琴说道,“相信业内的朋友都会有关注,最近该指标的热度很高,它可以用来评估人的生活方式是否健康。”据悉,AGEs是可穿戴健康监测领域的一个“萌新”指标,近来备受关注。如果站在学术角度来理解它,那么AGEs是在非酶促条件下,蛋白质、氨基酸
    艾迈斯欧司朗 2025-02-27 14:50 424浏览
  • 在2024年的科技征程中,具身智能的发展已成为全球关注的焦点。从实验室到现实应用,这一领域正以前所未有的速度推进,改写着人类与机器的互动边界。这一年,我们见证了具身智能技术的突破与变革,它不仅落地各行各业,带来新的机遇,更在深刻影响着我们的生活方式和思维方式。随着相关技术的飞速发展,具身智能不再仅仅是一个技术概念,更像是一把神奇的钥匙。身后的众多行业,无论愿意与否,都像是被卷入一场伟大变革浪潮中的船只,注定要被这股汹涌的力量重塑航向。01为什么是具身智能?为什么在中国?最近,中国具身智能行业的进
    艾迈斯欧司朗 2025-02-28 15:45 243浏览
  • 在物联网领域中,无线射频技术作为设备间通信的核心手段,已深度渗透工业自动化、智慧城市及智能家居等多元场景。然而,随着物联网设备接入规模的不断扩大,如何降低运维成本,提升通信数据的传输速度和响应时间,实现更广泛、更稳定的覆盖已成为当前亟待解决的系统性难题。SoC无线收发模块-RFM25A12在此背景下,华普微创新推出了一款高性能、远距离与高性价比的Sub-GHz无线SoC收发模块RFM25A12,旨在提升射频性能以满足行业中日益增长与复杂的设备互联需求。值得一提的是,RFM25A12还支持Wi-S
    华普微HOPERF 2025-02-28 09:06 166浏览
  •           近日受某专业机构邀请,参加了官方举办的《广东省科技创新条例》宣讲会。在与会之前,作为一名技术工作者一直认为技术的法例都是保密和侵权方面的,而潜意识中感觉法律有束缚创新工作的进行可能。通过一个上午学习新法,对广东省的科技创新有了新的认识。广东是改革的前沿阵地,是科技创新的沃土,企业是创新的主要个体。《广东省科技创新条例》是广东省为促进科技创新、推动高质量发展而制定的地方性法规,主要内容包括: 总则:明确立法目
    广州铁金刚 2025-02-28 10:14 111浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦