Momenta C++ ⼀⾯凉经

进程内存飙升时你会用什么命令排查?

先找高内存进程,再看内存构成,最后判断是否泄漏或缓存失控。

常用命令:

  • ps aux --sort=-%mem | head
  • top -p <pid> / htop
  • pmap -x <pid>
  • cat /proc/<pid>/status(看 VmRSS、VmSize)
  • 测试环境可用:valgrind --leak-check=full ./app

你怎么查看 CPU 状态?

从系统、核、进程三层判断是否 CPU 瓶颈或 IO wait 偏高。

常用命令:

  • uptime / top
  • mpstat -P ALL 1
  • pidstat -u 1
  • vmstat 1

云服务器内存不足你会怎么处理?

思路:先止血,再定位,再治理。

  • 止血:扩容、临时开 swap、限流降级
  • 定位:内存泄漏、缓存策略不当、流量突增
  • 治理:优化数据结构与回收策略,完善监控告警

你项目里用过哪些 C++ 版本特性?

按“场景 + 收益”回答更好:

  • auto、范围 for、nullptr、enum class
  • unique_ptr/shared_ptr 做资源管理
  • thread/mutex/condition_variable 做并发控制
  • 移动语义 + emplace_back 做性能优化
  • chrono 做耗时统计

你平时怎么用 gdb?

典型流程:

  1. gdb ./app 或 gdb ./app core
  2. b <file:line|func>
  3. run
  4. n/s 单步
  5. p、info locals 看变量
  6. bt 看调用栈
  7. thread apply all bt 看全部线程栈

gdb 怎么查看调用栈?

  • bt:当前线程调用栈
  • thread apply all bt:所有线程调用栈
  • frame <n>:切换栈帧查看上下文

你平时怎么编译项目?

单文件可直接 g++,项目建议 Makefile/CMake。

g++ -std=c++17 -O2 -g main.cpp -I./include -L./lib -lfoo -o app

说一下 Makefile 怎么写

核心是变量清晰、规则完整、支持增量编译。

CXX := g++
CXXFLAGS := -std=c++17 -O2 -g -Wall -Wextra
INCLUDES := -I./include
LDFLAGS := -L./lib
LDLIBS := -lfoo -lpthread

SRCS := main.cpp foo.cpp
OBJS := $(SRCS:.cpp=.o)
TARGET := app

all: $(TARGET)

$(TARGET): $(OBJS)
	$(CXX) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)

%.o: %.cpp
	$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@

clean:
	rm -f $(OBJS) $(TARGET)

.PHONY: all clean

