实战项目: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/1950228032513961984.htm"
                           title="ARM 和 AMD 架构的区别" target="_blank">ARM 和 AMD 架构的区别</a>
                        <span class="text-muted">m0_69576880</span>
<a class="tag" taget="_blank" href="/search/arm%E5%BC%80%E5%8F%91/1.htm">arm开发</a><a class="tag" taget="_blank" href="/search/windows/1.htm">windows</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                        <div>ARM架构和AMD架构是两种不同的计算机处理器架构,它们有以下几个主要区别:设计出发点、兼容性、性能特点、市场定价。设计出发点:①ARM构架:ARM架构最初是为嵌入式系统设计的,旨在提供低功耗和高效能的解决方案。它主要应用于移动设备、嵌入式系统和物联网设备②AMD架构:AMD架构是基于x86架构的扩展,旨在提供与Intel架构兼容的处理器。它主要用于台式机、服务器和工作站等计算机系统。兼容性:AR</div>
                    </li>
                    <li><a href="/article/1950222990553706496.htm"
                           title="可处理!环境排放3.0项目怎么提现?裕华投资会刘裕华免费荐股骗局曝光!" target="_blank">可处理!环境排放3.0项目怎么提现?裕华投资会刘裕华免费荐股骗局曝光!</a>
                        <span class="text-muted">墨守成法</span>

                        <div>骗子冒充裕华投资会刘裕华通过伪造或仿冒投资平台,向股民发送虚假环境排放3.0项目链接,引导股民者下载进行投资,以送一万体验金操作小额投资能提现作为诱饵,不断引导消费者加大资金投入。不法分子随后迅速转移资金,当投资者要提现时候就以“流水未完成”“登录异常”“服务器维护”“比赛未结束”等借口不让提现,直到平台关闭跑了或者完成流水任务为由一波亏完。在以翻本为借口继续让投资者加入资金。若你不幸遭遇到裕华投</div>
                    </li>
                    <li><a href="/article/1950218817753903104.htm"
                           title="【项目实战】 容错机制与故障恢复:保障系统连续性的核心体系" target="_blank">【项目实战】 容错机制与故障恢复:保障系统连续性的核心体系</a>
                        <span class="text-muted">本本本添哥</span>
<a class="tag" taget="_blank" href="/search/004/1.htm">004</a><a class="tag" taget="_blank" href="/search/-/1.htm">-</a><a class="tag" taget="_blank" href="/search/%E7%A0%94%E6%95%88%E4%B8%8EDevOps%E8%BF%90%E7%BB%B4%E5%B7%A5%E5%85%B7%E9%93%BE/1.htm">研效与DevOps运维工具链</a><a class="tag" taget="_blank" href="/search/002/1.htm">002</a><a class="tag" taget="_blank" href="/search/-/1.htm">-</a><a class="tag" taget="_blank" href="/search/%E8%BF%9B%E9%98%B6%E5%BC%80%E5%8F%91%E8%83%BD%E5%8A%9B/1.htm">进阶开发能力</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a>
                        <div>在分布式系统中,硬件故障、网络波动、软件异常等问题难以避免。容错机制与故障恢复的核心目标是:通过主动检测故障、自动隔离风险、快速转移负载、重建数据一致性,最大限度减少故障对业务的影响,保障系统“持续可用”与“数据不丢失”。以下从核心机制、实现方式、典型案例等维度展开说明。一、故障检测:及时发现异常节点故障检测是容错的第一步,需通过多维度手段实时感知系统组件状态,确保故障被快速识别。1.健康检查与心</div>
                    </li>
                    <li><a href="/article/1950208107032408064.htm"
                           title="DPDK 技术详解:榨干网络性能的“瑞士军刀”" target="_blank">DPDK 技术详解:榨干网络性能的“瑞士军刀”</a>
                        <span class="text-muted"></span>

                        <div>你是否曾感觉,即使拥有顶级的服务器和万兆网卡,你的网络应用也总是“喂不饱”硬件,性能总差那么一口气?传统的网络处理方式,就像在高速公路上设置了太多的收费站和检查点,限制了数据包的“奔跑”速度。今天,我们要深入探讨一个能够打破这些瓶颈,让你的网络应用快到飞起的“黑科技”——DPDK(DataPlaneDevelopmentKit,数据平面开发套件)。这不仅仅是一个工具包,更是一种全新的网络处理哲学。</div>
                    </li>
                    <li><a href="/article/1950207097413103616.htm"
                           title="微信公众号回调java_处理微信公众号消息回调" target="_blank">微信公众号回调java_处理微信公众号消息回调</a>
                        <span class="text-muted">weixin_39607620</span>
