什么是搜索引擎(深入搜索引擎原理)

访客3年前黑客文章502

以前几个工作经验都和检索相关,如今也是有业务流程再用检索,对百度搜索引擎做一个基本原理性的共享,包含检索的一系列关键算法设计和优化算法,尽可能遮盖百度搜索引擎的关键基本原理,但不涉及到大数据挖掘、NLP等。文章内容有点儿长,多多的指导~~

百度搜索引擎是啥?

这儿有一个定义必须提一下。信息搜索 (Information Retrieval 通称 IR) 和 检索 (Search) 是有差别的,信息搜索是一门课程,科学研究信息内容的获得、表明、储存、机构和浏览,而检索仅仅信息搜索的一个支系,别的的如问答网站、信息抽取、信息内容过虑还可以是信息搜索。

文中要讲的百度搜索引擎,是一般实际意义上的全篇百度搜索引擎、竖直百度搜索引擎的广泛基本原理,例如 Google、Baidu,天猫商城检索产品、用户评价检索特色美食、飞猪网检索酒店餐厅等。

Lucene 是十分知名且高效率的全文搜索工具箱,ES 和 Solr 更底层全是应用的 Lucene,文中的绝大多数基本原理和优化算法都是会以 Lucene 来举例说明详细介绍。

看一个具体的事例:怎样从一个亿级数据信息的产品表中,找寻姓名含“秋衣”的 产品。

应用SQL Like

select * from item where name like '%秋衣%'

如上,大伙儿之一能想起的完成是用 like,但这没法应用上数据库索引,会在很多数据上做一次解析xml实际操作,查看会十分的慢。是否有更简易的方式 呢,很有可能要说是否可以使加个秋衣的归类或是标识,非常好,那假如增加一个产品类目怎么办呢?得加无数归类和标识吗?怎样能更简易高效率的解决全文搜索呢?

应用百度搜索引擎

回答是检索,会事前 build 一个全文索引,根据句法语法分析、词性标注、搭建字典、搭建倒排表、缩小提升等实际操作搭建一个数据库索引,查看时根据字典能迅速取得結果。这既能处理全文搜索的难题,又能解决了SQL查看速度比较慢的难题。

那麼, *** 网是怎样在1ms从上亿次产品寻找上千百种秋衣的呢,Google怎样在1ms从万亿个网页页面中找寻到与你关键词配对的几十万个网页页面,这般大的信息量是怎么保证ms回到的。

Part1. 词性标注

词性标注便是对一段文字,根据标准或是优化算法分离出来好几个词,每一个词做为检索的最粗粒度一个个一个字或是英语单词。仅有词性标注后有这个词,检索才可以搜到,词性标注的准确性十分关键。词性标注粒度分布很大,检索均方误差便会稍低,词性标注粒度分布很小,准确度便会减少。怎样恰如其分的词性标注,是百度搜索引擎必须做的之一步。

准确性&粒度分布

词性标注准确性

词性标注的粒度分布

词性标注的粒度分布并并不是越低越好,他会减少准确度,例如检索 “中秋节” 也会发生上条結果,并且粒度分布越小,数据库索引字典越大,检索高效率也会降低,后边会详说。

怎样精确的把控词性标注,牵涉到 NLP 的內容啦,这儿也不进行了。

停用词

许多句子中的词全是没有意义的,例如 “的”,“在” 等介词、谓词,英语中的 “a”,“an”,“the”,在检索是无一切实际意义的,因此在词性标注搭建数据库索引时都是会除去,减少不不要的数据库索引室内空间,叫停用词 (StopWord)。

一般能够根据文本文档集頻率和维护保养停用词表的 *** 来分辨停用词。

词项解决

词项解决,就是指在本来的词项上在做一些附加的解决,例如归一化、词形合并、派生词复原等实际操作,以提升检索的实际效果。并非是全部的要求和业务流程都需要词项解决,必须依据情景来分辨。

