详情

全站展示位

恢复“新建”文件类型方寸之间

有的时候我们会发现自己常用的“新建”文件类型丢失了,这时候我们可以修改注册表来添加找回。 假设丢失的是新建.txt 文件类型 用记事本新建一个文本文件,命名为“ADDTXT.REG” 输入以下代码:Windows Registry Editor Version 5.00[HKEY_CLASSE...。。。

推荐

分类目录归档:ENglISh |

技術文章及人生思考

心灵鸡汤

  南宋大臣张浚因与奸相秦桧政见不和,被贬往湖南零陵做地方官。

  他出发时,带了几箱书随行,有人诬告他与乱党有关系,结果被高宗检查书信和破旧衣物,高宗叹息道:“想不到张浚贫守到如此地步!”

  很可怜他,于是派人骑快马追上张浚,赏赐他黄金三百两。

列表展示

主站展示位

Arch Linux 如何切换内核方寸之间

Notice切换内核不是一件容易的事。我建议你有一个实际的理由这样做,而不仅仅是实验/为了好玩。虽然这本身并不是一个困难的过程。因为 linux 发行版通常设置为与特定内核配合使用。虽然有些不像其他发行版那样与内核紧密相连,但许多发行版维护者选择特…

Arch Linux音响有杂音的解决办法方寸之间

Arch Linux 台式机(AMD)最近安装完新系统之后,在配置电脑的时候发现电脑的音响在不播放声音的时候会出现puta puta的声音。原因某些驱动模块会在声卡闲置时关闭它以节约用电。解决办法方法1:在/etc/modprobe.d目录下新建一个d…

安装Linux后Windows EFI分区消失的问题解决方寸之间

最近在电脑上安装了最新的Arch Linux,这次不同于之前,使用了Gnome的桌面环境,用起来还不错,所以就按照我之前的配置文件,光速配置了一下电脑。然而当我配置Windows双启动的时候,却找不到Windows的EFI分区了,很奇怪,我的两个系统安装在两个硬盘里,所…

PGP工作原理方寸之间

最近在浏览博客的时候发现博主的PGP Key页面,虽然之前知道是用于邮件通信加密的,但是具体原理及使用却不太清楚,所以找了时间查阅了相关资料,整理一下PGP加密的一些内容。

Build site with Franklin.jl方寸之间

Forward Franklin.jl is a simple, customisable static site generator oriented towards technical blogging and light, fast-loading pages. At first, I want to learning Julia with a small open source project, smaller and better. Then I search on github with topic#julia, and I find this tool. As I learned about it on its site, I think I can use this for my massively personal site(maybe it is beautiful, but too complex), and learning Julia when rebuilding my site. Therefore, I write this tutorial as my beginning. Last but not least, Franklin.jl has many features: Augmented markdown allowing definition of LaTeX-like commands, Easy inclusion of user-defined div-blocks, Maths rendered via KaTeX, code via highlight.js both can be pre-rendered, Can live-evaluate Julia code blocks, Live preview of modifications, Simple optimisation step to compress and pre-render the website, Simple publication step to deploy the website, Straightforward integration with Literate.jl. Setup Environment...

C++继承/多态/虚函数方寸之间

继承 访问控制和继承 访问publicprotectedprivate同一个类yesyesyes派生类yesyesno外部的类yesnono 一个派生类继承了所有的基类方法,但下列情况除外: 基类的构造函数、析构函数和拷贝构造函数。 基类的重载运算符。 基类的友元函数。 一个问题 #include <iostream> class A{ private: int a; char b; }; class B: public A{ public: char getc(){return this->c;} private: char c='j'; }; int main() { B test; cout<<test.getc()<<endl; cout<<sizeof(int)<<endl; // output is 4 cout<<sizeof(char)<<endl; // output is 1 cout<<sizeof(test)<<endl; // output is 8 } 如果把A的private属性a,b变成public属性,那么test的size就变成了12 继承类型 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。 保护继承(protected): 当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。 在多继承时,如果省略继承方式,默认为private 多态 C++多态性是通过虚函数来实现的 多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定。 多态的四种形式 多态总体上分为:编译时的多态(静态多态)和运行时的多态(动态多态)。又被细分为:参数多态,包含多态,过载多态,强制多态。前两种为通用多态,后两种为特定多态。 参数多态:采用参数化模板,通过给出不同的类型参数,使得一个结构有多种类型。如 C++语言中的函数模板和类模板属于参数多态。参数多态又叫静态多态,它的执行速度快,异常少,调用在编译时已经确定。参数多态是应用比较广泛的一种多态,被称为最纯的多态。 包含多态:在许多语言中都存在,最常见的例子就是子类型化,即一个类型是另外一个类型的子类型。一般需要进行运行时的类型检查,属于动态多态。包含多态的基础是虚函数。虚函数是引入了派生概念后用来表现基类和派生类的成员函数之间的一种关系。 过载多态:同一个名字在不同的上下文中所代表的含义不同。典型的例子是运算符重载和函数重载,属于静态多态。 强制多态:编译程序通过语义操作,把操作对象的类型强行加以变换,以符合函数或操作符的要求。程序设计语言中基本类型的大多数操作符,在发生不同类型的数据进行混合运算时,编译程序一般都会进行强制多态。程序员也可以显示地进行强制多态的操作。如 int+double,编译系统一般会把 int 转换为 double,然后执行 double+double 运算,这个int->double 的转换,就实现了强制多态,即可是隐式的,也可显式转换。强制多态属于静态多态。 相关概念 多态性 指相同对象收到不同消息或不同对象收到相同消息时产生不同的实现动作。C++支持两种多态性:编译时多态性,运行时多态性。  a、编译时多态性:通过重载函数实现  b、运行时多态性:通过虚函数实现 <<

Linux创建systemd服务方寸之间

创建自定义systemd Service 创建一个脚本或者使用可执行文件,本文以一个test.bash脚本为例: DATE=`date '+%Y-%m-%d %H:%M:%S'` echo

如何将Julia添加到Jupyter Notebook方寸之间

Julia是一门灵活的动态语言,适合用于科学计算和数值计算,并且性能可与传统的静态类型语言媲美。JupyterNotebook是目前最流行的数据科学Web程序,功能涵盖数据清理和转换,数值模拟,统计建模,数据可视化,机器学习等。本文旨在使用IJulia将Julia集成到Jupyter交互式环境中。本文假设你已经安装好了Julia和Jupyter环境。 第一步 在命令行键入julia,运行Julia程序,出现以下提示: $ julia _ _ _(_)_ | Documentation:

How to Create Linux Desktop Entry方寸之间

create a file named yourappname.desktop in /usr/share/applications/ directory or ~/.local/share/applications/. input the following lines: [Desktop Entry] Type=Application Terminal=false Exec=/path/to/app Name=app Comment=app comment Icon=/path/to/app/icon

使用UFW配置Linux防火墙方寸之间

UFW 代表 Uncomplicated Firewall ,是用于管理 iptables(netfilter) 防火墙规则的对用户更加友好的前端工具,它是Ubuntu的默认防火墙配置工具。 列出 UFW 规则 您可以通过以下命令检查 UFW 的状态并列出所有规则: sudo ufw status 如果未启用UFW,则会显示: Status: inactive 如果已经启用,则UFW 处于活动状态,输出将打印所有活动防火墙规则的列表: Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) 如果想要获得额外信息,可以使用status verbose: sudo ufw status verbose 输出将包含有关日志记录,默认策略和新配置文件的信息: Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) 如果想要得到所有活动规则的顺序和 ID,可以使用status numbered: sudo ufw status numbered 输出则会显示以下内容: Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 22/tcp (v6) ALLOW IN Anywhere (v6) 添加UFW规则 添加规则很简单,不过在添加之前,首先确认UFW是否开启。 例如,如果你要添加打开12345端口的规则,键入以下命令即可: sudo ufw allow 12345 拒绝: sudo ufw deny 12345 删除UFW规则 有两种方法可以删除 UFW 规则: 按规则编号 按规则格式 如果你是通过 SSH 删除防火墙规则,请确保不要通过删除允许 SSH 通信端口的规则来将自己锁定在远程服务器之外。默认情况下,SSH 侦听端口 22 。 按规则编号删除 UFW 规则 列出规则并找到要删除的规则编号(上面提到的status numbered命令); 知道规则编号后,使用ufw delete命令后跟要删除的规则编号。 例如,要删除带有 number 的规则4,您可以键入: sudo ufw delete 4 系统将提示您确认是否要删除规则: Deleting: allow 22/tcp Proceed...

