gRPC vs RPC 高频面试题

一、gRPC 最常见面试题

gRPC 是什么?它和传统 REST 有什么区别?

  • 考察你是否理解 gRPC 的定义、通信协议(HTTP/2)、序列化方式(Protocol Buffers)以及与 REST 的性能、数据格式差异。

一、gRPC 是什么?

  • 定义 :gRPC 是 Google 开源的 高性能、跨语言的 RPC 框架 ,基于 HTTP/2 协议,使用 Protocol Buffers(Protobuf) 作为接口定义语言(IDL)和序列化协议。
  • 核心目标:让不同语言的服务之间可以像调用本地方法一样进行远程调用,同时保证高性能和可扩展性。
  • 跨语言支持:Java、Go、Python、C++、Node.js、C# 等。

二、gRPC 核心原理

  1. 接口定义

    • 使用 .proto 文件定义服务和消息结构。
    • 通过 protoc 编译器生成各语言的客户端和服务端代码。
  2. 通信协议

    • 基于 HTTP/2,支持多路复用、流式传输、头部压缩、双向通信。
  3. 序列化方式

    • 使用 Protobuf,二进制格式,体积小、解析快。
  4. 调用流程

    • 客户端调用 → 序列化请求 → HTTP/2 传输 → 服务端反序列化 → 执行方法 → 序列化响应 → 返回客户端。

三、gRPC 与传统 REST 的区别

对比维度 gRPC REST
协议 HTTP/2 HTTP/1.1
数据格式 Protobuf(二进制) JSON(文本)
性能 高性能,低延迟 相对较慢
通信模式 支持四种模式(Unary、Server streaming、Client streaming、Bidirectional streaming) 单请求-单响应
类型安全 强类型(IDL 定义) 弱类型(JSON)
跨语言支持 自动生成多语言代码 需手动编写客户端
可读性 二进制不可读 JSON 可读
适用场景 微服务内部高性能通信 对外 API、浏览器调用

四、使用场景分析

  • 适合 gRPC 的场景
    • 微服务之间的高性能通信
    • 多语言服务交互
    • 需要流式数据传输(如实时聊天、视频流)
  • 适合 REST 的场景
    • 对外开放 API
    • 浏览器直接调用
    • 需要人类可读的调试数据

五、面试高分答法

gRPC 是 Google 开源的高性能、跨语言 RPC 框架,基于 HTTP/2 协议,使用 Protobuf 进行序列化。它通过 .proto 文件定义接口,自动生成多语言客户端和服务端代码,支持四种通信模式,包括双向流式通信。

与传统 REST 相比,gRPC 在性能、类型安全、跨语言支持和通信模式上更优,但可读性较差,适合微服务内部高性能通信;REST 则更适合对外 API 和浏览器调用。

六、示例:

需求场景

我们有一个 用户服务 ,需要提供一个接口:
根据用户 ID 获取用户信息(包含姓名、邮箱、年龄)。


1. REST 示例

接口定义(HTTP/1.1 + JSON):

复制代码
GET /user/123

返回数据(JSON,可读性强)

java 复制代码
{
  "id": 123,
  "name": "Alice",
  "email": "alice@example.com",
  "age": 25
}

调用方式

  • 浏览器直接访问 http://api.example.com/user/123
  • 或者用 curl
bash 复制代码
curl http://api.example.com/user/123

特点

  • 可读性强(JSON)
  • 跨平台方便(浏览器、Postman 都能直接调)
  • 性能一般(文本格式,体积大)

2. gRPC 示例

接口定义.proto 文件):

java 复制代码
syntax = "proto3";

service UserService {
  rpc GetUser (UserRequest) returns (UserResponse);
}

message UserRequest {
  int32 id = 1;
}

message UserResponse {
  int32 id = 1;
  string name = 2;
  string email = 3;
  int32 age = 4;
}

调用方式

  • 客户端调用生成的 UserServiceStub
java 复制代码
UserRequest request = UserRequest.newBuilder().setId(123).build();
UserResponse response = userServiceStub.getUser(request);
System.out.println(response.getName());

返回数据(Protobuf 二进制,不可直接读)

  • 在网络上传输的是压缩后的二进制数据,比 JSON 小很多。

特点

  • 性能高(二进制序列化,体积小)
  • 强类型(编译时生成代码)
  • 不适合直接用浏览器调试(需要客户端 Stub)

直观对比