<a class="tag" taget="_blank" href="/search/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%8F%B7%E5%9B%9E%E8%B0%83java/1.htm">微信公众号回调java</a>
                        <div>1、背景在上一节中,咱们知道如何接入微信公众号,可是以后公众号会与咱们进行交互,那么微信公众号如何通知到咱们本身的服务器呢?咱们知道咱们接入的时候提供的url是GET/mp/entry,那么公众号以后产生的事件将会以POST/mp/entry发送到咱们本身的服务器上。html2、代码实现,此处仍是使用weixin-java-mp这个框架实现一、引入weixin-java-mpcom.github.</div>
                    </li>
                    <li><a href="/article/1950201675771867136.htm"
                           title="分布式链路追踪系统架构设计:从理论到企业级实践" target="_blank">分布式链路追踪系统架构设计:从理论到企业级实践</a>
                        <span class="text-muted">ma451152002</span>
<a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a><a class="tag" taget="_blank" href="/search/%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84/1.htm">系统架构</a>
                        <div>分布式链路追踪系统架构设计:从理论到企业级实践本文深入探讨分布式链路追踪系统的架构设计原理、关键技术实现和企业级应用实践,为P7架构师提供完整的技术方案参考。目录引言:分布式链路追踪的重要性核心概念与技术原理系统架构设计数据模型与协议标准核心组件架构设计性能优化与扩展性设计企业级实施策略技术选型与对比分析监控与运维体系未来发展趋势P7架构师面试要点引言:分布式链路追踪的重要性微服务架构下的挑战在现</div>
                    </li>
                    <li><a href="/article/1950194742100815872.htm"
                           title="用代码生成艺术字:设计个性化海报的秘密" target="_blank">用代码生成艺术字:设计个性化海报的秘密</a>
                        <span class="text-muted"></span>

                        <div>本文围绕“用代码生成艺术字:设计个性化海报的秘密”展开,先概述代码生成艺术字在海报设计中的独特价值,接着介绍常用的代码工具(如HTML、CSS、JavaScript等),详细阐述从构思到实现的完整流程,包括字体样式设计、动态效果添加等,还分享了提升艺术字质感的技巧及实际案例。最后总结代码生成艺术字的优势,为设计师提供打造个性化海报的实用指南,助力提升海报设计的独特性与吸引力,符合搜索引擎SEO标准</div>
                    </li>
                    <li><a href="/article/1950192091439099904.htm"
                           title="K8S 常用命令全解析:高效管理容器化集群" target="_blank">K8S 常用命令全解析:高效管理容器化集群</a>
                        <span class="text-muted">恩爸编程</span>
<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%AE%B9%E5%99%A8/1.htm">容器</a><a class="tag" taget="_blank" href="/search/k8s%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/1.htm">k8s常用命令</a><a class="tag" taget="_blank" href="/search/k8s%E6%9C%89%E5%93%AA%E4%BA%9B%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4/1.htm">k8s有哪些常用命令</a><a class="tag" taget="_blank" href="/search/k8s%E5%91%BD%E4%BB%A4%E6%9C%89%E5%93%AA%E4%BA%9B/1.htm">k8s命令有哪些</a><a class="tag" taget="_blank" href="/search/K8S%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E6%9C%89%E5%93%AA%E4%BA%9B/1.htm">K8S常用命令有哪些</a>
                        <div>K8S常用命令全解析:高效管理容器化集群一、引言Kubernetes(K8S)作为强大的容器编排平台,其丰富的命令行工具(kubectl)为用户提供了便捷的方式来管理集群中的各种资源。熟练掌握K8S常用命令对于开发人员和运维人员至关重要,能够有效提高容器化应用的部署、监控与维护效率。本文将详细介绍一些K8S常用命令及其使用案例。二、基础资源操作命令(一)kubectlcreate功能:用于创建K8</div>
                    </li>
                    <li><a href="/article/1950185537319006208.htm"
                           title="新手如何通过github pages静态网站托管搭建个人网站和项目站点" target="_blank">新手如何通过github pages静态网站托管搭建个人网站和项目站点</a>
                        <span class="text-muted">vvandre</span>
