zoukankan      html  css  js  c++  java
  • 扩展2

    C++相关

    1、宏定义

    #define:写法为#define 标识符(形参) 字符串,作用是定义标识符为字符串。
    #if、#else、#endif、#elif:和去掉#意思差不多,只是最后一定要加#endif
    #ifdef:如果后面的宏定义了,那么编译
    #ifndef:如果后面的宏没有定义,那么编译
    #undef:取消宏

    2、O(1)插入,删除,随机等概率获取数

    不能重复元素使用:
    使用vector存数字,用unordered_map<int, int>记录每个值在vector的索引。这样插入和随机都能O(1)了。删除的时候,把要删除的数和末尾交换,然后pop_back()。

    可重复:
    ,用unordered_map<int, vector>记录每个值在vector的索引。

    3、虚函数表在哪?

    Linux/Unix放在只读数据段,Windows放在常量段。

    4、引用折叠

    即推导类似T& &&,T&& &&的类型。
    规则为:只有右值引用折叠到右值引用才为右值引用,其他折叠均为左值引用,即T&& &&=T&&,其余T& &&/T&& &/T& &=T&。

    5、再谈右值引用作用

    之前看的已经忘了...、

    右值引用是C++11为了实现移动操作而引入的新的引用类型
    作用:

    1. 实现移动语义,也就是move(),move就是把左值强制转换为右值引用。为了避免了拷贝带来的开销(构造析构等等),直接把所有权进行移动,移完之后原来的变量失去对值的控制。比如unique_ptr的所有权移动需要使用move。
      实现为static_cast静态强制转换。
    2. 实现完美转发,也就是forward(),在传递参数的时候保留其左右值属性。通常情况下,函数内部对一个参数都是以左值使用的,所以需要forward<>()进行一个完美转发。

    6、std::move和std::forward

    move:
    使用static_cast把左值(右值)变成一个右值引用。

    template <typename T>
    typename remove_reference<T>::type&& move(T&& t)
    {
    	return static_cast<typename remove_reference<T>::type&&>(t);
    }
    

    forward:
    需要了解一点引用折叠的知识。

    template<class _Ty>
    	_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>& _Arg) noexcept
    	{	// forward an lvalue as either an lvalue or an rvalue
    	return (static_cast<_Ty&&>(_Arg));
    	}
    
    template<class _Ty>
    	_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept
    	{	// forward an rvalue as an rvalue
    	static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
    	return (static_cast<_Ty&&>(_Arg));
    	}
    
    

    7、多线程thread

    头文件:#include<thread>
    创建线程t1调用函数function:std::thread t1(function[, args...])
    创建线程t1调用类的成员函数:thread t1(&Object::fun, &obj, str)
    拷贝构造:thread没有左值的拷贝构造,有右值的拷贝构造,即只可以std::thread t2(std::move(t1))
    线程id:t1.get_id()
    join和detach的区别:join会使主线程阻塞,执行完子线程才能继续往下执行;detach会在后台自己运行。
    关于传引用参数:如果fuction中参数为引用,需要使用std::ref()。因为thread是拷贝参数进行值传递,所以引用需要用ref函数

    8、原子操作

    可用于多线程之间的同步操作。

    atomic_flag:
    std::atomic_flag是原子布尔类型,禁止拷贝构造和move赋值。初始化时要用宏定义ATOMIC_FLAG_INIT保证处于clear状态,如果没初始化那么处于未定义状态。
    使用atomic_flag.test_and_set()检查布尔类型,如果是clear,那么就会set并返回false;否则返回true。
    使用atomic_flag.clear()把布尔类型清空。

    9、printf

    printf中从右向左计算。
    例如 x=0; printf("%d %d ", ++x, x++) 输出为2 0.因为printf中从右到左计算,先算x++,再算++x。

    网络

    1、详细Ping过程描述/二层转发三层转发

    主机A建立一个ICMP回显请求报文,和主机B的IP地址发送给IP层,构建一个IP数据包。然后要获得MAC地址(二、三层转发):

    1.同一网段:
    主机A要ping主机B,先判断一下是不是处于同一网段(掩码),发现是同一网段。然后查MAC地址表,发现没有B的MAC地址,那么向外发送ARP广播。交换机收到报文后,学习A的地址,看一下有没有B的MAC地址,有就发给A;没有就向所有端口发送ARP广播。非主机B收到报文后会丢弃,主机B收到报文后学习A的MAC地址,然后发送ARP回应报文告诉A自己的MAC地址。A收到后学习B的MAC地址。

    2.不同网段:
    先判断一下是不是处于同一网段,发现不是同一网段。主机A找网关转发。如果不知道网关MAC地址,那么就同上进行ARP广播,得到网关MAC地址。然后发送ICMP请求报文给网关路由器。网关收到后,查找路由表,确定发出去的端口,看一下目标IP是不是在同一网段,是的找到B的MAC地址转发过去(找不到ARP广播一下);不是的话,使用下一跳的IP地址查ARP表,发到下一跳。

    主机B收到报文,返回ICMP回显应答报文。
    用到的协议主要有:DNS(域名转地址),UDP(DNS协议使用),IP,ARP。

    参考资料

    详细Ping过程描述(二、三层转发)
    C++11尝鲜:std::move和std::forward源码分析
    引用折叠和完美转发
    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)

  • 相关阅读:
    (翻译)Entity Framework技巧系列之九 Tip 35 36
    (翻译)Entity Framework技巧系列之十 Tip 37 41
    (翻译)Entity Framework技巧系列之一 Tip 1 5
    (翻译)Entity Framework技巧系列之五 Tip 16 – 19
    [翻译]C#数据结构与算法 – 第五章栈与队列(Part 1)
    [翻译]C#数据结构与算法 – 第六章BitArray类
    (翻译)Entity Framework技巧系列之七 Tip 26 – 28
    (翻译)Entity Framework技巧系列之四 Tip 13 – 15
    (翻译)Entity Framework技巧系列之二 Tip 6 8
    使用YCSB测试mongodb
  • 原文地址:https://www.cnblogs.com/KirinSB/p/12961966.html
Copyright © 2011-2022 走看看