1.2次握手为什么不可以
现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。
原文链接:https://blog.csdn.net/xumin330774233/article/details/14448715
2.redis 有哪些数据结构
Redis有5个基本数据结构,string、list、hash、set和zset
https://juejin.im/post/5b53ee7e5188251aaa2d2e16
3.n个数,每个数不同,求3个数之和为m
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; //数组无序,数组都>0,不重复,3 数之和 m, int main() { int data[10]={1,2,3,4,5,6,7,8,9,10}; int m=10; int n=10; sort(data,data+n); vector< vector<int> > ans; for(int i=0;i<n;i++){ int r=n-1; for(int j=i+1;j<r;){ if(data[i]+data[j]+data[r]<m){ j++; } else if(data[i]+data[j]+data[r]>m){ r--; } else { vector<int> three_; three_.push_back(data[i]); three_.push_back(data[j]); three_.push_back(data[r]); ans.push_back(three_); j++; r--; } } } for(int i=0;i<ans.size();i++){ for(int j=0;j<ans[i].size();j++){ cout<<ans[i][j]<<" "; } cout<<endl; } }
4.数据库,求第100名
select * from student order by score desc limit 100,1; 检索 第101行到101 , 第一个数是指的开始位置,但不包含100 后面是页大小,结果集有一个,
5.golang new 和make 区别
所以从这里可以看的很明白了,二者都是内存的分配(堆上),但是make只用于slice、map以及channel的初始化(非零值);而new用于类型的内存分配,并且内存置为零。所以在我们编写程序的时候,就可以根据自己的需要很好的选择了。
make返回的还是这三个引用类型本身;而new返回的是指向类型的指针
https://www.flysnow.org/2017/10/23/go-new-vs-make.html
6.nginx 惊群效应
惊群简单来说就是多个进程或者线程在等待同一个事件,当事件发生时,所有线程和进程都会被内核唤醒。唤醒后通常只有一个进程获得了该事件并进行处理,其他进程发现获取事件失败后又继续进入了等待状态,在一定程度上降低了系统性能。
nginx如何处理惊群:
前面提到内核解决epoll的惊群效应是比较晚的,因此nginx自身解决了该问题(更准确的说是避免了)。其具体思路是:不让多个进程在同一时间监听接受连接的socket,而是让每个进程轮流监听,这样当有连接过来的时候,就只有一个进程在监听那肯定就没有惊群的问题。具体做法是:利用一把进程间锁,每个进程中都尝试获得这把锁,如果获取成功将监听socket加入wait集合中,并设置超时等待连接到来,没有获得所的进程则将监听socket从wait集合去除。
https://www.jianshu.com/p/21c3e5b99f4a
7.golang 中引用和赋值
map,slice,channel 是传的引用
Go 中函数传参仅有值传递一种方式;
slice、map、channel都是引用类型,但是跟c++的不同;
slice能够通过函数传参后,修改对应的数组值,是因为 slice 内部保存了引用数组的指针,并不是因为引用传递。
https://segmentfault.com/a/1190000015246182