Skip to content

败犬日报 2025-07-16

1. 有没有优化编译时间的编译选项

不开优化就行了,-O0

不过这做不到任何情况最优。理论上可能存在某些 pass 可以大量简化 IR,然后加快后续的编译进度,比如死代码删除的 pass。

2. 将引用绑定到两个变量中的一个

用三目就行了。

cpp
int x;
int y;
int &ref = condition ? x : y;

3. 工作只需要用现成的库,之前学的基础知识有什么用

面试的时候不就用到了吗。


另一方面,做项目不是说会调几个库跑个 mvp 出来就行了,出现问题了你得会定位,某些情况下你得自己编下库把断点打到那里,你如果没有通用的相对 low level 的知识,效率会很低。—— hiki

4. std::sort 是内省排序 (introsort)

是快速排序、堆排序、插入排序融合版。快排为主,如果范围小用插入,如果递归深度大用堆排。

5. 实现快速排序,但是 swap 开销特别大

先对索引快速排序,然后 swap 捋一遍,尽可能减少 swap 次数。

6. llm-friendly LLM 体工程学

未来大量接口首先需要考虑面向 llm。例如微服务,由于上下文短非常适合 LLM 写。而 infra 上下文牵涉太多,还得靠人。

7. 怎么判断 shared_ptr 基类和 shared_ptr 子类指向的是同一个对象

可以判断控制块 (control block) 的指针是否相同。

控制块是什么?shared_ptr 包含指向对象、控制块两个指针,而控制块存储的是对象(或对象的指针)、Deleter、分配器、引用计数和弱引用计数。ref https://en.cppreference.com/w/cpp/memory/shared_ptr.html 里的 Implementation notes 章节。

不过判断控制块的技巧没什么用。赋值一般是 swap 实现(就是 copy-and-swap idiom),不需要判断对象相同。

== 不能判断是同一对象,在菱形继承情况下(下面解释),标准规定了 == 比较的都是存储的指针,https://en.cppreference.com/w/cpp/memory/shared_ptr/operator_cmp.html

In all cases, it is the stored pointer (the one returned by get()) that is compared.


一般来说,判断指针相同可以直接 ==,因为编译期基类地址对于子类的偏移是确定的(偏移不为 0 的情况是多继承、有虚函数类继承无虚函数类)。

cpp
#include <cstdio>

struct Base1 {
    int data0;
};
struct Base2 {
    int data1;
};
struct Derived : Base1, Base2 {};

int main() {
    Derived d;
    Derived* derived_ptr = &d;
    Base1* base1_ptr = &d;
    Base2* base2_ptr = &d;

    printf("%p %p %p\n", derived_ptr, base1_ptr, base2_ptr);  // 可能输出 0x7ffcdf034dcc 0x7ffcdf034dcc 0x7ffcdf034dd0
    printf("%d %d\n", derived_ptr == base1_ptr, derived_ptr == base2_ptr);  // 输出 1 1
}

但是菱形继承是不行的,因为子类包含了多个基类(类型相同但是地址不同),就会有歧义。

cpp
#include <cstdio>

struct Base0 {};
struct Base1 : Base0 {
    int data0;
};
struct Base2 : Base0 {
    int data1;
};
struct Derived : Base1, Base2 {};

int main() {
    Derived d;
    Derived* derived_ptr = &d;
    Base0* base0_ptr = static_cast<Base1*>(&d);

    printf("%d\n", derived_ptr == base0_ptr);  // error: 'Base0' is an ambiguous base of 'Derived'
}