字节跳动 C++ 一面
自我介绍
根据自身具体情况回答
项目介绍
看个人项目了
进程和线程的区别
- 进程是资源分配的基本单位,线程是CPU调度的基本单位
- 进程拥有独立地址空间,线程共享进程的地址空间
- 进程切换开销大,线程切换开销小
- 进程间通信复杂(需IPC),线程间可直接读写共享数据
进程通信方式
- 管道:匿名管道(父子进程)、命名管道
- 消息队列:内核中的消息链表
- 共享内存:最快方式,需配合信号量同步
- 信号量:计数器,用于同步互斥
- 信号:通知事件发生
- Socket:跨网络通信
线程是否有共享内存
- 有共享内存:同一进程的线程共享堆、全局变量、代码段
- 私有部分:每个线程有自己的栈、寄存器、线程局部存储(TLS)
用户态和内核态区别
- 用户态权限低,不能直接访问硬件和内核数据
- 内核态权限高,可执行所有指令
- 切换场景:系统调用、异常、中断
栈和堆的生命周期区别?栈何时销毁?
- 栈:函数调用时分配,返回时自动销毁(由编译器管理)
- 堆:程序员手动申请和释放(new/delete),生命周期由代码控制
- 栈销毁时机:函数执行完毕(遇到}或return)时销毁
MySQL 事务了解吗?
- ACID:原子性、一致性、隔离性、持久性
- 隔离级别(从低到高):读未提交:可能脏读读已提交:可能不可重复读可重复读(MySQL默认):可能幻读(InnoDB通过MVCC解决)串行化:性能最低,无并发问题
git 常用命令,回滚知道吗?
常用命令:
git clonegit addgit commitgit pushgit pullgit branchgit merge
回滚命令:
# reset:回退版本(修改历史) git reset --soft HEAD^ # 回退commit,保留修改 git reset --hard HEAD^ # 回退commit,丢弃修改 # revert:撤销某次提交(生成新提交,不修改历史) git revert <commit-id>
算法题一:子结构判断
来源:力扣 LCR 143. 子结构判断
题目描述:输入两棵二叉树A和B,判断B是不是A的子结构(约定空树不是任何树的子结构)
解题代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSubStructure(TreeNode* A, TreeNode* B) {
if (!A || !B) return false;
// 先判断当前节点是否包含B,再递归判断左右子树
return dfs(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
}
bool dfs(TreeNode* A, TreeNode* B) {
if (!B) return true; // B匹配完了,说明包含
if (!A) return false; // A没了B还在,说明不包含
if (A->val != B->val) return false;
return dfs(A->left, B->left) && dfs(A->right, B->right);
}
};
算法题二:生成小于n的最大数
题目描述:给出一个整数n,要求从给定数组中选取数字(可重复取用),拼成一个小于n的最大数
解题思路:
- 将数组排序(降序)
- 回溯构建数字,长度与n相同或少一位
- 某位放小于对应位的数字后,后面全填最大值
- 若找不到等长解,返回长度-1的最大数
解题代码:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int getMaxLessThanN(vector<int>& nums, int n) {
string s = to_string(n);
int len = s.length();
// 降序排序,优先用大数
sort(nums.begin(), nums.end(), greater<int>());
// 尝试构建等长的数
string res = dfs(s, nums, 0, true);
if (!res.empty()) {
return stoi(res);
}
// 没有等长解,返回长度-1的最大数
string maxLenMinusOne(len - 1, '0' + nums[0]);
return stoi(maxLenMinusOne);
}
private:
string dfs(string& target, vector<int>& nums, int pos, bool isLimit) {
if (pos == target.length()) return "";
for (int num : nums) {
if (isLimit && num > target[pos] - '0') continue;
bool nextLimit = isLimit && (num == target[pos] - '0');
string suffix = dfs(target, nums, pos + 1, nextLimit);
// 如果后面能拼成功,或者这是最后一位
if (suffix != "no" || pos == target.length() - 1) {
return char('0' + num) + suffix;
}
}
return "no";
}
};
C++面试总结 文章被收录于专栏
本专栏系统梳理C++面试高频考点,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力。
查看14道真题和解析