1.归一化

USA - U.S.A. [简称]

7月30日 - 7/30 [中英]

color - colour [通假词]

高兴 - 开心 [近义词拓展范围]

那样查看 U.S.A. 也可以获得 USA 的結果,近义词能够算是归一化处理,但是近义词还能够有别的的处理 *** 。

2.词形合并(Lemmatization)

针对英语同一个词有不一样的形状,能够做词形合并成一个,如:

am, are, is -> be

car, cars, car's, cars' -> car

the boy's cars are different colors -> the boy car be different color

3.派生词复原(Stemming)

一般指的就粗略地的除去英语单词两边橙装的研讨式全过程

automate(s), automatic, automation -> automat.

欢欢喜喜 -> 开心 [汉语重叠词复原]

清清楚楚 -> 搞清楚

英语的普遍派生词复原优化算法,Porter优化算法。

要掌握全文索引,先看一下什么叫正排数据库索引。例如有下边几句话:

id1, “百度搜索引擎出示检索服务”

id2, “百度搜索引擎是信息搜索系统软件”

正排数据库索引

正排数据库索引便是 MySQL 里的 B Tree,数据库索引的結果是:

“百度搜索引擎是信息搜索系统软件” -> id2

“百度搜索引擎出示检索服务” -> id1

表明对详细內容按字典序排列,获得一个井然有序的目录,以加速查找的速率。

全文索引

之一步 词性标注

“百度搜索引擎-出示-查找-服务项目” -> id1

“百度搜索引擎-信息内容-查找-系统软件” -> id2

第二步 将词性标注项搭建一个字典

百度搜索引擎

出示

查找

服务项目

信息内容

系统软件

第三步 搭建倒排链

百度搜索引擎 -> id1, id2

出示 -> id1

查找 -> id1, id2

服务项目 -> id1

信息内容 -> id2

系统软件 -> id2

从而,一个全文索引就完成了,检索 “查找” 时,获得 id1, id2,表明这两根数据信息都是有,检索 “服务项目” 仅有 id1 存有。但假如检索 “检索系统”,这时会先建搜索关键词依照与搭建同一种对策词性标注,获得 “查找-系统软件”,2个词项,各自检索 查找 -> id1, id2 和 系统软件 -> id2,随后对其做一个相交,获得 id2。同样,根据求或且能够适用更繁杂的查看。

全文索引到此也就讲明白了吧。

存储结构

以 Lucene 为例子,简易表明一下 Lucene 的存储结构。从大到小是Index -> Segment -> Doc -> Field -> Term,对比 MySQL 为 Database -> Table -> Record -> Field -> Value。

百度搜索排列是依据 关键词 和 Document 的关联性评分排列,一般实际意义下,除开能够人力的设定权重值 boost,也存有一套十分有效的关联性评分优化算法,看了你能感觉十分有趣。

TF-IDF

TF(高频词)-IDF(逆文本文档頻率) 在全自动获取文章内容关键字上常常采用,根据它能够了解某一关键词在这篇文本文档里的关键水平。在其中 TF 表明某一 Term 在 Document 里发生的次数,越高表明越关键;DF 表明在所有 Document 里,共有多少个 Document 发生了这个词,DF 越大,表明这个词很普遍,并不重要,越小反倒表明他越关键,IDF 是 DF 的到数(取log), IDF 越大,表明这个词越关键。

TF-IDF 如何危害检索排列,举一个具体事例来表述:

假设现在有一篇blog《Blink 实战总结》,我们要统计分析本文的关键词,更先是对文章内容词性标注统计分析高频词,发生频次数最多的词是--"的"、"是"、"在",这种是“停用词”,大部分在全部的文章内容里都是会发生,他对寻找結果没什么协助,所有过虑掉。

