2026-07-08 03:38:11
字节TikTok后端三面整体围绕技术深度、系统设计能力和底层原理展开,涉及实习经历、时序数据库、八股文及算法题,已通过技术面并进入HR面流程。 以下是对面试内容的详细解析:
一、实习经历相关监控系统:如服务器性能指标(CPU、内存、网络流量等)的实时采集与存储。
物联网(IoT):传感器数据(温度、湿度、压力等)的长时间序列存储与分析。
金融交易:股票价格、交易量等高频数据的实时记录与回溯。
日志分析:系统日志、用户行为日志等时间序列数据的聚合与查询。
数据采集层:通过Agent或SDK收集数据,支持高并发写入。
存储引擎层:负责数据的持久化存储,采用列式存储、压缩算法(如Gorilla、ZSTD)和索引技术(如倒排索引、时间线索引)优化存储效率和查询性能。
查询引擎层:支持SQL或专用查询语言,提供时间范围查询、聚合计算、降采样等功能。
管理服务层:包括集群管理、元数据管理、监控告警等模块。
高压缩率:相同类型的数据连续存储,便于应用压缩算法(如Delta Encoding、Run-Length Encoding),减少存储空间。
高效查询:针对聚合查询(如SUM、AVG)或范围查询,只需读取相关列,减少I/O开销。
适合时序数据:时序数据通常按时间戳和指标值存储,列式存储能更好地支持时间范围查询和指标聚合。
通过行号映射或元数据索引定位到目标行的所有列数据。
读取时需将分散的列数据拼接成完整行,可能引入额外开销,但可通过缓存或预取优化。
包括每列的最小值、最大值、平均值、分位数、直方图等,用于查询优化(如跳过无关数据块)和结果估算。
统计信息通常由存储引擎在数据写入或压缩时更新。
LSM树:将数据分为内存中的MemTable和磁盘上的SSTable,通过后台Compaction合并SSTable,减少查询时的I/O。
Compaction策略:包括层级式(LevelDB)、大小分级式(RocksDB)等,目标是最小化写入放大和查询延迟。
时序数据库中的优化:针对时序数据的时间局部性,可采用时间分区或时间线分区的Compaction策略,优先合并相邻时间范围的数据。
预编译SQL语句,将参数化查询与执行计划分离,提高查询效率和安全性。
优势包括:
减少解析开销:SQL语句只需解析一次,后续执行直接使用预编译计划。
防止SQL注入:参数通过占位符传递,避免恶意拼接SQL。
提升性能:数据库可缓存执行计划,重复执行时跳过优化阶段。
缓冲窗口:设置时间窗口(如5分钟),将乱序数据暂存于内存或磁盘,待窗口关闭后统一处理。
版本控制:为每个数据点添加版本号或时间戳,查询时按版本排序或合并。
Merge_Reader实现:
维护一个优先级队列(如最小堆),按时间戳排序数据流。
从队列中取出最早的数据点,若与前一个数据点时间重叠,则根据业务规则(如取最新值、求和、平均)合并。
处理后的数据写入输出流,并继续读取后续数据。
若统计操作(如SUM、COUNT)支持重叠区间,需明确合并规则(如加权平均、最大值覆盖)。
若统计操作不支持重叠(如UNIQUE COUNT),需先去重或按时间分区计算。
若不了解,可诚实说明,但可补充对缓存、数据结构(如String、Hash、List)或持久化机制(RDB、AOF)的基本认识。
Fork:创建子进程时复制父进程的页表,但共享物理内存,仅在写入时触发Copy-On-Write(COW),避免不必要的内存拷贝。
应用场景:如Linux的fork()系统调用、Redis的RDB持久化(通过fork子进程生成快照)。
第一次fork()后,父进程和子进程分别执行,a在父进程为子进程PID,在子进程为0。
第二次fork()时,父进程和子进程各自再fork,b的值取决于当前进程是父进程的子进程还是子进程的子进程。
输出可能为:
父进程:a=子进程PID, b=孙进程PID
第一次fork的子进程:a=0, b=孙进程PID
第二次fork的子进程(父进程的孙进程):a=0, b=0
包括保存/恢复寄存器状态、切换页表、刷新TLB、调度算法计算等,通常需微秒级时间。
开销来源:
CPU缓存失效:切换进程后,CPU缓存需重新加载新进程的数据。
TLB刷新:页表切换导致TLB命中率下降,增加内存访问延迟。
SPDK(Storage Performance Development Kit):用户态存储开发套件,通过DPDK(Data Plane Development Kit)实现零拷贝、无锁队列和轮询模式,绕过Linux内核的存储栈(如块设备层、文件系统层),显著提升I/O性能。
应用场景:高性能存储(如NVMe SSD)、分布式存储系统(如Ceph)、数据库存储引擎等。
归并排序的时间复杂度为O(n log n),与数据分布无关。
在链表实现中,合并两个有序链表的时间复杂度为O(n),共需log n层合并,因此总时间复杂度为O(n log n)。
分割链表:使用快慢指针找到中点,将链表分为两部分。
递归排序:对左右两部分递归调用归并排序。
合并链表:合并两个已排序的链表,返回新链表的头节点。
提前准备HR面常见问题(如“为什么选择字节跳动”“未来3-5年规划”)。
复盘技术面中的不足,如对某些知识点(如Redis)的掌握不够深入,可后续补充学习。
保持沟通顺畅,及时确认HR面后的后续流程(如Offer发放时间)。