这个问题曾在一家大型软件公司中问过。我想出了一个简单的解决方案,我想知道别人对解决方案的看法。访谈:系统/ API设计
你应该设计一个系统的API和后端,可以 分配给住在城市的人的电话号码。电话号码 从111-111-1111开始,结束于999-999-9999。该API应该使 客户端(在市人)做到以下几点:
- 当一个电话号码的客户端请求时,它的下发的可用号码其中之一。
- 有些客户可能需要花哨的号码,所以他们可以特别要求一个号码被分配给他们。如果请求的号码是 可用,则系统将其分配给他们,否则系统 分配任何可用号码。
该系统不需要知道哪个号码被分配给哪个客户端 。同一个客户可能会连续发出请求,并为自己获得多个电话号码,但系统不会受到影响。在任何 时间点,系统只知道哪些电话号码被分配 以及哪些电话号码是免费的。
从111-111-1111到999-999-9999的数字大致对应于80亿个数字。假设记忆不是一个约束,我可以想到以下两种方法(几乎相似)。
保持长度为8十亿的一个巨大的布尔阵列和具有
next
指针指向数组索引(next
被初始化为零)。如果next
指向的值不空闲,则转发next
,直到找到空闲号码。当请求花哨的数字时,只需检查相应的索引位置是否空闲并返回该数字。这种方法的不足之处在于,当按照常规方式分配数字时,如果中间有一个庞大的数据块(比如说10亿个数字)被奇特分配分配,那么next
指针必须移动10亿次。为了克服前面提到的困难,我们可以使用某种链接的散列表。我们维护一个双向链表(这取代了前面设计中的数组)和另一个与列表长度相同的数组,其中数组的每个元素都指向列表中的相应元素。因此,当在常规方法中分配数字时,我们在链表中标记一个指针,并在分配时标记节点(与之前的方法相同)。当分配花式数字时,我们可以直接在列表中找到对应于首先索引到数组中的特殊数字所对应的节点以及随后的指针。一旦识别出节点,就将前一个节点和下一个节点短路,这样我们就不必在进行常规分配时一个接一个地跳过使用的数字(这是前一种方法的问题)。
让我知道我是否在正确的轨道上。请告诉我我缺少的任何重要细节。