维度 REST gRPC
协议 HTTP/1.1 HTTP/2
数据格式 JSON(可读) Protobuf(二进制)
调用方式 URL + HTTP 方法 生成的客户端 Stub 调用
性能 较慢 高性能
调试 浏览器/工具直接调 需专用客户端
适用场景 对外 API 微服务内部通信

💡 面试技巧

当面试官问"gRPC 和 REST 有什么区别"时,你可以先用一句话总结理论,然后用这个用户服务的例子快速对比,这样既有深度又有落地感。

gRPC 的四种通信模式是什么?

  • Unary(单次请求响应)
  • Server streaming(服务端流式响应)
  • Client streaming(客户端流式请求)
  • Bidirectional streaming(双向流式通信)

一、gRPC 的四种通信模式

gRPC 基于 HTTP/2,支持四种通信模式:

  1. Unary RPC(单次请求-单次响应)
  2. Server Streaming RPC(服务端流式响应)
  3. Client Streaming RPC(客户端流式请求)
  4. Bidirectional Streaming RPC(双向流式通信)

二、详细讲解 + 示例

1. Unary RPC(单次请求-单次响应)

定义:客户端发送一次请求,服务端返回一次响应,类似传统 REST 调用。

示例 .proto

java 复制代码
service UserService {
  rpc GetUser (UserRequest) returns (UserResponse);
}

调用流程

  1. 客户端构造 UserRequest(包含用户 ID)。
  2. 发送到服务端。
  3. 服务端处理请求,返回 UserResponse
  4. 连接关闭。

特点

  • 最简单的模式
  • 类似 HTTP GET/POST
  • 适合一次性数据查询

2. Server Streaming RPC(服务端流式响应)

定义 :客户端发送一次请求,服务端返回一个数据流,可以持续推送多条消息。

示例 .proto

java 复制代码
service OrderService {
  rpc ListOrders (OrderRequest) returns (stream OrderResponse);
}

调用流程

  1. 客户端发送 OrderRequest(如用户 ID)。
  2. 服务端开始不断推送 OrderResponse(每条订单一条消息)。
  3. 客户端逐条接收,直到服务端结束流。
  4. 连接关闭。

特点

  • 适合批量数据返回(如订单列表、日志流)
  • 客户端可以边接收边处理
  • 减少多次请求的开销

3. Client Streaming RPC(客户端流式请求)

定义 :客户端发送一个数据流给服务端,服务端在接收完所有数据后返回一次响应。

示例 .proto

java 复制代码
service UploadService {
  rpc UploadFile (stream FileChunk) returns (UploadStatus);
}

调用流程

  1. 客户端不断发送 FileChunk(文件分片)。
  2. 服务端接收并处理每个分片。
  3. 当客户端发送完成,服务端返回 UploadStatus(如成功/失败)。
  4. 连接关闭。

特点

  • 适合大文件上传、批量数据提交
  • 服务端在接收完全部数据后才返回结果

4. Bidirectional Streaming RPC(双向流式通信)

定义 :客户端和服务端都可以同时发送数据流,互相独立,不必等待对方完成。

示例 .proto

java 复制代码
service ChatService {
  rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}

调用流程

  1. 客户端和服务端建立连接。
  2. 客户端发送 ChatMessage,服务端立即返回 ChatMessage
  3. 双方可以同时发送和接收消息。
  4. 连接在双方都结束流时关闭。

特点

  • 适合实时聊天、视频通话、实时数据推送
  • 双方可以并行通信
  • 需要处理并发和流控制

三、四种模式流程对比

模式 请求次数 响应次数 适用场景
Unary 1 1 查询单条数据
Server Streaming 1 批量数据返回
Client Streaming 1 大文件上传
Bidirectional Streaming 实时通信

四、面试高分答法

gRPC 基于 HTTP/2,支持四种通信模式:Unary(一次请求一次响应)、Server Streaming(一次请求多次响应)、Client Streaming(多次请求一次响应)、Bidirectional Streaming(多次请求多次响应)。

例如,查询用户信息用 Unary;获取订单列表用 Server Streaming;上传大文件用 Client Streaming;实时聊天用 Bidirectional Streaming。

这些模式让 gRPC 在微服务内部通信、实时数据传输等场景比 REST 更灵活高效。

gRPC 为什么使用 HTTP/2?有什么优势?

  • 多路复用、头部压缩、双向流、低延迟等。