Solution for _CRT_SECURE_NO_WARNINGS方寸之间

platform: VS2019os: win10 Problem:An error about _CRT_SECURE_NO_WARNINGS when I use the std::localtime() function for getting the current systime. Solution: Use an alternative feature function in C++. add this line at the first line. #define _CRT_SECURE_NO_WARNINGS add _CRT_SECURE_NO_WARNINGS on the pre-processor(project>properties>C/C++>preprocessor)

Multithreaded Processing in Dynamic Inverted Indexes for Web Search Engines方寸之间

ABSTRACT 在Web搜索引擎中处理查询需要有效地使用硬件资源来应对用户流量的规模和动态。本文重点讨论了多线程处理查询,这些查询需要访问大型反向索引数据结构以获取一组文档,通过执行WAND运算符对它们进行排名,以获得前K个最相关的文档。以及在执行查询的同时解决在反向索引上插入新文档的问题。 我们提出了一种高效的策略来为查询和索引更新操作分配线程,这种策略适合于在查询处理的同时支持索引的更新。 我们提案的核心是一种简单的分类技术,旨在快速为查询操作分配线程。 Introduction Web搜索引擎中最耗时的任务是对用户查询的大量潜在答案的排名。其成本与在支持搜索引擎服务的处理器的分布式存储器集群中保持索引和压缩的Web样本的(通常是巨大的)大小成比例。每个处理器都保存一小部分Web样本,该样本在称为倒置文件或索引的数据结构中索引。基本上,反向文件由词汇表组成,该词汇表包含Web示例中找到的所有相关术语,并且对于每个术语,存在包含该术语的Web文档的列表以及诸如术语文档内频率的额外数据。该索引可以快速检索包含所有查询项的文档以及计算这些文档的分数所需的额外数据。分数越高,文档对于给定查询越相关。然后通过选择具有最高分数的K个文档来产生查询的答案。有几种方法可以为Okapi BM25 等文档分配分数。 WAND运算符通过将与文档评分(例如,BM25)相关联的昂贵计算限制为仅几个文档,同时跳过没有机会进入前K个的文档,使得能够有效地执行文档排序过程。这使得文档评分成为一个进程,其运行时间成本是不可预测的,并且在查询中变化很大。不可能假设其成本与所涉及的文档列表的长度成比例。因此,在运行时以及在很短的几分之一秒内确定分配给WAND操作的线程数变成了一个非常重要的问题,因为总执行成本仅在查询完全已知时才知道在处理器中解决了。 多线程查询处理的实用方法是让每个活动查询由单个线程顺序处理。由于Web搜索引擎始终包含大量活动查询,因此在不需要支持倒置文件中的并发更新时,这种方法在实践中非常有效。但是,当需要支持在倒置文件中插入新文档时,这种方法效率不高。在这种情况下,必须修改许多文档列表,并且由于人们倾向于在文档和查询中使用一组非常流行的术语,因为在处理查询和线程更新文档列表的线程之间的冲突读写操作可能会降低性能。 [4]中提出的解决方案允许所有线程一次参与一个查询或索引更新的并行处理。由于传入的查询/更新请求是按顺序处理的,因此不会发生读取和写入冲突。当文档包含足够大的术语时,此策略是合适的,并且可以有效地使用所有线程来解析每个查询。但是,在许多情况下,WAND需要一些线程来使用处理器中可用的所有线程所需的时间大约相同(甚至更短)。因此,这种方法不能扩展WAND查询,并且通常,它不能扩展到支持高效执行大量线程的处理器。 请注意,在生产搜索引擎中,我们应该期望在索引更新之间使用可变大小的用户查询序列来处理工作负载。我们研究了几种利用这一事实的方法。例如,除了使用每个查询/更新操作的单个线程和锁定以防止读/写冲突的简单但效率低的策略之外,我们可以累积足够的更新操作以在索引更新期间保持所有线程忙,并快速处理批处理通过将一个或多个线程正确分配给单个查询来使查询保持繁忙,以便尽快使用每个批处理。在这种情况下,特别是对于小批量,每个查询分配一个线程不是一个好主意,因为查询解决方案时间的差异可能非常高,从而产生空闲线程,并且在许多情况下,顺序查询解决方案时间可能超过预先定义的时间作为设计要求对搜索引擎施加的查询响应时间的上限。 在本文中,我们提出了一个有效解决WAND查询批处理问题的解决方案,每个WAND查询都有适当数量的线程来快速解决它们并避免在每个批处理结束时空闲线程。我们的解决方案基于工作单元中的查询分解,这些查询放在队列中,线程从这些队列中完成下一个工作。为了完成查询分解,我们提出了一种新的分类方案,该方案非常快速并且达到了合理的精度。根据该方案,我们提出了一种更新倒排文件的策略,该策略将处理并发查询/更新操作的整个任务转换为比以前的方法更有效的方法。 本文的结构如下。第2节介绍相关工作。第3节描述了我们用于查询和文档插入的线程分配技术,以及我们的分类技术。第4节介绍绩效评估研究,第5部分介绍结论。 Related work 现代搜索引擎使用倒排索引来加速文档搜索过程。倒排索引是一种简单的结构,它存储文档数据,允许快速查找和排列包含某些查询术语的集合的文档[10]。在倒排索引中,我们存储表示单个术语的倒排列表以及包含该特定术语的所有文档。文档由数字文档标识符(docID)表示,并且通常还存储每个特定文档中术语的频率(特定术语的该文档中出现的次数)。还可以存储附加信息,例如每个文档中术语的各个位置。还有许多压缩技术[9,3,2]用于以高效的方式存储倒排索引,这其中的许多压缩技术存储越来越多的docID,以便只有delta(docID和前一个之间的差异)存储。 确定可在docID有序索引中使用的前K个(top-K)文档的一种有效方法是WAND [5]。WAND算法将查询术语列表按每个查询术语的当前docID排序。该方法使用每个文档的分数的上限通过列表前进,并丢弃其分数不大于当前top-K文档中的最不相关候选者的那些,其得分是查询的当前阈值。因此,该算法仅计算那些不能被丢弃的候选者的完整分数,减少了为每个查询执行的计算总量。通过跳过整个发布列表块[6]和并行化[8]的处理来改进这种技术。 WAND使用基于文档的两级评估的排名。在第一级,它使用每个文档的分数的上限来尝试丢弃尽可能多的文档。在第二级,它计算通过第一级测试的文档的真实分数。为了使这个过程高效,它使用堆数据结构来存储到目前为止找到的最好的top-K文档。堆中排名最低的文档的分数被用作第一级评估的阈值,以丢弃不能作为最终前K文档的一部分的文档。这样可以实现高效的丢弃过程,确保在此过程中不会丢失相关文档。这意味着实现多线程WAND的两种方法。其中一个是使用本地堆(LH),每个线程一个,另一个是使用共享堆(SH)。在LH方案中,每个线程处理索引的一部分,同时保持本地堆与当前特定线程找到的当前top-K文档。在该过程结束时,每个线程的结果必须合并到一个结果集中。在SH方案中,每个线程处理索引的一部分并将文档存储在共享堆中。 在共享堆方案中,不需要合并,并且丢弃过程往往更有效(因为具有更高分数的文档往往在堆上)。但是,必须通过原始锁(lock primitive,就这么翻译了)来控制对堆的访问。我们在第4节中描述的实验设置下进行了测试以比较两种方法的平均时间和效率,我们发现SH WAND通常对多线程WAND更有效[8],见图1。所以我们选择了共享堆WAND在我们的实验中使用。 PROPOSAL Threads Management 我们将倒排索引分区以通过为单个查询分配多个线程来执行多线程查询处理。为实现这一目标,我们将每个术语的列表划分为多个独立列表。分区数等于处理器中允许的最大线程数。要解析具有一定数量线程的查询,我们在参与线程之间分配不同的部分。但是,如果我们启动将解析单个查询的线程并等待它们在为其分配处理其他查询之前结束其工作,则会有空闲线程等待参与线程完成其工作,如图2所示。 相反,我们建议通过在我们称之为工作单元的分解查询处理来增加维持所有线程忙于执行有用工作的机会,如图3所示。为此,我们将查询划分为多个独立单元,这些单元等于分配的线程数,并将这些单元存储在共享队列中。一旦线程完成其当前的工作单元,它就会从队列中获取下一个工作单元。对队列的访问由简单的锁定机制控制。这是可以接受的,因为我们感兴趣的是优化系统的查询吞吐量(每单位时间的查询),前提是单个查询响应时间不大于给定的边界。 用于确定任何到达查询的工作单元数的分类方案是使我们的方案正常工作的关键参与者,因为查询处理时间可以显着地相互影响。在我们的方案中,可以使用大量线程来解决要求严格的查询以减少其处理时间,而需要很少工作的查询可以被调度为共享队列中的单个单元。问题是事先不知道查询的实际工作量。我们的分类方案设计用于预测运行时任何查询的不同线程数所需的工作量。它必须是在很短的时间内提供合理预测的快速方法。 A Simple and Fast Classification Technique 我们提出了一种简单的策略来确定分配给每个查询的正确线程数。与更复杂和精确的方法相比,该方法在查询时非常有效并产生了良好的结果(比较研究见第4节)。我们的分类方法背后的概念是,没有必要花费大量资源来预测查询运行时间,以估计查询的适当线程数。预测的目标实际上并不是知道真实的查询时间,而只是知道适当数量的线程。 请注意,当使用太多线程来处理给定查询时,会出现显著的开销,特别是考虑到多线程WAND的平均效率对于大量线程而言往往较低(我们定义效率为最大线程工作除以平均线程工作)。通常,由于需要少量计算,因此可以处理大量快查询,因此无需使用多个线程来解决它们。此外,由于需要解析大量计算,因此处理的慢查询数量相对较少。查询分类的目标是识别慢查询以分配更多资源来解决它们。 实现此识别的一种方法是使用机器学习技术来预测处理查询的成本。这可能涉及使用预测技术,范围从简单的线性模型到使用大量特征进行更精确预测的模型,甚至使用人工神经网络和其他复杂的机器学习技术。然而,这将需要预测每个不同数量的线程的查询时间,这可能导致需要为每个案例训练模型并且在查询到达时间对每个模型执行预测计算。然后,在查询时有效使用处理器线程的低成本启发式方法是为查询选择最小的线程数,以确保整个查询响应时间的上限。 但是,对于慢查询,它必须至少引用与查询术语相关联的大型发布列表所代表的许多文档。即使其他方面影响查询成本,例如每个文档发布列表上的术语频率分布,以及查询术语之间的关系,但是查询引用许多文档是必要条件。考虑到这一事实,在我们的方法中,我们只使用查询项的数量和各个发布列表的长度总和来执行设置要分配给查询的线程数所需的分类。 我们的技术首先确定查询中的术语数量,因为它是影响查询时间的重要因素。例如,在我们的实验数据(第4节)的示例中,我们发现,当使用一个线程顺序处理时,只有4.8%的具有2个术语的查询花费超过160毫秒,而具有5个术语的35%的查询需要类似时间。这部分是因为具有更多术语的查询往往需要审阅更多文档,但是由于他们使用包含所评估文档的所有相关术语的数据,因此计算得分的成本也更高。 在每种情况下,我们独立地计算查询项列表长度的总和,并使用它们来确定应该分配给查询的线程数。这是通过使用之前在训练阶段确定的截止值(或阈值)来实现的。计算截止值,以便它们倾向于分配足够的线程,以确保查询花费的时间小于上限。这个界限可以定义为训练数据集中查询的平均连续运行时间的一到两倍之间的值。这种方法比上面描述的方法更不灵活,它包括测试几个线程,直到达到不超过上限的最小数量为止。在我们的案例中,在训练时确定了界限及其各自的界限值。但是,我们的方法比其他方法快了几个数量级,只给实际查询执行时间增加了几纳秒。 为了确定适当的截止值,我们使用训练查询的样本,并计算每个线程数的实际执行时间。为了简单起见,我们只使用2的幂作为分配给查询的潜在线程数。因此,例如,对于一个高效地支持16个线程执行的处理器,我们有5类查询,根据1、2、4、8或16个线程是否实现了确保查询时间小于上限的最小线程数。 在准备阶段,我们根据术语的数量分离训练查询,并且在每种情况下,我们独立地按列表的长度总和对它们进行排序。因此,我们获得了一组对(文档总数,线程数ID)按文档总和排序,并且类ID等于所用线程数。对于此集合中文档总和的4个cuto ff值,我们可以将查询分为5个类,用于前一个支持16个线程的处理器示例。这可以扩展到任意数量的处理器线程(类),因为这些总和在实际Web样本中往往是非常大的值。 为了确定cuto ff值,我们执行搜索过程以找到最大的F-Score的值。对于增加cuto ff值的任意初始化来定义每个类的限制,我们通过根据正确分类的查询数量计算True Positive案例,False Positive案例和False Negative案例来确定所选择的cuto ff值集合的好坏程度。每节课。如前所述,当相关联的线程数是产生低于上限的查询执行时间的最小线程数时,认为查询被正确分类。通过这些计数,我们计算精度(真阳性除以真阳性和假阳性的总和)和召回(真阳性除以真阳性和假阴性的总和)。通过这种方式,平均F-Score被定义为Precision和Recall指标的调和平均值,因此我们只需寻找最大化类集平均F-Score的cuto ff值。 网络搜索引擎用户倾向于使用极少数条款提交查询。我们通过定义由1,2,3,4,5和5个以上术语的查询组成的训练集来利用这一事实。对于每组,我们用上述方法获得cuto ff值的矢量。然后在查询运行时选择右侧集。 Dynamic Indexing 我们研究的重点是优化处理节点的性能,该处理节点使用多个线程解析查询,并且还在主存中保持倒排索引更新。该节点必须允许向Web文档索引集中添加新文档。在标准实践中,我们假设docID是增加的整数,其中索引列表通过增加docID来保持排序,以实现其高效压缩[2]。 在我们的实验中,我们省略了文档删除的情况,因为压缩索引列表的实现面临的困难超出了本文范围。 一种粗略但实用的方法是定期重建受影响的索引列表,并跟踪无效的docID,以便在查询的文档排名过程中省略它们。 WAND同时处理查询中涉及的所有索引列表。 因此,在解决查询之前必须锁定所有这些索引列表。以相同的方式,如果正在修改查询中涉及的任何索引列表,则必须等待修改完成以继续处理查询。有几种方法可以处理潜在的读/写冲突。在下文中,我们描述了我们在应用领域中发现的最有效的策略。注意,通过使用数据库和操作系统文献中提出的并发控制策略(例如,读和写锁)来同时处理查询和索引更新的方法已经在[4]中进行了测试。 我们设计了三种策略来解决新文档的插入问题,并根据不同的文档到达率评估它们的性能。我们称之为直接插入的第一种方法是安排将每个新文档作为工作单元插入队列中。任何空闲线程都可以使用此工作单元并在涉及的索引列表上执行插入过程。通过迭代新文档的每个术语,请求对要修改的列表的独占访问锁定,并在释放锁定并移动到下一个索引列表之前插入具有相应术语频率的新文档docID来解决插入。 第二种方法,我们称之为批量插入,首先收集一定数量的新文档,然后构建临时子倒排索引。 在这种情况下,主索引中的插入过程比直接插入中的插入过程更有效,因为在新文档中出现多次的术语将具有在子倒排索引中具有多个文档的索引列表。 然后,将子索引插入类型工作单元插入队列中。 因此,当空闲线程占用该工作单元时,它仍然在插入所涉及的每个索引列表的文档,而其他线程继续同时解决查询。 第三种方法类似于第二种方法,在临时子索引中为其组织收集了一定数量的文档,但是不是生成单个工作单元,而是将子索引术语加上它们各自的索引列表分布到多个工作单元中,这样所有线程都可以并行处理插入。 我们称这种方法为分布式批量插入(Distributed Batch Insertion),它有望改进以前的方案,因为它可以消除来自查询和索引列表更新的独占访问锁之间的冲突。当所有线程在处理当前批次查询的同时完成所有线程时,实际上消除了冲突。 在第二种和第三种情况下,插入过程比第一种情况要快得多,因为涉及的发布列表保持锁定在主索引中。 这是因为大部分处理时间都花费在构建子倒排索引上,因此一旦子发布列表准备插入,它们在相应主索引发布列表末尾的位置就会非常快速地执行,因为它需要的计算量要少得多。 EXPERIMENTAL EVALUATION 我们使用来自TREC GOV2 Collection的2500万个文档中的16个线程来评估解决WAND查询的不同方法,并在每个实验中解决50,000个查询。 我们构建了一个倒排索引,其发布列表分为16个部分,可以在查询时分配给线程。使用Simple 9 [1]作为代表性技术压缩索引,压缩比和解压缩速度之间具有良好的平衡。 所有实验均使用两个四核英特尔(R)Xeon(R)CPU E5620 @ 2.40GHz处理器和96GB RAM进行。 我们使用C ++实现了这些技术,并使用优化选项-O3使用g ++ 4.4.5编译了代码。 在实验中,我们使用主内存中的完整索引执行固定数量的查询(50,000)。在查询解决的同时,在索引中插入可变数量的文档,从50到50,000个文档。我们评估了处理文档插入(直接插入,批量插入和分布式批量插入)的三种技术的性能,并结合4种技术来确定每个查询使用的单位数。我们使用(a)每个查询1个单元(即用一个线程顺序解决每个查询),(b)完美估计器,其中查询时间事先已知,并且之前已用于确定满足条件的最小线程数查询响应时间的上限,(c)WAND查询[7]中提出的多变量线性估计器,它估计我们使用它的顺序查询时间,如完全估计器的情况,以及(d)我们的简单分类器方法训练使用一组与实验中使用的查询不同的查询。 在每种情况下,我们都测量了系统解决所有查询和插入所有文档所需的总时间。 图4,5,6和7显示了每种技术解决插入所花费的总时间,并结合了为查询分配单元的每种方法。图8显示了分布式批量插入的每个单元分配技术的总时间,因为它可以获得最佳结果。这个图省略了每个查询1个单元的情况,因为它没有达到良好的性能。结果表明,通过Simple Classifier结合Distributed Batch Insertion进行多线程处理是最佳选择。 搜索引擎的设计要求是实现高吞吐量,其在先前的图中由完成该组操作所需的总时间表示。 另一个相关的设计要求是各个响应时间低于给定上限时间的查询的百分比。 在下文中,我们评估查询的90Percentile和99-Percentile时间限制值。 也就是说,我们显示最小时间限制值,以确保在比相应绑定值更短的时间内完全处理90%和99%的查询。 如图9和10所示,通过使用每个查询1个单元的方法实现的查询时间限制值远远高于使用替代工作单元分配技术观察到的值。这进一步证明,这种方法虽然易于实施,但并不像其他替代方案那样有效,因此我们将其丢弃。 图11至图16显示简单分类器策略在99-百分位查询约束时间内具有竞争性,其中简单分类器和多线性估计技术之间的差异相当小。然而,当考虑如图8所示的总执行时间时,简单分类器优于多线性估计器,因为它引入查询处理的累积开销要低得多。 CONCLUSIONS 本文重点讨论了在Web搜索引擎的倒排索引中执行更新的同时处理多线程查询的问题。我们已经提出了一种有效的策略来动态地分配线程,以根据它们的特定特征处理各个查询。我们将查询处理分解为多个工作单元,这些工作单元可以由多个线程并行处理。我们设计了一种简单的分类方法来确定每个查询的工作单元数,这种方法足够精确且比其他查询时间估计策略快得多。根据该方案,我们建议在执行实际索引更新并在所有线程之间分发整个插入任务之前,在子索引中预处理文档。总的来说,提出的方法是以两步方式进行,其中(1)通过在查询级别应用并行性使用所有线程处理一批待处理查询,随后(2)处理一组待处理发布列表更新。批量使用并行的所有线程。实验表明,这两步策略对搜索引擎查询吞吐量有积极影响,并确保查询时间的竞争上限。 REFERENCE [1] V. N. Anh and A. Moffat. Inverted index compression using word-aligned binary codes. Inf. Retr., 8(1):151–166, 2005. [2] D. Arroyuelo, S. Gonz´alez, M. Oyarzu´n, and V. Sepulveda. Document identifier reassignment and run-length-compressed inverted indexes for improved search performance. In SIGIR, pages 173–182,...

