实战项目:Boost搜索引擎

目录

  • 1. 项目的相关背景与目标
  • 2.相关宏观原理
  • 3.技术栈和项目环境
  • 4. 正排索引、倒排索引
  • 5. 数据去标签与数据清洗 Parser
    • 5.1下载文件&&准备工作
    • 5.2编写parser解析文档
      • 5.2.1整体架构
      • 5.2.2EnumFile
      • 5.2.3ParseHtml
        • 5.2.3.1框架
        • 5.2.3.2ns_util::FileUtil::ReadFile(); 读取文件
        • 5.2.3.3ParseTitle();提取标签
        • 5.2.3.4ParseContent();获取文档的Content(解析去标签)
        • 5.2.3.5 ParseUrl();
        • 5.2.3.6测试
    • 5.3SaveHtml();将解析结果写入到文件当中
    • 5.4锦上添花
    • 5.5结果
  • 6. 建立索引模块 Index
    • 6.1 index.hpp整体框架
    • 6.2GetForwardIndex();GetInvertedList();BuildIndex()框架
      • 6.2.1BuildForwardIndex();构建正排索引
      • 6.2.2BuildInvertedIndex();构建倒排索引
        • 6.2.2.1思路
        • 6.2.2.2 分词工具 cppjieba 介绍:
        • 6.2.2.3将cppjieba 写入util.hpp中
        • 6.2.2.4问题:暂停词
        • 6.2.2.5编写倒排索引的代码
  • 7.搜索引擎模块 Searcher.hpp
    • 7.1整体框架
    • 7.2将Index设置为单例模式
    • 7.3 InitSearcher();
    • 7.4Search();
      • 7.4.1安装josncpp
      • 7.4.2josncpp测试:
      • 7.4.3Search()编写
      • 7.4.4测试
      • 7.4.5建立摘要
      • 7.4.6GetDesc();
      • 7.4.7问题:
        • 7.4.7.1问题介绍:
        • 7.4.7.2问题测试:
        • 7.4.7.3问题解决
  • 8.http_server模块
    • 8.1准备工作,
      • 8.1.1安装较新版本的gcc
      • 8.1.2安装cpp-httplib
      • 8.1.3测试
    • 8.2代码:
  • 9.前端
  • 10.添加日志log.hpp
    • 10.1代码:
    • 10.2测试:
    • 10.3将程序部署到服务器上
  • 11.整体理解
    • 11.1各个文件简介
    • 整体思路
  • 12.个人遇见问题整理
    • 12.1点击链接自动添加ip和端口号
    • 12.2关于12.1的补充
    • 12.3关于网络端口号

1. 项目的相关背景与目标

针对boost网站没有搜索导航功能,为boost网站文档的查找提供搜索功能

站内搜索:搜索的数据更垂直,数据量小
类似于cplusplus.com的搜索
实战项目:Boost搜索引擎_第1张图片

2.相关宏观原理

实战项目:Boost搜索引擎_第2张图片

3.技术栈和项目环境

技术栈:C/C++,C++11,STL,准标准库Boost(相关文件操作),jsoncpp(客户端和数据端数据交互),cppjieba(将搜索关键字进行切分),cpp-httplib(构建http服务器)
其他技术栈(前端):html5,css,js,jQuery,Ajax
项目环境:Centos 7云服务器,vim/gcc(g++)/Makefile,vs2019/vs code(网页)

4. 正排索引、倒排索引

正排索引:从文档ID找到文档内容(文档内的关键字)
正排索引类似于书的目录,我们可以根据页数查找到对应的内容

目标文档进行分词:目的:方便建立倒排索引和查找
停止词:了,吗,的,the,a,一般情况我们在分词的时候可以不考虑

倒排索引:根据文档内容,分词,整理不重复的各个关键字,对应联系到文档ID的方案
文档ID中,各个文档ID的排序按照权重进行排序
倒排索引和正排索引是相反的概念,我们可以根据文档内容查询到这部分内容在哪些文件中出现,从而找到对应的文件

模拟查找过程
用户输入:
关键字->倒排索引中查找->提取出是文档ID(x,y,z,,,)->根据正排索引->找到文档的内容->将文档内容中的title+conent(desc)+url+文档结果进行摘要->构建响应结果

5. 数据去标签与数据清洗 Parser

5.1下载文件&&准备工作

实战项目:Boost搜索引擎_第3张图片

经过测试:
edge,和360浏览器不能下载,每次的速度都是极慢(不到30KB),
并且在下载到一定时间后,会因为权限不足等情况直接不能下载
所以这个下载只能使用chrome下载,
虽然下载的速度还是很慢,但是不会因为其他问题而导致不能下载

