• 地址:https://wangcy6.github.io/post/2021/06_ask_1/

http://127.0.0.1:1313//post/2021/06_ask_1/

  • 方法:
  1. 阅读(输入:三天,万句 输出 笔记摘要就哪里,但是自己看不懂,别人看不懂 )
  2. 发现问题(输入:技术文档 30分钟 百句,输出 :一大堆东西不无法语言描述,反正就是他,自己回答不清楚,别人听不清楚)
  3. 整理问题(输入:5分钟 10句 技术文档 输出:核心根本无法理解,至少说到重点,不管别人听不懂,至少自己理解极限了)
  4. 回答问题(输入:60秒,2句 技术语言 输出:一个视频)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13


### 一、这个技术出现的背景、初衷和要达到什么样的目标或是要解决什么样的问题

### 二、这个技术的优势和劣势分别是什么 

### 三、这个技术适用的场景。任何技术都有其适用的场景,离开了这个场景

### 四、技术的组成部分和关键点。

### 五、技术的底层原理和关键实现

### 六、已有的实现和它之间的对比

[FQA-6] c++11 特性

  • 6.1 青铜-:小白回答
1
2
3
4
5
6
7
8
怎么回答都不对

C++11中的std::future是一个模板类。std::future提供了一种用于访问异步操作结果的机制
我们想要从线程中返回异步任务结果,一般需要依靠全局变量;
从安全角度看,有些不妥;为此C++11提供了std::future类模板,
future对象提供访问异步操作结果的机制,很轻松解决从异步任务中返回结果。

move semantics and perfect forwarding
  • 阅读:CRTP – Curiously Recurring Template Pattern

https://gzuliani.github.io/cpp/crtp.html

https://www.fluentcpp.com/2017/05/12/curiously-recurring-template-pattern/

  • C++ Template 模版的本质html

    自动化是人类进化的动力

https://www.shangmayuan.com/a/d9c0ca76edc54a8190dc7ae5.html

输出:

1
2
3
4
5
6
7
note that contrary to typical casts to derived class, we don’t use dynamic_cast here. 

A dynamic_cast is used when you want to make sure at run-time that the derived class you are casting into is the correct one. 

But here we don’t need this guarantee: the Base class is designed to be inherited from by its template parameter, and by nothing else. 
Therefore it takes this as an assumption, and a static_cast is enough.

  • 6.2 白银:熟练工回答
  1. 增加了右值引用和通用引用 universal reference.,解决移动语义和完美转发问题。提供std:moved() std:forard工具

  1. std 支持移动语义(move-only types类型使用场景): unique_ptr智能指针。future访问异步操作结果

Move semantics also enables the creation of move-only types, such as std::unique_ptr, std::future, and std::thread.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
template<typename T> 
void f(T&& param);

/**
   *  @brief  Convert a value to an rvalue.
   *  @param  __t  A thing of arbitrary type.
   *  @return The parameter cast to an rvalue-reference to allow moving it.
  */
  template<typename _Tp>
    _GLIBCXX_NODISCARD
    constexpr typename std::remove_reference<_Tp>::type&&
    move(_Tp&& __t) noexcept
    { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }

The construct type&& doesnt always represent an rvalue reference.
  
To prevent this from happening, the type trait (see Item 9) std::remove_reference is applied to T, thus ensuring that && is applied to a type that isnt a reference
  
 
 The other meaning for T&& is either rvalue reference or lvalue reference. 
   
模版作用:
 If the initializer is an rvalue, the universal reference corresponds to an rvalue reference. 
 If the initializer is an lvalue, the universal reference corresponds to an lvalue reference
   
   vector<_Tp, _Alloc>::
      emplace_back(_Args&&... __args)
      {
	if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
	  {
	    _GLIBCXX_ASAN_ANNOTATE_GROW(1);
	    _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish,
				     std::forward<_Args>(__args)...);
	    ++this->_M_impl._M_finish;
	    _GLIBCXX_ASAN_ANNOTATE_GREW(1);
	  }
	else
	  _M_realloc_insert(end(), std::forward<_Args>(__args)...);
