文章目录
- 初战AI Infra团队
- 广泛收集信息,增加对面试相关团队的了解
- Paypal的AI infra Engineer 极客时间演讲视频:
- AI在金融应用
- HR面试
- 首面 zhang chao
- 首先让我介绍自己和项目
- 基础知识
- 出题 lettcode 1and0s
- 二面 luwen
- 没有让我重复介绍自己
- 那好,问java基础知识
- 出题 类似快排
- 再战GDS (global data science)
- 首面 jiang zhao
- 终面决战
- 2:00-2:45 第一场
- 2:45-3:30 第二场
- 3:30-4:15 第三场
- 4:25-5:10 第四场
- 5:10-5:55 第五场
- 收到offer
本文记述的是我两年多之前在PayPal的面试记录。最近准备重新回到金融赛道,所以对以往的技术、项目、面试等做一个梳理和总结。
PayPal在业内属于一线,具有全球的业务,同时和中国金融监管又比较合,属于大家感兴趣的公司,所以分享经历。
初战AI Infra团队
获得信息来源有V2EX帖子:https://www.v2ex.com/t/754005
原来在eBay的同事Eric也帮忙内推:
如上明显2个方向:
- 中国支付
- 为中国向境外支付或收款服务 两个中国paypal账户(不区分企业还是个人),不能互相付款;
- 现在paypal收购了国付宝,但是在境内支付上是很难竞争过支付宝和微信的,人家有生态,paypal优势还是跨境
- 机器学习
- 这个是有点像eBay现在的广告部门,做得是全球的需求,特别主要是给美国那边,提供技术支持
广泛收集信息,增加对面试相关团队的了解
Paypal的AI infra Engineer 极客时间演讲视频:
https://time.geekbang.org/dailylesson/detail/100020744
AI在金融应用
- risk 第一应用
- marketing 像eBay
- customer service 主要是email
HR面试
巧的是这个HR我之前在19年就联系过,她有印象;上面这个精美的招聘图就是她做得
谈到我应聘他们的 AI ml平台,他们的数据源也是交易产生的,可以用于AI风控
我对应他们有大数据经验,另外还有全栈经验(但是要想好选哪个方向)
和hr说的点,why PayPal:
- 好久就看上他们,19年就联系过
- 他们是金融赛道,我比较熟悉
- 欣赏他们工作上的精进,比如创造了用知乎搜索找人方法 https://zhuanlan.zhihu.com/p/36983883
PayPal也有股票,3年拿完,每年一次vet,vet时间比eBay短点。
到傍晚约了下周五面试(留点时间复习下)
首面 zhang chao
首先让我介绍自己和项目
挑个最合适的项目,我介绍了mep项目的可视化,和性能调优cache,用redash原来的api
基础知识
- 因为说到spark和react,他反而不怎么问java;spark的处理过程,我类比了区块链和spark,把程序分发到数据那边执行。2. react他问了虚拟dom,我回答是改善渲染性能的
- setProps,这个我没接触过,如实回答,他答复其实他也不知道,因为他用vue的。很坦诚的交流。
出题 lettcode 1and0s
You are given an array of binary strings strs and two integers m and n.
Return the size of the largest subset of strs such that there are at most m 0's and n 1's in the subset.
A set x is a subset of a set y if all elements of x are also elements of y.
strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
//calc all the 0s 1s
//dp: aux stack
const sovle = function(strs) {
const dp = [];
//init dp matrix
for (let i=0; i<=m; i++) {
const item = [];
for (let j=0; j<=n; j++) {
item.push(0);
}
dp.push(item);
}
//dp calc
for (let i=0; i<strs.length; i++) {
const str = strs[i];
const {zeros, ones} = counts(str);
for (let i = m; i >= zeros; i--) {
for (let j = n; j >= ones; j--) {
//dp迁跃:要么维持原状,要么从dp[i-zeros][j-ones]加上当前这个str结果更大的,那么算入
dp[i][j] = Math.max(1 + dp[i-zeros][j-ones], dp[i][j]);
}
}
}
return dp[m][n];
}
const counts = function(str) {
let zeros = 0;
let ones = 0;
for (let i=0; i<str.length(); i++) {
if (str(i) === '1') {
ones++;
} else {
zeros++;
}
}
return {zeros, ones};
}
二面 luwen
没有让我重复介绍自己
问了我做的面广,那倾向于那个呢?我回答java
那好,问java基础知识
- 并发,场景:10个worker,要准确统计,如果每个worker要一个变量的话,我回答用volatile,可见性
- 如果是一个变量呢,我回答用锁或者cas,不能用volatile了,因为读和写不是一个原子操作,要考虑原子性,可以用atomic的方法,为什么atomic的可以,因为利用了操作系统和cpu底层的CAS方法
- 然后问扩展到多个jvm会不会有问题?我回答,要用分布式锁
- 锁太重型,cas,设计(我回答没在工程中用过redis,他说没关系),我设计了:资源id,workerId,通过null比较且设置;那边进一步,如果锁的worker死了,我回答用一个monitor线程,他说太复杂,直接在worker里面设置超时。我问了一个如果分布式时间不准呢?他回答monitor线程没有解决这个问题。对,不过worker超时也没有。我进一步说明了,是monitory里面记录了时间
出题 类似快排
但是如下写法始终不够简洁且出错,后来受了启发:leetcode75 荷兰国旗问题终于理解,对应paypal的第二题,快排相关
终于复盘成功,正确解法应该是:先是荷兰国旗或者是3-way-partition,然后再sort
For lu wen
100 正整数 奇左 从大到小 ; 偶右 从小到大
//思路:sort -》 双指针 O(1)空间复杂度
import java.util.Arrays;
public class Main {
private static void swap(int[] input, int i, int j) {
if (i == j) return;
int tmp = input[i];
input[i] = input[j];
input[j] = tmp;
}
public static void main(String[] args) {
System.out.println("main");
int[] input = {1,2,3,4,5,6,7,8};
Arrays.sort(input);
System.out.println(Arrays.toString(input));
int pleft = -1;
int pright = input.length;
int pproc = input.length - 1;
while (pleft < pright) {
if (input[pproc] % 2 == 0) {
pright--;
swap(input, pright, pproc);
} else {
pleft++;
swap(input, pleft, pproc);
}
if (pleft == pproc) break;
pproc--;
}
System.out.println(Arrays.toString(input));
}
}
以上写的还是有点问题,最终挂了,第二个工作日得到了通知,应该还是算法题的问题:
Dear Zezhou,
Thanks for you participating PayPal interview and do appreciate your effort and time. We appreciate the opportunity to review your background, qualifications, and eligibility. The excellent qualifications of superior candidates, such as you, have made our selection process a difficult one.
Due to the selection requirements, we thought you are a good candidate but not the most suitable one on current stage. If we have any other suitable position, we will contact with you if you still have interest in joining PayPal.
We will keep your CV into our talent pool and contact you for any further potential suitable position. If you are interested in PayPal position, here are some way you can get the information:
Search the position in PayPal career page. Pls. click here to get it.
Join PayPal linkedin community
Once again, thank you for considering PayPal as your potential employer and we wish you every success to your career development.
再战GDS (global data science)
HR: 之前团队觉得你不是特别合适,你还愿意尝试其他团队吗
我:非常乐意
GDS(global data science) GDS做的事情比之前 ai ml团队稍微上层一些些
可以上领英搜索GDS,了解下他们团队的背景信息
Leading global teams (60+ people in San Jose & Chennai) to develop & deliver data & data science solutions (AI/ML models, variables, data asset) on real time sync, near-real time async & offline Hadoop or Teradata batch platforms;
首面 jiang zhao
- 会议前周密准备:写代码变量名简单节约时间,画图,介绍简历简单,采用倒序方式(突出eBay)
- 先介绍自己,我重点介绍了eBay的,技术栈是全栈,spark,java,redash,cache
- 他问了系统用户,我说不是外部个人用户,是data science,是BU,是内部服务系统,他说和他们当前的很像
- 技术问题:java,volatile和锁区别,XX场景下分别用什么?为什么?
- 设计:如果自己设计Barrier,到了下一轮再一起出发,我说要有锁,要有api,还有有condition
- 做题 https://codeinterview.io/LSIJZHHMJR
二叉树,最底层的叶子节点的和
// package whatever; // don't place package name!
import java.io.*;
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
class MyCode {
//层序遍历 sum leaf.val
public int leafsum(TreeNode root) {
if (root == null) return 0;
Deque<TreeNode> q = new LinkedList<>();
q.offerLast(root);
int sum = 0;
while (!q.isEmpty()) {
int size = q.size();
sum = 0;
for (int i=0; i<size; i++) {
TreeNode curr = q.pollFirst();
sum += curr.val;
if (curr.left != null) q.offerLast(curr.left);
if (curr.right != null) q.offerLast(curr.right);
}
}
return sum;
}
public static void main (String[] args) {
//testcase : null, 1节点 , 多节点。。
MyCode code = new MyCode();
TreeNode tree = new TreeNode(5);
System.out.println("case null:" + code.leafsum(null));
System.out.println("case single:" + code.leafsum(tree));
tree.left = new TreeNode(1);
tree.right = new TreeNode(3);
System.out.println("case multi:" + code.leafsum(tree));
//负数, 不平衡树等
TreeNode t1 = new TreeNode(-100);
System.out.println("case neg:" + code.leafsum(t1));
t1.left = new TreeNode(10);
t1.left.left = new TreeNode(20);
System.out.println("case un balance:" + code.leafsum(t1));
System.out.println("Hello Java");
}
}
//
层序遍历我比较熟悉
如下编译一次通过:
问他的问题:
当前什么工作内容,最大挑战?
他有点像model engine,也是为data science服务,现在挑战是引入TensorFlow,引入其他开源的,如何集成和二次开发
还问了为什么离开eBay去paypal,我回答:2年了(意思是互联网2年也挺长了);而且两者在沟通方式,团队组成,思维习惯等有些不同,我喜欢做金融的;而且19年也是首先投的paypal。另外觉得paypla平台也很大
他有问我是内推还是外部投简历?为什么他要问这个,要拿内推奖?
终面决战
提前了解到面试安排如下,这点PayPal这类的国际大公司还是做得很不错的,有充分的知情权:
2:00-2:45 Weiwei
2:45-3:30 Yubin
3:30-4:15 Teng
4:15-4:25 rest time
4:25-5:10 Yucheng
5:10-5:55 Feng
可以看到面试安排非常紧凑,要做好精神和体力上充分的准备。
具体分组:
2. 高级 /资深软件工程师 – 上海 /北京
两年以上工作经验;熟悉 Java/Scala/Python ;熟练操作各种数据库;熟悉 Unix/Linux, Bash, Shell Script 应用和系统操作;熟悉设计模式;有大数据或机器学习工作经验的优先
以下 4 种方向可供你选择:
- 大数据系统新功能实现,系统调优 /迁移
- 开发在线和离线特征变量和模型(主要是分类模型,深度学习模型等)
- 构建深度学习平台以及工具集合,帮助分析师 /数据科学家搭建深度学习的生命周期和管理的平台
- 数据准备,数据模拟,线上系统监控
后2者比较偏好,前者可以接触到这个TensorFlow之类框架;后者是智涵干过的,数据模拟
系统迁移调优对基础技术打磨比较好;开发在线和离线特征变量和模型 – 对各种深度学习模型比较了解
如下共同的反馈就是ebay和paypal的技术很像的,也是raptorIO
2:00-2:45 第一场
非常友好,整场只有他开了视频
先自我介绍,然后针对分布式锁,让我写下伪代码。讨论是写status必须在事务之外
//zzz distrubited lock
//demand: multi batch server to exec a batch, avoid dup
//distrubited lock : db redis zk , finally decide db
//db lock table design
create table lock_table {
id int,
batchId int,
workerId int,
ts TimeStamp,
status tinyint,
...
}
//app code
@Transactional
public void trans() {
//get lock
lockServ.getLock(status); //record
if (record.workerId != this.workerId) {
return;
}
// record.workerId == null or is this workerId
this.transBatch(batchSize); //config file
//update status
int ret = updateBatchStatus(); //timeout update sql : where status= true and workerId = this.workerId
if (ret == 0) {
rollback();
}
}
2:45-3:30 第二场
聊的时候了解到面试官他也在eBay干过,巧了。
// package whatever; // don't plac package name!
// combine 2 sorted linked list
// 1>2>4 1>3>4
// 1>1>2>3>4>4
//given a sorted int array, all elements appear twice except one element which appears once, find that element
// [1,2,2,4,4] -> 1
import java.io.*;
class Node {
int val;
Node next;
public Node(int val) {
this.val = val;
}
}
class MyCode {
public void sortedBsearch(int[] sorted) {
//in place search ; binary search O(logn)
//check
if (sorted.length == 1) return sorted[0];
int left = 0;
int right = sorted.length - 1;
int mid = (right - left)/2 + left;
int target = 0;
while (left < right) {
int ml = sorted[mid -1];
int mv = sorted[mid];
int mr = sorted[mid +1];
if (ml != mv && mv != mr) {
target = mv;
break;
}
//determine next step
if (ml == mv) {
if (mid%2 == 0) { //turn right
left = mid;
} else { //turn left
right = mid - 1;
}
} else {
if (mid%2 == 0) { //turn right
left = mid;
} else {
right = mid - 1;
}
}
}
return target;
}
public Node merge(Node a, Node b) {
//check
if (a == null) return b;
if (b == null) return a;
Node dummy = new Node(0);
Node curr = dummy;
Node p1 = a;
Node p2 = b;
while (p1 != null && p2 != null) {
if (p1.val < p2.val) {
curr.next = p1;
p1 = p1.next;
} else {
curr.next = p2;
p2 = p2.next;
}
curr = curr.next;
}
if (p1 != null) curr.next = p1;
if (p2 != null) curr.next = p2;
return dummy.next;
}
public static void main (String[] args) {
//combine link
Node n1 = new Node(1);
n1.next = new Node(2);
n1.next.next = new Node(4);
Node n2 = new Node(1);
n2.next = new Node(3);
n2.next.next = new Node(4);
MyCode code = new MyCode();
code.print(n1);
code.print(n2);
Node ret = code.merge(n1, n2);
code.print(ret);
Node n3 = new Node(1);
n3.next = new Node(2);
n3.next.next = new Node(4);
Node n4 = new Node(1);
n4.next = new Node(3);
n4.next.next = new Node(4);
//all null
code.print(code.merge(null, null));
code.print(code.merge(null, n3));
code.print(code.merge(n4, null));
Node n5 = new Node(1);
n5.next = new Node(2);
n5.next.next = new Node(4);
n5.next.next.next = new Node(14);
Node n6 = new Node(1);
n6.next = new Node(3);
n6.next.next = new Node(4);
code.print(code.merge(n5, n6));
System.out.println("Hello Java");
}
public void print(Node n) {
while (n != null) {
System.out.print(n.val + " -> ");
n = n.next;
}
System.out.println("");
}
}
第二场发挥较好,代码编译一次通过,而且二分查找法也弄出来了
3:30-4:15 第三场
一上来就英文自我介绍,介绍项目
然后问java问题,
- hashmap的结构,原理
- volatile 指令重排
- 分布式锁实现介绍
coding部分,1是if null check我刚开始没有加上; 2.是删除部分复盘还有点小瑕疵
// Binary Search Tree
// Find/Insert/Delete a node
// no dup
public class Node {
public Node left;
public Node right;
public int i;
public Node(Node left, Node right, int i) {
this.left = left;
this.right = right;
this.i = i;
}
// Find
public bool findNode(int k, Node tree) {
//check
if (tree == null) return false;
if (k == tree.i) {
return true;
} else if (k < tree.i) {
return findNode(k, tree.left);
} else {
return findNode(k, tree.right);
}
}
// Insert return operated node
public Node insertNode(int k, Node tree) {
if (tree == null) return new Node(k);
if (k == tree.i) {
throw new RuntimeException("No dup val.");
} else if (k < tree.i) {
if (tree.left == null) {
tree.left = new Node(k);
return tree.left;
} else {
return insertNode(k, tree.left);
}
} else {
if (tree.right == null) {
tree.right = new Node(k);
return tree.right;
} else {
return insertNode(k, tree.right);
}
}
}
// Delete
public Node deleteNode(int k, Node tree) {
if (tree == null) return null;
if (k == tree.i) {
//search the lowest left
if (tree.right == null || tree.left == null) return tree;
Node lowest = tree.right;
Node previous = lowest;
while (lowest != null) {
previous = lowest;
lowest = lowest.left;
}
previous.left = tree.left;
return tree;
} else if (k < tree.i) {
return deleteNode(k, tree.left);
} else {
retrun deleteNode(k, tree.right);
}
}
};
4:25-5:10 第四场
说实在,进行到这里,我已经有点疲惫了。持续高强度的思考和应答。
我要求喝口水歇下,上了厕所。
回来后,面试官问模式,设计等。没太纠结技术细节。主要是motivation
然后聊起来我过去项目经历 startup,连连那种上线压力
5:10-5:55 第五场
team的manager
主要检查动机
我说我要1.金融 2.外资 3.互联网 好像也就paypal了。他问为什么不外资银行,我说通过了渣打的终面了。但是我看重人,向同事多学习,这么多年银行,网易,startup等下来,还是eBay和Paypal素质高(有paypal来eBay的同事,我了解的)
问为什么没有转管理岗,我说不太适合干,短时间尝试过,但是国企管理岗很郁闷的,没有权限
后来他说他们还在wfh,不过反馈应该比较快
问他:怎么工作让领导可见。他说,工作分两种1.不错没人看,1️⃣错要死人(比如感冒,都治不好) 2.做了一点大家都知道,都喜欢(比如不孕不育,治不好正常,但是治好了大家都很happy)
所有人都喜欢干第二种,但是只有第二种工作你这个组没有价值,所以需要平衡。很好的经验总结,隐约感觉到这位Manager是平衡的高手,算是找对组了。
问他们的,都是工作挑战
- teng说起上游数据来源问题,部门墙问题,沟通挑战;技术上还好
- weiwei说起资源争用问题
- 第二个主要写代码了,没怎么问
- 最后2个都有说到on call的问题。比如Yucheng说到批量2种,一种hourly的,一种延迟也没关系的,第一种挂掉会紧张
收到offer
数周之后,paypal终于来了口头offer:工资xxk(基本和eBay一样),年终10%浮动(就是1-2个月);股票多点,7万美金,3年行权; 餐补7500元,mini benefit 5000元;签字费5万,一次或者两次,绑定一年
后来因为Shopee的offer,最终没去PayPal,主要是Shopee的岗位是在新加坡,我想增加海外工作经历,另外报酬方面也是Shopee好点。不过PayPal的面试过程还是给我良好印象,一是问的比较细,考核扎实的基础,二是面试安排比较集中,节约时间,当然强度也比较大,需要做好准备。