<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Zeki&#39;s Blog</title>
  
  
  <link href="http://example.com/atom.xml" rel="self"/>
  
  <link href="http://example.com/"/>
  <updated>2022-12-03T10:47:53.800Z</updated>
  <id>http://example.com/</id>
  
  <author>
    <name>Zeki Li</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>使用ssh连接github</title>
    <link href="http://example.com/2022/12/03/%E4%BD%BF%E7%94%A8ssh%E8%BF%9E%E6%8E%A5github/"/>
    <id>http://example.com/2022/12/03/%E4%BD%BF%E7%94%A8ssh%E8%BF%9E%E6%8E%A5github/</id>
    <published>2022-12-03T10:41:51.000Z</published>
    <updated>2022-12-03T10:47:53.800Z</updated>
    
    <content type="html"><![CDATA[<p>国内服务器由于网络环境无法正常使用github管理项目</p><p>解决方式：</p><ol><li>添加github-client源</li><li>apt update &amp; apt install gh</li><li>gh auth login. # choose ssh</li></ol><p>enjoy!</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;国内服务器由于网络环境无法正常使用github管理项目&lt;/p&gt;
&lt;p&gt;解决方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;添加github-client源&lt;/li&gt;
&lt;li&gt;apt update &amp;amp; apt install gh&lt;/li&gt;
&lt;li&gt;gh auth login. #</summary>
      
    
    
    
    
    <category term="issue" scheme="http://example.com/tags/issue/"/>
    
    <category term="github" scheme="http://example.com/tags/github/"/>
    
  </entry>
  
  <entry>
    <title>Hello World</title>
    <link href="http://example.com/2022/12/03/hello-world/"/>
    <id>http://example.com/2022/12/03/hello-world/</id>
    <published>2022-12-03T10:25:37.380Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><span id="more"></span><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">&quot;My New Post&quot;</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Welcome to &lt;a href=&quot;https://hexo.io/&quot;&gt;Hexo&lt;/a&gt;! This is your very first post. Check &lt;a href=&quot;https://hexo.io/docs/&quot;&gt;documentation&lt;/a&gt; for more info. If you get any problems when using Hexo, you can find the answer in &lt;a href=&quot;https://hexo.io/docs/troubleshooting.html&quot;&gt;troubleshooting&lt;/a&gt; or you can ask me on &lt;a href=&quot;https://github.com/hexojs/hexo/issues&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>最后的Typora免费版本</title>
    <link href="http://example.com/2022/10/25/%E6%9C%80%E5%90%8E%E7%9A%84Typora%E5%85%8D%E8%B4%B9%E7%89%88%E6%9C%AC/"/>
    <id>http://example.com/2022/10/25/%E6%9C%80%E5%90%8E%E7%9A%84Typora%E5%85%8D%E8%B4%B9%E7%89%88%E6%9C%AC/</id>
    <published>2022-10-25T07:36:18.000Z</published>
    <updated>2022-12-03T10:25:37.384Z</updated>
    
    <content type="html"><![CDATA[<p>转自:<a href="https://zahui.fan/posts/64b52e0d/">最后一个Typora免费版0.11.18</a></p><ul><li><a href="https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.exe">Windows</a></li><li><a href="https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.dmg">Mac</a></li><li><a href="https://github.com/iuxt/src/releases/download/2.0/Typora_Linux_0.11.18_amd64.deb">Ubuntu</a></li><li><a href="https://github.com/iuxt/src/releases/download/2.0/typora-0-11-18.tar.gz">其他Linux (非debian)</a></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;转自:&lt;a href=&quot;https://zahui.fan/posts/64b52e0d/&quot;&gt;最后一个Typora免费版0.11.18&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/iuxt/src/releases/downlo</summary>
      
    
    
    
    
    <category term="markdown" scheme="http://example.com/tags/markdown/"/>
    
    <category term="typora" scheme="http://example.com/tags/typora/"/>
    
    <category term="software" scheme="http://example.com/tags/software/"/>
    
  </entry>
  
  <entry>
    <title>Spark之基础概念</title>
    <link href="http://example.com/2022/10/25/Spark%E4%B9%8B%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5/"/>
    <id>http://example.com/2022/10/25/Spark%E4%B9%8B%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5/</id>
    <published>2022-10-25T07:34:04.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p>基于内存，分布式计算，函数式处理</p><h1 id="RDD：Resilient-Distributed-Dataset"><a href="#RDD：Resilient-Distributed-Dataset" class="headerlink" title="RDD：Resilient Distributed Dataset"></a>RDD：Resilient Distributed Dataset</h1><p>弹性分布式数据集：不可变，分布式抽象数据。使用时可以显示的将其换存在内存中以提高速度</p><ul><li>分片，每一个分片会被一个计算任务处理，可以在创建RDD时指定分片数</li><li>迭代器，每个分片计算结果可以通过迭代器的compute函数进行整合，无需保存每次计算的结果</li><li>依赖关系，RDD转换后形成新的RDD，新的RDD就依赖之前的结果。在部分分区计算失败或数据丢失时，可以具体到依赖的分区进行重新计算即可</li><li>分片函数，哈希分片语范围分片，其决定了分片数量</li><li>移动计算而不是移动数据，任务调度时尽可能将任务下发到所需处理的数据块存储节点执行</li></ul><h1 id="创建RDD"><a href="#创建RDD" class="headerlink" title="创建RDD"></a>创建RDD</h1><ul><li>HDFS</li><li>数据库</li><li>本地文件</li><li>其他</li></ul><h1 id="算子"><a href="#算子" class="headerlink" title="算子"></a>算子</h1><ul><li><p>Transformation</p><p>将一个RDD转换为另一个RDD，transfromation具有lazy load特性。需要遇到action算子时才会执行</p><table><thead><tr><th><strong>Transformation</strong></th><th><strong>含义</strong></th></tr></thead><tbody><tr><td><strong>map</strong>(func)</td><td>返回一个新的RDD，该RDD由每一个输入元素经过func函数转换后组成</td></tr><tr><td><strong>filter</strong>(func)</td><td>返回一个新的RDD，该RDD由经过func函数计算后返回值为true的输入元素组成</td></tr><tr><td><strong>flatMap</strong>(func)</td><td>类似于map，但是每一个输入元素可以被映射为0或多个输出元素（所以func应该返回一个序列，而不是单一元素）</td></tr><tr><td><strong>mapPartitions</strong>(func)</td><td>类似于map，但独立地在RDD的每一个分片上运行，因此在类型为T的RDD上运行时，func的函数类型必须是Iterator[T] &#x3D;&gt; Iterator[U]</td></tr><tr><td><strong>mapPartitionsWithIndex</strong>(func)</td><td>类似于mapPartitions，但func带有一个整数参数表示分片的索引值，因此在类型为T的RDD上运行时，func的函数类型必须是(Int, Interator[T]) &#x3D;&gt; Iterator[U]</td></tr><tr><td><strong>sample</strong>(withReplacement, fraction, seed)</td><td>根据fraction指定的比例对数据进行采样，可以选择是否使用随机数进行替换，seed用于指定随机数生成器种子</td></tr><tr><td><strong>union</strong>(otherDataset)</td><td>对源RDD和参数RDD求并集后返回一个新的RDD</td></tr><tr><td><strong>intersection</strong>(otherDataset)</td><td>对源RDD和参数RDD求交集后返回一个新的RDD</td></tr><tr><td><strong>distinct</strong>([numTasks]))</td><td>对源RDD进行去重后返回一个新的RDD</td></tr><tr><td><strong>groupByKey</strong>([numTasks])</td><td>在一个(K,V)的RDD上调用，返回一个(K, Iterator[V])的RDD</td></tr><tr><td><strong>reduceByKey</strong>(func, [numTasks])</td><td>在一个(K,V)的RDD上调用，返回一个(K,V)的RDD，使用指定的reduce函数，将相同key的值聚合到一起，与groupByKey类似，reduce任务的个数可以通过第二个可选的参数来设置</td></tr><tr><td><strong>aggregateByKey</strong>(zeroValue)(seqOp, combOp, [numTasks])</td><td>先按分区聚合 再总的聚合  每次要跟初始值交流 例如：aggregateByKey(0)(<em>+</em>,<em>+</em>) 对k&#x2F;y的RDD进行操作</td></tr><tr><td><strong>sortByKey</strong>([ascending], [numTasks])</td><td>在一个(K,V)的RDD上调用，K必须实现Ordered接口，返回一个按照key进行排序的(K,V)的RDD</td></tr><tr><td><strong>sortBy</strong>(func,[ascending], [numTasks])</td><td>与sortByKey类似，但是更灵活 第一个参数是根据什么排序 第二个是怎么排序 false倒序  第三个排序后分区数 默认与原RDD一样</td></tr><tr><td><strong>join</strong>(otherDataset, [numTasks])</td><td>在类型为(K,V)和(K,W)的RDD上调用，返回一个相同key对应的所有元素对在一起的(K,(V,W))的RDD 相当于内连接（求交集）</td></tr><tr><td><strong>cogroup</strong>(otherDataset, [numTasks])</td><td>在类型为(K,V)和(K,W)的RDD上调用，返回一个(K,(Iterable<V>,Iterable<W>))类型的RDD</td></tr><tr><td><strong>cartesian</strong>(otherDataset)</td><td>两个RDD的笛卡尔积 的成很多个K&#x2F;V</td></tr><tr><td><strong>pipe</strong>(command, [envVars])</td><td>调用外部程序</td></tr><tr><td><strong>coalesce</strong>(numPartitions**)**</td><td>重新分区 第一个参数是要分多少区，第二个参数是否shuffle 默认false 少分区变多分区 true  多分区变少分区 false</td></tr><tr><td><strong>repartition</strong>(numPartitions)</td><td>重新分区 必须shuffle 参数是要分多少区 少变多</td></tr><tr><td><strong>repartitionAndSortWithinPartitions</strong>(partitioner)</td><td>重新分区+排序 比先分区再排序效率高 对K&#x2F;V的RDD进行操作</td></tr><tr><td><strong>foldByKey</strong>(zeroValue)(seqOp)</td><td>该函数用于K&#x2F;V做折叠，合并处理 ，与aggregate类似  第一个括号的参数应用于每个V值 第二括号函数是聚合例如：_+_</td></tr><tr><td><strong>combineByKey</strong></td><td>合并相同的key的值 rdd1.combineByKey(x &#x3D;&gt; x, (a: Int, b: Int) &#x3D;&gt; a + b, (m: Int, n: Int) &#x3D;&gt; m + n)</td></tr><tr><td><strong>partitionBy****（partitioner）</strong></td><td>对RDD进行分区 partitioner是分区器 例如new HashPartition(2</td></tr><tr><td><strong>cache</strong></td><td>RDD缓存，可以避免重复计算从而减少时间，区别：cache内部调用了persist算子，cache默认就一个缓存级别MEMORY-ONLY ，而persist则可以选择缓存级别</td></tr><tr><td><strong>persist</strong></td><td></td></tr><tr><td></td><td></td></tr><tr><td><strong>Subtract****（rdd）</strong></td><td>返回前rdd元素不在后rdd的rdd</td></tr><tr><td><strong>leftOuterJoin</strong></td><td>leftOuterJoin类似于SQL中的左外关联left outer join，返回结果以前面的RDD为主，关联不上的记录为空。只能用于两个RDD之间的关联，如果要多个RDD关联，多关联几次即可。</td></tr><tr><td><strong>rightOuterJoin</strong></td><td>rightOuterJoin类似于SQL中的有外关联right outer join，返回结果以参数中的RDD为主，关联不上的记录为空。只能用于两个RDD之间的关联，如果要多个RDD关联，多关联几次即可</td></tr><tr><td>subtractByKey</td><td>substractByKey和基本转换操作中的subtract类似只不过这里是针对K的，返回在主RDD中出现，并且不在otherRDD中出现的元素</td></tr></tbody></table></li><li><p>Action</p><p>触发代码执行，一段spark代码至少需要一个action</p><table><thead><tr><th><strong>Action</strong></th><th><strong>含义</strong></th></tr></thead><tbody><tr><td><strong>reduce</strong>(<em>func</em>)</td><td>通过func函数聚集RDD中的所有元素，这个功能必须是课交换且可并联的</td></tr><tr><td><strong>collect</strong>()</td><td>在驱动程序中，以数组的形式返回数据集的所有元素</td></tr><tr><td><strong>count</strong>()</td><td>返回RDD的元素个数</td></tr><tr><td><strong>first</strong>()</td><td>返回RDD的第一个元素（类似于take(1)）</td></tr><tr><td><strong>take</strong>(<em>n</em>)</td><td>返回一个由数据集的前n个元素组成的数组</td></tr><tr><td><strong>takeSample</strong>(<em>withReplacement</em>,<em>num</em>, [<em>seed</em>])</td><td>返回一个数组，该数组由从数据集中随机采样的num个元素组成，可以选择是否用随机数替换不足的部分，seed用于指定随机数生成器种子</td></tr><tr><td><strong>takeOrdered</strong>(<em>n</em>, <em>[ordering]</em>)</td><td></td></tr><tr><td><strong>saveAsTextFile</strong>(<em>path</em>)</td><td>将数据集的元素以textfile的形式保存到HDFS文件系统或者其他支持的文件系统，对于每个元素，Spark将会调用toString方法，将它装换为文件中的文本</td></tr><tr><td><strong>saveAsSequenceFile</strong>(<em>path</em>)</td><td>将数据集中的元素以Hadoop sequencefile的格式保存到指定的目录下，可以使HDFS或者其他Hadoop支持的文件系统。</td></tr><tr><td><strong>saveAsObjectFile</strong>(<em>path</em>)</td><td></td></tr><tr><td><strong>countByKey</strong>()</td><td>针对(K,V)类型的RDD，返回一个(K,Int)的map，表示每一个key对应的元素个数。</td></tr><tr><td><strong>foreach</strong>(<em>func</em>)</td><td>在数据集的每一个元素上，运行函数func进行更新。</td></tr><tr><td><strong>aggregate</strong></td><td>先对分区进行操作，在总体操作</td></tr><tr><td><strong>reduceByKeyLocally</strong></td><td></td></tr><tr><td><strong>lookup</strong></td><td></td></tr><tr><td><strong>top</strong></td><td></td></tr><tr><td><strong>fold</strong></td><td></td></tr><tr><td><strong>foreachPartition</strong></td><td></td></tr></tbody></table></li></ul><h1 id="Spark任务基础概念"><a href="#Spark任务基础概念" class="headerlink" title="Spark任务基础概念"></a>Spark任务基础概念</h1><ul><li><p>Application</p><p>driver程序以及集群执行的代码</p></li><li><p>driver</p><p>创建sc，加载数据集，处理数据以及展示流程</p></li><li><p>集群节点</p><p>driver：创建sc，启动spark级集群计算任务</p><p>master：master节点</p><p>worker：集群任务执行节点，启动executor进程</p><p>Executor：执行应用程序以及汇报执行状态</p><p>cluster manager：集群资源管理器，负责申请资源调度任务，如yarn</p></li><li><p>jobs</p><p>RDD中的action，每个action变为一个job，然后DAGScheduler回分解stage执行</p></li><li><p>stage</p><p>一个job拆分为多组task，每组是一个stage</p></li><li><p>task</p><p>送到executor执行的工作单元，两类：shuffleMapTask：输出shffle所需要的数据；resultTask：无需shuffle直接返回处理结果</p></li><li><p>partition</p><p>数据划分</p></li><li><p>cores</p><p>worker执行进程</p></li><li><p>memory</p><p>内存设置</p></li><li><p>shuffle</p><p>stage之间的数据拷贝</p></li></ul><h1 id="窄依赖与宽依赖"><a href="#窄依赖与宽依赖" class="headerlink" title="窄依赖与宽依赖"></a>窄依赖与宽依赖</h1><p>窄依赖：每个RDD只会被一个子RDD所依赖，例如map、filter、union等操作都会产生窄依赖；（独生子女）</p><p>宽依赖：每个RDD被多个子RDD所依赖，例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖；（超生）</p><p>关于join的依赖关系：</p><p>两个RDD在进行join操作时，一个RDD的partition仅仅和另一个RDD中已知个数的Partition进行join，那么这种类型的join操作就是窄依赖。否则就是宽依赖。</p><h1 id="DAG图与宽窄依赖"><a href="#DAG图与宽窄依赖" class="headerlink" title="DAG图与宽窄依赖"></a>DAG图与宽窄依赖</h1><p>DAGScheduler遇到action job时，会根据宽窄依赖决定stage划分。如果遇到窄依赖会将该action加入当前stage，遇到宽依赖则创建新的stage去执行</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;基于内存，分布式计算，函数式处理&lt;/p&gt;
&lt;h1 id=&quot;RDD：Resilient-Distributed-Dataset&quot;&gt;&lt;a href=&quot;#RDD：Resilient-Distributed-Dataset&quot; class=&quot;headerlink&quot; title=&quot;RD</summary>
      
    
    
    
    
    <category term="spark" scheme="http://example.com/tags/spark/"/>
    
    <category term="basic" scheme="http://example.com/tags/basic/"/>
    
  </entry>
  
  <entry>
    <title>Git commit message specification</title>
    <link href="http://example.com/2022/10/25/Git-commit-message-specification/"/>
    <id>http://example.com/2022/10/25/Git-commit-message-specification/</id>
    <published>2022-10-25T07:32:10.000Z</published>
    <updated>2022-12-03T10:25:37.372Z</updated>
    
    <content type="html"><![CDATA[<p>Git commit message specification</p><p><a href="https://www.conventionalcommits.org/en/v1.0.0/">https://www.conventionalcommits.org/en/v1.0.0/</a></p><p><a href="https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html">https://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html</a></p><h1 id="Specification"><a href="#Specification" class="headerlink" title="Specification"></a>Specification</h1><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;type&gt;[optional scope]: &lt;description&gt;</span><br><span class="line"></span><br><span class="line">[optional body]</span><br><span class="line"></span><br><span class="line">[optional footer(s)]</span><br></pre></td></tr></table></figure><p>Types:</p><figure class="highlight tex"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">abaliable types:</span><br><span class="line">[</span><br><span class="line">  &#x27;build&#x27;,</span><br><span class="line">  &#x27;chore&#x27;,</span><br><span class="line">  &#x27;ci&#x27;,</span><br><span class="line">  &#x27;docs&#x27;,</span><br><span class="line">  &#x27;feat&#x27;,</span><br><span class="line">  &#x27;fix&#x27;,</span><br><span class="line">  &#x27;perf&#x27;,</span><br><span class="line">  &#x27;refactor&#x27;,</span><br><span class="line">  &#x27;revert&#x27;,</span><br><span class="line">  &#x27;style&#x27;,</span><br><span class="line">  &#x27;test&#x27;</span><br><span class="line">];</span><br><span class="line"></span><br><span class="line">description:</span><br><span class="line">feat：新功能（feature）</span><br><span class="line">fix：修补bug</span><br><span class="line">docs：文档（documentation）</span><br><span class="line">style： 格式（不影响代码运行的变动）</span><br><span class="line">refactor：重构（即不是新增功能，也不是修改bug的代码变动）</span><br><span class="line">test：增加测试</span><br><span class="line">chore：构建过程或辅助工具的变动</span><br></pre></td></tr></table></figure><h2 id="Examples"><a href="#Examples" class="headerlink" title="Examples"></a>Examples</h2><h3 id="Commit-message-with-description-and-breaking-change-footer"><a href="#Commit-message-with-description-and-breaking-change-footer" class="headerlink" title="Commit message with description and breaking change footer"></a>Commit message with description and breaking change footer</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">feat: allow provided config object to extend other configs</span><br><span class="line"></span><br><span class="line">BREAKING CHANGE: `extends` key in config file is now used for extending other config files</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-to-draw-attention-to-breaking-change"><a href="#Commit-message-with-to-draw-attention-to-breaking-change" class="headerlink" title="Commit message with ! to draw attention to breaking change"></a>Commit message with <code>!</code> to draw attention to breaking change</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">feat!: send an email to the customer when a product is shipped</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-scope-and-to-draw-attention-to-breaking-change"><a href="#Commit-message-with-scope-and-to-draw-attention-to-breaking-change" class="headerlink" title="Commit message with scope and ! to draw attention to breaking change"></a>Commit message with scope and <code>!</code> to draw attention to breaking change</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">feat(api)!: send an email to the customer when a product is shipped</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-both-and-BREAKING-CHANGE-footer"><a href="#Commit-message-with-both-and-BREAKING-CHANGE-footer" class="headerlink" title="Commit message with both ! and BREAKING CHANGE footer"></a>Commit message with both <code>!</code> and BREAKING CHANGE footer</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">chore!: drop support for Node 6</span><br><span class="line"></span><br><span class="line">BREAKING CHANGE: use JavaScript features not available in Node 6.</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-no-body"><a href="#Commit-message-with-no-body" class="headerlink" title="Commit message with no body"></a>Commit message with no body</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docs: correct spelling of CHANGELOG</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-scope"><a href="#Commit-message-with-scope" class="headerlink" title="Commit message with scope"></a>Commit message with scope</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">feat(lang): add Polish language</span><br></pre></td></tr></table></figure><h3 id="Commit-message-with-multi-paragraph-body-and-multiple-footers"><a href="#Commit-message-with-multi-paragraph-body-and-multiple-footers" class="headerlink" title="Commit message with multi-paragraph body and multiple footers"></a>Commit message with multi-paragraph body and multiple footers</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">fix: prevent racing of requests</span><br><span class="line"></span><br><span class="line">Introduce a request id and a reference to latest request. Dismiss</span><br><span class="line">incoming responses other than from latest request.</span><br><span class="line"></span><br><span class="line">Remove timeouts which were used to mitigate the racing issue but are</span><br><span class="line">obsolete now.</span><br><span class="line"></span><br><span class="line">Reviewed-by: Z</span><br><span class="line">Refs: #123</span><br></pre></td></tr></table></figure><h1 id="Others"><a href="#Others" class="headerlink" title="Others"></a>Others</h1><p>idea plugins: <code>git commit template</code></p><p>hangelog generate &amp; commit message validate</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;Git commit message specification&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/&quot;&gt;https://www.conventionalcommits.org/en/v</summary>
      
    
    
    
    
    <category term="git" scheme="http://example.com/tags/git/"/>
    
    <category term="commit" scheme="http://example.com/tags/commit/"/>
    
    <category term="specification" scheme="http://example.com/tags/specification/"/>
    
  </entry>
  
  <entry>
    <title>spark之广播与累加器</title>
    <link href="http://example.com/2022/10/25/spark%E4%B9%8B%E5%B9%BF%E6%92%AD%E4%B8%8E%E7%B4%AF%E5%8A%A0%E5%99%A8/"/>
    <id>http://example.com/2022/10/25/spark%E4%B9%8B%E5%B9%BF%E6%92%AD%E4%B8%8E%E7%B4%AF%E5%8A%A0%E5%99%A8/</id>
    <published>2022-10-25T07:30:43.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<h1 id="广播"><a href="#广播" class="headerlink" title="广播"></a>广播</h1><p>如果我们要在分布式计算里面分发大对象，例如：字典，集合，黑白名单等，这个都会由Driver端进行分发，一般来讲，如果这个变量不是广播变量，那么每个task就会分发一份，这在<strong>task数目十分多的情况下Driver的带宽会成为系统的瓶颈，而且会大量消耗task服务器上的资源</strong>，如果将这个变量声明为广播变量，那么知识每个executor拥有一份，这个executor启动的task会共享这个变量，节省了通信的成本和服务器的资源。</p><h2 id="使用方式"><a href="#使用方式" class="headerlink" title="使用方式"></a>使用方式</h2><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># create</span><br><span class="line"><span class="keyword">val</span> a = <span class="number">3</span></span><br><span class="line"><span class="keyword">val</span> broadcast = sc.broadcast(a)</span><br><span class="line"></span><br><span class="line"># use</span><br><span class="line"><span class="keyword">val</span> c = broadcast.value</span><br></pre></td></tr></table></figure><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><p>1、能不能将一个RDD使用广播变量广播出去？</p><pre><code>不能，因为RDD是不存储数据的。**可以将RDD的结果广播出去。**</code></pre><p>2、 广播变量只能在Driver端定义，<strong>不能在Executor端定义。</strong></p><p>3、 在Driver端可以修改广播变量的值，<strong>在Executor端无法修改广播变量的值。</strong></p><p>4、如果executor端用到了Driver的变量，如果<strong>不使用广播变量在Executor有多少task就有多少Driver端的变量副本。</strong></p><p>5、如果Executor端用到了Driver的变量，如果<strong>使用广播变量在每个Executor中只有一份Driver端的变量副本。</strong></p><h1 id="累加器"><a href="#累加器" class="headerlink" title="累加器"></a>累加器</h1><p>在spark应用程序中，我们经常会有这样的需求，如异常监控，调试，记录符合某特性的数据的数目，这种需求都需要用到计数器，如果一个变量不被声明为一个累加器，那么它将在被改变时不会再driver端进行全局汇总，即在分布式运行时每个task运行的只是原始变量的一个副本，并不能改变原始变量的值，但是当这个变量被声明为累加器后，该变量就会有分布式计数的功能。</p><h2 id="使用方式-1"><a href="#使用方式-1" class="headerlink" title="使用方式"></a>使用方式</h2><figure class="highlight scala"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"># create</span><br><span class="line"><span class="keyword">val</span> a = sc.accumulator(<span class="number">0</span>)</span><br><span class="line"></span><br><span class="line"># use</span><br><span class="line"><span class="keyword">val</span> b = a.value</span><br></pre></td></tr></table></figure><h2 id="注意事项-1"><a href="#注意事项-1" class="headerlink" title="注意事项"></a>注意事项</h2><p>累加器在Driver端定义赋初始值，累加器只能在Driver端读取最后的值，在Excutor端更新。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;广播&quot;&gt;&lt;a href=&quot;#广播&quot; class=&quot;headerlink&quot; title=&quot;广播&quot;&gt;&lt;/a&gt;广播&lt;/h1&gt;&lt;p&gt;如果我们要在分布式计算里面分发大对象，例如：字典，集合，黑白名单等，这个都会由Driver端进行分发，一般来讲，如果这个变量不是广播变量，那</summary>
      
    
    
    
    
    <category term="spark" scheme="http://example.com/tags/spark/"/>
    
    <category term="broadcast" scheme="http://example.com/tags/broadcast/"/>
    
    <category term="accumulator" scheme="http://example.com/tags/accumulator/"/>
    
  </entry>
  
  <entry>
    <title>Linux 安装shadowsocks并开启全局代理</title>
    <link href="http://example.com/2022/10/25/Linux-%E5%AE%89%E8%A3%85shadowsocks%E5%B9%B6%E5%BC%80%E5%90%AF%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86/"/>
    <id>http://example.com/2022/10/25/Linux-%E5%AE%89%E8%A3%85shadowsocks%E5%B9%B6%E5%BC%80%E5%90%AF%E5%85%A8%E5%B1%80%E4%BB%A3%E7%90%86/</id>
    <published>2022-10-25T07:09:38.000Z</published>
    <updated>2022-12-03T10:25:37.372Z</updated>
    
    <content type="html"><![CDATA[<p>linux安装ss客户端与kcp并开启全局代理</p><span id="more"></span><h1 id="1-安装ss客户端和kcp客户端"><a href="#1-安装ss客户端和kcp客户端" class="headerlink" title="1.安装ss客户端和kcp客户端"></a>1.安装ss客户端和kcp客户端</h1><ul><li>kcp客户端：<a href="https://github.com/xtaci/kcptun/releases">https://github.com/xtaci/kcptun/releases</a> 选择对应版本下载即可</li><li>shadowsocks客户端linux版本：<a href="https://github.com/shadowsocks/shadowsocks-rust/releases">https://github.com/shadowsocks/shadowsocks-rust/releases</a> 选择对应版本</li></ul><h1 id="2-修改配置启动kcp与ss客户端"><a href="#2-修改配置启动kcp与ss客户端" class="headerlink" title="2.修改配置启动kcp与ss客户端"></a>2.修改配置启动kcp与ss客户端</h1><h2 id="2-1-配置"><a href="#2-1-配置" class="headerlink" title="2.1 配置"></a>2.1 配置</h2><ul><li>创建kcp.json, 主要配置远程vps服务地址以及本地端口如: <code>:10080</code></li><li>创建ss.json, 配置服务地址为kcp配置的本地端口，本地端口设置如：<code>10088</code></li></ul><h2 id="2-2-启动"><a href="#2-2-启动" class="headerlink" title="2.2 启动"></a>2.2 启动</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">kcp-client -c kcp.json</span><br><span class="line">sslocal -c ss.json</span><br></pre></td></tr></table></figure><h1 id="3-开启全局代理"><a href="#3-开启全局代理" class="headerlink" title="3.开启全局代理"></a>3.开启全局代理</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export ALL_PROXY=&quot;socks5://代理服务器IP地址:代理端口&quot;  # 开启sock代理</span><br><span class="line">unset ALL_PROXY  # 关闭代理</span><br></pre></td></tr></table></figure><h1 id="4-使用polipo将socks代理转为http代理"><a href="#4-使用polipo将socks代理转为http代理" class="headerlink" title="4.使用polipo将socks代理转为http代理"></a>4.使用polipo将socks代理转为http代理</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">apt install polipo</span><br><span class="line">修改配置：/etc/polipo/config： 协议端口指定为socks地址</span><br><span class="line">service start polipo</span><br></pre></td></tr></table></figure><p>开启代理：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">export HTTP_PROXY=http://xxxx:xxx</span><br><span class="line">export HTTPS_PROXY=https://xxxx:xxx</span><br></pre></td></tr></table></figure><h1 id="5-开启代理后python使用requets报错"><a href="#5-开启代理后python使用requets报错" class="headerlink" title="5.开启代理后python使用requets报错"></a>5.开启代理后python使用requets报错</h1><p>错误信息：ValueError: check_hostname requires server_hostname</p><p>解决方式：降低urllib3版本至1.25.8</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;linux安装ss客户端与kcp并开启全局代理&lt;/p&gt;</summary>
    
    
    
    
    <category term="shadowsocks" scheme="http://example.com/tags/shadowsocks/"/>
    
    <category term="kcp" scheme="http://example.com/tags/kcp/"/>
    
    <category term="linux" scheme="http://example.com/tags/linux/"/>
    
    <category term="proxy" scheme="http://example.com/tags/proxy/"/>
    
  </entry>
  
  <entry>
    <title>Vim 复制内容到剪切板</title>
    <link href="http://example.com/2022/10/25/Vim-%E5%A4%8D%E5%88%B6%E5%86%85%E5%AE%B9%E5%88%B0%E5%89%AA%E5%88%87%E6%9D%BF/"/>
    <id>http://example.com/2022/10/25/Vim-%E5%A4%8D%E5%88%B6%E5%86%85%E5%AE%B9%E5%88%B0%E5%89%AA%E5%88%87%E6%9D%BF/</id>
    <published>2022-10-25T06:42:20.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># 行复制：光标移动到需要复制的行，输入下面命令</span><br><span class="line">&quot;+y</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;</summary>
      
    
    
    
    
    <category term="vim" scheme="http://example.com/tags/vim/"/>
    
  </entry>
  
  <entry>
    <title>git总结</title>
    <link href="http://example.com/2022/06/13/git%E6%80%BB%E7%BB%93/"/>
    <id>http://example.com/2022/06/13/git%E6%80%BB%E7%BB%93/</id>
    <published>2022-06-13T13:14:59.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p>Git 是一个开源的分布式版本控制系统，用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同，它采用了分布式版本库的方式，不必服务器端软件支持。</p><p>Git 一般只添加数据, 你执行的 Git 操作，几乎只往 Git 数据库中增加数据。 很难让Git 执行任何不可逆操作，或者让它以任何方式清除数据。 同别的 VCS 一样，未提交更新时有可能丢失或弄乱修改的内容;但是一旦你提交快照到 Git 中，就难以再丢失数据，特别是如果你定期的推送数据库到其它仓库的话。</p><span id="more"></span><p><img src="/Users/zeki/Documents/Blog/source/_posts/git%E6%80%BB%E7%BB%93/1595228461@2ffee7bd1f90f29273dadb9cb5b06440.jpg.png" alt="1595228461@2ffee7bd1f90f29273dadb9cb5b06440.jpg"></p><ul><li><p>Workspace：工作区</p></li><li><p>Index&#x2F;Stage：暂存区，也叫索引</p></li><li><p>Repository：仓库区（或本地仓库），也存储库</p></li><li><p>Remote：远程仓库</p></li></ul><p>这使得我们使用 Git 成为一个安心愉悦的过程，因为我们深知可以尽情做各种尝试，而没有把事情弄糟的危险。 更深度探讨 Git 如何保存数据及恢复丢失数据的话题，请参考撤消操作。</p><ol><li><p>历史操作记录</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">log</span>  <span class="comment"># 查看历史操作记录</span></span><br><span class="line">git <span class="built_in">log</span> --oneline  <span class="comment"># 简洁版本的历史操作记录</span></span><br><span class="line">git <span class="built_in">log</span> --graph  <span class="comment"># 拓扑图选项</span></span><br><span class="line">git <span class="built_in">log</span> --reverse  <span class="comment"># 逆向显示日志</span></span><br><span class="line">git <span class="built_in">log</span> --auther=auther  <span class="comment"># 查看auther的提交</span></span><br><span class="line"><span class="comment"># 指定日期，可以执行几个选项：--since 和 --before，也可以用 --until 和 --after。</span></span><br></pre></td></tr></table></figure></li><li><p>查看当前仓库状态</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git status  <span class="comment"># 查看当前仓库状态</span></span><br></pre></td></tr></table></figure></li><li><p>推送</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git add *  <span class="comment"># 添加至暂存区</span></span><br><span class="line">git commit -m <span class="string">&quot;commit message&quot;</span>  <span class="comment"># 提交</span></span><br><span class="line">git push origin master  <span class="comment"># 推送至远程仓库master分支</span></span><br></pre></td></tr></table></figure></li><li><p>更新与拉取</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> http://xxx.com/xxx.git  <span class="comment"># clone远程仓库</span></span><br><span class="line">git pull  <span class="comment"># 获取新更改</span></span><br></pre></td></tr></table></figure></li><li><p>暂存区保留临时更改</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git stash  <span class="comment"># 本地更改暂存 </span></span><br><span class="line">git stash list  <span class="comment"># 列出本地暂存数据</span></span><br><span class="line">git stash pop  <span class="comment"># 恢复</span></span><br></pre></td></tr></table></figure></li><li><p>移动</p><p>对于仓库的文件做移动</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">mv</span> xxx yyy  <span class="comment"># xxx移动/重命名到yyy, git文件前显示R表示已被重命名</span></span><br><span class="line">git commit -a -m <span class="string">&quot;rename xxx to yyy&quot;</span>  <span class="comment"># -a标志，这使git commit自动检测修改的文件</span></span><br></pre></td></tr></table></figure></li><li><p>删除</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">rm</span> xxx  <span class="comment"># 删除xxx文件</span></span><br><span class="line">git commit -a -m <span class="string">&quot;remove file xxx&quot;</span></span><br></pre></td></tr></table></figure></li></ol><p>todo: <a href="http://www.bjpowernode.com/tutorial_git/1775.html">http://www.bjpowernode.com/tutorial_git/1775.html</a></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Git 是一个开源的分布式版本控制系统，用于敏捷高效地处理任何或小或大的项目。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。Git 与常用的版本控制工具 CVS, Subversion 等不同，它采用了分布式版本库的方式，不必服务器端软件支持。&lt;/p&gt;
&lt;p&gt;Git 一般只添加数据, 你执行的 Git 操作，几乎只往 Git 数据库中增加数据。 很难让Git 执行任何不可逆操作，或者让它以任何方式清除数据。 同别的 VCS 一样，未提交更新时有可能丢失或弄乱修改的内容;但是一旦你提交快照到 Git 中，就难以再丢失数据，特别是如果你定期的推送数据库到其它仓库的话。&lt;/p&gt;</summary>
    
    
    
    
    <category term="git" scheme="http://example.com/tags/git/"/>
    
    <category term="总结" scheme="http://example.com/tags/%E6%80%BB%E7%BB%93/"/>
    
  </entry>
  
  <entry>
    <title>Markdown UML</title>
    <link href="http://example.com/2022/06/10/Markdown-UML/"/>
    <id>http://example.com/2022/06/10/Markdown-UML/</id>
    <published>2022-06-10T02:41:38.000Z</published>
    <updated>2022-12-03T10:25:37.372Z</updated>
    
    <content type="html"><![CDATA[<p>本文介绍如何使用Markdown绘制UML图</p><span id="more"></span><ol><li><p>创建UML类图</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">pre</span> <span class="attr">class</span>=<span class="string">&quot;mermaid&quot;</span>&gt;</span></span>   classDiagram</span><br><span class="line">// 以上为固定写法,此处开始创建对象与关系<span class="language-xml"><span class="tag">&lt;/<span class="name">pre</span>&gt;</span></span></span><br></pre></td></tr></table></figure></li><li><p>类与接口</p><ul><li><p>创建</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">class A &#123;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramclass A {    }</pre></li><li><p>类型</p><table><thead><tr><th>符号</th><th>类型</th></tr></thead><tbody><tr><td>&lt;<interface>&gt;</td><td>接口</td></tr><tr><td>&lt;<abstract>&gt;</td><td>抽象类</td></tr><tr><td>&lt;<service>&gt;</td><td>service类</td></tr><tr><td>&lt;<enumeration>&gt;</td><td>枚举</td></tr></tbody></table><p>使用方式: </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 方式一：内嵌</span><br><span class="line">class A &#123;</span><br><span class="line">&lt;&lt;Interface&gt;&gt;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">// 方式二：单独的行</span><br><span class="line">class B</span><br><span class="line">&lt;&lt;Interface&gt;&gt; B</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramclass A {    <<Interface>>}class B<<Interface>> B</pre></li><li><p>属性</p><p>两种方式内联和单独指定</p><p>方式一:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">class A</span><br><span class="line">A : +String name</span><br><span class="line">A : -int age</span><br><span class="line">A : List~Object~ child    //泛型变量</span><br><span class="line">A : +eat()</span><br><span class="line">A : +sleep(time)          //有参数的方法</span><br><span class="line">A : +getAge() int         //有返回值的方法</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramclass AA : +String nameA : -int ageA : List~Object~ child    //泛型变量A : +eat()A : +sleep(time)          //有参数的方法A : +getAge() int         //有返回值的方法</pre><p>方式二:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">class B &#123;</span><br><span class="line">    +String name</span><br><span class="line">    -int age</span><br><span class="line">    List~Object~ child</span><br><span class="line">    +eat()</span><br><span class="line">    +sleep(time)</span><br><span class="line">    +getAge() int</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramclass B {    +String name    -int age    List~Object~ child    +eat()    +sleep(time)    +getAge() int}</pre><p>元素可见范围:</p><table><thead><tr><th align="left">修饰符号</th><th>可见范围</th></tr></thead><tbody><tr><td align="left">-</td><td>private</td></tr><tr><td align="left">+</td><td>public</td></tr><tr><td align="left">#</td><td>protected</td></tr><tr><td align="left">~</td><td>package</td></tr></tbody></table></li></ul></li><li><p>关系</p><ul><li><p>继承</p><p>表示子类继承父类的所有特征和行为</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ClassA &lt;|-- ClassB  // class B extends A</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramClassA <|-- ClassB</pre></li><li><p>实现</p><p>类是接口所有特征和行为的实现</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">InterfaceA &lt;|.. ClassB  // class B implements interface A</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramInterfaceA <|.. ClassB</pre></li><li><p>组合&#x2F;聚合</p><p>组合: 整体与部分的关系，但部分不能离开整体而单独存在 带实心菱形的实线，实心菱形指向整体</p><p>聚合: 整体与部分的关系，且部分可以离开整体而单独存在 带空心菱形的实现，空心菱形指向整体。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ClassA *-- ClassB  // class B is part of A</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramClassA *-- ClassB</pre></li><li><p>关联</p><p>一个类知道另一个类的属性和方法；关联可以是双向的，也可以是单向的。双向的关联可以有两个箭头或者没有箭头，单向的关联有一个箭头</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ClassA -- ClassB</span><br><span class="line">ClassC &lt;-- ClassD</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramClassA -- ClassBClassC <-- ClassD</pre></li><li><p>依赖</p><p>一个类的实现需要另一个类的协助</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ClassA &lt;.. ClassB</span><br></pre></td></tr></table></figure><pre class="mermaid">     classDiagramClassA <.. ClassB</pre></li><li><p>关系标识</p><ul><li><p>关系上添加标签</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ClassA &lt;.. ClassB : 依赖</span><br></pre></td></tr></table></figure><pre class="mermaid">       classDiagramClassA <.. ClassB : 依赖</pre></li><li><p>关系上添加数量</p><table><thead><tr><th>符号</th><th>含义</th></tr></thead><tbody><tr><td>1</td><td>1个</td></tr><tr><td>0..1</td><td>0或1个</td></tr><tr><td>1..*</td><td>1个或多个</td></tr><tr><td>*</td><td>任意个</td></tr><tr><td>n</td><td>n个(n&gt;1)</td></tr><tr><td>0..n</td><td>0个到n个(n&gt;0)</td></tr><tr><td>1..n</td><td>1到n个(n&gt;1)</td></tr></tbody></table><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ClassA &quot;1&quot; --&gt; &quot;*&quot; ClassB</span><br></pre></td></tr></table></figure><pre class="mermaid">       classDiagramClassA "1" --> "*" ClassB</pre></li></ul></li></ul></li><li><p>例子</p></li></ol><pre class="mermaid">classDiagramclass Parent {  <<Abstract>>    +String name    -int age    #List<String> children    ~Float weight    +eat()    +sleep()}class Child {    +String toy    -Integer grade}Parent "1" <|-- "*" Child : 继承</pre>]]></content>
    
    
    <summary type="html">&lt;p&gt;本文介绍如何使用Markdown绘制UML图&lt;/p&gt;</summary>
    
    
    
    
    <category term="Markdown" scheme="http://example.com/tags/Markdown/"/>
    
    <category term="UML" scheme="http://example.com/tags/UML/"/>
    
  </entry>
  
  <entry>
    <title>二叉搜索树与双向链表</title>
    <link href="http://example.com/2022/06/07/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%8E%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8/"/>
    <id>http://example.com/2022/06/07/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%8E%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8/</id>
    <published>2022-06-07T02:06:53.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://leetcode.cn/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/">二叉搜索树与双向链表</a></p><p>输入一棵二叉搜索树，将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点，只能调整树中节点指针的指向。</p><span id="more"></span><p>为了让您更好地理解问题，以下面的二叉搜索树为例：</p><p><img src="/2022/06/07/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%8E%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8/bstdllreturndll.png" alt="bstdllreturndll"></p><p>我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表，第一个节点的前驱是最后一个节点，最后一个节点的后继是第一个节点。</p><p>下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。</p><p><img src="/2022/06/07/%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E4%B8%8E%E5%8F%8C%E5%90%91%E9%93%BE%E8%A1%A8/bstdlloriginalbst.png" alt="bstdlloriginalbst"></p><p>特别地，我们希望可以就地完成转换操作。当转化完成以后，树中节点的左指针需要指向前驱，树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。</p><p>思路: 可以将整颗树的转化分解为左子树转化和右子树转化. 然后对于左子树转化后的结果获取头尾节点更新与当前根节点的指针即可, 右子树同样如此</p><p>代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">// Definition for a Node.</span></span><br><span class="line"><span class="comment">class Node &#123;</span></span><br><span class="line"><span class="comment">    public int val;</span></span><br><span class="line"><span class="comment">    public Node left;</span></span><br><span class="line"><span class="comment">    public Node right;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    public Node() &#123;&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    public Node(int _val) &#123;</span></span><br><span class="line"><span class="comment">        val = _val;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">    public Node(int _val,Node _left,Node _right) &#123;</span></span><br><span class="line"><span class="comment">        val = _val;</span></span><br><span class="line"><span class="comment">        left = _left;</span></span><br><span class="line"><span class="comment">        right = _right;</span></span><br><span class="line"><span class="comment">    &#125;</span></span><br><span class="line"><span class="comment">&#125;;</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> Node <span class="title function_">treeToDoublyList</span><span class="params">(Node root)</span> &#123;</span><br><span class="line">         <span class="keyword">if</span>(root == <span class="literal">null</span>) &#123; </span><br><span class="line">             <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="comment">// 返回节点,默认当前根节点</span></span><br><span class="line">         <span class="type">Node</span> <span class="variable">ret</span> <span class="operator">=</span> root;</span><br><span class="line">         <span class="comment">// 尾结点,默认根节点</span></span><br><span class="line">         <span class="type">Node</span> <span class="variable">end</span> <span class="operator">=</span> root;</span><br><span class="line">         <span class="type">Node</span> <span class="variable">left</span> <span class="operator">=</span> root.left;</span><br><span class="line">         <span class="type">Node</span> <span class="variable">right</span> <span class="operator">=</span> root.right;</span><br><span class="line">         <span class="comment">// 左侧双向链表</span></span><br><span class="line">         <span class="type">Node</span> <span class="variable">linkLeft</span> <span class="operator">=</span> treeToDoublyList(left);</span><br><span class="line">         <span class="comment">// 右侧双向链表</span></span><br><span class="line">         <span class="type">Node</span> <span class="variable">linkRight</span> <span class="operator">=</span> treeToDoublyList(right);</span><br><span class="line">         <span class="keyword">if</span>(linkLeft != <span class="literal">null</span>) &#123;</span><br><span class="line">             ret = linkLeft;</span><br><span class="line">             <span class="type">Node</span> <span class="variable">tmp</span> <span class="operator">=</span> linkLeft;</span><br><span class="line">             <span class="comment">// 这里是寻找子树尾结点(后续可以优化)</span></span><br><span class="line">             <span class="keyword">while</span>(tmp.right != <span class="literal">null</span>) &#123;</span><br><span class="line">                 <span class="keyword">if</span>(tmp.right == linkLeft)&#123;</span><br><span class="line">                     <span class="keyword">break</span>;</span><br><span class="line">                 &#125;</span><br><span class="line">                 tmp = tmp.right;</span><br><span class="line">             &#125;</span><br><span class="line">             <span class="comment">// 更新指针指向</span></span><br><span class="line">             tmp.right = root;</span><br><span class="line">             root.left = tmp;</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">if</span>(linkRight != <span class="literal">null</span>) &#123;</span><br><span class="line">             <span class="type">Node</span> <span class="variable">tmp</span> <span class="operator">=</span> linkRight;</span><br><span class="line">             <span class="keyword">while</span>(tmp.right != <span class="literal">null</span>) &#123;</span><br><span class="line">                 <span class="keyword">if</span>(tmp.right == linkRight)&#123;</span><br><span class="line">                     <span class="keyword">break</span>;</span><br><span class="line">                 &#125;</span><br><span class="line">                 tmp = tmp.right;</span><br><span class="line">             &#125;</span><br><span class="line">             <span class="comment">// 更新指针指向</span></span><br><span class="line">             root.right = linkRight;</span><br><span class="line">             linkRight.left = root;</span><br><span class="line">             <span class="comment">// 更新头尾节点的指向关系</span></span><br><span class="line">             tmp.right = ret;</span><br><span class="line">             ret.left = tmp;</span><br><span class="line">         &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">             ret.left = root;</span><br><span class="line">             root.right = ret;</span><br><span class="line">         &#125;</span><br><span class="line">         <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://leetcode.cn/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/&quot;&gt;二叉搜索树与双向链表&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;输入一棵二叉搜索树，将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点，只能调整树中节点指针的指向。&lt;/p&gt;</summary>
    
    
    
    
    <category term="leetcode" scheme="http://example.com/tags/leetcode/"/>
    
    <category term="算法" scheme="http://example.com/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="树" scheme="http://example.com/tags/%E6%A0%91/"/>
    
    <category term="链表" scheme="http://example.com/tags/%E9%93%BE%E8%A1%A8/"/>
    
  </entry>
  
  <entry>
    <title>长度最小的子数组</title>
    <link href="http://example.com/2022/06/07/%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84/"/>
    <id>http://example.com/2022/06/07/%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84/</id>
    <published>2022-06-07T01:41:20.000Z</published>
    <updated>2022-12-03T10:25:37.392Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://leetcode.cn/problems/minimum-size-subarray-sum/">长度最小的子数组</a></p><p>给定一个含有 n 个正整数的数组和一个正整数 target 。</p><p>找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ，并返回其长度。如果不存在符合条件的子数组，返回 0 。</p><span id="more"></span><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">输入：target = 7, nums = [2,3,1,2,4,3]</span><br><span class="line">输出：2</span><br><span class="line">解释：子数组 [4,3] 是该条件下的长度最小的子数组。</span><br></pre></td></tr></table></figure><p>思路: 先遍历找到第一个累加到大于等于target的索引值idx,找不到就返回0. 随后设置左指针为0, 右指针为idx. 通过控制左右指针移动寻找最短连续子数组长度</p><p>代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">minSubArrayLen</span><span class="params">(<span class="type">int</span> target, <span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="comment">// 最短长度</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">match</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="comment">// 当前累计和</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="comment">// 从0开始第一个累计和达到target的索引</span></span><br><span class="line">        <span class="type">int</span> <span class="variable">beginIdx</span> <span class="operator">=</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; nums.length; i++) &#123;</span><br><span class="line">            sum += nums[i];</span><br><span class="line">            <span class="keyword">if</span>(sum &gt;= target) &#123;</span><br><span class="line">                beginIdx = i;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(beginIdx == -<span class="number">1</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="type">int</span> <span class="variable">l</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">        <span class="type">int</span> <span class="variable">r</span> <span class="operator">=</span> beginIdx;</span><br><span class="line">        <span class="keyword">while</span>(l &lt;= r &amp;&amp; r &lt; nums.length) &#123;</span><br><span class="line">            <span class="keyword">if</span>(sum &gt;= target) &#123;</span><br><span class="line">                match = Math.min(match, r - l + <span class="number">1</span>);</span><br><span class="line">                <span class="keyword">if</span>(match == <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// 当前sum满足条件,尝试左指针右移并更新sum</span></span><br><span class="line">                sum -= nums[l];</span><br><span class="line">                l++;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 当前sum不满足条件,右指针右移并更新sum</span></span><br><span class="line">                r++;</span><br><span class="line">                <span class="keyword">if</span>(r &gt;= nums.length)&#123;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                sum += nums[r];</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> match;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://leetcode.cn/problems/minimum-size-subarray-sum/&quot;&gt;长度最小的子数组&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;给定一个含有 n 个正整数的数组和一个正整数 target 。&lt;/p&gt;
&lt;p&gt;找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ，并返回其长度。如果不存在符合条件的子数组，返回 0 。&lt;/p&gt;</summary>
    
    
    
    
    <category term="leetcode" scheme="http://example.com/tags/leetcode/"/>
    
    <category term="算法" scheme="http://example.com/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="双指针" scheme="http://example.com/tags/%E5%8F%8C%E6%8C%87%E9%92%88/"/>
    
  </entry>
  
  <entry>
    <title>复制带随机指针的链表</title>
    <link href="http://example.com/2022/06/07/%E5%A4%8D%E5%88%B6%E5%B8%A6%E9%9A%8F%E6%9C%BA%E6%8C%87%E9%92%88%E7%9A%84%E9%93%BE%E8%A1%A8/"/>
    <id>http://example.com/2022/06/07/%E5%A4%8D%E5%88%B6%E5%B8%A6%E9%9A%8F%E6%9C%BA%E6%8C%87%E9%92%88%E7%9A%84%E9%93%BE%E8%A1%A8/</id>
    <published>2022-06-07T01:04:43.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<h4 id="复制带随机指针的链表"><a href="#复制带随机指针的链表" class="headerlink" title="复制带随机指针的链表"></a><a href="https://leetcode.cn/problems/copy-list-with-random-pointer/">复制带随机指针的链表</a></h4><p>给你一个长度为 n 的链表，每个节点包含一个额外增加的随机指针 random ，该指针可以指向链表中的任何节点或空节点。</p><p>构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成，其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点，并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。</p><span id="more"></span><p>例如，如果原链表中有 X 和 Y 两个节点，其中 X.random –&gt; Y 。那么在复制链表中对应的两个节点 x 和 y ，同样有 x.random –&gt; y 。</p><p>返回复制链表的头节点。</p><p>用一个由 n 个节点组成的链表来表示输入&#x2F;输出中的链表。每个节点用一个 [val, random_index] 表示：</p><p>val：一个表示 Node.val 的整数。<br>random_index：随机指针指向的节点索引（范围从 0 到 n-1）；如果不指向任何节点，则为  null 。<br>你的代码 只 接受原链表的头节点 head 作为传入参数。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入：head = [[7,null],[13,0],[11,4],[10,2],[1,0]]</span><br><span class="line">输出：[[7,null],[13,0],[11,4],[10,2],[1,0]]</span><br></pre></td></tr></table></figure><p>思路：首先遍历原链表，并在遍历过程中创建复制节点，并且维护一个新旧节点的映射关系。然后第二次遍历时，根据映射关系，找出每一个random节点在新链表的节点并指向它。</p><p>代码：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> Node <span class="title function_">copyRandomList</span><span class="params">(Node head)</span> &#123;</span><br><span class="line">        <span class="keyword">if</span>(head == <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="keyword">return</span> head;</span><br><span class="line">        &#125;</span><br><span class="line">        Map&lt;Node, Node&gt; nmap = <span class="keyword">new</span> <span class="title class_">HashMap</span>();</span><br><span class="line">        <span class="type">Node</span> <span class="variable">bak</span> <span class="operator">=</span> head;</span><br><span class="line">        <span class="type">Node</span> <span class="variable">node</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Node</span>(head.val);</span><br><span class="line">        <span class="type">Node</span> <span class="variable">nodebak</span> <span class="operator">=</span> node;</span><br><span class="line">        <span class="type">Node</span> <span class="variable">ret</span> <span class="operator">=</span> node;</span><br><span class="line">        nmap.put(head, node);</span><br><span class="line">        head = head.next;</span><br><span class="line">        <span class="keyword">while</span>(head != <span class="literal">null</span>) &#123;</span><br><span class="line">            <span class="type">Node</span> <span class="variable">next</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Node</span>(head.val);</span><br><span class="line">            nmap.put(head, next);</span><br><span class="line">            node.next = next;</span><br><span class="line">            node = node.next;</span><br><span class="line">            head = head.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(bak!=<span class="literal">null</span>)&#123;</span><br><span class="line">            <span class="type">Node</span> <span class="variable">radom</span> <span class="operator">=</span> bak.random;</span><br><span class="line">            <span class="type">Node</span> <span class="variable">rnode</span> <span class="operator">=</span> nmap.get(radom);</span><br><span class="line">            nodebak.random = rnode;</span><br><span class="line">            nodebak = nodebak.next;</span><br><span class="line">            bak = bak.next;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> ret;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h4 id=&quot;复制带随机指针的链表&quot;&gt;&lt;a href=&quot;#复制带随机指针的链表&quot; class=&quot;headerlink&quot; title=&quot;复制带随机指针的链表&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://leetcode.cn/problems/copy-list-with-random-pointer/&quot;&gt;复制带随机指针的链表&lt;/a&gt;&lt;/h4&gt;&lt;p&gt;给你一个长度为 n 的链表，每个节点包含一个额外增加的随机指针 random ，该指针可以指向链表中的任何节点或空节点。&lt;/p&gt;
&lt;p&gt;构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成，其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点，并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。&lt;/p&gt;</summary>
    
    
    
    
    <category term="leetcode" scheme="http://example.com/tags/leetcode/"/>
    
    <category term="算法" scheme="http://example.com/tags/%E7%AE%97%E6%B3%95/"/>
    
  </entry>
  
  <entry>
    <title>打家劫舍</title>
    <link href="http://example.com/2022/06/05/%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D/"/>
    <id>http://example.com/2022/06/05/%E6%89%93%E5%AE%B6%E5%8A%AB%E8%88%8D/</id>
    <published>2022-06-05T07:38:58.000Z</published>
    <updated>2022-12-03T10:25:37.384Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://leetcode.cn/problems/house-robber/">打家劫舍</a></p><p>你是一个专业的小偷，计划偷窃沿街的房屋。每间房内都藏有一定的现金，影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统，如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报警。</p><p>给定一个代表每个房屋存放金额的非负整数数组，计算你 不触动警报装置的情况下 ，一夜之内能够偷窃到的最高金额。</p><span id="more"></span><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">输入：[1,2,3,1]</span><br><span class="line">输出：4</span><br><span class="line">解释：偷窃 1 号房屋 (金额 = 1) ，然后偷窃 3 号房屋 (金额 = 3)。</span><br><span class="line">     偷窃到的最高金额 = 1 + 3 = 4 。</span><br></pre></td></tr></table></figure><p>思路1: 递归实现,以任一个房屋开始,对于下一个不触发警报的房屋进行决策:是否偷他?! 然后对于不同的状况继续进行偷取. 在每一次偷取成功后就尝试更新最大偷盗金额.</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">rob</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        rob(nums, <span class="number">0</span>, <span class="number">0</span>, <span class="literal">null</span>);</span><br><span class="line">        <span class="keyword">return</span> max;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * home 当前偷到哪一个房子了</span></span><br><span class="line"><span class="comment">     * money 当前偷了多少钱了</span></span><br><span class="line"><span class="comment">     * last 最后一个偷的房间</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">rob</span><span class="params">(<span class="type">int</span>[] nums, <span class="type">int</span> home, <span class="type">int</span> money, Integer last)</span> &#123;</span><br><span class="line">        max = Math.max(max, money);</span><br><span class="line">        <span class="keyword">if</span>(home &gt;= nums.length) &#123;</span><br><span class="line">            <span class="keyword">return</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> home; i &lt; nums.length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(last == <span class="literal">null</span>) &#123;</span><br><span class="line">                rob(nums, i, nums[i] + money, i);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="comment">// 确认不会触发报警</span></span><br><span class="line">                <span class="keyword">if</span>(i &gt; last + <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="comment">// 偷,然后继续下一个房间</span></span><br><span class="line">                    rob(nums, i, nums[i] + money, i);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(last == <span class="literal">null</span>) &#123;</span><br><span class="line">                rob(nums, i+<span class="number">1</span>, money, i+<span class="number">1</span>);</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">if</span>(i &gt; last + <span class="number">1</span>) &#123;</span><br><span class="line">                    <span class="comment">// 不偷,继续下一个房间</span></span><br><span class="line">                    rob(nums, i + <span class="number">1</span>, money, i + <span class="number">1</span>);</span><br><span class="line">                &#125;</span><br><span class="line"></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>思路2: 动态规划, 定义dp数组, dp[i] 代表到第i位最大的金额,存在状态转移关系:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">dp[i] = nums[i] i == 0</span><br><span class="line">dp[i] = max(nums[i], dp[i-1], dp[i-1]) i &gt; 0, i &gt; 1</span><br></pre></td></tr></table></figure><p>代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="type">int</span> <span class="variable">max</span> <span class="operator">=</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">rob</span><span class="params">(<span class="type">int</span>[] nums)</span> &#123;</span><br><span class="line">        <span class="type">int</span> <span class="variable">length</span> <span class="operator">=</span> nums.length;</span><br><span class="line">        <span class="type">int</span>[] dp = <span class="keyword">new</span> <span class="title class_">int</span>[length];</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; length; i++) &#123;</span><br><span class="line">            <span class="keyword">if</span>(i == <span class="number">0</span>) &#123;</span><br><span class="line">                dp[i] = nums[i];</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="type">int</span> <span class="variable">last</span> <span class="operator">=</span> i - <span class="number">2</span>;</span><br><span class="line">                <span class="type">int</span> <span class="variable">last2</span> <span class="operator">=</span> i - <span class="number">1</span>;</span><br><span class="line">                <span class="keyword">if</span>(last2 &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">                    dp[i] = Math.max(dp[i], dp[i - <span class="number">1</span>]);</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(last &gt;= <span class="number">0</span>) &#123;</span><br><span class="line">                    dp[i] = Math.max(dp[last] + nums[i], dp[i]);</span><br><span class="line">                &#125; </span><br><span class="line">                dp[i] = Math.max(dp[i], nums[i]);</span><br><span class="line">                </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> dp[length - <span class="number">1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://leetcode.cn/problems/house-robber/&quot;&gt;打家劫舍&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;你是一个专业的小偷，计划偷窃沿街的房屋。每间房内都藏有一定的现金，影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统，如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报警。&lt;/p&gt;
&lt;p&gt;给定一个代表每个房屋存放金额的非负整数数组，计算你 不触动警报装置的情况下 ，一夜之内能够偷窃到的最高金额。&lt;/p&gt;</summary>
    
    
    
    
    <category term="leetcode" scheme="http://example.com/tags/leetcode/"/>
    
    <category term="算法" scheme="http://example.com/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="dp" scheme="http://example.com/tags/dp/"/>
    
    <category term="递归" scheme="http://example.com/tags/%E9%80%92%E5%BD%92/"/>
    
  </entry>
  
  <entry>
    <title>基本计算器II</title>
    <link href="http://example.com/2022/06/05/%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8II/"/>
    <id>http://example.com/2022/06/05/%E5%9F%BA%E6%9C%AC%E8%AE%A1%E7%AE%97%E5%99%A8II/</id>
    <published>2022-06-05T05:06:36.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://leetcode.cn/problems/basic-calculator-ii/">基本计算器 II</a></p><p>给你一个字符串表达式 s ，请你实现一个基本计算器来计算并返回它的值。</p><p>整数除法仅保留整数部分。</p><p>你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。</p><p>注意：不允许使用任何将字符串作为数学表达式计算的内置函数，比如 eval() 。</p><span id="more"></span><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">输入：s = &quot;3+2*2&quot;</span><br><span class="line">输出：7</span><br></pre></td></tr></table></figure><p>思路: 维护一个操作符栈和操作数栈以及操作符优先级字典. 流程如下: 遇到数字入栈,遇到操作符,如果优先级小于已入栈的操作符, 计算之前大于该操作符的操作,并将计算结果入栈操作数栈. 然后入栈新操作符,重复以上操作. 最终返回操作符栈剩下的结果即可.</p><p>代码:</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> &#123;</span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">calculate</span><span class="params">(String s)</span> &#123;</span><br><span class="line">        Stack&lt;Integer&gt; nums = <span class="keyword">new</span> <span class="title class_">Stack</span>();</span><br><span class="line">        Stack&lt;Character&gt; ops = <span class="keyword">new</span> <span class="title class_">Stack</span>();</span><br><span class="line">        <span class="type">StringBuilder</span> <span class="variable">sb</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">        Map&lt;Character, Integer&gt; pmap = <span class="keyword">new</span> <span class="title class_">HashMap</span>();</span><br><span class="line">        pmap.put(<span class="string">&#x27;+&#x27;</span>, <span class="number">1</span>);</span><br><span class="line">        pmap.put(<span class="string">&#x27;-&#x27;</span>, <span class="number">1</span>);</span><br><span class="line">        pmap.put(<span class="string">&#x27;*&#x27;</span>, <span class="number">2</span>);</span><br><span class="line">        pmap.put(<span class="string">&#x27;/&#x27;</span>, <span class="number">2</span>);</span><br><span class="line">        <span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; s.length(); i++) &#123;</span><br><span class="line">            <span class="type">char</span> <span class="variable">c</span> <span class="operator">=</span> s.charAt(i);</span><br><span class="line">            <span class="keyword">if</span>(c == <span class="string">&#x27; &#x27;</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span>(!sb.isEmpty()) &#123;</span><br><span class="line">                    nums.push(Integer.parseInt(sb.toString()));</span><br><span class="line">                    sb = <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">continue</span>;</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">if</span>(pmap.containsKey(c)) &#123;</span><br><span class="line">                <span class="keyword">if</span>(!sb.isEmpty()) &#123;</span><br><span class="line">                    nums.push(Integer.parseInt(sb.toString()));</span><br><span class="line">                    sb = <span class="keyword">new</span> <span class="title class_">StringBuilder</span>();</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">if</span>(ops.isEmpty()) &#123;</span><br><span class="line">                    ops.push(c);</span><br><span class="line">                &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="keyword">while</span>(!ops.isEmpty() &amp;&amp; pmap.get(ops.peek()) &gt;= pmap.get(c)) &#123;</span><br><span class="line">                        <span class="type">int</span> <span class="variable">v2</span> <span class="operator">=</span> nums.pop();</span><br><span class="line">                        <span class="type">int</span> <span class="variable">v1</span> <span class="operator">=</span> nums.pop();</span><br><span class="line">                        nums.push(calc(v1, v2, ops.pop()));   </span><br><span class="line">                    &#125;</span><br><span class="line">                    ops.push(c);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                sb.append(c);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(!sb.isEmpty()) &#123;</span><br><span class="line">            nums.push(Integer.parseInt(sb.toString()));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">while</span>(!ops.isEmpty())&#123;</span><br><span class="line">            <span class="type">int</span> <span class="variable">v2</span> <span class="operator">=</span> nums.pop();</span><br><span class="line">            <span class="type">int</span> <span class="variable">v1</span> <span class="operator">=</span> nums.pop();</span><br><span class="line">            nums.push(calc(v1, v2, ops.pop()));</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> nums.pop();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">calc</span><span class="params">(<span class="type">int</span> v1, <span class="type">int</span> v2, <span class="type">char</span> op)</span> &#123;</span><br><span class="line">        <span class="keyword">switch</span>(op) &#123;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;+&#x27;</span>:</span><br><span class="line">                <span class="keyword">return</span> v1 + v2;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;-&#x27;</span>:</span><br><span class="line">                <span class="keyword">return</span> v1 - v2;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;*&#x27;</span>:</span><br><span class="line">                <span class="keyword">return</span> v1 * v2;</span><br><span class="line">            <span class="keyword">case</span> <span class="string">&#x27;/&#x27;</span>:</span><br><span class="line">                <span class="keyword">return</span> v1 / v2;</span><br><span class="line">            <span class="keyword">default</span>:</span><br><span class="line">                <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;p&gt;&lt;a href=&quot;https://leetcode.cn/problems/basic-calculator-ii/&quot;&gt;基本计算器 II&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;给你一个字符串表达式 s ，请你实现一个基本计算器来计算并返回它的值。&lt;/p&gt;
&lt;p&gt;整数除法仅保留整数部分。&lt;/p&gt;
&lt;p&gt;你可以假设给定的表达式总是有效的。所有中间结果将在 [-231, 231 - 1] 的范围内。&lt;/p&gt;
&lt;p&gt;注意：不允许使用任何将字符串作为数学表达式计算的内置函数，比如 eval() 。&lt;/p&gt;</summary>
    
    
    
    
    <category term="leetcode" scheme="http://example.com/tags/leetcode/"/>
    
    <category term="算法" scheme="http://example.com/tags/%E7%AE%97%E6%B3%95/"/>
    
    <category term="stack" scheme="http://example.com/tags/stack/"/>
    
  </entry>
  
  <entry>
    <title>基础数据结构</title>
    <link href="http://example.com/2022/06/05/%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    <id>http://example.com/2022/06/05/%E5%9F%BA%E7%A1%80%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/</id>
    <published>2022-06-05T03:32:08.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p>数组, 链表</p><p>栈, 堆, 树, 图</p><span id="more"></span><ol><li><p>数组</p></li><li><p>链表</p><p>优点:</p><p>缺点: 节点内存不连续, 无法很好的利用CPU缓存. 同时链表需要维护指针带来的内存开销</p></li></ol>]]></content>
    
    
    <summary type="html">&lt;p&gt;数组, 链表&lt;/p&gt;
&lt;p&gt;栈, 堆, 树, 图&lt;/p&gt;</summary>
    
    
    
    
    <category term="数据结构" scheme="http://example.com/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
    
  </entry>
  
  <entry>
    <title>英文面试自我介绍</title>
    <link href="http://example.com/2022/06/05/%E8%8B%B1%E6%96%87%E9%9D%A2%E8%AF%95%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D/"/>
    <id>http://example.com/2022/06/05/%E8%8B%B1%E6%96%87%E9%9D%A2%E8%AF%95%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D/</id>
    <published>2022-06-05T02:59:50.000Z</published>
    <updated>2022-12-03T10:25:37.384Z</updated>
    
    <content type="html"><![CDATA[<p>转自: <a href="https://zhuanlan.zhihu.com/p/30566237">英文面试准备</a></p><p>外企面试，英文自我介绍是必答题，是送分题。</p><p>无论是电话面试，还是face to face面试，只要能流利，语速适度的完成1分钟左右自我介绍，基本都可以通关。</p><p>而大部分面试者，要么没有准备，要么磕磕巴巴，要么自我介绍太长，要么语速过快……</p><p>如果你面试环节的自我介绍被面试官打断了，99%是个失败的自我介绍。 </p><span id="more"></span><h2 id="01-自我介绍方程式"><a href="#01-自我介绍方程式" class="headerlink" title="01 自我介绍方程式"></a><strong>01 自我介绍方程式</strong></h2><h2 id="A-For-New-Graduates-毕业生自我介绍"><a href="#A-For-New-Graduates-毕业生自我介绍" class="headerlink" title="A. For New Graduates 毕业生自我介绍"></a><strong>A. For New Graduates 毕业生自我介绍</strong></h2><p>我叫小小，xx大学，xx专业毕业。大学期间我顺利通过xx级，xx级，拿到xx证书，我的平均成绩都在Top xx，我是xx协会的xx，是xx志愿者，我在平时还参加了xx实践项目。我熟练掌握英语、计算机和xx，精通office软件，具有(可以开始说你的各种能力)良好的沟通能力，xx能力，xx能力，xx能力，和人际交往能力….我相信我很适合xx职位.谢谢。</p><p>I am <strong>Xiao Xiao</strong>. I recently graduated from <strong>×× University</strong> with a <strong>bachelor degree in Business Accounting</strong>. My GPA was among the <strong>top 3</strong> in my class. I passed <strong>CET6.</strong> Besides studying I was very active on campus. I participated in <strong>volunteer activities</strong> whenever I had time. I became the <strong>Chairman for the Student Union</strong> during my senior year. I also worked with Baidu as a <strong>Social Media Intern</strong> for a semester. I learned a lot about <strong>content curation</strong> and <strong>using social media tools</strong>. I could speak <strong>（pretty） good English</strong> and I’m fluent in Mandarin Chinese (Hahaha…因为我是中国人). I am highly proficient with <strong>Office.</strong> I have great communication <strong>skills</strong>. I am an <strong>outgoing person</strong>. I am very <strong>responsible and hardworking</strong>. I believe I’m a good fit for the Department Assistant position. Thank you for the opportunity.</p><p>描述顺序拆解：</p><p><img src="/2022/06/05/%E8%8B%B1%E6%96%87%E9%9D%A2%E8%AF%95%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D/v2-e8f4b001bc4db1ad2b8f28bd3ec8f525_r.jpg" alt="v2-e8f4b001bc4db1ad2b8f28bd3ec8f525_r"></p><p><strong>B. For Working Professionals 有工作经验自我介绍</strong></p><p>我是小小，具有xx年xx领域的经验，现在是xx公司xx职位。之前是有xx年xx行业经验，xx行业xx经验。我的专长是xx比如说品牌管理和业务发展。我也很擅长xx比如说项目管理和活动策划。我英语很好英语、计算机和xx，擅长xx， 在工作中，我曾经获得xx等奖项。我有优秀的沟通技能，有很强的团队精神和自我驱动力。我相信以我的经验和热情我能够在xx岗位上给xx公司的成功做出贡献。谢谢。</p><p>I am <strong>Xiao Xiao</strong>. I have <strong>over 8 years of experience in marketing</strong>. I am the <strong>team manager of marketing for HP since 2013</strong>. Previously I worked in <strong>IT for a year</strong> and <strong>retail for another 4 years or so</strong>. My specialties include <strong>brand management</strong> and <strong>business development</strong>. I’m also very experienced with <strong>project management</strong> and <strong>event coordination</strong>. I was voted the <strong>2016 Best Employee</strong> among my peers. I could speak <strong>（pretty） good English</strong> and I’m fluent in Mandarin Chinese(Hahaha…因为我是中国人). I am highly proficient with <strong>Microsoft Office softwares and Photoshop</strong>. I have <strong>excellent written and verbal communication skills</strong>. I’m a <strong>team player and self-driven</strong>. I believe I have the combination of experience and enthusiasm to contribute to the success of Intel Shanghai as the Senior Manager of Marketing. Thanks. </p><p>描述顺序拆解：</p><p><img src="/2022/06/05/%E8%8B%B1%E6%96%87%E9%9D%A2%E8%AF%95%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D/v2-be67c5fbf089d4a1fe958c16c9bd82bf_1440w.jpg.png" alt="v2-be67c5fbf089d4a1fe958c16c9bd82bf_1440w.jpg"></p><p><strong>C. Top 10个常用句型</strong></p><p><strong>计算机和英语证书</strong></p><p>I am highly proficient with…</p><p><strong>学习成绩优秀</strong></p><p>My grades were top in the class.</p><p><strong>社团&#x2F;志愿者&#x2F;实践项目</strong></p><p>I was very active on campus.</p><p>I’ve participated in many campus groups, volunteer programs, and practical activities</p><p><strong>具备能力</strong></p><p>I’m passionate about…</p><p>I’m very familiar with…</p><p>I’m experienced with…</p><p><strong>行业经验</strong></p><p>I’ve work in marketing&#x2F;sales&#x2F;business development&#x2F;international education for X years</p><p><strong>管理经验</strong></p><p>I have x years of management experiences</p><p><strong>项目经验</strong></p><p>I took the lead in xxx project which was very successful.</p><p><strong>获奖经历</strong></p><p>I was recognized as…</p><p>I was awarded the…</p><p>I was voted the…</p><p><strong>性格特质</strong></p><p>I’m a people person.</p><p>I’m a team player.</p><p>I’m very hardworking.</p><p>I’m super self-driven.</p><p><strong>职位匹配描述</strong></p><p>I believe I have the right combination of experience and enthusiasm to be successful in xxx position.</p><p>I believe I am a good fit for xxx company as the xxx position. </p><p>I believe I can do a great job as your xxx.</p><p><strong>D: General Skill list 通用技能列表</strong></p><p><strong>Personality and Characteristics 好用的性格和特征</strong></p><p>A people person; 善于与人打交道的人</p><p>A team player; 善于团队合作的人</p><p>A good listener;好的倾听者</p><p>A good leader; 好的领导</p><p>An analytical thinker; 善于分析的思考者</p><p>Hard working; 勤奋的</p><p>Self-motivated;有上进心的，积极主动的</p><p>Very driven;自我驱动很强的</p><p>Adaptable; 适应能力不错</p><p>Energetic;精力充沛的</p><p>Proactive;积极主动的</p><p>Business oriented;商业&#x2F;业务导向的</p><p>Results oriented;结果导向的</p><p>High attention to detail; 非常关注细节</p><p><strong>Skills 技能</strong></p><p>Excellent communication skills; 卓越的沟通技能</p><p>Outstanding organization skills; 出众的组织技能</p><p>Great verbal and written communication<br>skills in English and Chinese; 优秀的中英文口语和书面交流技能</p><p>Good interpersonal skills; 很好的交际能力</p><p>Fantastic organizational skills; 极好组织能力</p><p>Excellent time management skills;卓越的时间管理技能</p><p>Fantastic negotiation skills；极好的谈判技能</p><p>Strong analytical skills; 很强的分析能力</p><p>Highly proficient in PC skills.精通电脑</p><p><strong>Abilities 能力</strong></p><p>Ability to work effectively with staff at all levels; 能和各个级别员工高效工作</p><p>Ability to interpret financial statements&#x2F;statistics; 解释财务报表&#x2F;统计数据的能力</p><p>Strong problem solving ability; 较强的问题处理能力</p><p>Strong business acumen; 良好的商业敏感度</p><p>Ability to prioritize and work within tight timeframe; 能在时间紧迫的情况下安排工作优先等级</p><p>Excellent research ability; 优秀的研究&#x2F;调研能力</p><p>Very familiar with labor law and related policies in China; 非常熟悉劳动法和中国的相关政策法规</p><p>Fluent in both English and Mandarin Chinese;英语和中文都很流利</p><p>Tech savvy；科技通</p><p>Ability to adapt quickly to any new accounting&#x2F;information system; 能够迅速适应任何新会计&#x2F;信息系统</p><p><strong>Computer skills 电脑技能</strong></p><p>Good at Office 精通 Office</p><p>Proficient in Photoshop 精通PS</p><p>High proficiency in PowerPoint 精通PPT</p><p>Advanced level proficiency in Excel 精通Excel</p><p><strong>Certificate List 证书列表</strong></p><p>CET-4;四级</p><p>CET-6;六级</p><p>Certificate of English Interpreting:<br>Preliminary; 英语初级口译</p><p>Certificate of English Interpreting:<br>Intermediate; 英语中级口译</p><p>Certificate of English Interpreting:<br>Advanced; 英语高级口译</p><p>Certificate of Teachers’Qualification (English); 教师资格证书</p><p>Certificate of Mandarin Test.普通话测试证书</p><p>……</p><p><strong>Personality and characteristics 更多性格特质形容词</strong></p><p>aggressive有进取心的,攻击性的 (这不是一个好的特质，听起来像是很有野心)</p><p>passionate&#x2F;enthusiastic 热情的</p><p>creative 富有创造性（力）的</p><p>insightful 富有洞察力的</p><p>diligent 好学的,勤奋的</p><p>liberal 慷慨的,不拘泥的,宽大的</p><p>nice 友善的</p><p>Kind 善良的</p><p>friendly 友善的</p><p>considerate考虑周到的,体谅的</p><p>humorous 幽默的</p><p>confident 自信的</p><p>imaginative 富想像力的</p><p>responsible 负责的</p><p>courageous 勇敢的</p><p>independent 独立的</p><p>demanding 要求多的 （a demanding position对员工要求很多，很高的职位）</p><p>individualistic 个人主义的</p><p>efficient 效率高的,有能力的</p><p>energetic 精力旺盛的</p><p>loyal 忠诚的</p><p>modest 谦虚的</p><p>thoughtful 考虑周到的</p><p>motivated 有动力的</p><p>positive&#x2F;optimistic 积极的&#x2F;乐观的</p><p>open-minded 思想开明的</p><p>trustworthy 值得信赖的</p><p>gentle 温文尔雅的</p><p>precise 精确的</p><p>good-natured 脾气好的,温厚的</p><p>idealistic 理想主义的</p><p>witty 急智的</p><p>wise 明智的,聪明的</p><p>smart&#x2F;intelligent&#x2F;clever 聪明的</p><p>outgoing&#x2F;sociable 爱好交际的</p><p>easy-going 随和的,跟谁都处得来</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;转自: &lt;a href=&quot;https://zhuanlan.zhihu.com/p/30566237&quot;&gt;英文面试准备&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;外企面试，英文自我介绍是必答题，是送分题。&lt;/p&gt;
&lt;p&gt;无论是电话面试，还是face to face面试，只要能流利，语速适度的完成1分钟左右自我介绍，基本都可以通关。&lt;/p&gt;
&lt;p&gt;而大部分面试者，要么没有准备，要么磕磕巴巴，要么自我介绍太长，要么语速过快……&lt;/p&gt;
&lt;p&gt;如果你面试环节的自我介绍被面试官打断了，99%是个失败的自我介绍。 &lt;/p&gt;</summary>
    
    
    
    
    <category term="面试" scheme="http://example.com/tags/%E9%9D%A2%E8%AF%95/"/>
    
    <category term="英语" scheme="http://example.com/tags/%E8%8B%B1%E8%AF%AD/"/>
    
  </entry>
  
  <entry>
    <title>Redis数据结构底层原</title>
    <link href="http://example.com/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/"/>
    <id>http://example.com/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/</id>
    <published>2022-06-04T14:10:02.000Z</published>
    <updated>2022-12-03T10:25:37.376Z</updated>
    
    <content type="html"><![CDATA[<p>参考: <a href="https://www.cnblogs.com/xiaolincoding/p/15628854.html">Redis数据结构</a></p><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-lastnew.png" alt="redis数据结构-lastnew"></p><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/redis%E5%85%A8%E6%99%AF%E5%9B%BE.png" alt="redis全景图"></p><p>*redis存储访问流程</p><ul><li>redisDb 结构，表示 Redis 数据库的结构，结构体里存放了指向了 dict 结构的指针；</li><li>dict 结构，结构体里存放了 2 个哈希表，正常情况下都是用「哈希表1」，「哈希表2」只有在 rehash 的时候才用；</li><li>ditctht 结构，表示哈希表的结构，结构里存放了哈希表数组，数组中的每个元素都是指向一个哈希表节点结构（dictEntry）的指针；</li><li>dictEntry 结构，表示哈希表节点的结构，结构里存放了 <strong>void * key 和 void * value 指针， *key 指向的是 String 对象，而 *value 则可以指向 String 对象，也可以指向集合类型的对象，比如 List 对象、Hash 对象、Set 对象和 Zset 对象</strong>。</li></ul><span id="more"></span><h1 id="string：字符串"><a href="#string：字符串" class="headerlink" title="string：字符串"></a>string：字符串</h1><p>redis使用c语言开发, 在redis中，其自己定义了一种字符串格式，叫做SDS（Simple Dynamic String），即简单动态字符串. 结构定义sds.h:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="type">char</span> *sds;</span><br></pre></td></tr></table></figure><p>sds包含以下属性:</p><ul><li>len：已使用的长度，即字符串的真实长度. 降低获取字符串长度复杂度到O(1). 同时帮助二进制安全</li><li>alloc：分配的长度, 除去标头和终止符(‘\0’)后的长度. 减少而内存分配次数</li><li>flags：表示不同类型的SDS, 低3位表示</li><li>buf[]：存储字符数据</li></ul><h1 id="list：列表"><a href="#list：列表" class="headerlink" title="list：列表"></a>list：列表</h1><p>使用双向链表, 获取节点前后节点时间复杂度O(1),获取头尾节点也是O(1). 同时链表使用指针保存值, 可以保存各种类型的数据.</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">list</span> &#123;</span></span><br><span class="line">    <span class="comment">//链表头节点</span></span><br><span class="line">    listNode *head;</span><br><span class="line">    <span class="comment">//链表尾节点</span></span><br><span class="line">    listNode *tail;</span><br><span class="line">    <span class="comment">//节点值复制函数</span></span><br><span class="line">    <span class="type">void</span> *(*dup)(<span class="type">void</span> *ptr);</span><br><span class="line">    <span class="comment">//节点值释放函数</span></span><br><span class="line">    <span class="type">void</span> (*<span class="built_in">free</span>)(<span class="type">void</span> *ptr);</span><br><span class="line">    <span class="comment">//节点值比较函数</span></span><br><span class="line">    <span class="type">int</span> (*match)(<span class="type">void</span> *ptr, <span class="type">void</span> *key);</span><br><span class="line">    <span class="comment">//链表节点数量</span></span><br><span class="line">    <span class="type">unsigned</span> <span class="type">long</span> len;</span><br><span class="line">&#125; <span class="built_in">list</span>;</span><br><span class="line"></span><br></pre></td></tr></table></figure><ul><li><p>ziplist</p><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/%E5%8E%8B%E7%BC%A9%E5%88%97%E8%A1%A8%E8%8A%82%E7%82%B9%E7%BB%93%E6%9E%84.png" alt="压缩列表节点结构"></p><p>相比链表, 设计为更为内存紧凑的数据结构, 可以有效利用CPU缓存. 而且针对不同长度数据进行编码以节省内存开销. 同样存在缺陷: 不可以保存过多的元素,新增修改元素时,内存需要重分配和引发连锁更新问题.</p><ul><li>zlbytes：4个字节（32bits），表示ziplist占用的总字节数</li><li>zltail：4个字节（32bits），表示ziplist中最后一个节点在ziplist中的偏移字节数</li><li>entries：2个字节（16bits），表示ziplist中的元素数</li><li>entry：长度不定，表示ziplist中的数据 (内部包含prevlen: 记录前一个节点长度(如果内存重新分配,后续的该字段都要更新,造成性能下降–<strong>连锁更新问题</strong>), encoding: 记录当前节点类型与长度, data: 数据)</li><li>zlend：1个字节（8bits），表示结束标记，这个值固定为ff（255）</li></ul><p>这些数据均为小端存储，所以可能有些人查看数据的二进制流与其含义对应不上，其实是因为读数据的方式错了</p><p>ziplist内部采取数据压缩的方式进行存储，压缩方式就不是重点了，我们仅从宏观来看，ziplist类似一个封装的数组，通过zltail可以方便地进行追加和删除尾部数据、使用entries可以方便地计算长度</p><p>但是其依然有数组的缺点，就是当插入和删除数据时会频繁地引起数据移动，所以就引出了quicklist数据类型</p></li><li><p>quick list</p><p>「双向链表 + 压缩列表」组合，因为一个 quicklist 就是一个链表，而链表中的每个元素又是一个压缩列表。</p><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/quicklist.png" alt="quicklist"></p></li><li><p>listpack</p><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/listpack%E8%8A%82%E7%82%B9.png" alt="listpack节点"></p></li></ul><h1 id="hash：散列表"><a href="#hash：散列表" class="headerlink" title="hash：散列表"></a>hash：散列表</h1><p><img src="/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%BB%93%E6%9E%84.png" alt="哈希表结构"></p><ul><li>哈希冲突</li><li>链式哈希</li><li>rehash</li><li>渐进式 rehash</li><li>rehash 触发条件</li></ul><h1 id="set：无序集合"><a href="#set：无序集合" class="headerlink" title="set：无序集合"></a>set：无序集合</h1><p>整数集合是 Set 对象的底层实现之一。当一个 Set 对象只包含整数值元素，并且元素数量不时，就会使用整数集这个数据结构作为底层实现。</p><ul><li>整数集合</li></ul><h1 id="zset：有序集合"><a href="#zset：有序集合" class="headerlink" title="zset：有序集合"></a>zset：有序集合</h1><p>内部使用跳表</p><ul><li>跳表</li></ul><p>待补充</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;参考: &lt;a href=&quot;https://www.cnblogs.com/xiaolincoding/p/15628854.html&quot;&gt;Redis数据结构&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-lastnew.png&quot; alt=&quot;redis数据结构-lastnew&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/2022/06/04/Redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%BA%95%E5%B1%82%E5%8E%9F/redis%E5%85%A8%E6%99%AF%E5%9B%BE.png&quot; alt=&quot;redis全景图&quot;&gt;&lt;/p&gt;
&lt;p&gt;*redis存储访问流程&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;redisDb 结构，表示 Redis 数据库的结构，结构体里存放了指向了 dict 结构的指针；&lt;/li&gt;
&lt;li&gt;dict 结构，结构体里存放了 2 个哈希表，正常情况下都是用「哈希表1」，「哈希表2」只有在 rehash 的时候才用；&lt;/li&gt;
&lt;li&gt;ditctht 结构，表示哈希表的结构，结构里存放了哈希表数组，数组中的每个元素都是指向一个哈希表节点结构（dictEntry）的指针；&lt;/li&gt;
&lt;li&gt;dictEntry 结构，表示哈希表节点的结构，结构里存放了 &lt;strong&gt;void * key 和 void * value 指针， *key 指向的是 String 对象，而 *value 则可以指向 String 对象，也可以指向集合类型的对象，比如 List 对象、Hash 对象、Set 对象和 Zset 对象&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;</summary>
    
    
    
    
    <category term="Redis" scheme="http://example.com/tags/Redis/"/>
    
  </entry>
  
  <entry>
    <title>TCP半连接队列和全连接队列溢出</title>
    <link href="http://example.com/2022/06/04/TCP%E5%8D%8A%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E5%92%8C%E5%85%A8%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E6%BA%A2%E5%87%BA/"/>
    <id>http://example.com/2022/06/04/TCP%E5%8D%8A%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E5%92%8C%E5%85%A8%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E6%BA%A2%E5%87%BA/</id>
    <published>2022-06-04T11:38:46.000Z</published>
    <updated>2022-12-03T10:25:37.380Z</updated>
    
    <content type="html"><![CDATA[<p>转自: <a href="https://www.cnblogs.com/sidesky/p/6844228.html">TCP连接队列</a></p><h1 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h1><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">JAVA的client和server，使用socket通信。server使用NIO。</span><br><span class="line">1.间歇性的出现client向server建立连接三次握手已经完成，但server的selector没有响应到这连接。</span><br><span class="line">2.出问题的时间点，会同时有很多连接出现这个问题。</span><br><span class="line">3.selector没有销毁重建，一直用的都是一个。</span><br><span class="line">4.程序刚启动的时候必会出现一些，之后会间歇性出现。</span><br></pre></td></tr></table></figure><span id="more"></span><h1 id="分析问题"><a href="#分析问题" class="headerlink" title="分析问题"></a>分析问题</h1><ul><li>第一步：client 发送 syn 到server 发起握手；</li><li>第二步：server 收到 syn后回复syn+ack给client；</li><li>第三步：client 收到syn+ack后，回复server一个ack表示收到了server的syn+ack（此时client的56911端口的连接已经是established）</li></ul><p>从问题的描述来看，有点像TCP建连接的时候全连接队列（accept队列）满了，尤其是症状2、4. 为了证明是这个原因，马上通过 ss -s 去看队列的溢出统计数据：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">667399 times the listen queue of a socket overflowed</span><br></pre></td></tr></table></figure><p>反复看了几次之后发现这个overflowed 一直在增加，那么可以明确的是server上全连接队列一定溢出了</p><p>接着查看溢出后，OS怎么处理：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># cat /proc/sys/net/ipv4/tcp_abort_on_overflow</span><br><span class="line">0</span><br></pre></td></tr></table></figure><p>tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack（在server端认为连接还没建立起来）</p><p>为了证明客户端应用代码的异常跟全连接队列满有关系，我先把tcp_abort_on_overflow修改成 1，1表示第三步的时候如果全连接队列满了，server发送一个reset包给client，表示废掉这个握手过程和这个连接（本来在server端这个连接就还没建立起来）。</p><p>接着测试然后在客户端异常中可以看到很多connection reset by peer的错误，到此证明客户端错误是这个原因导致的。</p><p>于是开发同学翻看java 源代码发现socket 默认的backlog（这个值控制全连接队列的大小，后面再详述）是50，于是改大重新跑，经过12个小时以上的压测，这个错误一次都没出现过，同时 overflowed 也不再增加了。</p><p>到此问题解决，简单来说TCP三次握手后有个accept队列，进到这个队列才能从Listen变成accept，默认backlog 值是50，很容易就满了。满了之后握手第三步的时候server就忽略了client发过来的ack包（隔一段时间server重发握手第二步的syn+ack包给client），如果这个连接一直排不上队就异常了。</p><h1 id="TCP握手创建流程"><a href="#TCP握手创建流程" class="headerlink" title="TCP握手创建流程"></a>TCP握手创建流程</h1><p><img src="/2022/06/04/TCP%E5%8D%8A%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E5%92%8C%E5%85%A8%E8%BF%9E%E6%8E%A5%E9%98%9F%E5%88%97%E6%BA%A2%E5%87%BA/3d05f574867b70d1134e685e5f5ac137.jpg" alt="3d05f574867b70d1134e685e5f5ac137"></p><p>在 TCP 三次握手的过程中，Linux 内核会维护两个队列，分别是：</p><ul><li>半连接队列 (SYN Queue)</li><li>全连接队列 (Accept Queue)</li></ul><p>正常的 TCP 三次握手过程：</p><ol><li>Client 端向 Server 端发送 SYN 发起握手，Client 端进入 SYN_SENT 状态</li><li>Server 端收到 Client 端的 SYN 请求后，Server 端进入 SYN_RECV 状态，此时内核会将连接存储到半连接队列(SYN Queue)，并向 Client 端回复 SYN+ACK</li><li>Client 端收到 Server 端的 SYN+ACK 后，Client 端回复 ACK 并进入 ESTABLISHED 状态</li><li>Server 端收到 Client 端的 ACK 后，内核将连接从半连接队列(SYN Queue)中取出，添加到全连接队列(Accept Queue)，Server 端进入 ESTABLISHED 状态</li><li>Server 端应用进程调用 accept 函数时，将连接从全连接队列(Accept Queue)中取出</li></ol><p>半连接队列和全连接队列都有长度大小限制，超过限制时内核会将连接 Drop 丢弃或者返回 RST 包。</p><h1 id="相关指标查看"><a href="#相关指标查看" class="headerlink" title="相关指标查看"></a>相关指标查看</h1><ul><li><p>ss 命令</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"># -n 不解析服务名称 </span><br><span class="line"># -t 只显示 tcp sockets </span><br><span class="line"># -l 显示正在监听(LISTEN)的 sockets </span><br><span class="line"> </span><br><span class="line">$ ss -lnt </span><br><span class="line">State      Recv-Q Send-Q    Local Address:Port         Peer Address:Port </span><br><span class="line">LISTEN     0      128       [::]:2380                  [::]:* </span><br><span class="line">LISTEN     0      128       [::]:80                    [::]:* </span><br><span class="line">LISTEN     0      128       [::]:8080                  [::]:* </span><br><span class="line">LISTEN     0      128       [::]:8090                  [::]:* </span><br><span class="line"> </span><br><span class="line">$ ss -nt </span><br><span class="line">State      Recv-Q Send-Q    Local Address:Port         Peer Address:Port </span><br><span class="line">ESTAB      0      0         [::ffff:33.9.95.134]:80                   [::ffff:33.51.103.59]:47452 </span><br><span class="line">ESTAB      0      536       [::ffff:33.9.95.134]:80                  [::ffff:33.43.108.144]:37656 </span><br><span class="line">ESTAB      0      0         [::ffff:33.9.95.134]:80                   [::ffff:33.51.103.59]:38130 </span><br><span class="line">ESTAB      0      536       [::ffff:33.9.95.134]:80                   [::ffff:33.51.103.59]:38280 </span><br><span class="line">ESTAB      0      0         [::ffff:33.9.95.134]:80                   [:: </span><br></pre></td></tr></table></figure><p>LISTEN状态Socket</p><ul><li>Recv-Q：当前全连接队列的大小，即已完成三次握手等待应用程序 accept() 的 TCP 链接</li><li>Send-Q：全连接队列的最大长度，即全连接队列的大小</li></ul><p>非LISTEN状态Socket</p><ul><li>Recv-Q：已收到但未被应用程序读取的字节数</li><li>Send-Q：已发送但未收到确认的字节数</li></ul></li><li><p>netstat命令</p><p>通过 netstat -s 命令可以查看 TCP 半连接队列、全连接队列的溢出情况</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ netstat -s | grep -i &quot;listen&quot; </span><br><span class="line">189088 times the listen queue of a socket overflowed </span><br><span class="line">30140232 SYNs to LISTEN sockets dropped </span><br></pre></td></tr></table></figure><p>上面输出的数值是累计值，分别表示有多少 TCP socket 链接因为全连接队列、半连接队列满了而被丢弃</p><ul><li>189088 times the listen queue of a socket overflowed 代表有 189088 次全连接队列溢出</li><li>30140232 SYNs to LISTEN sockets dropped 代表有 30140232 次半连接队列溢出</li></ul><p>在排查线上问题时，如果一段时间内相关数值一直在上升，则表明半连接队列、全连接队列有溢出情况</p></li></ul><p>其他内容待补充, 参考文首链接</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;转自: &lt;a href=&quot;https://www.cnblogs.com/sidesky/p/6844228.html&quot;&gt;TCP连接队列&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;问题描述&quot;&gt;&lt;a href=&quot;#问题描述&quot; class=&quot;headerlink&quot; title=&quot;问题描述&quot;&gt;&lt;/a&gt;问题描述&lt;/h1&gt;&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;JAVA的client和server，使用socket通信。server使用NIO。&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;1.间歇性的出现client向server建立连接三次握手已经完成，但server的selector没有响应到这连接。&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2.出问题的时间点，会同时有很多连接出现这个问题。&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3.selector没有销毁重建，一直用的都是一个。&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4.程序刚启动的时候必会出现一些，之后会间歇性出现。&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;</summary>
    
    
    
    
    <category term="TCP" scheme="http://example.com/tags/TCP/"/>
    
  </entry>
  
  <entry>
    <title>结构化,半结构化和非结构化数据</title>
    <link href="http://example.com/2022/06/04/%E7%BB%93%E6%9E%84%E5%8C%96-%E5%8D%8A%E7%BB%93%E6%9E%84%E5%8C%96%E5%92%8C%E9%9D%9E%E7%BB%93%E6%9E%84%E5%8C%96%E6%95%B0%E6%8D%AE/"/>
    <id>http://example.com/2022/06/04/%E7%BB%93%E6%9E%84%E5%8C%96-%E5%8D%8A%E7%BB%93%E6%9E%84%E5%8C%96%E5%92%8C%E9%9D%9E%E7%BB%93%E6%9E%84%E5%8C%96%E6%95%B0%E6%8D%AE/</id>
    <published>2022-06-04T11:07:40.000Z</published>
    <updated>2022-12-03T10:25:37.384Z</updated>
    
    <content type="html"><![CDATA[<p>转自<a href="https://cloud.tencent.com/developer/article/1351609">https://cloud.tencent.com/developer/article/1351609</a></p><h1 id="一、结构化数据"><a href="#一、结构化数据" class="headerlink" title="一、结构化数据"></a><strong>一、结构化数据</strong></h1><p>结构化的数据是指可以使用<a href="https://cloud.tencent.com/product/cdb-overview?from=10680">关系型数据库</a>表示和存储，表现为二维形式的数据。一般特点是：数据以行为单位，一行数据表示一个实体的信息，每一行数据的属性是相同的。举一个例子：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">id      name            age     gender</span><br><span class="line"><span class="number">1</span>       <span class="title class_">Liu</span> <span class="title class_">Yi</span>          <span class="number">20</span>      male</span><br><span class="line"><span class="number">2</span>       <span class="title class_">Chen</span> <span class="title class_">Er</span>         <span class="number">35</span>      female</span><br><span class="line"><span class="number">3</span>       <span class="title class_">Zhang</span> <span class="title class_">San</span>       <span class="number">28</span>      male</span><br></pre></td></tr></table></figure><span id="more"></span><p>所以，结构化的数据的存储和排列是很有规律的，这对查询和修改等操作很有帮助。</p><p>但是，它的扩展性不好。比如，如果字段不固定，利用关系型数据库也是比较困难的，有人会说，需要的时候加个字段就可以了，这样的方法也不是不可以，但在实际运用中每次都进行反复的表结构变更是非常痛苦的，这也容易导致后台接口从数据库取数据出错。你也可以预先设定大量的预备字段，但这样的话，时间一长很容易弄不清除字段和数据的对应状态，即哪个字段保存有哪些数据。</p><h1 id="二、半结构化数据"><a href="#二、半结构化数据" class="headerlink" title="二、半结构化数据"></a><strong>二、半结构化数据</strong></h1><p>半结构化数据是结构化数据的一种形式，它并不符合关系型数据库或其他数据表的形式关联起来的数据模型结构，但包含相关标记，用来分隔语义元素以及对记录和字段进行分层。因此，它也被称为自描述的结构。</p><p>半结构化数据，属于同一类实体可以有不同的属性，即使他们被组合在一起，这些属性的顺序并不重要。</p><p>常见的半结构数据有XML和JSON，对于对于两个XML文件，第一个可能有</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;person&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">name</span>&gt;</span>A<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span></span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">age</span>&gt;</span>13<span class="tag">&lt;/<span class="name">age</span>&gt;</span></span></span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">gender</span>&gt;</span>female<span class="tag">&lt;/<span class="name">gender</span>&gt;</span></span></span><br><span class="line">&lt;/person&gt;</span><br></pre></td></tr></table></figure><p>复制</p><p>第二个可能为：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&lt;person&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">name</span>&gt;</span>B<span class="tag">&lt;/<span class="name">name</span>&gt;</span></span></span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">gender</span>&gt;</span>male<span class="tag">&lt;/<span class="name">gender</span>&gt;</span></span></span><br><span class="line">&lt;/person&gt;</span><br></pre></td></tr></table></figure><p>复制</p><p>从上面的例子中，属性的顺序是不重要的，不同的半结构化数据的属性的个数是不一定一样的。有些人说半结构化数据是以树或者图的数据结构存储的数据，怎么理解呢？上面的例子中，标签是树的根节点，和标签是子节点。通过这样的数据格式，可以自由地表达很多有用的信息，包括自我描述信息（元数据）。所以，半结构化数据的扩展性是很好的。</p><h1 id="三、非结构化数据"><a href="#三、非结构化数据" class="headerlink" title="三、非结构化数据"></a><strong>三、非结构化数据</strong></h1><p>非结构化数据是数据结构不规则或不完整，没有预定义的数据模型，不方便用数据库二维逻辑表来表现的数据。包括所有格式的办公文档、文本、图片、各类报表、图像和音频&#x2F;视频信息等等。</p><p>非结构化数据其格式非常多样，标准也是多样性的，而且在技术上非结构化信息比结构化信息更难标准化和理解。所以存储、检索、发布以及利用需要更加智能化的IT技术，比如海量存储、智能检索、知识挖掘、内容保护、信息的增值开发利用等。</p><h1 id="四、应用场景"><a href="#四、应用场景" class="headerlink" title="四、应用场景"></a><strong>四、应用场景</strong></h1><p>结构化数据，简单来说就是数据库。结合到典型场景中更容易理解，比如企业ERP、财务系统；医疗HIS数据库；教育一卡通；政府行政审批；其他核心数据库等。这些应用需要哪些存储方案呢？基本包括高速存储应用需求、数据备份需求、数据共享需求以及数据容灾需求。</p><p>非结构化数据，包括视频、音频、图片、图像、文档、文本等形式。具体到典型案例中，像是医疗影像系统、教育视频点播、视频监控、国土GIS、设计院、文件服务器（PDM&#x2F;FTP）、媒体资源管理等具体应用，这些行业对于存储需求包括数据存储、数据备份以及数据共享等。</p><p>半结构化数据，包括邮件、HTML、报表、资源库等等，典型场景如邮件系统、WEB集群、教学资源库、数据挖掘系统、档案系统等等。这些应用对于数据存储、数据备份、数据共享以及数据归档 等基本存储需求。</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;转自&lt;a href=&quot;https://cloud.tencent.com/developer/article/1351609&quot;&gt;https://cloud.tencent.com/developer/article/1351609&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;一、结构化数据&quot;&gt;&lt;a href=&quot;#一、结构化数据&quot; class=&quot;headerlink&quot; title=&quot;一、结构化数据&quot;&gt;&lt;/a&gt;&lt;strong&gt;一、结构化数据&lt;/strong&gt;&lt;/h1&gt;&lt;p&gt;结构化的数据是指可以使用&lt;a href=&quot;https://cloud.tencent.com/product/cdb-overview?from=10680&quot;&gt;关系型数据库&lt;/a&gt;表示和存储，表现为二维形式的数据。一般特点是：数据以行为单位，一行数据表示一个实体的信息，每一行数据的属性是相同的。举一个例子：&lt;/p&gt;
&lt;figure class=&quot;highlight javascript&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;id      name            age     gender&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;       &lt;span class=&quot;title class_&quot;&gt;Liu&lt;/span&gt; &lt;span class=&quot;title class_&quot;&gt;Yi&lt;/span&gt;          &lt;span class=&quot;number&quot;&gt;20&lt;/span&gt;      male&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;       &lt;span class=&quot;title class_&quot;&gt;Chen&lt;/span&gt; &lt;span class=&quot;title class_&quot;&gt;Er&lt;/span&gt;         &lt;span class=&quot;number&quot;&gt;35&lt;/span&gt;      female&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;       &lt;span class=&quot;title class_&quot;&gt;Zhang&lt;/span&gt; &lt;span class=&quot;title class_&quot;&gt;San&lt;/span&gt;       &lt;span class=&quot;number&quot;&gt;28&lt;/span&gt;      male&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;</summary>
    
    
    
    
    <category term="数据处理" scheme="http://example.com/tags/%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86/"/>
    
  </entry>
  
</feed>