只考虑到剩余的有现实意义的词,假如文章内容中词频数关联: “Blink” > “高频词”=“小结”,那麼肯定是 Blink 是本文更关键的关键词。但又会碰到了另一个难题,假如发觉 "Blink"、"实战演练"、"小结"这三个词的发生频次一样多。这是否代表着,做为关键字,他们的必要性是一样的?

并不是的,根据统计分析所有blog,你发觉 含关键词总blog数: “Blink”

BM25

上边表述了 TF 和 IDF,那麼 TF 和 IDF 谁更关键呢,怎么计算最后的关联性评分呢?那便是 BM25。

BM25优化算法,一般用于作检索关联性均分。一句话概述其关键观念:对Query开展语素分析,转化成语素qi;随后,针对每一个百度搜索D,测算每一个语素qi与D的关联性评分,最终,将qi相对性于D的关联性评分开展加权求和,进而获得Query与D的关联性评分。

BM25优化算法的一般性公式计算以下:

在其中,Q表明Query,qi表明Q分析以后的一个语素(对汉语来讲,我们可以把对Query的词性标注做为语素剖析,每一个词当做语素qi。);d表明一个百度搜索文档;Wi表明语素qi的权重值;R(qi,d)表明语素qi与文本文档d的关联性评分。

在其中 Wi 一般应用 IDF 来表述,R 应用 TF 来表述;综上所述,BM25优化算法的关联性评分公式计算可小结为:

BM25 根据应用不一样的语素统计分析 *** 、语素权重值判断方式 ,及其语素与文本文档的关联性判断方式 ,我们可以衍化出不一样的检索关联性评分计算方式,这就为大家设计方案优化算法出示了很大的协调能力。

在评价用户评价上,常常有相近的情景,检索 “一公里之内的特色美食”,那麼这一一公里如何完成呢?

在数据库查询中能够根据暴力行为测算、矩形框过虑、及其B树对经纬度和层面建数据库索引,但这特性依然比较慢(可参照 为何必须室内空间数据库索引 )。检索里用了一个很恰当的方式 ,Geo Hash。

如圖,表明依据 GeoHash 对北京市好多个地区转化成的字符串数组,几个特性:

一个字符串数组,意味着一个矩形框地区

字符串数组越长,表明的范畴越精准 (长短为8时精密度在19米长,而当编号长短为9时精密度在两米上下)

字符串数组类似的,表明间距相仿 (这就可以运用字符串数组的作为前缀配对来查看周边的POI信息内容)

地球上一切一个部位都能够用经纬度表示,层面的区段是 [-90, 90],经纬度的区段 [-180, 180]。例如北京天安门广场的座标是 39.908,116.397,总体编号全过程以下:

一、对层面 39.908 的编号以下:

将层面区划两个区段,左区段 [-90, 0) 用 0 表明,右区段 [0, 90] 用 1 表明, 39.908 处于右区段,故之一位编号是 1;

在将 [0, 90] 区划两个区段,左区段 [0, 45) 用 0 表明,右区段 [45, 90] 用 1 表明,39.908处于左区段, 故第二位编号是 0;

同1、2的测算流程,39.908 的最终10位编号是 “10111 00011”

二、对经纬度 116.397 的编号以下:

将经纬度区划两个区段,左区段 [-180, 0) 用 0 表明,右区段 [0, 180] 用 1 表明,116.397处于右区段, 故之一位编号是 1;

在将 [0, 180] 区划两个区段,左区段 [0, 90) 用 0 表明,右区段 [90, 180] 用 1 表明,116.397处于右区段,故第二位编号是 1;

同1、2的测算流程,116.397 的最终6位编号是 “11010 01011”

三、合拼组码

将合数位放经纬度,双数位放层面,把2串编号组成转化成新串:“11100 11101 00100 01111”;

根据 Base32 编号,每五个二进制编码一个数,“28 29 04 15”

依据 Base32 表,获得 Geo Hash 为:“WX4g”

即最终北京天安门广场的4位 Geo Hash 为 “WX4g”,假如必须经纬度更精确,在相匹配的地理坐标编号粒度分布再向下追朔就可以。