一、背景

  • gRPC 是 Google 开源的高性能 RPC 框架,目标是 低延迟、高吞吐、跨语言
  • 传统 REST 大多基于 HTTP/1.1 ,但 HTTP/1.1 在性能和功能上有一些限制:
    • 队头阻塞(同一连接一次只能处理一个请求)
    • 连接复用效率低
    • 头部冗余大(每次请求都要重复发送大量 HTTP 头)
    • 不支持原生双向流

二、gRPC 为什么选择 HTTP/2

gRPC 需要:

  1. 多路复用(同时处理多个请求)
  2. 低延迟(减少等待时间)
  3. 双向流式通信(实时数据传输)
  4. 高效压缩(减少带宽占用)
  5. 更好的连接管理(长连接)

HTTP/2 正好满足这些需求。


三、HTTP/2 的优势

1. 多路复用(Multiplexing)

  • 在一个 TCP 连接上同时发送多个请求和响应,互不阻塞。
  • 解决了 HTTP/1.1 的队头阻塞问题。
  • gRPC 利用场景:多个 RPC 方法可以并行执行,不需要为每个请求建立新连接。

2. 头部压缩(Header Compression)

  • 使用 HPACK 压缩 HTTP 头部,减少冗余数据。
  • gRPC 利用场景:Protobuf 本身数据很小,头部压缩进一步降低带宽占用。

3. 双向流(Bidirectional Streaming)

  • 客户端和服务端可以在同一连接上同时发送数据。
  • gRPC 利用场景:实现四种通信模式中的流式模式(Server Streaming、Client Streaming、Bidirectional Streaming)。

4. 长连接(Persistent Connection)

  • 一个连接可以长期保持,减少频繁建立连接的开销。
  • gRPC 利用场景:微服务之间的持续通信。

5. 更好的优先级控制

  • HTTP/2 可以为不同的流设置优先级,优化资源分配。
  • gRPC 利用场景:在高并发场景下优先处理关键请求。

四、面试高分答法

gRPC 选择 HTTP/2 是因为它提供了多路复用、头部压缩、双向流、长连接等特性,这些特性可以显著提升 RPC 调用的性能和灵活性。

例如,HTTP/2 的多路复用让多个 RPC 方法可以在同一连接上并行执行,双向流支持实时通信,头部压缩减少带宽占用,这些都是 HTTP/1.1 无法高效实现的。

gRPC 的序列化协议是什么?为什么选择它?

  • Protocol Buffers(Protobuf),高效、跨语言、结构化。

一、gRPC 的序列化协议是什么?

  • gRPC 默认使用 Protocol Buffers(简称 Protobuf) 作为 接口定义语言(IDL)序列化协议
  • 作用
    1. IDL :用 .proto 文件定义服务接口和数据结构。
    2. 序列化协议:将数据结构转换为二进制格式进行传输,并在接收端反序列化为对象。

二、为什么选择 Protobuf?

gRPC 的目标是 高性能、跨语言、可扩展,而 Protobuf 在这些方面表现优异:

  1. 高性能

    • 二进制格式,体积小,解析速度快。
    • 比 JSON、XML 更节省带宽和 CPU。
  2. 跨语言支持

    • 官方支持 Java、Go、Python、C++、C#、Node.js 等多种语言。
    • .proto 文件编译后自动生成各语言的客户端和服务端代码。
  3. 强类型 & 向后兼容

    • 编译时生成类型安全的代码,避免运行时类型错误。
    • 支持字段的新增、删除,不影响旧版本客户端(通过字段编号管理)。
  4. 结构清晰

    • .proto 文件既是接口文档,也是代码生成的源文件。
    • 开发、维护、调试更方便。
  5. 与 HTTP/2 配合良好

    • 二进制数据在 HTTP/2 的多路复用和头部压缩下传输效率更高。

三、Protobuf 与 JSON 对比

对比维度 Protobuf JSON
格式 二进制 文本
体积
解析速度
类型安全 强类型(编译生成代码) 弱类型(运行时解析)
可读性 不可直接读 可直接读
跨语言支持 自动生成代码 需手动解析
适用场景 微服务内部高性能通信 对外 API、调试友好

四、面试高分答法

gRPC 默认使用 Protocol Buffers 作为序列化协议,因为它是高性能、跨语言、强类型的二进制格式。

相比 JSON,Protobuf 体积更小、解析更快,并且通过 .proto 文件可以自动生成多语言客户端和服务端代码,保证类型安全和向后兼容,非常适合微服务内部的高性能通信。


