程序员的算法能力测试

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_1018944104/article/details/84978638

这六个真实软件开发中的算法问题,你都能解决吗?

乔布斯说,一个天才员工可以顶得上50个平庸的员工。但,在软件开发行业里,一个优秀靠谱的工程师,可以顶得上100个普通的工程师。普通的业务开发,有时候并不能区分一个工程师是普通还是优秀。但是,面对一些稍微复杂的技术问题,这个区分就会显得非常明显。

实战测试题(一)

假设猎聘网有10万名猎头顾问,每个猎头顾问都可以通过做任务(比如发布职位),来积累积分,然后通过积分来下载简历。假设你是猎聘网的一名工程师,如何在内存中存下10万个猎头的ID和积分信息,让它能够支持这样几个操作:

  • 根据猎头的ID快速查找、删除、更新这个猎头的积分信息;
  • 查找积分在某个区间的猎头ID列表;
  • 查询积分从小到大排在第x位的猎头ID信息;
  • 查找按照积分从小到大排名在第x位到第y位之间的猎头ID列表

思路点拨:

  • 跳表:为什么Redis一定要用跳表来实现有序集合?
  • 散列表(下):为什么散列表和链表经常会一起使用?
  • 红黑树:为什么工程中都用红黑树这种二叉树?

实战测试题(二)

电商交易系统中,订单数据一般都会很大,我们一般都分库分表来存储。假设我们分了10个库并存储在不同的机器上,在不引入复杂的分库分表中间件的情况下,我们希望开发一个小的功能,能够快速地查询金额最大的前K个订单(K是输入参数,可能是1、10、1000、10000,假设最大不会超过10万)。

如果是这个功能的设计开发负责人,你会如何设计一个比较详细的、可以落地执行的设计方案呢?

为了方便你的设计,我先交代一些必要的背景,在设计过程中,如果需要其他需要明确的背景,你可以自行假设。

  • 数据库中,订单表的金额字段上建有索引,我们可以通过select order by limit 语句来获取数据库中的数据;
  • 我们的机器可用内存有限,比如只有几百M剩余可用内存。希望你的设计尽量节省内存,不要发生Out of Memory Error。

思路点拨:

  • 排序(下):如何用快排思想在O(n)内查找第K大元素?
  • 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
  • 哈希算法(下):哈希算法在分布式系统中有哪些应用?

实战测试题(三)

我们知道CPU资源是有限的,任务的处理速度与线程个数并不是线性正相关。想反,过多的线程反而导致CPU频繁切换,处理性能下降。所以,线程池的大小一般都是综合考虑要处理任务的特点和硬件环境,来事先设置的。

当我们向固定大小的线程池中请求一个线程时,如果线程池中没有空闲资源了,这个时候线程池如何处理这种请求?是拒绝请求还是排队请求?各种处理策略有是怎么实现的?

思路点拨:

  • 队列:队列在线程池等有限资源池中的应用

实战测试题(四)

通过IP地址来查找IP归属地的功能,不知道你有没有用过?没用过也没有关系,你现在可以打开百度,在搜索框里随便输入一个IP地址,就会看到它的归属地。

这个功能并不复杂,它是通过维护一个很大的IP地址库来实现的。地址库中包括IP地址范围和归属地对应关系。比如,当我们想要查询202.102.133.13这个IP地址的归属地时,我们就在地址库中搜索,发现这个IP地址落在[202.102.133.0, 202.102.133.255]这个地址范围内,那我们就可以将这个IP地址范围对应的归属地“山东东营市”显示给用户了。

在庞大的地址库中逐一比对IP地址所在的区间是非常耗时的。假设在内存中有12万条这样的IP区间与归属地的对应关系,如何快速定位出一个IP地址的归属地呢?

思路点拨:

  • 二分查找(上):如何用最省内存的方式实现快速查找功能?
  • 二分查找(下):如何快速定位IP对应的省份地址?

实战测试题(五)

假设我们现在希望设计一个简单的海量图片存储系统,最大预期能够存储一亿张图片,并且希望这个海量图片存储系统具有下面这样几个功能:

  • 存储一张图片及其它的元信息,主要的元信息有:图片名称以及一组tag信息。比如图片名称叫玫瑰花,tag信息是(红色、花、情人节);
  • 根据关键词搜索一张图片,比如关键词是“情人节 花” “玫瑰花”
  • 避免重复插入相同的图片。这里,我们不能单纯地用图片的元信息,来比对是否是同一张图片,因为有可能存在名称相同但图片内容不同,或者名称不同图片内容相同的情况。

我们希望自助开发一个简单的系统,不希望借助和维护过于复杂的三分系统,比如数据库(MySQL、Redis等)、分布式存储系统(GFS、BigTable)等,并且我们单台机器性能有限,比如硬盘只有1TB,内存只有2GB,如何设计一个符合我们上面要求,操作高效,且使用机器资源最少的存储系统呢?

思路点拨:

  • 哈希算法(上):如何防止数据库中的用户信息被脱库?
  • 哈希算法(下):哈希算法在分布式系统有哪些应用?

实战测试题(六)

我们知道,散列表的查询效率并不能笼统地说成是O(1)。它跟散列函数、装载因子、散列冲突等都有关系。如果散列函数设计得不好,或者装载因子过高,都可能导致散列冲突发生的概率升高,查询效率下降。

在极端情况下,有些恶意攻击者,还可能通过精心构造的数据,使得所有的数据经过散列函数之后,都散列到同一个槽里。如果我们使用的是基于链表的冲突解决方法,那这个时候,散列表就会退化为链表,查询的时间复杂度就从O(1)急剧退化到O(n)。

如果散列表中有10万个数据,退化后的散列表查询的效率就下降了10万倍。更直观的观点说,如果之前运行100次查询只需要0.1秒,那现在就需要1万秒。这样就有可能因为查询操作消耗大量CPU或者线程资源,导致系统无法响应其他请求,从而达到拒绝服务攻击(DoS)的目的。这也就是散列表碰撞攻击的基本原理。

如何设计一个可以应对各种异常情况的工业级散列表,来避免在散列冲突的情况下,散列表性能的急剧下降,并且能够抵抗散列碰撞攻击?

思路点拨:

  • 散列表(上):Word文档中的单词拼写检查功能是如何实现的?
  • 散列表(中):如何打造一个工业级水平的散列表?

猜你喜欢

转载自blog.csdn.net/qq_1018944104/article/details/84978638
今日推荐