附:Base32 编号图

Geo Hash 怎样用以自然地理检索?

举个事例,检索北京天安门广场周边 200 米的旅游景点,以下是北京天安门广场周边的Geo编号

检索全过程以下:

更先明确北京天安门广场的Geo Hash为 WX4g0B,(6位地区码约 0.34均分公里,约为宽度600米地区)

而6位编码表示 600 米,半经 300 米 > 规定的 200 米,检索全部编号为 WX4g0B 的旅游景点就可以

可是因为北京天安门广场处在 WX4g0B 的边沿部位,并不一定处于正管理中心。这就必须将 WX4g0B 周边的八个地区另外列入检索,故检索 WX4g0B、WX4g09、WX4g0C 一共9个编号的旅游景点

第三步早已将范畴变小到不大的一个区段,可是获得的旅游景点间距并并不是精确的,必须在根据间距测算过虑出低于 200 米的旅游景点,获得最后結果。

由上边流程能够看得出,Geo Hash 将本来很多的间距测算,变为一个字符串数组查找变小范畴后,再开展小范畴的间距测算,及迅速又精确的开展间距检索。

Geo Hash 根据的数学原理

如下图所示,大家将二进制编码的結果填好到室内空间中,当将室内空间区划为四块情况下,编号的次序分别是左下方00,左上方01,右下栏10,右上方11,也就是类似Z的曲线图。在我们递归的将每个块转化成更小的子块时,编号的次序是自类似的(分形),每一个子快也产生Z曲线图,这类种类的曲线图被称作Peano室内空间添充曲线图。

这类种类的室内空间添充曲线图的优势是将二维空间转化成一维曲线图(实际上是分形维),对绝大多数来讲,编号类似的间距也相仿, 但Peano室内空间添充曲线图较大 的缺陷便是突变性,有一些编号邻近但间距却相距很远,例如0111与1000,编号是邻近的,但间距相距非常大。

除Peano室内空间添充曲线图外,也有许多室内空间添充曲线图,如下图所示,在其中实际效果认可不错是Hilbert室内空间添充曲线图,相比于Peano曲线图来讲,Hilbert曲线图沒有很大的突然变化。为何GeoHash不挑选Hilbert室内空间添充曲线图呢?可能是Peano曲线图构思及其测算上非常简单吧,实际上,Peano曲线图便是一种四叉树线形编码 *** 。

Lucene的全文索引决策,数据库索引內容是一个可排列的字符串数组,假如要搜索一个数据,那麼也必须将数据转成字符串数组。那样,查找一个数据是没什么问题的,假如必须检索一个标值范畴,怎么做呢?

要做范畴搜索,那麼规定数据转为的字符串数组也是井然有序并简单的,但数据自身的十位数是不一样的,非常简单的版本号便是前缀补0,例如 35, 234, 1 都补成 4 位,获得 0035, 0234, 0001,那样能确保:

数据(a) > 数据(b)===> 字符串数组(a) > 字符串数组(b)

此刻,查看应当用范畴内的全部标值或查看,例如查看 [33, 36) 这一范畴,相匹配的查看英语的语法是:

33 || 34 || 35

嗯看上去非常好的解决了范畴查看,可是,那样存有3个难题:

补位是多少适合呢?总有一个数据会超过你的补位范畴

由于存有补位,便会空出许多的室内空间,这在百度搜索引擎里珍贵的运行内存是没法接纳的

如果是范畴查看,必须用数次或查看,特性并不高

故,牵涉到范畴不可以简易的做字符串数组补位变换,是不是存有及节约室内空间,又能更高效率解决困难的计划方案呢?

便是:

标值Trie树,下边详解

上边讲了如何数据库索引,那麼Query呢?例如我给你一个Range Query从423-642,如何寻找那6个term呢?

