题目

114 阅读23分钟

网络题目

1. OSI七层模型是什么?每层的功能描述?
  1. 应用层:各种程序,例如Web应用
  2. 表示层:将数据转化为一定的可传输的数据格式,包含了数据压缩、加密,
  3. 会话层:控制传输层与应用程序之间的交互
  4. 传输层:端到端的数据传输
  5. 网络层:IP地址,标识不同设备的转发
  6. 数据链路层:定义数据基本格式
  7. 物理层:底层数据传输,光电信号
2. TCP是OSI模型的那个层面?

TCP 与UDP 同在 传输层

3. TCP为什么需要3次握手,4次挥手?

TCP的3次握手: 起始状态client:closed ,server :listen

  • 客户端发送给服务端一个syn报文,指明client的seq为x,client处于syn_send状态
  • server接收到syn报文后,以自己的syn报文作为回答,制定了seq为y,同时传递ack = x+1 ,标识收到了client的syn,server处于syn_send状态
  • client收到syn报文后,发送ack= Y+1 ,表示收到了server报文,client 处于established
  • server收到ack后,处于establish状态

TCP4次挥手

  • 起始状态:client,server为established状态
  • client发送一个FIN报文,制定一个seq=X,client处于FIN_WAIT1状态
  • server 收到FIN后,发送ack = X+1,表示收到了client的请求,server处于CLOSE_WAIT 状态
  • 若server断开连接,发送FIN报文,制定seq =Y,server处于LAST_ACk状态
  • client收到了FIN报文后,发送一个ack=Y+1给server,client处于TIME_WAIT状态,经过一段时间后却报之收到server收到ack后,client处于closed
  • server收到ack后,置为closed
4. TCP与UDP的区别应用场景分析?

TCP是面向连接的、双向的、可靠的、面向字节流的全双工通信协议;

  • 连接:表示双方在传输数据之前,必须先建立一条连接通道,才可以,TCP的连接是通过三次握手的方式来进行连接;
  • 双向:TCP的连接只能是点对点的连接,只能有两个端;
  • 安全:TCP提供了安全可靠的数据传输服务,无差错、不丢失、无重复、按顺序;
  • 全双工通信:允许通信双方在任何时候都可以发送接收数据,两端均设有接收、发送缓存;
  • 面向字节流:应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流.TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。

其中操作系统通过TCP协议的传输会将一个消息分为多个TCP报文,也就是说一个完整的用户信息被拆分为多个TCP报文传输,

  • 出现的问题:接收方无法知道用户消息的边界在哪儿,造成粘包。 解决粘包的方案:
  • 固定长度发送消息
  • 特殊字符作为边界
  • 自定义消息结构

流量控制? //todo 阻塞控制? //todo

UDP是无连接的、不可靠的、面向报文的传输协议

  • 操作系统不会对消息进行拆分、组装好UDP头部后就直接交由网络层处理,一个报文就是一个用户信息的边界,接收方收到UDP的报文后,就是一个完整的用户信息

TCP和UDP的场景?

  • TCP应用于效率相对较低,准确性相对较高的场景中,主要原因是传输的数据需要保证有序、不重复、可靠性决定的,比如文件传输、邮件、远程登录等
  • UDP应用于效率高,但准确性相对较低的场景,比如即时通讯、在线视频等
5. TCP的窗口函数 && 阻塞控制?

TCP使用滑动窗口来实现流量控制,其中滑动窗口的大小意味着接收方有多大的缓冲区接受数据,发送方使用滑动窗口大小确定发送了多少字节的数据,当滑动窗口为0时,发送方不能发送数据。 其中的流量控制是为了控制发送方发送的速率,保证接收方来的及接收。窗口大小保证了发送效率

6. TCP如何有效传输和阻塞控制原理?

阻塞控制原理: 原因是由于网络环境很差,容易丢包

  • 慢启动阈值+拥塞避免
    • 发送端使用阻塞窗口大小控制发送窗口的大小
  • 快速重传:
    • 选择重传:只传输丢失的包
    • 在传输的过程中,发送了丢包,接收端会收到发送之前的重复的ack,这样发送端收到后就会立即重传
  • 快速恢复
    • 如果发送方发现了丢包了,那么网络进入了阻塞状态,进入快速恢复阶段
      • 会将拥塞阈值降低为 拥塞窗口的一半
      • 然后拥塞窗口大小变为拥塞阈值
      • 拥塞窗口再进行线性增加,以适应网络状况
7. TCP如何保证有效传输?

