这篇文章中所列出的面试题基本上都是我们日常经常能够听到和用到的一些词汇和概念,这些题目的主要目的是衡量应聘者对于新技术的敏感程度和对常用技术的把握程度。
专题系列文章:
对设计模式的理解,简述你了解的设计模式?
设计模式是经过总结,优化的,对我们经常会碰到的一些编程问题的可重用解决方案。一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码,反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。
针对性评价目标:知识面以及总结能力。
IO密集型和CPU密集型区别,线程和进程都适用于哪个场景?
IO密集型:系统运行,大部分的状况是CPU在等 I/O(硬盘/内存)的读/写。多线程适合应用于IO密集型操作(读写数据操作比多的的,比如爬虫)。
CPU密集型:大部分时间用来做计算,逻辑判断等CPU动作的程序称之CPU密集型。多进程适合应用于CPU密集操作(CPU操作指令比较多,如位多的的浮点运算)。
针对性评价目标:对于操作系统中常见概念的区分和使用。
并行(parallel)和并发(concurrency)的区别?线程和进程哪个是并行,哪个是并发?
并行: 同一时刻多个任务同时在运行。进程是并行。
并发:不会在同一时刻同时运行,存在交替执行的情况。线程是并发。
针对性评价目标:多线程的基本概念,以及术语使用的准确程度。
为什么要使用分布式ID?分布式ID生成策略有哪些?
在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID不能满足需求,此时一个能够生成全局唯一ID的系统是非常必要的。
分布式ID生成策略要求:
- 全局唯一性:不能出现重复的ID号,既然是唯一标识,这是最基本的要求。
- 趋势递增:在MySQL InnoDB引擎中使用的是聚集索引,由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
- 单调递增:保证下一个ID一定大于上一个ID,例如事务版本号、IM增量消息、排序等特殊需求。
- 信息安全:如果ID是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定URL即可;如果是订单号就更危险了,竞争对手可以直接知道我们一天的单量。所以在一些应用场景下,会需要ID无规则、不规则。
- 分布式ID里面最好包含时间戳,这样就能够在开发中快速了解这个分布式ID的生成时间。
常见分布式ID生成算法:UUID/GUID、Snowflake、数据库自增ID、Redis生成。
针对性评价目标:分布式下的信息管理策略。
了解RPC吗?简要描述一下什么是RPC?
在分布式计算,远程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。RPC是一种服务器-客户端(Client/Server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统。
如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,例:Java RMI。
RPC是一种进程间通信的模式,程序分布在不同的地址空间里。如果在同一主机里,RPC可以通过不同的虚拟地址空间(即便使用相同的物理地址)进行通讯,而在不同的主机间,则通过不同的物理地址进行交互。许多技术(常常是不兼容)都是基于这种概念而实现的。
针对性评价目标:分布式服务通信基础。
简述一下 TCP 和 UDP 的区别
TCP(传输控制协议)与UDP(用户数据报协议)之间有以下几个区别:
- 连接与无连接:TCP是一种面向连接的协议,通信双方在传输数据之前需要先建立连接,然后才能进行数据传输。而UDP是一种无连接的协议,通信双方可以直接发送数据,无需建立连接。
- 可靠性:TCP提供可靠的数据传输,它使用确认机制、重传机制和顺序控制来确保数据的可靠传输。而UDP不提供可靠性保证,它只是简单地将数据从一个端点发送到另一个端点,不保证数据的正确性和顺序性。
- 延迟和带宽利用率:由于TCP使用了可靠性机制,它的传输延迟较高,适用于对传输速度要求较高但对延迟要求相对较低的应用,如网页浏览、文件传输等。而UDP没有可靠性机制,传输延迟较低,适用于对传输速度要求较高但对延迟要求较低的应用,如音视频传输、实时游戏等。
- 消息边界:TCP是基于字节流的协议,它没有消息边界的概念,发送方的数据可以被接收方按任意大小的数据块进行接收。而UDP是基于数据报的协议,每个UDP数据报都有固定的大小,接收方按照数据报的边界进行接收。
- 拥塞控制:TCP具有拥塞控制机制,它可以根据网络的拥塞程度动态调整数据的传输速率,以避免网络拥塞。而UDP没有拥塞控制机制,它将数据以恒定的速率发送,不考虑网络的拥塞程度。
TCP 为什么需要进行三次握手?
TCP协议进行三次握手的目的是为了建立一个可靠的通信连接。具体来说,三次握手的过程如下:
- 第一次握手:客户端发送一个SYN(同步)报文给服务器,并指定客户端的初始序列号(ISN)。
- 第二次握手:服务器收到客户端的SYN报文后,会发送一个SYN-ACK(同步-确认)报文给客户端作为响应,并指定服务器的初始序列号(ISN)。
- 第三次握手:客户端收到服务器的SYN-ACK报文后,会发送一个ACK(确认)报文给服务器,表示客户端已经收到了服务器的响应。
通过三次握手,客户端和服务器完成了彼此之间的初始化序列号的交换,并确认了彼此都能够正常收发数据。这样就建立了一个可靠的通信连接,双方可以开始进行数据传输。三次握手的过程中,每次握手都需要对方的确认,这样可以确保双方都准备好了进行数据传输。同时,三次握手还可以防止已经失效的连接请求报文段被服务器接收并误认为是新的连接请求。
TCP 粘包是如何发生的?
TCP粘包是指在TCP传输过程中,发送方发送的多个小数据包被接收方接收成一个大数据包的现象。这种现象通常是由于发送方连续发送的多个数据包在网络传输过程中被合并成一个数据包,导致接收方无法正确解析和处理数据。
TCP粘包的发生原因主要有以下几个方面:
- 数据发送速度过快:当发送方连续发送多个小数据包时,如果发送速度过快,可能会导致这些小数据包在传输过程中被合并成一个大数据包。
- TCP缓冲区大小限制:TCP协议在发送和接收数据时会使用缓冲区来缓存数据。如果发送方的数据发送速度大于接收方的数据接收速度,发送方的数据可能会在发送缓冲区中排队等待发送,而接收方可能无法及时接收这些数据,导致数据包合并成一个大数据包。
- 网络拥塞:当网络出现拥塞时,数据包的传输可能会出现延迟或丢失。如果发送方连续发送的多个数据包在网络传输过程中被延迟或丢失,接收方在接收到这些数据包时可能会将它们合并成一个大数据包。
为了解决TCP粘包问题,可以采取以下几种方法:
- 设置数据包边界:在发送方和接收方之间定义一个数据包边界,例如在数据包前面添加固定长度的头部,接收方根据头部信息将接收到的数据包进行拆分。
- 使用特殊字符分隔数据包:在发送方发送数据包时,在每个数据包的末尾添加一个特殊字符作为分隔符,接收方根据分隔符将接收到的数据包进行拆分。
- 使用消息长度字段:在发送方发送数据包时,在每个数据包的头部添加一个表示数据包长度的字段,接收方根据这个长度字段将接收到的数据包进行拆分。
- 使用应用层协议解决:在应用层协议中定义数据包的格式和解析方式,确保发送方和接收方对数据包的解析一致。
OSI 的七层模型都是哪七层?常见的应用和服务都分属其中的哪一层?
OSI的七层模型包括以下七层:
- 物理层(Physical Layer):负责传输数据的物理介质,如电缆、光纤等。它处理的是比特流的传输。
- 数据链路层(Data Link Layer):负责将物理层传输的比特流转换为数据帧,并提供错误检测和纠正的功能。它处理的是帧的传输。
- 网络层(Network Layer):负责将数据帧从源主机传输到目标主机,它提供了网络间的路由和寻址功能。它处理的是数据包的传输。
- 传输层(Transport Layer):负责在源主机和目标主机之间建立可靠的数据传输连接,提供端到端的数据传输服务。它处理的是段的传输。
- 会话层(Session Layer):负责建立、管理和终止应用程序之间的会话。它处理的是会话的管理。
- 表示层(Presentation Layer):负责数据的格式化、加密和解密等操作,确保应用程序能够正确解析和处理数据。它处理的是数据的表示。
- 应用层(Application Layer):负责提供各种应用程序和服务,如电子邮件、文件传输、网页浏览等。它处理的是应用数据。
什么是工厂模式?简单工厂和抽象工厂有什么区别?
工厂模式是一种创建对象的设计模式。它提供了一种封装对象创建过程的方式,使得创建对象的代码与使用对象的代码分离。通过工厂模式,可以将对象的创建和具体实现解耦,同时可以灵活地添加、替换或扩展对象的创建逻辑。
在工厂模式中,通常会定义一个工厂类,该工厂类负责创建具体的对象。它通过提供一个公共的接口或方法来创建对象,并隐藏了对象创建的具体细节。通过调用工厂类的方法,客户端代码可以获取所需的对象,而无需关心对象的创建过程。
工厂模式主要有三种常见的实现方式:
- 简单工厂模式(Simple Factory Pattern):由一个工厂类来负责创建所有的产品对象。客户端通过工厂类的静态方法或者非静态方法来获取所需的对象。
- 工厂方法模式(Factory Method Pattern):每个具体的对象都有一个对应的工厂类,客户端通过调用具体的工厂类来获取所需的对象。
- 抽象工厂模式(Abstract Factory Pattern):定义了一个工厂接口,该接口可以创建一组相关或相互依赖的对象。客户端通过调用工厂接口的方法来获取所需的对象,具体的工厂类负责创建具体的对象。