QW大佬面试

1.OSI七层

应用层:所有能和用户交互产生流量的程序

比如说QQ、邮箱、HTTP

表示层:用于处理在两个通信系统中交换信息的表示方式

  1. 数据格式的变换:不同主机能够进程数据的交换
  2. 数据加密和解密:微信支付密码
  3. 数据压缩和恢复

会话层:向表示层提供建立链接并在连接上有序的传输数据

  1. 建立、管理、终止会话
  2. 使用校验点使会话使通信失效的时从校验点恢复通信实现数据同步(适合传输大文件)

主要协议:ADSP,ADP

传输层:负责主机中两个进程的通信,即端到端的通信。

上三层资源子网和下三层通信子网的一个接口,上面三层是端到端的通信,下边三层是点到点的通信(下一步的路径);

 

  1. 可靠传输和不可靠传输
  2. 差错控制
  3. 流量控制
  4. 复用和分用

复用:多个应用层进程可以同时使用下边运输层的服务

分用:运输层把收到的消息分别交付给相应的进程

TCP UDP

网络层:为分组交换网上的不同主机提供通信服务

  1. 路由选择
  2. 流量控制
  3. 差错控制
  4. 拥塞控制

数据链路层:将网络层的数据包组装成帧

SDLC、HDLC、PPP、STP

物理媒体比特流的透明传输

2.非对称加密的应用场景

3.十大排序方法

选择排序、插入排序、冒泡排序、归并排序、快速排序、希尔排序、堆排序、桶排序、基数排序、计数排序

4.数组和链表

5.map和unordered_map

6.deque内存是否连续

deque是双向开口的连续性存储空间。虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,deque自身的机制把这一块一块的存储区虚拟地连在一起。

    它首次插入一个元素,默认会动态分配512字节空间,当这512字节空间用完后,它会再动态分配自己另外的512字节空间,然后虚拟地连在一起。deque的这种设计使得它具有比vector复杂得多的架构、算法和迭代器设计。它的性能损失比之vector,是几个数量级的差别。所以说,deque要慎用。

7.容器适配器,stack,queue

首先我们要知道容器适配器是干啥的。
我们可以简单的将容器适配器当做一个接口装置。有的电脑上没有数据转接口,但是有usb接口,这是我们没必要重新买一个电脑,我们可以做一个usb数据转接线。而这根数据转接线就类似于适配器一样。在C++中,我们已经有了(vector、list、deque等容器)插入、删除、迭代器就电脑usb接口,当我们想要实现栈的操作时,我么没有必要再重新写新的数据结构,只需要将其接口进行重新的封装,相当于做了一根数据转接线。我们就可以将这个容器当做数据结构使用。

C++中定义了3种容器适配器,它们让容器提供的接口变成了我们常用的的3种数据结构,stack(栈)、queue(队列)、priority_queue(优先级对列)

  • 栈:先进后出,我们可以想一下,在STL中,其底层应该一些序列式中容器,能够进行提供push_back(向栈顶插入元素) 、pop_back(删除栈顶元素)序列式容器都可以满足封装成栈的要求。
  • 队列:先进先出。对pop_front(头删)、push_back(尾插)操作的序列式容器的封装,底层不可能是vector。
  • 优先级队列:支持随机访问的功能,所以其底层结构只能为vector或duque。

8.不写析构函数会怎样

内存泄漏:

内存泄露是指:内存泄漏也称作"存储渗漏",用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元。直到程序结束

野指针:

指针被释放时没有置空

防止野指针;置空

写的申请堆区的内存,要释放干净

系统生成的默认析构函数只bai会释放对象本du身所占据的内存,对象通zhi过其他方式如动态dao内存分配(new)和打开文件等方式获得的内存和系统资源是不会被释放的。


如果你自定义了一个,系统就不会生成默认析构函数,而采用你定义的这个。

9.线程池

10.CPU架构、控制器、寄存器、运算器、高速缓存

11.面向对象

封装可以使代码模块化,是把数据和函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全

继承可以扩展已存在的代码,继承允许我们依据另一个类来定义一个类,比如已经定义了一个类A,要定义的下一个类B,在A的基础上增加了成员变量和成员函数,就可以使用继承,达到了重用代码功能和提高执行效率的效果,

多态的目的是为了接口重用,最常见的用法就是声明基类类型的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。因为没有多态性,函数调用的地址将是固定的,这就无法实现“一个接口,多种方法”的目的了。

静态多态:通常通过函数重载实现,函数调用的地址在编译器期间就可以确定函数的调用地址

动态多态:通常通过虚函数实现,虚函数允许派生类重新定义成员函数,而派生类重新定义基类的做法叫覆盖或者重写,函数调用的地址不能在编译器期间确定,必须在运行期间确定,属于晚绑定,也叫动态联编

12.析构函数为什么是虚函数

基类指针可以指向子类的函数,这是多态性,在调用delete删除该指针的时候,就会调用该指针指向的派生类的析构函数,派生类的析构函数又会自动调用基类的析构函数,这样整个的对象就会被释放。如果不写成虚函数,在删除基类指针的时候,只会调用基类的析构函数而不调用派生类的析构函数,从而使得析构不完全

13.析构函数为什么是虚函数

虚函数的调用需要虚函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为虚函数,那么由于对象还未创建,还没有内存空间,更没有虚函数表地址用来调用虚函数即构造函数了

14.举例说一下运行时多态

https://blog.csdn.net/qq_37934101/article/details/81365449

15.面向对象在工程上的应用

16.设计模式,单例模式,工厂模式,分别用在什么场景,其他的一些模式

单例模式:保证整个系统中一个类只有一个对象的实例

应用场景:有的类对象创建和销毁对资源来说消耗不大,但是有的类比较庞大和复杂,如果频繁的创建和销毁对象,并且这些对象完全是可以复用,那么将会造成一些不必要的性能浪费;例如,数据库的访问中,创建数据库的链接对象是一个耗资源的操作,并且数据库链接完全是可以复用的,那么可以将对象设计成单例的,创建一个并且重复使用这个对象就行了