TCP是面向连接的、可靠的、传输层的通讯协议,

  • 其中有状态表示TCP会确认发送了哪些报文,收到了哪些报文,哪些没收到,保证了数据包的到达
  • 可控制是指出现丢包或网络问题,会跳转自己的行为
  • 数据包校验:检测数据在传输过程中的任何变化,若有校验包出错,那么丢弃报文不给响应,TCP会重新发送数据
  • 时序的数据包重排序:TCP报文作为IP数据报来传输,而IP数据报的到达会失序,因此TCP报文段也会失序,TCP会给失序的数据报重排,交给应用层
  • 丢弃重复数据:对于重复数据,能够丢弃重复数据
  • 应答机制:当TCP收到发自TCP另一端的数据,发送确认ack,推迟发送
  • 超时重发:当TCP发出一个段后,启动了定时器,等待目的段确认收到报文段,如果不能及时收到确认,那么将重发
  • 流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许另一独胆发送接收段缓冲区所能容纳的数据,防止较快主机致使较慢主机的缓冲区溢出即为流量控制
8. HTTP 1.0/ 1.1/2.0的区别?

http 1.0

  • 短连接,浏览器的每次访问都需要和server建立一个TCP连接,server完成就断开连接 http 1.1
  • 持久连接,TCP连接默认不关闭,可以被多个请求复用
  • 管道机制:在一个TCP连接里面,client可以同时发送多个请求 http 2.0
  • 多路复用的机制,一个连接里面,client和浏览器可以发送多个请求或者回应,不用按照顺序意义对应;原理:使用了二进制分帧,将所有的传输的信息分割为更小的消息和帧,并对其进行二进制格式的编码
  • Header压缩 ??
  • 服务端推送 ??
9. POST和GET的区别及底层原理使用场景?

区别:

  • 请求参数:GET放在URL中,POST放在请求体中
  • 请求体大小:GET的请求参数只能放在URL中,对于URL有长度限制,参数大小会比较小
  • 安全性:GET 不会更改服务器的状态,POST大部分情况是用来提交数据实体的,因此状态会发生改变
  • 幂等性:GET请求一次或者多次执行后的效果是一样的,服务器状态也是一样的
  • 可缓存:GET请求的结果是可以缓存的,可以指定Cache-Control制定是否缓存
  • 数据包:GET请求 ,浏览器会把 Http的header 和data 一起发送出去,服务器响应;POST请求 ,浏览器发送header,服务器响应后,在发送data,服务器进行响应
10. HTTP的状态码及使用场景?

1xx:协议的中间状态,需要再次请求 2xx:请求成功 200 204 205 3xx:重定向 301 永久重定向(会缓存) 302 临时重定向(不会缓存) 4xx:client出现问题 404 403 400 5xx:server 错误 502 500

11. HTTP与HTTPS的区别?

http代表了超文本传输协议,用于网络传输数据,特点如下:

  • 支持客户端/服务端模式
  • 简单快速 :只需要传送请求方法和路径,由于HTTP协议简单使得HTTP服务器程序规模小,通信简单
  • 灵活:Http 可以传输任意类型的数据对象,使用Content——Type加以标记
  • 无连接的:每次连接都处理一个请求,服务器处理完成后,断开连接
  • 无状态: 无法根据之前的状态进行本次的处理

https是使用了TLS来加密和认证 http请求和响应的

  • 端口不同:Http的端口是80,https的端口是443
  • 资源消耗:https会由于加密/解密来消耗CPU和内存资源
  • 开销:https需要证书,而证书需要购买 https的加密机制是一种共享密钥+公钥加密并用的混合加密机制
12. 对称加密与非对称加密的区别?

对称密钥加密是指加密和解密都是使用同一个密钥的方式, 非对称加密是指使用一对公钥和私钥,公钥随意发布,但是私钥只有自己知道,发秘文一方使用对方的公钥进行加密处理,对方收到加密信息后,使用自己的私钥进行解密

13. HTTP 如何实现长连接?在什么时候会超时?

通过设置头部Connection:Keep-alive,

  • http一般都会有httpd守护进程,设置keep-alive timeout,当tcp连接闲置超过这个时间就会关闭,也可以在HTTP的请求头里面设置超时时间
  • http 并没有长短连接,只有TCP有,tcp的一个长连接可以复用一个TCP的连接发起多次HTTP请求,减少资源的消耗
14. XSS攻击及场景?

恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些脚本代码嵌入到web页面中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式 解决方案:不信任提交的数据 ,对提交的数据进行过滤 ,使用正则/html.encode进行处理

15. SQL注入?
16. cookies、session、token、oauth区别?

因为http 是无状态的协议,那么服务端需要记录用户的状态,需要某种机制识别具体的用户,session和cookies应运而生,同为认证方式。 cookies: 存储在客户端,cookies是服务器发送到用户浏览器并保存在本地的一小块数据,会在浏览器下次向同一个服务器在发起请求时会被携带并发送到服务器上,cookie是不可跨域的,每个cookie都会绑定单一的域名,无法在别的域名下获取使用

session:一种记录服务器与客户端会话状态的机制 session是基于cookies实现的,session 存储在服务器端,sessionId会被存储在客户端的cookies中 cookies 与session的区别?

  • 安全性: session 比cookie安全,session存储在服务器端,cookies 存储在服务端
  • 存取值类型不同:cookies只支持存字符串数据,想要设置其他数据类型的数据,需要将其转化为字符串,seesion可以存取任一数据类型
  • 有效期不同: cookies 可设置为长时间保持,默认登录状态,session 一般失效时间短,客户端关闭/失效都会失效
  • 存储大小:cookies 存存在客户端,因此大小有限制,session可存储的数据高于cookies,当访问量过多,会占用过多的服务器资源。

token:访问资源需要的资源凭证

  • 服务端无状态化,扩展性强
  • 支持移动端的设备
  • 安全
  • 支持跨程序调用

token 与session的区别

  • session 是一种记录服务器与客户端的会话状态的机制,使得服务端有状态化,记录会话信息,而token是令牌,访问资源接口时所需要的资源凭证,token 使得服务端无状态化,你不会存储会话信息。
  • 作为身份验证的token比session好,因为每一个请求都签名还能防止监听以及重放攻击,而session 就必须依赖链路层来保证通讯安全,如果需要实现有状态的话,仍然可以增加session在服务器端保存一些状态。 JWT的组成:
  • header头 记录了整个令牌的类型和算法 alg和typ字段 base64 对header 头进行编码
  • payload负载 记录了主体信息,比如保存用户信息可以放到这里
  • signature 签名 保证了令牌不被伪造和篡改

token和JWT的区别

  • 都是访问资源的令牌
  • 都可以记录用户信息
  • 使服务端无状态化
  • 只有验证成功后,客户端才能访问服务端上的受保护的资源
17. UDP如何实现可靠传输

UDP 不属于连接协议,具有资源消耗少,处理速度快的特点大多用于 音视频的数据传输中,使用UDP较多,丢失数据也不会对结果产生较大的影响。 传输层无法保证数据的可靠传输,只能通过应用层实现,实现方式可以参考TCP可靠传输的方式,

  • 添加seq/ac机制,确保数据发送到对端
  • 添加发送和接收的缓冲区,主要是用户的超时重传
  • 添加超时重传的机制

RTC

18.webSocket

操作系统

1. 进程、线程的区别和联系
  • 进程是操作系统的资源调度和分配的基本单位,进程具有独立的内存空间,上下文切换开销大,较稳定

  • 线程:轻量级的进程,CPU调度的最小单元,一个进程包含了多个线程,多线程之间共享内存空间,线程切换开销较小,进程内的线程切换涉及用户态和内核态的转换,如何实现共享内存呢?

  • 协程:一种用户的轻量级线程,协程的调度完全由用户态调度,协程不被操作系统管理,被用户管理,协程拥有自己的寄存器上下文和栈,将寄存器上下文和栈保存到其他地方,切换回来的时候,恢复先前保存的数据

2. 有了进程为什么还要线程 && 线程之间如何通信

不同的进程切换实现并发,各自占有CPU实现并行,线程减少了在并发程序执行时所付出的时间和空间开销,提高并发性能

3. 进程状态的切换 && 进程的通信方式

进程的通信方式:每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另外的一个全局变量中都看不到,因此进程之间通信,需要在内核中开辟一块缓冲区,从而实现通信

  • 匿名通道 :半双工的通信方式,数据只能单向流动,只能处理父子进程
  • 高级管道:将另一个程序当作一个新的进程在当前的程序中启动,当作当前程序的子程序
  • 有名管道:半双工通信,允许无亲缘关系的进程通信
  • 消息队列:消息队列是由消息的链表,存放在内核中并由消息队列标识符表示。
  • 信号量通信:信号量是一个计数器,用来控制多个进程来对共享资源的访问,作为一种锁机制防止某进程正在访问共享资源。
  • 信号 L:用于通知接受进程的某个事件发生了
  • 共享内存:共享内存时映射一段能够被其他的进程所访问的内存,这段内存由一个进程创建,但多个进抻之间可以访问,是最快的IPC方式
  • 套接字通信:进程间的通信机制,可用于不同机器间的进程通信

