用C++来设计开发的基于boost文档的站内搜索引擎项目,点赞收藏起来!

So Easy搜索引擎

  • 项目描述
  • 主要技术
  • 项目特点
    • 0. 准备工作
    • 1. 预处理模块
    • 2. 索引模块
    • 3. 搜索模块
    • 4. 服务器模块
  • 项目难点和提升
  • 结束语

项目描述

boost官网虽然提供了在线文档,但是没有一个方便的搜索入口,因此我基于这样的一个问题上,自主设计开发了一款基于boost文档的站内搜索引擎,可以让我们通过浏览器精准定位获取到我们所需要查找的信息内容,实现小型搜索引擎的功能。

主要技术

介绍主要项目,更有利于在学习这个项目的时候更好的进行下去:


  • 在这个项目中我使用到的一些相关的功能实现总体而言的话是不需要我们进行深入了解的,如boost标准库的一些函数使用,cppjieba中分词函数进行倒排索引分词,,jsoncpp格式将我们生成的数据以json格式存放,cpphttpliib用来搭建http
    模块之中的html文件,因此对于这些功能函数体我们只需要包含它的头文件并且知道在项目之中使用了相关的那个功能就可以了。
  • 除此之外其中最大的难点是对倒排索引的构建,它和正排索引这两个知识模块是我之前没有接触过的,这也是关于搜索引擎的一个新知识点,也是我在进行这个项目设计时候所遇到的项目中继分词功能实现后最为困难的一个疑难点。
  • 正排索引:根据文档id查找相关的文档内容
  • 倒排索引:根据文档内容查找相关的文档id
  • 其中对于容器STL中vector,string的合理使用是C++中最经典的用法也是比较快捷的,其中在存储倒排索引权重时候使用哈希表,是对数据结构知识模块的考察。
  • 因此整体来说,除过一开始那些相关的函数包含之外,更多的都是对于我所学习知识的一个考验,为了能够更加合理的将所学习过的知识融入到一起。

项目特点

0. 准备工作


  • 在进行所有模块的初始化之前,需要按照我们的模块创建好对应的文件夹,将数据也放入对应的文件夹之中(即boosthtml文档,),因此需要提前设定好读取boost文档文件input的html的路径和存放从html取出的优化信息output的路径。
  • 读取数据函数(Read)——是一个比较底层且使用频率较高的读函数,多个模块都能够使用到,我将其放入到公共目录common文件的util.hpp头文件之中,这样提供一个对外的接口更加便捷我们调用。
  • 分词函(Split)——分词函数被索引模块和搜索模块共同使用,因此将其定义和声明放入到公共函数Util.hpp之中
       基于 boost 中的字符串切分, 封装一下
       delimiter 表示分割符, 按照啥字符来切分.
      理解 token_compress_off:
       例如有个字符串: aaa\3bbb\3\3ccc
       此时按照 \3 进行切分,
       切分结果可能有两种风格:
       1. 结果有三个部分,  aaa bbb ccc       token_compress_on 有分割符相邻时,
       会压缩切分结果
       2. 结果有四个部分,  aaa bbb "" ccc    token_compress_off
       不会压缩切分结果的.
      static void Split(const string &input, const string &delimiter,
                        vector<string> *output) {
          boost::split(*output, input, boost::is_any_of(delimiter),
                       boost::token_compress_off);
     }

  • 索引模块和搜索模块的很多内容是相互用的,也就是同样的函数会在这两个模块之中都被调用到,因此我将其中两个都用到的函数以及HTTP模块所需要调用的函数全定义在同一个头文件searcher.h之中,并且将其两个模块的功能放在同一个具体函数之中进行实现。
    在头文件之中需要定义索引模块(Index)的内容和搜索模块(Searcher)的内容,使用命名空间概念namespace searcher

searcher.h中索引模块使用到的函数API接口

  • 定义一个基于索引所需要用到的结构体DocInfo,这也是正排索引的基础,给定doc_id后映射到文档内容,也就是DocInfo对象;
  struct DocInfo {
      int64_t doc_id;//id在那个文档中出现
      string title;//标题
      string url;//url
      string content;//正文
  };
  • 倒排索引的话则是给定词之后映射到包含该词的文档id列表,此处不光是要有文档的id,还应该有权重信息来对此进行最优化的一个排序,则定义一个倒排索引所需要用的权重信息及词内容的结构体Weight
  struct Weight {
      // 该词在哪个文档中出现
      int64_t doc_id;
      // 对应的权重是多少
      int weight;
      // 词是啥
      string word;
 };

其中要定义一个叫做“倒排拉链”的东西typedef vector InvertedList;,倒排拉链中是很多权重,用此来实现对倒排索引的哈希存储中kv键值对的v值类型

  • 提供外部调用的API接口,构造一个Index类表示整个索引结构
  class Index {
    private:
      // 索引结构
       正排索引, 数组下标就对应到 doc_id
      vector<DocInfo> forward_index;
       倒排索引, 使用一个 hash 表来表示这个映射关系
      unordered_map<string, InvertedList> inverted_index;
  
    public:
      Index();
      // 提供一些对外调用的函数
       1. 查正排, 返回指针就可以使用  而NULL 表示无效结果的情况
      const DocInfo* GetDocInfo(int64_t doc_id);
       2. 查倒排
      const InvertedList* GetInvertedList(const string& key);
       3. 构建索引
      bool Build(const string& input_path);
       4. 分词函数
      void CutWord(const string& input, vector<string>* output);
  
    private:
      DocInfo* BuildForward(const string& line);//字符串切分,使用\3将其行文本切分为3部分
      void BuildInverted(const DocInfo& doc_info);//
  
      cppjieba::Jieba jieba;
  };

searcher.h中搜索模块所用到的函数API接口

 class Searcher {
    private:
      Index* index;// 搜索过程依赖索引的. 就需要持有一个 Index 的指针.
 
    public:
      Searcher() : index(new Index()) {//构造函数
      }
      bool Init(const string& input_path);//初始化函数
      bool Search(const string& query, string* results);//搜索函数
  
    private:
      string GenerateDesc(const string& content, const string& word);//在正文之后显示160字的详细描述
 };

  • jieba分词的字符定义
    提前将我们下载好的cppjieba文件解压的doc文档中的信息存放在自己具体的目录之中,之后将其定义出来,这段定义代码是在索引模块函数之中的。
 const char* const DICT_PATH = "../jieba_dict/jieba.dict.utf8";
 const char* const HMM_PATH = "../jieba_dict/hmm_model.utf8";
 const char* const USER_DICT_PATH = "../jieba_dict/user.dict.utf8";
 const char* const IDF_PATH = "../jieba_dict/idf.utf8";
 const char* const STOP_WORD_PATH = "../jieba_dict/stop_words.utf8";

Index::Index() : jieba(DICT_PATH, HMM_PATH, USER_DICT_PATH, IDF_PATH, STOP_WORD_P    ATH) {
 26 }

1. 预处理模块

读取原始的html文档的内容,进行预处理操作:解析出一些重要的信息,文档标题,文档的URL,文档的正文(是去除原来的html标签,只保留正文)


因boost文档提供了两个版本,离线版本(下载)和在线版本(浏览器访问),所以为了能够在浏览器进行搜索的时候,直接展示出我们想要的内容,我通过基于离线版本分析文档页面的内容,为搜索功能提供支持,之后在浏览器点击进行搜索的时候,通过离线版本的倒排索引找到在线版的相关url信息,将其直接展示在浏览器上。

读取文档之前首先要定义好相关的变量结构体用来存放具体的数据,文档的标题,文档的正文,文档的url

  创建一个重要的结构体, 表示一个文档(一个 HTML)
  struct DocInfo {
       文档的标题
      string title;
       文档的 url
      string url;
       文档的正文
      string content;
  };

我将预处理模块分为三个部分
1. 把input目录中所有的html路径都枚举出来:将文件传入枚举函数

  • 如果自己一个个目录进行枚举的话,对于boost的5500+文件想要枚举遍历完,不仅是对内存和时间会产生非常巨大的消耗,而且会严重的影响到使用者的查找体验,因此我这里使用boost函数来完成;
  • 首先检查所传入的地址目录是否存在,如果存在则成功打开其文件进行递归遍历,在递归遍历的时候使用一个核心的类,之后其迭代器循环实现的时候其内部自动调用递归遍历方式完成递归。
  • 什么样的内容会被枚举:遇见的不是普通文件而是一个目录则直接跳过,或者不是html文件是其他文件也直接跳过,直到找到一个将其路径加入到最终结果vector之中。
      fs::recursive_directory_iterator end_iter;
      for (fs::recursive_directory_iterator iter(root_path); iter != end_iter;
           ++iter) {
          当前的路径对应的是不是一个普通文件. 如果是目录, 直接跳过.
          if (!fs::is_regular_file(*iter)) {
              continue;
          }
          当前路径对应的文件是不是一个 html 文件. 如果是其他文件也跳过.
          if (iter->path().extension() != ".html") {
             continue;
          }
          把得到的路径加入到最终结果的 vector 中
          file_list->push_back(iter->path().string());
      }