大家更先可以用shift==0寻找范畴的起始点后终点站(有可能沒有相同的,例如检索422,也会寻找423)。随后一直往上找,直至寻找一个一同的先祖(毫无疑问能寻找,由于树杆是全部叶子节点的先祖),相匹配起始点,每一次往上升的情况下, 左侧范畴连接点都需要把它右侧的弟兄连接点都加上, 右侧范畴连接点都需要把它左侧的弟兄连接点加上, 若早已抵达端点, 则是将左侧范畴连接点和右侧范畴连接点中间的连接点加开展去

搜索423到642中间的实际的区段:

423-429,640-642

43-49,60-63

5-5

此外还有一个难题,例如423会被词性标注成423,42和4,那麼4也会被词性标注成4,那麼4表明哪一个呢?

因此intToPrefixCoded方式 会附加用一个char来储存shift:buffer[0]=(char)(SHIFT_START_INT shift);

例如423词性标注的4的shift是2(这儿是10进制的事例,二进制也是一样的),423分为423的shift是0,4的shift是0,因而作为前缀毫无疑问比后缀名大。

最终,因为数据库索引在分辨时不用认知是不是数据,能够把全部的数据当做二进制解决,那样在储存和高效率上高些。

L *** 观念

L *** (Log Structured Merge Tree),最开始是Google的 “BigTable” 明确提出来的,总体目标是确保载入特性,另外又能适用较效率高的查找,在许多 NoSQL 上都有应用,Lucene 也是应用 L *** 观念来载入。

一般的B 树提升纪录很有可能必须实行 seek update 实际操作,这必须很多硬盘寻道挪动磁带机。而 L *** 选用纪录在文档结尾,次序载入降低挪动磁带机/寻道,实行高效率高过 B 树。实际 L *** 的基本原理是什么呢?

为了更好地维持硬盘的IO高效率,lucene防止对数据库索引文档的立即改动,全部的数据库索引文档一旦转化成,便是写保护,不可以被更改的。其操作流程以下:

在运行内存中储存增加的数据库索引, 运行内存缓存文件(也就是memtable);

运行内存中的数据库索引总数做到一定阀值时,开启写实际操作,将这些数据信息大批量载入新文档,大家称之为segment;也就是 sstable文档

增加的segment转化成后,不可以被改动;

update实际操作和delete实际操作不容易马上造成 原来的数据信息被改动或是删掉,会以append的 *** 储存update和delete标识;

最后获得很多的 segment,为了更好地降低資源占有,也提升查找高效率,会按时的将这种小的 segment 合拼成大的 segment,因为map中的数据信息全是排好序的,因此合拼也不会有任意写实际操作;

根据merge,还能够把update和delete实际操作真实起效,删掉不必要的数据信息,节约室内空间。

合拼的全过程:

Basic Compaction

每一个文档固定不动N个总数,超出N,则新创建一个sstable;当sstable数超过M,则合拼一个大sstable;当大sstable的总数超过M,则合拼一个更高的sstable文档,依次类推。

可是,这会发生一个难题,便是很多的文档被建立,在最坏的状况下,全部的文档都需要检索。

Levelled Compaction

像 LevelDB 和 Cassandra处理这个问题的方式 是:完成了一个层次的,而不是依据图片大小来实行合拼实际操作。

各层维护保养特定总数的文档,确保不许 key 重合,搜索一个 key 总是搜索一个 key;

每一次文档总是被合拼到上一层的一个文档。当一层的文档数考虑特殊数量时,合拼到上一层。

因此, L *** 是日志和传统式的单文件数据库索引(B tree,Hash Index)的保持中立,他出示一个体制来管理 *** 更小的单独的数据库索引文档(sstable)。

根据管理 *** 一组数据库索引文档而不是单一的数据库索引文档,L *** 将B 树等构造价格昂贵的任意IO变的迅速,而成本便是读实际操作要解决很多的数据库索引文档(sstable)而不是一个,此外還是一些IO被合拼实际操作耗费。