#if __cplusplus > 201402L
	return back();
#endif
      }
#endif
  1. 移动语义:创建一个unique_ptr 完美转发:模版函数中,传递T类型 ==过程中 c++11 新增函数 emplace_back()

Item 25: Use std::move on rvalue references, std::forward on universal references.

  1. 异步实现:future
  • 6.3 王者:别人怎么回答

c++11 新特性

  1. 增加了右值引用和通用引用 universal reference.,解决移动语义和完美转发问题。提供std:moved() std:forard工具

  2. 移动语义:创建一个unique_ptr 完美转发:模版函数中,传递T类型 ==过程中 c++11 新增函数 emplace_back()

  3. 线程:获取异步结果:future

5. 虚拟内存是怎么实现的?怎么映射的 为分段分野

4.1 青铜-:小白回答

  • 之间用 malloc 返回的地址
  • 虚假的很大 (类 对象 地址 。)

阅读:

9.2 地址空间

第 3 章:程序的机器级表示

虚拟内存被组织成一个存储在磁盘上的N个连续字节大小的数组。【字长】

阅读:计算机系统基础(八)虚拟存储器

  • 一个程序是如何加载到内存中去的。

阅读:怎样通俗的理解操作系统中内存管理分页和分段?

分段其实是特定时期的产物,主要是由于寄存器位数不够,而地址线的位数超过了寄存器的位数,所以采用分段的方式好访问所有内存。随着时间的流逝,分页逐渐站上了历史舞台,它更灵活,支持的内存大,安全性控制好,所以成为主流

分段机制早于分页机制,使用分段考虑的是多进程并行,在分段的基础上产生了分页,分页可以减少外部碎片

输出:

而栈,堆,bss段,数据段均是匿名映射 [ anon ]

内存文件映射mmap。 mmap() creates a new mapping in the virtual address space of the calling process. mmap就是将文件映射到内存上,进程直接对内存进行读写,然后就会反映到磁盘上。 实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。实现这样的映射关系后 进程的代码段来自于镜像,采用文件映射方式;

4.2 白银:熟练工回答

4.3 王者:别人怎么回答

5.2022-3-1 在c语言中,浮点型数据只有有符号类型。这是为什么

https://zhuanlan.zhihu.com/p/138845520

4. 2022-2-24 raft 日志怎么commited,apply id,follow如何接受数据的?如何优化传输。

4.1 青铜-:小白回答

4.2 白银:熟练工回答

4.3 王者:别人怎么回答

3. 2022-2-24 为分页和分段,优缺点?

3.1 青铜-:小白回答

3.2 白银:熟练工回答

3.3 王者:别人怎么回答

2、gdb 问号?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

(gdb) bt
#0  0x0000003ec40e91a3 in __epoll_wait_nocancel () from /lib64/libc.so.6
#1  0x00000000006410da in _st_epoll_dispatch ()
#2  0x000000000063bc78 in _st_idle_thread_start ()
#3  0x000000000063c082 in _st_thread_main ()
#4  0x000000000063c8ff in st_thread_create ()
#5  0x00007ffcd2733958 in ?? ()
#6  0x0000000000915258 in vtable for _SrsContextId ()
#7  0x00007ffcd2733968 in ?? ()
#8  0x0000000000000008 in ?? () at /usr/local/gcc/include/c++/6.3.0/bits/stl_tree.h:2318
#9  0x3138343863373838 in ?? ()
#10 0x00007ffcd2733900 in ?? ()
#11 0x0000000000000002 in ?? () at /usr/local/gcc/include/c++/6.3.0/bits/stl_tree.h:2318
#12 0x0000000030006e6f in ?? ()
#13 0x0000000000ec90b0 in ?? ()
#14 0x0000000000f0e280 in ?? ()
#15 0x0000000000000064 in ?? () at /usr/local/gcc/include/c++/6.3.0/bits/stl_tree.h:2322
#16 0x0000000000000064 in ?? () at /usr/local/gcc/include/c++/6.3.0/bits/stl_tree.h:2322
#17 0x0000003e00000001 in ?? ()
#18 0x0000000000915258 in vtable for _SrsContextId ()
#19 0x00007ffcd27339c8 in ?? ()
#20 0x0000000000000008 in ?? () at /usr/local/gcc/include/c++/6.3.0/bits/stl_tree.h:2318
#21 0x3138343863373838 in ?? ()
#22 0x0000000000000000 in ?? ()