几个超级好用的UML工具方寸之间

废话不说, 直入主题 draw.io 这个是我一直在用的一个在线UML工具,超级好用。 支持多种导入格式: 添加图片注释,不超过 140 字(可选) 当然还支持导出,如果你想自定义一些导出参数,选择advanced选项进行导出前的配置: 添加图片注释,不超过 140 字(可选) 支持多种存储方式:Google Drive、Onedrive、Dropbox、GitHub、GitLab以及存储到本地。 添加图片注释,不超过 140 字(可选) 支持各种形状,不仅可以画电路图: 添加图片注释,不超过 140 字(可选) 还支持手绘风格的流程图,字体的话,可以通过更换字体格式为Comic Sans MS来实现手写体: 添加图片注释,不超过 140 字(可选) 最最最强大的是,现在还支持导入.VSDX文件来进行编辑,不过导出还有点问题,过一段时间更新了应该就解决这个bug了。 之前只有web版,最近好像又更新出了桌面版,网站一直在推荐,大致看了看介绍,感觉就是把web封装起来了,不过还没用过,不知道体验怎么样,毕竟web版已经满足我的所有需求了:) Excalidraw 这个之前写文章的时候经常用,功能比较简单,只支持简单的导入导出,而且还有一个最大的特点(其实也算缺点)只支持手绘风格,支持中文,但是中文字体不是手绘体,换句话说,就是只支持英文的手写体。 添加图片注释,不超过 140 字(可选) 如果要导入的话,支持.json格式以及.ezcalidraw格式的文件导入,虽然比较少,但是呢,其实使用这个也绘制不了太复杂的图,而且一般用这个也是即画即用、即用即画。即使你想之后再绘制或者更改,使用工具自带的.ezcalidraw这个格式也够用了。支持导出的格式也只支持PNG、SVG,哦,还支持剪切板导出,如果你想,还能加个官方水印。 导出界面 剪切板导出效果 比较惊喜的是,还支持链接共享,不过不知道链接有效期是多久,个人猜测应该是永久有效的吧,毕竟是加密上传到服务器的。 链接分享界面 下面的链接是我测试的用例,有兴趣的童鞋可以点下看看是不是还在: 太臃肿了!!!不适合我这种追求极简生活的人。

