目录

谭同学的面经(2025-8)

百度C++(搜索架构部/2025-08-11)

讲一下你工作中独立负责的项目或者比较大的开发工作

怎么会想到使用图技术?怎么做的技术选型

并发?怎么解决并发问题?

在项目中有没有遇到过性能优化问题?C++ 有内存泄露,内存雪花

对C++ ,介绍一下内存呢管理

算法

K和升序集合,求交集

// 测试用例数组 vector<vector> arrays1 = { {1, 3, 5, 7, 9}, {2, 3, 5, 8, 9}, {3, 5, 6, 9, 10} };

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <vector>
#include <climits>  // 用于 INT_MAX

using namespace std;

// 函数声明(也可直接把函数定义写在 main 之前,这里演示标准写法)
vector<int> intersect(const vector<vector<int>>& arrays);

int main() {
    // 测试用例数组
    vector<vector<int>> arrays1 = {
        {1, 3, 5, 7, 9},
        {2, 3, 5, 8, 9},
        {3, 5, 6, 9, 10}
    };

    // 调用求交集函数
    vector<int> result = intersect(arrays1);

    // 输出结果
    cout << "交集结果: ";
    for (int num : result) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

// 函数定义:K 个升序数组求交集
vector<int> intersect(const vector<vector<int>>& arrays) {
    vector<int> res;
    if (arrays.empty()) {
        return res;
    }

    // 记录每个子数组当前遍历的指针位置  子数组的指针
    // 创建一个与 arrays 大小相同的 vector 容器,所有元素都初始化为 0
    vector<int> pointers(arrays.size(), 0);
    while (true) {
        int min_val = INT_MAX;
        bool all_same = true;

        // 1. 找到当前所有指针位置的最小值,同时检查是否越界
        for (size_t i = 0; i < arrays.size(); ++i) {
            if (pointers[i] >= arrays[i].size()) {
                // 某个数组已遍历完,直接返回结果
                return res;
            }
            if (arrays[i][pointers[i]] < min_val) {
                min_val = arrays[i][pointers[i]];
            }
        }

        // 2. 检查所有指针位置的值是否都等于最小值
        for (size_t i = 0; i < arrays.size(); ++i) {
            if (arrays[i][pointers[i]] != min_val) {
                all_same = false;
                break;
            }
        }

        // 3. 处理逻辑:相等则加入结果,所有指针后移;否则只移动对应指针
        if (all_same) {
            res.push_back(min_val);
            for (size_t i = 0; i < arrays.size(); ++i) {
                pointers[i]++;
            }
        } else {
            for (size_t i = 0; i < arrays.size(); ++i) {
                if (arrays[i][pointers[i]] == min_val) {
                    pointers[i]++;
                }
            }
        }
    }
}

手动实现一下memcpy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstddef>  // 用于 size_t 类型
#include <iostream>
using namespace std;

// 手动实现 memcpy,模拟标准库行为
// dest: 目标内存起始地址
// src:  源内存起始地址
// count: 要拷贝的字节数
void* my_memcpy(void* dest, const void* src, size_t count) {
    // 1. 空指针保护(可选,标准库 memcpy 不检查,传递空指针会崩溃)
    if (dest == nullptr || src == nullptr) {
        return nullptr;
    }

    // 2. 转换为 unsigned char* 操作单个字节
    // unsigned char 能正确表示所有可能的字节值,不会有符号扩展问题
    unsigned char* dest_ptr = static_cast<unsigned char*>(dest);
    const unsigned char* src_ptr = static_cast<const unsigned char*>(src);

    // 3. 逐字节拷贝
    for (size_t i = 0; i < count; ++i) {
        dest_ptr[i] = src_ptr[i];
    }

    // 4. 返回目标地址(符合标准库 memcpy 返回值)
    return dest;
}

// 测试用例
int main() {
    // 源数据
    char src[] = "Hello, Manual memcpy!";
    // 目标缓冲区
    char dest[100] = {0}; 

    // 调用自定义 memcpy
    my_memcpy(dest, src, sizeof(src));  

    // 输出结果
    cout << "源数据: " << src << endl;
    cout << "目标数据: " << dest << endl;

    return 0;
}

百度C++二面(搜索架构部/2025-08-13)

讲一下简历里面的项目是怎么设计的?【主要聊简历项目: 设计、数据层、服务层、应用层】

讲一下内存泄漏问题, C++为例

写一个生产者,消费者模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumerDemo {
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity = 5;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    public static void main(String[] args) {
        ProducerConsumerDemo pc = new ProducerConsumerDemo();
        new Thread(pc::produce, "Producer").start();
        new Thread(pc::consume, "Consumer").start();
    }

    public void produce() {
        int value = 0;
        while (true) {
            lock.lock();
            try {
                while (queue.size() == capacity) {
                    notFull.await();
                }
                System.out.println("Produced: " + value);
                queue.add(value++);
                notEmpty.signal();
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }

    public void consume() {
        while (true) {
            lock.lock();
            try {
                while (queue.isEmpty()) {
                    notEmpty.await();
                }
                int value = queue.poll();
                System.out.println("Consumed: " + value);
                notFull.signal();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}