Lucene的Segment设计方案观念,与L *** 相近但又有一些不一样,承继了L *** 中数据载入的优势,可是在查看上只有出示近即时并非实时查询。

Segment在被flush或commit以前,数据信息储存在运行内存中,是不能被检索的,这也就是为何Lucene被称作出示近即时并非实时查询的缘故。读过它的编码后,发觉它并并不是不可以完成数据信息载入就可以查,仅仅完成起來非常复杂。缘故是Lucene中数据检索依靠搭建的数据库索引(比如倒排依靠Term Dictionary),Lucene中对数据信息数据库索引的搭建会在Segment flush时,并非即时搭建,目地是为了更好地搭建更高效率数据库索引。自然它可引进此外一套数据库索引体制,在数据信息即时载入时即搭建,但这套数据库索引完成会与当今Segment内数据库索引不一样,必须引进附加的载入时数据库索引及其此外一套查看体制,有一定复杂性。

数据流图 Term Dictionary,一般要从数据流图寻找特定的词的方式 是,将全部词排列,用二分查找就可以。这类 *** 的算法复杂度是 Log(N),占有室内空间尺寸是 O(N*len(term))。缺陷是耗费运行内存,存有详细的term,当 term 数做到上干万时,占有运行内存十分大。

lucene从8开始很多应用的算法设计是FST(Finite State Transducer)。FST有两个优势:

室内空间占有小,根据读 term 分拆多路复用及前缀和后缀名的器重,缩小了储存空间;

查看速度更快,查看仅有 O(len(term)) 算法复杂度

那麼 FST 算法设计是啥基本原理呢? 先讨论一下什么叫 F *** (Finite State Machine), 有限状态机,从“起止情况”到“停止情况”,可接纳一个字符后,自循环系统或迁移到下一个情况。

而FST呢,便是一种独特的 F *** ,在 Lucene 中用于完成词典搜索作用(NLP中还能够做变换作用),FST 能够表明成FST的方式

举例说明:对“cat”、 “deep”、 “do”、 “dog” 、“dogs” 这五个英语单词搭建FST(注:务必已排列),构造以下:

当存有 value 为相匹配的 docId 时,如 cat/0 deep/1 do/2 dog/3 dogs/4, FST 框架图以下:

FST 还有一个特性,便是在作为前缀公共的基本上,还会继续做一个后缀名公共,总体目标一样是为了更好地缩小储存空间。

在其中鲜红色的斜线表 NEXT-optimized,能够根据 画图工具 来检测。

为了更好地可以迅速搜索docid,lucene选用了SkipList这一算法设计。SkipList有下列好多个特点:

原素排列的,相匹配到大家的倒排链,lucene是依照docid开展排列,由小到大;

弹跳有一个固定不动的间距,这个是必须创建SkipList的情况下特定好,比如下面的图以间距是;

SkipList的层级,这一就是指全部SkipList有多层

在什么位置设定跳表表针?

? 设定较多的表针,较短的步幅, 大量的弹跳机遇

? 大量的表针较为频次和大量的储存空间

? 设定较少的表针,较少的表针较为频次,可是必须设定较长的步幅?较少的持续弹跳

假如倒排表的长短是L,那麼在每过一个步幅S处匀称置放跳表表针。

也叫 Block KD-tree,依据FST构思,假如查询条件十分多,必须对每一个标准依据 FST 查出来結果,开展求或且实际操作。如果是标值种类,那麼潜在性的 Term 很有可能十分多,查看销售量也会很低,为了更好地适用高效率的标值类或是多层次查看,引进 BKD Tree。在一维下便是一棵二叉搜索树,在二维下是假如要查看一个区段,logN的复杂性就可以浏览到叶子节点相匹配的倒排链。

明确分割层面,这儿层面的选择次序是数据信息在这个层面方式 较大 的层面优先选择。一个立即的了解便是,数据信息分散化越开的层面,大家优先选择分割。