Linux挂起和休眠的区别方寸之间

linux的挂起和休眠之间的区别到底是什么? Linux有三种挂起方式:挂起至RAM(通常称为suspend),挂起至磁盘(通常称为hibernate)和混合挂起(hybrid suspend) 挂起至RAM(Suspend,译为睡眠) 该模式通过将系统状态保存在RAM 中使计算机进入睡眠状态。在这种状态下,计算机进入低功耗模式,但是系统仍然需要电源才能将数据保留在RAM中。 需要明确的是,挂起不会关闭计算机。 挂起至磁盘(Hibernate,译为休眠) 该模式将内存的当前内容移入[SWAP]空间。在这种状态下,计算机不需要电源。当你启动计算机时,所有内容都会复制回RAM,然后从上次中断的地方继续。 需要明确的是,计算机已完全关闭了Hibernate的电源。 混合挂起(Hybrid Suspend) 该模式结合了以上两种模式的特点,将计算机的状态保存到交换空间中,但不关闭计算机电源,而是是调用suspend模式。因此,如果电池没有耗尽,则系统可以从RAM恢复。如果电池电量耗尽,则可以从磁盘恢复系统,这比从RAM恢复速度要慢得多,但是计算机的状态并未丢失。 对于ArchLinux,默认的管理接口是systemd,如果你没有安装其他的电源管理软件的话,你需要手动设置才可以正常使用休眠功能。当然,前提是你有设置SWAP分区。

