http和https区别

Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。主要是:

  1. 端口不同:http:80;https:443;
  2. 资源消耗:https由于加减密处理消耗更多的CPU和内存资源
  3. 开销:https通信需要证书,一般要购买的

https加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。

http常见状态码
200:服务器成功处理请求
304:上次请求后,请求网页未修改过
403:服务器拒绝请求
404:服务器找不到要请求的网页
500:服务器遇到错误,无法完成请求

tcp和udp

  • TCP:面向连接、可靠的、只支持点对点通信、具有拥塞机制、首部开销20字节、面向字节流,分段传输、慢
  • UDP:一个数据报就完成数据通信;无连接、不可靠、无拥塞、首部8字节、支持一对一、一对多、多对一、多对多通信、快

TCP可靠传输实现方式:以字节位单位的滑动窗口技术、超时重传三次机制、确认ack机制

避免网络拥塞方式: 动态改变窗口
慢开始:从1开始以2倍增长,到达慢门限以+1增长,出现拥塞,开始丢包至0,重设慢开始门限为0.5倍上限值。
快恢复:大致与慢开始相似,但丢包只丢至新的门限值再执行拥塞避免算法+1法;

cookie和session

  1. 实现机制:Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID;
  2. 大小限制:Cookie有大小限制并且浏览器对每个站点也有cookie的个数限制,Session没有大小限制,理论上只与服务器的内存大小有关;
  3. 安全性:Cookie存在安全隐患,通过拦截或本地文件找得到cookie后可以进行攻击,而Session由于保存在服务器端,相对更加安全;
  4. 服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。

三次握手和四次挥手

三次握手
第一次A—>B:客户A主动发送 连接请求的报文段 至服务器B。SYN=1,代表请求建立会话;seq=x,同时序号=x代表数据段的第一个字节是整个文件的第x个字节。A进入SYN_SENT状态。
第二次B—>A:服务器B接收到 连接请求 后发出回应。同意则发送 同意连接请求 至A。同步位SYN=1,代表同意建立会话;ACK=1,表明确认字节段生效;seq=y,同时序号=y代表发送的数据段的第一个字节是整个文件的第y个字节;ack=x+1,代表确认收到上一数据段。A的TCP通知上层应用进程,连接已建立。B进入SYN_RECV状态。
第一次A—>B:客户A收到B回复后。发送 回复报文段 至服务器B。SYN=0,会话已建立,归0;ACK=1,表明确认字节段生效;seq=x+1,代表发出 的数据段的第一个字节是x+1,即B发送的确认号。ack=y+1,代表确认收到B数据段。B的TCP通知上层应用进程,连接已建立。
A发送后进入ESTAB-LISHED状态。B接收后进入ESTAB-LISHED状态。

四次挥手
第一次A—>B:传输结束后,客户机A的应用进程表示要释放连接,TCP发出 释放连接报文段 至服务器B,并主动关闭TCP连接。FIN=1,代表释放连接;序号seq=u,发送一个数据等待B的确认。A处于 等待释放1——FIN-WAIT1状态。
第二次B—>A: 服务器B收到 释放连接报文段后,向A发送 确认收到 报文段。ACK=1,代表确认号生效;seq=v,代表发送数据的序号;ack=u+1,代表确认已收到释放连接的报文段。服务器B的TCP通知上层应用进程即将关闭连接。A到B连接释放。但B依然可连接A;若B还有数据发送,A仍要接收。B处于等待关闭——CLOSE-WAIT状态,A接收到此报文段后处于 等待释放2——FIN-WAIT2状态.
第三次B—>A: 服务器B向A的数据传送完成,B则向A发送 释放连接 报文段。FIN=1,代表释放连接;ACK=1,代表确认号生效;seq=w,发送一个数据等待A的确认;ack=u+1,表明确认已收到A释放连接的报文段。B处于最后确认——LAST-ACK状态;
第四次A—>B:客户端A收到B的报文段,发送确认报文段 至B;ACK=1,代表确认号生效;seq=u+1,代表发送数据序号;ack=w+1,代表确认收到了B的释放连接报文段。TCP 连接必须经过时间2MSL 后才真正释放掉,此时A处于计时等待——TIME-WAIT状态;当B收到时,关闭连接。计时结束后A关闭连接。

