一道数据结构相关的题,请教一下站里的大神们 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fxybk
V2EX    问与答

一道数据结构相关的题,请教一下站里的大神们

  •  
  •   fxybk 2021-01-31 22:30:07 +08:00 1518 次点击
    这是一个创建于 1743 天前的主题,其中的信息可能已经有所发展或是发生改变。

    小弟本人是前端,最近被问到一道数据结构的题

    实现一个 new Cache(length)来存储数据,要求实现 get(key)和 set(key,data)这两个方法,重点,要考虑性能(优先考虑 get 的性能)

    小弟不才,实现的时候不知道要从哪方面去体现性能优化,请教一下各位大神

    12 条回复    2021-02-01 15:51:35 +08:00
    zxCoder
        1
    zxCoder  
       2021-01-31 23:03:55 +08:00
    哈希表?
    oooolongtea
        2
    oooolongtea  
       2021-02-01 04:56:55 +08:00 via iPhone   1
    可以参考 lru 或者 lfu
    fxybk
        3
    fxybk  
    OP
       2021-02-01 09:49:41 +08:00
    @oooolongtea 学习了~
    Claar
        4
    Claar  
       2021-02-01 10:01:13 +08:00 via iPhone   1
    感觉就是简单的哈希表啊,本身哈希表的速度不是很快了吗? lru 我没有写过,感觉 lru 的前提是储存空间不足被迫使用的方案,而且 lru 可能还会用到哈希表来储存(如果想要速度快的话),题目很可能是想要你实现一个简单的好的树实现,也可能是好的哈希表实现(我没写过这个,感觉可能会难点)
    zoyua
        5
    zoyua  
       2021-02-01 10:13:16 +08:00
    lru 双向哈希链表
    fxybk
        6
    fxybk  
    OP
       2021-02-01 12:27:15 +08:00
    @Claar 懂了,查找跟数据储存分开考虑,查找用哈希表,储存空间问题用 lru 或者 lfu 。。感谢~
    fxybk
        7
    fxybk  
    OP
       2021-02-01 12:27:44 +08:00
    @zoyua 是的。有思路了。感谢感谢
    Claar
        8
    Claar  
       2021-02-01 12:54:46 +08:00
    当然,感觉 func Cache(length)这个命名有很强的 LRU 的暗示,可能他表达的就是 LRU
    Claar
        9
    Claar  
       2021-02-01 14:04:26 +08:00
    另外我始终认为出题的人描述不正确,你可以通过指出问题的问题来表现你懂的知识哈哈哈
    1.实际上如果想要无特殊的限制 /规律下以尽量快的平均速度去实现储存访问,应该是哈希表或者树的实现
    2.LRU 一类的缓存置换算法,其核心应该在于 1 )空间利用的最大化,2 )依据思想:如果一个数据被使用,那么接下来这个数据被再次使用的几率比其他数据高。个人认为是更偏向 1 的,(主要是我没有看过 OS 上 LRU 的官方实现)。我认为如果不是为了缓存空间的利用率尽可能高,使用哈希表这类 O(log N)的算法平均应该更快一些。
    所以我觉得如果他想要的答案是 LRU 的话,应该增加一些规律要求。
    fxybk
        10
    fxybk  
    OP
       2021-02-01 15:03:52 +08:00
    @Claar 感谢。。。非常详细的考虑,看完真是觉得这题难为这么一个前端小弟了
    xiaoqiao24
        11
    xiaoqiao24  
       2021-02-01 15:12:49 +08:00
    key 使用 hash 来生成,不管数据多少,查找效率都是 1
    Claar
        12
    Claar  
       2021-02-01 15:51:35 +08:00
    @fxybk #10
    哈哈哈其实简单的判断并不难,只需要知道
    1.哈希表是多数情况下 key-value 储存算法的选择,他的算法复杂度不高,效率相对来说应该是能经过考验的。另外“hash”也是指具体的“实现方式”
    2.树形是常见普通人手写 key-value 算法选择,和哈希表对比可能他的速度稍稍差一点点(但是树形实现多数情况下速度也很优秀了,如果选用具体的如红黑树这种经典树形实现(红黑树算是树里面相当优秀的),基本是很够用了),且树形相对哈希来说可能好写一些(这只是个人认为)
    3.像哈希这种优秀的算法比较大的缺点是空间占用不小,一般来说你要储存 100 个 key-value 可能需要 300 个左右的空间
    4.相对来说树的具体实现,红黑树是很优秀的,但难写一些,AVL 没红黑树强,但依然优秀,且比较好写
    5.树形实现速度也很快,复杂度是 O(log N),大概就是总量为 2 ^ 20 次方的数据,每次查找差不多只需要查 20 个数据即可,而和一般的如队列从头找到尾的查找方案对比是快的没边了
    6.LRU 是缓存置换算法,并不是具体的“实现”,只是一种思想形成的结构,也就是说只要满足一定的特征就能称为 LRU,但是具体实现方案的不同,效率可能差很远

    在没有特殊技巧的前提下,如果侧重速度,选用哈希表 /树来储存 key-value 应该平均下来最快的了。
    如果有特殊技巧,比如:最近用过的数据接下来被使用的几率更高这种规律下,如果频繁的进行查找最近用过的几个数据,那么队列的实现会快一丢丢(因为虽然有 2 ^ 20 个数据,但你查来查去只查前面几个,那当然容易啊)
    而且“最近用过的数据接下来被使用的几率更高”这种规律其实只是像算力“摩尔定律”一样只是人为粗略的概括起来的一种规律,实际效果比较玄学,如果不是空间很有限的话,我认为根本没必要使用严格的 LRU 实现,直接使用自带的哈希表存下来就可以了;而使用如(链表+哈希表)来实现的 LRU 其实就是用链表来占据“最近用过的数据接下来被使用的几率更高”的优势,除了用哈希表来查找之外,链表可以加速排在前面的项的查找,并且方便把久远没用的数据丢掉来减小空间占用


    综上:如果想要实现简单,直接用语言自带的哈希表走起,不过这太简单了,估计不是人家想考的,如果要实现 LRU 的话,最好是用链表+哈希表,用哈希表来找具体位置,关于规律的部分就是把最新用的数据排到最前面,每次查找完就把这个数据放到最前排就可以了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3295 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 00:06 PVG 08:06 LAX 16:06 JFK 19:06
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86