深入理解数据库事务方寸之间

定义 事务(Transaction)在计算机术语中是数据库管理系统执行过程中的一个由一个有限的数据库操作序列构成的逻辑单位。 在数据库中以一致模式完成的任何逻辑计算都称为事务。 性质 数据库事务通常包含了一个序列的对数据库的读/写操作。包含有以下两个目的: 提供可靠的工作单元,可以从故障中正确恢复并保持数据库一致,即使在系统故障的情况下(执行停止(完全或部分)并且对数据库的许多操作仍未完成且状态不明时)。 提供并发访问数据库的程序之间的隔离,以防止彼此的操作互相干扰。如果没有提供这种隔离,程序的结果可能是错误的。 当事务被提交给了数据库管理系统(DBMS),则DBMS需要确保该事务中的所有操作都成功完成且其结果被永久保存在数据库中,如果事务中有的操作没有成功完成,则事务中的所有操作都需要回滚,回到事务执行前的状态;同时,该事务对数据库或者其他事务的执行无影响,所有的事务都好像在独立的运行。  ACID特性 根据定义,数据库事务必须是原子的(它必须是完整的或没有任何影响)、一致的(它必须符合数据库中现有的约束)、隔离的(它不能影响其他事务)和持久的(它必须写入持久存储)。数据库从业者经常使用首字母缩写词 ACID 来指代数据库事务的这些属性。 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束,即系统获得有效的新状态或保持在先前状态。 隔离性(Isolation):处理过程中事务与其他事务分开,一个事务的执行不应影响其他事务的执行。 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中,即使在系统出现故障后系统仍保持有效状态。 示例 张三要在商店购买100元的东西,当中至少包括两个操作: 张三账户减少100元 商店账户增加100元 原子性: 数据库管理系统就要确保以上两个操作(整个“事务”)都能完成,或一起取消;否则就会出现100元平白消失或出现的情况。  一致性: 交易完成,张三账户减少100元,商店账户增加100元 交易失败,张三账户和商店账户不变 隔离性: 如果张三在支付的同时,李四也在支付(是50元),那么即使李四取消支付,只要张三支付成功,商店账户也会增加100元,即不会影响张三的支付。 持久性: 交易完成,二者账户变化生效(写入数据库) 参考

