c++八股8

  1. 友元函数能不能是虚函数:
    友元函数不属于类的成员函数,它独立于类存在,因此不存在是否为虚函数的概念。友元函数主要用于突破类的封装性,使外部函数能访问类的私有和保护成员,它与类的继承和多态无关。
  2. TCP三握四挥:
    TCP连接建立过程(三次握手):
    客户端发送带有SYN标志的数据包给服务器,进入SYN_SENT状态。
    服务器接收到SYN后回复带有SYN+ACK标志的数据包,进入SYN_RECEIVED状态。
    客户端收到服务器的SYN+ACK后,再发送一个带有ACK标志的数据包作为确认,此时客户端和服务端都进入ESTABLISHED状态,完成连接建立。
    TCP连接关闭过程(四次挥手):
    主动关闭方(例如客户端)发送FIN标志的数据包给对方,进入FIN_WAIT_1状态。
    服务端接收到FIN后,回复一个带有ACK标志的数据包,进入CLOSE_WAIT状态,此时客户端进入FIN_WAIT_2状态。
    服务端准备好关闭连接时,发送自己的FIN标志的数据包,进入LAST_ACK状态。
    客户端收到服务端的FIN后,再次回复一个带有ACK标志的数据包,进入TIME_WAIT状态,等待一段时间确保最后一个ACK已被服务端接收后彻底关闭连接;服务端收到最后一个ACK后关闭连接。
  3. 数据结构封装: 在编程中,数据结构的封装是指将数据结构(如数组、链表、树、图等)以及在其上进行操作的方法一起包装在类或结构体中,形成一个独立且易于使用的单元。通过封装,可以隐藏实现细节,提供一致和安全的接口,方便代码维护和重用。
    例如,在C++中封装一个简单的动态数组:
Cpp
template <typename T>
class MyVector {
private:
    T* data;
    int size;
    int capacity;

public:
    // 构造函数、析构函数、拷贝构造、赋值运算符等
    MyVector(int initial_capacity = 10);
    ~MyVector();
    MyVector(const MyVector& other);
    MyVector& operator=(const MyVector& other);

    // 常规操作
    void push_back(T value);
    void pop_back();
    T& at(int index);
    const T& at(int index) const;
    // ... 其他方法,如:insert, erase, resize, clear 等

    // 访问器方法
    int getSize() const { return size; }
    int getCapacity() const { return capacity; }

    // 私有辅助方法
private:
    void resize(int new_capacity);
};
  1. map与unordered_map的区别及使用场景:std::map:
    底层通常采用红黑树(RBTree)实现,保证键值对按键的升序排列。
    插入、删除和查找的时间复杂度均为O(log n),其中n是元素数量。
    如果需要有序遍历或者基于键的排序操作,map是一个很好的选择。
    示例使用场景:电话簿(按姓名排序)、日志记录(按时间戳排序)等。
    std::unordered_map:
    底层采用哈希表(Hash Table)实现,不保证内部顺序。
    查找、插入和删除平均时间复杂度为O(1),但最坏情况下可能是O(n)(当哈希冲突严重时)。
    若仅需高效查找而不关心顺序,unordered_map更优。
    示例使用场景:缓存系统、关键词索引等无需排序的应用。
    总结:
    当需要键值对保持有序性时,应选用std::map。
    对于快速查找和不需要维持顺序的场景,优先考虑使用std::unordered_map以获取更好的平均性能。同时,unordered_map对于内存要求可能更低,因为其存储结构更为紧凑。然而要注意的是,由于哈希表的特性,当插入大量数据时,合理的负载因子和良好的哈希函数对于性能至关重要。

你可能感兴趣的:(八股八股八股文,c++)