var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="problem123456Clone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.A graph is defined below:struct Node &#123;vector neighbors;&#125;">
<metaname="description"content="problemClone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.A graph is defined below:struct Node &#123;vector neighbors;&#125;">
<metaproperty="og:type"content="article">
<metaproperty="og:type"content="article">
<metaproperty="og:title"content="Clone Graph Part I">
<metaproperty="og:title"content="Clone Graph Part I">
<metaproperty="og:description"content="problem123456Clone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.A graph is defined below:struct Node &#123;vector neighbors;&#125;">
<metaproperty="og:description"content="problemClone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph. A graph is defined below: struct Node &#123; vector neighbors; &#125;">
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br></pre></td><tdclass="code"><pre><spanclass="line">Clone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.</span><br><spanclass="line"></span><br><spanclass="line">A graph is defined below:</span><br><spanclass="line">struct Node {</span><br><spanclass="line">vector neighbors;</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><preclass="line-numbers language-none"><codeclass="language-none">Clone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.
<h3id="anlysis"><ahref="#anlysis"class="headerlink"title="anlysis"></a>anlysis</h3><p>using the Breadth-first traversal<br>and use a map to save the neighbors not to be duplicated.</p>
<h3id="anlysis"><ahref="#anlysis"class="headerlink"title="anlysis"></a>anlysis</h3><p>using the Breadth-first traversal<br>and use a map to save the neighbors not to be duplicated.</p>
</div>
</div>
@ -303,16 +333,16 @@
<divclass="popular-posts-title"><ahref="/2015/03/11/Number-Of-1-Bits/"rel="bookmark">Number of 1 Bits</a></div>
<divclass="popular-posts-title"><ahref="/2015/03/11/Number-Of-1-Bits/"rel="bookmark">Number of 1 Bits</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<metaproperty="og:description"content="problemGiven a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.">
<metaproperty="og:description"content="problemGiven a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.">
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.</p>
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.</p>
<aid="more"></a>
<spanid="more"></span>
<p>For example:<br>Given the below binary tree and sum = 22,</p>
<p>For example:<br>Given the below binary tree and sum = 22,</p>
<metaproperty="og:description"content="Pcre Perl Compatible Regular Expressions (PCRE) is a regular expression C library inspired by the regular expression capabilities in the Perl programming language, written by Philip Hazel, starting in">
<metaproperty="og:description"content="Pcre Perl Compatible Regular Expressions (PCRE) is a regular expression C library inspired by the regular expression capabilities in the Perl programming language, written by Philip Hazel, starting in">
<p>Perl Compatible Regular Expressions (PCRE) is a regular<br> expression C library inspired by the regular expression<br> capabilities in the Perl programming language, written<br> by Philip Hazel, starting in summer 1997.</p>
<p>Perl Compatible Regular Expressions (PCRE) is a regular<br> expression C library inspired by the regular expression<br> capabilities in the Perl programming language, written<br> by Philip Hazel, starting in summer 1997.</p>
int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize)<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span></span></code></pre>
<metaproperty="og:description"content="Number of 1 Bits Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary represent">
<metaproperty="og:description"content="Number of 1 Bits Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary represent">
<h3id="Number-of-1-Bits"><ahref="#Number-of-1-Bits"class="headerlink"title="Number of 1 Bits "></a><ahref="https://leetcode.com/problems/number-of-1-bits/"target="_blank"rel="noopener">Number of 1 Bits </a></h3><h4id="Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-’1’-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-‘11’-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"><ahref="#Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-’1’-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-‘11’-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"class="headerlink"title="Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation 00000000000000000000000000001011, so the function should return 3."></a>Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation <code>00000000000000000000000000001011</code>, so the function should return 3.</h4><aid="more"></a>
<h3id="Number-of-1-Bits"><ahref="#Number-of-1-Bits"class="headerlink"title="Number of 1 Bits "></a><atarget="_blank"rel="noopener"href="https://leetcode.com/problems/number-of-1-bits/">Number of 1 Bits </a></h3><h4id="Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-’1’-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-‘11’-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"><ahref="#Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-’1’-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-‘11’-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"class="headerlink"title="Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation 00000000000000000000000000001011, so the function should return 3."></a>Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation <code>00000000000000000000000000001011</code>, so the function should return 3.</h4><spanid="more"></span>
<h3id="code"><ahref="#code"class="headerlink"title="code"></a>code</h3><figureclass="highlight c++"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="function"><spanclass="keyword">int</span><spanclass="title">hammingWeight</span><spanclass="params">(<spanclass="keyword">uint32_t</span> n)</span></span>{</span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">uint32_t</span> m1 = <spanclass="number">0x55555555</span>; <spanclass="comment">//binary: 0101... </span></span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">uint32_t</span> m2 = <spanclass="number">0x33333333</span>; <spanclass="comment">//binary: 00110011.. </span></span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">uint32_t</span> m4 = <spanclass="number">0x0f0f0f0f</span>; <spanclass="comment">//binary: 4 zeros, 4 ones ... </span></span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">uint32_t</span> m8 = <spanclass="number">0x00ff00ff</span>; <spanclass="comment">//binary: 8 zeros, 8 ones ... </span></span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">uint32_t</span> m16 = <spanclass="number">0x0000ffff</span>; <spanclass="comment">//binary: 16 zeros, 16 ones ... </span></span><br><spanclass="line"></span><br><spanclass="line"> n = (n & m1 ) + ((n >><spanclass="number">1</span>) & m1 ); <spanclass="comment">//put count of each 2 bits into those 2 bits </span></span><br><spanclass="line"> n = (n & m2 ) + ((n >><spanclass="number">2</span>) & m2 ); <spanclass="comment">//put count of each 4 bits into those 4 bits </span></span><br><spanclass="line"> n = (n & m4 ) + ((n >><spanclass="number">4</span>) & m4 ); <spanclass="comment">//put count of each 8 bits into those 8 bits </span></span><br><spanclass="line"> n = (n & m8 ) + ((n >><spanclass="number">8</span>) & m8 ); <spanclass="comment">//put count of each 16 bits into those 16 bits </span></span><br><spanclass="line"> n = (n & m16) + ((n >><spanclass="number">16</span>) & m16); <spanclass="comment">//put count of each 32 bits into those 32 bits </span></span><br><spanclass="line"><spanclass="keyword">return</span> n; </span><br><spanclass="line"></span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<divclass="post-toc motion-element"><olclass="nav"><liclass="nav-item nav-level-3"><aclass="nav-link"href="#Number-of-1-Bits"><spanclass="nav-number">1.</span><spanclass="nav-text">Number of 1 Bits </span></a><olclass="nav-child"><liclass="nav-item nav-level-4"><aclass="nav-link"href="#Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-’1’-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-‘11’-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"><spanclass="nav-number">1.1.</span><spanclass="nav-text">Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation 00000000000000000000000000001011, so the function should return 3.</span></a></li></ol></li><liclass="nav-item nav-level-3"><aclass="nav-link"href="#分析"><spanclass="nav-number">2.</span><spanclass="nav-text">分析</span></a></li><liclass="nav-item nav-level-3"><aclass="nav-link"href="#code"><spanclass="nav-number">3.</span><spanclass="nav-text">code</span></a></li></ol></div>
<divclass="post-toc motion-element"><olclass="nav"><liclass="nav-item nav-level-3"><aclass="nav-link"href="#Number-of-1-Bits"><spanclass="nav-number">1.</span><spanclass="nav-text">Number of 1 Bits </span></a><olclass="nav-child"><liclass="nav-item nav-level-4"><aclass="nav-link"href="#Write-a-function-that-takes-an-unsigned-integer-and-returns-the-number-of-%E2%80%991%E2%80%99-bits-it-has-also-known-as-the-Hamming-weight-For-example-the-32-bit-integer-%E2%80%9811%E2%80%99-has-binary-representation-00000000000000000000000000001011-so-the-function-should-return-3"><spanclass="nav-number">1.1.</span><spanclass="nav-text">Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight). For example, the 32-bit integer ‘11’ has binary representation 00000000000000000000000000001011, so the function should return 3.</span></a></li></ol></li><liclass="nav-item nav-level-3"><aclass="nav-link"href="#%E5%88%86%E6%9E%90"><spanclass="nav-number">2.</span><spanclass="nav-text">分析</span></a></li><liclass="nav-item nav-level-3"><aclass="nav-link"href="#code"><spanclass="nav-number">3.</span><spanclass="nav-text">code</span></a></li></ol></div>
<metaproperty="og:description"content="Reverse Bits Reverse bits of a given 32 bits unsigned integer.For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as">
<metaproperty="og:description"content="Reverse Bits Reverse bits of a given 32 bits unsigned integer.For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as">
<h3id="Reverse-Bits"><ahref="#Reverse-Bits"class="headerlink"title="Reverse Bits "></a><ahref="https://leetcode.com/problems/reverse-bits/"target="_blank"rel="noopener">Reverse Bits </a></h3><h4id="Reverse-bits-of-a-given-32-bits-unsigned-integer"><ahref="#Reverse-bits-of-a-given-32-bits-unsigned-integer"class="headerlink"title="Reverse bits of a given 32 bits unsigned integer."></a>Reverse bits of a given 32 bits unsigned integer.</h4><p>For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).</p>
<aid="more"></a>
<h3id="Reverse-Bits"><ahref="#Reverse-Bits"class="headerlink"title="Reverse Bits "></a><atarget="_blank"rel="noopener"href="https://leetcode.com/problems/reverse-bits/">Reverse Bits </a></h3><h4id="Reverse-bits-of-a-given-32-bits-unsigned-integer"><ahref="#Reverse-bits-of-a-given-32-bits-unsigned-integer"class="headerlink"title="Reverse bits of a given 32 bits unsigned integer."></a>Reverse bits of a given 32 bits unsigned integer.</h4><p>For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).</p>
<spanid="more"></span>
<p>Follow up:<br>If this function is called many times, how would you optimize it?</p>
<p>Follow up:<br>If this function is called many times, how would you optimize it?</p>
<hr>
<hr>
<h3id="code"><ahref="#code"class="headerlink"title="code"></a>code</h3><figureclass="highlight c++"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="class"><spanclass="keyword">class</span><spanclass="title">Solution</span>{</span></span><br><spanclass="line"><spanclass="keyword">public</span>:</span><br><spanclass="line"><spanclass="function"><spanclass="keyword">uint32_t</span><spanclass="title">reverseBits</span><spanclass="params">(<spanclass="keyword">uint32_t</span> n)</span></span>{</span><br><spanclass="line"> n = ((n >><spanclass="number">1</span>) &<spanclass="number">0x55555555</span>) | ((n &<spanclass="number">0x55555555</span>) <<<spanclass="number">1</span>);</span><br><spanclass="line"> n = ((n >><spanclass="number">2</span>) &<spanclass="number">0x33333333</span>) | ((n &<spanclass="number">0x33333333</span>) <<<spanclass="number">2</span>);</span><br><spanclass="line"> n = ((n >><spanclass="number">4</span>) &<spanclass="number">0x0f0f0f0f</span>) | ((n &<spanclass="number">0x0f0f0f0f</span>) <<<spanclass="number">4</span>);</span><br><spanclass="line"> n = ((n >><spanclass="number">8</span>) &<spanclass="number">0x00ff00ff</span>) | ((n &<spanclass="number">0x00ff00ff</span>) <<<spanclass="number">8</span>);</span><br><spanclass="line"> n = ((n >><spanclass="number">16</span>) &<spanclass="number">0x0000ffff</span>) | ((n &<spanclass="number">0x0000ffff</span>) <<<spanclass="number">16</span>);</span><br><spanclass="line"><spanclass="keyword">return</span> n;</span><br><spanclass="line">}</span><br><spanclass="line">};</span><br></pre></td></tr></table></figure>
<metaproperty="og:description"content="Reverse IntegerReverse digits of an integer.Example1: x = 123, return 321Example2: x = -123, return -321">
<metaproperty="og:description"content="Reverse IntegerReverse digits of an integer.Example1: x = 123, return 321Example2: x = -123, return -321">
<h3id="Reverse-Integer"><ahref="#Reverse-Integer"class="headerlink"title="Reverse Integer"></a><ahref="https://leetcode.com/problems/reverse-integer/"target="_blank"rel="noopener">Reverse Integer</a></h3><h4id="Reverse-digits-of-an-integer"><ahref="#Reverse-digits-of-an-integer"class="headerlink"title="Reverse digits of an integer."></a>Reverse digits of an integer.</h4><p>Example1: x = 123, return 321<br>Example2: x = -123, return -321</p>
<aid="more"></a>
<h3id="Reverse-Integer"><ahref="#Reverse-Integer"class="headerlink"title="Reverse Integer"></a><atarget="_blank"rel="noopener"href="https://leetcode.com/problems/reverse-integer/">Reverse Integer</a></h3><h4id="Reverse-digits-of-an-integer"><ahref="#Reverse-digits-of-an-integer"class="headerlink"title="Reverse digits of an integer."></a>Reverse digits of an integer.</h4><p>Example1: x = 123, return 321<br>Example2: x = -123, return -321</p>
<spanid="more"></span>
<h4id="spoilers"><ahref="#spoilers"class="headerlink"title="spoilers"></a>spoilers</h4><p>Have you thought about this?<br>Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!</p>
<h4id="spoilers"><ahref="#spoilers"class="headerlink"title="spoilers"></a>spoilers</h4><p>Have you thought about this?<br>Here are some good questions to ask before coding. Bonus points for you if you have already thought through this!</p>
<p>If the integer’s last digit is 0, what should the output be? ie, cases such as 10, 100.</p>
<p>If the integer’s last digit is 0, what should the output be? ie, cases such as 10, 100.</p>
<p>Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?</p>
<p>Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases?</p>
<p>For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.</p>
<p>For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.</p>
<hr>
<hr>
<h3id="code"><ahref="#code"class="headerlink"title="code"></a>code</h3><figureclass="highlight c++"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="class"><spanclass="keyword">class</span><spanclass="title">Solution</span>{</span></span><br><spanclass="line"><spanclass="keyword">public</span>:</span><br><spanclass="line"><spanclass="function"><spanclass="keyword">int</span><spanclass="title">reverse</span><spanclass="params">(<spanclass="keyword">int</span> x)</span></span>{</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">int</span><spanclass="built_in">max</span> = <spanclass="number">1</span><<<spanclass="number">31</span> - <spanclass="number">1</span>;</span><br><spanclass="line"><spanclass="keyword">int</span> ret = <spanclass="number">0</span>;</span><br><spanclass="line"><spanclass="built_in">max</span> = (<spanclass="built_in">max</span> - <spanclass="number">1</span>) * <spanclass="number">2</span> + <spanclass="number">1</span>;</span><br><spanclass="line"><spanclass="keyword">int</span><spanclass="built_in">min</span> = <spanclass="number">1</span><<<spanclass="number">31</span>;</span><br><spanclass="line"><spanclass="keyword">if</span>(x <<spanclass="number">0</span>)</span><br><spanclass="line"><spanclass="keyword">while</span>(x != <spanclass="number">0</span>){</span><br><spanclass="line"><spanclass="keyword">if</span>(ret < (<spanclass="built_in">min</span> - x % <spanclass="number">10</span>) / <spanclass="number">10</span>)</span><br><spanclass="line"><spanclass="keyword">return</span><spanclass="number">0</span>;</span><br><spanclass="line"> ret = ret * <spanclass="number">10</span> + x % <spanclass="number">10</span>;</span><br><spanclass="line"> x = x / <spanclass="number">10</span>;</span><br><spanclass="line">}</span><br><spanclass="line"><spanclass="keyword">else</span></span><br><spanclass="line"><spanclass="keyword">while</span>(x != <spanclass="number">0</span>){</span><br><spanclass="line"><spanclass="keyword">if</span>(ret > (<spanclass="built_in">max</span> -x % <spanclass="number">10</span>) / <spanclass="number">10</span>)</span><br><spanclass="line"><spanclass="keyword">return</span><spanclass="number">0</span>;</span><br><spanclass="line"> ret = ret * <spanclass="number">10</span> + x % <spanclass="number">10</span>;</span><br><spanclass="line"> x = x / <spanclass="number">10</span>;</span><br><spanclass="line">}</span><br><spanclass="line"><spanclass="keyword">return</span> ret;</span><br><spanclass="line">}</span><br><spanclass="line">};</span><br></pre></td></tr></table></figure>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="*Longest Substring Without Repeating Characters *">
<metaname="description"content="**Longest Substring Without Repeating Characters **">
<p>*<em>Longest Substring Without Repeating Characters *</em></p>
<aid="more"></a>
<p>**Longest Substring Without Repeating Characters **</p>
<spanid="more"></span>
<h3id="description"><ahref="#description"class="headerlink"title="description"></a>description</h3><p>Given a string, find the length of the longest substring without repeating characters.<br>For example, the longest substring without repeating letters for “abcabcbb” is “abc”,<br>which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1. </p>
<h3id="description"><ahref="#description"class="headerlink"title="description"></a>description</h3><p>Given a string, find the length of the longest substring without repeating characters.<br>For example, the longest substring without repeating letters for “abcabcbb” is “abc”,<br>which the length is 3. For “bbbbb” the longest substring is “b”, with the length of 1. </p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="Invert a binary tree 4 / \ 2 7 / \ / \ 1 3 6 9to 4 / \ 7 2 / \ / \ 9 6 3 1Trivia:This problem was inspired by this original tweet by Max Howell: Google:">
<metaname="description"content="Invert a binary tree 4 / \ 2 7 / \ / \ 1 3 6 9to 4 / \ 7 2 / \ / \ 9 6 3 1Trivia:This problem was inspired by this original tweet by Max Howell: Goog">
<metaproperty="og:description"content="Invert a binary tree 4 / \ 2 7 / \ / \ 1 3 6 9to 4 / \ 7 2 / \ / \ 9 6 3 1Trivia:This problem was inspired by this original tweet by Max Howell: Google:">
<metaproperty="og:description"content="Invert a binary tree 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Goog">
9 6 3 1</code></pre><p><strong>Trivia:</strong><br>This problem was inspired by <ahref="https://twitter.com/mxcl/status/608682016205344768"target="_blank"rel="noopener">this original tweet</a> by <ahref="https://twitter.com/mxcl"target="_blank"rel="noopener">Max Howell</a>:</p>
9 6 3 1
</code></pre>
<p><strong>Trivia:</strong><br>This problem was inspired by <atarget="_blank"rel="noopener"href="https://twitter.com/mxcl/status/608682016205344768">this original tweet</a> by <atarget="_blank"rel="noopener"href="https://twitter.com/mxcl">Max Howell</a>:</p>
<blockquote>
<blockquote>
<p>Google: 90% of our engineers use the software you wrote (Homebrew),<br>but you can’t invert a binary tree on a whiteboard so fuck off. </p>
<p>Google: 90% of our engineers use the software you wrote (Homebrew),<br>but you can’t invert a binary tree on a whiteboard so fuck off. </p>
<metaproperty="og:description"content="question34. Search for a RangeOriginal Page Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm’s runtime complexity must be in the order of">
<metaproperty="og:description"content="question34. Search for a RangeOriginal Page Given a sorted array of integers, find the starting and ending position of a given target value. Your algorithm’s runtime complexity must be in the order of">
<h2id="question"><ahref="#question"class="headerlink"title="question"></a>question</h2><h3id="34-Search-for-a-Range"><ahref="#34-Search-for-a-Range"class="headerlink"title="34. Search for a Range"></a>34. Search for a Range</h3><p><ahref="https://leetcode.com/problems/search-for-a-range/"target="_blank"rel="noopener">Original Page</a></p>
<h2id="question"><ahref="#question"class="headerlink"title="question"></a>question</h2><h3id="34-Search-for-a-Range"><ahref="#34-Search-for-a-Range"class="headerlink"title="34. Search for a Range"></a>34. Search for a Range</h3><p><atarget="_blank"rel="noopener"href="https://leetcode.com/problems/search-for-a-range/">Original Page</a></p>
<p>Given a sorted array of integers, find the starting and ending position of a given target value.</p>
<p>Given a sorted array of integers, find the starting and ending position of a given target value.</p>
<p>Your algorithm’s runtime complexity must be in the order of <em>O</em>(log <em>n</em>).</p>
<p>Your algorithm’s runtime complexity must be in the order of <em>O</em>(log <em>n</em>).</p>
<p>If the target is not found in the array, return <code>[-1, -1]</code>.</p>
<p>If the target is not found in the array, return <code>[-1, -1]</code>.</p>
<p>For example,<br>Given <code>[5, 7, 7, 8, 8, 10]</code> and target value 8,<br>return <code>[3, 4]</code>.</p>
<p>For example,<br>Given <code>[5, 7, 7, 8, 8, 10]</code> and target value 8,<br>return <code>[3, 4]</code>.</p>
<h3id="主从配置"><ahref="#主从配置"class="headerlink"title="主从配置"></a>主从配置</h3><p>同样退出重启容器,然后是配置主从,首先进入主库,用命令mysql -u root -pxxxx进入mysql,然后赋予一个同步<br>权限<code>GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';</code>还是同样说明下,ON <em>.</em>表示了数<br>据库全部的权限,如果要指定数据库/表的话可以使用类似<code>testDb/testTable</code>,然后是<code>'backup'@'%'</code>表示给予同步<br>权限的用户名及其主机ip,%表示不限制ip,当然如果有防火墙的话还是会有限制的,最后的<code>identified by '123456'</code><br>表示同步用户的密码,然后就查看下主库的状态信息<code>show master status</code>,如下图:<br><imgdata-src="https://ooo.0o0.ooo/2016/08/10/57aac43029559.png"alt="9G5FE[9%@7%G(B`Q7]E)5@R.png"><br>把file跟position记下来,然后再开一个terminal,进入从库容器,登陆mysql,然后设置主库</p>
<h3id="主从配置"><ahref="#主从配置"class="headerlink"title="主从配置"></a>主从配置</h3><p>同样退出重启容器,然后是配置主从,首先进入主库,用命令mysql -u root -pxxxx进入mysql,然后赋予一个同步<br>权限<code>GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';</code>还是同样说明下,ON *.*表示了数<br>据库全部的权限,如果要指定数据库/表的话可以使用类似<code>testDb/testTable</code>,然后是<code>'backup'@'%'</code>表示给予同步<br>权限的用户名及其主机ip,%表示不限制ip,当然如果有防火墙的话还是会有限制的,最后的<code>identified by '123456'</code><br>表示同步用户的密码,然后就查看下主库的状态信息<code>show master status</code>,如下图:<br><imgdata-src="https://ooo.0o0.ooo/2016/08/10/57aac43029559.png"alt="9G5FE[9%@7%G(B`Q7]E)5@R.png"><br>把file跟position记下来,然后再开一个terminal,进入从库容器,登陆mysql,然后设置主库</p>
<preclass="line-numbers language-none"><codeclass="language-none">change master to
<metaproperty="og:description"content="problemA binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). Each LED represents a zero or one, with the least significant">
<metaproperty="og:description"content="problemA binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). Each LED represents a zero or one, with the least significant">
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). </p>
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). </p>
<p>Each LED represents a zero or one, with the least significant bit on the right. </p>
<p>Each LED represents a zero or one, with the least significant bit on the right. </p>
<h4id="Example"><ahref="#Example"class="headerlink"title="Example:"></a>Example:</h4><preclass="line-numbers language-none"><codeclass="language-none">Input: n = 1
<metaproperty="og:description"content="problemGiven an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead. For example, given the array">
<metaproperty="og:description"content="problemGiven an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead. For example, given the array">
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead. </p>
<h3id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h3><p>Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead. </p>
<p>For example, given the array <code>[2,3,1,2,4,3]</code> and <code>s = 7</code>,<br>the subarray <code>[4,3]</code> has the minimal length under the problem constraint. </p>
<p>For example, given the array <code>[2,3,1,2,4,3]</code> and <code>s = 7</code>,<br>the subarray <code>[4,3]</code> has the minimal length under the problem constraint. </p>
<h4id="Code"><ahref="#Code"class="headerlink"title="Code"></a>Code</h4><figureclass="highlight c++"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="class"><spanclass="keyword">class</span><spanclass="title">Solution</span>{</span></span><br><spanclass="line"><spanclass="keyword">public</span>:</span><br><spanclass="line"><spanclass="function"><spanclass="keyword">int</span><spanclass="title">minSubArrayLen</span><spanclass="params">(<spanclass="keyword">int</span> s, <spanclass="built_in">vector</span><<spanclass="keyword">int</span>>& nums)</span></span>{</span><br><spanclass="line"><spanclass="keyword">int</span> len = nums.<spanclass="built_in">size</span>();</span><br><spanclass="line"><spanclass="keyword">if</span>(len == <spanclass="number">0</span>) <spanclass="keyword">return</span><spanclass="number">0</span>;</span><br><spanclass="line"><spanclass="keyword">int</span> minlen = INT_MAX;</span><br><spanclass="line"><spanclass="keyword">int</span> sum = <spanclass="number">0</span>;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">int</span> left = <spanclass="number">0</span>;</span><br><spanclass="line"><spanclass="keyword">int</span> right = <spanclass="number">-1</span>;</span><br><spanclass="line"><spanclass="keyword">while</span>(right < len)</span><br><spanclass="line">{</span><br><spanclass="line"><spanclass="keyword">while</span>(sum < s && right < len)</span><br><spanclass="line"> sum += nums[++right];</span><br><spanclass="line"><spanclass="keyword">if</span>(sum >= s)</span><br><spanclass="line">{</span><br><spanclass="line"> minlen = minlen < right - left + <spanclass="number">1</span> ? minlen : right - left + <spanclass="number">1</span>;</span><br><spanclass="line"> sum -= nums[left++];</span><br><spanclass="line">}</span><br><spanclass="line">}</span><br><spanclass="line"><spanclass="keyword">return</span> minlen > len ? <spanclass="number">0</span> : minlen;</span><br><spanclass="line">}</span><br><spanclass="line">};</span><br></pre></td></tr></table></figure>
<metaproperty="og:description"content="problemGiven a sorted integer array without duplicates, return the summary of its ranges. For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. 题解每一个区间的起点nu">
<metaproperty="og:description"content="problemGiven a sorted integer array without duplicates, return the summary of its ranges. For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. 题解每一个区间的起点nu">
<h4id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h4><p>Given a sorted integer array without duplicates, return the summary of its ranges.</p>
<h4id="problem"><ahref="#problem"class="headerlink"title="problem"></a>problem</h4><p>Given a sorted integer array without duplicates, return the summary of its ranges.</p>
<p>For example, given <code>[0,1,2,4,5,7]</code>, return <code>["0->2","4->5","7"]</code>.</p>
<p>For example, given <code>[0,1,2,4,5,7]</code>, return <code>["0->2","4->5","7"]</code>.</p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<h2id="示例代码"><ahref="#示例代码"class="headerlink"title="示例代码"></a>示例代码</h2><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br><spanclass="line">26</span><br><spanclass="line">27</span><br><spanclass="line">28</span><br></pre></td><tdclass="code"><pre><spanclass="line"><?php</span><br><spanclass="line">interface int1{</span><br><spanclass="line"> const INTER1 = 111;</span><br><spanclass="line"> function inter1();</span><br><spanclass="line">}</span><br><spanclass="line">interface int2{</span><br><spanclass="line"> const INTER1 = 222;</span><br><spanclass="line"> function inter2();</span><br><spanclass="line">}</span><br><spanclass="line">abstract class abst1{</span><br><spanclass="line"> public function abstr1(){</span><br><spanclass="line"> echo 1111;</span><br><spanclass="line">}</span><br><spanclass="line"> abstract function abstra1(){</span><br><spanclass="line"> echo 'ahahahha';</span><br><spanclass="line">}</span><br><spanclass="line">}</span><br><spanclass="line">abstract class abst2{</span><br><spanclass="line"> public function abstr2(){</span><br><spanclass="line"> echo 1111;</span><br><spanclass="line">}</span><br><spanclass="line"> abstract function abstra2();</span><br><spanclass="line">}</span><br><spanclass="line">class normal1 extends abst1{</span><br><spanclass="line"> protected function abstr2(){</span><br><spanclass="line"> echo 222;</span><br><spanclass="line">}</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<h2id="result"><ahref="#result"class="headerlink"title="result"></a>result</h2><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br></pre></td><tdclass="code"><pre><spanclass="line">PHP Fatal error: Abstract function abst1::abstra1() cannot contain body in new.php on line 17</span><br><spanclass="line"></span><br><spanclass="line">Fatal error: Abstract function abst1::abstra1() cannot contain body in php on line 17</span><br></pre></td></tr></table></figure>
<h2id="result"><ahref="#result"class="headerlink"title="result"></a>result</h2><preclass="line-numbers language-none"><codeclass="language-none">PHP Fatal error: Abstract function abst1::abstra1() cannot contain body in new.php on line 17
Fatal error: Abstract function abst1::abstra1() cannot contain body in php on line 17<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br></pre></td><tdclass="code"><pre><spanclass="line">Cluster status of node rabbit@rabbit1 ...</span><br><spanclass="line">[{nodes,[{disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]}]},</span><br><spanclass="line">{running_nodes,[rabbit@rabbit2,rabbit@rabbit1]}]</span><br><spanclass="line">...done.</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">Cluster status of node rabbit@rabbit1 ...
<h2id="一些坑"><ahref="#一些坑"class="headerlink"title="一些坑"></a>一些坑</h2><h3id="消息丢失"><ahref="#消息丢失"class="headerlink"title="消息丢失"></a>消息丢失</h3><p>这里碰到过一个坑,对于使用exchange来做消息路由的,会有一个情况,就是在routing_key没被订阅的时候,会将该条找不到路由对应的queue的消息丢掉<code>What happens if we break our contract and send a message with one or four words, like "orange" or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.</code><ahref="http://www.rabbitmq.com/tutorials/tutorial-five-python.html"target="_blank"rel="noopener">对应链接</a>,而当使用空的exchange时,会保留消息,当出现消费者的时候就可以将收到之前生产者所推送的消息<ahref="http://www.rabbitmq.com/tutorials/tutorial-two-python.html"target="_blank"rel="noopener">对应链接</a>,这里就是用了空的exchange。</p>
<h2id="一些坑"><ahref="#一些坑"class="headerlink"title="一些坑"></a>一些坑</h2><h3id="消息丢失"><ahref="#消息丢失"class="headerlink"title="消息丢失"></a>消息丢失</h3><p>这里碰到过一个坑,对于使用exchange来做消息路由的,会有一个情况,就是在routing_key没被订阅的时候,会将该条找不到路由对应的queue的消息丢掉<code>What happens if we break our contract and send a message with one or four words, like "orange" or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.</code><atarget="_blank"rel="noopener"href="http://www.rabbitmq.com/tutorials/tutorial-five-python.html">对应链接</a>,而当使用空的exchange时,会保留消息,当出现消费者的时候就可以将收到之前生产者所推送的消息<atarget="_blank"rel="noopener"href="http://www.rabbitmq.com/tutorials/tutorial-two-python.html">对应链接</a>,这里就是用了空的exchange。</p>
<li><p>后来又碰到了一个坑是nginx有个client_body_buffer_size的配置参数,nginx在32位和64位系统里有8K和16K两个默认值,当请求内容大于这两个值的时候,会把请求内容放到临时文件里,这个时候openresty里的ngx.req.get_post_args()就会报“failed to get post args: requesty body in temp file not supported”这个错误,将client_body_buffer_size这个参数配置调大一点就好了</p>
<li><p>后来又碰到了一个坑是nginx有个client_body_buffer_size的配置参数,nginx在32位和64位系统里有8K和16K两个默认值,当请求内容大于这两个值的时候,会把请求内容放到临时文件里,这个时候openresty里的ngx.req.get_post_args()就会报“failed to get post args: requesty body in temp file not supported”这个错误,将client_body_buffer_size这个参数配置调大一点就好了</p>
<li><p>还有一个是redis链接时如果host使用的是域名的话会提示“failed to connect: no resolver defined to resolve “redis.xxxxxx.com””,这里需要使用nginx的resolver指令,<br><code>resolver 8.8.8.8 valid=3600s;</code></p>
<li><p>还有一个是redis链接时如果host使用的是域名的话会提示“failed to connect: no resolver defined to resolve “redis.xxxxxx.com””,这里需要使用nginx的resolver指令,<br><code>resolver 8.8.8.8 valid=3600s;</code></p>
<h2id="饿汉模式"><ahref="#饿汉模式"class="headerlink"title="饿汉模式"></a>饿汉模式</h2><preclass="line-numbers language-Java"data-language="Java"><codeclass="language-Java">public class Singleton1 {
// 首先,将构造方法变成私有的
private Singleton1() {};
// 创建私有静态实例,这样第一次使用的时候就会进行创建
private static Singleton instance = new Singleton1();
<h2id="饱汉模式"><ahref="#饱汉模式"class="headerlink"title="饱汉模式"></a>饱汉模式</h2><preclass="line-numbers language-Java"data-language="Java"><codeclass="language-Java">public class Singleton2 {
// 首先,也是先堵死 new Singleton() 这条路,将构造方法变成私有
<h2id="嵌套类"><ahref="#嵌套类"class="headerlink"title="嵌套类"></a>嵌套类</h2><preclass="line-numbers language-Java"data-language="Java"><codeclass="language-Java">public class Singleton3 {
private Singleton3() {}
// 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性
private static class Holder {
private static Singleton3 instance = new Singleton3();
<p>这里引用了 redis 在 github 上最早的 2.2 版本的代码,代码路径是<code>https://github.com/antirez/redis/blob/2.2/src/sds.h</code>,可以看到这个结构体里只有仨元素,两个 int 型和一个 char 型数组,两个 int 型其实就是我说的优化,因为 C 语言本身的字符串数组,有两个问题,一个是要知道它实际已被占用的长度,需要去遍历这个数组,第二个就是比较容易踩坑的是遍历的时候要注意它有个以<code>\0</code>作为结尾的特点;通过上面的两个 int 型参数,一个是知道字符串目前的长度,一个是知道字符串还剩余多少位空间,这样子坐着两个操作从 <code>O(N)</code>简化到了<code>O(1)</code>了,还有第二个 free 还有个比较重要的作用就是能防止 C 字符串的溢出问题,在存储之前可以先判断 free 长度,如果长度不够就先扩容了,先介绍到这,这个系列可以写蛮多的,慢慢介绍吧</p>
<p>这里引用了 redis 在 github 上最早的 2.2 版本的代码,代码路径是<code>https://github.com/antirez/redis/blob/2.2/src/sds.h</code>,可以看到这个结构体里只有仨元素,两个 int 型和一个 char 型数组,两个 int 型其实就是我说的优化,因为 C 语言本身的字符串数组,有两个问题,一个是要知道它实际已被占用的长度,需要去遍历这个数组,第二个就是比较容易踩坑的是遍历的时候要注意它有个以<code>\0</code>作为结尾的特点;通过上面的两个 int 型参数,一个是知道字符串目前的长度,一个是知道字符串还剩余多少位空间,这样子坐着两个操作从 <code>O(N)</code>简化到了<code>O(1)</code>了,还有第二个 free 还有个比较重要的作用就是能防止 C 字符串的溢出问题,在存储之前可以先判断 free 长度,如果长度不够就先扩容了,先介绍到这,这个系列可以写蛮多的,慢慢介绍吧</p>
<h2id="链表"><ahref="#链表"class="headerlink"title="链表"></a>链表</h2><p>链表是比较常见的数据结构了,但是因为 redis 是用 C 写的,所以在不依赖第三方库的情况下只能自己写一个了,redis 的链表是个有头的链表,而且是无环的,具体的结构我也找了 github 上最早版本的代码</p>
<h2id="链表"><ahref="#链表"class="headerlink"title="链表"></a>链表</h2><p>链表是比较常见的数据结构了,但是因为 redis 是用 C 写的,所以在不依赖第三方库的情况下只能自己写一个了,redis 的链表是个有头的链表,而且是无环的,具体的结构我也找了 github 上最早版本的代码</p>
<h2id="字典"><ahref="#字典"class="headerlink"title="字典"></a>字典</h2><p>字典也是个常用的数据结构,其实只是叫法不同,数据结构中叫 hash 散列,Java 中叫 Map,PHP 中是数组 array,Python 中也叫字典 dict,因为纯 C 语言本身不带这些数据结构,所以这也是个痛并快乐着的过程,享受 C 语言的高性能的同时也要接受它只提供了语言的基本功能的现实,各种轮子都需要自己造,redis 同样实现了自己的字典<br>下面来看看代码</p>
<h2id="字典"><ahref="#字典"class="headerlink"title="字典"></a>字典</h2><p>字典也是个常用的数据结构,其实只是叫法不同,数据结构中叫 hash 散列,Java 中叫 Map,PHP 中是数组 array,Python 中也叫字典 dict,因为纯 C 语言本身不带这些数据结构,所以这也是个痛并快乐着的过程,享受 C 语言的高性能的同时也要接受它只提供了语言的基本功能的现实,各种轮子都需要自己造,redis 同样实现了自己的字典<br>下面来看看代码</p>
<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br><spanclass="line">26</span><br><spanclass="line">27</span><br><spanclass="line">28</span><br><spanclass="line">29</span><br><spanclass="line">30</span><br><spanclass="line">31</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="keyword">typedef</span><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">dictEntry</span>{</span></span><br><spanclass="line"><spanclass="keyword">void</span> *key;</span><br><spanclass="line"><spanclass="keyword">void</span> *val;</span><br><spanclass="line"><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">dictEntry</span> *<spanclass="title">next</span>;</span></span><br><spanclass="line">} dictEntry;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">typedef</span><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">dictType</span>{</span></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">unsigned</span><spanclass="title">int</span><spanclass="params">(*hashFunction)</span><spanclass="params">(<spanclass="keyword">const</span><spanclass="keyword">void</span> *key)</span></span>;</span><br><spanclass="line"><spanclass="keyword">void</span> *(*keyDup)(<spanclass="keyword">void</span> *privdata, <spanclass="keyword">const</span><spanclass="keyword">void</span> *key);</span><br><spanclass="line"><spanclass="keyword">void</span> *(*valDup)(<spanclass="keyword">void</span> *privdata, <spanclass="keyword">const</span><spanclass="keyword">void</span> *obj);</span><br><spanclass="line"><spanclass="keyword">int</span> (*keyCompare)(<spanclass="keyword">void</span> *privdata, <spanclass="keyword">const</span><spanclass="keyword">void</span> *key1, <spanclass="keyword">const</span><spanclass="keyword">void</span> *key2);</span><br><spanclass="line"><spanclass="keyword">void</span> (*keyDestructor)(<spanclass="keyword">void</span> *privdata, <spanclass="keyword">void</span> *key);</span><br><spanclass="line"><spanclass="keyword">void</span> (*valDestructor)(<spanclass="keyword">void</span> *privdata, <spanclass="keyword">void</span> *obj);</span><br><spanclass="line">} dictType;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="comment">/* This is our hash table structure. Every dictionary has two of this as we</span></span><br><spanclass="line"><spanclass="comment"> * implement incremental rehashing, for the old to the new table. */</span></span><br><spanclass="line"><spanclass="keyword">typedef</span><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">dictht</span>{</span></span><br><spanclass="line"> dictEntry **table;</span><br><spanclass="line"><spanclass="keyword">unsigned</span><spanclass="keyword">long</span><spanclass="built_in">size</span>;</span><br><spanclass="line"><spanclass="keyword">unsigned</span><spanclass="keyword">long</span> sizemask;</span><br><spanclass="line"><spanclass="keyword">unsigned</span><spanclass="keyword">long</span> used;</span><br><spanclass="line">} dictht;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">typedef</span><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">dict</span>{</span></span><br><spanclass="line"> dictType *type;</span><br><spanclass="line"><spanclass="keyword">void</span> *privdata;</span><br><spanclass="line"> dictht ht[<spanclass="number">2</span>];</span><br><spanclass="line"><spanclass="keyword">int</span> rehashidx; <spanclass="comment">/* rehashing not in progress if rehashidx == -1 */</span></span><br><spanclass="line"><spanclass="keyword">int</span> iterators; <spanclass="comment">/* number of iterators currently running */</span></span><br><spanclass="line">} dict;</span><br></pre></td></tr></table></figure>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<p>Flexible array members<ahref="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-1"target="_blank"rel="noopener">1</a> were introduced in the <ahref="https://en.wikipedia.org/wiki/C99"target="_blank"rel="noopener">C99</a> standard of the <ahref="https://en.wikipedia.org/wiki/C_(programming_language)"target="_blank"rel="noopener">C programming language</a> (in particular, in section §6.7.2.1, item 16, page 103).<ahref="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-2"target="_blank"rel="noopener">2</a> It is a member of a struct, which is an array without a given dimension. It must be the last member of such a struct and it must be accompanied by at least one other member, as in the following example:</p>
<p>Flexible array members<atarget="_blank"rel="noopener"href="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-1">1</a> were introduced in the <atarget="_blank"rel="noopener"href="https://en.wikipedia.org/wiki/C99">C99</a> standard of the <atarget="_blank"rel="noopener"href="https://en.wikipedia.org/wiki/C_(programming_language)">C programming language</a> (in particular, in section §6.7.2.1, item 16, page 103).<atarget="_blank"rel="noopener"href="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-2">2</a> It is a member of a struct, which is an array without a given dimension. It must be the last member of such a struct and it must be accompanied by at least one other member, as in the following example:</p>
</blockquote>
</blockquote>
<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="class"><spanclass="keyword">struct</span><spanclass="title">vectord</span>{</span></span><br><spanclass="line"><spanclass="keyword">size_t</span> len;</span><br><spanclass="line"><spanclass="keyword">double</span> arr[]; <spanclass="comment">// the flexible array member must be last</span></span><br><spanclass="line">};</span><br></pre></td></tr></table></figure>
<p>The ziplist is a specially encoded dually linked list that is designed to be very memory efficient.<br>这是摘自 redis 源码中ziplist.c 文件的注释,也说明了原因,它的大概结构是这样子</p>
<p>The ziplist is a specially encoded dually linked list that is designed to be very memory efficient.<br>这是摘自 redis 源码中ziplist.c 文件的注释,也说明了原因,它的大概结构是这样子</p>
<figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br><spanclass="line">26</span><br><spanclass="line">27</span><br></pre></td><tdclass="code"><pre><spanclass="line">* |00pppppp| - 1 byte</span><br><spanclass="line">* String value with length less than or equal to 63 bytes (6 bits).</span><br><spanclass="line">* "pppppp" represents the unsigned 6 bit length.</span><br><spanclass="line">* |01pppppp|qqqqqqqq| - 2 bytes</span><br><spanclass="line">* String value with length less than or equal to 16383 bytes (14 bits).</span><br><spanclass="line">* IMPORTANT: The 14 bit number is stored in big endian.</span><br><spanclass="line">* |10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes</span><br><spanclass="line">* String value with length greater than or equal to 16384 bytes.</span><br><spanclass="line">* Only the 4 bytes following the first byte represents the length</span><br><spanclass="line">* up to 32^2-1. The 6 lower bits of the first byte are not used and</span><br><spanclass="line">* are set to zero.</span><br><spanclass="line">* IMPORTANT: The 32 bit number is stored in big endian.</span><br><spanclass="line">* |11000000| - 3 bytes</span><br><spanclass="line">* Integer encoded as int16_t (2 bytes).</span><br><spanclass="line">* |11010000| - 5 bytes</span><br><spanclass="line">* Integer encoded as int32_t (4 bytes).</span><br><spanclass="line">* |11100000| - 9 bytes</span><br><spanclass="line">* Integer encoded as int64_t (8 bytes).</span><br><spanclass="line">* |11110000| - 4 bytes</span><br><spanclass="line">* Integer encoded as 24 bit signed (3 bytes).</span><br><spanclass="line">* |11111110| - 2 bytes</span><br><spanclass="line">* Integer encoded as 8 bit signed (1 byte).</span><br><spanclass="line">* |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer.</span><br><spanclass="line">* Unsigned integer from 0 to 12. The encoded value is actually from</span><br><spanclass="line">* 1 to 13 because 0000 and 1111 can not be used, so 1 should be</span><br><spanclass="line">* subtracted from the encoded 4 bit value to obtain the right value.</span><br><spanclass="line">* |11111111| - End of ziplist special entry.</span><br></pre></td></tr></table></figure>
* String value with length greater than or equal to 16384 bytes.
* Only the 4 bytes following the first byte represents the length
* up to 32^2-1. The 6 lower bits of the first byte are not used and
* are set to zero.
* IMPORTANT: The 32 bit number is stored in big endian.
* |11000000| - 3 bytes
* Integer encoded as int16_t (2 bytes).
* |11010000| - 5 bytes
* Integer encoded as int32_t (4 bytes).
* |11100000| - 9 bytes
* Integer encoded as int64_t (8 bytes).
* |11110000| - 4 bytes
* Integer encoded as 24 bit signed (3 bytes).
* |11111110| - 2 bytes
* Integer encoded as 8 bit signed (1 byte).
* |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer.
* Unsigned integer from 0 to 12. The encoded value is actually from
* 1 to 13 because 0000 and 1111 can not be used, so 1 should be
* subtracted from the encoded 4 bit value to obtain the right value.
* |11111111| - End of ziplist special entry.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2id="简单运行"><ahref="#简单运行"class="headerlink"title="简单运行"></a>简单运行</h2><p>然后再来运行个 hello world 呗,</p>
<h2id="简单运行"><ahref="#简单运行"class="headerlink"title="简单运行"></a>简单运行</h2><p>然后再来运行个 hello world 呗,</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br></pre></td><tdclass="code"><pre><spanclass="line">sudo docker run hello-world</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">sudo docker run hello-world<spanaria-hidden="true"class="line-numbers-rows"><span></span></span></code></pre>
<p>看看这个运行命令是怎么用的,一般都会看到这样子的,sudo docker run -it ubuntu bash<code>, 前面的 docker run 反正就是运行一个容器的意思,</code>-it<code>是啥呢,还有这个什么 ubuntu bash,来看看</code>docker run`的命令帮助信息</p>
<p>看看这个运行命令是怎么用的,一般都会看到这样子的,sudo docker run -it ubuntu bash<code>, 前面的 docker run 反正就是运行一个容器的意思,</code>-it<code>是啥呢,还有这个什么 ubuntu bash,来看看</code>docker run`的命令帮助信息</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br></pre></td><tdclass="code"><pre><spanclass="line">-i, --interactive Keep STDIN open even if not attached</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">-i, --interactive Keep STDIN open even if not attached<spanaria-hidden="true"class="line-numbers-rows"><span></span></span></code></pre>
<p>就是要有输入,我们运行的时候能输入</p>
<p>就是要有输入,我们运行的时候能输入</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br></pre></td><tdclass="code"><pre><spanclass="line">-t, --tty Allocate a pseudo-TTY</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">-t, --tty Allocate a pseudo-TTY<spanaria-hidden="true"class="line-numbers-rows"><span></span></span></code></pre>
<p>要有个虚拟终端,</p>
<p>要有个虚拟终端,</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br></pre></td><tdclass="code"><pre><spanclass="line">Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]</span><br><spanclass="line"></span><br><spanclass="line">Run a command in a new container</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 1234567#include <stdio.h>int main(void)&#123; int i = 0; for(;;) i++; return 0;&#125; 就是一个最简单的死循环,然后在容器里跑起来 12$ gcc 1.c">
<metaname="description"content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 #include <stdio.h>int main(void)&#123; int i = 0; for(;;) i++; return 0;&#125; 就是一个最简单的死循环,然后在容器里跑起来 $ gcc 1">
<metaproperty="og:description"content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 1234567#include <stdio.h>int main(void)&#123; int i = 0; for(;;) i++; return 0;&#125; 就是一个最简单的死循环,然后在容器里跑起来 12$ gcc 1.c">
<metaproperty="og:description"content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 #include <stdio.h> int main(void) &#123; int i = 0; for(;;) i++; return 0; &#125; 就是一个最简单的死循环,然后在容器里跑起来 $ gcc 1">
<h2id="限制下-docker-的-cpu-使用率"><ahref="#限制下-docker-的-cpu-使用率"class="headerlink"title="限制下 docker 的 cpu 使用率"></a>限制下 docker 的 cpu 使用率</h2><p>这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码</p>
<h2id="限制下-docker-的-cpu-使用率"><ahref="#限制下-docker-的-cpu-使用率"class="headerlink"title="限制下 docker 的 cpu 使用率"></a>限制下 docker 的 cpu 使用率</h2><p>这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码</p>
<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="meta">#<spanclass="meta-keyword">include</span><spanclass="meta-string"><stdio.h></span></span></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">int</span><spanclass="title">main</span><spanclass="params">(<spanclass="keyword">void</span>)</span></span></span><br><spanclass="line"><spanclass="function"></span>{</span><br><spanclass="line"><spanclass="keyword">int</span> i = <spanclass="number">0</span>;</span><br><spanclass="line"><spanclass="keyword">for</span>(;;) i++;</span><br><spanclass="line"><spanclass="keyword">return</span><spanclass="number">0</span>;</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<p>然后我们来看下系统资源占用(CPU)<br><imgdata-src="https://i.loli.net/2020/03/09/Xs562iawhHyMxeO.png"alt="Xs562iawhHyMxeO"><br>上图是在容器里的,可以看到 cpu 已经 100%了<br>然后看看容器外面的<br><imgdata-src="https://i.loli.net/2020/03/09/ecqH8XJ4k7rKhzu.png"alt="ecqH8XJ4k7rKhzu"><br>可以看到一个核的 cpu 也被占满了,因为是个双核的机器,并且代码是单线程的<br>然后呢我们要做点啥<br>因为已经在这个 ubuntu 容器中装了 vim 和 gcc,考虑到国内的网络,所以我们先把这个容器 commit 一下,</p>
<p>然后我们来看下系统资源占用(CPU)<br><imgdata-src="https://i.loli.net/2020/03/09/Xs562iawhHyMxeO.png"alt="Xs562iawhHyMxeO"><br>上图是在容器里的,可以看到 cpu 已经 100%了<br>然后看看容器外面的<br><imgdata-src="https://i.loli.net/2020/03/09/ecqH8XJ4k7rKhzu.png"alt="ecqH8XJ4k7rKhzu"><br>可以看到一个核的 cpu 也被占满了,因为是个双核的机器,并且代码是单线程的<br>然后呢我们要做点啥<br>因为已经在这个 ubuntu 容器中装了 vim 和 gcc,考虑到国内的网络,所以我们先把这个容器 commit 一下,</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br></pre></td><tdclass="code"><pre><spanclass="line">docker commit -a "nick" -m "my ubuntu" f63c5607df06 my_ubuntu:v1</span><br></pre></td></tr></table></figure>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">docker commit -a "nick" -m "my ubuntu" f63c5607df06 my_ubuntu:v1<spanaria-hidden="true"class="line-numbers-rows"><span></span></span></code></pre>
<p>然后再运行起来</p>
<p>然后再运行起来</p>
<figureclass="highlight shell"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br></pre></td><tdclass="code"><pre><spanclass="line">docker run -it --cpus=0.1 my_ubuntu:v1 bash</span><br></pre></td></tr></table></figure>
<p><imgdata-src="https://i.loli.net/2020/03/15/x2oGCPQr9Mm8ZYj.png"alt=""><br>我们的代码跟可执行文件都还在,要的就是这个效果,然后再运行一下<br><imgdata-src="https://i.loli.net/2020/03/10/3EgzYxpqlwobNRj.png"alt=""><br>结果是这个样子的,有点神奇是不,关键就在于 run 的时候的<code>--cpus=0.1</code>这个参数,它其实就是基于我前一篇说的 cgroup 技术,能将进程之间的cpu,内存等资源进行隔离</p>
<preclass="line-numbers language-shell"data-language="shell"><codeclass="language-shell">docker run -it --cpus=0.1 my_ubuntu:v1 bash<spanaria-hidden="true"class="line-numbers-rows"><span></span></span></code></pre>
<p><imgdata-src="https://i.loli.net/2020/03/15/x2oGCPQr9Mm8ZYj.png"><br>我们的代码跟可执行文件都还在,要的就是这个效果,然后再运行一下<br><imgdata-src="https://i.loli.net/2020/03/10/3EgzYxpqlwobNRj.png"><br>结果是这个样子的,有点神奇是不,关键就在于 run 的时候的<code>--cpus=0.1</code>这个参数,它其实就是基于我前一篇说的 cgroup 技术,能将进程之间的cpu,内存等资源进行隔离</p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<metaproperty="og:description"content="最近做 docker 系列,会经常进到 docker 内部,如上一篇介绍的,这些镜像一般都有用 ubuntu 或者alpine 这样的 Linux 系统作为底包,如果构建镜像的时候没有替换源的话,因为你懂的原因,在内部想编辑下东西要安装 vim 就会很慢很慢,thousand years later~而且如果在容器内部想改源配置的话也要编辑器,就陷入了一个鸡生蛋,跟蛋生鸡的问题中,对于 linux">
<metaproperty="og:description"content="最近做 docker 系列,会经常进到 docker 内部,如上一篇介绍的,这些镜像一般都有用 ubuntu 或者alpine 这样的 Linux 系统作为底包,如果构建镜像的时候没有替换源的话,因为你懂的原因,在内部想编辑下东西要安装 vim 就会很慢很慢,thousand years later~而且如果在容器内部想改源配置的话也要编辑器,就陷入了一个鸡生蛋,跟蛋生鸡的问题中,对于 linux">
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity 12345678910111213141516171819202122public class Entity &#123; private Long id; private Long sortValue; pu">
<metaname="description"content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity public class Entity &#123; private Long id; private Long sortValue; public Long getId() &#123;">
<metaproperty="og:description"content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity 12345678910111213141516171819202122public class Entity &#123; private Long id; private Long sortValue; pu">
<metaproperty="og:description"content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity public class Entity &#123; private Long id; private Long sortValue; public Long getId() &#123;">
<figureclass="highlight java"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="keyword">public</span><spanclass="class"><spanclass="keyword">class</span><spanclass="title">Entity</span></span>{</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">private</span> Long id;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">private</span> Long sortValue;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">public</span> Long <spanclass="title">getId</span><spanclass="params">()</span></span>{</span><br><spanclass="line"><spanclass="keyword">return</span> id;</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">public</span><spanclass="keyword">void</span><spanclass="title">setId</span><spanclass="params">(Long id)</span></span>{</span><br><spanclass="line"><spanclass="keyword">this</span>.id = id;</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">public</span> Long <spanclass="title">getSortValue</span><spanclass="params">()</span></span>{</span><br><spanclass="line"><spanclass="keyword">return</span> sortValue;</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">public</span><spanclass="keyword">void</span><spanclass="title">setSortValue</span><spanclass="params">(Long sortValue)</span></span>{</span><br><spanclass="line"><spanclass="keyword">this</span>.sortValue = sortValue;</span><br><spanclass="line">}</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<p>腆着脸说虽然这个不可行,但是思路是对的,具体实行起来需要做一系列(肥肠多)的改动,首先根据我的理解,其实这个拷贝一个表是变成拷贝一条记录,但是如果有多个事务,那就得拷贝多次,这个问题其实可以借助版本管理系统来解释,在用版本管理系统,git 之类的之前,很原始的可能是开发完一个功能后,就打个压缩包用时间等信息命名,然后如果后面要找回这个就直接用这个压缩包的就行了,后来有了 svn,git 中心式和分布式的版本管理系统,它的一个特点是粒度可以控制到文件和代码行级别,对应的我们的 mysql 事务是不是也可以从一开始预想的表级别细化到行的级别,可能之前很多人都了解过,数据库的一行记录除了我们用户自定义的字段,还有一些额外的字段,去源码<ahref="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/data0type.h#L170"target="_blank"rel="noopener">data0type.h</a>里捞一下</p>
<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="comment">/* Precise data types for system columns and the length of those columns;</span></span><br><spanclass="line"><spanclass="comment"><spanclass="doctag">NOTE:</span> the values must run from 0 up in the order given! All codes must</span></span><br><spanclass="line"><spanclass="comment">be less than 256 */</span></span><br><spanclass="line"><spanclass="meta">#<spanclass="meta-keyword">define</span> DATA_ROW_ID 0 <spanclass="comment">/* row id: a 48-bit integer */</span></span></span><br><spanclass="line"><spanclass="meta">#<spanclass="meta-keyword">define</span> DATA_ROW_ID_LEN 6 <spanclass="comment">/* stored length for row id */</span></span></span><br><spanclass="line"></span><br><spanclass="line"><spanclass="comment">/** Transaction id: 6 bytes */</span></span><br><spanclass="line"><spanclass="keyword">constexpr</span><spanclass="keyword">size_t</span> DATA_TRX_ID = <spanclass="number">1</span>;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="comment">/** Transaction ID type size in bytes. */</span></span><br><spanclass="line"><spanclass="keyword">constexpr</span><spanclass="keyword">size_t</span> DATA_TRX_ID_LEN = <spanclass="number">6</span>;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="comment">/** Rollback data pointer: 7 bytes */</span></span><br><spanclass="line"><spanclass="keyword">constexpr</span><spanclass="keyword">size_t</span> DATA_ROLL_PTR = <spanclass="number">2</span>;</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="comment">/** Rollback data pointer type size in bytes. */</span></span><br><spanclass="line"><spanclass="keyword">constexpr</span><spanclass="keyword">size_t</span> DATA_ROLL_PTR_LEN = <spanclass="number">7</span>;</span><br></pre></td></tr></table></figure>
<p>很久以前,有位面试官问到,你知道 mysql 的事务隔离级别吗,“额 O__O …,不太清楚”,完了之后我就去网上找相关的文章,找到了这篇<atarget="_blank"rel="noopener"href="https://www.cnblogs.com/zhoujinyi/p/3437475.html">MySQL 四种事务隔离级的说明</a>, 文章写得特别好,看了这个就懂了各个事务隔离级别都是啥,不过看了这个之后多思考一下的话还是会发现问题,这么神奇的事务隔离级别是怎么实现的呢</p>
<p>腆着脸说虽然这个不可行,但是思路是对的,具体实行起来需要做一系列(肥肠多)的改动,首先根据我的理解,其实这个拷贝一个表是变成拷贝一条记录,但是如果有多个事务,那就得拷贝多次,这个问题其实可以借助版本管理系统来解释,在用版本管理系统,git 之类的之前,很原始的可能是开发完一个功能后,就打个压缩包用时间等信息命名,然后如果后面要找回这个就直接用这个压缩包的就行了,后来有了 svn,git 中心式和分布式的版本管理系统,它的一个特点是粒度可以控制到文件和代码行级别,对应的我们的 mysql 事务是不是也可以从一开始预想的表级别细化到行的级别,可能之前很多人都了解过,数据库的一行记录除了我们用户自定义的字段,还有一些额外的字段,去源码<atarget="_blank"rel="noopener"href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/data0type.h#L170">data0type.h</a>里捞一下</p>
<preclass="line-numbers language-c"data-language="c"><codeclass="language-c"><spanclass="token comment">/* Precise data types for system columns and the length of those columns;
NOTE: the values must run from 0 up in the order given! All codes must
<li>如果记录的事务 <code>id</code> 介于 <code>m_low_limit_id</code> 和 <code>m_up_limit_id</code> 之间,则要判断它是否在 <code>m_ids</code> 中,如果在,不可见,如果不在,表示已提交,可见<br>具体的<ahref="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/read0types.h#L160"target="_blank"rel="noopener">代码</a>捞一下看看<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br><spanclass="line">24</span><br><spanclass="line">25</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="comment">/** Check whether the changes by id are visible.</span></span><br><spanclass="line"><spanclass="comment"> @param[in] id transaction id to check against the view</span></span><br><spanclass="line"><spanclass="comment"> @param[in] name table name</span></span><br><spanclass="line"><spanclass="comment"> @return whether the view sees the modifications of id. */</span></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">bool</span><spanclass="title">changes_visible</span><spanclass="params">(<spanclass="keyword">trx_id_t</span> id, <spanclass="keyword">const</span><spanclass="keyword">table_name_t</span>&name)</span><spanclass="keyword">const</span></span></span><br><spanclass="line"><spanclass="function"><spanclass="title">MY_ATTRIBUTE</span><spanclass="params">((warn_unused_result))</span></span>{</span><br><spanclass="line"> ut_ad(id ><spanclass="number">0</span>);</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">if</span> (id < m_up_limit_id || id == m_creator_trx_id) {</span><br><spanclass="line"><spanclass="keyword">return</span> (<spanclass="literal">true</span>);</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"> check_trx_id_sanity(id, name);</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">if</span> (id >= m_low_limit_id) {</span><br><spanclass="line"><spanclass="keyword">return</span> (<spanclass="literal">false</span>);</span><br><spanclass="line"></span><br><spanclass="line">}<spanclass="keyword">else</span><spanclass="keyword">if</span> (m_ids.empty()) {</span><br><spanclass="line"><spanclass="keyword">return</span> (<spanclass="literal">true</span>);</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">const</span><spanclass="keyword">ids_t</span>::value_type *p = m_ids.data();</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="keyword">return</span> (!<spanclass="built_in">std</span>::binary_search(p, p + m_ids.<spanclass="built_in">size</span>(), id));</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
<li>如果记录的事务 <code>id</code> 介于 <code>m_low_limit_id</code> 和 <code>m_up_limit_id</code> 之间,则要判断它是否在 <code>m_ids</code> 中,如果在,不可见,如果不在,表示已提交,可见<br>具体的<atarget="_blank"rel="noopener"href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/read0types.h#L160">代码</a>捞一下看看<preclass="line-numbers language-C"data-language="C"><codeclass="language-C">/** Check whether the changes by id are visible.
@param[in] id transaction id to check against the view
@param[in] name table name
@return whether the view sees the modifications of id. */
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<figureclass="highlight c"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="comment">/**</span></span><br><spanclass="line"><spanclass="comment">Opens a read view where exactly the transactions serialized before this</span></span><br><spanclass="line"><spanclass="comment">point in time are seen in the view.</span></span><br><spanclass="line"><spanclass="comment">@param id Creator transaction id */</span></span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">void</span><spanclass="title">ReadView::prepare</span><spanclass="params">(<spanclass="keyword">trx_id_t</span> id)</span></span>{</span><br><spanclass="line"> ut_ad(mutex_own(&trx_sys->mutex));</span><br><spanclass="line"></span><br><spanclass="line"> m_creator_trx_id = id;</span><br><spanclass="line"></span><br><spanclass="line"> m_low_limit_no = m_low_limit_id = m_up_limit_id = trx_sys->max_trx_id;</span><br></pre></td></tr></table></figure>
<h2id="幻读"><ahref="#幻读"class="headerlink"title="幻读"></a>幻读</h2><p>还有一个问题是幻读的问题,这貌似也是个高频面试题,啥意思呢,或者说跟它最常拿来比较的脏读,脏读是指读到了别的事务未提交的数据,因为未提交,严格意义上来讲,不一定是会被最后落到库里,可能会回滚,也就是在 read uncommitted 级别下会出现的问题,但是幻读不太一样,幻读是指两次查询的结果数量不一样,比如我查了第一次是 <code>select * from table1 where id < 10 for update</code>,查出来了一条结果 id 是 5,然后再查一下发现出来了一条 id 是 5,一条 id 是 7,那是不是有点尴尬了,其实呢这个点我觉得脏读跟幻读也比较是从原理层面来命名,如果第一次接触的同学发觉有点不理解也比较正常,因为从逻辑上讲总之都是数据不符合预期,但是基于源码层面其实是不同的情况,幻读是在原先的 read view 无法完全解决的,怎么解决呢,简单的来说就是锁咯,我们知道innodb 是基于 record lock 行锁的,但是貌似没有办法解决这种问题,那么 innodb 就引入了 gap lock 间隙锁,比如上面说的情况下,id 小于 10 的情况下,是都应该锁住的,gap lock 其实是基于索引结构来锁的,因为索引树除了树形结构之外,还有一个next record 的指针,gap lock 也是基于这个来锁的<br>看一下 mysql 的文档</p>
<h2id="幻读"><ahref="#幻读"class="headerlink"title="幻读"></a>幻读</h2><p>还有一个问题是幻读的问题,这貌似也是个高频面试题,啥意思呢,或者说跟它最常拿来比较的脏读,脏读是指读到了别的事务未提交的数据,因为未提交,严格意义上来讲,不一定是会被最后落到库里,可能会回滚,也就是在 read uncommitted 级别下会出现的问题,但是幻读不太一样,幻读是指两次查询的结果数量不一样,比如我查了第一次是 <code>select * from table1 where id < 10 for update</code>,查出来了一条结果 id 是 5,然后再查一下发现出来了一条 id 是 5,一条 id 是 7,那是不是有点尴尬了,其实呢这个点我觉得脏读跟幻读也比较是从原理层面来命名,如果第一次接触的同学发觉有点不理解也比较正常,因为从逻辑上讲总之都是数据不符合预期,但是基于源码层面其实是不同的情况,幻读是在原先的 read view 无法完全解决的,怎么解决呢,简单的来说就是锁咯,我们知道innodb 是基于 record lock 行锁的,但是貌似没有办法解决这种问题,那么 innodb 就引入了 gap lock 间隙锁,比如上面说的情况下,id 小于 10 的情况下,是都应该锁住的,gap lock 其实是基于索引结构来锁的,因为索引树除了树形结构之外,还有一个next record 的指针,gap lock 也是基于这个来锁的<br>看一下 mysql 的文档</p>
<blockquote>
<blockquote>
@ -336,13 +335,13 @@
<divclass="popular-posts-title"><ahref="/2020/04/26/聊聊-mysql-的-MVCC/"rel="bookmark">聊聊 mysql 的 MVCC</a></div>
<divclass="popular-posts-title"><ahref="/2020/04/26/聊聊-mysql-的-MVCC/"rel="bookmark">聊聊 mysql 的 MVCC</a></div>
<metaproperty="og:description"content="看完前面两篇水文之后,感觉不得不来分析下 mysql 的锁了,其实前面说到幻读的时候是有个前提没提到的,比如一个select * from table1 where id = 1这种查询语句其实是不会加传说中的锁的,当然这里是指在 RR 或者 RC 隔离级别下,看一段 mysql官方文档 SELECT ... FROM is a consistent read, reading a snaps">
<metaproperty="og:description"content="看完前面两篇水文之后,感觉不得不来分析下 mysql 的锁了,其实前面说到幻读的时候是有个前提没提到的,比如一个select * from table1 where id = 1这种查询语句其实是不会加传说中的锁的,当然这里是指在 RR 或者 RC 隔离级别下,看一段 mysql官方文档 SELECT ... FROM is a consistent read, reading a snaps">
<p>除了第一条是 S 锁之外,其他都是 X 排他锁,这边在顺带下,S 锁表示共享锁, X 表示独占锁,同为 S 锁之间不冲突,S 与 X,X 与 S,X 与 X 之间都冲突,也就是加了前者,后者就加不上了<br>我们知道对于 RC 级别会出现幻读现象,对于 RR 级别不会出现,主要的区别是 RR 级别下对于以上的加锁读取都根据情况加上了 gap 锁,那么是不是 RR 级别下以上所有的都是要加 gap 锁呢,当然不是<br>举个例子,RR 事务隔离级别下,table1 有个主键id 字段<br><code>select * from table1 where id = 10 for update</code><br>这条语句要加 gap 锁吗?<br>答案是不需要,这里其实算是我看了这么久的一点自己的理解,啥时候要加 gap 锁,判断的条件是根据我查询的数据是否会因为不加 gap 锁而出现数量的不一致,我上面这条查询语句,在什么情况下会出现查询结果数量不一致呢,只要在这条记录被更新或者删除的时候,有没有可能我第一次查出来一条,第二次变成两条了呢,不可能,因为是主键索引。<br>再变更下这个题的条件,当 id 不是主键,但是是唯一索引,这样需要怎么加锁,注意问题是怎么加锁,不是需不需要加 gap 锁,这里呢就是稍微延伸一下,把聚簇索引(主键索引)和二级索引带一下,当 id 不是主键,说明是个二级索引,但是它是唯一索引,体会下,首先对于 id = 10这个二级索引肯定要加锁,要不要锁 gap 呢,不用,因为是唯一索引,id = 10 只可能有这一条记录,然后呢,这样是不是就好了,还不行,因为啥,因为它是二级索引,对应的主键索引的记录才是真正的数据,万一被更新掉了咋办,所以在 id = 10 对应的主键索引上也需要加上锁(默认都是 record lock行锁),那主键索引上要不要加 gap 呢,也不用,也是精确定位到这一条记录<br>最后呢,当 id 不是主键,也不是唯一索引,只是个普通的索引,这里就需要大名鼎鼎的 gap 锁了,<br>是时候画个图了<br><imgdata-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200510-1126082x.png"alt=""><br>其实核心的目的还是不让这个 id=10 的记录不会出现幻读,那么就需要在 id 这个索引上加上三个 gap 锁,主键索引上就不用了,在 id 索引上已经控制住了id = 10 不会出现幻读,主键索引上这两条对应的记录已经锁了,所以就这样 OK 了</p>
<p>除了第一条是 S 锁之外,其他都是 X 排他锁,这边在顺带下,S 锁表示共享锁, X 表示独占锁,同为 S 锁之间不冲突,S 与 X,X 与 S,X 与 X 之间都冲突,也就是加了前者,后者就加不上了<br>我们知道对于 RC 级别会出现幻读现象,对于 RR 级别不会出现,主要的区别是 RR 级别下对于以上的加锁读取都根据情况加上了 gap 锁,那么是不是 RR 级别下以上所有的都是要加 gap 锁呢,当然不是<br>举个例子,RR 事务隔离级别下,table1 有个主键id 字段<br><code>select * from table1 where id = 10 for update</code><br>这条语句要加 gap 锁吗?<br>答案是不需要,这里其实算是我看了这么久的一点自己的理解,啥时候要加 gap 锁,判断的条件是根据我查询的数据是否会因为不加 gap 锁而出现数量的不一致,我上面这条查询语句,在什么情况下会出现查询结果数量不一致呢,只要在这条记录被更新或者删除的时候,有没有可能我第一次查出来一条,第二次变成两条了呢,不可能,因为是主键索引。<br>再变更下这个题的条件,当 id 不是主键,但是是唯一索引,这样需要怎么加锁,注意问题是怎么加锁,不是需不需要加 gap 锁,这里呢就是稍微延伸一下,把聚簇索引(主键索引)和二级索引带一下,当 id 不是主键,说明是个二级索引,但是它是唯一索引,体会下,首先对于 id = 10这个二级索引肯定要加锁,要不要锁 gap 呢,不用,因为是唯一索引,id = 10 只可能有这一条记录,然后呢,这样是不是就好了,还不行,因为啥,因为它是二级索引,对应的主键索引的记录才是真正的数据,万一被更新掉了咋办,所以在 id = 10 对应的主键索引上也需要加上锁(默认都是 record lock行锁),那主键索引上要不要加 gap 呢,也不用,也是精确定位到这一条记录<br>最后呢,当 id 不是主键,也不是唯一索引,只是个普通的索引,这里就需要大名鼎鼎的 gap 锁了,<br>是时候画个图了<br><imgdata-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200510-1126082x.png"><br>其实核心的目的还是不让这个 id=10 的记录不会出现幻读,那么就需要在 id 这个索引上加上三个 gap 锁,主键索引上就不用了,在 id 索引上已经控制住了id = 10 不会出现幻读,主键索引上这两条对应的记录已经锁了,所以就这样 OK 了</p>
</div>
</div>
@ -337,13 +332,13 @@
<divclass="popular-posts-title"><ahref="/2020/04/26/聊聊-mysql-的-MVCC/"rel="bookmark">聊聊 mysql 的 MVCC</a></div>
<divclass="popular-posts-title"><ahref="/2020/04/26/聊聊-mysql-的-MVCC/"rel="bookmark">聊聊 mysql 的 MVCC</a></div>
<p>下单的是后要冻结核销优惠券,如果账户里有钱要冻结扣除账户里的钱,如果使用了J 豆也一样,可能还有 E 卡,忽略我借用的平台,因为目前一般后台服务化之后,可能每一项都是对应的一个后台服务,我们期望的执行过程是要不全成功,要不就全保持执行前状态,不能是部分扣减核销成功了,部分还不行,所以我们处理这种情况会引入一些通用的方案,第一种叫<ahref="https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4"target="_blank"rel="noopener">二阶段提交</a>,</p>
<p>下单的是后要冻结核销优惠券,如果账户里有钱要冻结扣除账户里的钱,如果使用了J 豆也一样,可能还有 E 卡,忽略我借用的平台,因为目前一般后台服务化之后,可能每一项都是对应的一个后台服务,我们期望的执行过程是要不全成功,要不就全保持执行前状态,不能是部分扣减核销成功了,部分还不行,所以我们处理这种情况会引入一些通用的方案,第一种叫<atarget="_blank"rel="noopener"href="https://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4">二阶段提交</a>,</p>
<p>对于上面的例子,我们将整个过程分成两个阶段,首先是提交请求阶段,这个阶段大概需要做的是确定资源存在,锁定资源,可能还要做好失败后回滚的准备,如果这些都 ok 了那么就响应成功,这里其实用到了一个叫事务的协调者的角色,类似于裁判员,每个节点都反馈第一阶段成功后,开始执行第二阶段,也就是实际执行操作,这里也是需要所有节点都反馈成功后才是执行成功,要不就是失败回滚。其实常用的分布式事务的解决方案主要也是基于此方案的改进,比如后面介绍的<ahref="https://zh.wikipedia.org/wiki/%E4%B8%89%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4"target="_blank"rel="noopener">三阶段提交</a>,有三阶段提交就是因为二阶段提交比较尴尬的几个点,</p>
<p>对于上面的例子,我们将整个过程分成两个阶段,首先是提交请求阶段,这个阶段大概需要做的是确定资源存在,锁定资源,可能还要做好失败后回滚的准备,如果这些都 ok 了那么就响应成功,这里其实用到了一个叫事务的协调者的角色,类似于裁判员,每个节点都反馈第一阶段成功后,开始执行第二阶段,也就是实际执行操作,这里也是需要所有节点都反馈成功后才是执行成功,要不就是失败回滚。其实常用的分布式事务的解决方案主要也是基于此方案的改进,比如后面介绍的<atarget="_blank"rel="noopener"href="https://zh.wikipedia.org/wiki/%E4%B8%89%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4">三阶段提交</a>,有三阶段提交就是因为二阶段提交比较尴尬的几个点,</p>
<p>因为传说中的出身问题,我以前写的是PHP,在使用 swoole 之前,基本的应用调试手段就是简单粗暴的 var_dump,exit,对于单进程模型的 PHP 也是简单有效,技术栈换成 Java 之后,就变得没那么容易,一方面是需要编译,另一方面是一般都是基于 spring 的项目,如果问题定位比较模糊,那框架层的是很难靠简单的 System.out.println 或者打 log 解决,(PS:我觉得可能我写的东西比较适合从 PHP 这种弱类型语言转到 Java 的小白同学)这个时候一方面因为是 Java,有了非常好用的 idea IDE 的支持,可以各种花式调试,条件断点尤其牛叉,但是又因为有 Spring+Java 的双重原因,有些情况下单步调试可以把手按废掉,这也是我之前一直比较困惑苦逼的点,后来随着慢慢精(jiang)进(you)之后,比如对于一个 oom 的情况,我们可以通过启动参数加上-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=xx/xx 来配置溢出时的堆dump 日志,获取到这个文件后,我们可以通过像 Memory Analyzer (MAT)[<ahref="https://www.eclipse.org/mat/]"target="_blank"rel="noopener">https://www.eclipse.org/mat/]</a> (The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption.)来查看诊断问题所在,之前用到的时候是因为有个死循环一直往链表里塞数据,属于比较简单的,后来一次是由于运维进行应用迁移时按默认的统一配置了堆内存大小,导致内存的确不够用,所以溢出了,<br>今天想说的其实主要是我们的 thread dump,这也是我最近才真正用的一个方法,可能真的很小白了,用过 ide 的单步调试其实都知道会有一个一层层的玩意,比如函数从 A,调用了 B,再从 B 调用了 C,一直往下(因为是 Java,所以还有很多🤦♂️),这个其实也是大部分语言的调用模型,利用了栈这个数据结构,通过这个结构我们可以知道代码的调用链路,由于对于一个 spring 应用,在本身框架代码量非常庞大的情况下,外加如果应用代码也是非常多的时候,有时候通过单步调试真的很难短时间定位到问题,需要非常大的耐心和仔细观察,当然不是说完全不行,举个例子当我的应用经常启动需要非常长的时间,因为本身应用有非常多个 bean,比较难说究竟是 bean 的加载的确很慢还是有什么异常原因,这种时候就可以使用 thread dump 了,具体怎么操作呢<br><imgdata-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png"alt=""><br>如果在idea 中运行或者调试时,可以直接点击这个照相机一样的按钮,右边就会出现了左边会显示所有的线程,右边会显示线程栈,</p>
<figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br></pre></td><tdclass="code"><pre><spanclass="line">"main@1" prio=5 tid=0x1 nid=NA runnable</span><br><spanclass="line"> java.lang.Thread.State: RUNNABLE</span><br><spanclass="line"> at TreeDistance.treeDist(TreeDistance.java:64)</span><br><spanclass="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><spanclass="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><spanclass="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><spanclass="line"> at TreeDistance.main(TreeDistance.java:45)</span><br></pre></td></tr></table></figure>
<p>因为传说中的出身问题,我以前写的是PHP,在使用 swoole 之前,基本的应用调试手段就是简单粗暴的 var_dump,exit,对于单进程模型的 PHP 也是简单有效,技术栈换成 Java 之后,就变得没那么容易,一方面是需要编译,另一方面是一般都是基于 spring 的项目,如果问题定位比较模糊,那框架层的是很难靠简单的 System.out.println 或者打 log 解决,(PS:我觉得可能我写的东西比较适合从 PHP 这种弱类型语言转到 Java 的小白同学)这个时候一方面因为是 Java,有了非常好用的 idea IDE 的支持,可以各种花式调试,条件断点尤其牛叉,但是又因为有 Spring+Java 的双重原因,有些情况下单步调试可以把手按废掉,这也是我之前一直比较困惑苦逼的点,后来随着慢慢精(jiang)进(you)之后,比如对于一个 oom 的情况,我们可以通过启动参数加上-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=xx/xx 来配置溢出时的堆dump 日志,获取到这个文件后,我们可以通过像 Memory Analyzer (MAT)[<atarget="_blank"rel="noopener"href="https://www.eclipse.org/mat/]">https://www.eclipse.org/mat/]</a> (The Eclipse Memory Analyzer is a fast and feature-rich Java heap analyzer that helps you find memory leaks and reduce memory consumption.)来查看诊断问题所在,之前用到的时候是因为有个死循环一直往链表里塞数据,属于比较简单的,后来一次是由于运维进行应用迁移时按默认的统一配置了堆内存大小,导致内存的确不够用,所以溢出了,<br>今天想说的其实主要是我们的 thread dump,这也是我最近才真正用的一个方法,可能真的很小白了,用过 ide 的单步调试其实都知道会有一个一层层的玩意,比如函数从 A,调用了 B,再从 B 调用了 C,一直往下(因为是 Java,所以还有很多🤦♂️),这个其实也是大部分语言的调用模型,利用了栈这个数据结构,通过这个结构我们可以知道代码的调用链路,由于对于一个 spring 应用,在本身框架代码量非常庞大的情况下,外加如果应用代码也是非常多的时候,有时候通过单步调试真的很难短时间定位到问题,需要非常大的耐心和仔细观察,当然不是说完全不行,举个例子当我的应用经常启动需要非常长的时间,因为本身应用有非常多个 bean,比较难说究竟是 bean 的加载的确很慢还是有什么异常原因,这种时候就可以使用 thread dump 了,具体怎么操作呢<br><imgdata-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png"><br>如果在idea 中运行或者调试时,可以直接点击这个照相机一样的按钮,右边就会出现了左边会显示所有的线程,右边会显示线程栈,</p>
at TreeDistance.main(TreeDistance.java:45)<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
type <spanclass="token operator">+</span><spanclass="token string">") could not be instantiated: "</span><spanclass="token operator">+</span> t<spanclass="token punctuation">.</span><spanclass="token function">getMessage</span><spanclass="token punctuation">(</span><spanclass="token punctuation">)</span><spanclass="token punctuation">,</span> t<spanclass="token punctuation">)</span><spanclass="token punctuation">;</span>
<figureclass="highlight java"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="comment">/**</span></span><br><spanclass="line"><spanclass="comment"> * test if clazz is a wrapper class</span></span><br><spanclass="line"><spanclass="comment"> * <p></span></span><br><spanclass="line"><spanclass="comment"> * which has Constructor with given class type as its only argument</span></span><br><spanclass="line"><spanclass="comment"> */</span></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">private</span><spanclass="keyword">boolean</span><spanclass="title">isWrapperClass</span><spanclass="params">(Class<?> clazz)</span></span>{</span><br><spanclass="line"><spanclass="keyword">try</span>{</span><br><spanclass="line"> clazz.getConstructor(type);</span><br><spanclass="line"><spanclass="keyword">return</span><spanclass="keyword">true</span>;</span><br><spanclass="line">}<spanclass="keyword">catch</span> (NoSuchMethodException e) {</span><br><spanclass="line"><spanclass="keyword">return</span><spanclass="keyword">false</span>;</span><br><spanclass="line">}</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 12grep 'xxx' xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\"userId\":\"123456\",因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了,如果直接这样">
<metaname="description"content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 grep 'xxx' xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\"userId\":\"123456\",因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了">
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:123Input: s = "abcab">
<metaname="description"content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:Input: s = "abcabcbb">
<metaproperty="og:type"content="article">
<metaproperty="og:type"content="article">
<metaproperty="og:title"content="Leetcode 3 Longest Substring Without Repeating Characters 题解分析">
<metaproperty="og:title"content="Leetcode 3 Longest Substring Without Repeating Characters 题解分析">
<metaproperty="og:description"content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:123Input: s = "abcab">
<metaproperty="og:description"content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:Input: s = "abcabcbb">
<h2id="简要介绍"><ahref="#简要介绍"class="headerlink"title="简要介绍"></a>简要介绍</h2><p>Given a string <code>s</code>, find the length of the <strong>longest substring</strong> without repeating characters.</p>
<h2id="简要介绍"><ahref="#简要介绍"class="headerlink"title="简要介绍"></a>简要介绍</h2><p>Given a string <code>s</code>, find the length of the <strong>longest substring</strong> without repeating characters.</p>
<h2id="样例"><ahref="#样例"class="headerlink"title="样例"></a>样例</h2><h4id="Example-1"><ahref="#Example-1"class="headerlink"title="Example 1:"></a>Example 1:</h4><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br></pre></td><tdclass="code"><pre><spanclass="line">Input: s ="abcabcbb"</span><br><spanclass="line">Output: 3</span><br><spanclass="line">Explanation: The answer is "abc", with the length of 3.</span><br></pre></td></tr></table></figure>
<h4id="Example-2"><ahref="#Example-2"class="headerlink"title="Example 2:"></a>Example 2:</h4><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br></pre></td><tdclass="code"><pre><spanclass="line">Input: s ="bbbbb"</span><br><spanclass="line">Output: 1</span><br><spanclass="line">Explanation: The answer is "b", with the length of 1.</span><br></pre></td></tr></table></figure>
<h4id="Example-3"><ahref="#Example-3"class="headerlink"title="Example 3:"></a>Example 3:</h4><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br></pre></td><tdclass="code"><pre><spanclass="line">Input: s ="pwwkew"</span><br><spanclass="line">Output: 3</span><br><spanclass="line">Explanation: The answer is "wke", with the length of 3.</span><br><spanclass="line">Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.</span><br></pre></td></tr></table></figure>
<h4id="Example-4"><ahref="#Example-4"class="headerlink"title="Example 4:"></a>Example 4:</h4><figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br></pre></td><tdclass="code"><pre><spanclass="line">Input: s =""</span><br><spanclass="line">Output: 0</span><br></pre></td></tr></table></figure>
<h2id="样例"><ahref="#样例"class="headerlink"title="样例"></a>样例</h2><h4id="Example-1"><ahref="#Example-1"class="headerlink"title="Example 1:"></a>Example 1:</h4><preclass="line-numbers language-none"><codeclass="language-none">Input: s ="abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h4id="Example-2"><ahref="#Example-2"class="headerlink"title="Example 2:"></a>Example 2:</h4><preclass="line-numbers language-none"><codeclass="language-none">Input: s ="bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h4id="Example-3"><ahref="#Example-3"class="headerlink"title="Example 3:"></a>Example 3:</h4><preclass="line-numbers language-none"><codeclass="language-none">Input: s ="pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h4id="Example-4"><ahref="#Example-4"class="headerlink"title="Example 4:"></a>Example 4:</h4><preclass="line-numbers language-none"><codeclass="language-none">Input: s =""
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/"rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<metaproperty="og:description"content="又 roll 到了一个以前做过的题,不过现在用 Java 也来写一下,是 easy 级别的,所以就简单说下 简要介绍You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nod">
<metaproperty="og:description"content="又 roll 到了一个以前做过的题,不过现在用 Java 也来写一下,是 easy 级别的,所以就简单说下 简要介绍You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nod">
<p>又 roll 到了一个以前做过的题,不过现在用 Java 也来写一下,是 easy 级别的,所以就简单说下</p>
<p>又 roll 到了一个以前做过的题,不过现在用 Java 也来写一下,是 easy 级别的,所以就简单说下</p>
<h2id="简要介绍"><ahref="#简要介绍"class="headerlink"title="简要介绍"></a>简要介绍</h2><p>You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.</p>
<h2id="简要介绍"><ahref="#简要介绍"class="headerlink"title="简要介绍"></a>简要介绍</h2><p>You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.</p>
<p>You may assume the two numbers do not contain any leading zero, except the number 0 itself.<br>就是给了两个链表,用来表示两个非负的整数,在链表中倒序放着,每个节点包含一位的数字,把他们加起来以后也按照原来的链表结构输出</p>
<p>You may assume the two numbers do not contain any leading zero, except the number 0 itself.<br>就是给了两个链表,用来表示两个非负的整数,在链表中倒序放着,每个节点包含一位的数字,把他们加起来以后也按照原来的链表结构输出</p>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/"rel="bookmark">Leetcode 121 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 题解分析</a></div>
<metaproperty="og:description"content="在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来">
<metaproperty="og:description"content="在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来">
<p>在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来对bean 内部的属性和方法进行判断,是否有 value 注解,如果有就是将它注册到一个 map 中,可以看到这个方法<code>com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor#processField</code></p>
<p>在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来对bean 内部的属性和方法进行判断,是否有 value 注解,如果有就是将它注册到一个 map 中,可以看到这个方法<code>com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor#processField</code></p>
<metaproperty="og:description"content="题目介绍Given a singly linked list, determine if it is a palindrome.给定一个单向链表,判断是否是回文链表 例一 Example 1:Input: 1->2Output: false 例二 Example 2:Input: 1->2->2->1Output: true 挑战下自己Follow up:Could you">
<metaproperty="og:description"content="题目介绍Given a singly linked list, determine if it is a palindrome.给定一个单向链表,判断是否是回文链表 例一 Example 1:Input: 1->2Output: false 例二 Example 2:Input: 1->2->2->1Output: true 挑战下自己Follow up:Could you">
<h3id="例二-Example-2"><ahref="#例二-Example-2"class="headerlink"title="例二 Example 2:"></a>例二 Example 2:</h3><p>Input: 1->2->2->1<br>Output: true</p>
<h3id="例二-Example-2"><ahref="#例二-Example-2"class="headerlink"title="例二 Example 2:"></a>例二 Example 2:</h3><p>Input: 1->2->2->1<br>Output: true</p>
<h3id="挑战下自己"><ahref="#挑战下自己"class="headerlink"title="挑战下自己"></a>挑战下自己</h3><p>Follow up:<br>Could you do it in O(n) time and O(1) space?</p>
<h3id="挑战下自己"><ahref="#挑战下自己"class="headerlink"title="挑战下自己"></a>挑战下自己</h3><p>Follow up:<br>Could you do it in O(n) time and O(1) space?</p>
<h2id="简要分析"><ahref="#简要分析"class="headerlink"title="简要分析"></a>简要分析</h2><p>首先这是个单向链表,如果是双向的就可以一个从头到尾,一个从尾到头,显然那样就没啥意思了,然后想过要不找到中点,然后用一个栈,把前一半塞进栈里,但是这种其实也比较麻烦,比如长度是奇偶数,然后如何找到中点,这倒是可以借助于双指针,还是比较麻烦,再想一想,回文链表,就跟最开始的一样,链表只有单向的,我用个栈不就可以逆向了么,先把链表整个塞进栈里,然后在一个个 pop 出来跟链表从头开始比较,全对上了就是回文了</p>
<h2id="简要分析"><ahref="#简要分析"class="headerlink"title="简要分析"></a>简要分析</h2><p>首先这是个单向链表,如果是双向的就可以一个从头到尾,一个从尾到头,显然那样就没啥意思了,然后想过要不找到中点,然后用一个栈,把前一半塞进栈里,但是这种其实也比较麻烦,比如长度是奇偶数,然后如何找到中点,这倒是可以借助于双指针,还是比较麻烦,再想一想,回文链表,就跟最开始的一样,链表只有单向的,我用个栈不就可以逆向了么,先把链表整个塞进栈里,然后在一个个 pop 出来跟链表从头开始比较,全对上了就是回文了</p>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/"rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<metaproperty="og:description"content="前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的本来其实也没什么想聊这个的,是在 B 站看了个吐槽这个的,然后刚好晚上乘公交的时候又碰到了有点类似的问题故事描述下,我们从始发站做了公交,这辆公交司机上次碰到过一回,就是会比较关注乘客的佩戴情况,主要考虑到目前国">
<metaproperty="og:description"content="前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的本来其实也没什么想聊这个的,是在 B 站看了个吐槽这个的,然后刚好晚上乘公交的时候又碰到了有点类似的问题故事描述下,我们从始发站做了公交,这辆公交司机上次碰到过一回,就是会比较关注乘客的佩戴情况,主要考虑到目前国">
<p>前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/ZovTIK.jpg"alt=""><br>然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/%E6%91%B8%E5%B1%81%E8%82%A1.png"alt=""><br>本来其实也没什么想聊这个的,是在 B 站看了个吐槽这个的,然后刚好晚上乘公交的时候又碰到了有点类似的问题<br>故事描述下,我们从始发站做了公交,这辆公交司机上次碰到过一回,就是会比较关注乘客的佩戴情况,主要考虑到目前国内疫情,然后这次在差不多人都坐满的情况下,可能在提示了三次让车内乘客戴好口罩,但是他指的那个中年女性还是没有反应,司机就转头比较大声指着这个乘客(中年女性)让戴好口罩,然后这个乘客(中年女性)就大声的说“我口罩是滑下来了,你指着我干嘛,你态度这么差,要吃了我一样,我要投诉你”等等,然后可能跟她一块的一个中年女性也是这么帮腔指责司机,比较基本的理解,车子里这么多乘客,假如是处于这位乘客口罩滑下来了而不自知的情况下,司机在提示了三次以后回头指着她说,我想的是没什么问题的,但是这位却反而指责这位司机指着她,并且说是态度差,要吃了她,完全是不可理喻的,并且一直喋喋不休说她口罩滑掉了有什么错,要投诉这个司机,让他可以提前退休了,在其他乘客的劝说下司机准备继续开车时,又口吐芬芳“你个傻<em>,你来打我呀”,真的是让我再次体会到了所谓的恶人先告状的又一完美呈现,后面还有个乘客还是表示要打死司机这个傻</em>,让我有点不明所以,俗话说有人是得理不饶人,前提是得理,这种理亏不饶人真的是挺让人长见识的,试想下,司机在提示三次后,这位乘客还是没有把口罩戴好,如何在不指着这位乘客的情况下能准确的提示到她呢,并且觉得语气态度不好,司机要载着一车的人,因为你这一个乘客不戴好口罩而不能正常出发,有些着急应该很正常吧,可能是平时自己在家里耀武扬威的使唤别人习惯了吧,别人不敢这么大声跟她说话,其实想想这位中年女性应该年纪不会很大,还比较时髦的吧,像一些常见的中年杭州本地人可能是不会说傻*这个词的吧。<br>杭州的公交可能是在二月份疫情还比较严重的时候是要求上车出示健康码,后面比较缓和以后只要求佩戴好口罩,但是在我们小绍兴,目前还是一律要求检验健康码和佩戴口罩,对于疫情中,并且目前阶段国内也时有报出小范围的疫情的情况下,司机尽职要求佩戴好口罩其实也是为了乘客着想,另一种情况如果司机不严格要求,万一车上有个感染者,这位中年女性被传染了,如果能找到这个司机的话,是不是想“打死”这个司机,竟然让感染者上了车,反正她自己是不可能有错的,上来就是对方态度差,要投诉,自己不戴好口罩啥都没错,我就想知道如果因为自己没戴好口罩被感染了,是不是也是司机的错,毕竟没有像仆人那样点头哈腰求着她戴好口罩。<br>再说回来,整个车就她一个人没戴好口罩,并且还有个细节,其实这个乘客是上了车之后就没戴好了,本来上车的时候是戴好的,这种比较有可能是觉得上车的时候司机那看一眼就好了,如果好好戴着口罩,一点事情都没有,唉,纯粹是太气愤了,调理逻辑什么的就忽略吧</p>
<p>前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/ZovTIK.jpg"><br>然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/%E6%91%B8%E5%B1%81%E8%82%A1.png"><br>本来其实也没什么想聊这个的,是在 B 站看了个吐槽这个的,然后刚好晚上乘公交的时候又碰到了有点类似的问题<br>故事描述下,我们从始发站做了公交,这辆公交司机上次碰到过一回,就是会比较关注乘客的佩戴情况,主要考虑到目前国内疫情,然后这次在差不多人都坐满的情况下,可能在提示了三次让车内乘客戴好口罩,但是他指的那个中年女性还是没有反应,司机就转头比较大声指着这个乘客(中年女性)让戴好口罩,然后这个乘客(中年女性)就大声的说“我口罩是滑下来了,你指着我干嘛,你态度这么差,要吃了我一样,我要投诉你”等等,然后可能跟她一块的一个中年女性也是这么帮腔指责司机,比较基本的理解,车子里这么多乘客,假如是处于这位乘客口罩滑下来了而不自知的情况下,司机在提示了三次以后回头指着她说,我想的是没什么问题的,但是这位却反而指责这位司机指着她,并且说是态度差,要吃了她,完全是不可理喻的,并且一直喋喋不休说她口罩滑掉了有什么错,要投诉这个司机,让他可以提前退休了,在其他乘客的劝说下司机准备继续开车时,又口吐芬芳“你个傻<em>,你来打我呀”,真的是让我再次体会到了所谓的恶人先告状的又一完美呈现,后面还有个乘客还是表示要打死司机这个傻</em>,让我有点不明所以,俗话说有人是得理不饶人,前提是得理,这种理亏不饶人真的是挺让人长见识的,试想下,司机在提示三次后,这位乘客还是没有把口罩戴好,如何在不指着这位乘客的情况下能准确的提示到她呢,并且觉得语气态度不好,司机要载着一车的人,因为你这一个乘客不戴好口罩而不能正常出发,有些着急应该很正常吧,可能是平时自己在家里耀武扬威的使唤别人习惯了吧,别人不敢这么大声跟她说话,其实想想这位中年女性应该年纪不会很大,还比较时髦的吧,像一些常见的中年杭州本地人可能是不会说傻*这个词的吧。<br>杭州的公交可能是在二月份疫情还比较严重的时候是要求上车出示健康码,后面比较缓和以后只要求佩戴好口罩,但是在我们小绍兴,目前还是一律要求检验健康码和佩戴口罩,对于疫情中,并且目前阶段国内也时有报出小范围的疫情的情况下,司机尽职要求佩戴好口罩其实也是为了乘客着想,另一种情况如果司机不严格要求,万一车上有个感染者,这位中年女性被传染了,如果能找到这个司机的话,是不是想“打死”这个司机,竟然让感染者上了车,反正她自己是不可能有错的,上来就是对方态度差,要投诉,自己不戴好口罩啥都没错,我就想知道如果因为自己没戴好口罩被感染了,是不是也是司机的错,毕竟没有像仆人那样点头哈腰求着她戴好口罩。<br>再说回来,整个车就她一个人没戴好口罩,并且还有个细节,其实这个乘客是上了车之后就没戴好了,本来上车的时候是戴好的,这种比较有可能是觉得上车的时候司机那看一眼就好了,如果好好戴着口罩,一点事情都没有,唉,纯粹是太气愤了,调理逻辑什么的就忽略吧</p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="题目介绍Given preorder and inorder traversal of a tree, construct the binary tree.给定一棵树的前序和中序遍历,构造出一棵二叉树 注意You may assume that duplicates do not exist in the tree.你可以假设树中没有重复的元素。(PS: 不然就没法做了呀) 例子:12preord">
<metaname="description"content="题目介绍Given preorder and inorder traversal of a tree, construct the binary tree.给定一棵树的前序和中序遍历,构造出一棵二叉树 注意You may assume that duplicates do not exist in the tree.你可以假设树中没有重复的元素。(PS: 不然就没法做了呀) 例子:preorder">
<metaproperty="og:type"content="article">
<metaproperty="og:type"content="article">
<metaproperty="og:title"content="Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析">
<metaproperty="og:title"content="Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析">
<metaproperty="og:description"content="题目介绍Given preorder and inorder traversal of a tree, construct the binary tree.给定一棵树的前序和中序遍历,构造出一棵二叉树 注意You may assume that duplicates do not exist in the tree.你可以假设树中没有重复的元素。(PS: 不然就没法做了呀) 例子:12preord">
<metaproperty="og:description"content="题目介绍Given preorder and inorder traversal of a tree, construct the binary tree.给定一棵树的前序和中序遍历,构造出一棵二叉树 注意You may assume that duplicates do not exist in the tree.你可以假设树中没有重复的元素。(PS: 不然就没法做了呀) 例子:preorder">
<h2id="题目介绍"><ahref="#题目介绍"class="headerlink"title="题目介绍"></a>题目介绍</h2><p>Given preorder and inorder traversal of a tree, construct the binary tree.<br>给定一棵树的前序和中序遍历,构造出一棵二叉树</p>
<h2id="题目介绍"><ahref="#题目介绍"class="headerlink"title="题目介绍"></a>题目介绍</h2><p>Given preorder and inorder traversal of a tree, construct the binary tree.<br>给定一棵树的前序和中序遍历,构造出一棵二叉树</p>
<h3id="注意"><ahref="#注意"class="headerlink"title="注意"></a>注意</h3><p>You may assume that duplicates do not exist in the tree.<br>你可以假设树中没有重复的元素。(PS: 不然就没法做了呀)</p>
<h3id="注意"><ahref="#注意"class="headerlink"title="注意"></a>注意</h3><p>You may assume that duplicates do not exist in the tree.<br>你可以假设树中没有重复的元素。(PS: 不然就没法做了呀)</p>
<divclass="popular-posts-title"><ahref="/2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/"rel="bookmark">Leetcode 121 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 题解分析</a></div>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 12345678910CREATE TABLE `null_index_t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `">
<metaname="description"content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 CREATE TABLE `null_index_t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `null_key`">
<metaproperty="og:type"content="article">
<metaproperty="og:type"content="article">
<metaproperty="og:title"content="聊聊 mysql 索引的一些细节">
<metaproperty="og:title"content="聊聊 mysql 索引的一些细节">
<metaproperty="og:description"content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 12345678910CREATE TABLE `null_index_t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `">
<metaproperty="og:description"content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 CREATE TABLE `null_index_t` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `null_key`">
<p><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/1HKVQH.png"alt=""><br>是不是不一样了,这里再补充下我试验使用的 mysql 是 5.7 的,不保证在其他版本的一致性,<br>其实可以看出随着数据量的变化,mysql 会不会使用索引是会变化的,不是说 is not null 一定会使用,也不是一定不会使用,而是优化器会根据查询成本做个预判,这个预判尽可能会减小查询成本,主要包括回表啥的,但是也不一定完全准确。</p>
<p><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/1HKVQH.png"><br>是不是不一样了,这里再补充下我试验使用的 mysql 是 5.7 的,不保证在其他版本的一致性,<br>其实可以看出随着数据量的变化,mysql 会不会使用索引是会变化的,不是说 is not null 一定会使用,也不是一定不会使用,而是优化器会根据查询成本做个预判,这个预判尽可能会减小查询成本,主要包括回表啥的,但是也不一定完全准确。</p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
<metaproperty="og:description"content="题目介绍A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the pat">
<metaproperty="og:description"content="题目介绍A path in a binary tree is a sequence of nodes where each pair of adjacent nodes in the sequence has an edge connecting them. A node can only appear in the sequence at most once. Note that the pat">
<divclass="popular-posts-title"><ahref="/2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/"rel="bookmark">Leetcode 121 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 题解分析</a></div>
<h3id="引线整理算法"><ahref="#引线整理算法"class="headerlink"title="引线整理算法"></a>引线整理算法</h3><p>这个真的长见识了,<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/6yeA7n.png"alt=""><br>可以看到,原来是 A,B,C 对象引用了 N,这里会在第一次遍历的时候把这种引用反过来,让 N 的对象头部保存下 A 的地址,表示这类引用,然后在遍历到 B 的时候在链起来,到最后就会把所有引用了 N 对象的所有对象通过引线链起来,在第二次遍历的时候就把更新A,B,C 对象引用的 N 地址,并且移动 N 对象</p>
<h3id="引线整理算法"><ahref="#引线整理算法"class="headerlink"title="引线整理算法"></a>引线整理算法</h3><p>这个真的长见识了,<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/6yeA7n.png"><br>可以看到,原来是 A,B,C 对象引用了 N,这里会在第一次遍历的时候把这种引用反过来,让 N 的对象头部保存下 A 的地址,表示这类引用,然后在遍历到 B 的时候在链起来,到最后就会把所有引用了 N 对象的所有对象通过引线链起来,在第二次遍历的时候就把更新A,B,C 对象引用的 N 地址,并且移动 N 对象</p>
<divclass="popular-posts-title"><ahref="/2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/"rel="bookmark">Leetcode 121 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<metaproperty="og:description"content="题目介绍You are given an array prices where prices[i] is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day">
<metaproperty="og:description"content="题目介绍You are given an array prices where prices[i] is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day">
<h3id="题目介绍"><ahref="#题目介绍"class="headerlink"title="题目介绍"></a>题目介绍</h3><p>You are given an array <code>prices</code> where <code>prices[i]</code> is the price of a given stock on the i<sup>th</sup> day.</p>
<h3id="题目介绍"><ahref="#题目介绍"class="headerlink"title="题目介绍"></a>题目介绍</h3><p>You are given an array <code>prices</code> where <code>prices[i]</code> is the price of a given stock on the i<sup>th</sup> day.</p>
<p>You want to maximize your profit by choosing a <strong>single day</strong> to buy one stock and choosing a <strong>different day in the future</strong> to sell that stock.</p>
<p>You want to maximize your profit by choosing a <strong>single day</strong> to buy one stock and choosing a <strong>different day in the future</strong> to sell that stock.</p>
<p>Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return <code>0</code>.</p>
<p>Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return <code>0</code>.</p>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/"rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/"rel="bookmark">Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析</a></div>
<divclass="popular-posts-title"><ahref="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/"rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
</li>
<liclass="popular-posts-item">
<liclass="popular-posts-item">
<divclass="popular-posts-title"><ahref="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/"rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 123-H :Threads-mode operation Instructs top to display indiv">
<metaname="description"content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 -H :Threads-mode operation Instructs top to display individ">
<metaproperty="og:type"content="article">
<metaproperty="og:type"content="article">
<metaproperty="og:title"content="聊聊 Linux 下的 top 命令">
<metaproperty="og:title"content="聊聊 Linux 下的 top 命令">
<metaproperty="og:description"content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 123-H :Threads-mode operation Instructs top to display indiv">
<metaproperty="og:description"content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 -H :Threads-mode operation Instructs top to display individ">
<p>top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加<code>-H</code>进入线程模式</p>
<p>top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加<code>-H</code>进入线程模式</p>
<figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br></pre></td><tdclass="code"><pre><spanclass="line">-H :Threads-mode operation</span><br><spanclass="line"> Instructs top to display individual threads. Without this command-line option a summation of all threads in each process is shown. Later</span><br><spanclass="line"> this can be changed with the `H' interactive command.</span><br></pre></td></tr></table></figure>
<p>这样就能用在 Java 中去 jstack 中找到对应的线程<br>其实还有比较重要的两个操作,<br>一个是在 top 启动状态下,按<code>c</code>键,这样能把比如说是一个 Java 进程,具体的进程命令显示出来<br>像这样<br>执行前是这样<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png"alt=""><br>执行后是这样<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/1xD6VM.png"alt=""><br>第二个就是排序了</p>
<figureclass="highlight plain"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br><spanclass="line">9</span><br><spanclass="line">10</span><br><spanclass="line">11</span><br><spanclass="line">12</span><br><spanclass="line">13</span><br><spanclass="line">14</span><br><spanclass="line">15</span><br><spanclass="line">16</span><br><spanclass="line">17</span><br><spanclass="line">18</span><br><spanclass="line">19</span><br><spanclass="line">20</span><br><spanclass="line">21</span><br><spanclass="line">22</span><br><spanclass="line">23</span><br></pre></td><tdclass="code"><pre><spanclass="line">SORTING of task window</span><br><spanclass="line"></span><br><spanclass="line"> For compatibility, this top supports most of the former top sort keys. Since this is primarily a service to former top users, these commands</span><br><spanclass="line"> do not appear on any help screen.</span><br><spanclass="line"> command sorted-field supported</span><br><spanclass="line"> A start time (non-display) No</span><br><spanclass="line"> M %MEM Yes</span><br><spanclass="line"> N PID Yes</span><br><spanclass="line"> P %CPU Yes</span><br><spanclass="line"> T TIME+ Yes</span><br><spanclass="line"></span><br><spanclass="line"> Before using any of the following sort provisions, top suggests that you temporarily turn on column highlighting using the `x' interactive com‐</span><br><spanclass="line"> mand. That will help ensure that the actual sort environment matches your intent.</span><br><spanclass="line"></span><br><spanclass="line"> The following interactive commands will only be honored when the current sort field is visible. The sort field might not be visible because:</span><br><spanclass="line"> 1) there is insufficient Screen Width</span><br><spanclass="line"> 2) the `f' interactive command turned it Off</span><br><spanclass="line"></span><br><spanclass="line">< :Move-Sort-Field-Left</span><br><spanclass="line"> Moves the sort column to the left unless the current sort field is the first field being displayed.</span><br><spanclass="line"></span><br><spanclass="line">> :Move-Sort-Field-Right</span><br><spanclass="line"> Moves the sort column to the right unless the current sort field is the last field being displayed.</span><br></pre></td></tr></table></figure>
Instructs top to display individual threads. Without this command-line option a summation of all threads in each process is shown. Later
this can be changed with the `H' interactive command.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>这样就能用在 Java 中去 jstack 中找到对应的线程<br>其实还有比较重要的两个操作,<br>一个是在 top 启动状态下,按<code>c</code>键,这样能把比如说是一个 Java 进程,具体的进程命令显示出来<br>像这样<br>执行前是这样<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png"><br>执行后是这样<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/1xD6VM.png"><br>第二个就是排序了</p>
<preclass="line-numbers language-none"><codeclass="language-none">SORTING of task window
For compatibility, this top supports most of the former top sort keys. Since this is primarily a service to former top users, these commands
do not appear on any help screen.
command sorted-field supported
A start time (non-display) No
M %MEM Yes
N PID Yes
P %CPU Yes
T TIME+ Yes
Before using any of the following sort provisions, top suggests that you temporarily turn on column highlighting using the `x' interactive com‐
mand. That will help ensure that the actual sort environment matches your intent.
The following interactive commands will only be honored when the current sort field is visible. The sort field might not be visible because:
1) there is insufficient Screen Width
2) the `f' interactive command turned it Off
< :Move-Sort-Field-Left
Moves the sort column to the left unless the current sort field is the first field being displayed.
> :Move-Sort-Field-Right
Moves the sort column to the right unless the current sort field is the last field being displayed.<spanaria-hidden="true"class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>查看 man page 可以找到这一段,其实一般 man page 都是最细致的,只不过因为太多了,有时候懒得看,这里可以通过大写 <code>M</code> 和大写 <code>P</code> 分别按内存和 CPU 排序,下面还有两个小技巧,通过按 x 可以将当前活跃的排序列用不同颜色标出来,然后可以通过<code><</code>和<code>></code>直接左右移动排序列</p>
<p>查看 man page 可以找到这一段,其实一般 man page 都是最细致的,只不过因为太多了,有时候懒得看,这里可以通过大写 <code>M</code> 和大写 <code>P</code> 分别按内存和 CPU 排序,下面还有两个小技巧,通过按 x 可以将当前活跃的排序列用不同颜色标出来,然后可以通过<code><</code>和<code>></code>直接左右移动排序列</p>
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
var CONFIG = {"hostname":"nicksxs.me","root":"/","scheme":"Pisces","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":true,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":true,"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
</script>
<metaname="description"content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 123456789fn main() &#123; let s1 = String::from("hello"); let len = calcu">
<metaname="description"content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 fn main() &#123; let s1 = String::from("hello"); let len = calculate_le">
<metaproperty="og:description"content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 123456789fn main() &#123; let s1 = String::from("hello"); let len = calcu">
<metaproperty="og:description"content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 fn main() &#123; let s1 = String::from("hello"); let len = calculate_le">
<li>没有同步数据访问的机制<br>并且我们不能在拥有不可变引用的情况下创建可变引用<h3id="悬垂引用"><ahref="#悬垂引用"class="headerlink"title="悬垂引用"></a>悬垂引用</h3>还有一点需要注意的就是悬垂引用<figureclass="highlight rust"><table><tr><tdclass="gutter"><pre><spanclass="line">1</span><br><spanclass="line">2</span><br><spanclass="line">3</span><br><spanclass="line">4</span><br><spanclass="line">5</span><br><spanclass="line">6</span><br><spanclass="line">7</span><br><spanclass="line">8</span><br></pre></td><tdclass="code"><pre><spanclass="line"><spanclass="function"><spanclass="keyword">fn</span><spanclass="title">main</span></span>() {</span><br><spanclass="line"><spanclass="keyword">let</span> reference_to_nothing = dangle();</span><br><spanclass="line">}</span><br><spanclass="line"></span><br><spanclass="line"><spanclass="function"><spanclass="keyword">fn</span><spanclass="title">dangle</span></span>() ->&<spanclass="built_in">String</span>{</span><br><spanclass="line"><spanclass="keyword">let</span> s = <spanclass="built_in">String</span>::from(<spanclass="string">"hello"</span>);</span><br><spanclass="line">&s</span><br><spanclass="line">}</span><br></pre></td></tr></table></figure>
这里可以看到其实在 dangle函数返回后,这里的 s 理论上就离开了作用域,但是由于返回了 s 的引用,在 main 函数中就会拿着这个引用,就会出现如下错误<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/JtrXSW.png"alt=""><h3id="总结"><ahref="#总结"class="headerlink"title="总结"></a>总结</h3>最后总结下</li>
这里可以看到其实在 dangle函数返回后,这里的 s 理论上就离开了作用域,但是由于返回了 s 的引用,在 main 函数中就会拿着这个引用,就会出现如下错误<br><imgdata-src="https://gitee.com/nicksxs/images/raw/master/uPic/JtrXSW.png"><h3id="总结"><ahref="#总结"class="headerlink"title="总结"></a>总结</h3>最后总结下</li>