分割点的选这一层面最中间的点。

递归开展流程1,2,我们可以设定一个阀值,点的数量低于是多少后就不会再分割,直至全部的点都分割好终止。

二进制解决,根据BKD-Tree搜索到的docID是混乱的,因此要不先转为井然有序的docID二维数组,或是结构BitSet,随后再与别的結果合拼。

IndexSorting

IndexSorting是一种预排列,在ES6.0以后才有,与查看时的Sort不一样,IndexSorting是一种预排列,即数据信息事先依照某类 *** 开展排列,它是Index的一个设定,不能变更。

一个Segment中的每一个文本文档,都是会被分派一个docID,docID从0开始,次序分派。在沒有IndexSorting时,docID是依照文本文档载入的次序开展分派的,在设定了IndexSorting以后,docID的次序就与IndexSorting的次序一致。

举个事例而言,倘若文本文档中有一列入Timestamp,我们在IndexSorting中设定依照Timestamp反序排列,那麼在一个Segment内,docID越小,相匹配的文本文档的Timestamp越大,即依照Timestamp从大到小的次序分派docID。

IndexSorting 往往能够提升特性,是由于能够提早终断及其提升数据编码率,可是他并不可以考虑全部的情景,例如应用非预排列字段名排列,还会继续耗损载入时的特性。

百度搜索引擎恰好是靠出色的基础理论加完美的提升,保证查看特性上的完美,事后会再融合源代码剖析压缩算法怎样保证完美的性能优化的。

来源于:莫然blog,热烈欢迎共享文中!

相关文章

斯莱特通过弯曲的玻璃体积扩展了丹麦的后现代

此延伸部分是由studio形玻璃翼制成的,由丹麦工作室Sleth设计,用于丹麦 南部Tønder 的后现代市政厅。Sleth 赢得了扩展和翻新TønderTownhall的竞赛,该竞赛最初是由丹麦现代...

女生黑色皮衣搭配什么裤子(黑色皮衣搭配哪个

女生黑色皮衣搭配什么裤子(黑色皮衣搭配哪个

皮衣是很帅气的外套,即使在寒冷的冬天也不可缺少呢,帅帅的皮衣下身搭配什么好看?配黑裤子就OK,让你造型更潮更帅。即使在寒冷的冬天,也要扮酷扮帅,那就选皮衣外套穿搭,配黑色裤子,让你冬天一帅到底,同时也...

王牌特工黑客(王牌特工系列)

王牌特工黑客(王牌特工系列)

电影《王牌特工》主要讲了什么? 《王牌特工:源起》讲述了王男的“裁缝店”在其总部创立的过程。费因斯扮演的是牛津公爵,迪金森扮演的是康拉德,这个英俊的、傲慢的公爵,他渴望为自己的服务,而王牌特工则有机会...

甜品店开店步骤,让你赢在起跑线!

甜品店开店步骤,让你赢在起跑线!

如今人人都想开一家眷于本身的甜品店,而作为当下创业越来越受人们的接待,就这样,甜品投资少利润高的这一金钱目就这样深受投资人的喜爱,加上如今人们对付甜品的需求也是越来越高,开一家甜品店长短常有利于存活的...

哪里有查询身边人和别人的聊天记录

  日前,一篇“同性恋公企鹅时隔一年再偷蛋”的报道在互联网上引发热议。管理员称同性恋在企鹅中很常见。报道称蛋也许会在明年顺利孵化。   同性恋公企鹅时隔一年再偷蛋   据媒体报道,它们轮流看守并打...

创业史读后感(重读《创业史》有感)

  创业史读后感(重读《创业史》有感)   □ 吕峻涛   初读《创业史》时,我还是一个不谙世事的中学生。那时因为我们所处地方偏僻闭塞、文百思特网化落后,加之家境贫寒,书籍真是少得可怜。在物质贫乏的年...