过程:(忘记问题,专注过程)

青铜->新手村:

  1. 这个问题自己无法根本解决,掌握知识不够(心态问题,你全部回顾你掌握的知识 )

  2. 我看文档 也找不大答案,(看方式不正确,全面看资料,问题是引子。意外收获呢,你看文档资料对吗?)

黄金->熟练工:


第四步:回答问题(输入:60秒,2句 技术语言 输出:一个视频)

第三步:整理问题(输入:5分钟 10句 技术文档 输出:说重点快问快答 )

# 问:什么是四次挥手,描述具体过程?

  • 如图1:

第一次握手:客户端发送close请求,传输含有fin标记报文段到服务器。

第二次握手:服务器 tcp回应 含有ack标记报到客户端。

第三次,四次握手 一次类推。

  • 如图2

拿客户端状态变化为例子。

tcp基于有序字节流传输,客户端发出第一次握手后。

接受数据包的情况:

  1. 客户端接受是: 第二次握手延三次握手合并传输 其中包括 第二次 第三次握手之间传递数据。((场景:tcp延迟确认))

    tcp状态是 ESTABLISHED —-FIN_WAIT_1—>直接进入TIME_WAIT状态. Tcp 默认开启

  2. 客户端接受是: 第二次握手,然后接受是 第三次握手先后传输 tcp状态是(场景:tcp没有延迟确认)

    从FIN_WAIT_1—变成FIN_WAIT_2>成TIME_WAIT

  3. 客户端接受: 第三次握手(场景:双方同时关闭场景)

    从FIN_WAIT_1—>CLOSING状态—>然后TIME_WAIT状态。

  • 总结:从FIN_WAIT_1 状态到 TIME_WAIT有三个情况(第二次握手 和第三次握手传输顺序:先后顺序,合并顺序,提前顺序)

小贴士:

  1. 当用ack fin 描述时候,自己跟不愿意说,感觉难受 不痛快,害怕担心陷入僵局无法调整。

  2. 设计底层原理 我跟不没有掌握 心虚。自己完全彻底吧自己打败了

  3. 然后用第二次握手,第三次握手代替感觉顺畅多了。

第二步骤:发现问题(输入:技术文档 30分钟 百句,输出 :依然不清楚的理解,尝试不着边际的回答)

1. 描述 tcp四次挥手的过程?【从青铜到王者】

#1.1 要点分析: (回答问题回到中岛)

  • 小白回答:就是4个步骤 就是找死。

  • 什么情况tcp层ack延迟发送 和应用层close请求进行合并。

​ - 请问最后一张图最下面,linux三次挥手指的是什么?

#1.2 答:

time_wait 状态变化有三个情况

2个图来说明

客户端状态变化:

ESTABLISHED —-FIN_WAIT_1—FIN_WAIT_2>TIME_WAIT—>CLOSED

ESTABLISHED —-FIN_WAIT_1—>TIME_WAIT—>CLOSED

ESTABLISHED —-FIN_WAIT_1—>CLOSING—>TIME_WAIT—>CLOSED

服务器端状态变化:

ESTABLISHED —->CLOSE_WAIT—>LAST_ACK—->CLOSED

ESTABLISHED —-FIN_WAIT_1—>CLOSING—>TIME_WAIT—>CLOSED

