Android 高级工程师面试:网络与数据层 近1年高频追问 18 题

文章目录

学习建议

目标层级 建议
初级 掌握基础层 6 题:OkHttp 基本用法、Retrofit 注解、GET/POST 区别、Room 三组件、HTTPS 概念
中级 通读全文;进阶层能讲清拦截器链、协程 suspend 适配、Room 迁移、Paging 3 架构
高级 核心层必答:缓存策略、网络层错误处理、离线优先、安全与证书校验;能串联「API→Repository→Room→UI」数据闭环

基础层(6 题)

#1 OkHttp 是什么?核心组件有哪些? 🔥

标准回答

OkHttp 是 Square 开源 HTTP 客户端,负责连接、复用、拦截、缓存与 TLS。核心:OkHttpClient(配置)、Request/ResponseInterceptor 链、ConnectionPool 复用 TCP、Dispatcher 管理线程池。Retrofit 默认底层用 OkHttp。

面试官可能继续追问

  • Android 工程里 OkHttp 怎么配置?

    单例 OkHttpClient 注入 Hilt;设置超时、拦截器、证书;Debug 加 HttpLoggingInterceptor。

  • OkHttp 和 HttpURLConnection 区别?

    OkHttp 连接池、拦截器扩展、HTTP/2 支持更好;官方与 Retrofit 生态首选。


#2 Retrofit 的工作原理是什么? 🔥

标准回答

Retrofit 用动态代理将接口方法转为 HTTP 请求:注解解析 URL、方法、参数体;Converter 序列化请求/反序列化响应(Gson/Moshi);CallAdapter 适配 suspend/Flow/Call。运行时生成实现类,无手写 HTTP 样板代码。

面试官可能继续追问

  • Android 里 Retrofit 怎么定义 API?

    @GET("users/{id}") suspend fun getUser(@Path id: String): UserDto;Hilt 提供单例 Retrofit。

  • Retrofit 能传多个 BaseUrl 吗?

    多 Retrofit 实例或多 @Url 动态完整地址。


#3 GET 和 POST 在 HTTP 语义上有什么区别? ⭐

标准回答

GET :幂等、可缓存、参数通常在 URL,语义获取资源;POST:非幂等、提交实体,常用于创建/提交。实际 REST 还用 PUT/PATCH/DELETE;HTTPS 下两者均加密,差别在语义与缓存策略而非「安全性高低」。

面试官可能继续追问

  • Android 里搜索用 GET 还是 POST?

    查询幂等用 GET;超长参数或敏感查询可 POST,但需服务端约定。

  • Retrofit @Query@Field 区别?

    Query 拼 URL;Field 用于 application/x-www-form-urlencoded 表单 POST。


#4 HTTPS 基本原理?Android 中注意什么? 🔥

标准回答

TLS 握手协商密钥,对称加密传数据,证书链校验服务器身份。Android 9+ 默认禁止明文 HTTP(可 networkSecurityConfig 例外);证书固定(Certificate Pinning)防中间人;勿信任所有证书;系统 CA 更新影响老设备。

面试官可能继续追问

  • Android 里怎么做证书固定?

    OkHttp CertificatePinner 固定公钥哈希;注意证书轮换策略。

  • Charles 抓包原理?

    用户安装代理 CA,属于中间人;生产环境应防。


#5 Room 三组件是什么? ⭐

标准回答

@Entity 表结构;@Dao 数据访问(SQL/suspend/Flow);@Database 版本与迁移入口。编译期生成 _Impl,运行时 SQLite 驱动;主线程查询默认禁止,协程/Flow 观察推荐。

面试官可能继续追问

  • Android 里 Room 实例怎么管理?

    单例 Room.databaseBuilder;Hilt @Provides @Singleton;多库多实例。

  • Room 和 SQLiteOpenHelper 比?

    Room 编译期校验 SQL、Lifecycle 整合;原生 Helper 更灵活但样板多。


#6 RESTful API 设计在客户端如何对接? ⭐

标准回答

资源用 URL 名词,HTTP 动词表操作;状态码表达结果(2xx 成功、4xx 客户端、5xx 服务端)。客户端映射 DTO→Domain Entity;错误体统一解析;版本通过路径或 Header;分页 page/cursor+limit

面试官可能继续追问

  • Android 里 HTTP 错误怎么统一处理?

    拦截器或 CallAdapterResult;4xx/5xx 映射业务错误码。

  • GraphQL 和 REST 客户端差异?

    GraphQL 单端点多查询;REST 多 endpoint,Retrofit 更贴 REST。


进阶层(6 题)

#7 OkHttp 拦截器链怎么工作?应用与网络拦截器区别? 🔥

标准回答

拦截器责任链:Chain.proceed(request) 向下传递,可改 request/response。应用拦截器靠近业务(日志、Header、重试);网络拦截器靠近 socket(缓存、桥接)。先加的应用拦截器先执行请求、后执行响应。

