Caching 采访问题:阶乘和缓存

Caching 采访问题:阶乘和缓存,caching,Caching,我最近遇到了以下面试问题: 您需要设计一个系统来为 在1到100之间。你可以缓存10个数字。你会怎么做 安排/管理该缓存,以及在缓存上查找的最坏情况是什么 缓存未命中 你认为什么是合适的答案?背后的原因是什么?就个人而言,我会为第一次输入缓存前十个数字,然后根据最近的输入维护LRU缓存,因为人们更可能重复搜索。不过,我并不确定查找缓存未命中的最坏情况是什么。如果在实现阶乘函数时使用动态规划方法,则可能是O(n)。你觉得怎么样?这里的想法是选择一些数字,以便可以从中计算其他数字。假设您的系统以恒定

我最近遇到了以下面试问题:

您需要设计一个系统来为 在1到100之间。你可以缓存10个数字。你会怎么做 安排/管理该缓存,以及在缓存上查找的最坏情况是什么 缓存未命中


你认为什么是合适的答案?背后的原因是什么?就个人而言,我会为第一次输入缓存前十个数字,然后根据最近的输入维护LRU缓存,因为人们更可能重复搜索。不过,我并不确定查找缓存未命中的最坏情况是什么。如果在实现阶乘函数时使用动态规划方法,则可能是O(n)。你觉得怎么样?

这里的想法是选择一些数字,以便可以从中计算其他数字。假设您的系统以恒定速度进行乘法,而不进行除法,则缓存(或“预计算”)1!,11!, 21!, 31!, 41!, 51!, 61!, 81!, 91! 允许计算所有剩余数字,每个数字最多9次乘法


实际上,将较大的数字相乘的成本更高,您也可以进行除法(例如90!=91!/91),而实际上不需要1!,这可以导致这些锚编号的另一个优化分布。

使用9个缓存插槽作为10、20、30、40、50、60、70、80和90的阶乘如何?第十个插槽可能是LRU。最坏的情况是O(10)或恒定时间

随后根据最近的输入维护LRU缓存,因为人们更可能重复搜索

这可能是一个合理的设计选择,但在采访中,我会把这句话更多地作为一个问题问采访者:“是否可以合理地假设通话更像是使用最近的值进行的,或者是否存在其他预期分组(大号码的请求频率高于小号码的请求频率,反之亦然)?”

例如,缓存LRU可能是有意义的,但决不要丢弃10、20、30、40等的值。这样一来,缓存填充这些值后计算阶乘的最坏情况是必须执行10次乘法

您可能需要考虑的另一个问题是,计算机可以非常轻松地处理某些阶乘:

  • 十二!!是32位字中可以容纳的最大值
  • 二十!是64位字中可以容纳的最大值
  • 34岁!是128位字中可以容纳的最大值
因为今天的机器可以轻松地处理64位算术(甚至可能是128位算术),所以永远不要将值缓存为20也是有意义的!当缓存中填充的值大于该值时,将显示或低于该值


查找缓存未命中的最坏情况取决于缓存的存储方式。它是按函数参数排序的数组吗?(查找是O(logn))它是按LRU顺序排列的数组吗?(查找缓存未命中率为O(n))。我认为您还需要明确指出,您希望缓存查找始终返回缓存中小于您正在查找的值的最高值-该缓存值表示您不必为这个特定阶乘计算所做的工作。

我的想法有点像ConnorDoyle的,我将缓存所有10的倍数。由于不知道用户将进行何种类型的呼叫,这将使您遇到最小的最坏情况,即7次乘法/除法,包括最初的两次查找1和10位数,或恒定时间

一个快速的psuedo算法在我脑海中浮现:

total;
mod = input%10;
div = input/10;
if(input%10 == 0)
    output(cache[input/10]);
else{
    if(mod < 5) {
        total = cache[div];
        for(i = 1; i<=mod; i++)
            total = total * (cache[div] + i);
    }
    else {
        total = cache[div + 1];
        for(i = 9; i>mod; i--)
            total = total / (cache[div] + i);
    }
    output(total);
}
total;
mod=输入%10;
div=输入/10;
如果(输入%10==0)
输出(缓存[input/10]);
否则{
如果(mod<5){
总计=缓存[div];
对于(i=1;imod;i--)
总计=总计/(缓存[div]+i);
}
产出(总数);
}

最坏的情况是1位数中的5。

是否提供了足够的信息来确定缓存策略?LRU是一种安全的赌注,但这取决于使用情况。也就是说,如果每次都要枚举1-100,该怎么办。在这种情况下,您可能会缓存计算成本最高的十个值?我不认为将较大的值相乘会很慢,尤其是当它们小于100时。使用除法是不好的,因为它比乘法慢好几倍。关键是从13开始!结果不适合32位数字,大约是21位!它不适合64位数字。所以我们需要更大的数字,对于大数字,乘法时间取决于大小。谢谢你的帮助,michael。我非常喜欢这个答案,但我认为缓存未命中的查找应该是O(1),因为您首先搜索LRU插槽(假设我们只保留了1个LRU插槽)。如果未命中,那么您可以使用数组的结构来搜索正确的元素(正如您所知,数组包含由10个阶乘计算分隔的元素)。给定确定性LRU算法,对手可以通过始终请求刚刚被逐出的页面来想出最坏的情况。