对于关闭TCP_NODELAY,则是应用了Nagle算法。数据只有在写缓存中累积到一定量之后,才会被发送出去,这样明显提高了网络利用率

  • TCP TCP_NODELAY选项与神秘的40ms延迟

  • TCP Delayed ACK 也是基于同样的目的而设计出来的,他的作用就是延迟ACK包的发送,使得协议栈可以合并多个ACK,提高网络利用率

  • TCP_CORK选项与TCP_NODELAY一样,是控制Nagle化的。

    1. 打开TCP_NODELAY选项,则意味着无论数据包是多么的小,都立即发送(不考虑拥塞窗口)。
    2. 就是A块数据的ACK为什么40ms之后才收到?这是因为TCP/IP中不仅仅有nagle算法,还有一个ACK延迟机制 。当Server端收到数据之后,它并不会马上向client端发送ACK,而是会将ACK的发送延迟一段时间(假设为t),它希望在t时间内server端会向client端发送应答数据,
    3. 那么可以通过设置TCP_NODELAY将其禁用
    4. CLOSING

1.3 更新

  1. 关闭tcp连接一定要四次挥手吗?为什么不是三个?
  • RST 强制终止 TCP 连接(SO_LINGER)
  • 当没有数据传输是,ack 和fin小包不同的请求,合并发送(negal算法)
  • 再谈TCP/IP三步握手&四步挥手原理及衍生问题—长文解剖IP

four-way Handshake 四次挥手

https://www.cnblogs.com/figo-cui/p/5137993.html

1

3. 为什么 TIME_WAIT 状态还需要等 2MSL 后才能返回到 CLOSED 状态?

  1. tcp和udp区别?和使用场景 【青铜-王者】

    大小:

    • 首部开销小,仅8字节,适用于实时应用(IP电话、视频会议、直播)

    • 首部最小20字节,最大60字节,适用于要求可靠传输的应

    • tcp 会将应用程序发送的数据分割合适的数据块来字节流传输。

    5 udp的问题

  2. 为什么流量型 都是用udp,不使用tcp ,tcp不能把带宽打满吗

5.1 有什么问题,自己都不知道,然后空白回答 就是pass

为什么流量型 都是用udp,不使用tcp ,tcp不能把带宽打满吗

一面凉 迅雷为什么用udp 答了半天 都不对

区别:

  • 格式大小:(从协议看)tup小。建立连接,

  • 传输数据大小

。而 UDP 继承了 IP 的特性,基于数据报的,一个一个地发,一个

  • 1:对传输

场景:

  • upd 打洞

  • udp flood攻击

  • 不需要一对一沟通,建立连接,而是可以广播的应用,比如 DHCP 协议就是基于 UDP 协议的。

  1. tcp 数据传输过程,如何实现的?

    7.什么tcp 延迟启动 快速重传。流量控制

    8 问:redis cluster节点间采取gossip协议进行通讯 。传递数据数是什么主从复制的数据吗?1主 1从 感觉不需要这么复杂协议吧

9. c++11 新特性

10 模版编译过程:编译器 连接器做了什么事情

小白思考:做了什么我围绕做什么思考,怎么说也说明白,。那些功能,很多东西付过 定义 生命 为市民办

编译器链接生成的符号详解

GCC编译分为四个阶段:

  1、预处理:将代码中的代码中的头文件,宏定义宏选择等进行展开及替换。 gcc -E

g++ -E -std=c++17 3_unique_ptr.cpp -o test.i

  2、编译 :产生汇编文件 。gcc -S

g++ -std=c++17 -S test.i -o test.s

  3、汇编 :将汇编文件编译为目标文件。 gcc -c

g++ -std=c++17 -c test.s -o test.o

  4、链接 :产生可执行文件

g++ -std=c++17 test.o -o test

1
2
3
4
5
6
7
8
https://www.jianshu.com/p/02a5a1bf1096
st=>start: Start
op=>operation: Your Operation
cond=>condition: Yes or No?
e=>end
st->op->cond
cond(yes)->e
cond(no)->op

«««< HEAD

问: 什么是深度拷贝 什么是浅拷贝?

  • 拷贝只是对象拷贝。指针赋值不属于拷贝。
  • 深度拷贝对应值拷贝(stl 容器值拷贝)。浅拷C++编译器默认提供的拷贝方式(memcpy)

