
2024 年秋招我投的是 Shopee 的 Client 提前批。说句实话看到题目之前我以为“Client 岗”的笔试重点会是界面框架、组件化、状态管理或者渲染优化这类东西。真正坐到在线笔试页面里我才发现这套题更看重的是一个客户端工程师对“从设备到服务端整条链路”的理解。整场做下来网络协议、API 版本兼容、数据库客户端认证、消息中间件连接、安全传输上下文这些内容占了大头最后还有一道实现网页内容抓取和一道与 MCP Client 连接 LLM 相关的题。这篇文章按我的记忆把考点归了一下类也会写清楚每类题背后的原理和复盘思路给准备走 Client 方向的同学做个参考。1. 提前批笔试到底在考什么Client 不是“写界面”那么简单1.1 题型全貌从选择填空到在线编程我印象里整套卷子分成三个大块客观题、简答/排查题、在线编程题。客观题不是单纯背概念很多题目会给你一段客户端日志或者一条报错信息让你判断根因。比如“firedac phys mysql client does not support authentication protocol requested”这种问你应该怎么处理再比如“client version 1.52 is too new, maximum supported api version is 1.43”让你选客户端版本和 API Server 版本之间的兼容关系。这种考法比“什么是 TCP 三次握手”要狠得多因为它默认你已经知道基础概念直接跳到真实排障场景。简答/排查题更偏向现场分析我遇到的有“Oracle Instant Client 装了之后程序还是提示找不到客户端可能是什么原因”“Kafka 客户端报 out of available brokers 怎么排查”“SAP OData gateway client 测试返回 405 是什么导致的”这类。每道题都需要你按排查链路去写不能只给结论。编程题则是两道完整的小题一道是实现网页内容抓取功能另一道方向比较新围绕 MCP Client 与 LLM 连接来出我记得当时看到题目愣了一下后来发现其实考的是对工具调用协议的理解不算超纲。我按考完后的回忆做了一个模块占比梳理不一定准确但能看个大概知识模块出现形式大致占比HTTP/HTTPS、TLS/mTLS 及安全上下文客观题、简答题20% 左右API 版本协商与客户端兼容客观题15% 左右数据库客户端认证与连接配置客观题、排查题20% 左右Redis/Kafka 等中间件客户端客观题、排查题15% 左右网页抓取与 HTTP 客户端实现在线编程15% 左右MCP client / LLM 工具调用在线编程或扩展题15% 左右1.2 为什么 Client 岗要看这么宽很多同学会对这个范围产生疑问客户端开发不是写界面吗为什么既要懂数据库认证协议又要懂消息中间件、API 版本协商这些后端才常见的东西原因在于Client 是分布式系统里离用户最近的那一层但它不是孤立的。一个客户端要完成登录就会涉及 TLS 握手、OAuth 客户端凭据、后端 API 版本匹配要展示数据就会连数据库或中间件甚至要直连 Redis 做本地缓存要做企业级功能可能还要接 SAP、Oracle、虚拟化平台的管理接口。任何一个环节出问题客户端表现出的就是“连不上”“登录失败”“请求报错”。所以笔试考的不是某个客户端框架的细枝末节而是你能不能从一段报错里快速定位是客户端自身的问题还是服务端、网络、协议版本的问题。这种能力恰恰是业务量上来之后最值钱的排查能力。2. 考场原题复盘版本协商、认证协议与 405 报错2.1 API 版本区间version too new 和 version too old 是同一个坑笔试里有一道题我印象特别深题目给了两段报错一段是“client version 1.52 is too newmaximum supported api version is 1.43”另一段是“status 400: client version 1.24 is too oldminimum supported api version is 1.27”。让你判断这两个场景分别应该怎么处理。这题背后是 API 的版本协商机制。很多云平台和基础组件在客户端接入时并不会无条件兼容所有历史版本而是维护一个最低支持版本和最高支持版本。客户端版本低于最低支持版本服务端会直接拒绝因为老客户端可能缺少必要的字段或安全补丁客户端版本高于最高支持版本服务端也会拒绝因为新客户端可能会发送服务端根本不认识的请求参数。我当时的解题思路是先把“版本区间”这个概念画出来。假设服务端支持的区间是 [1.27, 1.43]那么 1.24 落在左侧之外需要升级客户端到 1.27 及以上1.52 落在右侧之外要么升级服务端让服务端支持到 1.52要么把客户端降级到 1.43 及以下。笔试的选择题陷阱就在这里很多人看到“too new”就条件反射说升级客户端实际上太新和太旧的处理方向是相反的。做这类题关键是看服务端报错里给的边界值而不是凭直觉。2.2 MySQL 客户端认证协议不兼容从一道报错延伸出来的完整排障链路“firedac phys mysql client does not support authentication protocol requested”这条报错我猜不少做过数据库相关开发的人都见过。笔试把它放在了一个场景题里某内部系统升级到 MySQL 8随后所有用老版本 Firedac 物理连接的程序都连不上库客户端直接报 authentication protocol requested问怎么解决。这题的根因在 MySQL 8 的默认认证插件变成了 caching_sha2_password而老版本客户端在握手时只认识 mysql_native_password。服务端要求用 caching_sha2_password 完成认证客户端协议不支持于是握手失败。解决办法有几个方向最稳妥的是升级客户端驱动让它支持新的认证协议如果业务系统不方便升级可以临时把用户默认认证插件改回 mysql_native_password但这会降低安全性还有一种常见做法是给 JDBC 连接串加 allowPublicKeyRetrievaltrue 配合 useSSLfalse让客户端可以通过 RSA 公钥交换密码。笔试里如果问“最安全的方式”优先选升级驱动而不是改服务端插件。这里要补一个很容易被忽略的细节老客户端连 MySQL 8 时除了认证协议不兼容还会出现“Public Key Retrieval is not allowed”的报错。这是因为 caching_sha2_password 在非 SSL 连接下需要获取服务端公钥而客户端默认不允许自动获取。笔试时间充裕的话可以把这两种报错放在一起答会显得你对 MySQL 协议握手的过程真的有理解。2.3 mTLS 和“ssl server requires client certificate”有一道简答题问的是客户端连接某个内部服务时服务端返回“ssl server requires client certificate”这是什么意思客户端要做什么这个考点是双向 TLS也就是 mTLS。正常 HTTPS 是客户端验证服务端证书服务端不验证客户端。而 mTLS 要求客户端也要出示证书由服务端来验证。服务端报“requires client certificate”说明当前连接没有携带客户端证书或者携带的证书不被信任。客户端需要做的事很简单生成或申请一张客户端证书然后在发起请求时把证书和私钥带上。不同语言实现不同Java 里要配置 keystorePython 里 requests 可以传 cert(certfile, keyfile)Go 里用 tls.Config 的 Certificates 字段。这类题考的不只是 API 怎么传参而是让你理解“为什么需要客户端证书”。我当时答的是客户端证书相当于门禁卡服务端通过它确认“你是不是内部设备”防止任何拿到服务端地址的人都能调用接口。这个类比在笔试里用上面试官一般会认可。2.4 SAP OData 网关客户端测试 405HTTP 方法不是你想用就能用热词里有一个“sap sgew gateway client 测试 405报错”我实际笔试中也遇到类似的排查题。SAP 的 OData 服务通过 Gateway Client 测试时如果直接用 GET 去调一个只允许 POST 的资源或者没有在请求头带上 CSRF token很容易返回 405 Method Not Allowed。这道题我的排查思路是先确认 URL 对应的 OData 服务是否真的支持当前 HTTP 方法再检查是否缺少必需的请求头比如 SAP 网关经常要求先发起一次 GET 获取 CSRF token再在写操作里带上这个 token最后看服务端日志确认网关是否把请求正确路由到了后端。三个方向里前两个在客户端本地就能验证第三个需要看服务端。笔试里这种题想拿高分不能只答“方法不对”要写出完整的排查顺序客户端出错先看请求方法再看请求头再看 URL 映射最后看服务端日志。这个顺序本身比答案更有价值。3. 数据库与消息中间件连接不上的坑面试官很爱反复问3.1 Oracle Instant Client环境变量错了就是连不上Oracle Instant Client 的题目属于“看着简单实际全是坑”的类型。笔试给了一个场景下载了 19c 的 64 位 Instant Client装好后程序仍然报找不到 Oracle 客户端问你怎么排查。这题考的是对环境变量的理解。在 Windows 上Oracle Instant Client 解压后必须把目录加到 PATH 里程序运行时才能找到 oci.dll在 Linux 上要设置 ORACLE_HOME 和 LD_LIBRARY_PATH或者 ldconfig 配置否则即使可执行文件存在动态链接库也加载失败。这只是第一步。接下来还要确认 tnsnames.ora 的位置以及程序是否配置了正确的 TNS 连接串。一个常见坑是安装了 64 位 Instant Client但应用本身是 32 位进程两者不匹配仍然连不上。另一个是 NLS_LANG 没设置导致中文乱码或字符集转换报错。我当时把排查链路写成了四步检查位数是否匹配、检查动态库路径、检查 tnsnames.ora 和网络连通性、检查字符集配置。笔试如果给你一段报错“OCIEnvCreate failed with return code -1”要能想到多数是 ORACLE_HOME 或 LD_LIBRARY_PATH 的问题而不是网络问题。3.2 Redis Client协议、连接池、超时一个都不能少Redis 是典型的客户端直连场景笔试里容易出现选择题和简答题。我遇到的选择题是一个 Redis 客户端连接池满了新的请求一直阻塞应该优先调整哪几个参数。这题如果没实际调过连接池很容易选错。连接池核心参数包括 maxTotal、maxIdle、minIdle、maxWaitMillis、testOnBorrow。maxTotal 决定最大连接数maxIdle 决定空闲连接上限maxWaitMillis 决定拿不到连接时最多等多久。如果所有连接都被占用而且 maxWaitMillis 为 -1客户端会无限等待最终表现就是请求卡死。合理的做法是设置一个有限的最大等待时间同时结合 testOnBorrow 在取连接时做一次 PING 校验避免拿到失效连接。Redis 客户端还有一个隐藏考点是 RESP 协议。无论 jredis、go-redis 还是 redisson底层都在按 RESP 协议解析服务端返回。笔试如果问“为什么 Redis 客户端快”除了网络 IO 模型之外也要提到 RESP 协议本身是文本协议解析简单、性能开销低。如果你能随手写出一个极简 RESP 解析流程比如把OK\r\n映射为成功把-ERR ...\r\n映射为错误会显得你真的理解客户端实现。3.3 Kafka 客户端“out of available brokers”不要把锅全甩给网络“client has run out of available brokers to talk to” 这条报错笔试里出现的频率比我想象中高。它表面意思是客户端连不上任何 broker但根因通常不只是网络不通。我建议按以下顺序排查第一bootstrap.servers 配置是否正确包括 host、port以及是否有拼写错误。第二broker 是否真的启动并能被客户端访问可以在客户端机器上用 telnet 或者 nc 测端口。第三客户端版本和 broker 版本是否兼容过老或过新的客户端都可能导致握手失败。第四如果走的是 TLS 或认证模式还要检查证书、用户名密码是否配置正确。笔试里这题容易答偏的原因是很多人只写“网络不通”。实际上线上环境最常见的根因是 bootstrap.servers 只配了单点地址而该 broker 宕机后客户端没有任何备选地址可用。哪怕只是多配几个 broker 地址这个问题就能缓解。另一个常见根因是 Kafka 服务端启用了 SSL但客户端仍然用明文协议去连接导致握手被直接断开表现为“no available brokers”。3.4 SAP 不同 Client 配置传输一个容易被忽略的企业级场景热词里有“sap s4 不同client传输 po输出生成so的配置”这个方向偏企业级应用。SAP 里的 Client 与通用软件里的 Client 语义不完全一样它更多是系统内部的数据隔离层。企业里通常有开发 Client、测试 Client、生产 Client配置或程序的变更需要从开发 Client 传输到生产 Client。笔试里如果出现这类场景一般不会考具体事务代码而是考你对“客户端环境隔离 配置传输”这个概念的理解。比如 PO 输出生成销售订单SO的配置在某个 Client 下生效但另一个 Client 没生效大概率是传输请求没有完整包含相关配置项。这类题更看重你有没有跨系统、跨环境联调的经验能在排障时想到“是不是配置只落在单个 Client 上”而不是只盯着代码逻辑。4. 编程题从“实现网页抓取”到“MCP Client 连接 LLM”4.1 实现网页内容抓取功能代码要能跑思路要完整提前批笔试的编程题有一道是让实现抓取网页内容的功能。题干不会特别复杂通常会要求你传入一个 URL返回页面中的正文文本。我理解这道题的核心考察点不只是“会不会发 HTTP 请求”而是你写出来的代码能不能处理真实网页里的各种意外情况。我当时用 Python 写了个简化版本思路是先请求页面再解析 HTML最后提取正文文本。核心代码如下import requests from bs4 import BeautifulSoup def fetch_page_text(url): headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) } resp requests.get(url, headersheaders, timeout10) resp.raise_for_status() # 根据响应头里的 charset 处理编码避免中文乱码 if resp.encoding is None or resp.encoding.lower() iso-8859-1: resp.encoding resp.apparent_encoding soup BeautifulSoup(resp.text, html.parser) for tag in soup([script, style, noscript]): tag.decompose() return soup.get_text(separator\n, stripTrue)这里有几个细节很容易被忽略。第一个是 User-Agent很多站点会拦截裸 requests 请求加上常见浏览器的 User-Agent 是基础操作。第二个是编码问题如果服务器返回的响应头没有指定 charset或者错误地指定了 iso-8859-1直接用 resp.text 可能中文乱码所以要靠 apparent_encoding 做兜底。第三个是异常处理笔试环境网络不一定稳定请求超时、连接失败、404 都要能兜住不能让整个程序崩溃。如果你选择用 Java 写核心逻辑也类似用 HttpClient 发 GET 请求拿到响应后交给 Jsoup 解析。重点不在用哪个库而在于你能否把抓取流程拆成“请求、解析、清洗”三层。我当时还把清洗做了扩展把 script、style、noscript 标签全部去掉再按空行切分文本这样提取出的正文信息密度更高。4.2 MCP Client 与 LLM 连接理解“工具调用”比写代码更重要最后一道编程题跟 MCP Client 有关我看到题目时确实愣了一下。MCPModel Context Protocol是模型上下文协议的简称它在 LLM 应用与外部工具、数据源之间定义了一个标准通信协议。MCP Client 的角色相当于一个连接器一端对接 LLM一端对接工具或资源让模型可以调用真实世界的函数来回答问题。笔试不会要求你完整实现一个生产可用的 MCP 服务器而是会给你一段简化描述让你写一个客户端逻辑打通“LLM 请求工具调用”这条链路。核心流程大概是客户端启动时与 MCP Server 建立连接通过 initialize 完成协议握手随后列出可用工具比如 tools/list当 LLM 决定调用某个工具时客户端通过 tools/call 把参数传给服务端并把执行结果返回给 LLM。如果要用伪代码示意大概是这个样子class MCPClient: def __init__(self, server, llm): self.server server self.llm llm def chat(self, user_input): tools self.server.tools_list() # 把工具描述交给 LLM让它决定是否需要调用 response self.llm.complete(user_input, toolstools) if response.tool_call: result self.server.tools_call( response.tool_name, response.tool_args ) # 把工具结果返回给 LLM生成最终回答 return self.llm.complete( user_input, tool_resultresult ) return response.text这段代码真正想体现的是你对 function calling 机制的熟悉程度。LLM 本身不会真的去查数据库或抓网页它只能生成一个“调用请求”真正执行的是客户端。所以 MCP Client 的本质就是读取模型输出、识别工具调用意图、调用外部函数、把结果回传给模型。想提前准备这类题的同学可以去读一下 MCP 协议里 initialize、tools/list、tools/call 这几个核心方法理解它们各自的作用即可。4.3 为什么这类新协议值得关注笔试考 MCP 不代表你必须已经用过这套协议而是考察你面对一个新协议时能不能快速理解它的核心交互模型。方法其实通用先看两端是什么再看消息格式最后看生命周期。MCP 的两端是 LLM 和工具消息格式是 JSON-RPC生命周期是 initialize 到 shutdown。有了这三层框架就算遇到没见过的协议也能写出像样的设计方案。我当时在编程题里没有把代码写得很复杂而是把注释写得很清楚说明每个阶段在干什么最后这部分得分应该不低。5. 备考复盘我踩过的坑和后续建议5.1 考场上的三个真实教训第一个教训是时间分配。我刚开始做客观题时太较真在一道版本兼容题上花了不少时间想“为什么 maximum supported api version 是 1.43 而不是 1.50”浪费了后面编程题的时间。后来我意识到笔试的关键是先把所有题过一遍把能拿的分先拿到再回头抠有疑问的题目。Client 方向的知识面本身就宽不可能每道题都满分。第二个教训是复习时不能只背结论。比如 MySQL 认证协议不兼容如果我背的是“改成 mysql_native_password 就行”那题目换成“最安全的方案”我肯定选错。真正理解了 caching_sha2_password 和 mysql_native_password 的区别知道升级驱动才是最优解才能应对多角度的追问。秋招笔试里的选择题经常把“正确做法”和“临时方案”混在一起你需要有能力分辨哪个是最佳实践哪个只是短期规避。第三个教训是动手实践比看文档有用。Oracle Instant Client 的环境变量、Redis 连接池参数、Kafka 的 broker 列表这些内容如果只看资料印象很浅。我在准备阶段用 Docker 搭过 Kafka 和 Redis故意把 bootstrap.servers 写错观察报错信息再逐步修正。这个过程中积累下来的报错敏感度笔试时是真的能转化为分数的。5.2 给下一届同学的备考清单结合这次笔试我给准备 Client 方向秋招的同学列了一份复习清单按优先级排HTTP/HTTPS 与 TLS/mTLS重点是 HTTPS 握手流程、客户端证书场景、TLS 版本协商。API 版本兼容理解服务端维护的最低/最高支持版本能区分客户端升级和服务端升级两种处理方向。数据库客户端连接MySQL 8 认证插件兼容、Oracle Instant Client 环境变量、连接串字符集。中间件客户端参数Redis 连接池和超时、Kafka bootstrap servers 与认证配置。编程落地能力用一门语言实现 HTTP 客户端、解析网页、处理编码和异常。新协议学习能力理解 MCP、LSP、JSON-RPC 这类协议的基本交互流程。如果时间有限前三条优先因为它们更常出现在客观题里投入产出比最高。编程题则要保证至少能实现一个健壮的“请求-解析-清洗”链路语言不重要思路完整才重要。5.3 备考资料与模拟方式我不太推荐一上来就刷大量面试题。更有效的方式是把自己想象成一个“客户端排障工程师”每天处理一个连接报错。比如今天解决 MySQL 认证协议问题明天解决 Kafka 无可用 broker后天解决 Oracle Instant Client 的动态库加载错误。每个问题都记录三件事报错原文、根因、解决步骤。秋招前把这些记录翻一遍基本能应付大部分客户端链路相关的题目。也可以自己写一个小项目做模拟用语言内置 HTTP 客户端抓取一个网页解析正文然后试图把抓到的内容通过一个极简 MCP Client 暴露给本地 LLM。虽然真正生产环境用的框架会更复杂但这个最小链路能帮你打通“HTTP 客户端、解析、协议理解、LLM 工具调用”四个关键点和这次笔试的考点高度契合。最后再分享一个工具建立自己的“报错日志”整场提前批笔试给我的最大体会是知识面是一方面排障思路是另一方面两者可以同时通过“积累报错日志”来训练。我准备了一个文档专门记录各类客户端报错原文按数据库、消息队列、API 网关、安全认证分类。每条记录后面跟着根因和解决办法比如“MySQL does not support authentication protocol requested → 驱动太老升级驱动或切换认证插件”“client version too new → 客户端版本超过服务端支持上限需要降级客户端或升级服务端”。笔试复习到最后不用抱着大厚书翻看这些日志就够了。一个小技巧每次看到报错不要急着搜结果先自己猜一下根因。哪怕猜错也没关系再看答案时记忆会深刻很多。这个习惯帮我在笔试里快速定位了好几道题也希望对你明年秋招有用。