附录D 系统设计

最后更新于:2022-04-01 15:01:48

**1、搜索关键词智能提示suggestion** 百度搜索框中,输入“北京”,搜索框下面会以北京为前缀,展示“北京爱情故事”、“北京公交”、“北京医院”等等搜索词,输入“[结构之](http://www.baidu.com/s?wd=%E7%BB%93%E6%9E%84%E4%B9%8B&ie=utf-8)”,会提示“结构之法”,“结构之法 算法之道”等搜索词。 请问,如何设计此系统,使得空间和时间复杂度尽量低。 [![](http://box.kancloud.cn/2015-07-06_559a037a7dee8.jpg)](https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/images/36~37/36.1.jpg) 提示:此题比较开放,简单直接的方法是:用trie树存储大量字符串,当前缀固定时,存储相对来说比较热的后缀。然后用hashmap+堆,统计出如10个近似的热词,也就是说,只存与关键词近似的比如10个热词,我们把这个统计热词的方法称为TOP K算法。 当然,在实际中,还有很多细节需要考虑,有兴趣的读者可以继续参阅相关资料。 **2** 某服务器流量统计器,每天有1000亿的访问记录数据,包括时间、URL、IP。设计系统实现记录数据的保存、管理、查询。要求能实现以下功能: * 计算在某一时间段(精确到分)时间内的,某URL的所有访问量。 * 计算在某一时间段(精确到分)时间内的,某IP的所有访问量。 **3** 假设某个网站每天有超过10亿次的页面访问量,出于安全考虑,网站会记录访问客户端访问的IP地址和对应的时间,如果现在已经记录了1000亿条数据,想统计一个指定时间段内的区域IP地址访问量,那么这些数据应该按照何种方式来组织,才能尽快满足上面的统计需求呢? 设计完方案后,并指出该方案的优缺点,比如在什么情况下,可能会非常慢? � 提示:用B+树来组织,非叶子节点存储(某个时间点,页面访问量),叶子节点是访问的IP地址。这个方案的优点是查询某个时间段内的IP访问量很快,但是要统计某个IP的访问次数或是上次访问时间就不得不遍历整个树的叶子节点。或者可以建立二级索引,分别是时间和地点来建立索引。 **4** 给你10台机器,每个机器2个CPU和2GB内存,现在已知在10亿条记录的数据库里执行一次查询需要5秒,问用什么方法能让90%的查询能在100毫秒以内返回结果。 提示:将10亿条记录排序,然后分到10个机器中,分的时候是一个记录一个记录的轮流分,确保每个机器记录大小分布差不多,每一次查询时,同时提交给10台机器,同时查询,因为记录已排序,可以采用二分法查询。 如果无排序,只能顺序查询,那就要看记录本身的概率分布,否则不可能实现。毕竟一个机器2个CPU未必能起到作用,要看这两个CPU能否并行存取内存,取决于系统架构。 **5** 有1000万条URL,每条URL长度为50字节,只包含主机前缀,要求实现URL提示系统,并满足以下条件: * 实时更新匹配用户输入的地址,每输出一个字符,输出最新匹配URL * 每次只匹配主机前缀,例如对www.abaidu.com和www.baidu.com,用户输入www.b时只提示www.baidu.com * 每次提供10条匹配的URL **6** 例如手机朋友网有n个服务器,为了方便用户的访问会在服务器上缓存数据,因此用户每次访问的时候最好能保持同一台服务器。 已有的做法是根据ServerIPIndex[QQNUM%n]得到请求的服务器,这种方法很方便将用户分到不同的服务器上去。但是如果一台服务器死掉了,那么n就变为了n-1,那么ServerIPIndex[QQNUM%n]与ServerIPIndex[QQNUM%(n-1)]基本上都不一样了,所以大多数用户的请求都会转到其他服务器,这样会发生大量访问错误。 问: 如何改进或者换一种方法,使得: * 一台服务器死掉后,不会造成大面积的访问错误, * 原有的访问基本还是停留在同一台服务器上; * 尽量考虑负载均衡。 提示:一致性hash算法。 **7** 对于给定的整数集合S,求出最大的d,使得a+b+c=d。a,b,c,d互不相同,且都属于S。集合的元素个数小于等于2000个,元素的取值范围在[-2^28,2^28 - 1],假定可用内存空间为100MB,硬盘使用空间无限大,试分析时间和空间复杂度,找出最快的解决方法。 有一大批数据,百万级别的。数据项内容是:用户ID、科目ABC各自的成绩。其中用户ID为0~1000万之间,且是连续的,可以唯一标识一条记录。科目ABC成绩均在0~100之间。有两块磁盘,空间大小均为512MB,内存空间64MB。 * 为实现快速查询某用户ID对应的各科成绩,问磁盘文件及内存该如何组织; * 改变题目条件,ID为0~10亿之间,且不连续。问磁盘文件及内存该如何组织; * 在问题2的基础上,增加一个需求。在查询各科成绩的同时,获取该用户的排名,问磁盘文件及内存该如何组织。 **8** 有几百亿的整数,分布的存储到几百台通过网络连接的计算机上,你能否开发出一个算法和系统,找出这几百亿数据的中值?就是在一组排序好的数据中居于中间的数。显然,一台机器是装不下所有的数据。也尽量少用网络带宽。 **9** 类似做一个手机键盘,上面有1到9个数字,每个数字都代表几个字母(比如1代表abc三个字母,z代表wxyz等等),现在要求设计当输入某几个数字的组合时,查找出通讯录中的人名及电话号码。 **10** 这是一种用户登录验证手段,例如银行登录系统,这个设备显示6位数字,每60秒变一次,再经过服务器认证,通过则允许登录。问How to design this system? * 系统设计思路?服务器端为何能有效认证动态密码的正确性? * 如果是千万量级永固,给出系统设计图示或说明,要求子功能模块划分清晰,给出关键的数据结构或数据库表结构。 考虑用户量级的影响和扩展性,用户密码的随机性等,如果设计系统以支持这几个因素. * 系统算法升级时,服务器端和设备端可能都要有所修改,如何设计系统,能够使得升级过程(包括可能的设备替换或重设)尽量平滑? **11** http服务器会在用户访问某一个文件的时候,记录下该文件被访问的日志,网站管理员都会去统计每天每文件被访问的次数。写一个小程序,来遍历整个日志 文件,计算出每个文件被访问的访问次数。 * 请问这个管理员设计这个算法 * 该网站管理员后来加入腾讯从事运维工作,在腾讯,单台http服务器不够用的,同样的内容,会分布在全国各地上百台服务器上。每台服务器上的日志数量, 都是之前的10倍之多,每天服务器的性能更好,之前他用的是单核cpu,现在用的是8核的,管理员发现在这种的海量的分布式服务器,基本没法使用了,请重新设计一个算法。 **12** 一在线推送服务,同时为10万个用户提供服务,对于每个用户服务从10万首歌的曲库中为他们随机选择一首,同一用户不能推送重复的,设计方案,内存尽可能小,写出数据结构与算法。 **13** 每个城市的IP段是固定的,新来一个IP,找出它是哪个城市的,设计一个后台系统。 **14** 请设计一个排队系统,能够让每个进入队伍的用户都能看到自己在队列中所处的位置和变化,队伍可能随时有人加入和退出;当有人退出影响到用户的位置排名时需要及时反馈到用户。 **15** 设计相应的数据结构和算法,尽量高效的统计一片英文文章(总单词数目)里出现的所有英文单词,按照在文章中首次出现的顺序打印输出该单词和它的出现次数。 **16** 有几百亿的整数,分布的存储到几百台通过网络连接的计算机上,你能否开发出一个算法和系统,找出这几百亿数据的中值?就是在一组排序好的数据中居于中间的数。显然,一台机器是装不下所有的数据。也尽量少用网络带宽。 **17** 假设已有10万个敏感词,现给你50个单词,查询这50个单词中是否有敏感词。 分析:换句话说,题目要你判断这50个单词是否存在那10万个敏感词库里,明显是字符串匹配,由于是判断多个单词不是一个,故是多模式字符串匹配问题,既是多模式字符串匹配问题,那么便有一类称之为多模式字符串匹配算法,而这类算法无非是KMP、hash、trie、AC自动机、wm等等。 那到底用哪种算法呢?这得根据题目的应用场景而定。 10万 + 50,如果允许误差的话,你可能会考虑用布隆过滤器;否则,只查一次的话,可能hash最快,但hash消耗空间大,故若考虑tire的话,可以针对这10万个敏感词建立trie树,然后对那50个单词搜索这棵10万敏感词构建的tire树,但用tire树同样耗费空间,有什么更好的办法呢?Double Array Trie么?请读者继续思考。
';