<a class="tag" taget="_blank" href="/search/Web%E6%8A%80%E6%9C%AF/1.htm">Web技术</a><a class="tag" taget="_blank" href="/search/github/1.htm">github</a>
                        <div>一、githubpages静态网站托管介绍githubpages它是一个免费快捷的静态网站托管服务。对比传统建站,它有哪些优点呢?在传统方式中,首先要租用服务器,服务器上需要运行外部程序,还需要再购买域名,要配置SSL证书,最后还要配置DNS,将域名解析到服务器。这一套繁琐操作,基本上就把小白劝退了。graphTDA[租用服务器]-->B[部署Web应用(运行外部程序,如Nginx)]B-->C[</div>
                    </li>
                    <li><a href="/article/1950179236295798784.htm"
                           title="word转pdf、pdf转word在线工具分享" target="_blank">word转pdf、pdf转word在线工具分享</a>
                        <span class="text-muted">bpmh</span>
<a class="tag" taget="_blank" href="/search/%E5%B8%B8%E7%94%A8%E5%B7%A5%E5%85%B7/1.htm">常用工具</a><a class="tag" taget="_blank" href="/search/word/1.htm">word</a><a class="tag" taget="_blank" href="/search/pdf/1.htm">pdf</a>
                        <div>️一、在线转换网站(方便快捷,无需安装)MicrosoftOfficeOnline(官方推荐,最安全可靠):网址:直接使用你的Microsoft账户登录https://www.office.com/方法:将你的.docx或.doc文件上传到OneDrive。在OfficeOnline中打开该Word文档。点击文件>另存为>下载PDF副本。优点:官方出品,完全免费,无需额外上传到第三方服务器,安全性</div>
                    </li>
                    <li><a href="/article/1950175452580605952.htm"
                           title="Gerapy爬虫管理框架深度解析:企业级分布式爬虫管控平台" target="_blank">Gerapy爬虫管理框架深度解析:企业级分布式爬虫管控平台</a>
                        <span class="text-muted">Python×CATIA工业智造</span>
<a class="tag" taget="_blank" href="/search/%E7%88%AC%E8%99%AB/1.htm">爬虫</a><a class="tag" taget="_blank" href="/search/%E5%88%86%E5%B8%83%E5%BC%8F/1.htm">分布式</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/pycharm/1.htm">pycharm</a>
                        <div>引言:爬虫工程化的必然选择随着企业数据采集需求指数级增长,传统单点爬虫管理模式面临三重困境:管理效率瓶颈:手动部署耗时占开发总时长的40%以上系统可靠性低:研究显示超过65%的爬虫故障源于部署或调度错误资源利用率差:平均爬虫服务器CPU利用率不足30%爬虫管理方案对比:┌───────────────┬─────────────┬───────────┬───────────┬──────────</div>
                    </li>
                    <li><a href="/article/1950174315609649152.htm"
                           title="Python Gradio:实现交互式图像编辑" target="_blank">Python Gradio:实现交互式图像编辑</a>
                        <span class="text-muted">PythonAI编程架构实战家</span>
<a class="tag" taget="_blank" href="/search/Python%E7%BC%96%E7%A8%8B%E4%B9%8B%E9%81%93/1.htm">Python编程之道</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/ai/1.htm">ai</a>
                        <div>PythonGradio:实现交互式图像编辑关键词:Python,Gradio,交互式图像编辑,计算机视觉,深度学习,图像处理,Web应用摘要:本文将深入探讨如何使用Python的Gradio库构建交互式图像编辑应用。我们将从基础概念开始,逐步介绍Gradio的核心功能,并通过实际代码示例展示如何实现各种图像处理功能。文章将涵盖图像滤镜应用、对象检测、风格迁移等高级功能,同时提供完整的项目实战案例</div>
                    </li>
                    <li><a href="/article/1950169525244719104.htm"
                           title="从零到一:基于差分隐私决策树的客户购买预测系统实战开发" target="_blank">从零到一:基于差分隐私决策树的客户购买预测系统实战开发</a>
                        <span class="text-muted">笙囧同学</span>
<a class="tag" taget="_blank" href="/search/%E5%86%B3%E7%AD%96%E6%A0%91/1.htm">决策树</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/1.htm">机器学习</a>
                        <div>作者简介:笙囧同学,中科院计算机大模型方向硕士,全栈开发爱好者联系方式:3251736703@qq.com各大平台账号:笙囧同学座右铭:偷懒是人生进步的阶梯文章导航快速导航前言-项目背景与价值项目概览-系统架构与功能技术深度解析-核心算法原理️系统实现详解-工程实践细节性能评估与分析-实验结果分析Web系统开发-前后端开发部署与运维-DevOps实践完整复现指南-手把手教程️实践案例与故障排除-问</div>
                    </li>
                    <li><a href="/article/1950169523193704448.htm"
                           title="Claude Code 超详细完整指南(2025最新版)" target="_blank">Claude Code 超详细完整指南(2025最新版)</a>
                        <span class="text-muted">笙囧同学</span>
<a class="tag" taget="_blank" href="/search/python/1.htm">python</a>
                        <div>终端AI编程助手|高频使用点+生态工具+完整命令参考+最新MCP配置目录快速开始(5分钟上手)详细安装指南系统要求Windows安装(WSL方案)macOS安装Linux安装安装验证配置与认证首次认证环境变量配置代理配置⚡基础命令详解启动命令会话管理文件操作Think模式完全指南MCP服务器配置详解MCP基础概念添加MCP服务器10个必备MCP服务器MCP故障排除记忆系统详解高级使用技巧成本控制策</div>
                    </li>
                    <li><a href="/article/1950167758767452160.htm"
                           title="负载均衡-加权随机算法" target="_blank">负载均衡-加权随机算法</a>
                        <span class="text-muted">BP白朴</span>
<a class="tag" taget="_blank" href="/search/Nginx/1.htm">Nginx</a><a class="tag" taget="_blank" href="/search/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1/1.htm">负载均衡</a><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><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>负载均衡-加权随机算法由于访问概率大致相同,所以如果部分服务器性能不一致的话,容易导致性能差的服务器压力过大,所以要根据服务器性能不一致的情况,给性能好的服务器多处理请求,给差的少分配请求(能者多劳)所以就需要在随机算法的基础上给每台服务器设置权重,延伸为加权随机算法1、将应用服务器集群的IP存到Map里,每个IP对应有一个权重2、创建一个List,来将所有权重下的IP存到list里面如:192.</div>
                    </li>
                    <li><a href="/article/1950166876634017792.htm"
                           title="如何在 Ubuntu 24.04 或 22.04 Linux 上安装和运行 Redis 服务器" target="_blank">如何在 Ubuntu 24.04 或 22.04 Linux 上安装和运行 Redis 服务器</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/%E8%BF%90%E7%BB%B4%E5%8F%8A%E4%BD%BF%E7%94%A8/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><a class="tag" taget="_blank" href="/search/ubuntu/1.htm">ubuntu</a><a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a>
                        <div>Redis(RemoteDictionaryServer,远程字典服务器)是一种内存数据结构存储,通常用作NoSQL数据库、缓存和消息代理。它是开源的,因此用户可以免费安装,无需支付任何费用。Redis旨在为需要快速数据访问和低延迟的应用程序提供速度和效率。Redis支持多种数据类型,包括字符串(Strings)、列表(Lists)、集合(Sets)、哈希(Hashes)、有序集合(SortedS</div>
                    </li>
                    <li><a href="/article/1950164482621763584.htm"
                           title="彻底搞懂Cache-Control" target="_blank">彻底搞懂Cache-Control</a>
                        <span class="text-muted">qu木木</span>
<a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a><a class="tag" taget="_blank" href="/search/%E7%BC%93%E5%AD%98/1.htm">缓存</a>
                        <div>文章目录一、是什么?二、核心作用三、指令详解(常用)四、常见场景配置示例五、重要注意事项一、是什么?Cache-Control是HTTP头部中最关键、最灵活的控制缓存的字段,用于定义在客户端(浏览器)和代理服务器(如CDN)上的缓存策略。它取代了HTTP/1.0时代较为简单的Expires和Pragma头部,提供了更精细的控制。二、核心作用是否缓存:明确支出响应是否可以缓存,以及可以被谁缓存(浏览</div>
                    </li>
                    <li><a href="/article/1950163219788132352.htm"
                           title="webSocket双向通信" target="_blank">webSocket双向通信</a>
                        <span class="text-muted">@泽栖</span>
<a class="tag" taget="_blank" href="/search/websocket/1.htm">websocket</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/1.htm">网络协议</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a>
                        <div>webSocket基础使用webSocket小说明:作用浏览器与服务器全双工通信——浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。WebSocket与HTTP最大的区别HTTP通信是单向的,基于请求响应模式WebSocket支持双向通信。实现长连接适用场景:消息通信,视频弹幕,实时信息,等双向通信的使用需求使用:引入maven依赖org.springfram</div>
                    </li>
                    <li><a href="/article/1950163093577330688.htm"
                           title="Linux中Samba服务器安装与配置文件" target="_blank">Linux中Samba服务器安装与配置文件</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/%E8%BF%90%E7%BB%B4/1.htm">运维</a><a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8/1.htm">服务器</a>
                        <div>Samba简述27zkqsamba是一个基于TCP/IP协议的开源软件套件,可以在Linux、Windows、macOS等操作系统上运行。它允许不同操作系统的计算机之间实现文件和打印机共享。samba提供了一个服务,使得Windows操作系统可以像访问本地文件一样访问Linux、Mac等操作系统上的共享文件。实现跨平台的文件共享,提高办公环境的效率和便利性。samba也支持Windows网络邻居协</div>
                    </li>
                    <li><a href="/article/1950154523955752960.htm"
                           title="Docker" target="_blank">Docker</a>
                        <span class="text-muted">℡余晖^</span>
<a class="tag" taget="_blank" href="/search/%E9%BB%91%E9%A9%AC%E7%82%B9%E8%AF%84%E9%A1%B9%E7%9B%AE%E7%9B%B8%E5%85%B3%E9%97%AE%E9%A2%98%E5%92%8C%E7%AC%94%E8%AE%B0/1.htm">黑马点评项目相关问题和笔记</a><a class="tag" taget="_blank" href="/search/docker/1.htm">docker</a><a class="tag" taget="_blank" href="/search/eureka/1.htm">eureka</a><a class="tag" taget="_blank" href="/search/%E5%AE%B9%E5%99%A8/1.htm">容器</a>
                        <div>在黑马点评项目中,在谈到Redisson解决redis的主从一致性问题时,弹幕提到了Docker,本文来简单了解一下Docker,我的初步理解运维是维护多个集群的稳定,那它和VM虚拟机的区别又是什么?,如果要更深入地理解与学习(运维工程师),可以到b站搜索专门的课程(SpringCloud)。一、Docker是什么?重新理解“容器化”的本质1.1Docker的定义Docker是一个开源的容器化平台</div>
                    </li>
                    <li><a href="/article/1950146516492546048.htm"
                           title="搜索引擎技术选型" target="_blank">搜索引擎技术选型</a>
                        <span class="text-muted">dusty_giser</span>

                        <div>  近期,业主对POI检索提出了一些想法,针对之前简单的WordSegment分词和模糊匹配搜索需要进行一些更为符合业主需求的调整。于是这几天对搜索引擎进行了一些技术选型;一、ApacheLucene  Lucene是一个开源的高性能、可扩展的全文检索引擎工具包,但不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎。所以它是一套信息检索工具包,可以说是当今最先进</div>
                    </li>
                    <li><a href="/article/1950145701786742784.htm"
                           title="java web开发实战经典 当当_java web项目实战开发" target="_blank">java web开发实战经典 当当_java web项目实战开发</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/web%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%98%E7%BB%8F%E5%85%B8/1.htm">web开发实战经典</a><a class="tag" taget="_blank" href="/search/%E5%BD%93%E5%BD%93/1.htm">当当</a>
                        <div>本书以问题为导向,涵盖JavaWeb开发技术中所有的核心知识点;实战开发案例丰富,所有的知识案例都来源于企业真实项目,实战性和可操作性强;代码注释详细准确,结构简洁清晰;语言简明易懂,由浅入深地带你学会JavaWeb技术及应用。本书面向广大Java开发工程师和普通高校学生,可作为高等学校计算机及其相关专业Web编程技术课程教材,也可供从事JavaWeb应用开发的技术人员学习参考。¥80.00定价:</div>
                    </li>
                    <li><a href="/article/1950145702407499776.htm"
                           title="构建高性能Web应用:深入Spring WebFlux" target="_blank">构建高性能Web应用:深入Spring WebFlux</a>
                        <span class="text-muted">李多田</span>

                        <div>本文还有配套的精品资源,点击获取简介:SpringWebFlux是Spring框架的一部分,支持反应式编程模型,适合高并发和低延迟Web应用。它提供了非阻塞I/O和事件驱动模型,优化了多核处理器资源的使用。SpringWebFlux拥有两种编程模式,核心组件包括WebHandler,RouterFunction,WebFilter,和WebSession。它与高性能服务器集成,并提供反应式HTTP</div>
                    </li>
                    <li><a href="/article/1950144218282389504.htm"
                           title="为什么学习Web前端一定要掌握JavaScript?" target="_blank">为什么学习Web前端一定要掌握JavaScript?</a>
                        <span class="text-muted">web前端学习指南</span>

                        <div>为什么学习Web前端一定要掌握JavaScript?在前端的世界里,没有什么是JavaScript实现不了的,关于JS有一句话:凡是可以用JavaScript来写的应用,最终都会用JavaScript,JavaScript可运行在所有主要平台的所有主流浏览器上,也可运行在每一个主流操作系统的服务器端上。现如今我们在为网站写任何一个主要功能的时候都需要有懂能够用JavaScript写前端的开发人员。</div>
                    </li>
                    <li><a href="/article/1950144189979226112.htm"
                           title="Spring Security OAuth2.0在分布式系统中的安全实践" target="_blank">Spring Security OAuth2.0在分布式系统中的安全实践</a>
                        <span class="text-muted"></span>

                        <div>引言分布式系统架构下,安全认证与授权面临跨服务、高并发、多租户等挑战。SpringSecurity与OAuth2.0的结合为微服务安全提供了标准化解决方案。分布式系统中的安全挑战跨服务身份认证的复杂性令牌管理的可扩展性问题多租户场景下的权限隔离需求防止CSRF、XSS等常见攻击SpringSecurityOAuth2.0核心架构授权服务器设计@EnableAuthorizationServer配置</div>
                    </li>
                    <li><a href="/article/1950144062413664256.htm"
                           title="Spring Native与GraalVM:无服务器架构的突破" target="_blank">Spring Native与GraalVM:无服务器架构的突破</a>
                        <span class="text-muted">tmjpz04412</span>
<a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/serverless/1.htm">serverless</a><a class="tag" taget="_blank" href="/search/%E6%9E%B6%E6%9E%84/1.htm">架构</a>
                        <div>SpringNative与GraalVM的关系SpringNative是Spring生态系统的一个模块,旨在支持将Spring应用编译为原生可执行文件。GraalVM是一个高性能运行时,提供原生镜像编译能力,允许将Java应用转换为独立的可执行文件。两者结合,显著提升了启动速度和内存效率。无服务器架构中的优势原生编译后的应用启动时间从秒级降至毫秒级,完美适配无服务器环境的冷启动需求。内存占用减少5</div>
                    </li>
                    <li><a href="/article/1950132582230323200.htm"
                           title="使用 C# 实现 FTP 上传的方法,包括详细的代码示例和测试代码" target="_blank">使用 C# 实现 FTP 上传的方法,包括详细的代码示例和测试代码</a>
                        <span class="text-muted">zhxup606</span>
<a class="tag" taget="_blank" href="/search/%E6%9D%8E%E5%B7%A5%E7%AF%87/1.htm">李工篇</a><a class="tag" taget="_blank" href="/search/C%23%E5%AE%9E%E6%88%98%E6%95%99%E7%A8%8B/1.htm">C#实战教程</a><a class="tag" taget="_blank" href="/search/c%23/1.htm">c#</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a>
                        <div>以下是使用C#实现FTP上传的方法,包括详细的代码示例和测试代码。以下代码使用System.Net.FtpWebRequest实现文件上传,并附带一个简单的测试用例。C#FTP上传方法csharpusingSystem;usingSystem.IO;usingSystem.Net;publicclassFtpClient{//////上传文件到FTP服务器//////FTP服务器地址,例如ftp:</div>
                    </li>
                    <li><a href="/article/1950130692448907264.htm"
                           title="Vue CSR 到 Nuxt 3 SSR 迁移:技术实现与问题解决实录" target="_blank">Vue CSR 到 Nuxt 3 SSR 迁移:技术实现与问题解决实录</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/vue.js/1.htm">vue.js</a>
                        <div>1.迁移动机与技术选型1.1CSR架构的局限性基于Vue3和Vite构建的客户端渲染(CSR)单页应用(SPA)提供了良好的开发体验和用户交互流畅性。但是其核心局限在于:搜索引擎优化(SEO):初始HTML响应仅包含一个根div元素,实际内容由JavaScript在浏览器端动态生成。虽然主流搜索引擎(如Google)能够执行部分JavaScript,但其抓取效率和稳定性不如直接获取完整HTML。非</div>
                    </li>
                    <li><a href="/article/1950119980049690624.htm"
                           title="云服务器如何搭建多站点?Nginx多域名部署方案详解 (2025)" target="_blank">云服务器如何搭建多站点?Nginx多域名部署方案详解 (2025)</a>
                        <span class="text-muted"></span>

                        <div>更多云服务器知识,尽在hostol.com当你拥有了第一台云服务器时,那种感觉,就如同得到了一块充满无限可能的“数字画布”。很多人的第一反应是,将自己最心爱的那个域名和网站部署上去,看着它在互联网上成功“点亮”。但是,随着你的项目增多、想法迸发,你可能会开始思考一个极具性价比的问题:我能在这同一台服务器上,再多放几个网站吗?比如,除了我的主博客之外,再放一个作品集网站,一个用于测试的开发站点,甚至</div>
                    </li>
                    <li><a href="/article/1950118087764275200.htm"
                           title="【服务器知识】nginx配置ipv6支持" target="_blank">【服务器知识】nginx配置ipv6支持</a>
                        <span class="text-muted">问道飞鱼</span>
<a class="tag" taget="_blank" href="/search/%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9B%B8%E5%85%B3/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/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E7%BB%9C/1.htm">网络</a><a class="tag" taget="_blank" href="/search/ipv6/1.htm">ipv6</a>
                        <div>nginx配置ipv6支持Nginx全面支持IPv6配置指南一、基础IPv6配置1.启用IPv6监听2.IPv6地址格式说明二、高级IPv6配置1.双栈配置优化2.IPv6访问控制3.IPv6反向代理三、SSL/TLS配置1.IPv6SSL证书配置2.HSTS包含IPv6四、性能优化1.内核参数调优2.Nginx调优参数五、安全加固1.IPv6DDoS防护2.防止地址欺骗六、IPv6测试与诊断1.</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>