ip地址

  • A类地址以0开头,第一个字节作为网络号,地址范围为:0.0.0.0~127.255.255.255;(modified @2016.05.31)
  • B类地址以10开头,前两个字节作为网络号,地址范围是:128.0.0.0~191.255.255.255;
  • C类地址以110开头,前三个字节作为网络号,地址范围是:192.0.0.0~223.255.255.255。
  • D类地址以1110开头,地址范围是224.0.0.0~239.255.255.255,D类地址作为组播地址(一对多的通信);
  • E类地址以1111开头,地址范围是240.0.0.0~255.255.255.255,E类地址为保留地址,供以后使用。
  • 注:只有A,B,C有网络号和主机号之分,D类地址和E类地址没有划分网络号和主机号。
    A、B、C类私有地址
  • A类私有地址:10.0.0.0/8,范围是:10.0.0.0~10.255.255.255
  • B类私有地址:172.16.0.0/12,范围是:172.16.0.0~172.31.255.255
  • C类私有地址:192.168.0.0/16,范围是:192.168.0.0~192.168.255.255

**=========================================================**

c++的四种cast类型转换

  1. const_cast:用于将const变量转为非const
  2. static_cast:用于隐式转换,常用于向下转换,向上转不安全
  3. dynamic_cast:用于动态类型转换,只能转指针或引用,上下均可转
  4. reinterpret_cast:几乎什么都可以转,但尽量少用

c++的智能指针

智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。避免内存泄露。

  • auto_ptr:cpp11已放弃
  • unique_ptr:实现独占式拥有或严格拥有概念,保证同一时间内只有一个智能指针可以指向该对象。
  • shared_ptr:实现共享式拥有,多个智能指针可以指向相同对象。
  • weak_ptr:不控制对象生命周期的智能指针。不用于直接访问对象,用于解决shared_ptr相互引用时死锁问题。

野指针就是指向一个已删除的对象或者未申请访问受限内存区域的指针

虚函数

当类需作为父类/基类时,需将析构函数设置为虚函数。防止基类指针指向子类对象时,释放基类指针出现内存泄露现象。
虚函数表-虚函数指针;会占用内存,默认不是虚析构函数。

类析构顺序:1)派生类本身的析构函数;2)对象成员析构函数;3)基类析构函数。构造与其相反。
虚函数的实现:在有虚函数的类中,类的最开始部分是一个虚函数表的指针,这个指针指向一个虚函数表,表中放了虚函数的地址,实际的虚函数在代码段(.text)中。当子类继承了父类的时候也会继承其虚函数表,当子类重写父类中虚函数时候,会将其继承到的虚函数表中的地址替换为重新写的函数地址。使用了虚函数,会增加访问内存开销,降低效率。

重写和重载

  • 重载:两个函数名相同,但是参数列表不同(个数,类型),返回值类型没有要求,在同一作用域中

  • 重写:子类继承了父类,父类中的函数是虚函数,在子类中重新定义了这个虚函数,这种情况是重写

  • 动/静多态:多态的实现主要分为静态多态和动态多态,静态多态主要是重载,在编译的时候就已经确定;动态多态是用虚函数机制实现的,在运行期间动态绑定。
    举个例子:一个父类类型的指针指向一个子类对象时候,使用父类的指针去调用子类中重写了的父类中的虚函数的时候,会调用子类重写过后的函数,在父类中声明为加了virtual关键字的函数,在子类中重写时候不需要加virtual也是虚函数。

继承

公有 私有 保护

new/delete与malloc/free的区别

new/delete是C++的关键字,而malloc/free是C语言的库函数,后者使用必须指明申请内存空间的大小,对于类类型的对象,后者不会调用构造函数和析构函数。
malloc需要给定申请内存的大小,返回的指针需要强转。
new会调用构造函数,不用指定内存大小,返回的指针不用强转。

struct和class

