阿里 / 百度 / 快手 / 网易 / 小红书实习面经合集
个人在七月份的一些实习面经~
P.S. 都是实习!实习!实习面试!重要的事情说三遍!!!
阿里夸克(搜索引擎 - C++)
C++:
- 左值引用和右值引用
std::move()
LeetCode:
- 多数元素(No. 169)
百度(音频引擎 - C++)
C++:
- const 指针
constexptr
与 const 指针的区别(编译时进行常量的求值和运算)- new 和 malloc 的区别(类型安全、构造和析构、分配失败处理、大小计算)
- 内存对齐(变量、函数、虚函数、静态变量、嵌套结构体)
- vector 数组和普通数组的区别(要点:为何能追加元素)
- vector 如何判断应该扩容(size 和 capacity)
- vector
clear()
是清空所有元素还是清空内存 - 如何真正的清空 vector 内存(提示:与空 vector 做 swap 操作)
- map 和 unordered_map 的底层实现、区别、查找的时间复杂度、应用场景
- map 插入一个元素的时间复杂度(
O(logn)
) - 类中 static 函数能否声明为虚函数(不能)
- 构造函数能否声明为虚函数(不能)
- 还有哪些函数不能声明为虚函数(内联函数、友元函数、非成员函数)
- 如何保证类的对象只能被开辟在堆上(提示:将构造函数声明为私有、单例)
- C++ 源文件编译流程(预编译
.i
、编译.o
、汇编.s
、链接.exe
)
Linux:
- 查看指定进程占用的端口号(netstat & grep)
- 打印某一列并按空格分隔(
awk -F
)
MySQL:
- MVCC 实现原理
- 幻读是什么
- 如何解决幻读问题(间隙锁)
OS:
- 如何使用 gdb 排查多线程中哪个函数出现了死锁(
info thread
&thread 2
&bt
) - 一个线程会发生死锁吗(比如:多次尝试同一个锁、递归获取锁)
- select / poll / epoll 的区别
- epoll 底层实现
- ET 和 LT 的区别
LeetCode:
- 前 K 个高频元素(No. 347)
Expand:
- 静态绑定和动态绑定
- 虚函数表在哪个阶段被分配的(编译)
- 虚函数表存在哪个区(常量区)
- delete 和 free 的区别(类型检查)
push_back
和emplace_back
的区别- 浅拷贝和深拷贝的区别(举例说明)
快手(AI 软件开发 - Java - 一面)
Kafka:
- 与其他消息队列相比、为什么 Kafka 性能更好(批量处理和异步、每秒千万级)
- 多副本备份(Replica)
- 主节点挂了怎么办(选举新的主节点)
- 新的主节点是如何选举的(Zookeeper 一致性协议选举)
- Kafka 基本架构(Broker、Topic、Partition、Group)
Redis:
- ZSet 底层实现(跳表)
- 介绍一下跳表及其插入、查找、删除的时间复杂度(均为
O(logn)
) - 过期淘汰策略(惰性删除 + 定期删除)
- 持久化策略(AOF 和 RDB)
- 主从节点如何同步数据(RDB 全量 + AOF 增量)
- 一个新加入的从节点如何追上主节点(增加从节点性能、减少主节点写负载)
Network:
- 介绍一下三次握手和四次挥手
- 为什么不能是三次挥手(需要传输和处理数据)
- 第一次握手可以传输数据吗(不可以)
gRPC:
- 与 HTTP 相比 gRPC 的优点
- HTTP 和 gRPC 哪个传输效率更高
MySQL:
- 什么是聚簇索引
- 聚簇索引和普通索引有什么区别
- B+ 树和 B 树有什么区别
- 什么是覆盖索引
- 什么是回表
- 解释一下不可重复读、脏读、幻读以及在什么情况下会出现
- 如何解决幻读(间隙锁)
Personal:
- Redis 分布式锁是如何实现的
- Callback 回调函数是同步还是异步的
LeetCode:
- 二叉树最大宽度(No. 662)
- 环形链表(No. 141)
小红书(机器学习平台开发 - C++)
C++:
- 介绍一下虚函数(多态)
- 如何用 C 语言实现 C++ 虚函数(定义虚函数表、初始化虚函数表指针)
- static 关键字
- 能否在普通函数内部声明 static 变量、作用是什么(可以、全局变量)
- 什么是内联函数(将函数代码直接插入到调用点、例如
add(x, y)
直接变为x + y
) - 内联函数为何能提升执行效率、举例说明(普通函数需要传递参数、创建和销毁栈帧)
- 一次函数调用在编译过程是什么样的(关键:将函数返回地址压入堆栈或寄存器中)
Shell:
- grep & awk
LeetCode:
- 滑动窗口最大值(No. 239)
快手(AI 软件开发 - Java - 二面)
Golang:
- 如何理解 Go 线程和协程(协程是轻量级线程)
- 为什么 goroutine 性能更好(轻量级、并发调度、channel)
- 什么业务需求要开 goroutine
- 普通的加减乘除(函数)计算需要单独开一个 goroutine 吗
n
个协程和一个协程做计数哪个效率更高
OS & Network:
- 如何判断服务器性能是否符合预期、或达到性能瓶颈
- 客户端(多线程)和服务器(多线程)通信需要建立几个 TCP 连接(一个)
- 服务器如何区分来自客户端不同进程的 TCP 报文(源 IP 和端口号)
网易(全栈开发)
Docker:
- 介绍一下底层 cgroup 和 namespace
- 经常使用哪些命令
MySQL:
- 说一下表锁和行锁
- 写一个能够触发行锁的 SQL 语句
- 什么情况下能触发记录锁、是否需要为索引
Golang:
- goroutine 异常退出能释放 Redis 分布式锁吗(不能)
Expand:
- join 和 detach 线程的区别(join 阻塞等待、detach 后台运行)