数据结构实战-死磕王争

堆应用场景 找中位数, 新建一个大顶堆存前半部分数据,新建小顶堆存后半部分数据,
两个栈实现队列,一个in管入队,一个out管出队,push in.push pop peek 都是out.pop
反转数组最小值,二分法,大于low 在右边,小于high在左边,停止条件是 high>low 说明有顺序了,low就是要找的值
二维数组查找,从右上角开始,大于 行++ 小于 列–
图 互关 微博单向关注用有向图,qq亲密度是用带权图
存储方式 邻接矩阵 - 浪费空间但是直观计算方便
邻接表 - 节省空间,使用麻烦,类似散列表加链表的方式,链表可以换成红黑树提高效率
设计微博 关注方案, 使用领接表和逆领接表 由于需要按照首字母排序,分页获取粉丝列表,把链表改为跳表提升效率,小规模的可以存入内存直接计算,大规模使用hash取模分片计算。
六度分割理论,深度优先和广度优先搜索算法。
字符串匹配 BF - 暴力遍历
RK算法 - 对主串的所有子串hash, 和模式串的hash比较。
BM算法 - 当主串的某个字符和模式串不匹配是直接滑动到字符后边
KMP算法 - 类似BM算法
Trie字典树 - root不存储,提取字符串的公共前缀合并成树的节点。
Trie适合前缀模糊查找,红黑树跳表适合精确查找
字典树可以实现多模式串的敏感词匹配-ACnode。
贪心算法 - 霍夫曼编码压缩
位图 - 布隆过滤器,使用多个hash算法取模存入bitmap,判断是取出多个位置上的二进制位全为true说明肯定存在。
布隆过滤器是cpu密集型,散列表是内存密集型,判重效率布隆更高。
java 的 BitSet 类,Redis 也提供了 BitMap 位图类,Google 的 Guava 工具包提供了 BloomFilter 布隆过滤器
bit位-二进制, 1byte = 8bit 1kb = 1024byte 1m 1g 1t以此类推
int - 32bit
short - 16bit
long - 64bit
char -16bit
float - 32bit
double - 64bit
boolean - 1bit
string en -1bit cn - utf-8 - 2bit gbk - 3bit
朴素贝叶斯算法 -
音乐推荐系统思路: 寻找和你臭味相投的人,把他听过的你没听过的推荐给你。对一首歌的喜爱程度也可以量化,比如单曲循环加5分,收藏加2分,跳过-1分。设置一个阈值找到和你臭味相投的人。2-找你喜爱歌曲特征相似的歌曲。
K维空间点位表示方式(X1,X2…Xk),叫做向量。两个点位直接的距离用欧几里得公式。
同样歌曲的特征向量也可以量化,用公式计算获得相似度高的歌曲列表。
在这里插入图片描述
B+树 : 跳表很适合做索引存储,二叉树太耗费空间,存到磁盘的话树高导致IO次数很高,B+树完美解决。mysql是按照页存储数据的,树节点大小要小于等于页的大小,减少io操作。写操作会变慢,更新索引树时如果需要分页,父节点也跟着分裂。mysql索引优化也可以合并索引页。
叶子节点个数大于m/2小于m,通过链表把叶子节点连起来便于区间查找,根节点存在内存中,其他节点存在磁盘上。
A*算法,寻找地图两点之间的最短距离。
散列表,增删改查效率很好,一般做kv类缓存的索引底层。
B+树高度低,用于mysql oracle索引。红黑树,效率也很高适合内存索引,文件ext系统索引。
跳表,redis有序集合。
并行算法思想:归并排序,把大数据量均分成16等分,用16个线程进行排序后合并。
快速排序,分成16个从小到大排列的队列,16个线程分别排序。

redis常用数据类型对应的数据结构

列表单个数据小于64k,列表长度小于512使用压缩列表,类似数组允许存储不定长和不同类型的数据。
大数据量用双向链表,底层采用单独把list抽象出来存储节点的头和尾、长度信息。

