我之前在美团就面试过两轮,似乎是被刷掉了,又被另一个部门捞了起来,于是分别在前天和今天又进行了两轮面试。
一面
开头依然是自我介绍和项目经历介绍。我也还是那套逐渐熟练的老生常谈。
算法
1. 实现一个时间和空间复杂度都较低的队列。
一开始没太明白这个“较低”是什么意思,那尽量往
O
(
1
)
O(1)
O(1)优化吧。
一开始的想法是采用数组形式,把队列里的元素按顺序放在一个数组里。但这样需要提前分配空间,所以我问了一下元素个数是多少,面试官略一思索说
1
0
4
10^4
104吧。
但我并没有用上这个数据……因为这实在太浪费空间了,可能大部分时间大部分空间都是没用的。
然后就想用链表了。这个实现比较容易,各种操作的用时不长,虽然也会用一些空间存储指针这种不必要的信息,但总比数组好。
很快就写好了节点和队列的数据结构,也实现了push
函数。实现pop
的时候,我突然想到如果队列是空的该怎么办?然后磨蹭了好久想不出解决办法……面试官说“能考虑到这个就可以了”,我很尴尬但不能说什么。面试结束后,我很快就想到应该再给个isEmpty
函数,然后由pop
的调用者先调用isEmpty
。这好像是某本书上的做法,但我当时就想不出。
2. 一种数据结构,以单向链表存储小数,每个节点表示小数中的一位(包括小数点)。实现它的加法。
一开始误会了题意(题不是我这么写的,有点不清晰),以为返回值是double
,那其实只要把链表转成double
就行了。从前往后遍历,过一位就*10,小数点后面则都/10。
后来得到解释,甚至得到了“使用多个指针”的提示,还是……做不出。
网络
还是三次握手四次挥手,没什么好说的。
其他
他看我简历上没写成绩,问我怎么回事。不写自然是因为拿不出手……我说大概60-70%的位置吧。他又问我大学有啥后悔的事。我经常在匿名提问箱里问别人有什么后悔的事,因为我知道这个问题会触动人的痛处,也能知道ta在乎什么,是非常尖锐、非常适合用来了解一个人的问题。今天我终于也被问到了,只能说没好好学习,现在知道努力了可能为时不晚吧。
其他的问题我都忘了。只记得他一直忍不住笑,笑得我心里发毛。我知道这是因为我实在菜,也不好说什么,跟着讪笑。
最后他说我笔试成绩还挺好的(5题做出来3题多一点),数据结构和算法还行。我又尴尬地笑笑,知道这是矮子里挑将军式的夸奖。
到我提问了。我难得地提了问题,还是两个。一问我已经面试两次,这次啥性质;二问他们部门的业务。既然专业知识不行,那就
二面
操作系统
内存管理。
信号量。
死锁的种类,如何处理和避免。
进程和线程的状态。
数据库
多个用户同时访问一个表,怎么处理。
一个用户执行了一系列操作,其中一步失败了,如何消除前面操作的影响。
都不会。
网络
TCP和UDP的区别(终于有个不问握手挥手的了)。也是经典问题了,没什么好说的。
算法
实现LRU(Least Recently Used)。虽然我操作系统学的很烂,但也依稀记得这是内存管理的一种方式。当访问的页面在内存中miss时,要从内存中找到最近最少使用的页面,踢出并换为当前要访问的页面。
算法还算好理解,而且好巧不巧,我昨天正好看到一个文章讲这个题怎么做,而且记住了最关键的一点:用链表。因为这样可以把节点按照LRU的顺序排起来,添加、移动和删除都比较容易。
我提出来用链表实现,面试官就让我写。稍微有点生涩,但最后还算顺利地把get(key)
和put(key, value)
都实现了,能想到的边界情况也都考虑到了。尽管get
需要
O
(
n
)
O(n)
O(n)的时间,但我想不到更好的了。
不过他给的题目最后有句话:用map实现。如果遍历map寻找LRU的那一个,需要
O
(
n
)
O(n)
O(n)的时间。可能有结合链表来加快实现的方式,但又磨磨蹭蹭想不出来。面试官说“用指针就可以了嘛”,我嘴上说着“哦!对对对”,实际上脑中一片空白。
这几天笔试面试源源不断,我连轴转快要晕了。只想躺着,哎。