北大天网搜索引擎TSE分析及完全注释[3]来到关键字分词及相关性分析程序

本文主要是介绍北大天网搜索引擎TSE分析及完全注释[3]来到关键字分词及相关性分析程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有前面注释我们可以知道查询关键字和字典文件准备好好后,将进入用户关键字分词阶段

//TSESearch.cpp中:

view plain copy to clipboard print ?
  1. CHzSeg iHzSeg;      //include ChSeg/HzSeg.h   
  2.   
  3. //   
  4. iQuery.m_sSegQuery = iHzSeg.SegmentSentenceMM(iDict, iQuery.m_sQuery);  //将get到的查询变量分词分成 "我/        爱/      你们/ 的/      格式"   
  5.   
  6. vector<STRING></STRING> vecTerm;   
  7. iQuery.ParseQuery(vecTerm);     //将以"/"划分开的关键字一一顺序放入一个向量容器中   
  8.   
  9. set<STRING></STRING> setRelevantRst;    
  10. iQuery.GetRelevantRst(vecTerm, mapBuckets, setRelevantRst);    
  11.   
  12. gettimeofday(&end_tv,&tz);   
  13. // search end   
  14. //搜索完毕  
	CHzSeg iHzSeg;		//include ChSeg/HzSeg.h
//
iQuery.m_sSegQuery = iHzSeg.SegmentSentenceMM(iDict, iQuery.m_sQuery);	//将get到的查询变量分词分成 "我/		爱/		你们/	的/		格式"
vector vecTerm;
iQuery.ParseQuery(vecTerm);		//将以"/"划分开的关键字一一顺序放入一个向量容器中
set setRelevantRst; 
iQuery.GetRelevantRst(vecTerm, mapBuckets, setRelevantRst); 
gettimeofday(&end_tv,&tz);
// search end
//搜索完毕
view plain copy to clipboard print ?
  1. 看CHzSeg 中的这个方法  
看CHzSeg 中的这个方法
view plain copy to clipboard print ?
  1. //ChSeg/HzSeg.h  
//ChSeg/HzSeg.h
view plain copy to clipboard print ?
  1. /**   
  2.  * 程序翻译说明   
  3.  * 进一步净化数据,转换汉字   
  4.  * @access  public   
  5.  * @param   CDict, string 参数的汉字说明:字典,查询字符串   
  6.  * @return  string 0   
  7.  */   
  8. // process a sentence before segmentation   
  9. //在分词前处理句子   
  10. string CHzSeg::SegmentSentenceMM (CDict &dict, string s1) const   
  11. {   
  12.     string s2="";   
  13.     unsigned int i,len;   
  14.   
  15.     while (!s1.empty())    
  16.     {   
  17.         unsigned char ch=(unsigned char) s1[0];   
  18.         if(ch<128)    
  19.         { // deal with ASCII   
  20.             i=1;   
  21.             len = s1.size();   
  22.             while (i<LEN len="s1.length();" i="0;" 中文标点等非汉字字符="" if="" else="" yhf="" s1="s1.substr(i);" by="" added="" ch="=13)" s2="" cr=""></LEN>=161)   
  23.               && (!((unsigned char)s1[i]==161 && ((unsigned char)s1[i+1]>=162 && (unsigned char)s1[i+1]<=168)))   
  24.               && (!((unsigned char)s1[i]==161 && ((unsigned char)s1[i+1]>=171 && (unsigned char)s1[i+1]<=191)))   
  25.               && (!((unsigned char)s1[i]==163 && ((unsigned char)s1[i+1]==172 || (unsigned char)s1[i+1]==161)    
  26.               || (unsigned char)s1[i+1]==168 || (unsigned char)s1[i+1]==169 || (unsigned char)s1[i+1]==186   
  27.               || (unsigned char)s1[i+1]==187 || (unsigned char)s1[i+1]==191)))    
  28.                 {    
  29.                     ii=i+2; // 假定没有半个汉字   
  30.                 }   
  31.   
  32.                 if (i==0) ii=i+2;   
  33.   
  34.                 // 不处理中文空格   
  35.                 if (!(ch==161 && (unsigned char)s1[1]==161))    
  36.                 {    
  37.                     if (i <= s1.size())  // yhf   
  38.                         // 其他的非汉字双字节字符可能连续输出   
  39.                         s2 += s1.substr(0, i) + SEPARATOR;    
  40.                     else break; // yhf   
  41.                 }   
  42.   
  43.                 if (i <= s1.size())  // yhf   
  44.                     s1s1=s1.substr(i);   
  45.                 else break;     //yhf   
  46.   
  47.                 continue;   
  48.             }   
  49.         }   
  50.        
  51.   
  52.     // 以下处理汉字串   
  53.   
  54.         i = 2;   
  55.         len = s1.length();   
  56.   
  57.         while(i<LEN></LEN>=176)    
  58. //    while(i<LEN></LEN>=128 && (unsigned char)s1[i]!=161)   
  59.             i+=2;   
  60.   
  61.         s2+=SegmentHzStrMM(dict, s1.substr(0,i));   
  62.   
  63.         if (i <= len)    // yhf   
  64.             s1s1=s1.substr(i);   
  65.         else break; // yhf   
  66.     }   
  67.   
  68.     return s2;   
  69. }  