线程状态: 创建态(new)-就绪态(runnable)-运行态(running)-阻塞态(blocked)-timewaiting-waiting-消亡(dead)

4. 并发和并行

并发:一段时间内能同时运行多个程序 并行:同一时刻能运行多个指令

5.进程调度算法

先来先服务、短作业优先、最短剩余时间优先

  • 先来先服务 :按照请求的顺序进行调度执行,非抢占式
  • 短作业有限:估计运行时间按照用时短 的顺序进行调度
  • 最短剩余时间:最短作业优先是抢占式,按照剩余运行时间的顺序进行调度
  • 时间片轮转算法:将所有的就绪进程按照先来先服务的原则排成一个队列,将CPU时间分配给队首进程,该进程执行一个时间片,由计时器发出时钟中断,调度进程停止该进程的运行,将并其放到就绪队列的队尾,同时CPU时间分配给队首的进程
  • 优先级调度 :给每个进程分配一个优先级,按照优先级分分配
  • 多级反馈队列:
6.磁盘的调度算法

磁盘块的时间影响因素:

  • 旋转时间
  • 寻道时间
  • 实际的数据传输时间 其中 寻道时间最长,因此磁盘的调度主要目标是使磁盘的平均寻道时间最短 1、先来先服务:按照磁盘的请求顺序进行调度 2、最短寻道时间优先:有限调度与当前磁头最近的磁道 3、电梯扫描法:按照一个方向来进行磁盘调度,直到该磁道上没哦与请求
7.页面置换算法
  • 最佳置换法: 每次选择淘汰的页面都不会再用,或者长时间不在访问的页面
  • 先进先出的置换算法:每次淘汰的页面是最早进入内存的页面
  • 最近未使用的置换算法:每次淘汰的是最近最久未使用的页面
  • 时钟置换算法:循环扫描缓冲区像时钟一样转动 为每个页面设置一个访问位,再将内存中的页面都通过链接指针链接成一个循环队列
8. I/O多路复用 事件通知

I/O多路复用就是多个TCP连接,复用就是指复用一个或者少量线程,理解就是多个网络IO复用一个/多个线程处理连接执行过程

常见的IO模型

  • 同步阻塞IO:请求IO,等待server 返回结果,其他进行返回
  • 同步非阻塞IO:请求立即返回,但是返回的结果不能立即获取,轮训请求IO,获取结果
  • IO多路复用:使用一个/多个线程来处理多个TCP连接,IO多路复用使用两个系统调用,Reactor设计模式
    • select:基于轮训机制
      • 通过设置或检查存放的fd标志位的数据结构进行下一步处理
        • 单进程可监视的FD数量被限制,监听端口的数量有限
        • socket是线性扫描,轮训去访问,
        • 需要维护一个用来存放大量的fd的数据结构,浪费空间
    • poll
      • 将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。
    • epoll
      • epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式。LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的[返回值]小于请求值,或者 遇到EAGAIN错误。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似[callback]
  • 异步IO:

Go语言

Go的flag包的使用方法
Go的nil

nil 不是关键字,而是预先声明的标识符,指针、函数、接口、map 、切片零值均为nil nil 没有默认的类型,

两个nil是无法比较的?

  • 声明一个nil的map,可以读数据但是不能写入数据
  • 关闭一个nil的channel会引发panic
  • nil切片不能索引访问,引发panic
  • 方法的接受者为nil,在方法调用的时候会引发panic
  • 空指针一个没有任何值的指针
