
Stripe Integration 的面试是非常独特的,和传统的算法面试完全不同。无论是Intern还是Senior,几乎都在使用同一套题库,区别只在于面试官的期望和你能走到第几步。
题目模拟了真实的工作场景,整场面试时长通常为一小时,形式和内容都非常贴近真实的开发工作。面试开始后,面试官会发一个Github 链接给你,需要下载到本地,在本地通过IDE打开,Github的issue页面会有问题,你需要在本地的IDE里阅读代码,理解代码的结构和功能,然后根据issue里的要求进行修改和扩展。整个过程中,你需要不断在浏览器和IDE之间切换,查看文档、调试代码、提交修改。
Stripe Integration 题目
Part 1:实现一个基础工单路由系统:给定一组客服 agents和按顺序到达的 tickets(每个 ticket 有 id 和预计处理时长 duration),需要按到达顺序逐个处理工单,并始终把当前工单分配给当前累计工作量最小的客服,然后更新该客服的工作量(加上该工单时长),最后输出每个工单对应的分配结果。核心是维护每个 agent 的当前负载,并用贪心策略做负载均衡分配。
Part 2:带技能约束的工单负载均衡问题:给定一组客服每人有不同的specialties和一组按顺序到达的工单(包含duration和specialty),
要求每个工单只能分配给具备该specialty的客服,并且在所有符合资格的客服中选择当前累计workload最小的那一位进行分配,然后更新该客服的负载;若没有符合条件的客服则可视为未分配。目标是在满足技能匹配约束的前提下,实现按最小负载的贪心分配策略。
思路
Part1不考虑技能时,只要维护每个agent的load[],每次线性扫描找最小load的人分配即可;
Code:
import java.util.*;
public class Part1Solution {
// Ticket: id + duration
static class Ticket {
String id;
int duration;
Ticket(String id, int duration) {
this.id = id;
this.duration = duration;
}
}
// Part 1: assign each ticket to the least-loaded agent
static void routeTickets(List<String> agents, List<Ticket> tickets) {
int n = agents.size();
int[] load = new int[n]; // workload per agent
for (Ticket t : tickets) {
// find min load agent
int minIdx = 0;
for (int i = 1; i < n; i++) {
if (load[i] < load[minIdx]) {
minIdx = i;
}
}
// output assignment
System.out.println(t.id + ", " + agents.get(minIdx));
// update load
load[minIdx] += t.duration;
}
}
public static void main(String[] args) {
List<String> agents = Arrays.asList("support_1", "support_2", "support_3");
List<Ticket> tickets = Arrays.asList(
new Ticket("ticket_100", 4),
new Ticket("ticket_101", 3),
new Ticket("ticket_102", 2),
new Ticket("ticket_103", 1)
);
routeTickets(agents, tickets);
}
}Part2先按specialty过滤出能处理该类工单的合格agent,再在合格集合里找load最小者分配,若无人合格则标记unassigned,如果想优化性能的话可以用最小堆按(load, agent_id) 取最空闲的人;
Code:
import java.util.*;
public class Part2Solution {
// Agent: id + specialties
static class Agent {
String id;
Set<String> specialties;
Agent(String id, List<String> specialties) {
this.id = id;
this.specialties = new HashSet<>(specialties);
}
boolean canHandle(String specialty) {
return specialties.contains(specialty);
}
}
// Ticket: id + duration + specialty
static class Ticket {
String id;
int duration;
String specialty;
Ticket(String id, int duration, String specialty) {
this.id = id;
this.duration = duration;
this.specialty = specialty;
}
}
// Part 2: assign to least-loaded QUALIFIED agent
static void routeTickets(List<Agent> agents, List<Ticket> tickets) {
int n = agents.size();
int[] load = new int[n];
for (Ticket t : tickets) {
int minIdx = -1;
// must start from i=0 (not i=1)
for (int i = 0; i < n; i++) {
if (!agents.get(i).canHandle(t.specialty)) continue;
if (minIdx == -1 || load[i] < load[minIdx]) {
minIdx = i;
}
}
if (minIdx == -1) {
System.out.println(t.id + ", unassigned");
continue;
}
System.out.println(t.id + ", " + agents.get(minIdx).id);
load[minIdx] += t.duration;
}
}
public static void main(String[] args) {
List<Agent> agents = Arrays.asList(
new Agent("support_1", Arrays.asList("GENERAL", "PAYINS", "PAYOUTS")),
new Agent("support_2", Arrays.asList("TAXES", "CONNECT")),
new Agent("support_3", Arrays.asList("GENERAL", "PAYOUTS", "CONNECT"))
);
List<Ticket> tickets = Arrays.asList(
new Ticket("ticket_100", 2, "GENERAL"),
new Ticket("ticket_101", 2, "GENERAL"),
new Ticket("ticket_102", 3, "TAXES"),
new Ticket("ticket_103", 1, "PAYINS"),
new Ticket("ticket_104", 1, "CONNECT")
);
routeTickets(agents, tickets);
}
}面试体验
Stripe Integration 从内容上看步骤很多,但每一部分本身都不算难,真正花时间的是各种工程细节,比如数据格式、接口返回值、文件读写以及代码结构的组织方式。题目本身并不刁钻,考的就是你能不能把这些零碎的东西稳定地拼在一起。语言选择上,虽然官方会说你可以使用任何你熟悉的语言,但实际面下来会明显感觉到Python 是最省心的选择。相关库非常齐全,代码量短,调试速度也快。在一小时这种时间压力下,能少踩一点语言和工具链的坑,体验会好很多。
如果你也在准备 Stripe 或其他大厂的 OA/VO,可以直接联系 interviewAid 了解对应的面试辅助和陪跑支持。如果你想找我辅助面试,或者用 Stripe 面经 中的原题 mock,感受最真实的feedback,欢迎戳我。
全网唯一一家支持 L6 以上 system design mock,只放真实面经。