一、C++11的新特性都有哪些?
1.1 自动类型推断 (auto)
auto 关键字允许编译器自动推断变量的类型,从而简化代码的书写。
auto num = 5;        // int
auto pi = 3.14;     // double
auto str = "Hello"; // const char*
1.2 范围 for 循环
范围 for 循环可以简化容器(如数组和 STL 容器)的遍历。
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto& i : vec) {
    std::cout << i << " "; // 输出 1 2 3 4 5
}
1.3 Lambda 表达式和函数闭包
Lambda 表达式提供了一种简洁的方式来定义匿名函数,并允许捕获外部变量。
int x = 10;
auto lambda = [x](int y) { return x + y; };
std::cout << lambda(5); // 输出 15
1.4 右值引用和移动语义
右值引用允许对临时对象进行高效的资源管理,移动语义使得资源的转移比复制更高效。
#include <utility>
class MyClass {
public:
    MyClass() { /* 资源分配 */ }
    MyClass(MyClass&& other) { /* 资源转移 */ }
};
MyClass createMyClass() {
    return MyClass(); // 返回一个右值
}
MyClass obj = createMyClass(); // 通过移动构造
1.5 可变参数模板
可变参数模板允许函数接受任意数量的参数。
template<typename... Args>
void printAll(Args... args) {
    (std::cout << ... << args) << std::endl; // C++17 折叠表达式
}
printAll(1, 2, 3.5, "Hello"); // 输出: 1 2 3.5 Hello
1.6 初始化列表
初始化列表提供了一种更方便的方式来初始化容器和自定义类型。
std::vector<int> vec = {1, 2, 3, 4}; // 列表初始化
std::array<int, 3> arr = {1, 2, 3};   // std::array 初始化
1.7 强类型枚举
强类型枚举(enum class)提供了更强的类型安全性和作用域。
enum class Color { Red, Green, Blue };
Color c = Color::Red;
// c = 1; // 错误,不能隐式转换
1.8 智能指针如 std::unique_ptr 和 std::shared_ptr
 
智能指针帮助管理动态分配的内存,避免内存泄漏。
#include <memory>
std::unique_ptr<int> p1 = std::make_unique<int>(5); // 独占型智能指针
std::shared_ptr<int> p2 = std::make_shared<int>(10); // 共享型智能指针
1.9 空指针关键字 (nullptr)
nullptr 是一个类型安全的空指针常量,取代了 NULL。
int* p = nullptr; // p 是一个空指针
1.10 线程库支持
C++11 引入了 <thread> 头文件,使得多线程编程变得更加简单。
#include <thread>
void threadFunction() {
    std::cout << "Hello from thread!" << std::endl;
}
std::thread t(threadFunction);
t.join(); // 等待线程结束
1.11 新容器如 std::array 和 std::unordered_map
 
C++11 引入了一些新的标准容器。
- std::array是一个固定大小的数组,可以在编译时确定大小。
- std::unordered_map是一个基于哈希表的关联容器,提供常量时间复杂度的插入和查找。
#include <array>
#include <unordered_map>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
std::unordered_map<std::string, int> umap = {{"one", 1}, {"two", 2}};
这些特性极大地增强了 C++ 的功能和可用性,使得编写现代 C++ 代码更加简洁、易于维护和高效。
二、了解什么设计模式?单例了解吗?
单例模式是一种设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实
 例。
在C++中实现单例模式通常需要以下步骤:
私有化构造函数和析构函数:这样可以防止外部代码直接创建或销毁该类的实例。
提供一个私有的静态指针变量:该指针用于存储唯一实例的地址。
提供一个公共的静态方法:这个方法用于返回唯一实例,并确保实例在第一次调用时被创建。
#include <iostream>
#include <mutex>
class Singleton {
private:
    // 私有构造函数
    Singleton() {
        std::cout << "Singleton instance created!" << std::endl;
    }
    
    // 私有析构函数
    ~Singleton() {
        std::cout << "Singleton instance destroyed!" << std::endl;
    }
    // 私有静态指针,指向唯一实例
    static Singleton* instance;
    static std::mutex mutex_; // 线程安全的互斥锁
public:
    // 禁止拷贝构造和赋值
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    // 公共静态方法获取唯一实例
    static Singleton* getInstance() {
        if (instance == nullptr) {
            std::lock_guard<std::mutex> lock(mutex_); // 确保线程安全
            if (instance == nullptr) {
                instance = new Singleton();
            }
        }
        return instance;
    }
};
// 初始化静态指针
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex_;
int main() {
    Singleton* singleton1 = Singleton::getInstance();
    Singleton* singleton2 = Singleton::getInstance();
    // 验证两者是同一个实例
    if (singleton1 == singleton2) {
        std::cout << "Both are the same instance." << std::endl;
    }
    return 0;
}

三、TCP和UDP的区别?
TCP是面向连接的协议,进行数据传输前需要建立连接。
UDP是无连接的协议,不需要建立连接就可以直接发送数据。
3.2.可靠性:
TCP提供可靠的数据传输,确保数据完整性和顺序。
UDP提供不可靠的数据传输,可能出现丢包,不保证数据顺序。
 3.速度:
 ·TCP相对较慢,因为它需要确认机制和错误
 校正。
 ·UDP传输速度更快,没有确认机制,适用于
 对速度要求高的场合。
 4.数据流:
 ·TCP提供字节流服务,通过数据流的方式发
 送数据。
 ·UDP以数据报文的形式发送信息,发送独立
 的消息。
