公司岗位题库

阿里巴巴 后端开发面经第 3 页

141 道题 76 个标签 143 条出现记录

后端开发工程师相关题目第 3 页

什么是线程安全?

线程安全指一段代码、对象或组件在多个线程同时访问时,仍然能够保持预期的正确性,不因为执行时序交错而产生脏数据、丢失更新、状态破坏或偶发异常。判断线程安全不能只看单次调用是否正确,而要看共享可变状态在并发读写下是否满足原子性、可见性和有序性,并通过不可变、线程封闭、同步、原子类或并发容器等手段建立可靠的并发语义。

如何在实际中判断是否会出现线程安全问题?

判断实际项目中是否会出现线程安全问题,核心不是先看有没有多线程,而是追踪共享可变状态是否被多个执行路径并发访问,以及访问是否包含读改写、检查后执行、跨字段一致性、对象发布等风险。实战判断要结合代码审查、并发入口梳理、锁边界分析、压测和线上偶发症状,而不是依赖一次本地复现。

单例模式如何实现,如何保证线程安全?

单例模式的核心目标是让一个类在进程内只暴露一个可访问实例,并控制实例创建时机。回答时应从构造器私有化、全局访问点、线程安全发布、延迟加载、反射和序列化破坏边界几个维度展开。常见实现包括饿汉式、同步懒汉式、双重检查锁、静态内部类和枚举单例,其中推荐优先说明静态内部类和枚举单例,再解释为什么双重检查锁必须配合 volatile。

如果要用线程安全的数据结构,有什么替代方案?

使用线程安全数据结构时,核心不是简单把 ArrayList、HashMap 换成带锁版本,而是先判断共享状态是否真的必须共享,再按读写比例、是否需要阻塞、是否需要顺序、是否有复合操作一致性来选型。Java 中常见替代方案包括 ConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue、ConcurrentLinkedQueue、同步包装器、不可变快照、ThreadLocal、分段锁、Actor 或消息队列串行化,以及在跨进程场景下使用数据库或缓存的原子能力。

内核多线程模块的线程调度是怎么实现的?

Linux 内核多线程模块的线程调度通常不是模块自己实现调度器,而是模块创建多个内核线程后交给 Linux 统一调度。每个内核线程都有 task_struct,进入某个调度类,挂到 CPU 运行队列上,由 CFS、实时调度类或其他调度类根据状态、优先级、vruntime、CPU 负载和亲和性决定何时运行、抢占、阻塞、唤醒和上下文切换。模块开发者更关注线程创建、等待唤醒、停止退出、锁边界和不可睡眠上下文。

如何创建子进程?

创建子进程的核心方式是调用 fork():内核复制当前进程的进程描述信息,创建一个几乎相同但 PID 不同的新进程;父进程得到子进程 PID,子进程得到返回值 0。典型工程模式是 fork 后,子进程按需执行 exec 系列函数加载新程序,父进程使用 wait 或 waitpid 回收子进程退出状态,避免僵尸进程。Linux 中 fork 并不会立即完整拷贝父进程全部内存,而是依赖写时复制降低成本。面试回答应同时说明资源继承、文件描述符共享语义、信号处理、孤儿和僵尸进程、vfork 与 posix_spawn 的使用边界,以及多线程服务中 fork 后的工程风险。

常用的Linux指令有哪些?

这道题不适合只背命令清单,面试官更关注候选人是否能把 Linux 指令放进真实后端排障场景中:如何定位文件、查看日志、过滤文本、观察进程、确认端口、检查磁盘、调整权限、串联管道并形成稳定的排查路径。好的回答应按使用场景分类,并能说明每类命令解决什么问题、常见参数怎么用、出现异常时下一步怎么验证。

Linux 中如何用管道命令排查日志?

这类 Linux 日志排查题考察的不是背命令,而是能否在生产环境中安全、快速、可复现地定位问题。核心思路是先限定日志范围,再用管道逐步缩小:时间窗口、关键字、traceId、状态码、接口路径、调用方、异常栈,最后用统计命令判断问题规模和集中点。回答时要体现两个能力:一是熟练组合 tail、grep、awk、sed、sort、uniq、wc、xargs、less、journalctl;二是知道大文件、线上机器、权限、性能和误操作风险。

LRU 算法在操作系统中如何使用?

LRU 的核心思想是淘汰最近最少被访问的数据,在操作系统里主要用于页面置换、页缓存回收和内存压力下的缓存管理。但真正的系统通常不会实现严格 LRU,而是借助访问位、脏页状态、Clock、二次机会、活跃/非活跃链表等机制近似判断冷热,以降低维护成本并兼顾吞吐、延迟和写回开销。

在Linux里删除当前目录下七天前创建的所有文件会用到哪些命令?

核心命令通常是 find,用它限定当前目录、文件类型和时间条件,再用 -delete 或 -exec rm 执行删除。面试时要特别说明:Linux 中常用的 find -mtime 判断的是“修改时间”,不是严格意义上的“创建时间”;如果题目口语里说“七天前创建”,生产环境通常需要先确认到底是按创建时间、修改时间,还是业务生成时间清理。

知道如何查看线程的cpu内存等资源使用情况吗?

查看线程级 CPU、内存等资源使用情况,核心思路是先确认进程 PID,再进入线程维度观察。Linux 中线程本质上是轻量级进程,每个线程都有自己的 TID,因此可以用 top -H、ps -L、pidstat -t、/proc/<pid>/task/<tid>/ 等方式查看线程级 CPU、调度状态、上下文切换和栈。CPU 通常能定位到线程,但内存大多是进程级共享资源,不能简单拆给单个线程。

分表规则中,跨表查询+分页该怎么做?