/**
* 程序翻译说明
* 进一步净化数据,转换汉字
* @access  public
* @param   CDict, string 参数的汉字说明:字典,查询字符串
* @return  string 0
*/
// process a sentence before segmentation
//在分词前处理句子
string CHzSeg::SegmentSentenceMM (CDict &dict, string s1) const
{
string s2="";
unsigned int i,len;
while (!s1.empty()) 
{
unsigned char ch=(unsigned char) s1[0];
if(ch<128) 
{ // deal with ASCII
i=1;
len = s1.size();
while (i=161)
&& (!((unsigned char)s1[i]==161 && ((unsigned char)s1[i+1]>=162 && (unsigned char)s1[i+1]<=168)))
&& (!((unsigned char)s1[i]==161 && ((unsigned char)s1[i+1]>=171 && (unsigned char)s1[i+1]<=191)))
&& (!((unsigned char)s1[i]==163 && ((unsigned char)s1[i+1]==172 || (unsigned char)s1[i+1]==161) 
|| (unsigned char)s1[i+1]==168 || (unsigned char)s1[i+1]==169 || (unsigned char)s1[i+1]==186
|| (unsigned char)s1[i+1]==187 || (unsigned char)s1[i+1]==191))) 
{ 
i=i+2; // 假定没有半个汉字
}
if (i==0) i=i+2;
// 不处理中文空格
if (!(ch==161 && (unsigned char)s1[1]==161)) 
{ 
if (i <= s1.size())	// yhf
// 其他的非汉字双字节字符可能连续输出
s2 += s1.substr(0, i) + SEPARATOR; 
else break; // yhf
}
if (i <= s1.size())	// yhf
s1=s1.substr(i);
else break;		//yhf
continue;
}
}
// 以下处理汉字串
i = 2;
len = s1.length();
while(i=176) 
//    while(i=128 && (unsigned char)s1[i]!=161)
i+=2;
s2+=SegmentHzStrMM(dict, s1.substr(0,i));
if (i <= len)	// yhf
s1=s1.substr(i);
else break;	// yhf
}
return s2;
}
view plain copy to clipboard print ?
  1.    
 
view plain copy to clipboard print ?
  1. //Query.cpp  
