字节跳动 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的最大数

解题思路:

  1. 将数组排序(降序)
  2. 回溯构建数字,长度与n相同或少一位
  3. 某位放小于对应位的数字后,后面全填最大值
  4. 若找不到等长解,返回长度-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";
    }
};

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务