由MESI协议看内存屏障
本文主要内容来自于:Memory Barriers: a Hardware View... Continue reading...
ThreadLocal的作用是提供线程内的局部变量,不同的线程之间不会互相干扰,这种变量在线程的生命周期内起作用,减少通一个线程内多个函数或组件之间一些公共变量传递的复杂度。 总结下来就是: 线程并发:在多线程并发的场景下 传递数据:我们可以通过ThreadLocal在同一线程,不同组件中传递公共变量 线程隔离:每个线程的变量都是独立的,不会互相影响... Continue reading...
方法1:调整次序法 A∩(B∩C)、(A∩B)∩C要如何调整次序。假设A、B、C的元素个数分别是2、20、40,且A包含咋洗B内,B包含在C内。 A∩(B∩C)B和C求交集时间代价就是 20+40 =... Continue reading...
在许多大型系统中,倒排索引是最常用的检索技术,搜索引擎、广告引擎、推荐引擎等都是基于倒排索引技术实现的。而在倒排索引的检索过程中,两个 posting list 求交集是一个最重要、最耗时的操作。 跳表法加速倒排索引... Continue reading...
正排索引 我们先来看比较简单的那个问题:给出一首诗的题目,马上背出内容。这其实就是一个典型的键值查询场景。针对这个场景,我们可以给每首诗一个唯一的编号作为 ID,然后使用哈希表将诗的 ID 作为键(Key),把诗的内容作为键对应的值(Value)。这样,我们就能在... Continue reading...
如果我们要查询的对象ID本身是正整数类型,而且ID范围有上限的话,我们可以直接用用户ID的值作为下标,id存在为1,不存在为1。如果用4个字节存储0和1会造成巨大的浪费。 使用位图来减少存储空间 如果我们能以 bit 为单位来构建这个数组,那使用空间就是... Continue reading...
使用hash函数将key转换为数组下表 如果系统中的用户ID是从1开始到10000的整数,可以通过数组来实现O(1)级别的查询能力。 那如果内存空间有限,我们只能开辟一个存储 10000 个元素的数组该怎么办呢?这个时候,我们可以使用“tom”对应的数值... Continue reading...
总览 树结构是如何进行二分查找的? 链表的结构特点意味着它无法提供“随机访问“,那么如果我们要以O(1)的时间代价快速访问到中间节点,就可以和有序数组一样使用二分查找了。 如果我们把中间节点单独拎出来记录,那么第一步操作就是直接访问这个中间节点,然后决定去左还是去右。 这样,一个binary... Continue reading...
数组结构需要连续空间来存储,而链表不需要。 数组和链表分别代表了连续空间和不连续空间的最基础的存储方式,它们是线性表(Linear List)的典型代表。其他所有的数据结构,比如栈、队列、二叉树、B+ 树等,都不外乎是这两者的结合和变化。 使用二分法提升数组的检索效率:通过排序转为有序的数据集。... Continue reading...
RPC remote precedure call 远程过程调用,计算机通信协议。该协议允许运行一台计算机的程序调用另一台计算机的子程序,而程序员无需额外为这两个交互作业编程。... Continue reading...
运行顺序:必须先2后1 wait-notify版 // 用来同步的对象 static... Continue reading...
Reentrant Lock Synchronized和ReentrantLock: 相同点 ReentrantLock和synchronized都是独占锁,只允许线程互斥的访问临界区。但是实现上两者不同:synchronized加锁解锁的过程是隐式的,用户不用手动操作,优点是操作简单,但显得不够灵活。一般并发场景使用synchronized的就够了;ReentrantLock需要手动加锁和解锁,且解锁的操作尽量要放在finally代码块中,保证线程正确释放锁。ReentrantLock操作较为复杂,但是因为可以手动控制加锁和解锁过程,在复杂的并发场景中能派上用场。... Continue reading...
异步模式——生产者/消费者模式 要点 与前面的保护性暂停中的 GuardObject 不同,不需要产生结果和消费结果的线程一一对应... Continue reading...