zhoujingye

1. OSI七层和TCP/IP四层

  OSI/RM:开放系统互联基本参考模型(open system interconnection reference model),为了各种计算机在世界范围内互连成网的标准框架,国际标准化组织ISO于1977年成立了专门机构研究该问题。

  OSI七层/TCPIP四层/五层协议(综合OSI和TCP/IP的优点):

  

 

 

   物理层:物理层上传送的数据单位是比特,发送方发送1/0时,接收方应当受到1/0而不是0/1,因此物理层要考虑用多大的电压表示1/0,以及接收方如何识别发送方发出的比特;物理层还要确定连接电缆的插头有几根引脚以及如何连接;定义物理设备标准,例如网线的接口类型、光线的接口类型、各种传输介质的传输速率等。他的主要作用是传入比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们通常所说的数模转换与模数转换)。这一层的数据叫做比特流。

  数据链路层:定义了如何让数据格式化进行传输,将网络层下来的数据报组装成,还提供了错误检测和纠正,以保证数据的可靠传输。

  网络层:在位于不同地理位置的网络中的两个主机之间提供连接和路径选择。将运输层产生的报文段或者用户数据包封装成;Internet的发展使得从世界各站点访问信息的用户数大大增加,而网络层正是管理这种连接的层。

  运输层:定义了一些传输数据的协议和端口号(WWW端口80等),主要是将从下层的接收的数据进行分段和传输,到达目的地后再进行传输。常常把这一层数据叫做

  应用层:应用进程间通信与交互的规则,如HTTP协议(万维网应用)、SMTP(电子邮件)、FTP(文件传输)等,数据单位为报文

 

2.TCP,UDP,HTTP的报文格式(1个字节=8位)

(TCP、UDP是在运输层的协议,HTTP是在应用层的协议)

UDP报文格式:两个部分,UDP数据字段首部字段(8个字节源端口2、目的端口2、长度2、校验和2),12 字节的伪首部是为了计算检验和临时添加的。

 

 

 

TCP报文格式:两个部分,TCP报文段数据部分首部(源端口2、目的端口2、序号4、确认号4、数据偏移4位、保留6位、URG/ACK/PSH/RST/SYN/FIN6位标志位、窗口大小2、校验和2、紧急指针2、选项),首部的前20字节是确定的,选项长度可变,最长可达40字节

 

HTTP协议:定义了浏览器如何向万维网服务器请求万维网文档,以及服务器如何将文档传送给浏览器的,是面向事务的应用层协议

  HTTP报文格式:有两种报文,请求报文和响应报文

  请求报文和响应报文都是由三个部分组成:

  开始行:区分是请求还是响应,请求是:URL+CRLF回车换行,响应是:状态行

  首部行:说明浏览器、服务器、报文主题的信息

  实体主体:请求中一般不用,响应中可能不用

 

3.TCP,UDP的区别:

 - TCP:传输控制协议TCP,面向连接,传输效率低,可靠性强,点对点,用于传输可靠性要求高,数据量大的数据

   - UDP:用户数据报协议UDP,与TCP特性恰恰相反,面向报文,无连接的(不需要数据双方建立连接),尽最大努力交付,没有拥塞控制(实时视频会议、IP电话等允许丢失一些数据,以恒定的速率发送数据),支持一对一、一对多、多对一、多对多,用于传输可靠性要求不高、数据量小的数据,如QQ聊天数据就是通过这种方式传输的

  相同之处:都是传输层协议

 

  为什么TCP是安全的:

  TCP具有三次握手的双向机制,每次都需要建立一个可以双方互相信任的链接才开始传输数据,而且如果传输过程中发生校验失败、丢包、延时会发生重传;TCP还有拥塞控制和流量控制(窗口和计时器,窗口指明最大数据量)

 

拥塞控制4个核心算法:

当主机开始发送数据时,如果立即将较大的发送窗口的全部数据字节都注入网络,由于不清楚网络的状况,可能会引发网络拥塞