跨表查询和分页的核心不是把单表 limit offset 原样套到每个分表,而是先判断能否命中分片键;能命中就路由到单表或少量表,不能命中才考虑广播查询、局部排序、全局归并。深分页会被分片数放大,工程上更推荐游标分页、二级索引表、异步宽表或搜索服务承接全局查询。

fork发生复制的时候子进程会复制什么?

fork 的本质不是把父进程的一切都物理复制一份,而是创建一个几乎相同的子进程执行上下文:内核为子进程建立新的进程描述符、PID、虚拟地址空间视图和资源引用关系;用户态内存通常通过写时复制延迟分裂;文件描述符表被复制但底层打开文件对象常被共享。因此面试回答要区分“逻辑复制”“引用共享”和“写时复制后才真正复制”。

线程最大数量和什么有关?

Linux 下线程最大数量不是一个固定常量,而是由多层约束共同决定:系统级的 threads-max 和 pid_max、用户级的 RLIMIT_NPROC、服务或容器的 pids 限制、单进程可用地址空间、物理内存与 overcommit 策略、每个线程的用户栈和内核对象开销,以及语言运行时的栈配置共同取最小值。能创建多少线程是一回事,系统能否高效调度这些线程又是另一回事。

Kafka 为什么吞吐量高?

Kafka 的高吞吐不是单点优化,而是围绕日志追加模型构建的一整套链路设计:生产端批量发送和压缩降低请求次数与网络字节数,Broker 端用顺序写和 Page Cache 减少随机磁盘 IO,发送文件时利用零拷贝降低用户态与内核态拷贝成本,Topic 分区让读写并行扩展,消费者拉取模型让消费端按自身能力批量读取。同时,ISR、acks、副本数、刷盘策略等可靠性配置会影响吞吐,面试中要讲清这些设计如何共同减少 IO、网络、CPU 和锁竞争开销。

Http 报文里有什么?

HTTP 报文是客户端和服务端交换应用层数据的基本格式。HTTP/1.x 报文由起始行、请求头或响应头、空行、消息体组成。请求报文的起始行叫请求行,包含方法、请求目标和协议版本;响应报文的起始行叫状态行,包含协议版本、状态码和原因短语。头部字段描述元信息,空行分隔头部和消息体,消息体承载实际业务数据。

http 协议 转 dubbo 协议怎么做的?

HTTP 转 Dubbo 的本质不是协议字节直接翻译,而是在网关或适配层把一个 HTTP 请求解析成一次 Dubbo RPC 调用。核心流程是:接收 HTTP 请求,按路由规则定位 Dubbo 接口、方法和版本,完成参数绑定和类型转换,通过注册中心或本地配置找到服务提供者,使用 Dubbo 客户端按 Dubbo 协议编码、序列化并发起调用,再把 Dubbo 响应、异常和超时结果转换成 HTTP 状态码与响应体。回答要围绕映射、发现、调用、治理和观测展开,而不是只说用网关转发。

设计朋友圈功能时,数据库表如何从简单到复杂演进?

朋友圈数据库设计可以按复杂度分层回答:最小可用版本先有用户、好友关系、动态、媒体、评论和点赞;进阶版本补可见范围、权限校验和删除模型;高并发版本再讨论时间线、读扩散与写扩散、冷热数据、索引、分库分表、幂等与一致性。面试时不要一上来就堆表,而是先说明业务读写路径:发动态、刷列表、看详情、评论点赞、删除和权限变化。

Agent 工具调用失败后,如何通过 trace 定位是意图识别、工具选择、参数生成还是工具服务本身的问题?

这题考的是 Agent 工具调用失败后的分层定位能力。好的回答不能只说看日志,而要把一次请求拆成意图识别、工具检索与选择、参数生成、执行前校验、工具服务调用、结果解释几个 span,并让每一层都有输入、输出、置信度、候选集、错误码、耗时和重试信息。定位时先判断用户意图是否被理解错,再看工具候选和最终选择是否合理,然后检查参数 schema、枚举、时间范围、权限上下文等是否正确,最后才归因到工具服务的网络、鉴权、超时、限流或业务错误。

Agent 系统可观测性平台应记录哪些 trace,LangSmith 和 Langfuse 如何用于调试与评估?

这题考 Agent 可观测平台该记录什么,以及如何把 trace 用于调试和评估。好的回答要覆盖请求级 trace、LLM 调用、工具调用、检索、记忆、planner、guardrail、人工反馈、成本延迟和评测结果,并说明 LangSmith 与 Langfuse 都可以承载调试和评估闭环,但选型应基于技术栈、部署合规、数据治理、评测流程、成本和集成方式,而不是简单说谁更强。

Agent 中 Function Call、MCP 和 Skill 的工具描述上下文占用有什么差异,如何降低 token 成本?

这道题考察对 Agent 工具接入方式和上下文成本的工程理解。好答案要区分 Function Call 是模型请求内的工具 schema,MCP 是客户端和外部工具服务器之间的协议,Skill 是把说明、脚本和资源按能力打包并按需加载的机制。回答不能简单说 MCP 一定比 Skill 大,而要说明上下文占用取决于客户端暴露了多少工具描述、schema 是否冗长、是否做动态路由和懒加载。高质量答案还应给出降低 token 成本的方法,包括工具分层、候选工具筛选、描述压缩、结果引用、prompt caching 和按任务加载。

MCP 接入多个测评工具时,如果不同工具对同一问题返回格式不统一,应该如何设计统一输出协议或适配层?

这题考 MCP 多工具输出治理。多个 MCP 工具返回格式不统一时,应在工具和 Agent Runtime 之间加适配层,统一 envelope、内容块、结构化数据、错误协议、元数据、版本和审计,而不是让模型解析各类私有格式。