2. 根据枚举出来的路径依次遍历读取每个html中内容,进行解析:打开枚举出路径的文件,先将内容一股脑地全部读出来之后使用for循环将每一个html取出来将其内容拿出来解析

       负责从指定的路径中, 读取出文件的整体内容, 读到 output 这个 string 里
      static bool Read(const string &input_path, string *output) {
          std::ifstream file(input_path.c_str());
          if (!file.is_open()) {
              return false;
          }
           读取整个文件内容, 思路很简单, 只要按行读取就行了, 把读到的每行结果,
           追加到 output 中即可
           getline 功能就是读取文件中的一行.
           如果读取成功, 就把内容放到了 line 中. 并返回 true
           如果读取失败(读到文件末尾), 返回 false
          string line;
          while (std::getline(file, line)) {
              *output += (line + "\n");
          }
          file.close();
          return true;
      }

读取完成之后就是对其内容进行解析,解析的话因为需要能够得到需要的正文,url,title标题这三部分,我将其解析过程分为四块来进行解析:


  1. 读取文件内容,一股脑的把文件内容都读取出来
    直接调用common公共文件之中的Util.hpp文件之中的Read函数,来获取所有的文件内容;

  2. 根据文件内容解析出标题(html之中有着一个title标签)
    将每一个读取出的html传入标题解析函数,对其进行解析,解析出来title后放入到doc_info->title之中/
    查找标题的具体实现:要大概了解html的格式,会发现</code>标签引导开始的就是title内容,所以我们只要找到这个标签后,就能够确定后面的内容。</p> </li> <li> <p>根据文件路径构造出对应在线文档URL<br> 获取url的话我是根据本地路径获取到在线文档的路径<br> 本地路径:…/data/input/html/thread.html<br> 在线路径形如:https://www.boost.org/doc/libs/1_53_0/doc/html/thread.html<br> 通过两个的对比,可以轻松的发现两者的差别指出,因此我把本地路径的后半部分截取出来, 拼装上在线路径的前缀就可以了</p> </li> <li> <p>对文件中的内容进行去标签后所获取到的信息,作为doc_info中的content正文的内容<br> 这也是这个第2个局部模块之中较为难的一个地方,首先是因为我们对于一些相关的标签不是特别了解,所以如果很多人不知道这个是什么的话,也可以先看一些html中的内容,就会清晰了(其实就是那些无关紧要的一些字符和标志)<br> 最后将其去除掉标签的内容拿出来存放到我们实现创建好的目录文档之中,并且保证每一行对应一个原始的html</p> </li> </ol> <hr> <p><mark>3. 把解析出的整体结果写入到输出文件中</mark>:直接使用ofstream类将解析出的最终数据结果放入输出文件之中,这一操作的话可以和第二步放在同一个循环之中进行实现</p> <ul> <li>这里切记传参数的时候只能够传引用或者指针,不能是const引用,否则无法执行里面的写文件操作,每一个doc_info信息其实就是一行</li> </ul> <h2>2. 索引模块</h2> <p><mark>输入内容是解析后得到的行文本文件,通过读取这些内容,在内存中构造出一个正排索引和倒排索引,提供一些API供其他模块可以对其进行直接的调用</mark></p> <hr> <ol> <li>查正排函数:检查所传入的参数id是否小于0或者大于整个文件的最大值size,则返回空,否则返回这个文件id个的地址信息。</li> <li>查倒排函数:传入对应的搜索词,通过哈希来查其是否存在,find函数来进行,若存在则返回其所在的位置,也就是unordered_map的第二个参数val,把倒排拉链获取到。<br> <strong>相对于查找正排函数和查找倒排函数来说,构建索引则相对困难和复杂一些</strong></li> <li>构建索引</li> </ol> <ul> <li>按行读取输入文件的内容(即预处理模块所生成的raw_input文件:其结构为一个行文本文件每一行都对应一个文档)</li> <li>针对当前行,解析成DocInfo对象(将其行文本通过切分函数将其分成三部分,用\3 来进行切分,分别为标题,url,正文),并构造为正排索引。</li> </ul> <p><strong>切分函数并将其存储进DocInfo之中构成正排索引</strong></p> <pre><code class="prism language-cpp"> 核心操作<span class="token operator">:</span> 按照 \<span class="token number">3</span> 对 line 进行切分<span class="token punctuation">,</span> 第一个部分就是标题<span class="token punctuation">,</span> 第二个部分就是 url<span class="token punctuation">,</span>第三个部分就是正文 DocInfo<span class="token operator">*</span> Index<span class="token operator">::</span><span class="token function">BuildForward</span><span class="token punctuation">(</span><span class="token keyword">const</span> string<span class="token operator">&</span> line<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token number">1.</span> 先把 line 按照 \<span class="token number">3</span> 切分成 <span class="token number">3</span> 个部分 vector<span class="token operator"><</span>string<span class="token operator">></span> tokens<span class="token punctuation">;</span> common<span class="token operator">::</span>Util<span class="token operator">::</span><span class="token function">Split</span><span class="token punctuation">(</span>line<span class="token punctuation">,</span> <span class="token string">"\3"</span><span class="token punctuation">,</span> <span class="token operator">&</span>tokens<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>tokens<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 punctuation">{</span> 如果切分结果不是 <span class="token number">3</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 keyword">nullptr</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token number">2.</span> 把切分结果填充到 DocInfo 对象中 DocInfo doc_info<span class="token punctuation">;</span> doc_info<span class="token punctuation">.</span>doc_id <span class="token operator">=</span> forward_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">//当前读取文档的大小则就是其对应的id号</span> doc_info<span class="token punctuation">.</span>title <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//第一部分</span> doc_info<span class="token punctuation">.</span>url <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//第二部分</span> doc_info<span class="token punctuation">.</span>content <span class="token operator">=</span> tokens<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment">//第三部分</span> forward_index<span class="token punctuation">.</span><span class="token function">push_back</span><span class="token punctuation">(</span>std<span class="token operator">::</span><span class="token function">move</span><span class="token punctuation">(</span>doc_info<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//移动构造</span> <span class="token number">3.</span> 返回结果注意这里可能存在的野指针问题<span class="token punctuation">.</span> C<span class="token operator">++</span> 中的经典错误<span class="token punctuation">,</span>也是面试中的重要考点<span class="token operator">!</span><span class="token operator">!</span><span class="token operator">!</span> <span class="token comment">//return &doc_info;</span> <span class="token keyword">return</span> <span class="token operator">&</span>forward_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> <ul> <li><mark>根据当前的DocInfo对象,进行解析并构造倒排索引</mark><br> <strong>倒排是一个哈希表,key则是针对文档的分词结果中的词,而value则是倒排拉链,包含若干个Weight对象,因此每一次遍历正排索引的这个文档,就要分析这个文档,将这个文档的信息进行统计词频,计算权重之后将整体的信息更新到倒排索引结构中去。</strong><br> 为了便于统计词频并且计算权重,需创建用于专门统计词频的结构</li> </ul> <pre><code class="prism language-cpp"><span class="token keyword">struct</span> WordCnt <span class="token punctuation">{</span> <span class="token keyword">int</span> title_cnt<span class="token punctuation">;</span><span class="token comment">//标题出现的次数</span> <span class="token keyword">int</span> content_cnt<span class="token punctuation">;</span><span class="token comment">//正文出现的次数</span> <span class="token function">WordCnt</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 comment">//标题和正文初始都为0</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> 将其和所需要找的词存放在哈希表中 </code></pre> <p><strong>01 针对标题进行分词</strong><br> 将标题传入分词函数,将其分词结果装入vector之中。<br> <strong>02 遍历分词结果统计每个次出现的次数</strong><br> unordered_map[]有两个功能,key不存在就添加存在就修改,此处我们不考虑大小写的问题,我将其全部转换为小写来进行,使用boost标准库to_lower函数来完成。<br> for循环遍历整个vector容器,将其中每个日使用to_lower函数进行转换为小写,并把这个词出现的次数存放到标题词出现的次数变量中。<br> <strong>03 针对正文进行分词</strong><br> 将正文传入分词函数,将其分词结果装入vector之中<br> <strong>04 遍历分词结果统计每个词出现的次数</strong><br> 遍历分词的结果,将其转换为小写之后,统计其出现的次数,也就是使用map来进行查找,查找到了value++;<br> <strong>05根据统计结果,整合出Weight对象,并把结果更新到倒排索引中即可</strong><br> 构造Weight对象,将id序号赋给其权重结构体的id,计算权重,这里的话我使用的是标题出现的次数,出现一次我计为10,而在正文中出现一次,则计为1,之后将其出现的次数累加。</p> <pre><code class="prism language-cpp">weight<span class="token punctuation">.</span>weight <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>title_cnt <span class="token operator">+</span> word_pair<span class="token punctuation">.</span>second<span class="token punctuation">.</span>content_cnt<span class="token punctuation">;</span> weight<span class="token punctuation">.</span>word <span class="token operator">=</span> word_pair<span class="token punctuation">.</span>first<span class="token punctuation">;</span> </code></pre> <p>之后将其weight对象插入到倒排索引中去,因此需要先找到所对应的倒排拉链,然后将其追加到拉链末尾即可。<br> 4. 分词<br> 直接引用jieba函数 <code>jieba.CutForSearch(input,*output);</code>函数来进行分词</p> <h2>3. 搜索模块</h2> <p><mark>1. 分词:先针对查询词进行分词(查询词可能比较长)<br> 2. 触发:根据刚才的分词结果,查找倒排索引,找到那些文档是和当前的查询词相关的<br> 3. 排序:把刚才搜索到的文档按照一定的规则进行排序,相关性越高的文档排的会越靠前<br> 4. 构造结果:刚才触发出来的结果和排序的结果都是包含了一些文档id,而我们希望网页上显示的是标题,url,描述,因此就需要拿着文档id去查正排索引,把结果包装起来返回给发起请求的客户端</mark></p> <hr> <ul> <li>先初始化也就是检验所输入的数据是否有效,若有效则直接返回构建成功的索引</li> <li>把查询词进行搜索,得到搜索结果<br> <strong>01 分词</strong><br> 针对查询词进行分词<br> <strong>02 触发</strong><br> 根据分词结果,查倒排,把相关的文档都获取到<br> 因为在做索引的时候把词转换为了小写,因此在查倒排搜因的时候也需要把查询词统一转成小写<br> 进行倒排查询,若是该词在倒排索引中不存在,则表示此词是生僻词,在所有文档中都没有出现,则返回的倒排拉链就是nullptr。<br> 从我们所创建的vector容器头部开始将所遍历到的多个倒排拉链的结构全部合并到一起</li> </ul> <pre><code class="prism language-cpp">all_token_result<span class="token punctuation">.</span><span class="token function">insert</span><span class="token punctuation">(</span>all_token_result<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 operator">-</span><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> i nverted_list<span class="token operator">-</span><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> </code></pre> <p><strong>03 排序</strong><br> 把上面查找到的这些文档的倒排拉链合并在一起后就可以按照之前计算的每一个权重来进行降序排序(因为一般搜索引擎都是按照降序进行,如果我们需要使用升序,也可以使用仿函数来自己实现)<br> 在这里我使用lambda来实现的</p> <pre><code class="prism language-cpp">std<span class="token operator">::</span><span class="token function">sort</span><span class="token punctuation">(</span>all_token_result<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> all_token_result<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> Weight<span class="token operator">&</span> w1<span class="token punctuation">,</span> <span class="token keyword">const</span> Weight<span class="token operator">&</span> w2<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// 如果要实现升序排序, 就写成 w1.weight < w2.weight</span> <span class="token comment">// 如果要实现降序排序, 就写成 w1.weight > w2.weight</span> <span class="token keyword">return</span> w1<span class="token punctuation">.</span>weight <span class="token operator">></span> w2<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> </code></pre> <p><strong>04 包装结果</strong>:把得到的这些倒排拉链中的文档id获取到后,去查正排<br> 根据weight中的doc_id查正排,查找到之后把doc_info中的内容够造成最终预期的格式,JSON格式,使用jsoncpp这个库来实现json的操作</p> <pre><code class="prism language-cpp">Json<span class="token operator">::</span>Value results<span class="token punctuation">;</span> <span class="token comment">// 这个 results 中包含了若干个搜索结果. 每个搜索结果就是一个 JSON 对象</span> 循环遍历查正排,将查到的每一个结果包装成JSON对象 Json<span class="token operator">::</span>Value result<span class="token punctuation">;</span> result<span class="token punctuation">[</span><span class="token string">"title"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc_info<span class="token operator">-</span><span class="token operator">></span>title<span class="token punctuation">;</span> result<span class="token punctuation">[</span><span class="token string">"url"</span><span class="token punctuation">]</span> <span class="token operator">=</span> doc_info<span class="token operator">-</span><span class="token operator">></span>url<span class="token punctuation">;</span> result<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">GenerateDesc</span><span class="token punctuation">(</span>doc_info<span class="token operator">-</span><span class="token operator">></span>content<span class="token punctuation">,</span> weight<span class="token punctuation">.</span>word<span class="token punctuation">)</span><span class="token punctuation">;</span> results<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>最后一步,把得到的results这个JSON对象序列化成字符串,写入到output文件之中<br> <strong>05 160字的详细描述</strong><br> 根据正文找到word出现的位置,以该位置为中心,往前找60个字节,作为描述的起始位置,再从起始位置开始找160个字节,作为整个描述内容(需要注意的边界条件就是,前面不够60个或没在正文中出现只在标题中出现过,那就从0开始;如果后面内容不够了那就到末尾结束,如果后面内容显示不下,可以使用…省略号来表示[160这个数字大家可以随意改动])</p> <h2>4. 服务器模块</h2> <p><mark>http服务器,给外部提供服务</mark><br> 因为我更多的是学习的一些关于后端开发的知识和内容,所以对于http的一些内容我可能不是特别的熟悉,在了解http协议的基础上其大概的编程内容还都是从学校的选秀专业课计算机网络中学习到的,而我在整个模块中使用的cpphttplib,则不需要过多的关注HTTP服务器的实现细节,直接调用一些现成的函数即可,这对于大多数朋友来说应该都算是一个比较简捷的途径。</p> <hr> <ol> <li>调用搜索模块:<br> 创建Searcher搜索对象,是为了进行搜索;</li> </ol> <pre><code class="prism language-cpp"> searcher<span class="token operator">::</span>Searcher searcher<span class="token punctuation">;</span> <span class="token keyword">bool</span> ret <span class="token operator">=</span> searcher<span class="token punctuation">.</span><span class="token function">Init</span><span class="token punctuation">(</span><span class="token string">"../data/tmp/raw_input"</span><span class="token punctuation">)</span><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>ret<span class="token punctuation">)</span> <span class="token punctuation">{</span> std<span class="token operator">::</span>cout <span class="token operator"><<</span> <span class="token string">"Searcher 初始化失败"</span> <span class="token operator"><<</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> </code></pre> <ol start="2"> <li>搭建http服务器:<br> 创建Server对象(<code>Server server;</code>),这是httplib头文件中所包含的类,我们直接包含头文件按即可使用。</li> </ol> <pre><code class="prism language-cpp">server<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span><span class="token string">"/searcher"</span><span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token operator">&</span>searcher<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token keyword">const</span> Request<span class="token operator">&</span> req<span class="token punctuation">,</span>Response<span class="token operator">&</span> resp<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">"query"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token comment">//如果请求参数不存在的话返回空</span> resp<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 comment">//设置响应数据 </span> <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> string query <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">"query"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//请求参数</span> string results<span class="token punctuation">;</span> searcher<span class="token punctuation">.</span><span class="token function">Search</span><span class="token punctuation">(</span>query<span class="token punctuation">,</span> <span class="token operator">&</span>results<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将请求参数传入进行搜索</span> resp<span class="token punctuation">.</span><span class="token function">set_content</span><span class="token punctuation">(</span>results<span class="token punctuation">,</span> <span class="token string">"application/json; charset=utf-8"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//将result搜索结果进行展示</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> </code></pre> <p>以函数来进行响应数据的展示,在我们浏览器上访问某页面后加上一个/searcher的url,如果检查url中的路径,发现正确即会返回相应的响应数据(即我们访问后,浏览器会发送一个HTTP GET请求,将我们设置好的响应数据展示上去);<br> 告诉服务器静态资源存放在wwwroot目录之中,之后通过服务器启动之后就可以通过http/127.0.0.1.10001/index.html来进行此页面的访问,当然了也不能够忘记了启动我们服务端的服务器,和我们socket编程中的listen设置被动套接字是一样的,直接使用<code>server.listen("0.0.0.0",10001);</code><br> 我也是设置了相关的query查询词,来表示我们所需要查询的内容,也就是说如果我们访问向filesystem的话,只需要在网页上输入<code>127.0.0.1.10001/searcher?query=filesystem</code>就表示我们所需要查找的关键词是filesystem!</p> <p>关于对<strong>html的实现</strong>,因为我自身没有学习过更多的关于html开发设计的内容,只有着一些在学校专业课中简单的设置基础,所以一些大的模块我也是模仿和百度别人的模块,之后将其改过来,做了一些相关的改正和调整,因此对于这一方面我没有办法给大家做过多的解析,因为好多知识我自己也不懂,所以我直接将其放在了GitHub上,里面的每一个注释我也是详细的写上去了。</p> <h1>项目难点和提升</h1> <p>对于搜索引擎项目来说,因基于boost文档的所以它的规模是比较小的,我们开发起来也是比较方便的,但是若是对于搜索引擎有着深度的兴趣的话,我们可以尝试更大一点的搜索引擎,那么我们就需要考虑到:</p> <ol> <li>支持更大的数据量的问题:也就需要使用“爬虫”方式来主动抓取页面的内容</li> <li>请求量更大:需要满足的搜索内容更加多更加广泛</li> <li>业务也会更加的复杂:需要更加严格的索引检验,更加准确的权重描述,更加丰富的过滤规则和更完备的调试接口</li> </ol> <p>在整个项目之中对于我来说最难的部分应该就属于索引模块里的分词,构建正排索引和倒排索引这三个部分了,在一开始时候我不太清楚分词可以直接使用cppjieba其自带的分词来实现的,当时也是自己进行一些想法,最后看看发现自己也是傻的可以;<br> 而重点的正排索引和倒排索引,在这一块的时候我也是真正的发挥了搜索一七年的作用,我直接搜索了一些关于搜索引擎的内容,设计开发思路从其中得到了关于正排索引和倒排索引的一些知识,才弥补了索引模块所欠缺的那些知识,到现在也是对其有着一个充分的认识。<br> 正排索引:根据文档id查找相关的文档内容<br> 倒排索引:根据文档内容查找相关的文档id</p> <p>还有一个可能会出错的点,那就是对于在搜索模块和索引模块中多次出现的一些unordered_map结构,倒排拉链和vector等结构的来回使用,可能会让大家有着一些混淆,如果大家可以将其稍微的写一些或者画一下,那么就会大致明白他们之间的一个关系,并且有着深刻的记忆了,知道他们每一部分都是做什么,且是为何这么做,是为了存储什么的。</p> <h1>结束语</h1> <p><mark>和我前面那个网络工具项目相比,这个的难度肯定是更大的,字数也是破万了,熬过了多少个夜晚才能够有这样的成绩,写到这里也算是我对整个项目的彻底完成了,真的可以说是非常的激动和欣慰了。<br> 虽说网络工具相对简单,但那也是相抵搜索引擎来说简单,可作为底层实现的网络工具,它的每一个步骤都需要我们自己手动进行却显得会更加的繁杂,而在搜索引擎这个大的项目上面,它更多的接口和处理函数我们可以发现是现成的,我们可以借用他们的一些实例来了解,并且之后将其运用到自己的一些项目之中。<br> 通过这一次的项目也是给了我一个全新的经验,让我明白一些项目其实没有我们所想的特别难,所有的成功都是一步步的走过来的,对于一些功能的实现我们可以更好的借用当前所拥有的基础和一些相关的模块来实现,并且一个完整的项目也是需要耗费更多的心血,在自己所不擅长的部分模块里,也应该多问几个为什么或者是多请教别人帮助,对于它才能够有更号的进步,当然也是希望这个项目可以帮助到和我一样在找工作的朋友,让你的秋招之路更加顺畅!(可以收藏起来慢慢研究哦)</mark></p> <p>项目的GitHub:SoEasy搜索引擎</p> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1559733346836221952"></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">你可能感兴趣的:(项目,搜索引擎,boost,搜索引擎,c++,html,http,boost)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1835514207114719232.htm" title="关于沟通这件事,项目经理不需要每次都面对面进行" target="_blank">关于沟通这件事,项目经理不需要每次都面对面进行</a> <span class="text-muted">流程大师兄</span> <div>很多项目经理都会遇到这样的问题,项目中由于事情太多,根本没有足够的时间去召开会议,那在这种情况下如何去有效地管理项目中的利益相关者?当然,不建议电子邮件也不需要开会的话,建议可以采取下面几种方式来形成有效的沟通,这几种方式可以帮助你努力的通过各种办法来保持和各方面的联系。项目经理首先要问自己几个问题,项目中哪些利益相关者是必须要进行沟通的?可以列出项目中所有的利益相关者清单,同时也整理出项目中哪些</div> </li> <li><a href="/article/1835513551142350848.htm" title="OC语言多界面传值五大方式" target="_blank">OC语言多界面传值五大方式</a> <span class="text-muted">Magnetic_h</span> <a class="tag" taget="_blank" href="/search/ios/1.htm">ios</a><a class="tag" taget="_blank" href="/search/ui/1.htm">ui</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/objective-c/1.htm">objective-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>前言在完成暑假仿写项目时,遇到了许多需要用到多界面传值的地方,这篇博客来总结一下比较常用的五种多界面传值的方式。属性传值属性传值一般用前一个界面向后一个界面传值,简单地说就是通过访问后一个视图控制器的属性来为它赋值,通过这个属性来做到从前一个界面向后一个界面传值。首先在后一个界面中定义属性@interfaceBViewController:UIViewController@propertyNSSt</div> </li> <li><a href="/article/1835512920797179904.htm" title="element实现动态路由+面包屑" target="_blank">element实现动态路由+面包屑</a> <span class="text-muted">软件技术NINI</span> <a class="tag" taget="_blank" href="/search/vue%E6%A1%88%E4%BE%8B/1.htm">vue案例</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>el-breadcrumb是ElementUI组件库中的一个面包屑导航组件,它用于显示当前页面的路径,帮助用户快速理解和导航到应用的各个部分。在Vue.js项目中,如果你已经安装了ElementUI,就可以很方便地使用el-breadcrumb组件。以下是一个基本的使用示例:安装ElementUI(如果你还没有安装的话):你可以通过npm或yarn来安装ElementUI。bash复制代码npmi</div> </li> <li><a href="/article/1835511912843014144.htm" title="理解Gunicorn:Python WSGI服务器的基石" target="_blank">理解Gunicorn:Python WSGI服务器的基石</a> <span class="text-muted">范范0825</span> <a class="tag" taget="_blank" href="/search/ipython/1.htm">ipython</a><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> <div>理解Gunicorn:PythonWSGI服务器的基石介绍Gunicorn,全称GreenUnicorn,是一个为PythonWSGI(WebServerGatewayInterface)应用设计的高效、轻量级HTTP服务器。作为PythonWeb应用部署的常用工具,Gunicorn以其高性能和易用性著称。本文将介绍Gunicorn的基本概念、安装和配置,帮助初学者快速上手。1.什么是Gunico</div> </li> <li><a href="/article/1835511030260789248.htm" title="c++ 的iostream 和 c++的stdio的区别和联系" target="_blank">c++ 的iostream 和 c++的stdio的区别和联系</a> <span class="text-muted">黄卷青灯77</span> <a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a><a class="tag" taget="_blank" href="/search/%E7%AE%97%E6%B3%95/1.htm">算法</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/iostream/1.htm">iostream</a><a class="tag" taget="_blank" href="/search/stdio/1.htm">stdio</a> <div>在C++中,iostream和C语言的stdio.h都是用于处理输入输出的库,但它们在设计、用法和功能上有许多不同。以下是两者的区别和联系:区别1.编程风格iostream(C++风格):C++标准库中的输入输出流类库,支持面向对象的输入输出操作。典型用法是cin(输入)和cout(输出),使用>操作符来处理数据。更加类型安全,支持用户自定义类型的输入输出。#includeintmain(){in</div> </li> <li><a href="/article/1835509770287673344.htm" title="swagger访问路径" target="_blank">swagger访问路径</a> <span class="text-muted">igotyback</span> <a class="tag" taget="_blank" href="/search/swagger/1.htm">swagger</a> <div>Swagger2.x版本访问地址:http://{ip}:{port}/{context-path}/swagger-ui.html{ip}是你的服务器IP地址。{port}是你的应用服务端口,通常为8080。{context-path}是你的应用上下文路径,如果应用部署在根路径下,则为空。Swagger3.x版本对于Swagger3.x版本(也称为OpenAPI3)访问地址:http://{ip</div> </li> <li><a href="/article/1835509643619692544.htm" title="如何在 Fork 的 GitHub 项目中保留自己的修改并同步上游更新?github_fork_update" target="_blank">如何在 Fork 的 GitHub 项目中保留自己的修改并同步上游更新?github_fork_update</a> <span class="text-muted">iBaoxing</span> <a class="tag" taget="_blank" href="/search/github/1.htm">github</a> <div>如何在Fork的GitHub项目中保留自己的修改并同步上游更新?在GitHub上Fork了一个项目后,你可能会对项目进行一些修改,同时原作者也在不断更新。如果想要在保留自己修改的基础上,同步原作者的最新更新,很多人会不知所措。本文将详细讲解如何在不丢失自己改动的情况下,将上游仓库的更新合并到自己的仓库中。问题描述假设你在GitHub上Fork了一个项目,并基于该项目做了一些修改,随后你发现原作者对</div> </li> <li><a href="/article/1835508130608410624.htm" title="html 中如何使用 uniapp 的部分方法" target="_blank">html 中如何使用 uniapp 的部分方法</a> <span class="text-muted">某公司摸鱼前端</span> <a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/uni-app/1.htm">uni-app</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>示例代码:Documentconsole.log(window);效果展示:好了,现在就可以uni.使用相关的方法了</div> </li> <li><a href="/article/1835508122383380480.htm" title="抖音乐买买怎么加入赚钱?赚钱方法是什么" target="_blank">抖音乐买买怎么加入赚钱?赚钱方法是什么</a> <span class="text-muted">测评君高省</span> <div>你会在抖音买东西吗?如果会,那么一定要免费注册一个乐买买,抖音直播间,橱窗,小视频里的小黄车买东西都可以返佣金!省下来都是自己的,分享还可以赚钱乐买买是好省旗下的抖音返佣平台,乐买买分析社交电商的价值,乐买买属于今年难得的副业项目风口机会,2019年错过做好省的搞钱的黄金时期,那么2022年千万别再错过乐买买至于我为何转到高省呢?当然是高省APP佣金更高,模式更好,终端用户不流失。【高省】是一个自</div> </li> <li><a href="/article/1835504218178416640.htm" title="Google earth studio 简介" target="_blank">Google earth studio 简介</a> <span class="text-muted">陟彼高冈yu</span> <a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a> <div>GoogleEarthStudio是一个基于Web的动画工具,专为创作使用GoogleEarth数据的动画和视频而设计。它利用了GoogleEarth强大的三维地图和卫星影像数据库,使用户能够轻松地创建逼真的地球动画、航拍视频和动态地图可视化。网址为https://www.google.com/earth/studio/。GoogleEarthStudio是一个基于Web的动画工具,专为创作使用G</div> </li> <li><a href="/article/1835499615491813376.htm" title="四章-32-点要素的聚合" target="_blank">四章-32-点要素的聚合</a> <span class="text-muted">彩云飘过</span> <div>本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers5.3.xapi。源码见1032.html,对应的官网示例https://openlayers.org/en/latest/examples/cluster.htmlhttps://openlayers.org/en/latest/examples/earthquake-clusters.</div> </li> <li><a href="/article/1835499052125483008.htm" title="Git常用命令-修改远程仓库地址" target="_blank">Git常用命令-修改远程仓库地址</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/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>查看远程仓库地址gitremote-v返回结果originhttps://git.coding.net/*****.git(fetch)originhttps://git.coding.net/*****.git(push)修改远程仓库地址gitremoteset-urloriginhttps://git.coding.net/*****.git先删除后增加远程仓库地址gitremotermori</div> </li> <li><a href="/article/1835498925755297792.htm" title="DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理" target="_blank">DIV+CSS+JavaScript技术制作网页(旅游主题网页设计与制作)云南大理</a> <span class="text-muted">STU学生网页设计</span> <a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/%E6%9C%9F%E6%9C%AB%E7%BD%91%E9%A1%B5%E4%BD%9C%E4%B8%9A/1.htm">期末网页作业</a><a class="tag" taget="_blank" href="/search/html%E9%9D%99%E6%80%81%E7%BD%91%E9%A1%B5/1.htm">html静态网页</a><a class="tag" taget="_blank" href="/search/html5%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">html5期末大作业</a><a class="tag" taget="_blank" href="/search/%E7%BD%91%E9%A1%B5%E8%AE%BE%E8%AE%A1/1.htm">网页设计</a><a class="tag" taget="_blank" href="/search/web%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web大作业</a> <div>️精彩专栏推荐作者主页:【进入主页—获取更多源码】web前端期末大作业:【HTML5网页期末作业(1000套)】程序员有趣的告白方式:【HTML七夕情人节表白网页制作(110套)】文章目录二、网站介绍三、网站效果▶️1.视频演示2.图片演示四、网站代码HTML结构代码CSS样式代码五、更多源码二、网站介绍网站布局方面:计划采用目前主流的、能兼容各大主流浏览器、显示效果稳定的浮动网页布局结构。网站程</div> </li> <li><a href="/article/1835497537369370624.htm" title="利用Requests Toolkit轻松完成HTTP请求" target="_blank">利用Requests Toolkit轻松完成HTTP请求</a> <span class="text-muted">nseejrukjhad</span> <a class="tag" taget="_blank" href="/search/http/1.htm">http</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><a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>RequestsToolkit的力量:轻松构建HTTP请求Agent在现代软件开发中,API请求是与外部服务交互的核心。RequestsToolkit提供了一种便捷的方式,帮助开发者构建自动化的HTTP请求Agent。本文旨在详细介绍RequestsToolkit的设置、使用和潜在挑战。引言RequestsToolkit是一个强大的工具包,可用于构建执行HTTP请求的智能代理。这对于想要自动化与外</div> </li> <li><a href="/article/1835496402042580992.htm" title="GitHub上克隆项目" target="_blank">GitHub上克隆项目</a> <span class="text-muted">bigbig猩猩</span> <a class="tag" taget="_blank" href="/search/github/1.htm">github</a> <div>从GitHub上克隆项目是一个简单且直接的过程,它允许你将远程仓库中的项目复制到你的本地计算机上,以便进行进一步的开发、测试或学习。以下是一个详细的步骤指南,帮助你从GitHub上克隆项目。一、准备工作1.安装Git在克隆GitHub项目之前,你需要在你的计算机上安装Git工具。Git是一个开源的分布式版本控制系统,用于跟踪和管理代码变更。你可以从Git的官方网站(https://git-scm.</div> </li> <li><a href="/article/1835496149843275776.htm" title="关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript" target="_blank">关于城市旅游的HTML网页设计——(旅游风景云南 5页)HTML+CSS+JavaScript</a> <span class="text-muted">二挡起步</span> <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/%E6%97%85%E6%B8%B8/1.htm">旅游</a><a class="tag" taget="_blank" href="/search/%E9%A3%8E%E6%99%AF/1.htm">风景</a> <div>⛵源码获取文末联系✈Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业|游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作|HTML期末大学生网页设计作业,Web大学生网页HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScrip</div> </li> <li><a href="/article/1835496148601761792.htm" title="HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动" target="_blank">HTML网页设计制作大作业(div+css) 云南我的家乡旅游景点 带文字滚动</a> <span class="text-muted">二挡起步</span> <a class="tag" taget="_blank" href="/search/web%E5%89%8D%E7%AB%AF%E6%9C%9F%E6%9C%AB%E5%A4%A7%E4%BD%9C%E4%B8%9A/1.htm">web前端期末大作业</a><a class="tag" taget="_blank" href="/search/web%E8%AE%BE%E8%AE%A1%E7%BD%91%E9%A1%B5%E8%A7%84%E5%88%92%E4%B8%8E%E8%AE%BE%E8%AE%A1/1.htm">web设计网页规划与设计</a><a class="tag" taget="_blank" href="/search/html/1.htm">html</a><a class="tag" taget="_blank" href="/search/css/1.htm">css</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/dreamweaver/1.htm">dreamweaver</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>Web前端开发技术描述网页设计题材,DIV+CSS布局制作,HTML+CSS网页设计期末课程大作业游景点介绍|旅游风景区|家乡介绍|等网站的设计与制作HTML期末大学生网页设计作业HTML:结构CSS:样式在操作方面上运用了html5和css3,采用了div+css结构、表单、超链接、浮动、绝对定位、相对定位、字体样式、引用视频等基础知识JavaScript:做与用户的交互行为文章目录前端学习路线</div> </li> <li><a href="/article/1835495170972413952.htm" title="git - Webhook让部署自动化" target="_blank">git - Webhook让部署自动化</a> <span class="text-muted">大猪大猪</span> <div>我们现在有一个需求,将项目打包上传到gitlab或者github后,程序能自动部署,不用手动地去服务器中进行项目更新并运行,如何做到?这里我们可以使用gitlab与github的挂钩,挂钩的原理就是,每当我们有请求到gitlab与github服务器时,这时他俩会根据我们配置的挂钩地扯进行访问,webhook挂钩程序会一直监听着某个端口请求,一但收到他们发过来的请求,这时就知道用户有请求提交了,这时</div> </li> <li><a href="/article/1835494258262503424.htm" title="【JS】执行时长(100分) |思路参考+代码解析(C++)" target="_blank">【JS】执行时长(100分) |思路参考+代码解析(C++)</a> <span class="text-muted">l939035548</span> <a class="tag" taget="_blank" href="/search/JS/1.htm">JS</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%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>题目为了充分发挥GPU算力,需要尽可能多的将任务交给GPU执行,现在有一个任务数组,数组元素表示在这1秒内新增的任务个数且每秒都有新增任务。假设GPU最多一次执行n个任务,一次执行耗时1秒,在保证GPU不空闲情况下,最少需要多长时间执行完成。题目输入第一个参数为GPU一次最多执行的任务个数,取值范围[1,10000]第二个参数为任务数组长度,取值范围[1,10000]第三个参数为任务数组,数字范围</div> </li> <li><a href="/article/1835493753557708800.htm" title="每日算法&面试题,大厂特训二十八天——第二十天(树)" target="_blank">每日算法&面试题,大厂特训二十八天——第二十天(树)</a> <span class="text-muted">肥学</span> <a class="tag" taget="_blank" href="/search/%E2%9A%A1%E7%AE%97%E6%B3%95%E9%A2%98%E2%9A%A1%E9%9D%A2%E8%AF%95%E9%A2%98%E6%AF%8F%E6%97%A5%E7%B2%BE%E8%BF%9B/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%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a> <div>目录标题导读算法特训二十八天面试题点击直接资料领取导读肥友们为了更好的去帮助新同学适应算法和面试题,最近我们开始进行专项突击一步一步来。上一期我们完成了动态规划二十一天现在我们进行下一项对各类算法进行二十八天的一个小总结。还在等什么快来一起肥学进行二十八天挑战吧!!特别介绍小白练手专栏,适合刚入手的新人欢迎订阅编程小白进阶python有趣练手项目里面包括了像《机器人尬聊》《恶搞程序》这样的有趣文章</div> </li> <li><a href="/article/1835493373906087936.htm" title="libyuv之linux编译" target="_blank">libyuv之linux编译</a> <span class="text-muted">jaronho</span> <a class="tag" taget="_blank" href="/search/Linux/1.htm">Linux</a><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>文章目录一、下载源码二、编译源码三、注意事项1、银河麒麟系统(aarch64)(1)解决armv8-a+dotprod+i8mm指令集支持问题(2)解决armv9-a+sve2指令集支持问题一、下载源码到GitHub网站下载https://github.com/lemenkov/libyuv源码,或者用直接用git克隆到本地,如:gitclonehttps://github.com/lemenko</div> </li> <li><a href="/article/1835493247179386880.htm" title="Faiss Tips:高效向量搜索与聚类的利器" target="_blank">Faiss Tips:高效向量搜索与聚类的利器</a> <span class="text-muted">焦习娜Samantha</span> <div>FaissTips:高效向量搜索与聚类的利器faiss_tipsSomeusefultipsforfaiss项目地址:https://gitcode.com/gh_mirrors/fa/faiss_tips项目介绍Faiss是由FacebookAIResearch开发的一个用于高效相似性搜索和密集向量聚类的库。它支持多种硬件平台,包括CPU和GPU,能够在海量数据集上实现快速的近似最近邻搜索(AN</div> </li> <li><a href="/article/1835492244547792896.htm" title="冬天短期的暴利小生意有哪些?那些小生意适合新手做?" target="_blank">冬天短期的暴利小生意有哪些?那些小生意适合新手做?</a> <span class="text-muted">一起高省</span> <div>短期生意不失为创业的一个商机,不过短期生意的商机是转瞬即逝的,而且这类生意也很难作为长期的生意去做,那冬天短期暴利小生意查看更多关于短期暴利小生意的文章有哪些呢?给大家先推荐一个2023年风口项目吧,真很不错的项目,全程零投资,当做副业来做真的很稳定,不管你什么阶层的人,或多或少都网购吧?你们知道网购是可以拿提成,拿返利,拿分佣的吗?你们知道很多优惠券群里面,天天群主和管理发一些商品吗?他们其实在</div> </li> <li><a href="/article/1835491859351302144.htm" title="Python 实现图片裁剪(附代码) | Python工具" target="_blank">Python 实现图片裁剪(附代码) | Python工具</a> <span class="text-muted">剑客阿良_ALiang</span> <div>前言本文提供将图片按照自定义尺寸进行裁剪的工具方法,一如既往的实用主义。环境依赖ffmpeg环境安装,可以参考我的另一篇文章:windowsffmpeg安装部署_阿良的博客-CSDN博客本文主要使用到的不是ffmpeg,而是ffprobe也在上面这篇文章中的zip包中。ffmpy安装:pipinstallffmpy-ihttps://pypi.douban.com/simple代码不废话了,上代码</div> </li> <li><a href="/article/1835490471032483840.htm" title="高级 ECharts 技巧:自定义图表主题与样式" target="_blank">高级 ECharts 技巧:自定义图表主题与样式</a> <span class="text-muted">SnowMan1993</span> <a class="tag" taget="_blank" href="/search/echarts/1.htm">echarts</a><a class="tag" taget="_blank" href="/search/%E4%BF%A1%E6%81%AF%E5%8F%AF%E8%A7%86%E5%8C%96/1.htm">信息可视化</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90/1.htm">数据分析</a> <div>ECharts是一个强大的数据可视化库,提供了多种内置主题和样式,但你也可以根据项目的设计需求,自定义图表的主题与样式。本文将介绍如何使用ECharts自定义图表主题,以提升数据可视化的吸引力和一致性。1.什么是ECharts主题?ECharts的主题是指定义图表样式的配置项,包括颜色、字体、线条样式等。通过预设主题,你可以快速更改图表的整体风格,而自定义主题则允许你在此基础上进行个性化设置。2.</div> </li> <li><a href="/article/1835490218409553920.htm" title="01-Git初识" target="_blank">01-Git初识</a> <span class="text-muted">Meereen</span> <a class="tag" taget="_blank" href="/search/Git/1.htm">Git</a><a class="tag" taget="_blank" href="/search/git/1.htm">git</a> <div>01-Git初识概念:一个免费开源,分布式的代码版本控制系统,帮助开发团队维护代码作用:记录代码内容。切换代码版本,多人开发时高效合并代码内容如何学:个人本机使用:Git基础命令和概念多人共享使用:团队开发同一个项目的代码版本管理Git配置用户信息配置:用户名和邮箱,应用在每次提交代码版本时表明自己的身份命令:查看git版本号git-v配置用户名gitconfig--globaluser.name</div> </li> <li><a href="/article/1835489207716507648.htm" title="基于CODESYS的多轴运动控制程序框架:逻辑与运动控制分离,快速开发灵活操作" target="_blank">基于CODESYS的多轴运动控制程序框架:逻辑与运动控制分离,快速开发灵活操作</a> <span class="text-muted">GPJnCrbBdl</span> <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> <div>基于codesys开发的多轴运动控制程序框架,将逻辑与运动控制分离,将单轴控制封装成功能块,对该功能块的操作包含了所有的单轴控制(归零、点动、相对定位、绝对定位、设置当前位置、伺服模式切换等等)。程序框架由主程序按照状态调用分归零模式、手动模式、自动模式、故障模式,程序状态的跳转都已完成,只需要根据不同的工艺要求完成所需的动作即可。变量的声明、地址的规划都严格按照C++的标准定义,能帮助开发者快速</div> </li> <li><a href="/article/1835489081480540160.htm" title="C++ | Leetcode C++题解之第409题最长回文串" target="_blank">C++ | Leetcode C++题解之第409题最长回文串</a> <span class="text-muted">Ddddddd_158</span> <a class="tag" taget="_blank" href="/search/%E7%BB%8F%E9%AA%8C%E5%88%86%E4%BA%AB/1.htm">经验分享</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a><a class="tag" taget="_blank" href="/search/Leetcode/1.htm">Leetcode</a><a class="tag" taget="_blank" href="/search/%E9%A2%98%E8%A7%A3/1.htm">题解</a> <div>题目:题解:classSolution{public:intlongestPalindrome(strings){unordered_mapcount;intans=0;for(charc:s)++count[c];for(autop:count){intv=p.second;ans+=v/2*2;if(v%2==1andans%2==0)++ans;}returnans;}};</div> </li> <li><a href="/article/1835488955101966336.htm" title="C++菜鸟教程 - 从入门到精通 第二节" target="_blank">C++菜鸟教程 - 从入门到精通 第二节</a> <span class="text-muted">DreamByte</span> <a class="tag" taget="_blank" href="/search/c%2B%2B/1.htm">c++</a> <div>一.上节课的补充(数据类型)1.前言继上节课,我们主要讲解了输入,输出和运算符,我们现在来补充一下数据类型的知识上节课遗漏了这个知识点,非常的抱歉顺便说一下,博主要上高中了,更新会慢,2-4周更新一次对了,正好赶上中秋节,小编跟大家说一句:中秋节快乐!2.int类型上节课,我们其实只用了int类型int类型,是整数类型,它们存贮的是整数,不能存小数(浮点数)定义变量的方式很简单inta;//定义一</div> </li> <li><a href="/article/1835488702881689600.htm" title="Faiss:高效相似性搜索与聚类的利器" target="_blank">Faiss:高效相似性搜索与聚类的利器</a> <span class="text-muted">网络·魚</span> <a class="tag" taget="_blank" href="/search/%E5%A4%A7%E6%95%B0%E6%8D%AE/1.htm">大数据</a><a class="tag" taget="_blank" href="/search/faiss/1.htm">faiss</a> <div>Faiss是一个针对大规模向量集合的相似性搜索库,由FacebookAIResearch开发。它提供了一系列高效的算法和数据结构,用于加速向量之间的相似性搜索,特别是在大规模数据集上。本文将介绍Faiss的原理、核心功能以及如何在实际项目中使用它。Faiss原理:近似最近邻搜索:Faiss的核心功能之一是近似最近邻搜索,它能够高效地在大规模数据集中找到与给定查询向量最相似的向量。这种搜索是近似的,</div> </li> <li><a href="/article/11.htm" title="VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite" target="_blank">VMware Workstation 11 或者 VMware Player 7安装MAC OS X 10.10 Yosemite</a> <span class="text-muted">iwindyforest</span> <a class="tag" taget="_blank" href="/search/vmware/1.htm">vmware</a><a class="tag" taget="_blank" href="/search/mac+os/1.htm">mac os</a><a class="tag" taget="_blank" href="/search/10.10/1.htm">10.10</a><a class="tag" taget="_blank" href="/search/workstation/1.htm">workstation</a><a class="tag" taget="_blank" href="/search/player/1.htm">player</a> <div>最近尝试了下VMware下安装MacOS 系统, 安装过程中发现网上可供参考的文章都是VMware Workstation 10以下, MacOS X 10.9以下的文章, 只能提供大概的思路, 但是实际安装起来由于版本问题, 走了不少弯路, 所以我尝试写以下总结, 希望能给有兴趣安装OSX的人提供一点帮助。     写在前面的话: 其实安装好后发现, 由于我的th</div> </li> <li><a href="/article/138.htm" title="关于《基于模型驱动的B/S在线开发平台》源代码开源的疑虑?" target="_blank">关于《基于模型驱动的B/S在线开发平台》源代码开源的疑虑?</a> <span class="text-muted">deathwknight</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%A1%86%E6%9E%B6/1.htm">框架</a> <div>本人从学习Java开发到现在已有10年整,从一个要自学 java买成javascript的小菜鸟,成长为只会java和javascript语言的老菜鸟(个人邮箱:deathwknight@163.com) 一路走来,跌跌撞撞。用自己的三年多业余时间,瞎搞一个小东西(基于模型驱动的B/S在线开发平台,非MVC框架、非代码生成)。希望与大家一起分享,同时有许些疑虑,希望有人可以交流下 平台</div> </li> <li><a href="/article/265.htm" title="如何把maven项目转成web项目" target="_blank">如何把maven项目转成web项目</a> <span class="text-muted">Kai_Ge</span> <a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a><a class="tag" taget="_blank" href="/search/MyEclipse/1.htm">MyEclipse</a> <div>创建Web工程,使用eclipse ee创建maven web工程 1.右键项目,选择Project Facets,点击Convert to faceted from 2.更改Dynamic Web Module的Version为2.5.(3.0为Java7的,Tomcat6不支持). 如果提示错误,可能需要在Java Compiler设置Compiler compl</div> </li> <li><a href="/article/392.htm" title="主管???" target="_blank">主管???</a> <span class="text-muted">Array_06</span> <a class="tag" taget="_blank" href="/search/%E5%B7%A5%E4%BD%9C/1.htm">工作</a> <div>转载:http://www.blogjava.net/fastzch/archive/2010/11/25/339054.html 很久以前跟同事参加的培训,同事整理得很详细,必须得转! 前段时间,公司有组织中高阶主管及其培养干部进行了为期三天的管理训练培训。三天的课程下来,虽然内容较多,因对老师三天来的课程内容深有感触,故借着整理学习心得的机会,将三天来的培训课程做了一个</div> </li> <li><a href="/article/519.htm" title="python内置函数大全" target="_blank">python内置函数大全</a> <span class="text-muted">2002wmj</span> <a class="tag" taget="_blank" href="/search/python/1.htm">python</a> <div>最近一直在看python的document,打算在基础方面重点看一下python的keyword、Build-in Function、Build-in Constants、Build-in Types、Build-in Exception这四个方面,其实在看的时候发现整个《The Python Standard Library》章节都是很不错的,其中描述了很多不错的主题。先把Build-in Fu</div> </li> <li><a href="/article/646.htm" title="JSP页面通过JQUERY合并行" target="_blank">JSP页面通过JQUERY合并行</a> <span class="text-muted">357029540</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a><a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a> <div>在写程序的过程中我们难免会遇到在页面上合并单元行的情况,如图所示 如果对于会的同学可能很简单,但是对没有思路的同学来说还是比较麻烦的,提供一下用JQUERY实现的参考代码 function mergeCell(){         var trs = $("#table tr"); &nb</div> </li> <li><a href="/article/773.htm" title="Java基础" target="_blank">Java基础</a> <span class="text-muted">冰天百华</span> <a class="tag" taget="_blank" href="/search/java%E5%9F%BA%E7%A1%80/1.htm">java基础</a> <div>学习函数式编程 package base; import java.text.DecimalFormat; public class Main { public static void main(String[] args) { // Integer a = 4; // Double aa = (double)a / 100000; // Decimal</div> </li> <li><a href="/article/900.htm" title="unix时间戳相互转换" target="_blank">unix时间戳相互转换</a> <span class="text-muted">adminjun</span> <a class="tag" taget="_blank" href="/search/%E8%BD%AC%E6%8D%A2/1.htm">转换</a><a class="tag" taget="_blank" href="/search/unix/1.htm">unix</a><a class="tag" taget="_blank" href="/search/%E6%97%B6%E9%97%B4%E6%88%B3/1.htm">时间戳</a> <div>如何在不同编程语言中获取现在的Unix时间戳(Unix timestamp)? Java time JavaScript Math.round(new Date().getTime()/1000) getTime()返回数值的单位是毫秒 Microsoft .NET / C# epoch = (DateTime.Now.ToUniversalTime().Ticks - 62135</div> </li> <li><a href="/article/1027.htm" title="作为一个合格程序员该做的事" target="_blank">作为一个合格程序员该做的事</a> <span class="text-muted">aijuans</span> <a class="tag" taget="_blank" href="/search/%E7%A8%8B%E5%BA%8F%E5%91%98/1.htm">程序员</a> <div>作为一个合格程序员每天该做的事 1、总结自己一天任务的完成情况 最好的方式是写工作日志,把自己今天完成了什么事情,遇见了什么问题都记录下来,日后翻看好处多多 2、考虑自己明天应该做的主要工作 把明天要做的事情列出来,并按照优先级排列,第二天应该把自己效率最高的时间分配给最重要的工作 3、考虑自己一天工作中失误的地方,并想出避免下一次再犯的方法 出错不要紧,最重</div> </li> <li><a href="/article/1154.htm" title="由html5视频播放引发的总结" target="_blank">由html5视频播放引发的总结</a> <span class="text-muted">ayaoxinchao</span> <a class="tag" taget="_blank" href="/search/html5/1.htm">html5</a><a class="tag" taget="_blank" href="/search/%E8%A7%86%E9%A2%91/1.htm">视频</a><a class="tag" taget="_blank" href="/search/video/1.htm">video</a> <div>前言   项目中存在视频播放的功能,前期设计是以flash播放器播放视频的。但是现在由于需要兼容苹果的设备,必须采用html5的方式来播放视频。我就出于兴趣对html5播放视频做了简单的了解,不了解不知道,水真是很深。本文所记录的知识一些浅尝辄止的知识,说起来很惭愧。   视频结构   本该直接介绍html5的<video>的,但鉴于本人对视频</div> </li> <li><a href="/article/1281.htm" title="解决httpclient访问自签名https报javax.net.ssl.SSLHandshakeException: sun.security.validat" target="_blank">解决httpclient访问自签名https报javax.net.ssl.SSLHandshakeException: sun.security.validat</a> <span class="text-muted">bewithme</span> <a class="tag" taget="_blank" href="/search/httpclient/1.htm">httpclient</a> <div>     如果你构建了一个https协议的站点,而此站点的安全证书并不是合法的第三方证书颁发机构所签发,那么你用httpclient去访问此站点会报如下错误   javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path bu</div> </li> <li><a href="/article/1408.htm" title="Jedis连接池的入门级使用" target="_blank">Jedis连接池的入门级使用</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/redis/1.htm">redis</a><a class="tag" taget="_blank" href="/search/redis%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">redis数据库</a><a class="tag" taget="_blank" href="/search/jedis/1.htm">jedis</a> <div>Jedis连接池操作步骤如下:         a.获取Jedis实例需要从JedisPool中获取;         b.用完Jedis实例需要返还给JedisPool;         c.如果Jedis在使用过程中出错,则也需要还给JedisPool; packag</div> </li> <li><a href="/article/1535.htm" title="变与不变" target="_blank">变与不变</a> <span class="text-muted">bingyingao</span> <a class="tag" taget="_blank" href="/search/%E4%B8%8D%E5%8F%98/1.htm">不变</a><a class="tag" taget="_blank" href="/search/%E5%8F%98/1.htm">变</a><a class="tag" taget="_blank" href="/search/%E4%BA%B2%E6%83%85%E6%B0%B8%E6%81%92/1.htm">亲情永恒</a> <div>变与不变    周末骑车转到了五年前租住的小区,曾经最爱吃的西北面馆、江西水饺、手工拉面早已不在,    各种店铺都换了好几茬,这些是变的。    三年前还很流行的一款手机在今天看起来已经落后的不像样子。    三年前还运行的好好的一家公司,今天也已经不复存在。    一座座高楼拔地而起,</div> </li> <li><a href="/article/1662.htm" title="【Scala十】Scala核心四:集合框架之List" target="_blank">【Scala十】Scala核心四:集合框架之List</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a> <div>Spark的RDD作为一个分布式不可变的数据集合,它提供的转换操作,很多是借鉴于Scala的集合框架提供的一些函数,因此,有必要对Scala的集合进行详细的了解   1. 泛型集合都是协变的,对于List而言,如果B是A的子类,那么List[B]也是List[A]的子类,即可以把List[B]的实例赋值给List[A]变量   2. 给变量赋值(注意val关键字,a,b</div> </li> <li><a href="/article/1789.htm" title="Nested Functions in C" target="_blank">Nested Functions in C</a> <span class="text-muted">bookjovi</span> <a class="tag" taget="_blank" href="/search/c/1.htm">c</a><a class="tag" taget="_blank" href="/search/closure/1.htm">closure</a> <div>  Nested Functions 又称closure,属于functional language中的概念,一直以为C中是不支持closure的,现在看来我错了,不过C标准中是不支持的,而GCC支持。   既然GCC支持了closure,那么 lexical scoping自然也支持了,同时在C中label也是可以在nested functions中自由跳转的</div> </li> <li><a href="/article/1916.htm" title="Java-Collections Framework学习与总结-WeakHashMap" target="_blank">Java-Collections Framework学习与总结-WeakHashMap</a> <span class="text-muted">BrokenDreams</span> <a class="tag" taget="_blank" href="/search/Collections/1.htm">Collections</a> <div>        总结这个类之前,首先看一下Java引用的相关知识。Java的引用分为四种:强引用、软引用、弱引用和虚引用。         强引用:就是常见的代码中的引用,如Object o = new Object();存在强引用的对象不会被垃圾收集</div> </li> <li><a href="/article/2043.htm" title="读《研磨设计模式》-代码笔记-解释器模式-Interpret" target="_blank">读《研磨设计模式》-代码笔记-解释器模式-Interpret</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/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a> <div>声明: 本文只为方便我个人查阅和理解,详细的分析以及源代码请移步 原作者的博客http://chjavach.iteye.com/ package design.pattern; /* * 解释器(Interpreter)模式的意图是可以按照自己定义的组合规则集合来组合可执行对象 * * 代码示例实现XML里面1.读取单个元素的值 2.读取单个属性的值 * 多</div> </li> <li><a href="/article/2170.htm" title="After Effects操作&快捷键" target="_blank">After Effects操作&快捷键</a> <span class="text-muted">cherishLC</span> <a class="tag" taget="_blank" href="/search/After+Effects/1.htm">After Effects</a> <div>1、快捷键官方文档 中文版:https://helpx.adobe.com/cn/after-effects/using/keyboard-shortcuts-reference.html 英文版:https://helpx.adobe.com/after-effects/using/keyboard-shortcuts-reference.html 2、常用快捷键</div> </li> <li><a href="/article/2297.htm" title="Maven 常用命令" target="_blank">Maven 常用命令</a> <span class="text-muted">crabdave</span> <a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a> <div>Maven 常用命令   mvn archetype:generate mvn install mvn clean mvn clean complie mvn clean test mvn clean install mvn clean package mvn test mvn package mvn site   mvn dependency:res</div> </li> <li><a href="/article/2424.htm" title="shell bad substitution" target="_blank">shell bad substitution</a> <span class="text-muted">daizj</span> <a class="tag" taget="_blank" href="/search/shell/1.htm">shell</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a> <div>#!/bin/sh /data/script/common/run_cmd.exp 192.168.13.168 "impala-shell -islave4 -q 'insert OVERWRITE table imeis.${tableName} select ${selectFields}, ds, fnv_hash(concat(cast(ds as string), im</div> </li> <li><a href="/article/2551.htm" title="Java SE 第二讲(原生数据类型 Primitive Data Type)" target="_blank">Java SE 第二讲(原生数据类型 Primitive Data Type)</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>Java SE  第二讲: 1.   Windows: notepad, editplus, ultraedit, gvim Linux: vi, vim, gedit 2.   Java 中的数据类型分为两大类: 1)原生数据类型  (Primitive Data Type) 2)引用类型(对象类型)  (R</div> </li> <li><a href="/article/2678.htm" title="CGridView中实现批量删除" target="_blank">CGridView中实现批量删除</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/yii/1.htm">yii</a> <div>1,CGridView中的columns添加 array( 'selectableRows' => 2, 'footer' => '<button type="button" onclick="GetCheckbox();" style=&</div> </li> <li><a href="/article/2805.htm" title="Java中泛型的各种使用" target="_blank">Java中泛型的各种使用</a> <span class="text-muted">dyy_gusi</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%B3%9B%E5%9E%8B/1.htm">泛型</a> <div>Java中的泛型的使用:1.普通的泛型使用 在使用类的时候后面的<>中的类型就是我们确定的类型。 public class MyClass1<T> {//此处定义的泛型是T private T var; public T getVar() { return var; } public void setVa</div> </li> <li><a href="/article/2932.htm" title="Web开发技术十年发展历程" target="_blank">Web开发技术十年发展历程</a> <span class="text-muted">gcq511120594</span> <a class="tag" taget="_blank" href="/search/Web/1.htm">Web</a><a class="tag" taget="_blank" href="/search/%E6%B5%8F%E8%A7%88%E5%99%A8/1.htm">浏览器</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/1.htm">数据挖掘</a> <div>回顾web开发技术这十年发展历程: Ajax 03年的时候我上六年级,那时候网吧刚在小县城的角落萌生。传奇,大话西游第一代网游一时风靡。我抱着试一试的心态给了网吧老板两块钱想申请个号玩玩,然后接下来的一个小时我一直在,注,册,账,号。 彼时网吧用的512k的带宽,注册的时候,填了一堆信息,提交,页面跳转,嘣,”您填写的信息有误,请重填”。然后跳转回注册页面,以此循环。我现在时常想,如果当时a</div> </li> <li><a href="/article/3059.htm" title="openSession()与getCurrentSession()区别:" target="_blank">openSession()与getCurrentSession()区别:</a> <span class="text-muted">hetongfei</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/DAO/1.htm">DAO</a><a class="tag" taget="_blank" href="/search/Hibernate/1.htm">Hibernate</a> <div>来自 http://blog.csdn.net/dy511/article/details/6166134 1.getCurrentSession创建的session会和绑定到当前线程,而openSession不会。 2. getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭,而openSession必须手动关闭。 这里getCurrentSession本地事务(本地</div> </li> <li><a href="/article/3186.htm" title="第一章 安装Nginx+Lua开发环境" target="_blank">第一章 安装Nginx+Lua开发环境</a> <span class="text-muted">jinnianshilongnian</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/lua/1.htm">lua</a><a class="tag" taget="_blank" href="/search/openresty/1.htm">openresty</a> <div>首先我们选择使用OpenResty,其是由Nginx核心加很多第三方模块组成,其最大的亮点是默认集成了Lua开发环境,使得Nginx可以作为一个Web Server使用。借助于Nginx的事件驱动模型和非阻塞IO,可以实现高性能的Web应用程序。而且OpenResty提供了大量组件如Mysql、Redis、Memcached等等,使在Nginx上开发Web应用更方便更简单。目前在京东如实时价格、秒</div> </li> <li><a href="/article/3313.htm" title="HSQLDB In-Process方式访问内存数据库" target="_blank">HSQLDB In-Process方式访问内存数据库</a> <span class="text-muted">liyonghui160com</span> <div>    HSQLDB一大特色就是能够在内存中建立数据库,当然它也能将这些内存数据库保存到文件中以便实现真正的持久化。   先睹为快!   下面是一个In-Process方式访问内存数据库的代码示例:     下面代码需要引入hsqldb.jar包 (hsqldb-2.2.8)   import java.s</div> </li> <li><a href="/article/3440.htm" title="Java线程的5个使用技巧" target="_blank">Java线程的5个使用技巧</a> <span class="text-muted">pda158</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/1.htm">数据结构</a> <div>Java线程有哪些不太为人所知的技巧与用法?   萝卜白菜各有所爱。像我就喜欢Java。学无止境,这也是我喜欢它的一个原因。日常 工作中你所用到的工具,通常都有些你从来没有了解过的东西,比方说某个方法或者是一些有趣的用法。比如说线程。没错,就是线程。或者确切说是Thread这个类。当我们在构建高可扩展性系统的时候,通常会面临各种各样的并发编程的问题,不过我们现在所要讲的可能会略有不同。 </div> </li> <li><a href="/article/3567.htm" title="开发资源大整合:编程语言篇——JavaScript(1)" target="_blank">开发资源大整合:编程语言篇——JavaScript(1)</a> <span class="text-muted">shoothao</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>概述:本系列的资源整合来自于github中各个领域的大牛,来收藏你感兴趣的东西吧。     程序包管理器   管理javascript库并提供对这些库的快速使用与打包的服务。 Bower - 用于web的程序包管理。 component - 用于客户端的程序包管理,构建更好的web应用程序。 spm - 全新的静态的文件包管</div> </li> <li><a href="/article/3694.htm" title="避免使用终结函数" target="_blank">避免使用终结函数</a> <span class="text-muted">vahoa.ma</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/jvm/1.htm">jvm</a><a class="tag" taget="_blank" href="/search/C%2B%2B/1.htm">C++</a> <div>终结函数(finalizer)通常是不可预测的,常常也是很危险的,一般情况下不是必要的。使用终结函数会导致不稳定的行为、更差的性能,以及带来移植性问题。不要把终结函数当做C++中的析构函数(destructors)的对应物。       我自己总结了一下这一条的综合性结论是这样的: 1)在涉及使用资源,使用完毕后要释放资源的情形下,首先要用一个显示的方</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>