① 慢启动:由小到大逐渐增加拥塞窗口数值,如果接收方返回确认无延迟,发送方拥塞窗口加倍(为防止拥塞窗口cwnd增大过大引起网络拥塞,还要这是一个慢开始门限ssthresh,如果cwnd < ssthresh,则慢开始,如果>则拥塞避免)

② 拥塞避免:将TCP连接初始化,cwnd设置为1,cwnd加1而不是翻倍,发生网络拥塞时将ssthresh设置为拥塞前的一半

③ 快重传:快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方),当出现丢失,发送下一个时候,接收方会重复发送丢失数据上的上一个完整数据,当发送方连续收到三个重复确认时,立即重传对方尚未收到的报文

④ 快恢复:当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把sstresh门限减半(乘法减小)。考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞,所以此时不执行慢开始算法(cwnd不设置为1),而是把cwnd设置为sstresh减半后的数值,开始拥塞避免算法(加法增大)

 

TCP三次握手四次挥手:

三次握手:发送数据建立连接

 

SYN:请求建立连接,ACK确认号是否有效,FIN希望断开连接,seq=x ,seq=y 是选择的初始序列号,

 

第一次握手:建立连接时,客户端发送syn包(syn=序列号)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=序列号+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

 

四次挥手:停止发送数据关闭连接

 

 

 

1)客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
2)服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
3)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
4)服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
5)客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。

(MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。)

6)服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些

 

4. HTTP的长连接是怎么做的

HTTP的长连接,本质上是TCP的连接,HTTP是应用层的协议,TCP才是真正的传输层的协议(快递单子和实际送货过程),http1.1是长连接

如何实现? 通过设置connection为keep-alive实现

为了干什么? 为了复用TCP连接,长连接情况下,多个HTTP请求可以复用同一个TCP连接,节省了很多TCP连接建立和断开的消耗

平时普通的Web应用使用长连接有什么好处? 长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。节约TCP连接和断开的消耗。

长连接的问题:在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭,客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损。

5. JVM内存分布

JVM是什么:JVM(Java Virtual Machine,Java虚拟机)

Java程序的跨平台特性主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,Java虚拟机中的Java解释器负责将字节码文件解释成为特定的机器码进行运行。因此在运行时,Java源程序需要通过编译器编译成为.class文件。JVM是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。所以,JAVA虚拟机JVM是属于JRE的,而现在我们安装JDK时也附带安装了JRE(当然也可以单独安装JRE)。

JVM内存分布:

 

 

 堆:堆是Java虚拟机管理的内存中最大的一块区域,Java堆是所有线程共享的区域,在虚拟机启动的时候创建,堆的作用是用来存放几乎所有的对象实例,Java堆是垃圾器管理的主要区域,因此也被称为GC(garbage collect)堆。当要给新的实例分配内存空间的时候,堆空间不足会抛出OOM异常。

方法区:方法区也是用于线程共享的区域,用来存储已经被加载的类信息,常量、静态变量、即时编译器编译后的代码数据

虚拟机栈:每个线程都有一个自己的虚拟机栈,虚拟机栈是线程私有的,虚拟机栈执行方法的时候,会为每一个方法创建一个栈帧,用于存放局部变量、操作数栈、动态链接、方法出口等信息。每一个方法的调用过程,在虚拟机中就是一个栈帧的一次入栈出栈。所以在用递归的方法来处理量很大的数据的时候,就会 导致StackOverFlowError。

本地方法栈:功能和虚拟机栈作用非常相似,虚拟机栈执行的是Java字节码,而本地方法栈执行的是Native方法。

程序计数器:程序计数器是一小块内存区域,也是线程私有的。用来储存当前线程执行的字节码的行号。Java多线程是通过线程轮流切换并分配给处理器执行的方式实现的。所以如果当前线程切换后,要想恢复到正确的位置,就需要程序计数器了。如果当前线程执行的方法是Java方法,那程序计数器保存的就是字节码指令的地址,如果执行的是Native方法,计数器的值就为空(Undefind)。

 

6. Java的set,list,map(线程安全的map,map怎么实现之类的)