-g -I -L` 分别干什么?

  • -g:生成调试符号
  • -I:头文件搜索路径
  • -L:库文件搜索路径

给一段代码让你找问题,你怎么分析?

固定套路:

  • 编译期:类型/声明问题
  • 运行期:越界、空指针、悬空引用
  • 逻辑层:边界条件遗漏

基本上指出哪一行错、为什么、怎么改。

题目代码

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <thread>
#include <mutex>
using namespace std;

class UserCache {
public:
    const string& getName(int uid) {
        lock_guard<mutex> lk(mu_);
        if (nameById_.count(uid) == 0) {
            string tmp = "user_" + to_string(uid);
            nameById_[uid] = tmp;
        }
        return nameById_[uid];
    }

    void eraseIfOdd(int uid) {
        if (uid % 2 == 1) {
            lock_guard<mutex> lk(mu_);
            nameById_.erase(uid);
        }
    }

private:
    unordered_map<int, string> nameById_;
    mutex mu_;
};

int parseScore(const string& s) {
    int sign = 1;
    size_t i = 0;
    if (s[0] == '-') {
        sign = -1;
        i = 1;
    }
    int v = 0;
    for (; i <= s.size(); ++i) {
        if (s[i] < '0' || s[i] > '9') break;
        v = v * 10 + (s[i] - '0');
    }
    return sign * v;
}

int sumTopK(vector<int>& a, size_t k) {
    int sum = 0;
    for (size_t i = 0; i <= k; ++i) {
        sum += a[i];
    }
    return sum;
}

int main() {
    UserCache cache;
    vector<string> ids = {"12", "-7", "", "9x"};
    vector<int> scores;

    for (auto& s : ids) {
        int x = parseScore(s);
        scores.push_back(x);
    }

    thread t1([&](){
        for (int i = 0; i < 10000; ++i) {
            const string& n = cache.getName(i % 10);
            if (n.size() > 20) cout << n << endl;
        }
    });

    thread t2([&](){
        for (int i = 0; i < 10000; ++i) {
            cache.eraseIfOdd(i % 10);
        }
    });

    t1.join();
    t2.join();

    cout << "sum=" << sumTopK(scores, 3) << endl;
    return 0;
}

参考分析

  1. parseScore 越界 s[0] 在空串时越界 i <= s.size() 会在 i == s.size() 时访问 s[i] 越界 修复:先判空;循环改为 i < s.size()
  2. sumTopK 越界 i <= k 会访问 k+1 个元素 k 可能超过 a.size() 修复:i < min(k, a.size())
  3. 并发悬空引用风险 getName 返回 unordered_map 内部元素引用 锁释放后别的线程 erase/rehash 可能使引用失效 修复:getName 返回 string 值(副本)而不是引用

正确答案

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <thread>
#include <mutex>
using namespace std;

class UserCache {
public:
    string getName(int uid) {
        lock_guard<mutex> lk(mu_);
        auto it = nameById_.find(uid);
        if (it == nameById_.end()) {
            it = nameById_.emplace(uid, "user_" + to_string(uid)).first;
        }
        return it->second;
    }

    void eraseIfOdd(int uid) {
        if (uid % 2 == 1) {
            lock_guard<mutex> lk(mu_);
            nameById_.erase(uid);
        }
    }

private:
    unordered_map<int, string> nameById_;
    mutex mu_;
};

int parseScore(const string& s) {
    if (s.empty()) return 0;

    int sign = 1;
    size_t i = 0;
    if (s[i] == '-') {
        sign = -1;
        ++i;
    }

    int v = 0;
    for (; i < s.size(); ++i) {
        if (s[i] < '0' || s[i] > '9') break;
        v = v * 10 + (s[i] - '0');
    }
    return sign * v;
}

int sumTopK(const vector<int>& a, size_t k) {
    int sum = 0;
    size_t n = min(k, a.size());
    for (size_t i = 0; i < n; ++i) {
        sum += a[i];
    }
    return sum;
}

int main() {
    UserCache cache;
    vector<string> ids = {"12", "-7", "", "9x"};
    vector<int> scores;

    for (const auto& s : ids) {
        scores.push_back(parseScore(s));
    }

    thread t1([&]() {
        for (int i = 0; i < 10000; ++i) {
            string n = cache.getName(i % 10);
            if (n.size() > 20) cout << n << '\n';
        }
    });

    thread t2([&]() {
        for (int i = 0; i < 10000; ++i) {
            cache.eraseIfOdd(i % 10);
        }
    });

    t1.join();
    t2.join();

    cout << "sum=" << sumTopK(scores, 3) << endl;
    return 0;
}

合并区间题,给出思路和代码

思路:先按起点排序,再线性扫描合并重叠区间。

#include <vector>
#include <algorithm>
using namespace std;

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        if (intervals.empty()) return {};
        sort(intervals.begin(), intervals.end(),
             [](const vector<int>& a, const vector<int>& b) {
                 return a[0] < b[0];
             });

        vector<vector<int>> res;
        res.push_back(intervals[0]);

        for (size_t i = 1; i < intervals.size(); ++i) {
            auto& last = res.back();
            if (intervals[i][0] <= last[1]) {
                last[1] = max(last[1], intervals[i][1]);
            } else {
                res.push_back(intervals[i]);
            }
        }
        return res;
    }
};

C++面试总结 文章被收录于专栏

本专栏系统梳理C++面试高频考点,从基础语法、内存管理、STL与设计模式,到操作系统与项目实战,结合真实面试题深度解析,帮助开发者高效查漏补缺,提升技术理解与面试通过率,打造扎实的C++工程能力。

全部评论

相关推荐

点赞 评论 收藏
分享
02-16 01:39
南昌大学 Java
坚持无悔意无休:xhs上集美最爱说谎博人眼球
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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