Go的slice、map、interface、sync.Map,sync.Mutex、context、select、channel的源码解析
  • context

    • context是在go1.7引入的,用来在groutine中实现上下文信息的传递,相同的context可以传递给不同的Groutine中的函数,上下文对于多个groutine 同时使用是安全的,context定义了上下文类型,使用background、TODO创建一个上下文,使用withdeadline,WithTimeOut,withCancal或者withValue 创建的修改副本来替换

    • 方法

      • backgroud()

        • 是上下文的默认值,其他的上下文都是基于它衍生出来的,起始的上下文【父树】,衍生出了ctx1.0-cancel,ctx2.0-deadline,ctx3.0-timeout,ctx4.0-withvalue四个context
      • TODO()

        • 不确定应用哪种上下文的时候使用
      • WithCancel 取消控制

        • 使用withCannel 来衍生一个context来保证传递到多个groutine中,调用Cancel实现 停止所有的groutine
      • WithDeadLine

      • WithTimeout

      • WithValue

        • 设置携带的参数,通常用来设置trace_id,span_id 等
    • context是并发安全的吗?

      • cancelCtx 继承了Context,实现了canceler: image.png
    • context源码分析

      • DeadLine:当Context自动取消或者到了取消时间被取消返回
      • Done方法:当Context被取消或者到了deadline 返回一个被关闭的channel
      • Err方法:当Context被取消或者关闭后,返回context 取消的原因
      • Value方法 :获取Key对应的值
  • Map

    • Map在go的源码中是hmap结构体,同时包含几个特殊的字段,buckets,count、flags,mapextra 、B,hash0,count 代表着有多少个元素,flag标记是否是写标记,B是Bucket的对数,mapextra 代表着溢出的bucket, 其中buckets 是bmap的数组,bmap用于存储Map中的实体数据,包含了keys,values ,overflow 和tophash字段,其中overflow用于处理hash冲突的数据,tophash 标记了状态
    • 在查询的时候,首先经过hash函数后哈希值为64bit,获取到后面B的数据,得到在B号的bucket中,其中使用hash值 的高8位,计算槽位,其中查找到 bucket后,便利查询的key
    • 渐进式hash: 当负载因子达到6.5/ overflow的节点过多,那么进行rehash,其中hashgro函数分配新的bucket,并将老的bucket加载到oldBucket上,真正的迁移在插入、删除、修改的时候进行。
  • Slice

    • 动态的数组,其中包含cap、len、array字段,其中底层指向数组的指针
    • growslice slice的容量的计算方案 更改为 当容量的大小扩充为256个以上,那么容量递增 (oldcap+3*256)/4 小于 256则扩容为2倍
  • Chan

    • 底层主要是由环形的数组和两个groutine实现,
      • qcount :元素数量
      • dataqsiz:底层数组的长度
      • buf:底层数组的指针
      • closed: chan是否是关闭状态
      • elemtype: 元素的类型
      • elemSizeOf: 每个元素的大小
      • sendX:已发送的数据在哦循环数组中的索引
      • recvX:已经接受的数据在循环数组中的索引
      • sendq waitq等待发送的队列
      • recvq waitq:等待接受的队列
      • lock mutex 加锁保证原子操作
      • waitq:是个双向链表
内存逃逸
- 内存逃逸
    一段程序中,运行一个函数,这个函数的局部变量和地址会由编译器分配在栈空间中,在运行完函数结束后,栈空间自动释放,但是需要某些变量在函数运行后仍可供使用,那么就会在堆上分配一块连续的内存存储,相应的从栈到堆上的数据转移叫做内存逃逸

- 内存逃逸分析:
    内存空间分为栈空间和堆空间;堆空间适合不可预知大小的内存分配,但分配较慢,容易产生内存碎片,堆分配内存首先需要去找到一块大小合适; 栈分配快,只有PUSH 和RELASE指令;
内存对齐

现在的计算机中内存空间以字节进行划分,理论上对于任何类型的变量访问都可以从任意地址开始,在实际的情况中,在访问特定类型变量的时候会在特定的内存地址访问,需要将各种数据类型数据按照一定的规则在空间上排列,不是按照顺序一个一个的排放,称之为内存对齐

CSP【channel】
  CSP模型:在Go中是使用Channel和groutine进行搭配实现的 
  
GMP
GC

MySQL

Mysql的引擎有哪些,区别是什么?
  • 存储引擎作为数据存储的一种方式
  • innodb引擎:其中数据存储文件有 .frm文件和ibdata1文件,分别存放了什么? innodb 存储引擎为mysql提供了事务的机制,支持外键 回滚及系统崩溃后的修复和多版本的并发安全,innodb存储支持行锁、表锁,底层实现使用的是B+树,其中innodb 的缺点是读写效率较差,占用数据的空间较大 适用于并发读写
  • myIsam:存储的数据文件包含 .frm,.MYD,.MYI 进行数据的存储,其中MYISAM是不支持事务的,所以他的优点在于select数据,其中myIsam是支持表锁的。
  • Memory:memory存储的逻辑在于系统内存,提高了存储数据的表的查询