二、RPC 最常见面试题

什么是 RPC?它的基本原理是什么?

  • 考察你是否能解释 RPC 的概念:像调用本地方法一样调用远程服务,底层通过网络传输数据。

一、什么是 RPC?

  • 定义RPC(Remote Procedure Call,远程过程调用) 是一种像调用本地函数一样调用远程服务的技术。
  • 核心目标:屏蔽网络通信的细节,让开发者像调用本地方法一样调用远程方法。
  • 关键点:开发者不需要关心底层的网络协议、序列化方式、连接管理等。

二、核心思想

本地调用的体验 + 网络通信的能力

RPC 把远程调用封装成一个看起来像本地函数的接口,底层自动完成数据传输和结果返回。


三、RPC 的基本原理

RPC 的工作流程可以拆成 客户端 Stub → 网络传输 → 服务端 Stub → 执行方法 → 返回结果

  1. 客户端调用 Stub 方法

    • Stub 是由 RPC 框架生成的代理对象,方法签名和本地方法一样。
    • 开发者调用时,就像调用本地函数。
  2. 序列化请求数据

    • 将方法名、参数等信息序列化成二进制或其他格式(如 Protobuf、JSON)。
  3. 网络传输

    • 通过 TCP、HTTP/2 等协议将序列化后的数据发送到远程服务端。
  4. 服务端反序列化

    • 服务端 Stub 接收到数据后,反序列化成方法参数。
  5. 执行真实方法

    • 服务端调用实际的业务逻辑方法,得到结果。
  6. 序列化响应数据

    • 将结果序列化成二进制或其他格式。
  7. 返回给客户端

    • 客户端 Stub 接收响应数据,反序列化成对象,并返回给调用方。

四、简单示例

假设我们有一个 获取用户信息 的方法:

客户端调用:

java 复制代码
User user = userService.getUser(123);
System.out.println(user.getName());

底层实际发生的事情:

  1. getUser(123) 被 Stub 拦截。
  2. 参数 123 被序列化成二进制。
  3. 通过网络发送到服务端。
  4. 服务端反序列化成 123
  5. 调用真实的 getUser 方法,查询数据库。
  6. 将结果序列化成二进制。
  7. 发送回客户端并反序列化成 User 对象。

五、面试高分答法

RPC(Remote Procedure Call)是一种让我们像调用本地方法一样调用远程服务的技术。它的原理是通过客户端 Stub 将方法调用序列化成数据,通过网络传输到服务端,服务端 Stub 反序列化后调用真实方法,并将结果序列化返回。这样开发者无需关心底层通信细节,只需像写本地代码一样调用远程方法。

RPC 调用的核心流程是什么?

  • 客户端调用 → 序列化请求 → 网络传输 → 服务端反序列化 → 执行方法 → 序列化响应 → 返回客户端。

一、RPC 调用的核心流程

RPC 调用的核心流程可以分为 客户端发起调用 → 序列化 → 网络传输 → 服务端执行 → 返回结果 五大阶段:


1. 客户端发起调用

  • 开发者调用的是 客户端 Stub(代理对象) 提供的方法,看起来就像调用本地函数。
  • Stub 方法的签名与服务端方法一致,但内部会封装网络通信逻辑。

关键点Stub 是本地调用的入口,它屏蔽了底层的网络细节。


2. 序列化请求数据

  • 将方法名、参数等信息转换成可传输的格式(如 Protobuf、JSON、XML)。
  • 序列化的目标是压缩数据体积保证跨语言解析

关键点序列化协议决定了 RPC 的性能和跨语言能力


3. 网络传输

  • 通过 TCP、HTTP/2 等协议将序列化后的数据发送到服务端。
  • 可能会经过负载均衡、服务发现等中间环节。

关键点网络层负责数据的可靠传输,RPC 框架通常会内置连接管理和重试机制。


4. 服务端反序列化 & 执行方法

  • 服务端 Stub 接收到数据后,反序列化成方法参数。
  • 调用实际的业务逻辑方法(如查询数据库、计算结果)。

关键点服务端 Stub 是远程调用的接收入口,它负责把网络数据还原成可执行的本地方法调用。


5. 序列化响应数据 & 返回

  • 将方法执行结果序列化成可传输格式。
  • 通过网络返回给客户端。
  • 客户端 Stub 接收响应并反序列化成对象,返回给调用方。