C++中,可以用struct和class定义类,都可以继承。区别在于:structural的默认继承权限和默认访问权限是public,而class的默认继承权限和默认访问权限是private。

Cpp11新特性

C++11 最常用的新特性如下:

  • auto关键字:编译器可以根据初始值自动推导出类型。但是不能用于函数传参以及数组类型的推导
  • nullptr关键字:nullptr是一种特殊类型的字面值,它可以被转换成任意其它的指针类型;而NULL一般被宏定义为0,在遇到重载时可能会出现问题。
  • 智能指针:C++11新增了std::shared_ptr、std::weak_ptr等类型的智能指针,用于解决内存管理的问题。
  • 初始化列表:使用初始化列表来对类进行初始化
  • 右值引用:基于右值引用可以实现移动语义和完美转发,消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率
  • atomic原子操作用于多线程资源互斥操作
  • 新增STL容器array以及tuple

头文件含义

双引号和尖括号的区别:编译器预处理阶段查找头文件的路径不一样。

  • #include <>格式:引用标准库头文件,编译器从标准库目录开始搜索
  • #incluce ""格式:引用非标准库的头文件,编译器从用户的工作目录开始搜索

**===========================================================================**

vector和list

vector:物理逻辑都连续,堆上分配空间,底层实现市数组、两倍扩容,扩容可能会内存拷贝/深拷贝、适用场景:经常随机访问,且不经常对非尾节点进行插入删除。
list:逻辑、物理不连续、堆上分配、底层双层链表、适用场景:经常插入删除大量数据

堆与栈

堆:先进先出,内存中动态内存分配在堆,常量、返回值在栈。
栈:先进后出
堆是由低地址向高地址扩展;栈是由高地址向低地址扩展;堆中的内存需要手动申请和手动释放;栈中内存是由OS自动申请和自动释放;堆的分配效率较低,而栈的分配效率较高;栈是操作系统提供的数据结构,堆是由C/C++函数库提供的;

set和map的底层实现 红黑树

map和set都是C++的关联容器,其底层实现都是红黑树(RB-Tree)。

  • map中的元素是key-value(关键字—值)对:关键字起到索引的作用,值则表示与索引相关联的数据;set与之相对就是关键字的简单集合,set中每个元素只包含一个关键字。
  • set的迭代器是const的,不允许修改元素的值;map允许修改value,但不允许修改key。
  • map支持下标操作,set不支持下标操作。

STL基本组成

STL主要由以下几部分组成:
容器 迭代器 仿函数 算法 分配器 配接器
他们之间的关系:分配器给容器分配存储空间,算法通过迭代器获取容器中的内容,仿函数可以协助算法完成各种操作,配接器用来套接适配仿函数

hashmap

主干是entry,即key-value组合;实现是数组加链表

进程与线程,进程间通信

进程是一个程序的一次动态执行的过程,是os进行资源分配和调度的一个独立单位。抢占式任务调度
线程是CPU调度和分配的基本单位。一个进程可有多个线程。各线程间共享内存数据。
区别

  1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
  2. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
  3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间;
  4. 调度和切换:线程上下文切换比进程上下文切换要快得多;
  5. 线程廉价,线程启动比较快,退出比较快,对系统资源的冲击也比较小。

进程间通信

  • 管道:半双工,只能用于具有亲缘关系的进程之间的通信
  • FIFO:任何进程都能通讯,但速度慢,先进先出。
  • 消息队列:消息的链接表放在内核,消息具有特定的格式以及特定的优先级。独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除
  • 信号量:用于实现进程间的互斥与同步,不能传递复杂消息
  • 共享内存区:多个进程共享一个指定存储区,多进程可同时操作,快。通常与信号量结合使用。

B树、B+树、AVL、红黑树

B树是一种自平衡树数据结构 非常适合读取和写入相对较大的数据块(如光盘)的存储系统。它通常用于数据库和文件系统。
B+树 每个元素不保存数据,只用来索引,所有数据都保存在叶子节点更加“矮胖”,I/O操作更少

AVL 左右两个子树的高度差的绝对值不超过1
红黑树, 每条路径黑结点个数相同;红结点不连续;根和叶子都为黑结点