为防止HomeForSale对象被拷贝,可以继承Uncopyable类

C++ Boost库:禁止拷贝 nocopyable

What are the advantages of boost::noncopyable

  • 浅拷贝(构造函数)

std:moved()

  • 1
    
    成本:Clone(浅克隆.) > new > Kryo序列化 > Jdk序列化 > Json(各种Json类似)序列化
    

问:函数能返回局部变量吗?

# 第一步:阅读(输入:三天,万句 输出 笔记摘要,记录了但是不懂 )

TCP-IP详解卷1:协议

  1. TCP为什么是四次挥手,而不是三次?

https://www.zhoulujun.cn/html/theory/ComputerScienceTechnology/network/2015_0708_65.html

Redis Cluster采用P2P的Gossip协议进行通信,采用tcp还是udp这个没区别吗?

Gossip协议一般基于UDP实现,其自身即在应用层保证了协议的robustness。

https://maimai.cn/web/gossip_detail?gid=29170876&egid=61b42cdfe2f511eba165246e96b48088

UDP 全称 User Datagram Protocol,即用户数据报协议。

不需要一对一沟通,建立连接,而是可以广播的应用,比如 DHCP 协议就是基于 UDP 协议的。

。而 UDP 继承了 IP 的特性,基于数据报的,一个一个地发,一个

https://blog.csdn.net/weixin_39766014/article/details/111118107

Redis 集群是去中心化的,彼此之间状态同步靠 gossip 协议通信,集群的消息有以下几种类

Redis Cluster Gossip 协议

cluster bus 用的是一种叫gossip 协议的二进制协议,用于节点间高效的数据交换,占用更少的网络带宽和处理时间

元数据1:

将集群元数据集中存储在一个节点上。

典型代表是大数据领域的 storm。

它是分布式的大数据实时计算引擎,是集中式的元数据存储的结构,底层基于 zookeeper对所有元数据进行存储维护。

redis 维护集群元数据采用的是gossip 协议,所有节点都持有一份元数据,不同的节点如果出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更。

  • 优点

元数据的更新比较分散,不是集中在一个地方,降低了压力;

  • 缺点

元数据的更新有延时,可能导致集群中的一些操作会有一些滞后。

gossip 协议包含多种消息,包含 ping、pong、meet、fail等等。

<程序员自我修养> 第2章节。

编译器链接生成的符号详解

  • 编译过程就是把预处理完的文件进行一系列的词法分析、语法分析、语义分析以及优化后产生相应的. 汇编代码文件

  • GCC把预处理和编译两个步骤合并成一个步骤,使用一个叫ccl的程序来完成两个步骤。我们可以直接使用如下命令:

gcc -S test.c -o test.s

test.s: assembler source text, ASCII text

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
wangchuanyi@bogon 2022 % which ld
/usr/bin/ld
wangchuanyi@bogon 2022 % which as
/usr/bin/as
wangchuanyi@bogon 2022 % which cc 
/usr/bin/cc

movl $0x2a, var
 这条指令就是给这个var变量赋值0x2a,相当于C语言中的语句var = 42
  由于在编译目标文件B的时候,编译器并不知道变量var的目标地址,所以编译器在没法确定地址的情况下,将这条mov指令的目标地址设为0,等待链接器在将目标文件A和B链接起来的时候再将其修正

gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求取调用预处理编译程序ccl、汇编器as、链接器ld。

http://blog.chinaunix.net/uid-26430381-id-3842510.html

  • 由于在编译目标文件B的时候,编译器并不知道变量var的目标地址,所以编译器在没法确定地址的情况下,将这条mov指令的目标地址设为0,等待链接器在将目标文件A和B链接起来的时候再将其修正。假设A和B链接后,变量var的地址确定下来为0x1000,那么链接器将会把这个指令的目标地址部分修改成0x10000。这个地址修正的过程也叫做重定位,每个要被修正的地方叫一个重定位入口。