关键点响应过程与请求过程对称,同样依赖序列化和网络传输。


二、核心流程总结表

阶段 客户端 服务端
调用入口 Stub 方法 Stub 方法
序列化 请求参数 → 二进制 响应结果 → 二进制
网络传输 发送数据 返回数据
反序列化 响应结果 ← 二进制 请求参数 ← 二进制
执行方法 - 真实业务逻辑

三、面试高分答法

RPC 调用的核心流程是:客户端调用 Stub 方法 → 序列化请求数据 → 通过网络传输到服务端 → 服务端 Stub 反序列化并执行真实方法 → 序列化结果返回给客户端 → 客户端反序列化得到结果。

这样开发者就能像调用本地方法一样调用远程服务,而底层的序列化、网络传输、反序列化过程由 RPC 框架自动完成。

RPC 和 HTTP API 的区别是什么?

  • 协议层、性能、数据格式、调用方式、适用场景的差异。

一、定义回顾

  • RPC(Remote Procedure Call)

    像调用本地方法一样调用远程服务,底层自动完成序列化、网络传输、反序列化。

    常见实现:gRPC、Dubbo、Thrift。

  • HTTP API(REST API)

    基于 HTTP 协议,通过 URL + HTTP 方法(GET/POST/PUT/DELETE)访问资源,通常使用 JSON/XML 作为数据格式。


二、核心区别

对比维度 RPC HTTP API
调用方式 像调用本地方法(函数名 + 参数) 通过 URL 访问资源(路径 + HTTP 方法)
协议层 可基于 TCP、HTTP/2 等 基于 HTTP/1.1 或 HTTP/2
数据格式 二进制(如 Protobuf、Thrift) 文本(如 JSON、XML)
性能 高性能(二进制体积小、解析快) 相对较慢(文本解析开销大)
类型安全 强类型(编译生成代码) 弱类型(运行时解析)
跨语言支持 依赖 IDL 自动生成多语言代码 语言无关,但需手动解析 JSON/XML
可读性 不可直接读(需反序列化) 可直接读(调试方便)
适用场景 微服务内部高性能通信 对外开放 API、跨平台调用

三、场景对比

  • RPC 适合

    • 微服务内部调用(高性能、低延迟)
    • 需要强类型和自动代码生成的场景
    • 实时通信(双向流)
  • HTTP API 适合

    • 对外开放接口(易调试、易理解)
    • 浏览器直接调用
    • 第三方集成(跨语言、跨平台)

四、面试高分答法

RPC 和 HTTP API 的主要区别在于调用方式、协议层、数据格式和性能。

RPC 像调用本地方法一样调用远程服务,通常使用二进制序列化(如 Protobuf),性能高、类型安全,适合微服务内部通信;

HTTP API 基于 URL + HTTP 方法访问资源,通常使用 JSON/XML,易读易调试,适合对外开放接口。

简单来说,RPC 更偏向服务间高性能通信,HTTP API 更偏向对外资源访问

常见的 RPC 框架有哪些?

  • gRPC、Dubbo、Thrift、Hessian 等。
相关推荐
不过普通话一乙不改名19 小时前
Linux 网络发包的极致之路:从普通模式到 AF_XDP ZeroCopy
linux·运维·网络
Macbethad19 小时前
Profinet主站程序技术方案
网络协议·信息与通信
4***175419 小时前
linux 网卡配置
linux·网络·php
XiaoCCCcCCccCcccC20 小时前
多路复用 poll -- poll 的介绍,poll 的优缺点,poll 版本的 TCP 回显服务器
服务器·网络·c++
多看书少吃饭21 小时前
小程序支持HTTP POST 流式接口吗?
网络协议·http·小程序
陈奕昆21 小时前
n8n实战营Day2:复杂逻辑控制·HTTP请求+条件分支节点实操
网络·人工智能·python·网络协议·n8n
h***047721 小时前
IEEE 1588:电信网络的精确时间协议 (PTP)
网络
Han.miracle1 天前
JavaEE-- 网络编程 http请求报头
运维·服务器·网络·网络协议·计算机网络·http
SKYDROID云卓小助手1 天前
三轴云台之控制协同技术
服务器·网络·图像处理·人工智能·算法
云边有个稻草人1 天前
不用公网 IP 也能远程管 MongoDB?本地部署 + cpolar实用方案
网络协议·mongodb·cpolar