下载好之后,
创建目录
然后将文件拖进Linux中
然后解压
实战项目:Boost搜索引擎_第4张图片
我们只需要boost_1_79_0/doc/html/* 内的所有网址即可:
实战项目:Boost搜索引擎_第5张图片
然后删除boost_1_79_0即可:
实战项目:Boost搜索引擎_第6张图片
我们只需要:boost_1_79_0/doc/html 目录下的html文件,用它来进行建立索引


原始数据->去标签之后的数据
实战项目:Boost搜索引擎_第7张图片

查看一共多少html文件
在这里插入图片描述
目标:
把每个文档都去标签,然后写入到同一个文件中,每个文档内容只占一行!文档和文档之间‘\3’区分。

为什么是\3?
实战项目:Boost搜索引擎_第8张图片

5.2编写parser解析文档

5.2.1整体架构


#include                                                                                                                                                                        
#include    
#include

//目录   
const std::string src_path = "data/input/";
const std::string output = "data/raw_html/raw.txt";

typedef struct DocInfo
{
    std::string title;//文档标题    
    std::string content;//文档内容    
    std::string url;//该文档在官网中的url    
}DocInfo_t;


//格式规范:const &:输入;*:输出;&:输入输出
// 运用boost库进行读取
bool EnumFile(const std::string& src_path, std::vector<std::string>* files_list);
//解析标签, 
bool ParseHtml(const std::vector<std::string>& files_list, std::vector<DocInfo_t>* results);
//保存文件
bool SaveHtml(const std::vector<DocInfo_t>& results, const std::string& output);

int main()
{
    std::vector<std::string> files_list;
    //(1)将每个html文件名带路径保存到file_list中
    if (!EnumFile(src_path, &files_list))
    {
        std::cerr << "枚举文件名失败!" << std::endl;
        return 1;
    }

    //(2)对files_list中的每个文件内容进行解析
    std::vector<DocInfo_t> results;
    if (!ParseHtml(files_list, &results))
    {
        std::cerr << "解析html失败" << std::endl;
        return 2;
    }

    //(3)解析完后,将文件内容写入ouput,用'\3'进行分割
    if (!SaveHtml(results, output))
    {
        std::cerr << "保存文件失败!" << std::endl;
        return 3;
    }
    return 0;
}

实战项目:Boost搜索引擎_第9张图片

5.2.2EnumFile

我们需要使用filesystem函数(boost库中的)

boost库安装

sudo yum install -y boost-devel
//devel是boost开发库

我们用的是1.53,我们搜索的是1.79,这两个不冲突。

boost网页查看函数使用方法:
实战项目:Boost搜索引擎_第10张图片

#include
bool EnumFile(const std::string& src_path, std::vector<std::string>* files_list)
{
    namespace fs = boost::filesystem;
    fs::path root_path(src_path);//遍历时,从这个路径开始    

    //判断路径是否存在     
    if (!(fs::exists(root_path)))
    {
        std::cerr << src_path << "不存在" << std::endl;
        return false;
    }

    //对文件进行递归遍历    
    //定义一个空的迭代器,用来进行判断递归结束    
    fs::recursive_directory_iterator end;
    for (fs::recursive_directory_iterator iter(root_path); iter != end; iter++)
    {
        //判断文件是否为普通文件(html)都是普通文件    
        if (!(fs::is_regular_file(*iter)))  continue;


        //判断文件后缀是否为 .html     
        //path()迭代器的一种方法,用来提取路径的字符串;extension()提取带路径的文件名后缀    
        if (iter->path().extension() != ".html") continue;

        //std::cout<<"插入路径:"<path().string()<

        //当前的路径一定是一个合法的,以.html结束的普通网页文件                                       
        //string()可以将其转化为字符串的形式                                                          
        files_list->push_back(iter->path().string());
    }
    return true;
}

5.2.3ParseHtml

5.2.3.1框架

bool ParseHtml(const std::vector<std::string>& files_list, std::vector<DocInfo_t>* results)
{
	for (const std::string& file : files_list)
	{
		//1.读取文件 Read()    
		std::string result;//读取文件放到这里    
		if (!(ns_util::FileUtil::ReadFile(file, &result))) {
			continue;//读取失败,继续处理下一个文件    
		}

		//2.解析指定文件,提取title    
		DocInfo_t doc;
		//解析title    
		if (!(ParseTitle(result, &doc.title))) {
			continue;//提取报头失败    
		}

		//3.解析指令的文件,提取content(内容)(去标签)    
		if (!(ParseContent(result, &doc.content))) {
			continue;
		}

		//4.解析指定的文件路径,构建url    
		if (!(ParseUrl(file,&doc.url))){
			continue;
		}

		//push_back()本质是拷贝,效率低    
		results->push_back(doc);
	}
	return true;
}

5.2.3.2ns_util::FileUtil::ReadFile(); 读取文件

延伸知识点:
如何理解getline读取到文件结束呢?
getline返回的是一个&,
本质是因为重载了强制类型转化

#include      
#include      
#include      

namespace ns_util
{
    class FileUtil
    {
    public:
        //读取文件      
        static bool ReadFile(const std::string& file_path, std::string* out)
        {
            //只读打开      
            std::ifstream in(file_path, std::ios::in);
            if (!in.is_open())//打开失败      
            {
                std::cerr << "打开失败!" << std::endl;
                return false;
            }

            std::string line;
            while (std::getline(in, line))
            {
                *out += line;
            }
            in.close();
            return true;

        }
    };
}

5.2.3.3ParseTitle();提取标签

static bool ParseTitle(const std::string& file, std::string* title)
{
    std::size_t begin = file.find(""</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>begin <span class="token operator">==</span> std<span class="token double-colon punctuation">::</span>string<span class="token double-colon punctuation">::</span>npos<span class="token punctuation">)</span><span class="token comment">//没有找到    </span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>

    std<span class="token double-colon punctuation">::</span>size_t end <span class="token operator">=</span> file<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">"");
    if (end == std::string::npos)//没有找到    
        return false;

    begin += std::string(""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>begin <span class="token operator">></span> end<span class="token punctuation">)</span><span class="token comment">//判断begin和end位置关系    </span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token operator">*</span>title <span class="token operator">=</span> file<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>begin<span class="token punctuation">,</span> end <span class="token operator">-</span> begin<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h4>5.2.3.4ParseContent();获取文档的Content(解析去标签)</h4> 
  <p>在进行遍历的时候,<br> 只要碰到了 >,就意味着,当前的标签被处理完毕<br> 只要碰到了 <,就意味着,新的标签开始了</p> 
  <pre><code class="prism language-cpp"><span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ParseContent</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> file<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">*</span> content<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token comment">//去标签,基于一个简易的状态机</span>
    <span class="token keyword">enum</span> <span class="token class-name">status</span> <span class="token punctuation">{</span>
        LABLE<span class="token punctuation">,</span>
        CONTEN
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">enum</span> <span class="token class-name">status</span> s <span class="token operator">=</span> LABLE<span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">char</span> c <span class="token operator">:</span> file<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">switch</span> <span class="token punctuation">(</span>s<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
        <span class="token keyword">case</span> LABLE<span class="token operator">:</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token char">'>'</span><span class="token punctuation">)</span> s <span class="token operator">=</span> CONTEN<span class="token punctuation">;</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">case</span> CONTEN<span class="token operator">:</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token char">'<'</span><span class="token punctuation">)</span> s <span class="token operator">=</span> LABLE<span class="token punctuation">;</span>
            <span class="token keyword">else</span>
            <span class="token punctuation">{</span>
                <span class="token comment">//我们不想保留原始文件的'\n',因为我们想用'\n'作为html解析文本之后的分隔符</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>c <span class="token operator">==</span> <span class="token char">'\n'</span><span class="token punctuation">)</span> c <span class="token operator">=</span> <span class="token char">' '</span><span class="token punctuation">;</span>
                content<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>c<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token keyword">default</span><span class="token operator">:</span>
            <span class="token keyword">break</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h4>5.2.3.5 ParseUrl();</h4> 
  <p>构建URL<br> boost库的官方文档,和我们下载下来的文档,是有路径对应关系的</p> 
  <blockquote> 
   <p><strong>官网URL样例</strong>: https /www.boost.org/doc/libs/1_79_0/doc/html/accumulators.html<br> <strong>我们下载下来的url样例</strong>:boost_1_79_0 / doc / html / accumulators.html<br> <strong>我们拷贝到我们项目中的样例</strong>:data / input / accumulators.html<br> <strong>url_head</strong> = “https://www.boost.org/doc/libs/1_79_0/doc/html”;<br> <strong>url_tail</strong> = (data / input)(删除) / accumulators.html->url_tail = / accumulators.html<br> <strong>url = url_head + url_tail</strong>; 相当于形成了一个官网链接</p> 
  </blockquote> 
  <pre><code class="prism language-cpp"><span class="token keyword">static</span> <span class="token keyword">bool</span> <span class="token function">ParseUrl</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> file_path<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">*</span> url<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    std<span class="token double-colon punctuation">::</span>string url_head <span class="token operator">=</span> <span class="token string">"https ://www.boost.org/doc/libs/1_79_0/doc/html"</span><span class="token punctuation">;</span>
    std<span class="token double-colon punctuation">::</span>string url_tail <span class="token operator">=</span> file_path<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>src_path<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token operator">*</span>url <span class="token operator">=</span> url_head <span class="token operator">+</span> url_tail<span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h4>5.2.3.6测试</h4> 
  <pre><code class="prism language-cpp"><span class="token keyword">bool</span> <span class="token function">ParseHtml</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">&</span> files_list<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo_t<span class="token operator">></span><span class="token operator">*</span> results<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> file <span class="token operator">:</span> files_list<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token comment">//1.读取文件 Read()    </span>
		std<span class="token double-colon punctuation">::</span>string result<span class="token punctuation">;</span><span class="token comment">//读取文件放到这里    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">FileUtil</span><span class="token double-colon punctuation">::</span><span class="token function">ReadFile</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span> <span class="token operator">&</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token comment">//读取失败,继续处理下一个文件    </span>
		<span class="token punctuation">}</span>

		<span class="token comment">//2.解析指定文件,提取title    </span>
		DocInfo_t doc<span class="token punctuation">;</span>
		<span class="token comment">//解析title    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseTitle</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token operator">&</span>doc<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token comment">//提取报头失败    </span>
		<span class="token punctuation">}</span>

		<span class="token comment">//3.解析指令的文件,提取content(内容)(去标签)    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseContent</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token operator">&</span>doc<span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//4.解析指定的文件路径,构建url    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseUrl</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token operator">&</span>doc<span class="token punctuation">.</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//push_back()本质是拷贝,效率低    </span>
		results<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//测试</span>
        std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"title:"</span> <span class="token operator"><<</span> doc<span class="token punctuation">.</span>title <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"content:"</span> <span class="token operator"><<</span> doc<span class="token punctuation">.</span>content <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"url:"</span> <span class="token operator"><<</span> doc<span class="token punctuation">.</span>url <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        <span class="token keyword">break</span><span class="token punctuation">;</span><span class="token comment">//打印一份就行</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/35ac07109ac74ec6bce17b3d84adfe61.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/35ac07109ac74ec6bce17b3d84adfe61.jpg" alt="实战项目:Boost搜索引擎_第11张图片" width="650" height="345" style="border:1px solid black;"></a></p> 
  <h2>5.3SaveHtml();将解析结果写入到文件当中</h2> 
  <p>目标:将results,写入到output中 <br> 采用方案:</p> 
  <pre><code class="prism language-cpp">title\<span class="token number">3</span>content\<span class="token number">3u</span>rl \n title\<span class="token number">3</span>content\<span class="token number">3u</span>rl \n title\<span class="token number">3</span>content\<span class="token number">3u</span>rl \n <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
</code></pre> 
  <pre><code class="prism language-cpp"><span class="token comment">//保存文件</span>
<span class="token comment">//将results写入到output中    </span>
<span class="token keyword">bool</span> <span class="token function">SaveHtml</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo_t<span class="token operator">></span><span class="token operator">&</span> results<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> output<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">SEP</span> <span class="token char">'\3'</span>    </span>
    <span class="token comment">//将output对应的文件打开    </span>
    <span class="token comment">//按照二进制方式写入    </span>
    std<span class="token double-colon punctuation">::</span>ofstream <span class="token function">out</span><span class="token punctuation">(</span>output<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>out <span class="token operator">|</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>binary<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>out<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        std<span class="token double-colon punctuation">::</span>cerr <span class="token operator"><<</span> <span class="token string">"打开"</span> <span class="token operator"><<</span> <span class="token string">"output"</span> <span class="token operator"><<</span> <span class="token string">"失败"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">//文件内容写入    </span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span><span class="token operator">&</span> item <span class="token operator">:</span> results<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        std<span class="token double-colon punctuation">::</span>string out_string<span class="token punctuation">;</span>
        out_string <span class="token operator">=</span> item<span class="token punctuation">.</span>title<span class="token punctuation">;</span>
        out_string <span class="token operator">+=</span> SEP<span class="token punctuation">;</span>
        out_string <span class="token operator">+=</span> item<span class="token punctuation">.</span>content<span class="token punctuation">;</span>
        out_string <span class="token operator">+=</span> SEP<span class="token punctuation">;</span>
        out_string <span class="token operator">+=</span> item<span class="token punctuation">.</span>url<span class="token punctuation">;</span>
        out_string <span class="token operator">+=</span> <span class="token char">'\n'</span><span class="token punctuation">;</span>

        out<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>out_string<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> out_string<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    out<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h2>5.4锦上添花</h2> 
  <pre><code class="prism language-cpp">```cpp
<span class="token keyword">bool</span> <span class="token function">ParseHtml</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">&</span> files_list<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo_t<span class="token operator">></span><span class="token operator">*</span> results<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> file <span class="token operator">:</span> files_list<span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		<span class="token comment">//1.读取文件 Read()    </span>
		std<span class="token double-colon punctuation">::</span>string result<span class="token punctuation">;</span><span class="token comment">//读取文件放到这里    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">FileUtil</span><span class="token double-colon punctuation">::</span><span class="token function">ReadFile</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span> <span class="token operator">&</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token comment">//读取失败,继续处理下一个文件    </span>
		<span class="token punctuation">}</span>

		<span class="token comment">//2.解析指定文件,提取title    </span>
		DocInfo_t doc<span class="token punctuation">;</span>
		<span class="token comment">//解析title    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseTitle</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token operator">&</span>doc<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span><span class="token comment">//提取报头失败    </span>
		<span class="token punctuation">}</span>

		<span class="token comment">//3.解析指令的文件,提取content(内容)(去标签)    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseContent</span><span class="token punctuation">(</span>result<span class="token punctuation">,</span> <span class="token operator">&</span>doc<span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//4.解析指定的文件路径,构建url    </span>
		<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span><span class="token function">ParseUrl</span><span class="token punctuation">(</span>file<span class="token punctuation">,</span><span class="token operator">&</span>doc<span class="token punctuation">.</span>url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
			<span class="token keyword">continue</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//push_back()本质是拷贝,效率低    </span>
		results<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>每次循环之后,我们都要push_back(doc),其本质是拷贝,效率低下,影响性能</p> 
  <p>move:作为右值移动<br> 将我们所要拷贝的对象,在地址空间层面上,让我们对象直接和容器当中的成员相关联,也就是说不会发生太多的拷贝</p> 
  <pre><code class="prism language-cpp">
<span class="token comment">//push_back()本质是拷贝,效率低     </span>
<span class="token comment">//results->push_back(doc);      </span>
results<span class="token operator">-></span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> 
  <h2>5.5结果</h2> 
  <p>温馨提醒:<br> 记得把 5.2.3.6 中的测试代码删除</p> 
  <p><a href="http://img.e-com-net.com/image/info8/7ecec8b6516a4135a40d92a689a937e5.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/7ecec8b6516a4135a40d92a689a937e5.jpg" alt="实战项目:Boost搜索引擎_第12张图片" width="650" height="251" style="border:1px solid black;"></a></p> 
  <pre><code class="prism language-cpp">vim raw<span class="token punctuation">.</span>txt
</code></pre> 
  <blockquote> 
   <p><a href="http://img.e-com-net.com/image/info8/f43684f519c1454e8233ad18e858274a.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/f43684f519c1454e8233ad18e858274a.jpg" alt="在这里插入图片描述" width="650" height="76"></a><a href="http://img.e-com-net.com/image/info8/504539f470ea4f2b99ec0d76b73b2ec2.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/504539f470ea4f2b99ec0d76b73b2ec2.jpg" alt="实战项目:Boost搜索引擎_第13张图片" width="650" height="312" style="border:1px solid black;"></a><br> <a href="http://img.e-com-net.com/image/info8/4e6053b947a44ce79d02113c4132649b.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/4e6053b947a44ce79d02113c4132649b.jpg" alt="实战项目:Boost搜索引擎_第14张图片" width="650" height="372" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <h1>6. 建立索引模块 Index</h1> 
  <h2>6.1 index.hpp整体框架</h2> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">once</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><iostream></span>    </span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><string></span>    </span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><vector></span>    </span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><unordered_map></span>    </span>

<span class="token keyword">namespace</span> ns_index
<span class="token punctuation">{</span>
	<span class="token comment">//文档    </span>
	<span class="token keyword">struct</span> <span class="token class-name">DocInfo</span>
	<span class="token punctuation">{</span>
		std<span class="token double-colon punctuation">::</span>string title<span class="token punctuation">;</span>
		std<span class="token double-colon punctuation">::</span>string content<span class="token punctuation">;</span>
		std<span class="token double-colon punctuation">::</span>string url<span class="token punctuation">;</span>
		<span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">;</span> <span class="token comment">// 文档id    </span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span>

	<span class="token comment">//倒排对应的节点    </span>
	<span class="token keyword">struct</span> <span class="token class-name">InvertedElem</span>
	<span class="token punctuation">{</span>
		std<span class="token double-colon punctuation">::</span>string word<span class="token punctuation">;</span><span class="token comment">//关键字    </span>
		<span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">;</span><span class="token comment">//文档id    </span>
		<span class="token keyword">int</span> weight<span class="token punctuation">;</span><span class="token comment">//权重    </span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span>

	<span class="token comment">//倒排拉链    </span>
	<span class="token keyword">typedef</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>InvertedElem<span class="token operator">></span> InvertedList<span class="token punctuation">;</span>

	<span class="token keyword">class</span> <span class="token class-name">Index</span>
	<span class="token punctuation">{</span>
	<span class="token keyword">private</span><span class="token operator">:</span>
		<span class="token comment">//使用数组原因:数组下标可以当作文档id    </span>
		std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>DocInfo<span class="token operator">></span> for_ward_index<span class="token punctuation">;</span><span class="token comment">//正排索引 </span>

	 	<span class="token comment">//倒排索引:关键字与文档id = 1:n</span>
		std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span> InvertedList<span class="token operator">></span> inverted_index<span class="token punctuation">;</span>

	<span class="token keyword">public</span><span class="token operator">:</span>
		<span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
		<span class="token operator">~</span><span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

		<span class="token comment">//doc_id找到文档内容</span>
		DocInfo<span class="token operator">*</span> <span class="token function">GetForwardIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">)</span> <span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//关键字查找倒排拉链</span>
		InvertedList<span class="token operator">*</span> <span class="token function">GetInvertedList</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> word<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//构建索引:整理raw.txt</span>
		<span class="token keyword">bool</span> <span class="token function">BuildIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> input<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
	<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h2>6.2GetForwardIndex();GetInvertedList();BuildIndex()框架</h2> 
  <pre><code class="prism language-cpp">		DocInfo<span class="token operator">*</span> <span class="token function">GetForwardIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">if</span> <span class="token punctuation">(</span>doc_id <span class="token operator">>=</span> for_ward_index<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
			<span class="token punctuation">{</span>
				std<span class="token double-colon punctuation">::</span>cerr <span class="token operator"><<</span> <span class="token string">"索引id 越界"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
				<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
			<span class="token punctuation">}</span>
			<span class="token keyword">return</span> <span class="token operator">&</span>for_ward_index<span class="token punctuation">[</span>doc_id<span class="token punctuation">]</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token comment">//关键字查找倒排拉链</span>
		InvertedList<span class="token operator">*</span> <span class="token function">GetInvertedList</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> word<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">auto</span> iter <span class="token operator">=</span> inverted_index<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">if</span> <span class="token punctuation">(</span>iter <span class="token operator">==</span> inverted_index<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
			<span class="token punctuation">{</span>
				std<span class="token double-colon punctuation">::</span>cerr <span class="token operator"><<</span> <span class="token string">"没有找到【"</span> <span class="token operator"><<</span> word <span class="token operator"><<</span> <span class="token string">"】对应的倒排拉链"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
				<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
			<span class="token punctuation">}</span>
			<span class="token keyword">return</span> <span class="token operator">&</span><span class="token punctuation">(</span>iter<span class="token operator">-></span>second<span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>


		<span class="token comment">//构建索引:整理data/raw_html/raw.txt</span>
		<span class="token keyword">bool</span> <span class="token function">BuildIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> input<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			std<span class="token double-colon punctuation">::</span>ifstream <span class="token function">in</span><span class="token punctuation">(</span>input<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>in <span class="token operator">|</span> std<span class="token double-colon punctuation">::</span>ios<span class="token double-colon punctuation">::</span>binary<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>in<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
			<span class="token punctuation">{</span>
				std<span class="token double-colon punctuation">::</span>cerr <span class="token operator"><<</span> <span class="token string">"给定路径【"</span> <span class="token operator"><<</span> input <span class="token operator"><<</span> <span class="token string">"】不能打开!"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
				<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
			<span class="token punctuation">}</span>

			std<span class="token double-colon punctuation">::</span>string line<span class="token punctuation">;</span>
			<span class="token keyword">while</span> <span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">getline</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span> line<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">//按行读取内容</span>
			<span class="token punctuation">{</span>
				<span class="token comment">//构建正排索引</span>
				DocInfo<span class="token operator">*</span> doc <span class="token operator">=</span> <span class="token function">BuildForwardIndex</span><span class="token punctuation">(</span>line<span class="token punctuation">)</span><span class="token punctuation">;</span>
				<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> doc<span class="token punctuation">)</span>
				<span class="token punctuation">{</span>
					std<span class="token double-colon punctuation">::</span>cerr <span class="token operator"><<</span> <span class="token string">"构建【"</span> <span class="token operator"><<</span> line <span class="token operator"><<</span> <span class="token string">"】失败!"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
					<span class="token keyword">continue</span><span class="token punctuation">;</span>
				<span class="token punctuation">}</span>

				<span class="token comment">//构建倒排索引</span>
				<span class="token function">BuildInvertedIndex</span><span class="token punctuation">(</span><span class="token operator">*</span>doc<span class="token punctuation">)</span><span class="token punctuation">;</span>

			<span class="token punctuation">}</span>
			<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
	<span class="token keyword">private</span><span class="token operator">:</span>
		DocInfo<span class="token operator">*</span> <span class="token function">BuildForwardIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> line<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token keyword">bool</span> <span class="token function">BuildInvertedIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> DocInfo<span class="token operator">&</span> doc<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
</code></pre> 
  <h3>6.2.1BuildForwardIndex();构建正排索引</h3> 
  <pre><code class="prism language-cpp">		DocInfo<span class="token operator">*</span> <span class="token function">BuildForwardIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> line<span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			<span class="token comment">//1.解析line,对齐字符串按照"\3"切分</span>
			std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> result<span class="token punctuation">;</span>
			<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string sep <span class="token operator">=</span> <span class="token string">"\3"</span><span class="token punctuation">;</span><span class="token comment">//分隔符</span>
			ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">StringUtil</span><span class="token double-colon punctuation">::</span><span class="token function">Split</span><span class="token punctuation">(</span>line<span class="token punctuation">,</span> <span class="token operator">&</span>result<span class="token punctuation">,</span> sep<span class="token punctuation">)</span><span class="token punctuation">;</span>
			<span class="token keyword">if</span> <span class="token punctuation">(</span>result<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token comment">//切分字符串出错!</span>
			<span class="token punctuation">{</span>
				<span class="token keyword">return</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
			<span class="token punctuation">}</span>

			<span class="token comment">//2.字符串填充DocInfo</span>
			DocInfo doc<span class="token punctuation">;</span>
			doc<span class="token punctuation">.</span>title <span class="token operator">=</span> result<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
			doc<span class="token punctuation">.</span>content <span class="token operator">=</span> result<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
			doc<span class="token punctuation">.</span>url <span class="token operator">=</span> result<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
			doc<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> for_ward_index<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

			<span class="token comment">//3.插入到正排索引的vector中</span>
			for_ward_index<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>doc<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

			<span class="token keyword">return</span> <span class="token operator">&</span>for_ward_index<span class="token punctuation">.</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
</code></pre> 
  <p>util.hpp</p> 
  <pre><code class="prism language-cpp">    <span class="token keyword">class</span> <span class="token class-name">StringUtil</span>
    <span class="token punctuation">{</span>
    <span class="token keyword">public</span><span class="token operator">:</span>
        <span class="token comment">//target:切分目标;out:目的地;sep:分隔符</span>
        <span class="token comment">//这个方法需要被外部直接使用,所以要加static</span>
        <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> target<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">*</span> out<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string sep<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//boost/split:切分字符串</span>
            <span class="token comment">//out目的地;target:切分目标;boost::is_any_of("分隔符");boost::token_compress_on:切分是否间隔</span>
            boost<span class="token double-colon punctuation">::</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token operator">*</span>out<span class="token punctuation">,</span> target<span class="token punctuation">,</span> boost<span class="token double-colon punctuation">::</span><span class="token function">is_any_of</span><span class="token punctuation">(</span>sep<span class="token punctuation">)</span><span class="token punctuation">,</span> boost<span class="token double-colon punctuation">::</span>token_compress_on<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> 
  <h3>6.2.2BuildInvertedIndex();构建倒排索引</h3> 
  <h4>6.2.2.1思路</h4> 
  <p><a href="http://img.e-com-net.com/image/info8/3a30ce9dacbb4cae82b76e7404e700dd.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3a30ce9dacbb4cae82b76e7404e700dd.jpg" alt="实战项目:Boost搜索引擎_第15张图片" width="650" height="284" style="border:1px solid black;"></a></p> 
  <h4>6.2.2.2 分词工具 cppjieba 介绍:</h4> 
  <blockquote> 
   <p>cppjieba的使用方法路径:<br> <a href="http://img.e-com-net.com/image/info8/c01ffc94f28e4b5c9049ea7d0200b90d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/c01ffc94f28e4b5c9049ea7d0200b90d.jpg" alt="实战项目:Boost搜索引擎_第16张图片" width="603" height="106" style="border:1px solid black;"></a><br> <a href="http://img.e-com-net.com/image/info8/cb8fc1011f5340728387ac5665c57970.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/cb8fc1011f5340728387ac5665c57970.jpg" alt="" width="548" height="87"></a><br> 我们将放到cppjieba的同一目录下进行测试:</p> 
  </blockquote> 
  <blockquote> 
   <p>准备:<br> <a href="http://img.e-com-net.com/image/info8/e2076ded3aca4ebab0c1abb1643324c6.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/e2076ded3aca4ebab0c1abb1643324c6.jpg" alt="实战项目:Boost搜索引擎_第17张图片" width="650" height="550" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <blockquote> 
   <p>开始测试:<br> <a href="http://img.e-com-net.com/image/info8/5075a2e9b68a4cb1a3e283fd6fec0178.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/5075a2e9b68a4cb1a3e283fd6fec0178.jpg" alt="实战项目:Boost搜索引擎_第18张图片" width="650" height="276" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <blockquote> 
   <p>需要部分:<br> <a href="http://img.e-com-net.com/image/info8/10b1b40eee6745e681c29bee73f1b5f1.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/10b1b40eee6745e681c29bee73f1b5f1.jpg" alt="实战项目:Boost搜索引擎_第19张图片" width="650" height="538" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <h4>6.2.2.3将cppjieba 写入util.hpp中</h4> 
  <blockquote> 
   <p>准备工作:<br> <a href="http://img.e-com-net.com/image/info8/163dd8447c5540e698accafa2e585d0d.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/163dd8447c5540e698accafa2e585d0d.jpg" alt="实战项目:Boost搜索引擎_第20张图片" width="650" height="166" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><test/cppjieba/include/cppjieba/Jieba.hpp></span><span class="token comment">//注意位置</span></span>

<span class="token comment">//下面代码在ns_util中</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/jieba.dict.utf8"</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> HMM_PATH <span class="token operator">=</span> <span class="token string">"./dict/hmm_model.utf8"</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> USER_DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/user.dict.utf8"</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> IDF_PATH <span class="token operator">=</span> <span class="token string">"./dict/idf.utf8"</span><span class="token punctuation">;</span>
    <span class="token keyword">const</span> <span class="token keyword">char</span><span class="token operator">*</span> <span class="token keyword">const</span> STOP_WORD_PATH <span class="token operator">=</span> <span class="token string">"./dict/stop_words.utf8"</span><span class="token punctuation">;</span>
    <span class="token keyword">class</span> <span class="token class-name">JiebaUtil</span>
    <span class="token punctuation">{</span>
    <span class="token keyword">private</span><span class="token operator">:</span>
        <span class="token keyword">static</span> cppjieba<span class="token double-colon punctuation">::</span>Jieba jieba<span class="token punctuation">;</span>

    <span class="token keyword">public</span><span class="token operator">:</span>
        <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string<span class="token operator">&</span> src<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span><span class="token operator">*</span> out<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            jieba<span class="token punctuation">.</span><span class="token function">CutForSearch</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span> <span class="token operator">*</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token comment">//静态成员变量的初始化需要在类外面进行</span>
    <span class="token keyword">static</span> cppjieba<span class="token double-colon punctuation">::</span>Jieba <span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">jieba</span><span class="token punctuation">(</span>DICT_PATH<span class="token punctuation">,</span> HMM_PATH<span class="token punctuation">,</span> USER_DICT_PATH<span class="token punctuation">,</span> IDF_PATH<span class="token punctuation">,</span> STOP_WORD_PATH<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> 
  <h4>6.2.2.4问题:暂停词</h4> 
  <p>这个问题建议最后解决,此时可以忽略这块的问题<br> 原因:<br> 1.这里相当于只是优化,不影响整体效果<br> 2.如果这里修改了,那么以后的测试中,将会非常的慢,浪费时间</p> 
  <p>在进行分词的过程中,“暂停词”也会被建立倒排索引,,,<br> util.hpp</p> 
  <pre><code class="prism language-cpp">
  <span class="token keyword">class</span> <span class="token class-name">StringUtil</span>
  <span class="token punctuation">{</span>
  <span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token comment">// target:切分目标;out:目的地;sep:分隔符</span>
    <span class="token comment">//这个方法需要被外部直接使用,所以要加static</span>
    <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>target<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>out<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string sep<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      <span class="token comment">// boost/split:切分字符串</span>
      <span class="token comment">// out:结果;target:切分目标;boost::is_any_of('分隔符');boost::token_compress_on:切分是否间隔</span>
      boost<span class="token double-colon punctuation">::</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token operator">*</span>out<span class="token punctuation">,</span> target<span class="token punctuation">,</span> boost<span class="token double-colon punctuation">::</span><span class="token function">is_any_of</span><span class="token punctuation">(</span>sep<span class="token punctuation">)</span><span class="token punctuation">,</span> boost<span class="token double-colon punctuation">::</span>token_compress_on<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token keyword">const</span> DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/jieba.dict.utf8"</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token keyword">const</span> HMM_PATH <span class="token operator">=</span> <span class="token string">"./dict/hmm_model.utf8"</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token keyword">const</span> USER_DICT_PATH <span class="token operator">=</span> <span class="token string">"./dict/user.dict.utf8"</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token keyword">const</span> IDF_PATH <span class="token operator">=</span> <span class="token string">"./dict/idf.utf8"</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token keyword">const</span> STOP_WORD_PATH <span class="token operator">=</span> <span class="token string">"./dict/stop_words.utf8"</span><span class="token punctuation">;</span>
  <span class="token keyword">class</span> <span class="token class-name">JiebaUtil</span>
  <span class="token punctuation">{</span>
  <span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token comment">//static cppjieba::Jieba jieba;</span>
    cppjieba<span class="token double-colon punctuation">::</span>Jieba jieba<span class="token punctuation">;</span>
    
    <span class="token comment">//暂停词</span>
    std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span><span class="token keyword">bool</span><span class="token operator">></span> stop_words<span class="token punctuation">;</span>
    
    <span class="token comment">//设置成为单例模式</span>
    <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
      <span class="token operator">:</span><span class="token function">jieba</span><span class="token punctuation">(</span>DICT_PATH<span class="token punctuation">,</span>HMM_PATH<span class="token punctuation">,</span>USER_DICT_PATH<span class="token punctuation">,</span>IDF_PATH<span class="token punctuation">,</span>STOP_WORD_PATH<span class="token punctuation">)</span>
    <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token keyword">const</span> JiebaUtil<span class="token operator">&</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">delete</span><span class="token punctuation">;</span>
    <span class="token keyword">static</span> JiebaUtil <span class="token operator">*</span>instance<span class="token punctuation">;</span>
  <span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token keyword">static</span> JiebaUtil<span class="token operator">*</span> <span class="token function">get_instance</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>mutex mtx<span class="token punctuation">;</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> instance<span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        mtx<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span><span class="token operator">==</span>instance<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
          instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">JiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          instance<span class="token operator">-></span><span class="token function">InitJiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        mtx<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      <span class="token keyword">return</span> instance<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">void</span> <span class="token function">InitJiebaUtil</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      std<span class="token double-colon punctuation">::</span>ifstream <span class="token function">in</span><span class="token punctuation">(</span>STOP_WORD_PATH<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>in<span class="token punctuation">.</span><span class="token function">is_open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        <span class="token function">LOG</span><span class="token punctuation">(</span>FATAL<span class="token punctuation">,</span><span class="token string">"加载失败!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>

      std<span class="token double-colon punctuation">::</span>string line<span class="token punctuation">;</span>
      <span class="token keyword">while</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">getline</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span>line<span class="token punctuation">)</span><span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        stop_words<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token punctuation">{</span>line<span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      in<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">void</span> <span class="token function">CutstringHelper</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span> src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>out<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      jieba<span class="token punctuation">.</span><span class="token function">CutForSearch</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span><span class="token operator">*</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> iter <span class="token operator">=</span> out<span class="token operator">-></span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>iter<span class="token operator">!=</span>out<span class="token operator">-></span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        <span class="token keyword">auto</span> it <span class="token operator">=</span> stop_words<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token operator">*</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>it<span class="token operator">!=</span>stop_words<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
          <span class="token comment">//当前的词是暂停词,</span>
          iter <span class="token operator">=</span> out<span class="token operator">-></span><span class="token function">erase</span><span class="token punctuation">(</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">else</span>
        <span class="token punctuation">{</span>
          iter<span class="token operator">++</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
      <span class="token punctuation">}</span>

    <span class="token punctuation">}</span>
    <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">CutString</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span> src<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> <span class="token operator">*</span>out<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      <span class="token comment">//jieba.CutForSearch(src,*out);</span>
      ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">get_instance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">CutstringHelper</span><span class="token punctuation">(</span>src<span class="token punctuation">,</span>out<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token comment">//静态成员变量的初始化需要在类外面进行</span>
  <span class="token comment">//cppjieba::Jieba JiebaUtil::jieba(DICT_PATH,HMM_PATH,USER_DICT_PATH,IDF_PATH,STOP_WORD_PATH);</span>
  JiebaUtil <span class="token operator">*</span>JiebaUtil<span class="token double-colon punctuation">::</span>instance <span class="token operator">=</span><span class="token keyword">nullptr</span><span class="token punctuation">;</span>
</code></pre> 
  <p>testtest/index.html</p> 
  <pre><code class="prism language-cpp">function <span class="token function">Search</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token comment">// 是浏览器的一个弹出框</span>
            <span class="token comment">// alert("hello js!");</span>
            <span class="token comment">// 1. 提取数据, $可以理解成就是JQuery的别称</span>
            let query <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">".container .search input"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>query<span class="token operator">==</span><span class="token char">''</span> <span class="token operator">||</span> query<span class="token operator">==</span>null<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"query = "</span> <span class="token operator">+</span> query<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//console是浏览器的对话框,可以用来进行查看js数据</span>

            <span class="token comment">//2. 发起http请求,ajax: 属于一个和后端进行数据交互的函数,JQuery中的</span>
            $<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
                type<span class="token operator">:</span> <span class="token string">"GET"</span><span class="token punctuation">,</span>
                url<span class="token operator">:</span> <span class="token string">"/s?word="</span> <span class="token operator">+</span> query<span class="token punctuation">,</span>
                success<span class="token operator">:</span> <span class="token function">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">{</span>
                    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">BuildHtml</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        function <span class="token function">BuildHtml</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>data<span class="token operator">==</span><span class="token char">''</span> <span class="token operator">||</span> data <span class="token operator">==</span>null<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                document<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span><span class="token string">"搜索的内容没有、或搜索的内容是暂停词!"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">return</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
</code></pre> 
  <h4>6.2.2.5编写倒排索引的代码</h4> 
  <pre><code class="prism language-cpp">    <span class="token keyword">bool</span> <span class="token function">BuildInvertedIndex</span><span class="token punctuation">(</span><span class="token keyword">const</span> DocInfo <span class="token operator">&</span>doc<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      <span class="token comment">//字符串->倒排拉链</span>
      <span class="token keyword">struct</span> <span class="token class-name">word_cnt</span>
      <span class="token punctuation">{</span>
        <span class="token keyword">int</span> title_cnt<span class="token punctuation">;</span>
        <span class="token keyword">int</span> content_cnt<span class="token punctuation">;</span>

        <span class="token function">word_cnt</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span><span class="token function">title_cnt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">,</span><span class="token function">content_cnt</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span><span class="token punctuation">}</span>
      <span class="token punctuation">}</span><span class="token punctuation">;</span>

      <span class="token comment">//umpword_cnt 用来暂时存储词频</span>
      std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token punctuation">,</span>word_cnt<span class="token operator">></span> umpword_cnt<span class="token punctuation">;</span>
      
      <span class="token comment">//标题分词</span>
      std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> title_words<span class="token punctuation">;</span>
      ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">CutString</span><span class="token punctuation">(</span>doc<span class="token punctuation">.</span>title<span class="token punctuation">,</span><span class="token operator">&</span>title_words<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token comment">//标题词频统计</span>
      <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> s<span class="token operator">:</span>title_words<span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        boost<span class="token double-colon punctuation">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将s里面的字母全部转为小写</span>
        umpword_cnt<span class="token punctuation">[</span>s<span class="token punctuation">]</span><span class="token punctuation">.</span>title_cnt<span class="token operator">++</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>

      <span class="token comment">//内容分词</span>
      std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> content_words<span class="token punctuation">;</span>
      ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">CutString</span><span class="token punctuation">(</span>doc<span class="token punctuation">.</span>content<span class="token punctuation">,</span><span class="token operator">&</span>content_words<span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token comment">//内容词频统计</span>
      <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> s<span class="token operator">:</span>content_words<span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        boost<span class="token double-colon punctuation">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span>
        umpword_cnt<span class="token punctuation">[</span>s<span class="token punctuation">]</span><span class="token punctuation">.</span>content_cnt<span class="token operator">++</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>

      <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>word_pair<span class="token operator">:</span>umpword_cnt<span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        InvertedElem item<span class="token punctuation">;</span>
        item<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> doc<span class="token punctuation">.</span>doc_id<span class="token punctuation">;</span>
        item<span class="token punctuation">.</span>word <span class="token operator">=</span> word_pair<span class="token punctuation">.</span>first<span class="token punctuation">;</span>
        item<span class="token punctuation">.</span>weight <span class="token operator">=</span> word_pair<span class="token punctuation">.</span>second<span class="token punctuation">.</span>title_cnt<span class="token operator">*</span><span class="token number">10</span><span class="token operator">+</span>word_pair<span class="token punctuation">.</span>second<span class="token punctuation">.</span>content_cnt<span class="token operator">*</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token comment">//权重:10:1</span>

        <span class="token comment">//<字符串,数组>,,,,插入数组元素</span>
        InvertedList <span class="token operator">&</span>Inverted_List <span class="token operator">=</span> inverted_index<span class="token punctuation">[</span>word_pair<span class="token punctuation">.</span>first<span class="token punctuation">]</span><span class="token punctuation">;</span>
        Inverted_List<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
</code></pre> 
  <h1>7.搜索引擎模块 Searcher.hpp</h1> 
  <h2>7.1整体框架</h2> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">once</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">"index.hpp"</span></span>

<span class="token keyword">namespace</span> ns_searcher
<span class="token punctuation">{</span>
    <span class="token keyword">class</span> <span class="token class-name">Searcher</span>
    <span class="token punctuation">{</span>
    <span class="token keyword">private</span><span class="token operator">:</span>
        ns_index<span class="token double-colon punctuation">::</span>Index <span class="token operator">*</span>index<span class="token punctuation">;</span><span class="token comment">//系统查找的索引</span>

    <span class="token keyword">public</span><span class="token operator">:</span>
        <span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
        <span class="token operator">~</span><span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>

        <span class="token comment">//初始化</span>
        <span class="token keyword">void</span> <span class="token function">InitSearcher</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>input<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//1.获取/创建index对象</span>
            <span class="token comment">//2.根据index对象建立索引</span>
        <span class="token punctuation">}</span>

        <span class="token comment">//提供搜索服务</span>
        <span class="token comment">//query:搜索关键字;json_string:搜索结果</span>
        <span class="token keyword">void</span> <span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>query<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>json_string<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//1.query分词</span>
            <span class="token comment">//2.根据分“词”进行index查找</span>
            <span class="token comment">//3.根据查找结果,根据权重进行降序排序</span>
            <span class="token comment">//4.构建json_string</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <h2>7.2将Index设置为单例模式</h2> 
  <p>单例模式是存在线程安全的,所以我们需要对其进行加锁</p> 
  <pre><code class="prism language-cpp">  <span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token function">Index</span><span class="token punctuation">(</span><span class="token keyword">const</span> Index <span class="token operator">&</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">delete</span><span class="token punctuation">;</span>
    Index <span class="token operator">&</span><span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> Index <span class="token operator">&</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token keyword">delete</span><span class="token punctuation">;</span>

    <span class="token keyword">static</span> Index <span class="token operator">*</span>instance<span class="token punctuation">;</span>
    <span class="token keyword">static</span> std<span class="token double-colon punctuation">::</span>mutex mtx<span class="token punctuation">;</span>

  <span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token operator">~</span><span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

    <span class="token keyword">static</span> Index <span class="token operator">*</span><span class="token function">GetInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
      <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> instance<span class="token punctuation">)</span>
      <span class="token punctuation">{</span>
        mtx<span class="token punctuation">.</span><span class="token function">lock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> instance<span class="token punctuation">)</span>
          instance <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">Index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span>
      mtx<span class="token punctuation">.</span><span class="token function">unlock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token keyword">return</span> instance<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
</code></pre> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><mutex></span></span>

  Index <span class="token operator">*</span>Index<span class="token double-colon punctuation">::</span>instance <span class="token operator">=</span> <span class="token keyword">nullptr</span><span class="token punctuation">;</span>
  std<span class="token double-colon punctuation">::</span>mutex Index<span class="token double-colon punctuation">::</span>mtx<span class="token punctuation">;</span>
</code></pre> 
  <h2>7.3 InitSearcher();</h2> 
  <pre><code class="prism language-cpp">        <span class="token comment">//初始化</span>
        <span class="token keyword">void</span> <span class="token function">InitSearcher</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>input<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//1.获取/创建index对象(单例模式)</span>
            index <span class="token operator">=</span> ns_index<span class="token double-colon punctuation">::</span><span class="token class-name">Index</span><span class="token double-colon punctuation">::</span><span class="token function">GetInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">//2.根据index对象建立索引</span>
            index<span class="token operator">-></span><span class="token function">BuildIndex</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
</code></pre> 
  <h2>7.4Search();</h2> 
  <h3>7.4.1安装josncpp</h3> 
  <pre><code class="prism language-cpp">sudo yum install <span class="token operator">-</span>y jsoncpp<span class="token operator">-</span>devel
</code></pre> 
  <h3>7.4.2josncpp测试:</h3> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><iostream></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><string></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><vector></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><jsoncpp/json/json.h></span></span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  Json<span class="token double-colon punctuation">::</span>Value root<span class="token punctuation">;</span>
  Json<span class="token double-colon punctuation">::</span>Value item1<span class="token punctuation">;</span>
  item1<span class="token punctuation">[</span><span class="token string">"key1"</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"Value1"</span><span class="token punctuation">;</span>
  item1<span class="token punctuation">[</span><span class="token string">"key2"</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"Value2"</span><span class="token punctuation">;</span>

  Json<span class="token double-colon punctuation">::</span>Value item2<span class="token punctuation">;</span>
  item2<span class="token punctuation">[</span><span class="token string">"key1"</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"Value1"</span><span class="token punctuation">;</span>
  item2<span class="token punctuation">[</span><span class="token string">"key2"</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"Value2"</span><span class="token punctuation">;</span>

  root<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>item1<span class="token punctuation">)</span><span class="token punctuation">;</span>
  root<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>item2<span class="token punctuation">)</span><span class="token punctuation">;</span>

  Json<span class="token double-colon punctuation">::</span>StyledWriter writer<span class="token punctuation">;</span>
  std<span class="token double-colon punctuation">::</span>string s <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>

  std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span>s<span class="token operator"><<</span>std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>输出:</p> 
  <pre><code class="prism language-cpp"><span class="token punctuation">[</span>sakeww@VM<span class="token operator">-</span><span class="token number">24</span><span class="token operator">-</span><span class="token number">4</span><span class="token operator">-</span>centos test<span class="token punctuation">]</span>$ <span class="token punctuation">.</span><span class="token operator">/</span>a<span class="token punctuation">.</span>out 
<span class="token punctuation">[</span>
   <span class="token punctuation">{</span>
      <span class="token string">"key1"</span> <span class="token operator">:</span> <span class="token string">"Value1"</span><span class="token punctuation">,</span>
      <span class="token string">"key2"</span> <span class="token operator">:</span> <span class="token string">"Value2"</span>
   <span class="token punctuation">}</span><span class="token punctuation">,</span>
   <span class="token punctuation">{</span>
      <span class="token string">"key1"</span> <span class="token operator">:</span> <span class="token string">"Value1"</span><span class="token punctuation">,</span>
      <span class="token string">"key2"</span> <span class="token operator">:</span> <span class="token string">"Value2"</span>
   <span class="token punctuation">}</span>
<span class="token punctuation">]</span>

<span class="token punctuation">[</span>sakeww@VM<span class="token operator">-</span><span class="token number">24</span><span class="token operator">-</span><span class="token number">4</span><span class="token operator">-</span>centos test<span class="token punctuation">]</span>$ ll

</code></pre> 
  <h3>7.4.3Search()编写</h3> 
  <pre><code class="prism language-cpp">        <span class="token comment">//提供搜索服务</span>
        <span class="token comment">//query:搜索关键字;json_string:搜索结果</span>
        <span class="token keyword">void</span> <span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>query<span class="token punctuation">,</span>std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>json_string<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//1.query分词</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> words<span class="token punctuation">;</span>
            ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">CutString</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span><span class="token operator">&</span>words<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">//2.根据分“词”进行index查找</span>
            ns_index<span class="token double-colon punctuation">::</span>InvertedList inverted_list_all<span class="token punctuation">;</span><span class="token comment">//所有词的倒排拉链</span>
            <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>word<span class="token operator">:</span>words<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                boost<span class="token double-colon punctuation">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//转小写</span>

                ns_index<span class="token double-colon punctuation">::</span>InvertedList <span class="token operator">*</span>inverted_list<span class="token operator">=</span>index<span class="token operator">-></span><span class="token function">GetInvertedList</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span><span class="token operator">==</span>inverted_list<span class="token punctuation">)</span><span class="token punctuation">{</span>
                    <span class="token comment">//这个词没有倒排节点->没有正排节点->检测下一个词</span>
                    <span class="token keyword">continue</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                inverted_list_all<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>inverted_list<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>inverted_list<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            <span class="token comment">//3.根据查找结果,根据权重进行降序排序</span>
            <span class="token function">sort</span><span class="token punctuation">(</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\
                <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> ns_index<span class="token double-colon punctuation">::</span>InvertedElem <span class="token operator">&</span>a<span class="token punctuation">,</span><span class="token keyword">const</span> ns_index<span class="token double-colon punctuation">::</span>InvertedElem <span class="token operator">&</span>b<span class="token punctuation">)</span><span class="token punctuation">{</span>
                    <span class="token keyword">return</span> a<span class="token punctuation">.</span>weight<span class="token operator">></span>b<span class="token punctuation">.</span>weight<span class="token punctuation">;</span><span class="token comment">//降序</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


            <span class="token comment">//4.构建json_string</span>
            <span class="token comment">//根据3,构建json串-jsoncpp-通过jsoncpp完成序列化和反序列化</span>
            Json<span class="token double-colon punctuation">::</span>Value root<span class="token punctuation">;</span>
            <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>item<span class="token operator">:</span>inverted_list_all<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                ns_index<span class="token double-colon punctuation">::</span>DocInfo <span class="token operator">*</span>doc <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetForwardIndex</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>doc_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> doc<span class="token punctuation">)</span><span class="token comment">//查找失败</span>
                <span class="token punctuation">{</span>
                    <span class="token keyword">continue</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                Json<span class="token double-colon punctuation">::</span>Value elem<span class="token punctuation">;</span>
                elem<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span><span class="token operator">=</span>doc<span class="token operator">-></span>title<span class="token punctuation">;</span>
                <span class="token comment">//doc->content是文档去标签之后的内容,我们要的是截取其中一部分</span>
                elem<span class="token punctuation">[</span><span class="token string">"desc"</span><span class="token punctuation">]</span><span class="token operator">=</span>doc<span class="token operator">-></span>content<span class="token punctuation">;</span>
                elem<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span><span class="token operator">=</span>doc<span class="token operator">-></span>url<span class="token punctuation">;</span> 

                root<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>elem<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            Json<span class="token double-colon punctuation">::</span>StyledWriter writer<span class="token punctuation">;</span>
            <span class="token operator">*</span>json_string <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
</code></pre> 
  <h3>7.4.4测试</h3> 
  <p>server.cc</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">"searcher.hpp"</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><iostream></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string"><string></span></span>

<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string input<span class="token operator">=</span><span class="token string">"data/raw_html/raw.txt"</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
  <span class="token comment">//测试:</span>
  ns_searcher<span class="token double-colon punctuation">::</span>Searcher <span class="token operator">*</span>search <span class="token operator">=</span> <span class="token keyword">new</span> ns_searcher<span class="token double-colon punctuation">::</span><span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  search<span class="token operator">-></span><span class="token function">InitSearcher</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//初始化</span>

  std<span class="token double-colon punctuation">::</span>string query<span class="token punctuation">;</span><span class="token comment">//搜索内容</span>
  std<span class="token double-colon punctuation">::</span>string json_string<span class="token punctuation">;</span><span class="token comment">//最终结果</span>
  <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span>
  <span class="token punctuation">{</span>
    std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span><span class="token string">"输入搜索内容:"</span><span class="token punctuation">;</span>

    <span class="token comment">//当出现空格的时候,我们输入aa bb cc相当于我们搜索了三个内容</span>
    <span class="token comment">//cin>>query</span>
    <span class="token function">getline</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>cin<span class="token punctuation">,</span>query<span class="token punctuation">)</span><span class="token punctuation">;</span>
    search<span class="token operator">-></span><span class="token function">Search</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span><span class="token operator">&</span>json_string<span class="token punctuation">)</span><span class="token punctuation">;</span>

    std<span class="token double-colon punctuation">::</span>cout<span class="token operator"><<</span>json_string<span class="token operator"><<</span>std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>Makefile</p> 
  <pre><code class="prism language-cpp"><span class="token punctuation">.</span>PHONY<span class="token operator">:</span>all
all<span class="token operator">:</span>Parser Server

Parser<span class="token operator">:</span>parser<span class="token punctuation">.</span>cc 
	g<span class="token operator">++</span> <span class="token operator">-</span>o $@ $<span class="token operator">^</span> <span class="token operator">-</span>std<span class="token operator">=</span>c<span class="token operator">++</span><span class="token number">11</span> <span class="token operator">-</span>lboost_system <span class="token operator">-</span>lboost_filesystem

Server<span class="token operator">:</span>server<span class="token punctuation">.</span>cc
	g<span class="token operator">++</span> <span class="token operator">-</span>o $@ $<span class="token operator">^</span> <span class="token operator">-</span>std<span class="token operator">=</span>c<span class="token operator">++</span><span class="token number">11</span> <span class="token operator">-</span>lboost_system <span class="token operator">-</span>lboost_filesystem <span class="token operator">-</span>ljsoncpp

<span class="token punctuation">.</span>PHONY<span class="token operator">:</span>clean
clean<span class="token operator">:</span>
	rm <span class="token operator">-</span>f Parser Server
</code></pre> 
  <p>测试指令:</p> 
  <pre><code class="prism language-cpp"><span class="token comment">//数据去标签,对网页内容进行数据清理</span>
<span class="token punctuation">.</span><span class="token operator">/</span>Parser
<span class="token comment">//结果在data/raw_html/raw.txt形成8000多行数据</span>

<span class="token comment">//对数据进行处理,构建索引</span>
<span class="token punctuation">.</span><span class="token operator">/</span>Server

输入搜索内容
结果:出现大量数据
</code></pre> 
  <h3>7.4.5建立摘要</h3> 
  <p>为什么需要摘要?<br> 因为经过我们的测试,搜索出来的数据量很大,不是很美观。</p> 
  <p>在构建json_string中</p> 
  <pre><code class="prism language-cpp"> Json<span class="token double-colon punctuation">::</span>Value elem<span class="token punctuation">;</span>
 elem<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span><span class="token operator">=</span>doc<span class="token operator">-></span>title<span class="token punctuation">;</span>
 <span class="token comment">//doc->content是文档去标签之后的内容,我们要的是截取其中一部分</span>
 <span class="token comment">//elem["desc"]=doc->content;</span>
 <span class="token comment">//item.word关键字内容</span>
 elem<span class="token punctuation">[</span><span class="token string">"desc"</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token function">GetDesc</span><span class="token punctuation">(</span>doc<span class="token operator">-></span>content<span class="token punctuation">,</span>item<span class="token punctuation">.</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
 elem<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span><span class="token operator">=</span>doc<span class="token operator">-></span>url<span class="token punctuation">;</span> 
</code></pre> 
  <h3>7.4.6GetDesc();</h3> 
  <pre><code class="prism language-cpp">        std<span class="token double-colon punctuation">::</span>string <span class="token function">GetDesc</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>h_content<span class="token punctuation">,</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>word<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">//1.找到word在h_content首次出现位置,</span>
            <span class="token comment">//我们的准备过程中,是将所有的内容转为小写,然后加入到搜索内容中的,word可能包含大写!</span>
            <span class="token keyword">auto</span> iter <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">search</span><span class="token punctuation">(</span>h_content<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>h_content<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>word<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>word<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span><span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span>
                <span class="token keyword">return</span> <span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">tolower</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token operator">==</span>std<span class="token double-colon punctuation">::</span><span class="token function">tolower</span><span class="token punctuation">(</span>b<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>iter <span class="token operator">==</span> h_content<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">//判断“内容中”是否含有"word“</span>
            <span class="token punctuation">{</span>
                <span class="token keyword">return</span> <span class="token string">"h_content中找不到word!"</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
            <span class="token comment">//获取迭代器距离</span>
            std<span class="token double-colon punctuation">::</span>size_t pos <span class="token operator">=</span> std<span class="token double-colon punctuation">::</span><span class="token function">distance</span><span class="token punctuation">(</span>h_content<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>iter<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">//2.截取前五十(prev_cut)到word到后一百个(next_cut)的内容,</span>
            <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>size_t prev_cut <span class="token operator">=</span> <span class="token number">50</span><span class="token punctuation">;</span>
            <span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>size_t next_cut <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">;</span>

            <span class="token comment">//默认我们全部截取</span>
            std<span class="token double-colon punctuation">::</span>size_t begin <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>size_t end <span class="token operator">=</span> h_content<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>pos <span class="token operator">></span> begin<span class="token operator">+</span>prev_cut<span class="token punctuation">)</span> begin <span class="token operator">=</span> pos<span class="token operator">-</span>prev_cut<span class="token punctuation">;</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>pos<span class="token operator">+</span>next_cut<span class="token operator"><</span>end<span class="token punctuation">)</span> end <span class="token operator">=</span> pos<span class="token operator">+</span>next_cut<span class="token punctuation">;</span>

            <span class="token comment">//3.截取返回</span>
            <span class="token comment">//substr(开始位置,截取多少);</span>
            <span class="token keyword">if</span><span class="token punctuation">(</span>begin<span class="token operator">>=</span>end<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"截取返回出现问题!"</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span> h_content<span class="token punctuation">.</span><span class="token function">substr</span><span class="token punctuation">(</span>begin<span class="token punctuation">,</span>end<span class="token operator">-</span>begin<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
</code></pre> 
  <h3>7.4.7问题:</h3> 
  <h4>7.4.7.1问题介绍:</h4> 
  <p>在Search();的第二步:2.根据分“词”进行index查找中<br> 我们第一步会对一段话进行分词<br> 例如:<br> 搜索内容:吃葡萄不吐葡萄皮<br> 文档内容:吃葡萄不吐葡萄皮吃葡萄不吐葡萄皮吃葡萄不吐葡萄皮<br> 在根据分词进行查找时:<br> 吃,葡萄,吐,等等很多词语都会指向这个文档内容<br> 从而导致:输出结果会出现很多重复内容</p> 
  <h4>7.4.7.2问题测试:</h4> 
  <p>测试:<br> data/input目录下更改一个比较小的文件</p> 
  <pre><code class="prism language-cpp"><span class="token operator"><</span><span class="token operator">!</span>DOCTYPE HTML PUBLIC <span class="token string">"-//W3C//DTD HTML 4.01 Transitional//EN"</span><span class="token operator">></span>
<span class="token operator"><</span>html<span class="token operator">></span>
  <span class="token operator"><</span>head<span class="token operator">></span>
  <span class="token operator"><</span><span class="token operator">!</span><span class="token operator">--</span> <span class="token function">Copyright</span> <span class="token punctuation">(</span>C<span class="token punctuation">)</span> <span class="token number">2002</span> Douglas Gregor <span class="token operator"><</span>doug<span class="token punctuation">.</span>gregor <span class="token operator">-</span>at<span class="token operator">-</span> gmail<span class="token punctuation">.</span>com<span class="token operator">></span>

      Distributed under the Boost Software License<span class="token punctuation">,</span> Version <span class="token number">1.0</span><span class="token punctuation">.</span>
      <span class="token punctuation">(</span>See accompanying file LICENSE_1_0<span class="token punctuation">.</span>txt <span class="token operator">or</span> copy at
      http<span class="token operator">:</span><span class="token comment">//www.boost.org/LICENSE_1_0.txt) --></span>
    <span class="token operator"><</span>title<span class="token operator">></span>Redirect to generated documentation 测试搜索重复问题test test test test test test <span class="token operator"><</span><span class="token operator">/</span>title<span class="token operator">></span>
    <span class="token operator"><</span>meta http<span class="token operator">-</span>equiv<span class="token operator">=</span><span class="token string">"refresh"</span> content<span class="token operator">=</span><span class="token string">"0; URL=http://www.boost.org/doc/libs/master/doc/html/unordered.html"</span><span class="token operator">></span>
  <span class="token operator"><</span><span class="token operator">/</span>head<span class="token operator">></span>
  <span class="token operator"><</span>body<span class="token operator">></span>
    测试内容<span class="token operator">:</span>test test test test test test
    Automatic redirection failed<span class="token punctuation">,</span> please go to
    <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"http://www.boost.org/doc/libs/master/doc/html/unordered.html"</span><span class="token operator">></span>http<span class="token operator">:</span><span class="token comment">//www.boost.org/doc/libs/master/doc/html/unordered.html</a></span>
  <span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>html<span class="token operator">></span>
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/e21c167b36d44bedab44959ac4844d9c.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/e21c167b36d44bedab44959ac4844d9c.jpg" alt="实战项目:Boost搜索引擎_第21张图片" width="650" height="312" style="border:1px solid black;"></a></p> 
  <h4>7.4.7.3问题解决</h4> 
  <pre><code class="prism language-cpp">    <span class="token keyword">struct</span> <span class="token class-name">InvertedElemPrint</span>
    <span class="token punctuation">{</span>
        <span class="token keyword">uint64_t</span> doc_id<span class="token punctuation">;</span>
        <span class="token keyword">int</span> weight<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> word<span class="token punctuation">;</span>
        <span class="token function">InvertedElemPrint</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">doc_id</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">weight</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">class</span> <span class="token class-name">Searcher</span>
    <span class="token punctuation">{</span>
    <span class="token keyword">private</span><span class="token operator">:</span>
        ns_index<span class="token double-colon punctuation">::</span>Index <span class="token operator">*</span>index<span class="token punctuation">;</span> <span class="token comment">//系统查找的索引</span>

    <span class="token keyword">public</span><span class="token operator">:</span>
        <span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
        <span class="token operator">~</span><span class="token function">Searcher</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>

        <span class="token comment">//初始化</span>
        <span class="token keyword">void</span> <span class="token function">InitSearcher</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string input<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">// 1.获取/创建index对象(单例模式)</span>
            index <span class="token operator">=</span> ns_index<span class="token double-colon punctuation">::</span><span class="token class-name">Index</span><span class="token double-colon punctuation">::</span><span class="token function">GetInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"获取index单例成功"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>

            <span class="token comment">// 2.根据index对象建立索引</span>
            index<span class="token operator">-></span><span class="token function">BuildIndex</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"建立正排倒排索引成功"</span> <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token comment">//提供搜索服务</span>
        <span class="token comment">// query:搜索关键字;json_string:搜索结果</span>
        <span class="token keyword">void</span> <span class="token function">Search</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">&</span>query<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string <span class="token operator">*</span>json_string<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            <span class="token comment">// 1.query分词</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>std<span class="token double-colon punctuation">::</span>string<span class="token operator">></span> words<span class="token punctuation">;</span>
            ns_util<span class="token double-colon punctuation">::</span><span class="token class-name">JiebaUtil</span><span class="token double-colon punctuation">::</span><span class="token function">CutString</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span> <span class="token operator">&</span>words<span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 2.根据分“词”进行index查找</span>
            <span class="token comment">//ns_index::InvertedList inverted_list_all;                   //所有词的倒排拉链</span>
            std<span class="token double-colon punctuation">::</span>vector<span class="token operator"><</span>InvertedElemPrint<span class="token operator">></span> inverted_list_all<span class="token punctuation">;</span>
            std<span class="token double-colon punctuation">::</span>unordered_map<span class="token operator"><</span><span class="token keyword">uint64_t</span><span class="token punctuation">,</span> InvertedElemPrint<span class="token operator">></span> tokens_map<span class="token punctuation">;</span> <span class="token comment">// map</span>
            <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>word <span class="token operator">:</span> words<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                boost<span class="token double-colon punctuation">::</span><span class="token function">to_lower</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//转小写</span>

                ns_index<span class="token double-colon punctuation">::</span>InvertedList <span class="token operator">*</span>inverted_list <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetInvertedList</span><span class="token punctuation">(</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> inverted_list<span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    <span class="token comment">//这个词没有倒排节点->没有正排节点->检测下一个词</span>
                    <span class="token keyword">continue</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                <span class="token comment">//含有输出重复内容bug的地方:</span>
                <span class="token comment">// inverted_list_all.insert(inverted_list_all.end(),inverted_list->begin(),inverted_list->end());</span>
                <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>elem <span class="token operator">:</span> <span class="token operator">*</span>inverted_list<span class="token punctuation">)</span>
                <span class="token punctuation">{</span>
                    <span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">=</span> tokens_map<span class="token punctuation">[</span>elem<span class="token punctuation">.</span>doc_id<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment">//[]:如果存在直接获取,如果不存在新建</span>
                    <span class="token comment">// item一定是doc_id相同的print节点</span>
                    item<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> elem<span class="token punctuation">.</span>doc_id<span class="token punctuation">;</span>
                    item<span class="token punctuation">.</span>weight <span class="token operator">+=</span> elem<span class="token punctuation">.</span>weight<span class="token punctuation">;</span>
                    item<span class="token punctuation">.</span>word<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>elem<span class="token punctuation">.</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span>
            <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">:</span> tokens_map<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                inverted_list_all<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span><span class="token function">move</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>second<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            <span class="token comment">// 3.根据查找结果,根据权重进行降序排序</span>
            <span class="token comment">// sort(inverted_list_all.begin(), inverted_list_all.end(),</span>
            <span class="token comment">//      [](const ns_index::InvertedElem &a, const ns_index::InvertedElem &b)</span>
            <span class="token comment">//      {</span>
            <span class="token comment">//          return a.weight > b.weight; //降序</span>
            <span class="token comment">//      });</span>
            std<span class="token double-colon punctuation">::</span><span class="token function">sort</span><span class="token punctuation">(</span>inverted_list_all<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> inverted_list_all<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> InvertedElemPrint <span class="token operator">&</span>a<span class="token punctuation">,</span> <span class="token keyword">const</span> InvertedElemPrint <span class="token operator">&</span>b<span class="token punctuation">)</span><span class="token punctuation">{</span>
                        <span class="token keyword">return</span> a<span class="token punctuation">.</span>weight <span class="token operator">></span> b<span class="token punctuation">.</span>weight<span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token comment">// 4.构建json_string</span>
            <span class="token comment">//根据3,构建json串-jsoncpp-通过jsoncpp完成序列化和反序列化</span>
            Json<span class="token double-colon punctuation">::</span>Value root<span class="token punctuation">;</span>
            <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">auto</span> <span class="token operator">&</span>item <span class="token operator">:</span> inverted_list_all<span class="token punctuation">)</span>
            <span class="token punctuation">{</span>
                ns_index<span class="token double-colon punctuation">::</span>DocInfo <span class="token operator">*</span>doc <span class="token operator">=</span> index<span class="token operator">-></span><span class="token function">GetForwardIndex</span><span class="token punctuation">(</span>item<span class="token punctuation">.</span>doc_id<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">nullptr</span> <span class="token operator">==</span> doc<span class="token punctuation">)</span> <span class="token comment">//查找失败</span>
                <span class="token punctuation">{</span>
                    <span class="token keyword">continue</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>

                Json<span class="token double-colon punctuation">::</span>Value elem<span class="token punctuation">;</span>
                elem<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc<span class="token operator">-></span>title<span class="token punctuation">;</span>
                <span class="token comment">// doc->content是文档去标签之后的内容,我们要的是截取其中一部分</span>
                <span class="token comment">// elem["desc"]=doc->content;</span>
                <span class="token comment">// item.word关键字内容</span>
                elem<span class="token punctuation">[</span><span class="token string">"desc"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">GetDesc</span><span class="token punctuation">(</span>doc<span class="token operator">-></span>content<span class="token punctuation">,</span> item<span class="token punctuation">.</span>word<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                elem<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc<span class="token operator">-></span>url<span class="token punctuation">;</span>

                root<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>elem<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>

            Json<span class="token double-colon punctuation">::</span>StyledWriter writer<span class="token punctuation">;</span>
            <span class="token operator">*</span>json_string <span class="token operator">=</span> writer<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/3aba51a95c0547d099b9b82f81a1cb78.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/3aba51a95c0547d099b9b82f81a1cb78.jpg" alt="实战项目:Boost搜索引擎_第22张图片" width="650" height="408" style="border:1px solid black;"></a></p> 
  <h1>8.http_server模块</h1> 
  <h2>8.1准备工作,</h2> 
  <h3>8.1.1安装较新版本的gcc</h3> 
  <blockquote> 
   <p>cpp_httplib在使用的时候需要使用较新版本的gcc(大约是7.0以上的版本)<br> centos 7默认版本是4.8.5</p> 
  </blockquote> 
  <pre><code class="prism language-cpp"><span class="token comment">//查看gcc版本</span>
gcc <span class="token operator">-</span>v
</code></pre> 
  <p>安装gcc</p> 
  <pre><code class="prism language-cpp"><span class="token comment">//安装scl源</span>
sudo yum install centos<span class="token operator">-</span>release<span class="token operator">-</span>scl scl<span class="token operator">-</span>utils<span class="token operator">-</span>build
<span class="token comment">//安装新版本的gcc</span>
sudo yum install <span class="token operator">-</span>y devtoolset<span class="token operator">-</span><span class="token number">7</span><span class="token operator">-</span>gcc devtoolset<span class="token operator">-</span><span class="token number">7</span><span class="token operator">-</span>gcc<span class="token operator">-</span>c<span class="token operator">++</span>
<span class="token comment">//启动新版本</span>
<span class="token punctuation">[</span>whb@VM<span class="token operator">-</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">3</span><span class="token operator">-</span>centos boost_searcher<span class="token punctuation">]</span>$ scl enable devtoolset<span class="token operator">-</span><span class="token number">7</span> bash
</code></pre> 
  <h3>8.1.2安装cpp-httplib</h3> 
  <blockquote> 
   <p>最新的cpp-httplib在使用的时候,如果gcc不是特别新的话有可能会有运行时错误的问题<br> 建议:cpp-httplib 0.7.15<br> 下载zip安装包,上传到服务器即可</p> 
  </blockquote> 
  <pre><code class="prism language-cpp">cpp<span class="token operator">-</span>httplib安装路径:
https<span class="token operator">:</span><span class="token comment">//gitee.com/zhangkt1995/cpp-httplib?_from=gitee_search</span>
</code></pre> 
  <h3>8.1.3测试</h3> 
  <p>http_server.cc</p> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"cpp-httplib/httplib.h"</span></span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    httplib<span class="token double-colon punctuation">::</span>Server svr<span class="token punctuation">;</span>
    svr<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/test"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> httplib<span class="token double-colon punctuation">::</span>Request <span class="token operator">&</span>req<span class="token punctuation">,</span> httplib<span class="token double-colon punctuation">::</span>Response <span class="token operator">&</span>rsp<span class="token punctuation">{</span>
        rsp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span><span class="token string">"你好,这是一个测试!"</span><span class="token punctuation">,</span> <span class="token string">"text/plain; charset=utf-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    svr<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> <span class="token number">8081</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <p>在浏览器上:<br> 服务器号:8081/test</p> 
  <h2>8.2代码:</h2> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"cpp-httplib/httplib.h"</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">"searcher.hpp"</span></span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string input <span class="token operator">=</span> <span class="token string">"data/raw_html/raw.txt"</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> std<span class="token double-colon punctuation">::</span>string root_path <span class="token operator">=</span> <span class="token string">"./testtest"</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    ns_searcher<span class="token double-colon punctuation">::</span>Searcher search<span class="token punctuation">;</span>
    search<span class="token punctuation">.</span><span class="token function">InitSearcher</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>

    httplib<span class="token double-colon punctuation">::</span>Server svr<span class="token punctuation">;</span>
    svr<span class="token punctuation">.</span><span class="token function">set_base_dir</span><span class="token punctuation">(</span>root_path<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    svr<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/s"</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token operator">&</span>search<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> httplib<span class="token double-colon punctuation">::</span>Request <span class="token operator">&</span>req<span class="token punctuation">,</span> httplib<span class="token double-colon punctuation">::</span>Response <span class="token operator">&</span>rsp<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>req<span class="token punctuation">.</span><span class="token function">has_param</span><span class="token punctuation">(</span><span class="token string">"word"</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            rsp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span><span class="token string">"必须要有搜索关键字!"</span><span class="token punctuation">,</span> <span class="token string">"text/plain; charset=utf-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token keyword">return</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        std<span class="token double-colon punctuation">::</span>string word <span class="token operator">=</span> req<span class="token punctuation">.</span><span class="token function">get_param_value</span><span class="token punctuation">(</span><span class="token string">"word"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"用户在搜索:"</span> <span class="token operator"><<</span> word <span class="token operator"><<</span> std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
        std<span class="token double-colon punctuation">::</span>string json_string<span class="token punctuation">;</span>
        search<span class="token punctuation">.</span><span class="token function">Search</span><span class="token punctuation">(</span>word<span class="token punctuation">,</span> <span class="token operator">&</span>json_string<span class="token punctuation">)</span><span class="token punctuation">;</span>
        rsp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span>json_string<span class="token punctuation">,</span> <span class="token string">"application/json"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>


    <span class="token comment">//测试代码</span>
    <span class="token comment">// httplib::Server svr;</span>
    <span class="token comment">// svr.set_base_dir(root_path.c_str());</span>
    <span class="token comment">// svr.Get("/test", [](const httplib::Request &req, httplib::Response &rsp)</span>
    <span class="token comment">//         { rsp.set_content("你好,这是一个测试!", "text/plain; charset=utf-8"); });</span>
    svr<span class="token punctuation">.</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token string">"0.0.0.0"</span><span class="token punctuation">,</span> <span class="token number">8081</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> 
  <pre><code class="prism language-cpp">服务器号<span class="token operator">/</span>s<span class="token operator">?</span>word<span class="token operator">=</span>split
</code></pre> 
  <h1>9.前端</h1> 
  <p>testtest/index.html</p> 
  <pre><code class="prism language-cpp"><span class="token operator"><</span><span class="token operator">!</span>DOCTYPE html<span class="token operator">></span>
<span class="token operator"><</span>html lang<span class="token operator">=</span><span class="token string">"en"</span><span class="token operator">></span>
<span class="token operator"><</span>head<span class="token operator">></span>
    <span class="token operator"><</span>meta charset<span class="token operator">=</span><span class="token string">"UTF-8"</span><span class="token operator">></span>
    <span class="token operator"><</span>meta http<span class="token operator">-</span>equiv<span class="token operator">=</span><span class="token string">"X-UA-Compatible"</span> content<span class="token operator">=</span><span class="token string">"IE=edge"</span><span class="token operator">></span>
    <span class="token operator"><</span>meta name<span class="token operator">=</span><span class="token string">"viewport"</span> content<span class="token operator">=</span><span class="token string">"width=device-width, initial-scale=1.0"</span><span class="token operator">></span>
    <span class="token operator"><</span>script src<span class="token operator">=</span><span class="token string">"http://code.jquery.com/jquery-2.1.1.min.js"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span>

    <span class="token operator"><</span>title<span class="token operator">></span>boost 搜索引擎<span class="token operator"><</span><span class="token operator">/</span>title<span class="token operator">></span>
    <span class="token operator"><</span>style<span class="token operator">></span>
        <span class="token comment">/* 去掉网页中的所有的默认内外边距,html的盒子模型 */</span>
        <span class="token operator">*</span> <span class="token punctuation">{</span>
            <span class="token comment">/* 设置外边距 */</span>
            margin<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
            <span class="token comment">/* 设置内边距 */</span>
            padding<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* 将我们的body内的内容100%和html的呈现吻合 */</span>
        html<span class="token punctuation">,</span>
        body <span class="token punctuation">{</span>
            height<span class="token operator">:</span> <span class="token number">100</span><span class="token operator">%</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* 类选择器.container */</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">{</span>
            <span class="token comment">/* 设置div的宽度 */</span>
            width<span class="token operator">:</span> <span class="token number">800</span>px<span class="token punctuation">;</span>
            <span class="token comment">/* 通过设置外边距达到居中对齐的目的 */</span>
            margin<span class="token operator">:</span> <span class="token number">0</span>px <span class="token keyword">auto</span><span class="token punctuation">;</span>
            <span class="token comment">/* 设置外边距的上边距,保持元素和网页的上部距离 */</span>
            margin<span class="token operator">-</span>top<span class="token operator">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* 复合选择器,选中container 下的 search */</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>search <span class="token punctuation">{</span>
            <span class="token comment">/* 宽度与父标签保持一致 */</span>
            width<span class="token operator">:</span> <span class="token number">100</span><span class="token operator">%</span><span class="token punctuation">;</span>
            <span class="token comment">/* 高度设置为52px */</span>
            height<span class="token operator">:</span> <span class="token number">52</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* 先选中input标签, 直接设置标签的属性,先要选中, input:标签选择器*/</span>
        <span class="token comment">/* input在进行高度设置的时候,没有考虑边框的问题 */</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>search input <span class="token punctuation">{</span>
            <span class="token comment">/* 设置left浮动 */</span>
            <span class="token keyword">float</span><span class="token operator">:</span> left<span class="token punctuation">;</span>
            width<span class="token operator">:</span> <span class="token number">600</span>px<span class="token punctuation">;</span>
            height<span class="token operator">:</span> <span class="token number">50</span>px<span class="token punctuation">;</span>
            <span class="token comment">/* 设置边框属性:边框的宽度,样式,颜色 */</span>
            border<span class="token operator">:</span> <span class="token number">1</span>px solid black<span class="token punctuation">;</span>
            <span class="token comment">/* 去掉input输入框的有边框 */</span>
            border<span class="token operator">-</span>right<span class="token operator">:</span> none<span class="token punctuation">;</span>
            <span class="token comment">/* 设置内边距,默认文字不要和左侧边框紧挨着 */</span>
            padding<span class="token operator">-</span>left<span class="token operator">:</span> <span class="token number">10</span>px<span class="token punctuation">;</span>
            <span class="token comment">/* 设置input内部的字体的颜色和样式 */</span>
            color<span class="token operator">:</span> #CCC<span class="token punctuation">;</span>
            font<span class="token operator">-</span>size<span class="token operator">:</span> <span class="token number">14</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment">/* 先选中button标签, 直接设置标签的属性,先要选中, button:标签选择器*/</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>search button <span class="token punctuation">{</span>
            <span class="token comment">/* 设置left浮动 */</span>
            <span class="token keyword">float</span><span class="token operator">:</span> left<span class="token punctuation">;</span>
            width<span class="token operator">:</span> <span class="token number">150</span>px<span class="token punctuation">;</span>
            height<span class="token operator">:</span> <span class="token number">52</span>px<span class="token punctuation">;</span>
            <span class="token comment">/* 设置button的背景颜色,#4e6ef2 */</span>
            background<span class="token operator">-</span>color<span class="token operator">:</span> #<span class="token number">4e6</span>ef2<span class="token punctuation">;</span>
            <span class="token comment">/* 设置button中的字体颜色 */</span>
            color<span class="token operator">:</span> #FFF<span class="token punctuation">;</span>
            <span class="token comment">/* 设置字体的大小 */</span>
            font<span class="token operator">-</span>size<span class="token operator">:</span> <span class="token number">19</span>px<span class="token punctuation">;</span>
            font<span class="token operator">-</span>family<span class="token operator">:</span>Georgia<span class="token punctuation">,</span> <span class="token char">'Times New Roman'</span><span class="token punctuation">,</span> Times<span class="token punctuation">,</span> serif<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">{</span>
            width<span class="token operator">:</span> <span class="token number">100</span><span class="token operator">%</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">.</span>item <span class="token punctuation">{</span>
            margin<span class="token operator">-</span>top<span class="token operator">:</span> <span class="token number">15</span>px<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">.</span>item a <span class="token punctuation">{</span>
            <span class="token comment">/* 设置为块级元素,单独站一行 */</span>
            display<span class="token operator">:</span> block<span class="token punctuation">;</span>
            <span class="token comment">/* a标签的下划线去掉 */</span>
            text<span class="token operator">-</span>decoration<span class="token operator">:</span> none<span class="token punctuation">;</span>
            <span class="token comment">/* 设置a标签中的文字的字体大小 */</span>
            font<span class="token operator">-</span>size<span class="token operator">:</span> <span class="token number">20</span>px<span class="token punctuation">;</span>
            <span class="token comment">/* 设置字体的颜色 */</span>
            color<span class="token operator">:</span> #<span class="token number">4e6</span>ef2<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">.</span>item a<span class="token operator">:</span>hover <span class="token punctuation">{</span>
            text<span class="token operator">-</span>decoration<span class="token operator">:</span> underline<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">.</span>item p <span class="token punctuation">{</span>
            margin<span class="token operator">-</span>top<span class="token operator">:</span> <span class="token number">5</span>px<span class="token punctuation">;</span>
            font<span class="token operator">-</span>size<span class="token operator">:</span> <span class="token number">16</span>px<span class="token punctuation">;</span>
            font<span class="token operator">-</span>family<span class="token operator">:</span><span class="token char">'Lucida Sans'</span><span class="token punctuation">,</span> <span class="token char">'Lucida Sans Regular'</span><span class="token punctuation">,</span> <span class="token char">'Lucida Grande'</span><span class="token punctuation">,</span> <span class="token char">'Lucida Sans Unicode'</span><span class="token punctuation">,</span> Geneva<span class="token punctuation">,</span> Verdana<span class="token punctuation">,</span> sans<span class="token operator">-</span>serif<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token punctuation">.</span>container <span class="token punctuation">.</span>result <span class="token punctuation">.</span>item i<span class="token punctuation">{</span>
            <span class="token comment">/* 设置为块级元素,单独站一行 */</span>
            display<span class="token operator">:</span> block<span class="token punctuation">;</span>
            <span class="token comment">/* 取消斜体风格 */</span>
            font<span class="token operator">-</span>style<span class="token operator">:</span> normal<span class="token punctuation">;</span>
            color<span class="token operator">:</span> green<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>head<span class="token operator">></span>
<span class="token operator"><</span>body<span class="token operator">></span>
    <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"container"</span><span class="token operator">></span>
        <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"search"</span><span class="token operator">></span>
            <span class="token operator"><</span>input type<span class="token operator">=</span><span class="token string">"text"</span> value<span class="token operator">=</span><span class="token string">"请输入搜索关键字"</span><span class="token operator">></span>
            <span class="token operator"><</span>button onclick<span class="token operator">=</span><span class="token string">"Search()"</span><span class="token operator">></span>搜索一下<span class="token operator"><</span><span class="token operator">/</span>button<span class="token operator">></span>
        <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
        <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"result"</span><span class="token operator">></span>
            <span class="token operator"><</span><span class="token operator">!</span><span class="token operator">--</span> 动态生成网页内容 <span class="token operator">--</span><span class="token operator">></span>
            <span class="token operator"><</span><span class="token operator">!</span><span class="token operator">--</span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"item"</span><span class="token operator">></span>
                <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"#"</span><span class="token operator">></span>这是标题<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span>
                <span class="token operator"><</span>p<span class="token operator">></span>这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>
                <span class="token operator"><</span>i<span class="token operator">></span>https<span class="token operator">:</span><span class="token comment">//search.gitee.com/?skin=rec&type=repository&q=cpp-httplib</i></span>
            <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
            <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"item"</span><span class="token operator">></span>
                <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"#"</span><span class="token operator">></span>这是标题<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span>
                <span class="token operator"><</span>p<span class="token operator">></span>这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>
                <span class="token operator"><</span>i<span class="token operator">></span>https<span class="token operator">:</span><span class="token comment">//search.gitee.com/?skin=rec&type=repository&q=cpp-httplib</i></span>
            <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
            <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"item"</span><span class="token operator">></span>
                <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"#"</span><span class="token operator">></span>这是标题<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span>
                <span class="token operator"><</span>p<span class="token operator">></span>这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>
                <span class="token operator"><</span>i<span class="token operator">></span>https<span class="token operator">:</span><span class="token comment">//search.gitee.com/?skin=rec&type=repository&q=cpp-httplib</i></span>
            <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
            <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"item"</span><span class="token operator">></span>
                <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"#"</span><span class="token operator">></span>这是标题<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span>
                <span class="token operator"><</span>p<span class="token operator">></span>这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>
                <span class="token operator"><</span>i<span class="token operator">></span>https<span class="token operator">:</span><span class="token comment">//search.gitee.com/?skin=rec&type=repository&q=cpp-httplib</i></span>
            <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
            <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token string">"item"</span><span class="token operator">></span>
                <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token string">"#"</span><span class="token operator">></span>这是标题<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span>
                <span class="token operator"><</span>p<span class="token operator">></span>这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要这是摘要<span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span>
                <span class="token operator"><</span>i<span class="token operator">></span>https<span class="token operator">:</span><span class="token comment">//search.gitee.com/?skin=rec&type=repository&q=cpp-httplib</i></span>
            <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator">--</span><span class="token operator">></span>
        <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
    <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>
    <span class="token operator"><</span>script<span class="token operator">></span>
        function <span class="token function">Search</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token comment">// 是浏览器的一个弹出框</span>
            <span class="token comment">// alert("hello js!");</span>
            <span class="token comment">// 1. 提取数据, $可以理解成就是JQuery的别称</span>
            let query <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">".container .search input"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"query = "</span> <span class="token operator">+</span> query<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//console是浏览器的对话框,可以用来进行查看js数据</span>

            <span class="token comment">//2. 发起http请求,ajax: 属于一个和后端进行数据交互的函数,JQuery中的</span>
            $<span class="token punctuation">.</span><span class="token function">ajax</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
                type<span class="token operator">:</span> <span class="token string">"GET"</span><span class="token punctuation">,</span>
                url<span class="token operator">:</span> <span class="token string">"/s?word="</span> <span class="token operator">+</span> query<span class="token punctuation">,</span>
                success<span class="token operator">:</span> <span class="token function">function</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">{</span>
                    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token function">BuildHtml</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        function <span class="token function">BuildHtml</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">{</span>
            <span class="token comment">// 获取html中的result标签</span>
            let result_lable <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">".container .result"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">// 清空历史搜索结果</span>
            result_lable<span class="token punctuation">.</span><span class="token function">empty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

            <span class="token keyword">for</span><span class="token punctuation">(</span> let elem of data<span class="token punctuation">)</span><span class="token punctuation">{</span>
                <span class="token comment">// console.log(elem.title);</span>
                <span class="token comment">// console.log(elem.url);</span>
                let a_lable <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">"<a>"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
                    text<span class="token operator">:</span> elem<span class="token punctuation">.</span>title<span class="token punctuation">,</span>
                    href<span class="token operator">:</span> elem<span class="token punctuation">.</span>url<span class="token punctuation">,</span>
                    <span class="token comment">// 跳转到新的页面</span>
                    target<span class="token operator">:</span> <span class="token string">"_blank"</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                let p_lable <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">"<p>"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
                    text<span class="token operator">:</span> elem<span class="token punctuation">.</span>desc
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                let i_lable <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">"<i>"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
                    text<span class="token operator">:</span> elem<span class="token punctuation">.</span>url
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                let div_lable <span class="token operator">=</span> $<span class="token punctuation">(</span><span class="token string">"<div>"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
                    <span class="token keyword">class</span><span class="token operator">:</span> <span class="token string">"item"</span>
                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                a_lable<span class="token punctuation">.</span><span class="token function">appendTo</span><span class="token punctuation">(</span>div_lable<span class="token punctuation">)</span><span class="token punctuation">;</span>
                p_lable<span class="token punctuation">.</span><span class="token function">appendTo</span><span class="token punctuation">(</span>div_lable<span class="token punctuation">)</span><span class="token punctuation">;</span>
                i_lable<span class="token punctuation">.</span><span class="token function">appendTo</span><span class="token punctuation">(</span>div_lable<span class="token punctuation">)</span><span class="token punctuation">;</span>
                div_lable<span class="token punctuation">.</span><span class="token function">appendTo</span><span class="token punctuation">(</span>result_lable<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>body<span class="token operator">></span>
<span class="token operator"><</span><span class="token operator">/</span>html<span class="token operator">></span>

</code></pre> 
  <h1>10.添加日志log.hpp</h1> 
  <h2>10.1代码:</h2> 
  <pre><code class="prism language-cpp"><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">pragma</span> <span class="token expression">once</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><iostream></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><string></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string"><ctime></span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">NORMAL</span> <span class="token expression"><span class="token number">1</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">WARNING</span> <span class="token expression"><span class="token number">2</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DEBUG</span> <span class="token expression"><span class="token number">3</span></span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">FATAL</span> <span class="token expression"><span class="token number">4</span> </span><span class="token comment">//致命错误</span></span>

<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name function">LOG</span><span class="token expression"><span class="token punctuation">(</span>LEVEL<span class="token punctuation">,</span> MESSAGE<span class="token punctuation">)</span> <span class="token function">log</span><span class="token punctuation">(</span>#LEVEL<span class="token punctuation">,</span> MESSAGE<span class="token punctuation">,</span> <span class="token constant">__FILE__</span><span class="token punctuation">,</span> <span class="token constant">__LINE__</span><span class="token punctuation">)</span></span></span>

<span class="token comment">// level:日志等级;message:日志内容;file:错误文件;line:第几行</span>
<span class="token keyword">void</span> <span class="token function">log</span><span class="token punctuation">(</span>std<span class="token double-colon punctuation">::</span>string level<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string message<span class="token punctuation">,</span> std<span class="token double-colon punctuation">::</span>string file<span class="token punctuation">,</span> <span class="token keyword">int</span> line<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"["</span> <span class="token operator"><<</span> level <span class="token operator"><<</span> <span class="token string">"]"</span><span class="token punctuation">;</span>
    std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"["</span> <span class="token operator"><<</span> <span class="token function">time</span><span class="token punctuation">(</span><span class="token keyword">nullptr</span><span class="token punctuation">)</span> <span class="token operator"><<</span> <span class="token string">"]"</span><span class="token punctuation">;</span>
    std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"["</span> <span class="token operator"><<</span> message <span class="token operator"><<</span> <span class="token string">"]"</span><span class="token punctuation">;</span>
    std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"["</span> <span class="token operator"><<</span> file <span class="token operator"><<</span> <span class="token string">"]"</span><span class="token punctuation">;</span>
    std<span class="token double-colon punctuation">::</span>cout <span class="token operator"><<</span> <span class="token string">"["</span> <span class="token operator"><<</span> line <span class="token operator"><<</span> <span class="token string">"]"</span><span class="token operator"><<</span>std<span class="token double-colon punctuation">::</span>endl<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

</code></pre> 
  <h2>10.2测试:</h2> 
  <p>在lindex.hpp中<br> 我们在查看构建索引进度的地方</p> 
  <pre><code class="prism language-cpp">        <span class="token keyword">if</span><span class="token punctuation">(</span>count<span class="token operator">%</span><span class="token number">500</span><span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span> 
          <span class="token function">LOG</span><span class="token punctuation">(</span>NORMAL<span class="token punctuation">,</span><span class="token string">"当前进度:"</span><span class="token operator">+</span>std<span class="token double-colon punctuation">::</span><span class="token function">to_string</span><span class="token punctuation">(</span>count<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
          <span class="token comment">//std::cout<<"当前进度:"<<count<<std::endl;</span>
</code></pre> 
  <p><a href="http://img.e-com-net.com/image/info8/572568b143314fb0b5daa174e0b81031.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/572568b143314fb0b5daa174e0b81031.jpg" alt="实战项目:Boost搜索引擎_第23张图片" width="540" height="164" style="border:1px solid black;"></a><br> 我们将启动过程中生成的日志放进一个文件内</p> 
  <h2>10.3将程序部署到服务器上</h2> 
  <pre><code class="prism language-cpp">nohup <span class="token punctuation">.</span><span class="token operator">/</span>http_server <span class="token operator">></span> log<span class="token operator">/</span>log<span class="token punctuation">.</span>txt <span class="token number">2</span><span class="token operator">></span><span class="token operator">&</span><span class="token number">1</span> <span class="token operator">&</span>
</code></pre> 
  <p>查看进程</p> 
  <pre><code class="prism language-cpp">ps axj <span class="token operator">|</span> grep Http_server
</code></pre> 
  <p>删除</p> 
  <pre><code class="prism language-cpp">kill <span class="token operator">-</span><span class="token number">9</span> 进程
</code></pre> 
  <h1>11.整体理解</h1> 
  <h2>11.1各个文件简介</h2> 
  <p><a href="http://img.e-com-net.com/image/info8/bbdaed4071234f4686c5a57d35291f22.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/bbdaed4071234f4686c5a57d35291f22.jpg" alt="实战项目:Boost搜索引擎_第24张图片" width="650" height="333" style="border:1px solid black;"></a></p> 
  <h2>整体思路</h2> 
  <p><a href="http://img.e-com-net.com/image/info8/ab5fe7ca342548538759e9606f4c5497.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/ab5fe7ca342548538759e9606f4c5497.jpg" alt="实战项目:Boost搜索引擎_第25张图片" width="650" height="1055" style="border:1px solid black;"></a></p> 
  <h1>12.个人遇见问题整理</h1> 
  <h2>12.1点击链接自动添加ip和端口号</h2> 
  <blockquote> 
   <p>1.一切准备就绪,在搜索框内输入关键字,然后点击搜索,此时也是可以正常出现内容的,但是在点击出现内容的标题(正常情况下会进入一个新的网页),但是此时进入的是:<br> <a href="http://img.e-com-net.com/image/info8/136563f2e8964ef6a3aa5b51c136772f.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/136563f2e8964ef6a3aa5b51c136772f.jpg" alt="实战项目:Boost搜索引擎_第26张图片" width="650" height="161" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <p>只有将蓝色部分,删除了,才能进入这个我们想要的网页(除了蓝色部分以外的灰色部分)<br> 检查步骤:<br> ./Parser<br> 这个不需要执行,我们只需要看data/raw_html/raw.txt里面的内容即可<br> ./Server<br> 执行这个看后端整体是否有问题<br> ./Http_server<br> 就是我们目前的状态</p> 
  <p>延伸检查:<br> 在edge中ctrl+shift+i(开发人员工具)<br> 点击元素<br> 当我们正常输入关键字,然后搜索,<br> 打开我们要点击的网页蓝色字体部分,</p> 
  <p>问题所在:<br> https:这里有个空格//:www.boo…<br> 即:https://这部分格式不对,导致其自动添加</p> 
  <blockquote> 
   <p>解决思路起源点:<br> <a href="http://img.e-com-net.com/image/info8/aa97f63d26ca4785bc58d839419fca92.jpg" target="_blank"><img src="http://img.e-com-net.com/image/info8/aa97f63d26ca4785bc58d839419fca92.jpg" alt="实战项目:Boost搜索引擎_第27张图片" width="546" height="384" style="border:1px solid black;"></a></p> 
  </blockquote> 
  <h2>12.2关于12.1的补充</h2> 
  <p>不知道什么原因:12.1中的那个空格还是会拥有,虽然不知道什么情况,但是以下几点是我猜测和乱想,仅供参考<br> 1.长时间不使用这个项目,然后在加载的时候,打开了vscode,可能会自动优化,导致这里加了一个空格</p> 
  <h2>12.3关于网络端口号</h2> 
  <p><strong>现象</strong>:长时间不使用这个服务,或者不常用网络端口号,我以前打开网络端口的时候,是数字-数字的形式,今天访问范围内的网络端口的时候不行<br> <strong>解决</strong>:仅供参考<br> 在内部打开指定网络端口号</p> 
  <pre><code class="prism language-cpp">firewall<span class="token operator">-</span>cmd <span class="token operator">--</span>permanent <span class="token operator">--</span>zone<span class="token operator">=</span><span class="token keyword">public</span> <span class="token operator">--</span>add<span class="token operator">-</span>port<span class="token operator">=</span><span class="token number">8080</span><span class="token operator">/</span>tcp
</code></pre> 
 </div> 
</div>����
                            </div>
                        </div>
                    </div>
                    <!--PC和WAP自适应版-->
                    <div id="SOHUCS" sid="1559734119548653568"></div>
                    <script type="text/javascript" src="/views/front/js/chanyan.js"></script>
                    <!-- 文章页-底部 动态广告位 -->
                    <div class="youdao-fixed-ad" id="detail_ad_bottom"></div>
                </div>
                <div class="col-md-3">
                    <div class="row" id="ad">
                        <!-- 文章页-右侧1 动态广告位 -->
                        <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_1"> </div>
                        </div>
                        <!-- 文章页-右侧2 动态广告位 -->
                        <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_2"></div>
                        </div>
                        <!-- 文章页-右侧3 动态广告位 -->
                        <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad">
                            <div class="youdao-fixed-ad" id="detail_ad_3"></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="container">
        <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(项目实战,搜索引擎,服务器,运维)</h4>
        <div id="paradigm-article-related">
            <div class="recommend-post mb30">
                <ul class="widget-links">
                    <li><a href="/article/1881939556794691584.htm"
                           title="目前碰到的服务器并发性能问题" target="_blank">目前碰到的服务器并发性能问题</a>
                        <span class="text-muted">James506</span>
<a class="tag" taget="_blank" href="/search/Server/1.htm">Server</a><a class="tag" taget="_blank" href="/search/ACE/1.htm">ACE</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/LoadRunner/1.htm">LoadRunner</a><a class="tag" taget="_blank" href="/search/%E5%B9%B6%E5%8F%91%E6%80%A7%E8%83%BD/1.htm">并发性能</a><a class="tag" taget="_blank" href="/search/APACHE/1.htm">APACHE</a>
                        <div>背景:采用APACHE+PHP+ACE构建了一个服务器。ACE采用的是TP_Reactor框架。PHP和ACE之间采用SOCKET进行通信,PHP建立不了长连接,每次请求连接,处理完毕断开。APACHE+PHP部署在一台服务器,ACE部署在另一台服务器。问题:采用loadrunner进行性能测试时,发现并发上不去,以为是资源不够,查看服务器后,发现各服务器的CPU和内存资源都有空余,特别是ACE的</div>
                    </li>
                    <li><a href="/article/1881939430479032320.htm"
                           title="基于ubuntu环境搭建janus服务器" target="_blank">基于ubuntu环境搭建janus服务器</a>
                        <span class="text-muted">James506</span>
<a class="tag" taget="_blank" href="/search/%E9%9F%B3%E8%A7%86%E9%A2%91%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">音视频服务器</a><a class="tag" taget="_blank" href="/search/Server/1.htm">Server</a><a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/janus/1.htm">janus</a><a class="tag" taget="_blank" href="/search/TURN/1.htm">TURN</a><a class="tag" taget="_blank" href="/search/HTTPS/1.htm">HTTPS</a><a class="tag" taget="_blank" href="/search/webrtc/1.htm">webrtc</a>
                        <div>因为产品需要,选择Janus作为音视频通信服务器框架,在阿里云的ubuntu服务器上进行搭建测试。1、环境服务器:阿里云ECS系统:ubuntu16.04.6LTS,以root用户登录。2、下载Janus源码官网:gitclonehttps://github.com/meetecho/janus-gateway.git//下载不下来,直接上网下载最新的TAG0.11.1版本,解压处理//https</div>
                    </li>
                    <li><a href="/article/1881928841732091904.htm"
                           title="第九篇: 3.10. 【watchEffect】实现监听,立即执行函数" target="_blank">第九篇: 3.10. 【watchEffect】实现监听,立即执行函数</a>
                        <span class="text-muted">小画家~</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>官网:立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。watch对比watchEffect都能监听响应式数据的变化,不同的是监听数据变化的方式不同watch:要明确指出监视的数据watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)。示例代码:两种方式实现需求:水温达到50℃,或水位达到20cm,则联系服务器水温:{{temp}}水位:{{h</div>
                    </li>
                    <li><a href="/article/1881926066558267392.htm"
                           title="利用百度物联网MQTT平台远程在线聊天室的实现,使用自带GUI,并通过Pyinstaller进行exe打包" target="_blank">利用百度物联网MQTT平台远程在线聊天室的实现,使用自带GUI,并通过Pyinstaller进行exe打包</a>
                        <span class="text-muted">wss2210</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E7%89%A9%E8%81%94%E7%BD%91/1.htm">物联网</a><a class="tag" taget="_blank" href="/search/ui/1.htm">ui</a>
                        <div>一、项目简介XIBI(随便取的)是一个简单的聊天工具,通过MQTT协议实现消息的发布和订阅。你可以通过它和连接到同一个MQTT服务器的其他小伙伴聊天。当然,你也可以把它当作一个学习MQTT协议的练手项目。主要功能:连接MQTT服务器:输入昵称,点击连接按钮,就可以加入聊天室。发送消息:在输入框里输入你想说的话,按下回车键或者点击发送按钮,消息就会发送到所有连接到服务器的客户端。接收消息:当其他用户</div>
                    </li>
                    <li><a href="/article/1881915726516776960.htm"
                           title="Node.js HTTP模块详解:创建服务器、响应请求与客户端请求" target="_blank">Node.js HTTP模块详解:创建服务器、响应请求与客户端请求</a>
                        <span class="text-muted">m0_74823021</span>
<a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/1.htm">学习路线</a><a class="tag" taget="_blank" href="/search/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4/1.htm">阿里巴巴</a><a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>Node.jsHTTP模块详解:创建服务器、响应请求与客户端请求Node.js的http模块是Node.js核心模块之一,它允许你创建HTTP服务器和客户端。以下是一些关键知识点和代码示例:1.创建HTTP服务器使用http.createServer()方法可以创建一个新的HTTP服务器实例。这个方法接受一个回调函数,该函数在服务器接收到请求时被调用,参数为req(请求对象)和res(响应对象)。</div>
                    </li>
                    <li><a href="/article/1881915600171757568.htm"
                           title="ssti注入" target="_blank">ssti注入</a>
                        <span class="text-muted">m0_73818134</span>
<a class="tag" taget="_blank" href="/search/flask/1.htm">flask</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>flask有个明显的特征就是服务器模板,把用户输入的回显到web页面,一般在用户交互的地方(输入/输出),这个要用python去构造链子去执行python命令,来getshell。一般的注入是get型的如{{7*7}},{%7*7%},{#7*7#},还有{%print(7*7)%}.一般的链子1().__class__.__base__.__subclasses__()[140].__init_</div>
                    </li>
                    <li><a href="/article/1881914588199448576.htm"
                           title="美团Android开发200道面试题及参考答案(上)" target="_blank">美团Android开发200道面试题及参考答案(上)</a>
                        <span class="text-muted">大模型大数据攻城狮</span>
<a class="tag" taget="_blank" href="/search/android%E5%BC%80%E5%8F%91/1.htm">android开发</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%8D%93%E9%9D%A2%E7%BB%8F/1.htm">安卓面经</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E5%8E%82%E6%8B%9B%E8%81%98/1.htm">大厂招聘</a><a class="tag" taget="_blank" href="/search/https%E5%8D%8F%E8%AE%AE/1.htm">https协议</a><a class="tag" taget="_blank" href="/search/Ddos%E6%94%BB%E5%87%BB/1.htm">Ddos攻击</a><a class="tag" taget="_blank" href="/search/%E6%89%8B%E6%92%95%E4%BB%A3%E7%A0%81/1.htm">手撕代码</a><a class="tag" taget="_blank" href="/search/%E5%85%AB%E8%82%A1%E6%96%87/1.htm">八股文</a>
                        <div>http三次握手/四次挥手具体过程,信号量的变化,只有两次握手行不行三次握手过程:第一次握手:客户端向服务器发送一个SYN(同步)标志位为1的TCP报文段,其中包含客户端的初始序列号(ISN),此时客户端进入SYN_SENT状态,表示客户端请求建立连接。第二次握手:服务器收到客户端的SYN报文段后,会向客户端发送一个SYN和ACK(确认)标志位都为1的TCP报文段,其中包含服务器的初始序列号和对客</div>
                    </li>
                    <li><a href="/article/1881912064398651392.htm"
                           title="走进DevOps:让开发与运维齐头并进" target="_blank">走进DevOps:让开发与运维齐头并进</a>
                        <span class="text-muted">大梦百万秋</span>
<a class="tag" taget="_blank" href="/search/%E7%9F%A5%E8%AF%86%E5%AD%A6%E7%88%86/1.htm">知识学爆</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>引言:开发与运维的“世纪和解”还记得那些年,开发人员总是埋头写代码,然后甩手交给运维去部署,仿佛是把热山芋扔给别人。而运维呢,总是默默承受着系统崩溃、服务停机的风险,直到某一天他们终于忍不住咆哮:“你这破代码根本不能跑啊!”于是,开发和运维的“爱恨情仇”持续了很多年。直到有一天,一个叫DevOps的理念横空出世,终于促成了两者的“世纪和解”。开发和运维的团队终于可以手拉手,一起协作,快乐地共创代码</div>
                    </li>
                    <li><a href="/article/1881909919918125056.htm"
                           title="Flask SSTI注入:探索模板注入漏洞" target="_blank">Flask SSTI注入:探索模板注入漏洞</a>
                        <span class="text-muted">NfsVerilog</span>
<a class="tag" taget="_blank" href="/search/flask/1.htm">flask</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a>
                        <div>简介在Web应用程序开发中,安全性是至关重要的。然而,有时候由于不正确的输入验证或者配置设置,可能会导致安全漏洞的存在。在本文中,我们将探讨一种常见的Web应用程序漏洞——Flask中的SSTI(服务器端模板注入)注入。我们将介绍SSTI注入的原理,展示它的危害,并提供一些防御措施。什么是SSTI注入?SSTI(Server-SideTemplateInjection)注入是一种Web应用程序漏洞</div>
                    </li>
                    <li><a href="/article/1881906517838458880.htm"
                           title="Node.js 安装及环境配置指南" target="_blank">Node.js 安装及环境配置指南</a>
                        <span class="text-muted">ADFVBM</span>
<a class="tag" taget="_blank" href="/search/node.js/1.htm">node.js</a>
                        <div>文章目录前言一、Node.js概述二、准备工作三、Node.js安装1.Windows系统2.macOS系统3.Linux系统四、环境配置五、常用命令和技巧六、常见问题及解决方案结语前言随着互联网技术的不断发展,JavaScript已经成为了一门全栈编程语言。Node.js的出现,使得JavaScript不仅可以用于浏览器端,还可以用于服务器端的开发。本文将为您提供一个保姆级的教程,详细介绍如何在</div>
                    </li>
                    <li><a href="/article/1881895035604103168.htm"
                           title="Moretl FileSync增量文件采集工具" target="_blank">Moretl FileSync增量文件采集工具</a>
                        <span class="text-muted">Moretl</span>
<a class="tag" taget="_blank" href="/search/MES/1.htm">MES</a><a class="tag" taget="_blank" href="/search/QMS/1.htm">QMS</a><a class="tag" taget="_blank" href="/search/SCADA/1.htm">SCADA</a><a class="tag" taget="_blank" href="/search/%E6%99%BA%E8%83%BD%E5%88%B6%E9%80%A0/1.htm">智能制造</a><a class="tag" taget="_blank" href="/search/IoT/1.htm">IoT</a>
                        <div>永久免费:我们希望MoretlFileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题.同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采集功能.另外,我们具备从管理界面直接管理所有采集客户端,使整体运维工作更加高效简单.用途定时全量或增量采集工控机,电脑文件或日志.优势开箱即用:</div>
                    </li>
                    <li><a href="/article/1881881297882771456.htm"
                           title="网络安全渗透测试的八个步骤" target="_blank">网络安全渗透测试的八个步骤</a>
                        <span class="text-muted">披荆斩棘的GG</span>
<a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/1.htm">学习路线</a><a class="tag" taget="_blank" href="/search/Web%E5%AE%89%E5%85%A8/1.htm">Web安全</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/1.htm">网络安全</a><a class="tag" taget="_blank" href="/search/web%E5%AE%89%E5%85%A8/1.htm">web安全</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a>
                        <div>一、明确目标1.确定范围:测试目标的范畴、ip、网站域名、内外网、检测帐户。2.确定标准:能渗入到何种程度,所花费的时间、能不能改动提交、能不能漏洞利用、这些。3.确定要求:web应用的漏洞、业务逻辑漏洞、工作人员管理权限管理漏洞、这些。二、信息收集1.方法:积极扫描仪,开放搜索等。2.开放搜索:使用百度搜索引擎得到:后台管理、未经授权网页页面、比较敏感url、这些。3.基础信息:IP、子网、网站</div>
                    </li>
                    <li><a href="/article/1881866547987804160.htm"
                           title="常用性能压测工具实战总结" target="_blank">常用性能压测工具实战总结</a>
                        <span class="text-muted">黑洞托世</span>
<a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4--%E8%BF%90%E7%AD%B9%E5%B8%B7%E5%B9%84/1.htm">运维--运筹帷幄</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95/1.htm">压力测试</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>###一、压测背景>以前:未出社会之前经常用AB工具来压测自己的nginx欢迎页面,看着服务器的资源从20%到100%,发现原来一个开源的工具都可以把一台4C8G的虚拟机压爆满,然后就陷入沉思,低成本的压测都可以造成一台虚拟机的资源满负载,而且还是个静态页面,那如果发生在企业身上会如何?造成的损失远远高于压测方,后果不敢想象。>现在:我承认以前太天真了,既然有压测方,那肯定有防御方,遇到恶意压测他</div>
                    </li>
                    <li><a href="/article/1881857216974221312.htm"
                           title="Java 大视界 -- Java 大数据云原生应用开发:容器化与无服务器计算(十三)" target="_blank">Java 大视界 -- Java 大数据云原生应用开发:容器化与无服务器计算(十三)</a>
                        <span class="text-muted">青云交</span>
<a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%96%B0%E8%A7%86%E7%95%8C/1.htm">大数据新视界</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E8%A7%86%E7%95%8C/1.htm">大视界</a><a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/%E4%BA%91%E5%8E%9F%E7%94%9F/1.htm">云原生</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8%E5%8C%96/1.htm">容器化</a><a class="tag" taget="_blank" href="/search/%E6%97%A0%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%A1%E7%AE%97/1.htm">无服务器计算</a><a class="tag" taget="_blank" href="/search/Docker/1.htm">Docker</a><a class="tag" taget="_blank" href="/search/Kubernetes/1.htm">Kubernetes</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%9E%B6%E6%9E%84/1.htm">微服务架构</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                        <div>亲爱的朋友们,热烈欢迎你们来到青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而我的博客,正是这样一个温暖美好的所在。在这里,你们不仅能够收获既富有趣味又极为实用的内容知识,还可以毫无拘束地畅所欲言,尽情分享自己独特的见解。我真诚地期待着你们的到来,愿我们能在这片小小的天地里共同成长,共同进步。一、本博客的精华专栏:</div>
                    </li>
                    <li><a href="/article/1881846880640495616.htm"
                           title="Linux 安装gitlab" target="_blank">Linux 安装gitlab</a>
                        <span class="text-muted">絮落锦乡</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/gitlab/1.htm">gitlab</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>1.更新系统确保系统是最新的:sudoyumupdate-y2.安装依赖项安装必需的依赖项:sudoyuminstall-ycurlpolicycoreutils-pythonopenssh-serverGitLab需要一个邮件服务来发送通知。你可以使用现有的邮件服务器,或者在本地配置Postfix:sudoyuminstall-ypostfixsudosystemctlenablepostfix</div>
                    </li>
                    <li><a href="/article/1881841087400701952.htm"
                           title="WAF(Web应用防火墙)的关键技术分析" target="_blank">WAF(Web应用防火墙)的关键技术分析</a>
                        <span class="text-muted">?????????????!</span>
<a class="tag" taget="_blank" href="/search/WAF/1.htm">WAF</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/web%E5%AE%89%E5%85%A8/1.htm">web安全</a><a class="tag" taget="_blank" href="/search/%E5%AE%89%E5%85%A8/1.htm">安全</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8/1.htm">网络安全</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a>
                        <div>学习永无止境!!!目录前言一、WAF的工作原理二、WAF常见的部署方式三、WAF的一般工作流程前言本文主要介绍了WAF的工作原理、常见部署方式和工作流程,以帮助读者更好地理解WAF。一、WAF的工作原理WAF是一种根据预先定义的过滤规则和安全防护规则,对所有服务器的访问请求和响应进行检测和内容过滤,以保护Web服务器和Web应用安全的信息系统。相比于传统的网络安全设备如防火墙、入侵检测系统和入侵防</div>
                    </li>
                    <li><a href="/article/1881840835243339776.htm"
                           title="kafka和mq的区别" target="_blank">kafka和mq的区别</a>
                        <span class="text-muted">xsmxh-1314</span>
<a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a><a class="tag" taget="_blank" href="/search/kafka/1.htm">kafka</a><a class="tag" taget="_blank" href="/search/rabbitmq/1.htm">rabbitmq</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a>
                        <div>作为消息队列来说,企业中选择mq的还是多数,因为像Rabbit,Rocket等mq中间件都属于很成熟的产品,性能一般但可靠性较强,而kafka原本设计的初衷是日志统计分析,现在基于大数据的背景下也可以做运营数据的分析统计,而redis的主要场景是内存数据库,作为消息队列来说可靠性太差,而且速度太依赖网络IO,在服务器本机上的速度较快,且容易出现数据堆积的问题,在比较轻量的场合下能够适用。Rabbi</div>
                    </li>
                    <li><a href="/article/1881810810569814016.htm"
                           title="【YOLOv8改进 - 检测头】 RT-DETR检测头,解决传统目标检测器中非极大值抑制(NMS)所带来的速度和准确性之间的平衡问题" target="_blank">【YOLOv8改进 - 检测头】 RT-DETR检测头,解决传统目标检测器中非极大值抑制(NMS)所带来的速度和准确性之间的平衡问题</a>
                        <span class="text-muted">YOLO大师</span>
<a class="tag" taget="_blank" href="/search/YOLO/1.htm">YOLO</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/%E8%AE%BA%E6%96%87%E9%98%85%E8%AF%BB/1.htm">论文阅读</a><a class="tag" taget="_blank" href="/search/%E7%9B%AE%E6%A0%87%E6%A3%80%E6%B5%8B/1.htm">目标检测</a><a class="tag" taget="_blank" href="/search/yolov8/1.htm">yolov8</a>
                        <div>YOLO目标检测创新改进与实战案例专栏专栏目录:YOLO有效改进系列及项目实战目录包含卷积,主干注意力,检测头等创新机制以及各种目标检测分割项目实战案例专栏链接:YOLO基础解析+创新改进+实战案例介绍摘要YOLO系列因其在速度和准确性之间的合理平衡,已成为实时目标检测中最受欢迎的框架。然而,我们观察到YOLO的速度和准确性受到非极大值抑制(NMS)的负面影响。最近,基于Transformer的端</div>
                    </li>
                    <li><a href="/article/1881805014310121472.htm"
                           title="Arm64架构的Linux服务器安装tomcat并部署war包" target="_blank">Arm64架构的Linux服务器安装tomcat并部署war包</a>
                        <span class="text-muted">木枫Free</span>
<a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/arm/1.htm">arm</a><a class="tag" taget="_blank" href="/search/%E8%BF%90%E7%BB%B4/1.htm">运维</a>
                        <div>一、下载Tomcat打开浏览器,访问ApacheTomcat官方网站。在下载页面中,选择适合arm64架构的版本。一般来说,可以选择Tomcat的二进制发行版(BinaryDistributions)中的.tar.gz压缩包。我这里下载的是tomcat9二、安装Tomcat将下载的Tomcat压缩包上传到欧鹏操作系统的服务器上,或者使用命令行工具(如wget)直接下载到服务器上。解压Tomcat压</div>
                    </li>
                    <li><a href="/article/1881797450369396736.htm"
                           title="深入探秘 Java 网络编程:从基础到多线程服务器的全方位指南" target="_blank">深入探秘 Java 网络编程:从基础到多线程服务器的全方位指南</a>
                        <span class="text-muted">2的n次方_</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>我的主页:2的n次方_Java作为一门功能强大的编程语言,不仅在桌面应用、移动开发、后端开发等领域表现出色,还在网络编程中拥有广泛的应用。网络编程涉及在两个或多个设备之间通过网络进行通信,这对于构建分布式系统、客户端-服务器应用程序、以及互联网服务至关重要。在这篇博客中,我们将详细探讨Java网络编程的基础知识,并通过代码示例展示如何在Java中实现网络通信。1.Java网络编程基础Java网络编</div>
                    </li>
                    <li><a href="/article/1881790890918342656.htm"
                           title="模型部署工具01:Docker || 用Docker打包模型 Build Once Run Anywhere" target="_blank">模型部署工具01:Docker || 用Docker打包模型 Build Once Run Anywhere</a>
                        <span class="text-muted">Tiandaren</span>
<a class="tag" taget="_blank" href="/search/%E6%A8%A1%E5%9E%8B%E9%83%A8%E7%BD%B2/1.htm">模型部署</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0/1.htm">深度学习</a><a class="tag" taget="_blank" href="/search/%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD/1.htm">人工智能</a><a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                        <div>Docker是一个开源的容器化平台,可以让开发者和运维人员轻松构建、发布和运行应用程序。Docker的核心概念是通过容器技术隔离应用及其依赖项,使得软件在不同的环境中运行时具有一致性。无论是开发环境、测试环境,还是生产环境,Docker都能够提供高效、可靠的解决方案。在本教程中,我们将详细介绍Docker的核心概念、安装方法,以及如何使用Docker进行容器化操作。Docker是什么?为什么值得学</div>
                    </li>
                    <li><a href="/article/1881788118269489152.htm"
                           title="Spring Cloud LoadBalancer负载均衡" target="_blank">Spring Cloud LoadBalancer负载均衡</a>
                        <span class="text-muted">(空白格)</span>
<a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/Cloud/1.htm">Cloud</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/cloud/1.htm">cloud</a>
                        <div>PS:放假偷偷摸摸卷Java-------------------------------------------------正文分割线----------------------------------------------------概念:负载均衡换句话说就是将请求并发访问转发给后台多台云服务器实例,实现应用程序的流量均衡,性能上实现业务水平扩展。负载均衡还通过故障自动切换及时地消除服务的单</div>
                    </li>
                    <li><a href="/article/1881787362334273536.htm"
                           title="杨建:网站加速--服务器编写篇" target="_blank">杨建:网站加速--服务器编写篇</a>
                        <span class="text-muted">黄传通</span>
<a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/centos/1.htm">centos</a><a class="tag" taget="_blank" href="/search/buffer/1.htm">buffer</a><a class="tag" taget="_blank" href="/search/server/1.htm">server</a><a class="tag" taget="_blank" href="/search/tcp/1.htm">tcp</a><a class="tag" taget="_blank" href="/search/%E5%A4%9A%E7%BA%BF%E7%A8%8B/1.htm">多线程</a>
                        <div>杨建:网站加速--服务器编写篇(上)--提升性能的同时为你节约10倍以上成本From:http://blog.sina.com.cn/iyangjian一,如何节约CPU二,怎样使用内存三,减少磁盘I/O四,优化你的网卡五,调整内核参数六,衡量WebServer的性能指标七,NBAjs直播的发展历程八,新浪财经实时行情系统的历史遗留问题(7byte=10.68wRMB/year)---------</div>
                    </li>
                    <li><a href="/article/1881782320927666176.htm"
                           title="SpringBoot集成Netty实战:构建高效TCPUDP通信服务端【物联网开发必备】" target="_blank">SpringBoot集成Netty实战:构建高效TCPUDP通信服务端【物联网开发必备】</a>
                        <span class="text-muted">m0_74825678</span>
<a class="tag" taget="_blank" href="/search/%E9%9D%A2%E8%AF%95/1.htm">面试</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF/1.htm">学习路线</a><a class="tag" taget="_blank" href="/search/%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4/1.htm">阿里巴巴</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/%E7%89%A9%E8%81%94%E7%BD%91/1.htm">物联网</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a>
                        <div>SpringBoot集成Netty实现TCP/UDP通信协议【优化版】引言在现代物联网(IoT)应用中,设备与服务器之间的实时通信至关重要。Netty作为一个高性能的网络应用框架,与SpringBoot的集成可以简化开发过程,并提高应用性能。本文将详细介绍如何在SpringBoot中集成Netty,实现TCP和UDP通信协议。通讯协议在设计通讯协议时,我们考虑了数据的完整性和命令的明确性。以下是我</div>
                    </li>
                    <li><a href="/article/1881774377494704128.htm"
                           title="如何去控制大量请求并发?" target="_blank">如何去控制大量请求并发?</a>
                        <span class="text-muted">沐雨MUYU_</span>
<a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a>
                        <div>并发请求是在同一时刻发起大量请求,众所周知,浏览器发起的请求最大并发数量一般都是6~8个,这是因为浏览器会限制同一域名下的并发请求数量,以避免对服务器造成过大的压力。首先来模拟大量请求的场景constids=newArray(100).fill('')console.time()for(leti=0;i{}接受一个参数reqs,它是一个数组,包含需要发送的请求。函数的主要目的是对这些请求进行队列管</div>
                    </li>
                    <li><a href="/article/1881771727260807168.htm"
                           title="ReactNative进阶(三十五):应用脚手架 Yo 构建 RN 页面_reactnative 脚手架" target="_blank">ReactNative进阶(三十五):应用脚手架 Yo 构建 RN 页面_reactnative 脚手架</a>
                        <span class="text-muted">2401_84438654</span>
<a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a><a class="tag" taget="_blank" href="/search/react/1.htm">react</a><a class="tag" taget="_blank" href="/search/native/1.htm">native</a><a class="tag" taget="_blank" href="/search/arcgis/1.htm">arcgis</a><a class="tag" taget="_blank" href="/search/react.js/1.htm">react.js</a>
                        <div>算法冒泡排序选择排序快速排序二叉树查找:最大值、最小值、固定值二叉树遍历二叉树的最大深度给予链表中的任一节点,把它删除掉链表倒叙如何判断一个单链表有环由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!如果你觉得对你有帮助,可以戳这里获取:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】sudo</div>
                    </li>
                    <li><a href="/article/1881766559966359552.htm"
                           title="Java工程结构:服务器规约(JVM 碰到 OOM 场景时输出 dump 信息、设置tomcat的 JVM 的内存参数、了解服务平均耗时)" target="_blank">Java工程结构:服务器规约(JVM 碰到 OOM 场景时输出 dump 信息、设置tomcat的 JVM 的内存参数、了解服务平均耗时)</a>
                        <span class="text-muted">iOS逆向</span>
<a class="tag" taget="_blank" href="/search/Java%E5%BC%80%E5%8F%91%E7%9A%84%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA/1.htm">Java开发的深入浅出</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>文章目录I调用远程操作必须有超时设置。II推荐了解每个服务大致的平均耗时JVM的Xms和Xmx设置一样大小的内存容量让JVM碰到OOM场景时输出dump信息调大服务器所支持的最大文件句柄数(FileDescriptor,简写为fd)高并发服务器建议调小TCP协议的time_wait超时时间。III设置tomcat的JVM的内存参数查找Tomcat位置:快速定位服务状态和部署位置具体配置步骤查看JV</div>
                    </li>
                    <li><a href="/article/1881763784243081216.htm"
                           title="微信小程序的登录流程-登录与静默登录" target="_blank">微信小程序的登录流程-登录与静默登录</a>
                        <span class="text-muted">Allen_vv</span>
<a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">微信小程序</a><a class="tag" taget="_blank" href="/search/%E5%B0%8F%E7%A8%8B%E5%BA%8F/1.htm">小程序</a><a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1/1.htm">微信</a>
                        <div>1.首先通过uni.getProvider获取到服务的供应商,调用API接口时需要指定service的参数为'weixin',在success的回调函数中对登录的流程做处理。2.通过调用uni.login获取到所需要的参数code,再通过uni.getUserProfile获取微信用户的基本信息,这个API需要指定一个参数为desc:这个参数是需要通知给微信服务器的,在success的回调函数中获</div>
                    </li>
                    <li><a href="/article/1881760884955607040.htm"
                           title="深入探索C#中Newtonsoft.Json库的高级进阶之路" target="_blank">深入探索C#中Newtonsoft.Json库的高级进阶之路</a>
                        <span class="text-muted">步、步、为营</span>
<a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/php/1.htm">php</a>
                        <div>引言在C#开发的广袤天地中,数据的序列化与反序列化是构建高效、灵活应用程序的关键环节。而Newtonsoft.Json库,作为这一领域的璀璨明星,以其强大的功能和出色的性能,成为了众多开发者的首选工具。它不仅仅是一个简单的JSON处理库,更是一把能够解锁复杂数据处理场景的万能钥匙。无论是在构建WebAPI时,需要将服务器端的对象快速转换为JSON格式,以便在网络中传输;还是在处理复杂的配置文件,需</div>
                    </li>
                    <li><a href="/article/1881754452524855296.htm"
                           title="JSONObject解析数据库Date类型报错问题" target="_blank">JSONObject解析数据库Date类型报错问题</a>
                        <span class="text-muted">知忆_IS</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/database/1.htm">database</a><a class="tag" taget="_blank" href="/search/postgresql/1.htm">postgresql</a>
                        <div>JSONObject解析数据库Date类型报错问题最近项目在写服务器后端查询空间数据的接口时,由于表结构不一致,直接写了一个通用函数用json储存数据库中查询的结果,然而今天前端查询一个表的时候无法查到相应的结果,查了一下代码发现爆了如下错误。报错:Causedby:java.lang.IllegalArgumentExceptionatjava.sql.Date.getHours原因是该表中存在</div>
                    </li>
                                <li><a href="/article/42.htm"
                                       title="jQuery 键盘事件keydown ,keypress ,keyup介绍" target="_blank">jQuery 键盘事件keydown ,keypress ,keyup介绍</a>
                                    <span class="text-muted">107x</span>
<a class="tag" taget="_blank" href="/search/js/1.htm">js</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/keydown/1.htm">keydown</a><a class="tag" taget="_blank" href="/search/keypress/1.htm">keypress</a><a class="tag" taget="_blank" href="/search/keyup/1.htm">keyup</a>
                                    <div>本文章总结了下些关于jQuery 键盘事件keydown ,keypress ,keyup介绍,有需要了解的朋友可参考。 
一、首先需要知道的是:  1、keydown()  keydown事件会在键盘按下时触发.  2、keyup()     代码如下 复制代码    
$('input').keyup(funciton(){      </div>
                                </li>
                                <li><a href="/article/169.htm"
                                       title="AngularJS中的Promise" target="_blank">AngularJS中的Promise</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/AngularJS/1.htm">AngularJS</a><a class="tag" taget="_blank" href="/search/Promise/1.htm">Promise</a>
                                    <div>一.Promise 
        Promise是一个接口,它用来处理的对象具有这样的特点:在未来某一时刻(主要是异步调用)会从服务端返回或者被填充属性。其核心是,promise是一个带有then()函数的对象。 
        为了展示它的优点,下面来看一个例子,其中需要获取用户当前的配置文件: 
var cu</div>
                                </li>
                                <li><a href="/article/296.htm"
                                       title="c++ 用数组实现栈类" target="_blank">c++ 用数组实现栈类</a>
                                    <span class="text-muted">CrazyMizzz</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a>
                                    <div>#include<iostream>
#include<cassert>
using namespace std;

template<class T, int SIZE = 50>
class Stack{
private:
	T list[SIZE];//数组存放栈的元素
	int top;//栈顶位置

public:
	Stack(</div>
                                </li>
                                <li><a href="/article/423.htm"
                                       title="java和c语言的雷同" target="_blank">java和c语言的雷同</a>
                                    <span class="text-muted">麦田的设计者</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E9%80%92%E5%BD%92/1.htm">递归</a><a class="tag" taget="_blank" href="/search/scaner/1.htm">scaner</a>
                                    <div>软件启动时的初始化代码,加载用户信息2015年5月27号 
从头学java二 
1、语言的三种基本结构:顺序、选择、循环。废话不多说,需要指出一下几点: 
     a、return语句的功能除了作为函数返回值以外,还起到结束本函数的功能,return后的语句 
不会再继续执行。 
     b、for循环相比于whi</div>
                                </li>
                                <li><a href="/article/550.htm"
                                       title="LINUX环境并发服务器的三种实现模型" target="_blank">LINUX环境并发服务器的三种实现模型</a>
                                    <span class="text-muted">被触发</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>服务器设计技术有很多,按使用的协议来分有TCP服务器和UDP服务器。按处理方式来分有循环服务器和并发服务器。 
1  循环服务器与并发服务器模型 
在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求,对服务端的程序就提出了特殊的要求。 
目前最常用的服务器模型有: 
·循环服务器:服务器在同一时刻只能响应一个客户端的请求 
·并发服务器:服</div>
                                </li>
                                <li><a href="/article/677.htm"
                                       title="Oracle数据库查询指令" target="_blank">Oracle数据库查询指令</a>
                                    <span class="text-muted">肆无忌惮_</span>
<a class="tag" taget="_blank" href="/search/oracle%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">oracle数据库</a>
                                    <div>20140920 
  
单表查询 
-- 查询************************************************************************************************************ 
-- 使用scott用户登录 
  
-- 查看emp表 
  
desc emp 
  
</div>
                                </li>
                                <li><a href="/article/804.htm"
                                       title="ext右下角浮动窗口" target="_blank">ext右下角浮动窗口</a>
                                    <span class="text-muted">知了ing</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/ext/1.htm">ext</a>
                                    <div>第一种 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/</div>
                                </li>
                                <li><a href="/article/931.htm"
                                       title="浅谈REDIS数据库的键值设计" target="_blank">浅谈REDIS数据库的键值设计</a>
                                    <span class="text-muted">矮蛋蛋</span>
<a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a>
                                    <div>http://www.cnblogs.com/aidandan/ 
原文地址:http://www.hoterran.info/redis_kv_design 
 
丰富的数据结构使得redis的设计非常的有趣。不像关系型数据库那样,DEV和DBA需要深度沟通,review每行sql语句,也不像memcached那样,不需要DBA的参与。redis的DBA需要熟悉数据结构,并能了解使用场景。 
 </div>
                                </li>
                                <li><a href="/article/1058.htm"
                                       title="maven编译可执行jar包" target="_blank">maven编译可执行jar包</a>
                                    <span class="text-muted">alleni123</span>
<a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a>
                                    <div>http://stackoverflow.com/questions/574594/how-can-i-create-an-executable-jar-with-dependencies-using-maven 
 
 
<build>
  <plugins>
    <plugin>
      <artifactId>maven-asse</div>
                                </li>
                                <li><a href="/article/1185.htm"
                                       title="人力资源在现代企业中的作用" target="_blank">人力资源在现代企业中的作用</a>
                                    <span class="text-muted">百合不是茶</span>
<a class="tag" taget="_blank" href="/search/HR+%E4%BC%81%E4%B8%9A%E7%AE%A1%E7%90%86/1.htm">HR 企业管理</a>
                                    <div>//人力资源在在企业中的作用人力资源为什么会存在,人力资源究竟是干什么的 人力资源管理是对管理模式一次大的创新,人力资源兴起的原因有以下点: 工业时代的国际化竞争,现代市场的风险管控等等。所以人力资源 在现代经济竞争中的优势明显的存在,人力资源在集团类公司中存在着 明显的优势(鸿海集团),有一次笔者亲自去体验过红海集团的招聘,只 知道人力资源是管理企业招聘的 当时我被招聘上了,当时给我们培训 的人</div>
                                </li>
                                <li><a href="/article/1312.htm"
                                       title="Linux自启动设置详解" target="_blank">Linux自启动设置详解</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>linux有自己一套完整的启动体系,抓住了linux启动的脉络,linux的启动过程将不再神秘。 
阅读之前建议先看一下附图。 
本文中假设inittab中设置的init tree为: 
/etc/rc.d/rc0.d
/etc/rc.d/rc1.d
/etc/rc.d/rc2.d
/etc/rc.d/rc3.d
/etc/rc.d/rc4.d
/etc/rc.d/rc5.d
/etc</div>
                                </li>
                                <li><a href="/article/1439.htm"
                                       title="Spring Aop Schema实现" target="_blank">Spring Aop Schema实现</a>
                                    <span class="text-muted">bijian1013</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/AOP/1.htm">AOP</a>
                                    <div>本例使用的是Spring2.5 
1.Aop配置文件spring-aop.xml 
<?xml version="1.0" encoding="UTF-8"?>  
<beans  
    xmlns="http://www.springframework.org/schema/beans"  
    xmln</div>
                                </li>
                                <li><a href="/article/1566.htm"
                                       title="【Gson七】Gson预定义类型适配器" target="_blank">【Gson七】Gson预定义类型适配器</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/gson/1.htm">gson</a>
                                    <div>Gson提供了丰富的预定义类型适配器,在对象和JSON串之间进行序列化和反序列化时,指定对象和字符串之间的转换方式, 
  DateTypeAdapter 
  
public final class DateTypeAdapter extends TypeAdapter<Date> {
  public static final TypeAdapterFacto</div>
                                </li>
                                <li><a href="/article/1693.htm"
                                       title="【Spark八十八】Spark Streaming累加器操作(updateStateByKey)" target="_blank">【Spark八十八】Spark Streaming累加器操作(updateStateByKey)</a>
                                    <span class="text-muted">bit1129</span>
<a class="tag" taget="_blank" href="/search/update/1.htm">update</a>
                                    <div>在实时计算的实际应用中,有时除了需要关心一个时间间隔内的数据,有时还可能会对整个实时计算的所有时间间隔内产生的相关数据进行统计。 
比如: 对Nginx的access.log实时监控请求404时,有时除了需要统计某个时间间隔内出现的次数,有时还需要统计一整天出现了多少次404,也就是说404监控横跨多个时间间隔。 
  
Spark Streaming的解决方案是累加器,工作原理是,定义</div>
                                </li>
                                <li><a href="/article/1820.htm"
                                       title="linux系统下通过shell脚本快速找到哪个进程在写文件" target="_blank">linux系统下通过shell脚本快速找到哪个进程在写文件</a>
                                    <span class="text-muted">ronin47</span>

                                    <div>一个文件正在被进程写 我想查看这个进程 文件一直在增大 找不到谁在写 使用lsof也没找到 
这个问题挺有普遍性的,解决方法应该很多,这里我给大家提个比较直观的方法。 
linux下每个文件都会在某个块设备上存放,当然也都有相应的inode, 那么透过vfs.write我们就可以知道谁在不停的写入特定的设备上的inode。 
幸运的是systemtap的安装包里带了inodewatch.stp,位</div>
                                </li>
                                <li><a href="/article/1947.htm"
                                       title="java-两种方法求第一个最长的可重复子串" target="_blank">java-两种方法求第一个最长的可重复子串</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a>
                                    <div>
import java.util.Arrays;
import java.util.Collections;
import java.util.List;


public class MaxPrefix {

	
	public static void main(String[] args) {
		String str="abbdabcdabcx";
</div>
                                </li>
                                <li><a href="/article/2074.htm"
                                       title="Netty源码学习-ServerBootstrap启动及事件处理过程" target="_blank">Netty源码学习-ServerBootstrap启动及事件处理过程</a>
                                    <span class="text-muted">bylijinnan</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/netty/1.htm">netty</a>
                                    <div>Netty是采用了Reactor模式的多线程版本,建议先看下面这篇文章了解一下Reactor模式: 
 
http://bylijinnan.iteye.com/blog/1992325 
 
Netty的启动及事件处理的流程,基本上是按照上面这篇文章来走的 
文章里面提到的操作,每一步都能在Netty里面找到对应的代码 
其中Reactor里面的Acceptor就对应Netty的ServerBo</div>
                                </li>
                                <li><a href="/article/2201.htm"
                                       title="servelt filter listener 的生命周期" target="_blank">servelt filter listener 的生命周期</a>
                                    <span class="text-muted">cngolon</span>
<a class="tag" taget="_blank" href="/search/filter/1.htm">filter</a><a class="tag" taget="_blank" href="/search/listener/1.htm">listener</a><a class="tag" taget="_blank" href="/search/servelt/1.htm">servelt</a><a class="tag" taget="_blank" href="/search/%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/1.htm">生命周期</a>
                                    <div>1. servlet    当第一次请求一个servlet资源时,servlet容器创建这个servlet实例,并调用他的 init(ServletConfig config)做一些初始化的工作,然后调用它的service方法处理请求。当第二次请求这个servlet资源时,servlet容器就不在创建实例,而是直接调用它的service方法处理请求,也就是说</div>
                                </li>
                                <li><a href="/article/2328.htm"
                                       title="jmpopups获取input元素值" target="_blank">jmpopups获取input元素值</a>
                                    <span class="text-muted">ctrain</span>
<a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a>
                                    <div>jmpopups 获取弹出层form表单 
首先,我有一个div,里面包含了一个表单,默认是隐藏的,使用jmpopups时,会弹出这个隐藏的div,其实jmpopups是将我们的代码生成一份拷贝。 
当我直接获取这个form表单中的文本框时,使用方法:$('#form input[name=test1]').val();这样是获取不到的。 
我们必须到jmpopups生成的代码中去查找这个值,$(</div>
                                </li>
                                <li><a href="/article/2455.htm"
                                       title="vi查找替换命令详解" target="_blank">vi查找替换命令详解</a>
                                    <span class="text-muted">daizj</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">正则表达式</a><a class="tag" taget="_blank" href="/search/%E6%9B%BF%E6%8D%A2/1.htm">替换</a><a class="tag" taget="_blank" href="/search/%E6%9F%A5%E6%89%BE/1.htm">查找</a><a class="tag" taget="_blank" href="/search/vim/1.htm">vim</a>
                                    <div>一、查找 
 
查找命令 
 
/pattern<Enter> :向下查找pattern匹配字符串 
?pattern<Enter>:向上查找pattern匹配字符串 
使用了查找命令之后,使用如下两个键快速查找: 
n:按照同一方向继续查找 
N:按照反方向查找 
 
字符串匹配 
 
pattern是需要匹配的字符串,例如: 
 
1:  /abc<En</div>
                                </li>
                                <li><a href="/article/2582.htm"
                                       title="对网站中的js,css文件进行打包" target="_blank">对网站中的js,css文件进行打包</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/PHP/1.htm">PHP</a><a class="tag" taget="_blank" href="/search/%E6%89%93%E5%8C%85/1.htm">打包</a>
                                    <div>一,为什么要用smarty进行打包 
apache中也有给js,css这样的静态文件进行打包压缩的模块,但是本文所说的不是以这种方式进行的打包,而是和smarty结合的方式来把网站中的js,css文件进行打包。 
为什么要进行打包呢,主要目的是为了合理的管理自己的代码 。现在有好多网站,你查看一下网站的源码的话,你会发现网站的头部有大量的JS文件和CSS文件,网站的尾部也有可能有大量的J</div>
                                </li>
                                <li><a href="/article/2709.htm"
                                       title="php Yii: 出现undefined offset 或者 undefined index解决方案" target="_blank">php Yii: 出现undefined offset 或者 undefined index解决方案</a>
                                    <span class="text-muted">dcj3sjt126com</span>
<a class="tag" taget="_blank" href="/search/undefined/1.htm">undefined</a>
                                    <div>在开发Yii 时,在程序中定义了如下方式: 
       if($this->menuoption[2] === 'test'),那么在运行程序时会报:undefined offset:2,这样的错误主要是由于php.ini 里的错误等级太高了,在windows下错误等级</div>
                                </li>
                                <li><a href="/article/2836.htm"
                                       title="linux 文件格式(1) sed工具" target="_blank">linux 文件格式(1) sed工具</a>
                                    <span class="text-muted">eksliang</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/linux+sed%E5%B7%A5%E5%85%B7/1.htm">linux sed工具</a><a class="tag" taget="_blank" href="/search/sed%E5%B7%A5%E5%85%B7/1.htm">sed工具</a><a class="tag" taget="_blank" href="/search/linux+sed%E8%AF%A6%E8%A7%A3/1.htm">linux sed详解</a>
                                    <div>转载请出自出处:
http://eksliang.iteye.com/blog/2106082  
简介 
      sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾</div>
                                </li>
                                <li><a href="/article/2963.htm"
                                       title="Android应用程序获取系统权限" target="_blank">Android应用程序获取系统权限</a>
                                    <span class="text-muted">gqdy365</span>
<a class="tag" taget="_blank" href="/search/android/1.htm">android</a>
                                    <div>引用   
如何使Android应用程序获取系统权限 
 
 
        第一个方法简单点,不过需要在Android系统源码的环境下用make来编译: 
 
        1. 在应用程序的AndroidManifest.xml中的manifest节点</div>
                                </li>
                                <li><a href="/article/3090.htm"
                                       title="HoverTree开发日志之验证码" target="_blank">HoverTree开发日志之验证码</a>
                                    <span class="text-muted">hvt</span>
<a class="tag" taget="_blank" href="/search/.net/1.htm">.net</a><a class="tag" taget="_blank" href="/search/C%23/1.htm">C#</a><a class="tag" taget="_blank" href="/search/asp.net/1.htm">asp.net</a><a class="tag" taget="_blank" href="/search/hovertree/1.htm">hovertree</a><a class="tag" taget="_blank" href="/search/webform/1.htm">webform</a>
                                    <div>HoverTree是一个ASP.NET的开源CMS,目前包含文章系统,图库和留言板功能。代码完全开放,文章内容页生成了静态的HTM页面,留言板提供留言审核功能,文章可以发布HTML源代码,图片上传同时生成高品质缩略图。推出之后得到许多网友的支持,再此表示感谢!留言板不断收到许多有益留言,但同时也有不少广告,因此决定在提交留言页面增加验证码功能。ASP.NET验证码在网上找,如果不是很多,就是特别多</div>
                                </li>
                                <li><a href="/article/3217.htm"
                                       title="JSON API:用 JSON 构建 API 的标准指南中文版" target="_blank">JSON API:用 JSON 构建 API 的标准指南中文版</a>
                                    <span class="text-muted">justjavac</span>
<a class="tag" taget="_blank" href="/search/json/1.htm">json</a>
                                    <div>译文地址:https://github.com/justjavac/json-api-zh_CN 
如果你和你的团队曾经争论过使用什么方式构建合理 JSON 响应格式, 那么 JSON API 就是你的 anti-bikeshedding 武器。 
通过遵循共同的约定,可以提高开发效率,利用更普遍的工具,可以是你更加专注于开发重点:你的程序。 
基于 JSON API 的客户端还能够充分利用缓存,</div>
                                </li>
                                <li><a href="/article/3344.htm"
                                       title="数据结构随记_2" target="_blank">数据结构随记_2</a>
                                    <span class="text-muted">lx.asymmetric</span>
<a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a><a class="tag" taget="_blank" href="/search/%E7%AC%94%E8%AE%B0/1.htm">笔记</a>
                                    <div>第三章 栈与队列 
一.简答题 
1. 在一个循环队列中,队首指针指向队首元素的  前一个    位置。  
2.在具有n个单元的循环队列中,队满时共有  n-1  个元素。  
3. 向栈中压入元素的操作是先  移动栈顶指针&n</div>
                                </li>
                                <li><a href="/article/3471.htm"
                                       title="Linux下的监控工具dstat" target="_blank">Linux下的监控工具dstat</a>
                                    <span class="text-muted">网络接口</span>
<a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a>
                                    <div>1) 工具说明dstat是一个用来替换 vmstat,iostat netstat,nfsstat和ifstat这些命令的工具, 是一个全能系统信息统计工具. 与sysstat相比, dstat拥有一个彩色的界面, 在手动观察性能状况时, 数据比较显眼容易观察; 而且dstat支持即时刷新, 譬如输入dstat 3, 即每三秒收集一次, 但最新的数据都会每秒刷新显示. 和sysstat相同的是, </div>
                                </li>
                                <li><a href="/article/3598.htm"
                                       title="C 语言初级入门--二维数组和指针" target="_blank">C 语言初级入门--二维数组和指针</a>
                                    <span class="text-muted">1140566087</span>
<a class="tag" taget="_blank" href="/search/%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84/1.htm">二维数组</a><a class="tag" taget="_blank" href="/search/c%2Fc%2B%2B/1.htm">c/c++</a><a class="tag" taget="_blank" href="/search/%E6%8C%87%E9%92%88/1.htm">指针</a>
                                    <div>/* 
 二维数组的定义和二维数组元素的引用 
 
 二维数组的定义: 
 当数组中的每个元素带有两个下标时,称这样的数组为二维数组; 
 (逻辑上把数组看成一个具有行和列的表格或一个矩阵); 
 语法: 
 类型名 数组名[常量表达式1][常量表达式2] 
 
 二维数组的引用: 
 引用二维数组元素时必须带有两个下标,引用形式如下: 
 例如: 
 int a[3][4];  引用:</div>
                                </li>
                                <li><a href="/article/3725.htm"
                                       title="10点睛Spring4.1-Application Event" target="_blank">10点睛Spring4.1-Application Event</a>
                                    <span class="text-muted">wiselyman</span>
<a class="tag" taget="_blank" href="/search/application/1.htm">application</a>
                                    <div>10.1 Application Event 
 
 Spring使用Application Event给bean之间的消息通讯提供了手段 
 应按照如下部分实现bean之间的消息通讯 
   
   继承ApplicationEvent类实现自己的事件 
   实现继承ApplicationListener接口实现监听事件 
   使用ApplicationContext发布消息 
    
 </div>
                                </li>
                </ul>
            </div>
        </div>
    </div>

<div>
    <div class="container">
        <div class="indexes">
            <strong>按字母分类:</strong>
            <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a
                href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a
                href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a
                href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a
                href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a
                href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a
                href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a
                href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a
                href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a>
        </div>
    </div>
</div>
<footer id="footer" class="mb30 mt30">
    <div class="container">
        <div class="footBglm">
            <a target="_blank" href="/">首页</a> -
            <a target="_blank" href="/custom/about.htm">关于我们</a> -
            <a target="_blank" href="/search/Java/1.htm">站内搜索</a> -
            <a target="_blank" href="/sitemap.txt">Sitemap</a> -
            <a target="_blank" href="/custom/delete.htm">侵权投诉</a>
        </div>
        <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved.
<!--            <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>-->
        </div>
    </div>
</footer>
<!-- 代码高亮 -->
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script>
<script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script>
<link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/>
<script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script>





</body>

</html>