单例模式之饿汉式:单例模式的饿汉式就是在类刚被加载的时候,马上就创建对象

单例模式之懒汉式:实例对象是第一次调用的时候才真正构建的,而不是程序一启动构建好等着调用,这种滞后构建的方式叫做懒加载

因为有的对象构建开销比较大,加入对象在项目启动的时候就构建,万一从来就没有被调用过,那么就浪费了,只有真正使用了才去创建,更加合理

 

 

17.智能指针

share_ptr:允许多个指针指向同一个对象,使用计数对资源管理,当引用计数为0时,没有指针指向该资源,资源会释放;

    unique_ptr:c++11弃用了auto_ptr, 在任何时间点,资源只能唯一地被一个unique_ptr占有。当unique_ptr离开作用域,所包含的资源被释放

auto_ptr: 我们申请了一块内存来放Test对象,并且把他绑定到auto_ptr p上。所以当p离开作用域时,它所指向的内存块也会被自动释放。

weak_ptr: share_ptr虽然已经很好用了,但是有一点share_ptr智能指针还是有内存泄露的情况,当两个对象相互使用一个shared_ptr成员变量指向对方,会造成循环引用,使引用计数失效,从而导致内存泄漏

weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr

18.share_ptr是否是线程安全的

对同一个对象分享所有权的shared_ptr在多个线程上的析构不需要外部加锁保护,C++标准以及标准的实现保证这一动作的线程安全

19.c++11

1.关键字及用法

1.1 autoauto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型

1.2 nullptr:https://blog.csdn.net/qq_18108083/article/details/84346655

C++11加入了nullptr,可以保证在任何情况下都代表空指针

1.3for循环   :  for 循环冒号后还可以放置返回 string 字符串以及容器对象的函数

 

2.STL

2.1ayyay数组   array跟数组并没有太大区别

2.2 forward_list  forward_list为从++新增的线性表,与list区别在于它是单向链表。我们在学习数据结构的时候都知道,链表在对数据进行插入和删除是比顺序存储的线性表有优势,因此在插入和删除操作频繁的应用场景中,使用listforward_list比使用arrayvectordeque效率要高很多

2.3unordered_map std::unordered_mapstd::map用法基本差不多,但STL在内部实现上有很大不同,std::map使用的数据结构为二叉树,而std::unordered_map内部是哈希表的实现方式,哈希map理论上查找效率为O(1)。但在存储效率上,哈希map需要增加哈希表的内存开销。

2.4unordered_set std::unordered_set的数据存储结构也是哈希表的方式结构,除此之外,std::unordered_set在插入时不会自动排序,这都是std::set表现不同的地方

3.多线程 thread

4.智能指针

20.epoll LT ET模式

LT:水平触发

ET:边缘触发

相同点:都是通过epollwait从EPOLL等待队列读取激活事件

区别:

LT模式读取激活事件后,如果还有未处理的数据。事件会重新放入EPOLL等待队列

ET模式读取激活事件,直接从EPOLL等待队列移除,不管是否有未处理的数据

 

Level_triggered(水平触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据一次性全部读写完(如读写缓冲区太小),那么下次调用 epoll_wait()时,它还会通知你在上没读写完的文件描述符上继续读写,当然如果你一直不去读写,它会一直通知你!!!如果系统中有大量你不需要读写的就绪文件描述符,而它们每次都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率。

 

Edge_triggered(边缘触发):当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符

 

非阻塞IO:当你去读写一个非阻塞的文件描述符时,不管可不可以读写,它都会立即返回,返回成功说明读写操作完成了,返回失败会设置相应errno状态码,根据这个errno可以进一步执行其他处理。它不会像阻塞IO那样,卡在那里不动

21.linux下内存管理,线性地址,逻辑地址,物理地址是什么关系,如何映射的

  CPU将一个逻辑地址转换为物理地址,需要进行两步:首先将给定一个逻辑地址(其实是段内偏移量,这个一定要理解!!!),CPU要利用其段式内存管理单元,先将为个逻辑地址转换成一个线程地址,再利用其页式内存管理单元,转换为最终物理地址

22.linux命令,sedawk

Linux sed 命令是利用脚本来处理文本文件

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具

 

字节跳动客户端:

1.TCP三次握手和四次挥手,为什么是四次

为什么是四次,因为TCP是全双工的,当服务器收到客户端的FIN报文的时候,仅仅是因为客户端没有数据发送了,但是服务端还有可能有数据发送,所以先送一个ACK确认报文,等待服务端发送完数据之后,在发送FIN报文表示关闭连接,这里的FIN报文和ACK报文是分开发送的,所以是四次挥手

2.time_wait存在的意义

1.为了保证客户端发送的最后一个报文能够到到服务端,这个ACK有可能丢失,导致服务端大收不到ACK报文,这时客户端会超时重传这个FIN+ACK报文,重新启动这个2MSL计时器,服务端收到ACK报文,使得两方都正常关闭;如果不等待time_wait直接关闭,丢失之后会使得服务端无法正常关闭

2.在上述情况中,加入第一个报文并没有丢失,而是在网络节点中停留了很长的时间之后,以至于延误了一会才大到达B,这时本来是已失效的报文段,但是B并不知道,就会重新建一次链接,等待的2MSL就是为了结局这个问题的,A在发送完ACK后,在等待2MSL之后就会使得本链接持续时间内所有的报文段消失,这样就可以使得下一个新的连接中不会出现旧的链接请求。

3.为什么是三次握手不能是两次

1)如果是两次握手,在服务端发送确认报文后,服务端就已经准备好了,可以理解为服务端认为自己能发也能收,客户端没有收到服务端的确认报文就不知道服务端是不是连接好了,这种连接是不可靠的;

如果是三次链接的话,客户端发送ACK给客户端,客户端就知道服务端收到了自己的消息,自己的发送服务端能收到。即使第三次握手中客户端发的确认ack丢失,服务端在没有接收到ack报文的情况下会重新进行第二次握手,也就是会重新进行发送SYN报文段,客户端重新发送ACK报文,这样建立的连接才是可靠的