// 以下是C语言代码,因为Redis是用C语言实现的。
typedef struct listnode {
  struct listNode *prev;
  struct listNode *next;
  void *value;
} listNode;
typedef struct list {
  listNode *head;
  listNode *tail;
  unsigned long len;
  // ....省略其他定义
} list;

字典也是一样数据量小用压缩链表,条件和上班的列表一样。大数据量用散列表。
当数据量越来越大,装载因子很大时自动扩展2倍空间,当装载因子小于0.1时自动缩容,空间的变化使用渐进式策略,避免一次性重新hash导致的服务停顿。
集合也是数据量小时使用有序数组,条件是都是整数,个数小于512。数据量大使用散列表存储。
有序集合数据量小使用压缩列表,大时使用跳表。
redis如何持久化数据结构,两种思路,清除只存数据然后重新规划,浪费时间。原封不动存储无序重新hash,浪费空间。

搜索引擎背后的经典数据结构和算法

搜集 爬虫爬取网页
分析抽取网页内容,分词,构建临时索引,计算PageRank页。
索引通过分析阶段的临时索引构建倒排索引
查询响应用户请求,通过倒排索引取出网页内容,计算网页排序返回给用户

  1. 搜集阶段爬虫技术是把所有的网页地址抽象成有向图,找到一个核心知名网友作为根,使用有向图的广度优先遍历开始爬取。遇到新的连接就放入link.bin队列,可以抽象成大字符串通过标签隔开,支持断点续爬。使用布隆过滤器实现判重,为了防止布隆文件丢失,每隔半小时存储一次bloom_filter.bin中,重启后恢复到内存中。
    原始网页存储,使用doc_id.bin区分,超过1g拆分。并且按照计数法排序,doc_id.bin中存储网页地址和计数的关联关系。
  2. 分析阶段使用字典词库对中文进行分词,采用最长匹配规则。分词后的单词列表存入字典树,并对其进行编号,增加计数器功能。网页和单词列表的对应关系存入临时索引文件tmp_index.bin用于倒排索引,计数器编号和单词列表的关系存入term_id.bin。
  3. 索引阶段使用多路归并排序算法或者mapreduce,相同的单词排序后处理成倒排索引。倒排索引存入index.bin文件,单词编号在索引文件中的偏移量便于快速从索引中读取单词对应的网页编号列表。
  4. 查询阶段通过以上三步形成四个文件,doc_id.bin 网页链接和编号关系 term_id.bin 单词和编号关系
    term_offset.bin 单词编号在倒排索引中的偏移位置 index.bin 倒排索引,单词编号和网页编号列表关系
    前三个比较小可以直接放入内存操作。查询开始 - 用户输入文本进行分词后先去term_id.bin查找单词编号列表,
    – 拿单词编号列表去term_offset.bin中查找单词的偏移位置 – 再去index.bin中查找网页编号列表,统计出现次数后再去doc_id.bin中查找对应的网络链接分页显示给用户。
高性能队列Disruptor

使用循环队列实现,为了解决生产消费覆盖问题,使用两阶段写入模式,先申请一段连续空间时加锁,后边使用时不需要加锁可以提高性能。

微服务中的数据结构和算法
  • 鉴权:精准匹配URL是否有权限,字符串匹配算法 KMP、BM、BF等,也可以给url编码采用二分法快速查找。
    - 使用trie树实现前缀匹配,把url中公共部分抽出来。
  • 限流:固定时间窗口限流算法 --> 滑动时间窗口限流算法使用循环队列解决时间点间隔大流量问题。
    - 令牌桶算法,漏桶算法。
短网址服务算法
  • MurmurHash算法32bits的哈希值转换,再十进制62进制转换就更短了。先查库里的对应关系,再加盐继续hash解决冲突问题。用布隆过滤器判重减少一次IO查找。
  • 通过自增id,62进制的方法。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值