面试官可能继续追问

  • Android 里 Token 刷新拦截器怎么写?

    401 时同步刷新 Token 再 proceed 重放;注意死锁用单独 OkHttpClient 刷新。

  • 日志拦截器放哪?

    应用拦截器,避免重复读 body;body 只能读一次需 peekBody


#8 Retrofit 如何支持 Kotlin 协程? ⭐

标准回答

接口方法声明 suspend fun,Retrofit 2.6+ 内置挂起支持,在主线程调用会自动切线程执行网络(内部 Enqueue+suspendCancellableCoroutine)。配合 viewModelScope 结构化并发;取消时取消底层 Call。

面试官可能继续追问

  • Android 里 suspend API 错误处理?

    try/catchrunCatching;全局用 CoroutineExceptionHandler

  • Retrofit 返回 Flow 怎么做?

    自定义 CallAdapter 或上层 flow { emit(api.get()) };官方更常见 suspend。


#9 Gson 和 Moshi/Kotlin Serialization 怎么选? ⭐

标准回答

Gson :反射解析、Kotlin null 易踩坑需适配器;Moshi :Kotlin 友好、Codegen 性能更好;Kotlin Serialization:编译期、多平台一致。新项目 Kotlin 优先 Moshi 或 KSerialization;存量 Gson 注意默认值与 null。

面试官可能继续追问

  • Android 里泛型擦除 List 怎么解析?

    Gson TypeToken;Moshi Types.newParameterizedType

  • Proguard 下 Gson 注意?

    keep 数据类字段名;或用 Moshi codegen。


#10 Room 数据库迁移怎么做? 🔥

标准回答

版本号递增,Migration(start, end) { db.execSQL(...) } 注册到 Builder;AutoMigration(Room 2.4+)声明简单列变更。生产禁止随意 fallbackToDestructiveMigration;测试用 MigrationTestHelper 验证。

面试官可能继续追问

  • Android 里复杂迁移怎么测?

    导出旧版 schema JSON,runMigrationsAndValidate 比对 schema。

  • 迁移失败用户数据怎么办?

    备份、降级只读、弹窗引导;开发期才 destructive。


#11 Paging 3 架构是什么? ⭐

标准回答

Pager+PagingSource 分页加载;RemoteMediator 协调网络与 Room 离线缓存;Flow<PagingData<T>> 喂给 LazyPagingItemsLoadResult 管理 prev/next key;占位符与错误重试内置。

面试官可能继续追问

  • Android 里 Compose 怎么用 Paging?

    collectAsLazyPagingItems()items() 渲染;loadState 显示加载/错误。

  • Paging 2 和 3 区别?

    Paging 3 全 Kotlin Flow、RemoteMediator 统一网络+DB;2 已维护模式。


#12 网络超时如何设置?重试策略? ⭐

标准回答

connectTimeout/readTimeout/writeTimeout/callTimeout 分层设置;读超时最常触顶。重试:幂等 GET 可指数退避;POST 谨慎自动重试。OkHttp retryOnConnectionFailure 仅连接失败;业务重试用拦截器+Idempotency-Key。

面试官可能继续追问

  • Android 里弱网怎么优化?

    缩短首屏必要请求、合并接口、离线缓存、降级 UI、WorkManager 后台同步。

  • 超时和 ANR 关系?

    主线程 execute() 同步调用会 ANR;suspend 在 IO 线程不阻塞 UI。


核心层(6 题)

#13 缓存策略:OkHttp 缓存与业务缓存如何配合? 🔥

标准回答

OkHttp Cache 按 HTTP Cache-Control/ETag 磁盘缓存;业务层 Room 存结构化离线数据。读路径:内存→Room→网络;写路径:先写 DB 再异步刷新。Cache-Control: max-agestale-while-revalidate 按接口语义配置。

面试官可能继续追问

  • Android 里图片缓存和网络缓存分层?

    Coil 内存+磁盘;API JSON 用 OkHttp Cache 或 Room,不混用。

  • 强制刷新怎么做?

    Cache-Control: no-cache 或请求头 pragma;Repository 参数 forceRefresh


#14 离线优先(Offline-first)架构怎么实现? 🔥

标准回答

UI 观察 Room Flow,网络仅同步;RemoteMediator 拉取写入 DB;冲突解决用版本号/时间戳/服务端权威。无网展示本地;有网后台刷新。WorkManager 定期同步;乐观更新先改本地再回滚失败。

面试官可能继续追问

  • Android 里乐观更新 UI 怎么做?

    先写 Room+更新 StateFlow;请求失败回滚并提示。

  • 同步冲突例子?

    编辑草稿多端修改,以 updatedAt 或版本向量合并。


#15 网络层安全:签名、加密、防重放? 💡

标准回答