2)防止已经失效的请求链接报文段,突然传送到了服务端,产生错误;加入采用两次握手,失效的链接请求报文段突然发送到了服务端,服务端只有发出确认,链接就建立了,由于client没有发出请求,自然不会理睬,但是服务端却认为新的连接已经建立,一直等待client发送来资源,这样server很多情况就白白浪费掉了;

4.Cookie和session区别,Cookie怎么保存个人信息

Cookie是存储在用户主机的文本文件,用来记录用户在一段时间内访问记录,是用户客户端计算机暂时保存或者永久保存的信息;

Session和Cookie的效果相同,只不过一个是保存在服务端,一个是保存在客户端

Cookie保存个人信息的原理:

网络服务器用HTTP向客户端发送cookis,在客户终端,浏览器解析这次cookies并把它们保存为一个本地文件,它们会自动将同一服务器的任何请求附上这些cookies;

Cookies,Session,token

cookie session

作用,版本,创建,类型,属性,安全

  • 作用

HTTP  cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一个服务器的时候被携带发送到服务器上,通常,他用于告知服务端两个请求是否来自同一个浏览器,如保持用户的登录状态

  1. 会话状态的管理(登录状态)
  2. 个性化设置(用户个性化设置)
  3. 浏览器行为跟踪(分析用户行为)
  • 类型

会话期Cookie

持久性Cookie

第三方Cookie

Session:

主要是同步问题:

服务器很多,session保存在某一台上边 

web server1         web server2        web server3

    session

下一次访问werver2,但是没有seeion就要重新登录,解决办法

1)session复制,把sessio都复制一份,但是服务器很多,不可取

2)客户端保存,Cookie大小有限制

3)  固定用户发送到哪一台服务器

    1)ip hash 只要用户的IP没有变 则可以访问同一台

    2)业务数据    hash   用户userid等等信息 来分配服务器

4)共享存储  性能损耗大 多了一层业务

      把session放在数据库存储比如 redis(session)

5.HTTP/HTTPS

HTTP

超文本传输协议,一种基于请求和响应的,无状态的,应用层的协议,常基于TCP/IP协议,互联网上最广泛的一种应用协议,所有的www文件都必须遵守这个标准,设计HTTP的目的是为了提供一种发送和接收HTML的方法。


版本:

0.9:不涉及数据包传输,规定客户端和服务端之间通信格式,只能使用get请求     没有作为正式的标准

1.0:传输内容格式不限制,PUT、PATCH、HEAD、OPTIONS                              正式作为标准

1.1:持续链接,节约带宽,HOST域,管道传输,分块传输,编码                         使用最广泛

2   :多路、服务端推送、头信息压缩、二进制协议                                                 逐渐应用广泛

 

多路复用:同一时间发送多个请求,并且响应回来

HTTP:

无状态:对事物处理没有记忆能力,前后的请求没有联系,如果写一次的请求用到了上一次的信息,则它必须重传。而且没有任何的状态显示当前是第几次请求。

无连接:每一次请求完都是断开的,采用这种方式可以节省传输时间。

这样造成的优点是:简单、快速和灵活

缺点是:一直明文,请求和相应不会对通信方进行确认,无法保护数据的完整性;

 

HTTPS:

1.内容是加密的:采用混合加密技术,中间无法查看报文内容

2.验证身份:通过证书 认证客户端访问的是自己的服务器

3.保护数据完整性:防止传输过程中中间者冒充和篡改

6.HTTP1.0和HTTP1.1有哪些区别

7.HTTP都有那些头,幂等性

HTTP GET方法用于获取资源,不应有副作用,所以是幂等的。比如:GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是一次和N次具有相同的副作用,而不是每次GET的结果相同。GET http://www.news.com/latest-news这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的

8.HTTP请求方法

HTTP1.0定义了三种请求方法     GET, POST 和 HEAD方法。

HTTP1.1定义了六种请求方法     OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 

9.数据库隔离级别

 

 

 

网易互娱sp后端

1.tcp三次握手和四次回收的过程,四次挥手的time-wait

2.两次握手会怎么样

(1)如果是两次握手,在服务端发送确认报文后,服务端就已经准备好了,可以理解为服务端认为自己能发也能收,客户端没有收到服务端的确认报文就不知道服务端是不是连接好了,这种连接是不可靠的;

如果是三次链接的话,客户端发送ACK给客户端,客户端就知道服务端收到了自己的消息,自己的发送服务端能收到。即使第三次握手中客户端发的确认ack丢失,服务端在没有接收到ack报文的情况下会重新进行第二次握手,也就是会重新进行发送SYN报文段,客户端重新发送ACK报文,这样建立的连接才是可靠的

