笔试部分是作了10道题目, 主要是相似于LeetCode上的题. 也包含了一些设计题目, 好比说怎么设计一个爬虫系统的去重. 在面试的时候答题纸也被送过来, 面试官会选择里面一个问题(主要是没作出来的)来问你.面试
题目我会记录下来放到GitHub上.数据库
一面聊的时间很长, 总共70分钟左右.编程
总共问了三个大题吧. 发如今面试的过程当中, 有一些问题是一开始没有思考到的, 在交流想法的时候发现漏掉了. 多是没有一开始去设计测试用例, 或者去思考当前的可能的场景或者状况.数组
一开始作了一个设计的题目. 场景是一些关键操做, 要对用户的访问次数或者访问时间作出限制. 给出的例子是要设计一个函数或者功能, 限制单一用户在60分钟以内不能访问超过5词以上. 相似实现一个函数, 输入是用户的 uid. 返回一个布尔值用于表示是否应该 block 掉该次访问.数据结构
当时一开始的想法是把记录存在一个数据库表里, 相似<访问时间, uid, 状态(block/OK)>
而后每次去数据库查, 获取到当前的60分钟以内的数据, 大于5条就选择block掉.编程语言
后来以为放在MySQL这种数据库中太慢, 由于这个函数确定是一个热点, 在每次接受请求的时候都会调用. 能够放在Redis这种内存数据库中.函数
此外, 因为这种规则的限制只考虑好比 x 分钟以内的记录. 能够只保存必定时间以内的访问记录, 超时就作一个失效的处理.源码分析
后来要求用一种数据结构实现, 在内存中直接计算.测试
发现能够作一个HashMap的形式, 里面保存的是 uid和一个表示访问记录的队列.这个队列里保存一些过去的访问记录. 能够经过时间和数量来选择最大的容量.ui
好比说我如今须要考虑过去60分钟的5次数据. 我能够选择容量是5, 最多容纳五条.我直接选取队列中最先插入的(时间距离如今最久)看这条记录时间是否比当前时间早60分钟. 若是超过了就说明最近60分钟的访问次数少于5次. 若是没超过说明需求被block.
在每次接受请求的时候都须要把访问记录放到这个队列中, 也就是会退出一个最先插入的, 再在队尾加一个当前的访问记录.
在手写代码的时候发现没有思考冷启动的问题, 须要判断若是队列不满, 就应该直接放入数据.这也是考虑欠稳当的地方.
第二个问题, 面试官问我是否了解 HashMap . 其实不很了解, 没看过源代码, 看过一些文章.说了一下链表过长会树化,有开放寻址和链表法解决Hash冲突的问题. 而后问我map里桶的数组保存的是什么, 我说是链表的头结点. 面试以后看了一下源码分析的文章, 其实map里就是保存了一个 Entry的数组, 每一个Entry有指向下一个Entry的引用, 也就是一种链表的数组. 好像还问我何时扩容, 这个我答的不对. 后来看过是在map的大小超过阈值以后, 且发生了Hash冲突,才扩容. 在没超过阈值, 可是某个链表长度过长的时候发生树化.
第三个问题是问相似一个Linux的目录树, 怎么从[父目录, 子目录]这种信息构建出来.
提供的数据[[A,B],[B,C],[C,D],[D,E]] 这种, 构建出相似 Linux tree命令的结果.
须要考虑怎么构建树形结构, 还要考虑怎么能从树输出结果.
二面感受面的很差, 不少问题都没回答上来.