黑科技:使用GitHub搭建自己的短链接服务方寸之间

前两天偶然在GitHub发现一个挺有意思的项目,可以不依赖自己的服务器、数据库来构建一个短链接服务。自己尝试了一下,还挺简单的。这里记录一下自己的构建流程,感兴趣的小伙伴可以自己尝试一下。 Prerequisites 新建两个GitHub仓库,一个用来做服务器存储源码、提供服务(url_shortener),一个用来做数据库存储链接(url_shortener_db) 注册一个域名(可选),如果没有的话,可以直接使用GitHub pages的域名(username.github.io)。不过我是用了自己注册的域名:blog.johan.zone 获取及配置源码 首先,你需要获取这个服务的源代码,你可以直接fork这个源码仓库,当然也欢迎fork我的代码仓库。 然后,克隆自己的仓库到本地(当然,你也可以直接在GitHub网页上操作),修改404.html文件的GITHUB_ISSUES_LINK字段,指向自己的url_shortener_db仓库,这个仓库的issues就是作为存储你的链接的数据库: var GITHUB_ISSUES_LINK =

快速查看github代码库中某次commit的记录方寸之间

如果你想要学习一个开源库,最好的方法就是从头开始看源码,所以你可能想要从第一次commit开始看。有的人可能觉

How to prettify git log output方寸之间

4 formats git log --color --date=format:'%Y-%m-%d %H:%M

博客寄语:

    There are two wolves who are always fighting. One is darkness and despair. The other is light and hope. The question is... which wolf wins?

实时播报:

博客号-学习成长

相信每一分耕耘都有每一分收获,致力帮助博客主所创作的博客能更快的被收录! 如果有其它需求,可联系下方邮箱。