3.1 连接
-  TCP(传输控制协议): - TCP 是面向连接的协议,这意味着在实际数据传输之前,必须先建立一个连接。这是通过三次握手(Three-Way Handshake)完成的,确保双方都准备好进行通信。
- 三次握手的过程如下: 
    - 客户端发送一个 SYN(同步)包到服务器。
- 服务器回应一个 SYN-ACK(同步-确认)包。
- 客户端再发送一个 ACK(确认)包来确认连接建立。
 
 
-  UDP(用户数据报协议): - UDP 是无连接的协议,发送方和接收方之间不需要建立连接。数据可以立即发送,适合需要快速传输且对连接不敏感的应用。
 
3.2 可靠性
-  TCP: - TCP 提供可靠的数据传输,确保数据的完整性和按顺序到达。它使用序列号来跟踪每个字节的发送和接收,采用重传机制来处理丢失的数据包,并通过校验和来检测数据错误。
 
-  UDP: - UDP 不提供可靠性保证,数据包可能会丢失、重复或乱序到达。由于没有重传机制和流控制,UDP 适用于对实时性要求高的应用,比如视频会议、在线游戏等。
 
3.3 速度
-  TCP: - 因为 TCP 需要进行连接建立、数据确认、错误检测和重传等操作,所以相对较慢。它适合需要高可靠性的数据传输,像文件传输、电子邮件等。
 
-  UDP: - UDP 传输速度较快,因为它没有连接建立过程和确认机制,适用于速度要求高且可以容忍数据丢失的场景,例如 DNS 查询、实时视频和音频传输。
 
3.4 数据流
-  TCP: - TCP 是面向字节流的协议,它将数据视为一个连续的字节流。应用程序发送的数据会被分割成多个数据包,接收方再将这些数据包重新组装成完整的数据流。
 
-  UDP: - UDP 是面向消息的协议,每个数据包(称为数据报)都是独立的。数据报的大小有限,UDP 不会将多个数据报组合成一个流,需要应用程序自己处理消息的边界。
 
四、左值和右值引用?
左值引用是对可寻址的、可重复使用的对象(左值)的引用。它使用传统的单个&符号。
右值引用是对临时对象(右值)的引用,使用双&&符号。右值引用允许实现移动语义和完美转发,它可以将资源从一个(临时的)对象转移到另一个对象,提高效率,避免不必要的复制。
五、能说说static关键字吗?
5.1 static关键字有几个用途:
1. 当在类的数据成员前使用 static 时,表示该成员属于类本身,而不是任何特定的实例。所有实例共享这一成员。
class MyClass {
public:
    static int count; // 静态数据成员
    MyClass() {
        count++; // 每创建一个实例,count 增加
    }
};
// 静态成员定义和初始化
int MyClass::count = 0;
int main() {
    MyClass obj1;
    MyClass obj2;
    std::cout << MyClass::count; // 输出 2,表明创建了两个实例
    return 0;
}
 2.当在类的成员函数前使用 static 时,可以在不创建类实例的情况下直接调用该函数。这通常用于那些不依赖于类的实例的功能。
class MyClass {
public:
    static void display() {
        std::cout << "Hello from static function!" << std::endl;
    }
};
int main() {
    MyClass::display(); // 直接调用静态成员函数
    return 0;
}
 3.在函数内部使用static定义局部变量,使得该变量的值在函数调用间持久存在,而不是每次调
 用时都重新创建。
#include <iostream>
void counter() {
    static int count = 0; // 静态局部变量
    count++;
    std::cout << "Count: " << count << std::endl; // 每次调用显示当前计数
}
int main() {
    counter(); // 输出 Count: 1
    counter(); // 输出 Count: 2
    counter(); // 输出 Count: 3
    return 0;
}
 4.在文件、函数或区域前使用static,可以限制该变量或函数的链接可见性,令其只在定义它的
 文件或作用域内部可见。
// 文件 A.cpp
static void helper() {
    std::cout << "This is a static function." << std::endl;
}
void publicFunction() {
    helper(); // 可以调用
}
// 文件 B.cpp
// void anotherFunction() {
//     helper(); // 错误,无法访问 A.cpp 中的 static 函数
// }
2. static 关键字在 C++ 中具有多种用途:
 
用于定义类的静态数据成员和静态成员函数。
用于保持局部变量在函数调用之间的状态。
用于限制变量和函数的可见性,确保它们仅在定义它们的文件或作用域内可见。
六、进程间通信的方式有哪些?线程间的数据交互?
6.1 进程间通信方式包括:
1.管道(Pipes)
2.命名管道(FIFO)
3.信号(Signals】
4.消息队列(Message Queues)
5.共享内存(Shared Memory)
6.信号量(Semaphores)
7.套接字(Sockets)】
8.内存映射文件(Memory-mapped files)
6.2 线程间的数据交互可以通过:
1.锁(如互斥锁Mutex)
2.条件变量(Condition Variables)
3.信号量(Semaphores)
4.线程局部存储(Thread-local Storage,TLS)
5.全局变量(通过使用同步机制以避免并发访问问题)
  




