//Query.cpp
view plain copy to clipboard print ?
  1. <PRE class=csharp name="code">/**   
  2.  * 程序翻译说明   
  3.  * 将以"/"划分开的关键字一一顺序放入一个向量容器中   
  4.  *   
  5.  * @access  public   
  6.  * @param   vector<STRING></STRING> 参数的汉字说明:向量容器   
  7.  * @return  void   
  8.  */   
  9. void CQuery::ParseQuery(vector<STRING></STRING> &vecTerm)   
  10. {   
  11.     string::size_type idx;    
  12.     while ( (idx = m_sSegQuery.find("/  ")) != string::npos ) {    
  13.         vecTerm.push_back(m_sSegQuery.substr(0,idx));    
  14.         m_sSegQuerym_sSegQuery = m_sSegQuery.substr(idx+3);    
  15.     }   
  16. }   
  17. </PRE>  
  18. <PRE class=csharp name="code"> </PRE>  
  19. <PRE class=csharp name="code"><PRE class=csharp name="code">/**   
  20.  * 程序翻译说明   
  21.  * 相关性分析查询,构造结果集合setRelevantRst //瓶颈所在   
  22.  *   
  23.  * @access  public   
  24.  * @param   vector<STRING></STRING> map set<STRING></STRING> 参数的汉字说明: 用户提交关键字的分词组,倒排索引映射,相关性结果集合   
  25.  * @return  string 0   
  26.  */   
  27. bool CQuery::GetRelevantRst   
  28. (   
  29.     vector<STRING></STRING> &vecTerm,    
  30.     map &mapBuckets,    
  31.     set<STRING></STRING> &setRelevantRst   
  32. ) const   
  33. {   
  34.     set<STRING></STRING> setSRst;   
  35.   
  36.     bool bFirst=true;   
  37.     vector<STRING></STRING>::iterator itTerm = vecTerm.begin();   
  38.   
  39.     for ( ; itTerm != vecTerm.end(); ++itTerm )   
  40.     {   
  41.   
  42.         setSRst.clear();   
  43.         copy(setRelevantRst.begin(), setRelevantRst.end(), inserter(setSRst,setSRst.begin()));   
  44.   
  45.         map mapRstDoc;   
  46.         string docid;   
  47.         int doccnt;   
  48.   
  49.         map::iterator itBuckets = mapBuckets.find(*itTerm);   
  50.         if (itBuckets != mapBuckets.end())   
  51.         {   
  52.             string strBucket = (*itBuckets).second;   
  53.             string::size_type idx;   
  54.             idx = strBucket.find_first_not_of(" ");   
  55.             strBucketstrBucket = strBucket.substr(idx);   
  56.   
  57.             while ( (idx = strBucket.find(" ")) != string::npos )    
  58.             {   
  59.                 docid = strBucket.substr(0,idx);   
  60.                 doccnt = 0;   
  61.   
  62.                 if (docid.empty()) continue;   
  63.   
  64.                 map::iterator it = mapRstDoc.find(docid);   
  65.                 if ( it != mapRstDoc.end() )   
  66.                 {   
  67.                     doccnt = (*it).second + 1;   
  68.                     mapRstDoc.erase(it);   
  69.                 }   
  70.                 mapRstDoc.insert( pair(docid,doccnt) );   
  71.   
  72.                 strBucketstrBucket = strBucket.substr(idx+1);   
  73.             }   
  74.   
  75.             // remember the last one   
  76.             docid = strBucket;   
  77.             doccnt = 0;   
  78.             map::iterator it = mapRstDoc.find(docid);   
  79.             if ( it != mapRstDoc.end() )   
  80.             {   
  81.                 doccnt = (*it).second + 1;   
  82.                 mapRstDoc.erase(it);   
  83.             }   
  84.             mapRstDoc.insert( pair(docid,doccnt) );   
  85.         }   
  86.   
  87.         // sort by term frequencty   
  88.         multimap > newRstDoc;   
  89.         map::iterator it0 = mapRstDoc.begin();   
  90.         for ( ; it0 != mapRstDoc.end(); ++it0 ){   
  91.             newRstDoc.insert( pair((*it0).second,(*it0).first) );   
  92.         }   
  93.   
  94.         multimap::iterator itNewRstDoc = newRstDoc.begin();   
  95.         setRelevantRst.clear();   
  96.         for ( ; itNewRstDoc != newRstDoc.end(); ++itNewRstDoc ){   
  97.             string docid = (*itNewRstDoc).second;   
  98.   
  99.             if (bFirst==true) {   
  100.                 setRelevantRst.insert(docid);   
  101.                 continue;   
  102.             }   
  103.   
  104.             if ( setSRst.find(docid) != setSRst.end() ){       
  105.                 setRelevantRst.insert(docid);   
  106.             }   
  107.         }   
  108.   
  109.         //cout << "setRelevantRst.size(): " << setRelevantRst.size() << "<BR>";   
  110.         bFirst = false;   
  111.     }   
  112.     return true;   
  113. }</PRE>  
  114. </PRE>  
  115. 接下来的就是现实了,前面都只是处理数据得到 setRelevantRst 这个查询结构集合,这里就不多说了下面就和php之类的脚本语言差不多,格式化结果集合并显示出来。  