(2)因为需要考虑连接时丢包的问题,如果只握手2次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数(可以理解服务端已经连接成功)据,而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了(可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。

如果是三次握手,即便发生丢包也不会有问题,比如如果第三次握手客户端发的确认ack报文丢失,服务端在一段时间内没有收到确认ack报文的话就会重新进行第二次握手,也就是服务端会重发SYN报文段,客户端收到重发的报文段后会再次给服务端发送确认ack报文。

3.TCP的定时器

4.TCP和UDP区别

5.TCP的首部字段

6.http和https区别

7.http的状态码

8.HTTPS通信过程

1.HTTP/HTTPS

HTTP:

无状态:对事物处理没有记忆能力,前后的请求没有联系,如果写一次的请求用到了上一次的信息,则它必须重传。而且没有任何的状态显示当前是第几次请求。

无连接:每一次请求完都是断开的,采用这种方式可以节省传输时间。

这样造成的优点是:简单、快速和灵活

缺点是:一直明文,请求和相应不会对通信方进行确认,无法保护数据的完整性;

HTTPS简单来说HTTP的安全版,在HTTP下加了SSL层,HTTPS不同于HTTP的默认端口及一个加密/身份验证层

众所周知,WEB服务存在http和https两种通信方式,

http使用80为通信端口,对于传输采用不加密的方式;

https对传输的数据进行加密,目前主流的网站基本开始默认采用HTTPS作为通信方式

2.对称加密

对称加密算法的加密和解密都是同一个密钥;

如果通信双方都使用同一个密钥,且没有别人知道,那么两房的安全是可以被保证的(除非密钥被破解)

但是最大问题就是如何使得这个密钥让通信双方知晓,同时又不被别人知道,如果一方生成了一个密钥传输过去,传输的过程有可能被破解

如果浏览器预存了网站A的密钥,就可以确保不会有外部的人知道密钥,浏览器预存所有HTTPS网站的密钥是不现实的

3.非对称加密

解决对称密钥的方法是非对称密钥,非对称加密算法,需要一组密钥对,分别是私钥和密钥。这两个是成对出现的,公钥加密的内容需要对应的私钥解密,私钥加密的内容需要对应的公钥解密。私钥由服务器自己保存,公钥发送给客户端,客户端拿到公钥后进行加密发送给服务端,这时就算中间被截获,没有私钥也无法获取内容,这就保证了客户端发送到服务器数据的安全

4.非对称加密改良方案

通过一组公告密钥,已经可以保证的那个方向传输的安全性,那用两组公告私钥,是不是就能保证双向传输的安全;

流程:

  • 1. 某网站拥有非对称加密的公钥A1,私钥A2;浏览器拥有用于非对称加密的公钥B1、私钥B2;
  • 2. 浏览器向网站服务器请求,服务器把公钥传输给浏览器
  • 3. 浏览器把公钥B1明文传输给服务器
  • 4. 之后浏览器向服务器传输的信息都用A1加密,服务器收到后用私钥A2解密。由于只有服务器拥有私钥A2进行解密,所以能保证这条数据的安全。
  • 5. 服务器向浏览器传输的所有东西都用公钥B1加密,浏览器收到后用私钥B2解密。同上也可以保证这条数据的安全。

5.非对称加密 + 对称加密

用非对称密钥传输对称密钥,再用对称密钥加密,对称密钥解密

  1. 某网站拥有用于非对称加密的公钥A1、私钥A2。
  2. 浏览器向网站服务器请求,服务器把公钥A1明文给传输浏览器。
  3. 浏览器随机生成一个用于对称加密的密钥X,用公钥A1加密后传给服务器。
  4. 服务器拿到后用私钥A2解密得到密钥X。
  5. 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都用密钥X加密解密即可。

但是还是有漏洞的,中间人攻击

5.中间人攻击

中间人却完全不需要拿到私钥A2就能劫持信息

  1. 某网站拥有用于非对称加密的公钥A1、私钥A2。
  2. 浏览器向网站服务器请求,服务器把公钥A1明文传输给浏览器。
  3. 中间人劫持到公钥A1,保存下来,把数据包中的公钥A1替换成自己伪造的公钥B1(它当然也拥有公钥B1对应的私钥B2)。
  4. 浏览器随机生成一个用于对称加密的密钥X,用公钥B1(浏览器不知道公钥被替换了)加密后传给服务器。
  5. 中间人劫持后用私钥B2解密得到密钥X,再用公钥A1加密后传给服务器。
  6. 服务器拿到后用私钥A2解密得到密钥X。

这样在双方都不会发现异常的情况下,中间人得到了对称密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。那么下一步就是解决这个问题:如何证明浏览器收到的公钥一定是该网站的公钥?

6.数字证书

现实生活中,如果想证明某身份证号一定是小明的,怎么办?看身份证。这里政府机构起到了“公信”的作用,身份证是由它颁发的,它本身的权威可以对一个人的身份信息作出证明。互联网中也有这么一个公信机构,CA 机构。

网站在使用HTTPS前,需要向“CA机构”申请颁发一数字证书,数字证书里有证书持有者、证书持有者的公钥等信息。服务器把证书传输给浏览器,浏览器从证书里取公钥就可以了。然而这里又有一个显而易见的问题:证书本身的传输过程中,如何防止被篡改?即如何证明证书本身的真实性?数字证书怎么防伪呢?

7.数字签名

我们把证书内容生成一份“签名”,比对证书内容和签名是否一致就能察觉是否被篡改。这种技术就叫数字签名。

8.HTTPS工作原理

  1. client向server发送请求https://baidu.com,然后连接到server的443端口。

  2. 服务端必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。

  3. 传送证书
    这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间、服务端的公钥,第三方证书认证机构(CA)的签名,服务端的域名信息等内容。

  4. 客户端解析证书
    这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随机值(密钥)。然后用证书对该随机值进行加密。

  5. 传送加密信息
    这部分传送的是用证书加密后的密钥(随机值),目的就是让服务端得到这个密钥(随机值),以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

  6. 服务端加密信息
    服务端用私钥解密,得到了客户端传过来的密钥(随机值),然后把内容通过该值进行对称加密。

  7. 传输加密后的信息
    这部分信息是服务端用密钥(随机值)对称加密后的信息,可以在客户端被还原。

  8. 客户端解密信息
    客户端用之前生成的密钥(随机值)解密服务端传过来的信息,于是获取了解密后的内容。

SSL标准化之后就改名为TLS

9.HTTP工作原理

HTTP

9.mysql存储引擎

10.索引结构用什么实现的?使用B+树的好处

 

11.红黑树

自平衡的二叉查找树

重要的四个性质:

  • 每个结点不是红色就是黑色
  • 不可能有连在一起的红色节点
  • 根节点都是黑色 (根节点 :没有父节点 ,没有入度)
  • 每个红色结点的两个子节点都是黑色,叶子结点都是黑色:

面讲到红黑树能自平衡,它靠的是什么?三种操作:左旋、右旋和变色。

  • 左旋:以某个结点作为支点(旋转结点),其右子结点变为旋转结点的父结点,右子结点的左子结点变为旋转结点的右子结点,左子结点保持不变。如图3。
  • 右旋:以某个结点作为支点(旋转结点),其左子结点变为旋转结点的父结点,左子结点的右子结点变为旋转结点的左子结点,右子结点保持不变。如图4。
  • 变色:结点的颜色由红变黑或由黑变红。

数据库:

 
  1. select * from user where user_id =100

  2. select * from user where user_id<100 and user_id ?=500

  3. select * from user where user_id =100 and name ='赵云'组合

sql是数据库,sq语句究竟是怎么运行的?怎么去查找的?设计查找算法

目录查找:类似索引

键查找:hash查找

遍历:暴力

二分:就是B+树的基础算法

能做索引的数据结构:数组,链表,哈希,B树,B树(B-树,B+树)

红黑树做数据库存储的时候:缺点

1.读取磁盘数据次数过多

2.读取浪费

红黑树为什么可以用来hashmap:内存

改良方案:B树(B-tree,B+tree,B*Tree)

12.B-树

 

13.B+树的优点

  1. B+树的磁盘读写代价更低
    B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说I/O读写次数也就降低了。

  2. B+树的查询效率更加稳定
    由于内部结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

  3. B+树更有利于对数据库的扫描
    B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题,而B+树只需要遍历叶子节点就可以解决对全部关键字信息的扫描,所以对于数据库中频繁使用的range query,B+树有着更高的性能。

14.非可抢占式和抢占式进程调度的区别是什么?

15.事务的隔离级别,如何使用MVCC结局不可重复的问题

 

16.mysql锁

17.I/O多路复用

18.c++虚函数和纯虚函数

定义一个函数为虚函数,不代表函数为不被实现的函数。定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。

定义一个函数为纯虚函数,才代表函数没有被实现。定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数

19.python装饰器了解吗?都用python做什么

 

 

虾皮后端:

一个关于计算机网路讲的比较好的链接

1.tcp三次握手,四次挥手,能不能减少次数

流程

资料

为什么不能2次握手?

如果是两次握手,在服务端发送确认报文后,服务端就已经准备好了,可以理解为服务端认为自己能发也能收,客户端没有收到服务端的确认报文就不知道服务端是不是连接好了,这种连接是不可靠的;

如果是三次链接的话,客户端发送ACK给客户端,客户端就知道服务端收到了自己的消息,自己的发送服务端能收到。即使第三次握手中客户端发的确认ack丢失,服务端在没有接收到ack报文的情况下会重新进行第二次握手,也就是会重新进行发送SYN报文段,客户端重新发送ACK报文,这样建立的连接才是可靠的

2.TCP怎么保证可靠连接

确保可靠连接的机制:校验和、序列号和确认应答、超时重传、连接管理、流量控制、拥塞控制

(1)校验和:在数据传输的过程中,将发送的数据都当做一个16位的整数。这些整数加起来,并且前边的进位不能丢弃,补在后边,最后取反,得到校验和;

https://blog.csdn.net/a_tu_/article/details/84840592

发送方:在发送数据之前计算校验和,并进行校验和的填充

接收方:收到数据后,对数据以同样的方式计算,求出校验和

(2)确认应答和序列号

序列号:TCP传输的时候对每个字节都进行了编号

确认应答:TCP传输的过程中,接收方收到数据后,都要对传输方进行确认应答,也就是发送ACK报文,这个ACK报文中带有相应的确认序列号,告诉发送方,接收到了哪些数据;

(3)超时重传

发送方在发送完数据后等待一个时间,时间到达没有接收到ACK报文,那么对刚才的数据重新发送;

(4)连接管理

三次握手和四次挥手

(5)流量控制(滑动窗口)

通信过程中,发送方根据接收缓冲的大小,来动态的调整发送数据;

在TCP协议的报头信息中,有一个16字段的窗口大小,窗口的大小是接收端接收数据缓冲区的大小,这个数据越大,网络的吞吐量越大。接收端在确认应答发送ACK报文时,将自己的即时窗口大小填入,并跟随ACK报文一起发送过去,发送方根据ACK窗口的值改变自己的发送速度,如果接收到窗口的值是0,那么就停止发送数据,并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端;

这里写图片描述

注:16位的窗口大小最大能表示65535个字节(64K),但是TCP的窗口大小最大并不是64K。在TCP首部中40个字节的选项中还包含了一个窗口扩大因子M,实际的窗口大小就是16为窗口字段的值左移M位。每移一位,扩大两倍。

(6)拥塞控制

TCP的四种拥塞避免算法:

在这里插入图片描述

慢启动、拥塞避免、快重传、快恢复

慢启动是指一开始发送数据的时候发送数据以指数数据增长,增长的速度非常快,为了控制增长的速度,设置一个拥塞窗口,到达拥塞窗口的时候按线性规律增长,一旦发生拥塞,一方面将慢启动门限减少为当前拥塞窗口的一半,另一方面拥塞重置为1;重新开启慢启动算法,按指数规律增长,到达新的拥塞门限时,使用拥塞避免算法,当接收方收到三个重复确认时,就知道网络发生了拥塞,转而进行快重传和快恢复,也就是更新慢开始门限为当前拥塞窗口cwnd的一半,并将拥塞窗口cwnd置为新的慢开始门限值,转而执行避免算法。

3.TCP和UDP的区别

TCP是面向连接的,可靠的字节服务,即客户和服务端在交换数据前,必须双方建立一个TCP链接,之后才能传输数据,并且提供差错校验、序列号和应答确认、超时重传、流量控制等功能,确保建立一个可靠的链接。

UDP是一个无连接的,面向报文的尽最大努力交付的传输协议,不需要建立连接,也不需要保证他们能到达目的地,不需要确认回复,所以传输速度很快。

4.滑动窗口

TCP使用滑动窗口实现流量控制

5.ACID

MySQL 事务主要用于处理操作量大,复杂度高的数据;一般来说事物必须满足四个条件(ACID)

  • 原子性:一个事物的所有操作,要么全部完成,要么全部不完成,不能结束在中间某个环节
  • 一致性:在事务开始之前和事物结束之后,数据库的完整性没有被破坏。
  • 隔离性:数据库允许多个并发事物同时对数据进行读写和修改的能力
  • 持久性:事务结束后,对数据的修改是永久的,即便系统故障也不会消失

6.数据库脏读、事务的四大特性、四大隔离级别、三大范式

7.进程和线程的区别

进程是资源调度和分配的基本单位,线程是基本的cpu执行单元,也是程序执行流的最小单位,引入线程之后,进程之间可以并发的执行,线程之间也可以并发的执行,进一步提高了系统的并发度;

进程有自己的独立的地址空间,每启动一个进程,都为为其分配地址空间,建立PCB,数据段和程序段;线程没有独立的地址空间,同一个进程共享线程的地址空间;

一个进程下边可以有多个线程,但是一个线程只能属于一个进程,同一个进程线程的切换不会影响进程的切换,但是由一个进程的线程切换到另一个进程的线程会引起进程的切换;

进程之间切换资源消耗大,线程之前切换资源消耗小

8.进程之间的通信

共享存储、管道通信、消息队列

共享存储;在通信的进程之间存在一块可以直接访问的共享内存,通过对这块共享内存的读写可以进行信息的交换,两个进程对共享空间的访问必须是互斥的,操作系统只提供共享空间和同步互斥工具;共享存储分为两种,基于数据结构的存储,基于存储区的共享,基于存储区的共享可以在存储区放置一块数据,不由操作系统控制,而由进程控制,属于比较高级的通信方式。

管道通信:管道其实就是用来连接读写进程的一个共享文件,又名pipe文件;其实就是在内存中开辟大小一定的缓冲区。对管道的访问必须是互斥的,数据以字符流的形式写入管道,读进程必须等待写进程将管道写满,才可以读,写进程必须等待读进程数据取走为空,才可以写;

消息队列:进程之间的消息,以格式化的消息为单位,进程通过“发送消息/接收消息”原语进行数据交换。消息头包括:发送进程ID,接受进程ID、消息类型、消息长度等格式化的信息(计算机报文其实就是一种格式化的信息)

消息队列分为两种:直接通信方式,消息直接挂到接收进程的消息缓冲队列上;间接通信方式:消息先发送到中间实体(信箱),中,因此也称为“信箱通信方式”

线程之间的通信

1.锁机制

        1.1互斥锁:共享资源的使用是互斥的,即一个线程获得资源的使用权后就会将改资源加锁,使用完后会将其解锁,所以在使用过程中有其它线程想要获取该资源的锁,那么它就会被阻塞陷入睡眠状态,直到该资源被解锁才会别唤醒,如果被阻塞的资源不止一个,那么它们都会被唤醒,但是获得资源使用权的是第一个被唤醒的线程,其它线程又陷入沉睡。

        1.2读写锁:读写锁分为读锁和写锁,如果处于写状态锁下,任何获得锁的线程都会被阻塞,知道写状态锁被释放,但是如果是读状态下,允许其他线程获得读锁,但是不允许获得写锁,当读写锁感知到有线程想获得写状态锁时,就阻塞读状态锁的线程,所以读写锁飞非常适用于资源的读操作多于写操作的情况。

        1.3条件变量:

        1.4递归锁:一个线程可以多次获得锁,别的线程必须等待该线程释放所有次数的锁才能获得

        1.5自旋锁:特殊的互斥锁,当资源被加载后,其他线程想要再次加锁,此时该线程不会被阻塞睡眠而是陷入循环等待状态(不能再做其它事情),循环检查资源持有者是否已经释放了资源,这样做的好处是减少了线程从睡眠到唤醒的资源消耗,但会一直占用CPU资源。适用于资源的锁被持有的时间短,而不希望在线程的唤醒上花费太多资源的情况。

9.数组和链表的区别

数组是连续存储的,保存数据的个数和空间一开始就是指定的,数据操作的时间复杂度:访问第n个数据的时间复杂度为O(1)

查找指定数据的时间复杂度是O(N)

数组中插入或者删除数据的时间复杂度(与N有关)最好是O(1)最坏是O(N)

链表是非连续的存储单元保存数据,内存中的数据可以是连续的也可以是不连续的,一般是不连续的,插入和删除比较方便,访问和查找指定数据的时间复杂度是O(N),插入和删除的时间复杂度是O(1)

常见分类有单向链表,双向链表,循环链表

10.HTTP,HTTP和HTTPS的区别

HTTP超文本传输协议,一种发布和接收html页面的方法,被用在web浏览器和网站服务器之间传递信息。

区别:

HTTP以明文形式发送内容,不提供任何形式的数据加密,如果攻击者截取了传输报文,就可以直接读懂其中的信息,因此不适合传输一些敏感信息,比如银行卡号,密码支付信息

HTTPS是一种透过计算机网络来进行安全通信的传输协议,HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包,HTTPS开发的主要目的是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。

端口一个是8.0;一个是443

11.HTTP1.0和HTTP1.1的区别,http1.0怎么保持长链接

https://blog.csdn.net/u012813201/article/details/70211255

12.数据库的索引有了解吗?他的应用场景

逻辑角度:

  • 普通索引:最普通的索引,没有任何限制,允许在定义索引的列中插入重复值和空值
  • 唯一索引:索引列的值必须唯一,允许有空值
  • 主键索引:一个表只能只能有一个索引,不允许有空值
  • 组合索引:全文索引

13.索引有哪些数据结构

数据库索引的两个数据结构:B树索引和Hash索引

数据库索引背后的数据结构

14.数据库之中的锁

悲观锁:每次那数据都认为别人会修改,每次拿数据都会上锁,任何去数据的操作都会被阻塞(block)

按使用性质分类:

  • 共享锁
  • 排它锁
  • 更新锁

按作用范围分类:

  • 行锁
  • 表锁

乐观锁:每次去拿数据的时候都认为别人不会修改,所以,不会上锁,但是在更新的时候会判断一下在此期间别人有没有更新这个数据;

 

虾皮面经1:

1.哈希表怎么实现,冲突怎么解决

构建方法:

  • (1)直接定址:取关键字的某个线性函数为散列地址:f(key)= a*key+b
  • (2)数字分析:比如手机号,对几位数字抽取获得关键字,为了避免冲突,还可以进行翻转位移等等
  • (3)平方取中:比如1234,平方是1522756,取中间的三位作为散列地址
  • (4)折叠法:关键字分为三组,相加,再求后三位得散列地址为962
  • (5)除数留余:f(key) =  key mod p(p≤m)
  • (6)取关键字的随机数,作为散列地址,f(key) = random(key)

冲突解决:

  • (1)开放定址:一旦发生了冲突,就去寻找下一个空间的散列地址,只要散列表足够大,总会有空的地址

f1(key) = (f(key)+di)mod m

  • (2)再散列:多准备几个散列函数

(3)链地址法:将所有的哈希地址为I的元素构成一个称为同义词的单链表,并将单链表的头指针存在哈希表的第i个单元中,插入、删除和修改都在同一链表中

  • (4)建立公共溢出区,一个基本表和一个溢出表、溢出表存发生冲突的数据

2.如何从1000w个数据中选取1000最大的数

取出1000个数字维护一个小顶堆、顺序读取后续元素,如果比当前堆顶元素小,直接丢弃,比堆顶元素大,放进去堆

3.快速排序的时间复杂度是多少,简要说一下过程

十大排序算法时间复杂度

快排的时间复杂度是O(nlogn)

快排的基本思想:

  • 1.数列中选取第一个数字作为基准数
  • 2.分区过程,将比这个数小的数都放在基准数的左边,比这个数大的数都放在基准数的右边
  • 3.再对左右区间走相同的过程

快排代码:

4.B+树相对B树的区别

1.为什么需要B树

传统的平衡二叉树有很多,这些树在一般情况下查询性能非常好,但是数据非常大的时候,大部分数据放在磁盘上,非常耗时,如何提高访问效率,减少磁盘IO次数,提出了B树

第一次在第一层做一次IO,第二次在第二层找到了60

2.有了B树,为什么还需要B+树

B+树是B树的一个变种、它与B-树的主要的不同在于:

  • 在B+树中,key的副本存储在内部结点、真正的key和data存储在叶子结点上
  • n个key值的节点的节点指针域为n而不是n+1 (所有的数据都在叶子结点上)

上两层只是提供区间的划分

3.B树和B+树的区别?

  • B+树内部结点不存储数据,时间复杂度为log(n),B树不固定,时间复杂度最好为O(1),根节点拿到了
  • B+树叶结点两两相连大大增加区间访问性,可使用在范围查询,而B树每个节点key和data在一起,则无法区间查找

  • B+树内部无数据,每个节点能索引的范围更大更准确

  • 在数据结构上,B树为有序数组+平衡多叉树,而B+树为有序数组链表+平衡多叉树(可省略)

4.mysql使用B+树,mongoDB使用B树

因为mysql是一种关系型数据库,区间访问是最常见的一种情况,而B+树的数据全部存在叶子节点并且通过指针串在一起,这样就很统御进行区间遍历甚至全部遍历

 

5.聚簇索引和非聚簇索引

 

关系型数据库和非关系型数据库

(事务具有4个特征,分别是原子性、一致性、隔离性和持久性,简称事务的ACID特性)

 

关系型数据库的一大特性就是事务的一致性:具有ACID的特点,这个特性使得关系型数据库可以用于几乎所有对一致性有要求的系统中,

非关系型数据库:指非关系型的,分布式的,且一般不保证遵循ACID原则的数据存储系统

非关系型数据库以键值对存储,且结构不固定,每一个元组可以有不一样的字段,每个元组可以根据需要增加一些自己的键值对,不局限于固定的结构,可以减少一些时间和空间的开销

6.MVCC知道吗

数据库并发控制

7.数据库的log有哪些类型

    1.查询日志

    2.慢查询日志

    3.错误日志

    4.二进制日志

    5.中继日志

    6.事务日志

8.事务在什么场景下使用,有什么特性

MySQL 事务主要用于处理操作量大,复杂度高的数据。是用户定义的一系列SQL语句的操作,这些操作要么完全执行,要么完全不执行,他是一个不可分割的工作执行单元。

事务的使用场景:比如说,在人员管理系统中,你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

特性:

  • 原子性:一个事务的所有操作,要么完全执行,要么完全不执行,不会中间结束在某个环节
  • 一致性:一个事务在执行前和执行后,都处于一个状态
  • 隔离性:一个事务未提交的结果是否对其他业务可见:级别一般有  读未提交、读提交、可重复读、幻读
  • 持久性:一个事物一旦提交了,那么对数据库的改变就是永久的、即便是在数据库系统遇到故障了也不会丢失提交事务的操作

9.四种隔离特性,什么是读取未提交???

  • 读未提交:一个事务可以读取另一个未提交事务的数据,读未提交是最低的隔离级别,会造成脏读

脏读:一个事务正在对一个记录做修改,还没有提交,但是另一个事务却读取了这条没有提交的数据,并据此做进一步的处理,这叫脏读

举例:

公司发工资了,领导把5000元打到singo的账号上,但是该事务并未提交,而singo正好去查看账户,发现工资已经到账,是5000元整,非常高兴。可是不幸的是,领导发现发给singo的工资金额不对,是2000元,于是迅速回滚了事务,修改金额后,将事务提交,最后singo实际的工资只有2000元,singo空欢喜一场。

出现上述情况,即我们所说的脏读,两个并发的事务,“事务A:领导给singo发工资”、“事务B:singo查询工资账户”,事务B读取了事务A尚未提交的数据。

  • 读提交:只能读取已经提交过事务的数据,这个过程可以防止脏读的发生,但是不能防止可重复读和幻读的发生

不可重复读:一个事物先后读取同一条记录,而事务在两次读取之间数据却被其他数据修改,造成了两次读取的数据不同,不可重复读

举例:

singo拿着工资卡去消费,系统读取到卡里确实有2000元,而此时她的老婆也正好在网上转账,把singo工资卡的2000元转到另一账户,并在singo之前提交了事务,当singo扣款时,系统检查到singo的工资卡已经没有钱,扣款失败,singo十分纳闷,明明卡里有钱,为何......

先查后消费,中间被老婆修改,两次读取到了不同的结果

  • 重复读:在读取数据的开始的时候,不允许任何修改操作,可以防止脏读和可重复读,但是不能防止幻读

幻读:一个事务按照相同的查询条件重新读取以前操作过的数据,却发现其他事物插入了满足其条件的其他数据

举例:

singo的老婆工作在银行部门,她时常通过银行内部系统查看singo的信用卡消费记录。有一天,她正在查询到singo当月信用卡的总消费金额(select sum(amount) from transaction where month = 本月)为80元,而singo此时正好在外面胡吃海塞后在收银台买单,消费1000元,即新增了一条1000元的消费记录(insert transaction ... ),并提交了事务,随后singo的老婆将singo当月信用卡消费的明细打印到A4纸上,却发现消费总额为1080元,singo的老婆很诧异,以为出现了幻觉,幻读就这样产生了。

MySQL的默认隔离级别就是Repeatable read

  • 序列化:

是最高的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。

 

大多数数据库默认的事务隔离级别是Read committed,比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read。

10、TCP和UDP

都是传输层协议

TCP提供的面向链接的,可靠的字节流服务,客户和服务器交换数据前,必须先在双方建立一个TCP链接,之后才能传毒数据,并提供了超时重传、流量控制、可靠连接等机制,保证数据能从一端传到另外一端

UDP:是一个简单的面向数据包的传输层协议,不提供可靠性、只是把应用程序传给IP层的数据包发送出去、但是不能保证他们能到达目的地、由于不建立链接,所以传输速度快

11.TCP的一些可靠机制

可靠传输机制

12.挥手的过程.time_wait

13.get和post的区别

 

1、GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改、增加数据,不会影响资源的内容,即该请求不会产生副作用。无论进行多少次操作,结果都是一样的。

2、PUT请求是向服务器端发送数据的(与GET不同)从而改变信息,该请求就像数据库的update操作一样,用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同。

3、POST请求同PUT请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的insert操作一样,会创建新的内容。几乎目前所有的提交操作都是用POST请求的。

4、DELETE请求顾名思义,就是用来删除某一个资源的,该请求就像数据库的delete操作。

 就像前面所讲的一样,既然PUT和POST操作都是向服务器端发送数据的,那么两者有什么区别呢。。。POST主要作用在一个集合资源之上的(url),而PUT主要作用在一个具体资源之上的(url/xxx),通俗一下讲就是,如URL可以在客户端确定,那么可使用PUT,否则用POST。

综上所述,我们可理解为以下:

1、POST    /url      创建  
2、DELETE  /url/xxx  删除  
3、PUT     /url/xxx  更新
4、GET     /url/xxx  查看

14.head请求

类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头

connect    连接改为管道方式的代理服务器

options    允许客户端查看服务器的性能

trace        回显服务器收到的请求、主要用于测试或者诊断

patch      是对put方法的补充、用来对已知资源进行局部更新

15.https解决了什么问题

信息被劫持的问题

https://blog.csdn.net/ThinkWon/article/details/104903925?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

16.进程、线程、协程,协程在哪个语言实现了???

python协程:一个线程就是执行一个子程序

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

和线程相比的几大优势:

最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显

不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多

17.怎么查看进程、端口,杀死进程,kill的原理是什么

Linux ps命令用于显示当前进程 (process) 的状态。

ps -ed

ps -aux

 

kill用于删除执行中的程序和工作

18.C++面向对象的三个特性,多态是怎么实现的

虚函数:虚函数对多态来说至关重要,有了虚函数才能实现多态

多态的必要条件:

  •       必须存在继承关系
  •       必须有同名的函数
  •       存在基类的指针

19.vector和map,怎样通过遍历来删除

迭代器删除

20.简单说一下智能指针

https://www.cnblogs.com/WindSun/p/11444429.html

智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,会在析构函数中释放掉申请的内存,从而防止内存泄漏。C++ 11中最常用的智能指针类型为shared_ptr,它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。当新增一个时引用计数加1,当过期时引用计数减一。只有引用计数为0时,智能指针才会自动释放引用的内存资源。对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。可以通过make_shared函数或者通过构造函数传入普通指针。并可以通过get函数获得普通指针

21.resdis了解吗

Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库

优势:

性能高、丰富的数据类型、原子

22.单例模式了解吗,写一下

 

 

23.深拷贝和浅拷贝

浅拷贝:默认bai的拷贝就是浅拷贝。 仅仅多了个指针du指向原来的空间

深拷贝:自己写的拷贝,自己申请了动态内存空间,用了new 或 malloc 。不但多了指针,而且多了空间。

23.内存对齐

 

24.标准库是线程安全的吗,怎么做到线程安全

 

25.互斥锁和自旋锁

互斥锁对资源的访问是互斥的,即一个线程获得资源的使用权后就会对给资源加锁,任何想要获得该资源的线程都会被阻塞

递归锁:同一个线程可以多次获得锁,别的线程必须等待该线程释放所有次数的锁才能获得

自旋锁:一种特殊的互斥锁,当资源被加锁后,其他资源想要再次加锁,此线程不是被阻塞睡眠而是被陷入循环状态(不想再做其他事情),循环检查是否释放了资源,这样做的好处是减少了线程从睡眠到唤醒的资源消耗,但会一直占用CPU资源,使用于资源的锁被持有的时间缩短,而不希望在线程的唤醒上花费太多的时间

26.多线程编程的锁机制要注意啥

27.你任务服务器要懂什么知识

 

QW-虾皮

1.C++多态

2.虚函数和虚表

C++中的虚函数的作用主要是实现了多态的机制

3.C++内存分配方式

1.栈:是分配给函数局部变量的存储单元,函数结束后,该变量的存储单元自动释放,效率高,分配的空间有限。

2.堆:由new创建,由delete释放的动态内存单元。如果用户不释放该内存,程序结束时,系统会自动回收。

3.自由存储区:由malloc创建,由free释放的动态内存单元,与堆类似。

4.全局(静态)存储去:全局变量和静态变量占一块内存空间。

5.常量存储区:存储常量,内容不允许更改

4.C++内存管理,RAII

RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源

5.三种智能指针

6.malloc是如何实现的, 底层有哪些系统调用

7.linux内存管理,伙伴系统

8.nagle算法

9.epoll相关的api,epoll底层实现

10.MySql隔离级别,默认级别是什么

11读已提交会出现什么问题(幻读),如何解决幻读?

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值