c++ 基础题目lambda
1. auto lambda = [](double x) { return static_cast<int>(x); }; 是 匿名函数对象 ,不可直接声明
a.可以赋值给一个与其类型兼容的 std::function 类型的对象 std::function<int(int, int)> lambda = [](int x, int y) { return x + y; };
b.使用具体的 lambda 类型(函数指针) int (*lambda1)(int, int) = [](int x, int y) { return x + y; };
c. 推导类型decltype([](int x, int y) { return x + y; }) lambda = [](int x, int y) { return x + y; };
decltype 用于推导一个表达式的类型,而不是像 auto 那样推导变量的类型
int x = 5;
double y = 2.5;
decltype(x + y) z = x + y;  // decltype(x + y) 等同于 double
std::cout << z << std::endl;  // 输出 7.5 
 
2. 什么样的lambda不能复制给function
1. 捕获非复制对象的 lambda
std::unique_ptr<int> ptr = std::make_unique<int>(42);
    // 捕获了一个不可复制的对象 std::unique_ptr
    auto lambda = [ptr]() { return *ptr; }; 
std::unique_ptr<int> 是不可复制的,它的移动语义导致 lambda 无法被复制。因此,std::function 也无法复制该 lambda ,可以改为捕获指针或其他可复制的对象。
auto lambda = [ptr = std::move(ptr)]() { return *ptr; }; 
2.捕获了外部局部变量,并且该变量是不可复制的(例如,捕获了一个带有删除拷贝构造函数的类型),就不能将其赋值给 std::function
#include <iostream>
#include <functional>
struct NonCopyable {
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;  // 删除拷贝构造函数
};
int main() {
    NonCopyable nc;
    auto lambda = [nc]() { return 42; };  // 捕获了一个不可复制的对象
    // 无法将 lambda 赋值给 std::function,因为它捕获了不可复制的对象
    std::function<int()> func = lambda;  // 编译错误
   
3 . lambda 捕获的对象存在哪里
是由编译器在内存中为 lambda 创建的闭包对象所持有的。具体来说,lambda 捕获的对象被存储在一个类的成员变量中,这个类通常被称为闭包类型。
class lambda_class {
private:
    int x;  // 捕获的对象
public:
    lambda_class(int x) : x(x) {}
    void operator()() {
        std::cout << "Captured value: " << x << std::endl;
    }
};
int main() {
    int x = 10;
    lambda_class lambda(x);  // 创建 lambda 对象
    lambda();  // 调用 lambda
    return 0;
} 
 
 
lua 有几种原表
__index。用于访问表中不存在的字段时触发。可以用来实现表的继承或委托
__newindex 用于设置表中不存在的字段时触发。可以用于限制或控制表字段的赋值。
__call 当表被作为函数调用时触发。这允许你让表表现得像函数一样。
__tostring 当表被转换为字符串时触发。通常在使用 print() 或 tostring() 函数时,Lua 会调用 __tostring 元方法。
__add, __sub, __mul, __div, __mod, __pow, __concat, __len, __eq, __lt, __le 等运算符元方法
5. realloc 会尝试调整内存块的大小:
-  
扩展内存:
-  
如果当前内存块后面有足够的空闲空间,
realloc会直接扩展内存块,而无需移动数据。 -  
如果没有足够的空闲空间,
realloc会分配一块新的内存,将原有数据复制到新内存中,然后释放旧内存。 
 -  
 
6. 在 MySQL 中,"回表"(也叫做"二次查表")是指在使用覆盖索引时,如果查询需要的字段不在索引中,那么就需要通过索引中的记录再次去查询对应的数据表,从而获取那些没有包含在索引中的字段值。
为了更好理解,先简要了解下 MySQL 索引的相关概念:
- 覆盖索引:是指查询时,所需要的所有字段都在索引中,查询不需要再访问数据表(即回表操作)。
 - 非覆盖索引:是指查询需要的字段不完全在索引中,部分数据仍然需要通过索引中的主键或唯一索引回到数据表中查找。
 
举个例子
假设 users 表有如下字段:id(主键)、name 和 age,并且你创建了一个索引 idx_name,仅包含 name 字段。如果你执行以下查询:
ELECT id, name, age FROM users WHERE name = 'Alice';  
- MySQL 会首先利用 
idx_name索引查找符合条件的记录(即name = 'Alice')。 - 由于查询还需要 
id和age字段,而这些字段不包含在idx_name索引中,因此 MySQL 会通过索引中的主键值回到数据表中,查找对应的行数据并返回结果。 
怎么避免回表
1. 使用覆盖索引
CREATE INDEX idx_name_age ON users(name, age); 
2. 使用复合索引
如果查询涉及多个字段,最好创建一个复合索引,索引包含查询的所有字段,避免 MySQL 在查询过程中回表。
示例:
假设你频繁查询 name 和 age 字段,可以创建如下复合索引:
CREATE INDEX idx_name_age ON users(name, age); 
当你执行以下查询时:
SELECT name, age FROM users WHERE name = 'Alice' AND age = 25; 
MySQL 会使用复合索引 idx_name_age,通过索引直接返回数据,避免回表。
3. 合理选择查询字段
4. 使用主键查询
8. 模版是拷贝代码的.
#include <iostream>
template <typename T>
class t {
public:
    static int staticVar;  // 静态成员变量
    T a;
};
// 静态成员变量的定义
template <typename T>
int t<T>::staticVar = 0;
int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    
    t<float> c;
    c.staticVar = 99;
    
    t<int> b;
    b.staticVar = 100;
 
    printf("%d \n", c.staticVar);
    return 0;
}
 
 
互斥锁在父子进程中也是独立的,锁了的状态也会被复制,,需要在各自的进程解锁
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex;  // 定义互斥锁
int main() {
    pid_t pid;
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);
    // 父进程锁定互斥锁
    pthread_mutex_lock(&mutex);
    printf("Parent process: Mutex locked.\n");
    // 使用 fork 创建子进程
    pid = fork();
    if (pid == -1) {
        // 错误处理
        perror("fork failed");
        exit(1);
    }
    if (pid == 0) {  // 子进程
        // 子进程在这里会等到父进程锁定互斥锁
        printf("Child process: Waiting to unlock the mutex...\n");
        // 子进程解锁互斥锁
        pthread_mutex_unlock(&mutex);
        printf("Child process: Mutex unlocked.\n");
        exit(0);
    } else {  // 父进程
        // 父进程在这里等待子进程执行完毕
        wait(NULL);  // 等待子进程结束
        printf("Parent process: Mutex still locked after child exits.\n");
        // 父进程完成任务后解锁互斥锁
        pthread_mutex_unlock(&mutex);
        printf("Parent process: Mutex unlocked.\n");
        // 销毁互斥锁
        pthread_mutex_destroy(&mutex);
    }
    return 0;
}
 
                