view plaincopy to clipboardprint?
  1. /**  
  2.  * 程序翻译说明  
  3.  * 将以"/"划分开的关键字一一顺序放入一个向量容器中  
  4.  *  
  5.  * @access  public  
  6.  * @param   vector<STRING></STRING> 参数的汉字说明:向量容器  
  7.  * @return  void  
  8.  */  
  9. void CQuery::ParseQuery(vector<STRING></STRING> &vecTerm)   
  10. {   
  11.     string::size_type idx;    
  12.     while ( (idx = m_sSegQuery.find("/  ")) != string::npos ) {    
  13.         vecTerm.push_back(m_sSegQuery.substr(0,idx));    
  14.         m_sSegQuery = m_sSegQuery.substr(idx+3);    
  15.     }   
  16. }  
view plaincopy to clipboardprint?
  1.    
 
view plaincopy to clipboardprint?
  1. <PRE class=csharp name="code">/**  
  2.  * 程序翻译说明  
  3.  * 相关性分析查询,构造结果集合setRelevantRst //瓶颈所在  
  4.  *  
  5.  * @access  public  
  6.  * @param   vector<STRING></STRING> map set<STRING></STRING> 参数的汉字说明: 用户提交关键字的分词组,倒排索引映射,相关性结果集合  
  7.  * @return  string 0  
  8.  */  
  9. bool CQuery::GetRelevantRst   
  10. (   
  11.     vector<STRING></STRING> &vecTerm,    
  12.     map &mapBuckets,    
  13.     set<STRING></STRING> &setRelevantRst   
  14. const  
  15. {   
  16.     set<STRING></STRING> setSRst;   
  17.   
  18.     bool bFirst=true;   
  19.     vector<STRING></STRING>::iterator itTerm = vecTerm.begin();   
  20.   
  21.     for ( ; itTerm != vecTerm.end(); ++itTerm )   
  22.     {   
  23.   
  24.         setSRst.clear();   
  25.         copy(setRelevantRst.begin(), setRelevantRst.end(), inserter(setSRst,setSRst.begin()));   
  26.   
  27.         map mapRstDoc;   
  28.         string docid;   
  29.         int doccnt;   
  30.   
  31.         map::iterator itBuckets = mapBuckets.find(*itTerm);   
  32.         if (itBuckets != mapBuckets.end())   
  33.         {   
  34.             string strBucket = (*itBuckets).second;   
  35.             string::size_type idx;   
  36.             idx = strBucket.find_first_not_of(" ");   
  37.             strBucket = strBucket.substr(idx);   
  38.   
  39.             while ( (idx = strBucket.find(" ")) != string::npos )    
  40.             {   
  41.                 docid = strBucket.substr(0,idx);   
  42.                 doccnt = 0;   
  43.   
  44.                 if (docid.empty()) continue;   
  45.   
  46.                 map::iterator it = mapRstDoc.find(docid);   
  47.                 if ( it != mapRstDoc.end() )   
  48.                 {   
  49.                     doccnt = (*it).second + 1;   
  50.                     mapRstDoc.erase(it);   
  51.                 }   
  52.                 mapRstDoc.insert( pair(docid,doccnt) );   
  53.   
  54.                 strBucket = strBucket.substr(idx+1);   
  55.             }   
  56.   
  57.             // remember the last one   
  58.             docid = strBucket;   
  59.             doccnt = 0;   
  60.             map::iterator it = mapRstDoc.find(docid);   
  61.             if ( it != mapRstDoc.end() )   
  62.             {   
  63.                 doccnt = (*it).second + 1;   
  64.                 mapRstDoc.erase(it);   
  65.             }   
  66.             mapRstDoc.insert( pair(docid,doccnt) );   
  67.         }   
  68.   
  69.         // sort by term frequencty   
  70.         multimap > newRstDoc;   
  71.         map::iterator it0 = mapRstDoc.begin();   
  72.         for ( ; it0 != mapRstDoc.end(); ++it0 ){   
  73.             newRstDoc.insert( pair((*it0).second,(*it0).first) );   
  74.         }   
  75.   
  76.         multimap::iterator itNewRstDoc = newRstDoc.begin();   
  77.         setRelevantRst.clear();   
  78.         for ( ; itNewRstDoc != newRstDoc.end(); ++itNewRstDoc ){   
  79.             string docid = (*itNewRstDoc).second;   
  80.   
  81.             if (bFirst==true) {   
  82.                 setRelevantRst.insert(docid);   
  83.                 continue;   
  84.             }   
  85.   
  86.             if ( setSRst.find(docid) != setSRst.end() ){       
  87.                 setRelevantRst.insert(docid);   
  88.             }   
  89.         }   
  90.   
  91.         //cout << "setRelevantRst.size(): " << setRelevantRst.size() << "<BR>";   
  92.         bFirst = false;   
  93.     }   
  94.     return true;   
  95. }</PRE>  
view plaincopy to clipboardprint?
  1. /**  
  2.  * 程序翻译说明  
  3.  * 相关性分析查询,构造结果集合setRelevantRst //瓶颈所在  
  4.  *  
  5.  * @access  public  
  6.  * @param   vector<STRING></STRING> map set<STRING></STRING> 参数的汉字说明: 用户提交关键字的分词组,倒排索引映射,相关性结果集合  
  7.  * @return  string 0  
  8.  */  
  9. bool CQuery::GetRelevantRst   
  10. (   
  11.     vector<STRING></STRING> &vecTerm,    
  12.     map &mapBuckets,    
  13.     set<STRING></STRING> &setRelevantRst   
  14. const  
  15. {   
  16.     set<STRING></STRING> setSRst;   
  17.   
  18.     bool bFirst=true;   
  19.     vector<STRING></STRING>::iterator itTerm = vecTerm.begin();   
  20.   
  21.     for ( ; itTerm != vecTerm.end(); ++itTerm )   
  22.     {   
  23.   
  24.         setSRst.clear();   
  25.         copy(setRelevantRst.begin(), setRelevantRst.end(), inserter(setSRst,setSRst.begin()));   
  26.   
  27.         map mapRstDoc;   
  28.         string docid;   
  29.         int doccnt;   
  30.   
  31.         map::iterator itBuckets = mapBuckets.find(*itTerm);   
  32.         if (itBuckets != mapBuckets.end())   
  33.         {   
  34.             string strBucket = (*itBuckets).second;   
  35.             string::size_type idx;   
  36.             idx = strBucket.find_first_not_of(" ");   
  37.             strBucket = strBucket.substr(idx);   
  38.   
  39.             while ( (idx = strBucket.find(" ")) != string::npos )    
  40.             {   
  41.                 docid = strBucket.substr(0,idx);   
  42.                 doccnt = 0;   
  43.   
  44.                 if (docid.empty()) continue;   
  45.   
  46.                 map::iterator it = mapRstDoc.find(docid);   
  47.                 if ( it != mapRstDoc.end() )   
  48.                 {   
  49.                     doccnt = (*it).second + 1;   
  50.                     mapRstDoc.erase(it);   
  51.                 }   
  52.                 mapRstDoc.insert( pair(docid,doccnt) );   
  53.   
  54.                 strBucket = strBucket.substr(idx+1);   
  55.             }   
  56.   
  57.             // remember the last one   
  58.             docid = strBucket;   
  59.             doccnt = 0;   
  60.             map::iterator it = mapRstDoc.find(docid);   
  61.             if ( it != mapRstDoc.end() )   
  62.             {   
  63.                 doccnt = (*it).second + 1;   
  64.                 mapRstDoc.erase(it);   
  65.             }   
  66.             mapRstDoc.insert( pair(docid,doccnt) );   
  67.         }   
  68.   
  69.         // sort by term frequencty   
  70.         multimap > newRstDoc;   
  71.         map::iterator it0 = mapRstDoc.begin();   
  72.         for ( ; it0 != mapRstDoc.end(); ++it0 ){   
  73.             newRstDoc.insert( pair((*it0).second,(*it0).first) );   
  74.         }   
  75.   
  76.         multimap::iterator itNewRstDoc = newRstDoc.begin();   
  77.         setRelevantRst.clear();   
  78.         for ( ; itNewRstDoc != newRstDoc.end(); ++itNewRstDoc ){   
  79.             string docid = (*itNewRstDoc).second;   
  80.   
  81.             if (bFirst==true) {   
  82.                 setRelevantRst.insert(docid);   
  83.                 continue;   
  84.             }   
  85.   
  86.             if ( setSRst.find(docid) != setSRst.end() ){       
  87.                 setRelevantRst.insert(docid);   
  88.             }   
  89.         }   
  90.   
  91.         //cout << "setRelevantRst.size(): " << setRelevantRst.size() << "<BR>";   
  92.         bFirst = false;   
  93.     }   
  94.     return true;   
  95. }  
接下来的就是现实了,前面都只是处理数据得到 setRelevantRst 这个查询结构集合,这里就不多说了下面就和php之类的脚本语言差不多,格式化结果集合并显示出来。

//TSESearch.cpp

view plain copy to clipboard print ?
  1. //下面开始显示   
  2.     CDisplayRst iDisplayRst;    
  3.     iDisplayRst.ShowTop();    
  4.   
  5.     float used_msec = (end_tv.tv_sec-begin_tv.tv_sec)*1000    
  6.         +((float)(end_tv.tv_usec-begin_tv.tv_usec))/(float)1000;    
  7.   
  8.     iDisplayRst.ShowMiddle(iQuery.m_sQuery,used_msec,    
  9.             setRelevantRst.size(), iQuery.m_iStart);   
  10.   
  11.     iDisplayRst.ShowBelow(vecTerm,setRelevantRst,vecDocIdx,iQuery.m_iStart); 

这篇关于北大天网搜索引擎TSE分析及完全注释[3]来到关键字分词及相关性分析程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670220

相关文章

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

全网最全Tomcat完全卸载重装教程小结

《全网最全Tomcat完全卸载重装教程小结》windows系统卸载Tomcat重新通过ZIP方式安装Tomcat,优点是灵活可控,适合开发者自定义配置,手动配置环境变量后,可通过命令行快速启动和管理... 目录一、完全卸载Tomcat1. 停止Tomcat服务2. 通过控制面板卸载3. 手动删除残留文件4.

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

分析 Java Stream 的 peek使用实践与副作用处理方案

《分析JavaStream的peek使用实践与副作用处理方案》StreamAPI的peek操作是中间操作,用于观察元素但不终止流,其副作用风险包括线程安全、顺序混乱及性能问题,合理使用场景有限... 目录一、peek 操作的本质:有状态的中间操作二、副作用的定义与风险场景1. 并行流下的线程安全问题2. 顺

Java JUC并发集合详解之线程安全容器完全攻略

《JavaJUC并发集合详解之线程安全容器完全攻略》Java通过java.util.concurrent(JUC)包提供了一整套线程安全的并发容器,它们不仅是简单的同步包装,更是基于精妙并发算法构建... 目录一、为什么需要JUC并发集合?二、核心并发集合分类与详解三、选型指南:如何选择合适的并发容器?在多

MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决

《MyBatis/MyBatis-Plus同事务循环调用存储过程获取主键重复问题分析及解决》MyBatis默认开启一级缓存,同一事务中循环调用查询方法时会重复使用缓存数据,导致获取的序列主键值均为1,... 目录问题原因解决办法如果是存储过程总结问题myBATis有如下代码获取序列作为主键IdMappe

Java中最全最基础的IO流概述和简介案例分析

《Java中最全最基础的IO流概述和简介案例分析》JavaIO流用于程序与外部设备的数据交互,分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),处理... 目录IO流简介IO是什么应用场景IO流的分类流的超类类型字节文件流应用简介核心API文件输出流应用文