Java中的集合包括三大类,分别是set list map,他们都处于java.util包中,set list map都是接口,它们有各自的实现类;LIST SET继承自Collection接口,Map不是(Collection是所有集合类的接口)

  • Set(集) 实现类主要有HashSet和TreeSet,不能含有重复的元素
  • List(列表) 实现类主要有ArrayList,LinkedList,Vector(安全,多了个同步化机制),以特定次序存储元素
  • Map(映射)实现类主要有HashMap和TreeMap,HashTable(安全,比hashmap多了线程安全

collection和map的区别:

Collection类型者,每个位置只有一个元素。Map类型者,持有 key-value pair,像个小型数据库。

Collection、List、Set、Map都是接口,不能实例化。继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。

 

7. 线程创建,线程池参数

为什么要使用线程池?

线程池做的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程的数量超过最大数量,超过数量的线程将排队等候,等其他线程执行完毕,再从队列中取出任务来执行

特点:线程复用,控制最大并发数,管理线程

- 降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗

- 提高响应速度,当任务到达时,任务可以不需要的等到线程创建就能够立刻执行

- 提高线程的可管理性,线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,

- 还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

线程创建四大方法:

① 继承Thread类

② 实现Runnable接口

③ 使用Callable创建线程

④ 使用线程池创建线程

线程池七大参数:

① .corePoolSize:线程池中的常驻核心线程数,在创建了线程池后,当有请求任务进来之后,就会安排池中的线程去执行请求任务,近似理解为今日当值线程,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放入缓存队列中。

② .maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1

③ .keepAliveTime:多余的空闲线程的存活时间。当前线程池数量超过corePoolSize时,当空闲时间达到keepAliveTime值时,多余空闲线程会被销毁直到只剩下corePoolSize个线程为止,默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池找那个的线程数不大于corePoolSize。

④ .unit:keepAliveTime的单位

⑤ .workQueue:任务队列,被提交但尚未被执行的任务

⑥ .threadFactory:表示生成线程池中工作线程的线程工厂,用于创建线程一般默认即可

⑦ .handler:拒绝策略,表示当队列满了并且工作线程大于等于线程池最大线程数(maximumPoolSize)时如何处理

 

8. Udp数据报丢失怎么处理,在应用层处理的具体实现,选择udp而不是tcp的原因是什么?

UDP因为自身特性,尽最大可能传输,但是不保证数据的准确性,会有一定的数据丢失

选择UDP的情况:

当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。
比如,日常生活中,常见使用UDP协议的应用如下:QQ语音、QQ视频

9.部署在公网环境用udp是否可以?可以

10.如何解决粘包?加长度 具体的回答,说一下思路。(跳过)

答:粘包因为1.发送端使用Nagle算法2.接收端来不及接收  解决1.将数据包的长度加进去2.多线程接收 面试官反问接收端能解决吗?我懵逼,这个我从牛客看到有人这样说的。
 
10.数据表的设计?
数据表的设计要求尽量遵循三大范式:
①  第一范式(所有字段都是不可分解的原子值)
    第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式。
 
② 第二范式(确保表中的每列都和主键相关)

第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

 订单信息表:

这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示。

这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可。

                 

③ 第三范式(确保每列都和主键列直接相关,而不是间接相关)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。

这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余。

 
 
11. Mysql安全恢复 备份,如果磁盘坏了小部分坏了还能提供服务 融灾机制  项目商用机制  系统的健壮性  可伸缩性。
答:InnoDB有崩溃后的安全恢复机制,然后具体不清楚了。

 
12. 进程和线程区别和联系
 
区别:
① 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
③ 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程不可见;
 
 
联系:
① 一个进程可以包含多个线程
② 在没有实现线程的操作系统中,进程是资源分配的基本单位,也是调度的基本单位,它是系统中并发执行的单元;在实现线程的操作系统中,进程是资源分配的基本单位,但是线程是调度的基本单位,是并发执行的单元
 
 
 
13. 进程间通信方式
① 匿名管道:: 匿名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
② 命名管道:命名管道也是半双工的通信方式,它允许无亲缘关系进程间的通信,是一种文件类型
③ 高级管道:将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式
④ 消息队列: 消息队列是消息的链接表,存放在内核中,一个消息队列由一个标识符(即队列ID)来标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
⑤ 信号量: 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段
⑥ 信号: 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
⑦ 共享内存: 共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
⑧ 套接字:套解字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。
 
 
14. 数据库数据越来越多怎么办 分布式?
对于大表的优化,不一定上来就分库、分表,因为开发和运维的复杂度可能会直线上升,首先可以考虑单表的优化
单表优化可以从以下几个角度出发:
① 表分区:
② 增加缓存:减少对数据库的访问,客户端缓存、数据库访问层对sql语句的缓存、应用程序内的缓存、第三方缓存等
③ 字段设计优化:varchar分配给真正需要的空间,避免使用null,不要滥用bigint/id,
④ 索引优化:经常查询的字段加上索引、尽量不用unique,尽量不要在数据库层面约束表之间的关系,表之间的依赖应该在代码层面去解决,当表和表之间有约束时,虽然增删查的SQL语句变简单了,但是带来的负面效果是插入等操作数据库都会去检查约束(虽然可以手动设置忽略约束),这样相当于把一些业务逻辑写到了数据库层,不便于维护。
 
当数据量进一步增大时,考虑表拆分
① 垂直拆分:垂直拆分的意思就是把一个字段较多的表,拆分成多个字段较少的表
② 水平拆分:就是我们常说的分库分表了;分表,解决了单表数据过大的问题,但是毕竟还在同一台数据库服务器上,所以IO、CPU、网络方面的压力,并不会得到彻底的缓解,这个可以通过分库来解决。水平拆分优点很明显,可以利用多台数据库服务器的资源,提高了系统的负载能力;缺点是逻辑会变得复杂,跨节点的数据关联性能差,维护难度大(特别是扩容的时候)。
 
 
15.你对后端工程师的理解
 

16. 数组、链表的特性还给了一个具体的情景问题让选择用哪个效率更高
 
数组特性:内存中逐个存放,上一个地址是A,下一个就是A+1;数组一但被显示声明之后,大小固定,不能动态扩充;数组的查询和修改方便;数组具有下标,可以通过下标索引到数组元素
链表特性:链表的每个节点没有相对固定的位置关系;链表可以动态生成节点并添加到已有链表后;链表的增加和删除效率高
单链表:链表每一个元素都要保存一个指向下一个元素的指针 
双链表:每个元素即要保存到下一个元素的指针,还要保存一个上一个元素的指针。  
循环链表:最后一个元素中保存的下一个元素指针是指向第一个元素
 
17. 讲讲对socket的看法(因为有个项目涉及到了socket)。我就讲了用于c/s通信,又说了一遍socket的连接创建过程。这个确实了解的不太多,只知道bind、listen、close。。。。。
 socket是什么:是一组接口,将复杂的TCP/IP协议族封装到socket抽象层上,介于应用层和运输层之间;
解决什么问题:解决了计算机进程间通信问题
利用socket建立网络连接的步骤:
 
服务器端:socket()-bind()端口绑定-listen()端口监听-accept()阻塞等待客户端连接-read()读取数据-write()处理请求回应数据-close()结束连接
 
① 服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
② 客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
③ 连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
 

 

 

 
 
18. 讲讲mysql的四种??(好像是视图)类型(有个项目用了mysql)。这个我直接跳了,对mysql了解也不深,是一年前用过的。我都不知道他题目问的啥。。。。但感觉这道题应该是送分的。。。。可惜了
 
 
19. 讲讲html、css、js三者的关系(因为简历的专业技能一项里写上了这三个

分类:

技术点:

相关文章:

  • 2021-12-16
  • 2021-10-02
  • 2021-04-07
  • 2022-12-23
  • 2021-12-13
  • 2021-10-12
  • 2021-05-07
  • 2021-08-30
猜你喜欢
  • 2021-11-04
  • 2021-10-12
  • 2021-11-12
  • 2021-08-17
  • 2021-05-06
  • 2021-11-18
相关资源
相似解决方案