【腾讯科技】测试开发会议1面

介绍项目

项目是基于 HTTP 协议实现的点餐系统,主要分为客户端和服务器,客户端是通过网页访问的形式模拟用户进行点餐,而服务器实现的是解析数据,并给出响应,我所做的工作是,在后台服务器开发供用户调用的接口,比如说查看订单,新增订单,修改订单等等

另外服务器分为存储和 web 两个部分,web 服务器是通过 httplib 库实现,数据库是通过 C 语言的方式进行封装数据库常用的操作

数据是怎么从客户端传输到服务器的?
通过 HTTP 协议,将需要传输的数据序列化组装在 http 协议的 body 部分,或者首部字段中,然后生成请求报文给服务器发过去,在这过程中,会经历三次握手,服务器收到报文后按照 http 固定的协议格式进行解析数据以及进行反序列化,然后通过解析出的数据对数据库进行操作,最后给出响应的数据,生成响应报文发送给客户端

服务器的接口是怎么设计的?
使用 Restful 风格的 apl ,路径是可以自定以的,参数是一个 lambda 表达式,POST 作为插入数据,GET 是进行查找的,PUT 进行修改,DELETE 进行删除,url/path 表示要操作的资源在服务器下的路径.

数据是怎么解析的?
大致可以分为四个步骤
1、解析输入型参数中 json 格式的数据,如果失败意味着请求的数据的格式有误,返回给客户端 400 的状态码以及状态码解释,如果解析正确则进行下一步.

2、数据解析成功后进行参数的校验,看它是否为空或者数据是否非法,如果出错依然返回给客户端错误的状态码,如果参数合法则进行下一步.

3、如果前两步都没有问题,则进行数据库的操作,这一步是更新数据库中的数据,如果发生出错,则是服务器内部有问题,返回给 500 的状态码

4、如果数据库操作成功,则封装正确的状态码 200 返回给客户端

自己如何实现一个服务器

对于服务器第一步同样需要创建套接字,然后将端口号和 IP 地址绑定在一个套接字上,就比如我们通常使用的 HTTP 协议固定端口号时 80 ,那么我们在绑定的是需要避开这些常用的端口,(443 HTTPS,22 SSH远程连接),当绑定之后服务器进入监听状态,这个过程是调用 socket apl listen 函数,可以指定在同一时间最大的连接数,之后服务器进入处理事件的逻辑,在这个逻辑里面,首先调用 accept 函数阻塞等待客户端的连接,当收到一个请求时,通过调用 socket apl recv 函数去接收客户端发来的数据并进行解析,服务器经过处理后,就可以通过调用 send 函数将服务器处理的结果返回给客户端

说一下网络 7 层模型

7层模型分别是应用层,表示层、会话层、传输层、网络层、数据链路层和物理层

应用层完成的是应用程序之间的沟通,可以对数据进行解析和封装,表示层主要负责的是数据之间的格式转换,会话层负责建立连接和断开连接,管理网络设备的会话连接,传输层是实际的建立和断开连接,主要的协议有 TCP 和 UDP ,其中 TCP 可以保障可靠的传输,网络层主要负责将数据传输到目标网络地址,有地址管理和路由选择的功能,数据链路层负责两个节点之间的数据传输,物理层是传输的介质和信号的切换.

TCP 和 UDP 的区别

TCP 面向有连接,传输可靠,主要体现在传输数据之前需要先建立连接,在传输的过程中,收到数据后有确认应答机制,丢包后有超时重传机制,以及检验和,序列号和窗口控制保证传输的可靠性.

UDP 协议面向数据报,是不可靠的传输协议,使用 UDP 协议很容易发生丢包的现象,但是它的传输速率比 TCP 快

TCP 发出的数据是有序的,可以通过序列号进行排序,对于 UDP 是不保证任何的有序数据

TCP 不保证数据的边界,因为它是以数据流的方式发送,而且在接收数据的时候会有粘包现象,所以需要在包的头部明确它的长度,或者通过明确的标志表明数据的边界,对于 UDP 是不需要的,而且也没有粘包现象,因为它本身的数据就是一个完整的数据报.可以一次性读取和发送.

TCP 一般情况下在效率要求低,准确度高的场景,比如远程连接,邮件发送,UDP 用于效率要求高,对准确度低的场景,比如打电话,qq聊天,视频通话,广播等

UDP 如何保证数据的准确性

通过校验和来判断数据是否错误,如果校验和出错,收到的包会被全部丢弃,对于更加详细的控制,需要交给应用程序处理

TCP 和 UDP 为什么需要进行校验和,目的是什么
因为数据在进行传输的过程中,可能由于路由器的故障,或者程序漏洞导致数据被破坏,在这种情况下,就可以通过校验和计算并且判断协议首部或者数据是否被破坏.

进程的线程的区别?

进程可以理解为一个程序被动态加载到内存中,它是操作系统分配资源的基本单位,实现操作系统的并发

线程依赖于进程的存在,系统直接交资源分配给进程,线程共享的是进程资源,线程运行在 CPU 上,所以可以理解为进程内部的控制序列,它是 CPU 调用的基本单位

由于线程共享进程的地址空间,所以在创建和调度方面,线程效率要更快,每个线程虽然共享进程的数据空间和代码段,但是依然有自己独立的运行栈和程序计数器,目的是存放局部变量和临时变量,以及线程调度的时候保存上下文信息.

在通信方面,进程有自己的通信方式,比如管道、消息队列,共享内存、信号量、套接字,而线程可以访问全局变量的方式实现通信,但是会有线程不安全的情况,可以通过互斥锁和条件变量以及信号量来保证线程访问的安全性和合理性,所以线程的编写难度比进程大

线程的健壮性比进程弱,也就是说,如果一个进程挂掉,是不会影响到其他的进程,因为他们之间是相互独立的,但是如果一个线程挂掉,可能会导致整个进程挂掉,也可能导致系统的卡死

对于多进程和多线程来说,多进程指的是一个计算机系统运行两个或者两个以上的进程处于运行状态,比如一边听音乐,一边写代码,这个就是多进程,现代操作系统几乎都是多任务操作系统,能同时管理多个进程的运行

多线程指的是并行而不是并发,所以它的场景是多核分布,在这种情况下,多线程的运行效率比较高效

你可能感兴趣的:(C++校招面试合集)