HTTPS 传输加密;敏感字段额外 AES/RSA;请求签名(参数排序+HMAC+时间戳)防篡改;timestamp+nonce 防重放;Token 存 EncryptedSharedPreferences/DataStore;证书固定加固。密钥不进 APK 明文,用 NDK 或服务端下发。

面试官可能继续追问

  • Android 里签名校验放哪?

    拦截器统一加 Header;密钥放 native 或服务器换短期 token。

  • 反编译拿密钥怎么办?

    提高成本非绝对安全;核心逻辑服务端校验。


#16 大文件上传下载怎么做? ⭐

标准回答

@Streaming Retrofit 返回 ResponseBody 流式写文件,勿 bytes() 一次读入;上传 RequestBody 分块或 MultipartBody;断点续传用 Range 头+本地记录偏移;进度回调用 CountingSink 包装;前台服务通知长时间下载。

面试官可能继续追问

  • Android 里下载到 MediaStore?

    ContentResolver+IS_PENDING 标志;Scoped Storage 合规。

  • OkHttp 取消大下载?

    Call.cancel();协程取消传播到 Call。


#17 WebSocket 在 Android 中如何使用? 💡

标准回答

OkHttp WebSocket 长连接双向通信;心跳 ping/pong 保活;前台服务维持后台连接(受系统限制);重连指数退避;消息队列离线补发。与 REST 互补:实时推送用 WS,CRUD 仍 REST。

面试官可能继续追问

  • Android 里 WS 和 FCM 怎么选?

    系统级推送用 FCM;低延迟双向聊天可 WS+后台限制处理。

  • Doze 对 WS 影响?

    连接可能断;需重连或 FCM 唤醒。


#18 数据层测试策略? 🔥

标准回答

Room 用内存库 inMemoryDatabaseBuilder 测 DAO;Repository 用 MockWebServer 测 Retrofit 集成;Mapper 单测纯函数;PagingSource 测 load() 返回 key。不依赖真实网络;协程 runTest+TestDispatcher

面试官可能继续追问

  • Android 里 MockWebServer 示例?

    server.enqueue(MockResponse().setBody(json)) 断言请求路径与响应解析。

  • DAO Flow 怎么测?

    turbine test { awaitItem() } 插入后断言发射。


面试策略速查

面试等级 建议掌握
初级 ★★★☆☆
中级 ★★★★☆
高级 ★★★★★

必背知识(🔥)

OkHttp 组件、Retrofit 原理、HTTPS、拦截器链、Room 迁移、缓存策略、Offline-first、数据层测试

高频追问

「拦截器怎么加 Token」「suspend Retrofit 线程」「Room 迁移失败怎么办」「Paging RemoteMediator」「弱网策略」

加分项(💡)

证书固定、签名防重放、WebSocket、大文件断点续传

容易踩坑

主线程同步 OkHttp;Gson null 默认值;Room 主线程查询;POST 盲目重试;把 OkHttp 缓存当业务 DB;Token 明文存 SP


完整链路一句通

数据层一条线:Retrofit 声明 API+suspend → OkHttp 拦截器/TLS/连接池 → DTO Mapper 转 Entity → Room 持久化+Flow 观察 → Paging/RemoteMediator 协调分页与离线 → Repository 统一缓存与错误 → ViewModel StateFlow 驱动 UI;安全靠 HTTPS+存储加密+签名,测试靠 MockWebServer 与内存 Room。


相关推荐

Android 高级工程师面试:Jetpack 核心 近1年高频追问 20 题

Android 高级工程师面试:Kotlin 语法基础 近1年高频追问 22 题

相关推荐
网络小白不怕黑1 小时前
11.虚拟机模拟路由器实验
linux·运维·服务器·网络
三少爷的鞋2 小时前
Android 架构这些年,其实一直在消灭碎片化异步
android
ylscode10 小时前
OpenSSH 10.4 正式发布:后量子加密落地,多项高危漏洞得到修复
网络·安全·网络安全
DianSan_ERP11 小时前
电商架构演进:如何在高并发场景下实现多平台API的标准化履约?
运维·前端·网络·安全·架构·自动化
阿成学长_Cain11 小时前
Linux ipcs 命令超全详解:查看共享内存 / 消息队列 / 信号量,IPC 运维必备
linux·运维·服务器·网络·数据库
青瓦梦滋11 小时前
协议定制/序列化-反序列化(Linux视角)
linux·服务器·网络·c++
驭渊的小故事15 小时前
网络原理01(两千字解析)
网络
奔跑的蜗牛ing15 小时前
CentOS Nginx 安装与静态文件服务器配置指南
前端·面试·架构
KaMeidebaby17 小时前
卡梅德生物技术快报|小 RNA 适配体合成 + 多方法亲和力表征全流程标准化操作手册
前端·网络·数据库·人工智能·算法