Browse Source

Site updated: 2021-05-07 20:08:33

master
nicksxs 4 years ago
parent
commit
ef33248d54
517 changed files with 19998 additions and 5597 deletions
  1. BIN
      .DS_Store
  2. +4
    -10
      2014/12/23/my-new-post/index.html
  3. +12
    -12
      2014/12/24/MFC 模态对话框/index.html
  4. +51
    -21
      2014/12/30/Clone-Graph-Part-I/index.html
  5. +41
    -14
      2015/01/04/Path-Sum/index.html
  6. +56
    -13
      2015/01/14/Two-Sum/index.html
  7. +29
    -18
      2015/01/16/pcre-intro-and-a-simple-package/index.html
  8. +24
    -16
      2015/03/11/Number-Of-1-Bits/index.html
  9. +18
    -14
      2015/03/11/Reverse-Bits/index.html
  10. +32
    -14
      2015/03/13/Reverse-Integer/index.html
  11. +93
    -16
      2015/04/14/Add-Two-Number/index.html
  12. +22
    -17
      2015/04/15/Leetcode-No-3/index.html
  13. +33
    -16
      2015/06/22/invert-binary-tree/index.html
  14. +100
    -21
      2016/07/13/swoole-websocket-test/index.html
  15. +35
    -13
      2016/08/14/34-Search-for-a-Range/index.html
  16. +18
    -16
      2016/08/14/docker-mysql-cluster/index.html
  17. +24
    -16
      2016/09/29/binary-watch/index.html
  18. +30
    -14
      2016/10/11/minimum-size-subarray-sum-209/index.html
  19. +22
    -14
      2016/10/12/summary-ranges-228/index.html
  20. +38
    -15
      2016/11/10/php-abstract-class-and-interface/index.html
  21. +13
    -12
      2017/03/28/spark-little-tips/index.html
  22. +18
    -15
      2017/04/25/rabbitmq-tips/index.html
  23. +8
    -14
      2017/05/09/ambari-summary/index.html
  24. +32
    -16
      2019/06/18/openresty/index.html
  25. +62
    -19
      2019/09/23/AbstractQueuedSynchronizer/index.html
  26. +587
    -9
      2019/12/07/JVM-G1-Part-1/index.html
  27. +10
    -12
      2019/12/10/Redis-Part-1/index.html
  28. +2
    -1
      2019/12/18/1Q84读后感/index.html
  29. +58
    -11
      2019/12/21/聊聊Java中的单例模式/index.html
  30. +70
    -24
      2019/12/26/redis数据结构介绍/index.html
  31. +39
    -23
      2020/01/04/redis数据结构介绍二/index.html
  32. +31
    -25
      2020/01/10/redis数据结构介绍三/index.html
  33. +37
    -13
      2020/01/19/redis数据结构介绍四/index.html
  34. +44
    -12
      2020/01/20/redis数据结构介绍五/index.html
  35. +189
    -23
      2020/01/22/redis数据结构介绍六/index.html
  36. +9
    -9
      2020/02/01/2019年终总结/index.html
  37. +65
    -9
      2020/02/09/G1收集器概述/index.html
  38. +52
    -12
      2020/02/16/Maven实用小技巧/index.html
  39. +75
    -17
      2020/02/22/gogs使用webhook部署react单页应用/index.html
  40. +8
    -8
      2020/03/01/寄生虫观后感/index.html
  41. +23
    -27
      2020/03/08/docker比一般多一点的初学者介绍/index.html
  42. +27
    -20
      2020/03/15/docker比一般多一点的初学者介绍二/index.html
  43. +17
    -18
      2020/03/21/docker比一般多一点的初学者介绍三/index.html
  44. +8
    -10
      2020/03/29/echo命令的一个小技巧/index.html
  45. +84
    -19
      2020/04/05/Comparator使用小记/index.html
  46. +416
    -18
      2020/04/12/redis系列介绍七/index.html
  47. +512
    -43
      2020/04/18/redis系列介绍八/index.html
  48. +52
    -21
      2020/04/26/聊聊-mysql-的-MVCC/index.html
  49. +21
    -22
      2020/05/02/聊聊-mysql-的-MVCC-续篇/index.html
  50. +9
    -14
      2020/05/10/聊聊-mysql-的-MVCC-续续篇之加锁分析/index.html
  51. +12
    -18
      2020/05/17/聊聊我理解的分布式事务/index.html
  52. +11
    -16
      2020/05/22/聊聊我刚学会的应用诊断方法/index.html
  53. +74
    -9
      2020/05/31/聊聊-Dubbo-的-SPI/index.html
  54. +125
    -11
      2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/index.html
  55. +25
    -14
      2020/06/13/聊聊一次-brew-update-引发的血案/index.html
  56. +6
    -6
      2020/06/21/介绍一下-RocketMQ/index.html
  57. +761
    -28
      2020/06/26/聊一下-RocketMQ-的-Consumer/index.html
  58. +584
    -19
      2020/07/05/聊一下-RocketMQ-的-NameServer-源码/index.html
  59. +8
    -8
      2020/07/11/2020年中总结/index.html
  60. +461
    -18
      2020/07/19/聊聊-RocketMQ-的-Broker-源码/index.html
  61. +4
    -4
      2020/07/26/我是如何走上跑步这条不归路的/index.html
  62. +506
    -19
      2020/08/02/聊聊-Java-自带的那些逆天工具/index.html
  63. +14
    -13
      2020/08/06/Linux-下-grep-命令的一点小技巧/index.html
  64. +4
    -4
      2020/08/16/周末我在老丈人家打了天小工/index.html
  65. +442
    -17
      2020/08/22/Filter-Intercepter-Aop-啥-啥-啥-这些都是啥/index.html
  66. +4
    -4
      2020/08/30/这周末我又在老丈人家打了天小工/index.html
  67. +85
    -19
      2020/09/06/mybatis-的-和-是有啥区别/index.html
  68. +6
    -5
      2020/09/13/在老丈人家的小工记三/index.html
  69. +62
    -22
      2020/09/20/Leetcode-3-Longest-Substring-Without-Repeating-Characters-题解分析/index.html
  70. +4
    -2
      2020/09/26/在老丈人家的小工记四/index.html
  71. +222
    -24
      2020/10/03/mybatis-的缓存是怎么回事/index.html
  72. +53
    -23
      2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/index.html
  73. +5
    -4
      2020/10/18/在老丈人家的小工记五/index.html
  74. +39
    -16
      2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/index.html
  75. +72
    -9
      2020/11/01/Apollo-的-value-注解是怎么自动更新的/index.html
  76. +7
    -14
      2020/11/08/聊聊-Java-的类加载机制/index.html
  77. +43
    -18
      2020/11/15/Leetcode-234-回文联表-Palindrome-Linked-List-题解分析/index.html
  78. +105
    -9
      2020/11/22/聊聊-Dubbo-的容错机制/index.html
  79. +7
    -6
      2020/11/29/从清华美院学姐聊聊我们身边的恶人/index.html
  80. +69
    -15
      2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/index.html
  81. +49
    -15
      2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/index.html
  82. +5
    -4
      2020/12/20/从丁仲礼被美国制裁聊点啥/index.html
  83. +50
    -23
      2020/12/27/聊聊-mysql-索引的一些细节/index.html
  84. +30
    -11
      2021/01/03/聊聊-Java-的-equals-和-hashCode-方法/index.html
  85. +57
    -21
      2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/index.html
  86. +8
    -8
      2021/01/17/聊聊那些加塞狗/index.html
  87. +35
    -12
      2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/index.html
  88. +4
    -3
      2021/01/31/聊聊-redis-缓存的应用问题/index.html
  89. +4
    -3
      2021/02/07/关于读书打卡与分享/index.html
  90. +209
    -22
      2021/02/14/AQS篇一/index.html
  91. +477
    -20
      2021/02/21/AQS-之-Condition-浅析笔记/index.html
  92. +6
    -6
      2021/02/28/闲聊下乘公交的用户体验/index.html
  93. +11
    -10
      2021/03/07/《垃圾回收算法手册读书》笔记之整理算法/index.html
  94. +35
    -14
      2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/index.html
  95. +5
    -5
      2021/03/21/关于公共交通再吐个槽/index.html
  96. +34
    -11
      2021/03/28/聊聊-Linux-下的-top-命令/index.html
  97. +11
    -20
      2021/03/31/2020-年终总结/index.html
  98. +39
    -10
      2021/04/04/聊聊-dubbo-的线程池/index.html
  99. +7
    -6
      2021/04/11/聊聊厦门旅游的好与不好/index.html
  100. +61
    -24
      2021/04/18/rust学习笔记-所有权二/index.html

BIN
.DS_Store View File


+ 4
- 10
2014/12/23/my-new-post/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2014/12/23/my-new-post/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="在工作中碰到的一点C++指针上的一点小问题 在C++中,应该是从C语言就开始了,除了void型指针之外都是需要有分配对应的内存才可以使用,同时malloc与free成对使用,new与delete成对使用,否则造成内存泄漏。">
<meta property="og:locale">
<meta property="article:published_time" content="2014-12-23T01:58:11.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2014-12-23T01:58:11.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="博客,文章">
<meta name="twitter:card" content="summary">
@ -228,13 +229,6 @@
<time title="Created: 2014-12-23 09:58:11" itemprop="dateCreated datePublished" datetime="2014-12-23T09:58:11+08:00">2014-12-23</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -412,7 +406,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#在工作中碰到的一点C-指针上的一点小问题"><span class="nav-number">1.</span> <span class="nav-text">在工作中碰到的一点C++指针上的一点小问题</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E5%9C%A8%E5%B7%A5%E4%BD%9C%E4%B8%AD%E7%A2%B0%E5%88%B0%E7%9A%84%E4%B8%80%E7%82%B9C-%E6%8C%87%E9%92%88%E4%B8%8A%E7%9A%84%E4%B8%80%E7%82%B9%E5%B0%8F%E9%97%AE%E9%A2%98"><span class="nav-number">1.</span> <span class="nav-text">在工作中碰到的一点C++指针上的一点小问题</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 12
- 12
2014/12/24/MFC 模态对话框/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,14 +26,15 @@
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>
<meta name="description" content="1234567void CTestDialog::OnBnClickedOk() &amp;#123; CString m_SrcTest; int nIndex &#x3D; m_CbTest.GetCurSel(); m_CbTest.GetLBText(nIndex, m_SrcTest); OnOK();&amp;#125; 模态对话框弹出确定后,在弹出对话框时新建的类及其变量会存在,但是对于其中的控件对象">
<meta name="description" content="void CTestDialog::OnBnClickedOk() &amp;#123; CString m_SrcTest; int nIndex &#x3D; m_CbTest.GetCurSel(); m_CbTest.GetLBText(nIndex, m_SrcTest); OnOK(); &amp;#125; 模态对话框弹出确定后,在弹出对话框时新建的类及其变量会存在,但是对于其中的">
<meta property="og:type" content="article">
<meta property="og:title" content="MFC 模态对话框">
<meta property="og:url" content="https://nicksxs.me/2014/12/24/MFC%20%E6%A8%A1%E6%80%81%E5%AF%B9%E8%AF%9D%E6%A1%86/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="1234567void CTestDialog::OnBnClickedOk() &amp;#123; CString m_SrcTest; int nIndex &#x3D; m_CbTest.GetCurSel(); m_CbTest.GetLBText(nIndex, m_SrcTest); OnOK();&amp;#125; 模态对话框弹出确定后,在弹出对话框时新建的类及其变量会存在,但是对于其中的控件对象">
<meta property="og:description" content="void CTestDialog::OnBnClickedOk() &amp;#123; CString m_SrcTest; int nIndex &#x3D; m_CbTest.GetCurSel(); m_CbTest.GetLBText(nIndex, m_SrcTest); OnOK(); &amp;#125; 模态对话框弹出确定后,在弹出对话框时新建的类及其变量会存在,但是对于其中的">
<meta property="og:locale">
<meta property="article:published_time" content="2014-12-24T01:35:37.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2014-12-24T01:35:37.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="c++">
<meta property="article:tag" content="mfc">
@ -229,13 +230,6 @@
<time title="Created: 2014-12-24 09:35:37" itemprop="dateCreated datePublished" datetime="2014-12-24T09:35:37+08:00">2014-12-24</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,7 +279,13 @@
<div class="post-body" itemprop="articleBody">
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">CTestDialog::OnBnClickedOk</span><span class="params">()</span> </span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> CString m_SrcTest;</span><br><span class="line"> <span class="keyword">int</span> nIndex = m_CbTest.GetCurSel(); </span><br><span class="line"> m_CbTest.GetLBText(nIndex, m_SrcTest); </span><br><span class="line"> OnOK();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">void CTestDialog::OnBnClickedOk()
&#123;
CString m_SrcTest;
int nIndex &#x3D; m_CbTest.GetCurSel();
m_CbTest.GetLBText(nIndex, m_SrcTest);
OnOK();
&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>模态对话框弹出确定后,在弹出对话框时新建的类及其变量会存在,但是对于其中的控件<br>对象无法调用函数,即如果要在主对话框中获得弹出对话框的Combo box选中值的话,需<br>要在弹出 对话框的确定函数内将其值取出,赋值给弹出对话框的公有变量,这样就可以<br>在主对话框类得到值。 </p>


+ 51
- 21
2014/12/30/Clone-Graph-Part-I/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,17 +26,18 @@
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>
<meta name="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 &amp;#123;vector neighbors;&amp;#125;">
<meta name="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 &amp;#123; vector neighbors; &amp;#125;">
<meta property="og:type" content="article">
<meta property="og:title" content="Clone Graph Part I">
<meta property="og:url" content="https://nicksxs.me/2014/12/30/Clone-Graph-Part-I/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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 &amp;#123;vector neighbors;&amp;#125;">
<meta property="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 &amp;#123; vector neighbors; &amp;#125;">
<meta property="og:locale">
<meta property="article:published_time" content="2014-12-30T08:50:01.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2014-12-30T08:50:01.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="C++">
<meta property="article:tag" content="leetcode">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2014/12/30/Clone-Graph-Part-I/">
@ -229,13 +230,6 @@
<time title="Created: 2014-12-30 16:50:01" itemprop="dateCreated datePublished" datetime="2014-12-30T16:50:01+08:00">2014-12-30</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,10 +279,46 @@
<div class="post-body" itemprop="articleBody">
<h3 id="problem"><a href="#problem" class="headerlink" title="problem"></a>problem</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Clone a graph. Input is a Node pointer. Return the Node pointer of the cloned graph.</span><br><span class="line"></span><br><span class="line">A graph is defined below:</span><br><span class="line">struct Node &#123;</span><br><span class="line">vector neighbors;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="built_in">unordered_map</span>&lt;Node *, Node *&gt; Map;</span><br><span class="line"> </span><br><span class="line"><span class="function">Node *<span class="title">clone</span><span class="params">(Node *graph)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (!graph) <span class="keyword">return</span> <span class="literal">NULL</span>;</span><br><span class="line"> </span><br><span class="line"> Map <span class="built_in">map</span>;</span><br><span class="line"> <span class="built_in">queue</span>&lt;Node *&gt; q;</span><br><span class="line"> q.push(graph);</span><br><span class="line"> </span><br><span class="line"> Node *graphCopy = <span class="keyword">new</span> Node();</span><br><span class="line"> <span class="built_in">map</span>[graph] = graphCopy;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (!q.empty()) &#123;</span><br><span class="line"> Node *node = q.front();</span><br><span class="line"> q.pop();</span><br><span class="line"> <span class="keyword">int</span> n = node-&gt;neighbors.<span class="built_in">size</span>();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line"> Node *neighbor = node-&gt;neighbors[i];</span><br><span class="line"> <span class="comment">// no copy exists</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">map</span>.<span class="built_in">find</span>(neighbor) == <span class="built_in">map</span>.<span class="built_in">end</span>()) &#123;</span><br><span class="line"> Node *p = <span class="keyword">new</span> Node();</span><br><span class="line"> <span class="built_in">map</span>[node]-&gt;neighbors.push_back(p);</span><br><span class="line"> <span class="built_in">map</span>[neighbor] = p;</span><br><span class="line"> q.push(neighbor);</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123; <span class="comment">// a copy already exists</span></span><br><span class="line"> <span class="built_in">map</span>[node]-&gt;neighbors.push_back(<span class="built_in">map</span>[neighbor]);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> graphCopy;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="problem"><a href="#problem" class="headerlink" title="problem"></a>problem</h3><pre class="line-numbers language-none"><code class="language-none">Clone 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;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<span id="more"></span>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><pre class="line-numbers language-c++" data-language="c++"><code class="language-c++">typedef unordered_map&lt;Node *, Node *&gt; Map;
Node *clone(Node *graph) &#123;
if (!graph) return NULL;
Map map;
queue&lt;Node *&gt; q;
q.push(graph);
Node *graphCopy &#x3D; new Node();
map[graph] &#x3D; graphCopy;
while (!q.empty()) &#123;
Node *node &#x3D; q.front();
q.pop();
int n &#x3D; node-&gt;neighbors.size();
for (int i &#x3D; 0; i &lt; n; i++) &#123;
Node *neighbor &#x3D; node-&gt;neighbors[i];
&#x2F;&#x2F; no copy exists
if (map.find(neighbor) &#x3D;&#x3D; map.end()) &#123;
Node *p &#x3D; new Node();
map[node]-&gt;neighbors.push_back(p);
map[neighbor] &#x3D; p;
q.push(neighbor);
&#125; else &#123; &#x2F;&#x2F; a copy already exists
map[node]-&gt;neighbors.push_back(map[neighbor]);
&#125;
&#125;
&#125;
return graphCopy;
&#125;<span aria-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></span><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="anlysis"><a href="#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>
@ -303,16 +333,16 @@
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
<div class="popular-posts-title"><a href="/2020/02/09/G1收集器概述/" rel="bookmark">G1收集器概述</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
</ul>
@ -356,8 +386,8 @@
<footer class="post-footer">
<div class="post-tags">
<a href="/tags/leetcode/" rel="tag"># leetcode</a>
<a href="/tags/C/" rel="tag"># C++</a>
<a href="/tags/leetcode/" rel="tag"># leetcode</a>
</div>


+ 41
- 14
2015/01/04/Path-Sum/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2015/01/04/Path-Sum/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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.">
<meta property="og:locale">
<meta property="article:published_time" content="2015-01-04T07:44:10.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2015-01-04T07:44:10.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-01-04 15:44:10" itemprop="dateCreated datePublished" datetime="2015-01-04T15:44:10+08:00">2015-01-04</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -286,12 +280,45 @@
<h3 id="problem"><a href="#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>
<a id="more"></a>
<span id="more"></span>
<p>For example:<br>Given the below binary tree and sum = 22,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> 5</span><br><span class="line"> &#x2F; \</span><br><span class="line"> 4 8</span><br><span class="line"> &#x2F; &#x2F; \</span><br><span class="line"> 11 13 4</span><br><span class="line"> &#x2F; \ \</span><br><span class="line">7 2 1</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none"> 5
&#x2F; \
4 8
&#x2F; &#x2F; \
11 13 4
&#x2F; \ \
7 2 1<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>return true, as there exist a root-to-leaf path 5-&gt;4-&gt;11-&gt;2 which sum is 22.</p>
<h3 id="Analysis"><a href="#Analysis" class="headerlink" title="Analysis"></a>Analysis</h3><p>using simple deep first search</p>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> Definition for binary tree</span></span><br><span class="line"><span class="comment"> struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> int val;</span></span><br><span class="line"><span class="comment"> TreeNode *left;</span></span><br><span class="line"><span class="comment"> TreeNode *right;</span></span><br><span class="line"><span class="comment"> TreeNode(int x) : val(x), left(NULL), right(NULL)&#125;</span></span><br><span class="line"><span class="comment"> &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">deep_first_search</span><span class="params">(TreeNode *node, <span class="keyword">int</span> sum, <span class="keyword">int</span> curSum)</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (node == <span class="literal">NULL</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (node-&gt;left == <span class="literal">NULL</span> &amp;&amp; node-&gt;right == <span class="literal">NULL</span>)</span><br><span class="line"> <span class="keyword">return</span> curSum + node-&gt;val == sum;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> deep_first_search(node-&gt;left, sum, curSum + node-&gt;val) || deep_first_search(node-&gt;right, sum, curSum + node-&gt;val);</span><br><span class="line"> &#125;</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">hasPathSum</span><span class="params">(TreeNode *root, <span class="keyword">int</span> sum)</span> </span>&#123;</span><br><span class="line"> <span class="comment">// Start typing your C/C++ solution below</span></span><br><span class="line"> <span class="comment">// DO NOT write int main() function</span></span><br><span class="line"> <span class="keyword">return</span> deep_first_search(root, sum, <span class="number">0</span>);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">&#x2F;*
Definition for binary tree
struct TreeNode &#123;
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL)&#125;
&#125;;
*&#x2F;
class Solution &#123;
public:
bool deep_first_search(TreeNode *node, int sum, int curSum)
&#123;
if (node &#x3D;&#x3D; NULL)
return false;
if (node-&gt;left &#x3D;&#x3D; NULL &amp;&amp; node-&gt;right &#x3D;&#x3D; NULL)
return curSum + node-&gt;val &#x3D;&#x3D; sum;
return deep_first_search(node-&gt;left, sum, curSum + node-&gt;val) || deep_first_search(node-&gt;right, sum, curSum + node-&gt;val);
&#125;
bool hasPathSum(TreeNode *root, int sum) &#123;
&#x2F;&#x2F; Start typing your C&#x2F;C++ solution below
&#x2F;&#x2F; DO NOT write int main() function
return deep_first_search(root, sum, 0);
&#125;
&#125;;<span aria-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></span></span></code></pre>
</div>
@ -308,10 +335,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Reverse-Bits/" rel="bookmark">Reverse Bits</a></div>


+ 56
- 13
2015/01/14/Two-Sum/index.html
File diff suppressed because it is too large
View File


+ 29
- 18
2015/01/16/pcre-intro-and-a-simple-package/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2015/01/16/pcre-intro-and-a-simple-package/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2015-01-16T06:30:20.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2015-01-16T06:30:20.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="c++">
<meta property="article:tag" content="mfc">
@ -229,13 +230,6 @@
<time title="Created: 2015-01-16 14:30:20" itemprop="dateCreated datePublished" datetime="2015-01-16T14:30:20+08:00">2015-01-16</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,25 +279,42 @@
<div class="post-body" itemprop="articleBody">
<h3 id="Pcre"><a href="#Pcre" class="headerlink" title="Pcre"></a><a href="http://www.pcre.org/" target="_blank" rel="noopener">Pcre</a></h3><blockquote>
<h3 id="Pcre"><a href="#Pcre" class="headerlink" title="Pcre"></a><a target="_blank" rel="noopener" href="http://www.pcre.org/">Pcre</a></h3><blockquote>
<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>
</blockquote>
<p>因为最近工作内容的一部分需要做字符串的识别处理,所以就顺便用上了之前在PHP中用过的正则,在C/C++中本身不包含正则库,这里使用的pcre,对MFC开发,在<a href="http://www.psyon.org/projects/pcre-win32/index.php" target="_blank" rel="noopener">这里</a>提供了静态链接库,在引入lib跟.h文件后即可使用。</p>
<a id="more"></a>
<p>因为最近工作内容的一部分需要做字符串的识别处理,所以就顺便用上了之前在PHP中用过的正则,在C/C++中本身不包含正则库,这里使用的pcre,对MFC开发,在<a target="_blank" rel="noopener" href="http://www.psyon.org/projects/pcre-win32/index.php">这里</a>提供了静态链接库,在引入lib跟.h文件后即可使用。</p>
<span id="more"></span>
<h3 id="Regular-Expression-Syntax"><a href="#Regular-Expression-Syntax" class="headerlink" title="Regular Expression Syntax"></a>Regular Expression Syntax</h3><p>然后是一些<a href="http://www.pcre.org/original/doc/html/pcresyntax.html" target="_blank" rel="noopener">正则语法</a>,官方的语法文档比较科学严谨,特别是对类似于贪婪匹配等细节的说明,当然一般的使用可以在网上找到很多匹配语法,例如<a href="http://www.regextester.com/pregsyntax.html" target="_blank" rel="noopener">这个</a></p>
<h3 id="Regular-Expression-Syntax"><a href="#Regular-Expression-Syntax" class="headerlink" title="Regular Expression Syntax"></a>Regular Expression Syntax</h3><p>然后是一些<a target="_blank" rel="noopener" href="http://www.pcre.org/original/doc/html/pcresyntax.html">正则语法</a>,官方的语法文档比较科学严谨,特别是对类似于贪婪匹配等细节的说明,当然一般的使用可以在网上找到很多匹配语法,例如<a target="_blank" rel="noopener" href="http://www.regextester.com/pregsyntax.html">这个</a></p>
<h3 id="PCRE函数介绍"><a href="#PCRE函数介绍" class="headerlink" title="PCRE函数介绍"></a>PCRE函数介绍</h3><blockquote>
<p>pcre_compile<br>原型:</p>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pcre.h&gt;</span></span></span><br><span class="line"><span class="function">pcre *<span class="title">pcre_compile</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *pattern, <span class="keyword">int</span> options, <span class="keyword">const</span> <span class="keyword">char</span> **errptr, <span class="keyword">int</span> *erroffset, <span class="keyword">const</span> <span class="keyword">unsigned</span> <span class="keyword">char</span> *tableptr)</span></span>;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">#include &lt;pcre.h&gt;
pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr);<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>功能:将一个正则表达式编译成一个内部表示,在匹配多个字符串时,可以加速匹配。其同pcre_compile2功能一样只是缺少一个参数errorcodeptr。<br>参数:<br><code>pattern</code> 正则表达式<br><code>options</code> 为0,或者其他参数选项<br><code>errptr</code> 出错消息<br><code>erroffset</code> 出错位置<br><code>tableptr</code> 指向一个字符数组的指针,可以设置为空NULL</p>
<blockquote>
<p>pcre_exec<br>原型:</p>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;pcre.h&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">pcre_exec</span><span class="params">(<span class="keyword">const</span> pcre *code, <span class="keyword">const</span> pcre_extra *extra, <span class="keyword">const</span> <span class="keyword">char</span> *subject, <span class="keyword">int</span> length, <span class="keyword">int</span> startoffset, <span class="keyword">int</span> options, <span class="keyword">int</span> *ovector, <span class="keyword">int</span> ovecsize)</span></span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">#include &lt;pcre.h&gt;
int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>功能:使用编译好的模式进行匹配,采用与Perl相似的算法,返回匹配串的偏移位置。<br>参数:<br><code>code</code> 编译好的模式<br><code>extra</code> 指向一个pcre_extra结构体,可以为NULL<br><code>subject</code> 需要匹配的字符串<br><code>length</code> 匹配的字符串长度(Byte)<br><code>startoffset</code> 匹配的开始位置<br><code>options</code> 选项位<br><code>ovector</code> 指向一个结果的整型数组<br><code>ovecsize</code> 数组大小。</p>
<p>这里是两个最常用的函数的简单说明,pcre的静态库提供了一系列的函数以供使用,可以参考这个<a href="http://blog.csdn.net/sulliy/article/details/6247155" target="_blank" rel="noopener">博客</a>说明,另外对于以上函数的具体参数详细说明可以参考官网<a href="http://www.pcre.org/original/doc/html/" target="_blank" rel="noopener">此处</a></p>
<h3 id="一个丑陋的封装"><a href="#一个丑陋的封装" class="headerlink" title="一个丑陋的封装"></a>一个丑陋的封装</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">COcxDemoDlg::pcre_exec_all</span><span class="params">(<span class="keyword">const</span> pcre * re, PCRE_SPTR src, <span class="built_in">vector</span>&lt;pair&lt;<span class="keyword">int</span>, <span class="keyword">int</span>&gt;&gt; &amp;vc)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="keyword">int</span> rc;</span><br><span class="line"> <span class="keyword">int</span> ovector[<span class="number">30</span>];</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> pair&lt;<span class="keyword">int</span>, <span class="keyword">int</span>&gt; pr;</span><br><span class="line"> rc = pcre_exec(re, <span class="literal">NULL</span>, src, <span class="built_in">strlen</span>(src), i, <span class="number">0</span>, ovector, <span class="number">30</span>);</span><br><span class="line"> <span class="keyword">for</span> (; rc &gt; <span class="number">0</span>;)</span><br><span class="line"> &#123;</span><br><span class="line"> i = ovector[<span class="number">1</span>];</span><br><span class="line"> pr.first = ovector[<span class="number">2</span>];</span><br><span class="line"> pr.second = ovector[<span class="number">3</span>];</span><br><span class="line"> vc.push_back(pr);</span><br><span class="line"> rc = pcre_exec(re, <span class="literal">NULL</span>, src, <span class="built_in">strlen</span>(src), i, <span class="number">0</span>, ovector, <span class="number">30</span>);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里是两个最常用的函数的简单说明,pcre的静态库提供了一系列的函数以供使用,可以参考这个<a target="_blank" rel="noopener" href="http://blog.csdn.net/sulliy/article/details/6247155">博客</a>说明,另外对于以上函数的具体参数详细说明可以参考官网<a target="_blank" rel="noopener" href="http://www.pcre.org/original/doc/html/">此处</a></p>
<h3 id="一个丑陋的封装"><a href="#一个丑陋的封装" class="headerlink" title="一个丑陋的封装"></a>一个丑陋的封装</h3><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">void COcxDemoDlg::pcre_exec_all(const pcre * re, PCRE_SPTR src, vector&lt;pair&lt;int, int&gt;&gt; &amp;vc)
&#123;
int rc;
int ovector[30];
int i &#x3D; 0;
pair&lt;int, int&gt; pr;
rc &#x3D; pcre_exec(re, NULL, src, strlen(src), i, 0, ovector, 30);
for (; rc &gt; 0;)
&#123;
i &#x3D; ovector[1];
pr.first &#x3D; ovector[2];
pr.second &#x3D; ovector[3];
vc.push_back(pr);
rc &#x3D; pcre_exec(re, NULL, src, strlen(src), i, 0, ovector, 30);
&#125;
&#125;<span aria-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></code></pre>
<p>vector中是全文匹配后的索引对,只是简单地用下。</p>
</div>
@ -453,7 +464,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#Pcre"><span class="nav-number">1.</span> <span class="nav-text">Pcre</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Regular-Expression-Syntax"><span class="nav-number">2.</span> <span class="nav-text">Regular Expression Syntax</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#PCRE函数介绍"><span class="nav-number">3.</span> <span class="nav-text">PCRE函数介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#一个丑陋的封装"><span class="nav-number">4.</span> <span class="nav-text">一个丑陋的封装</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#Pcre"><span class="nav-number">1.</span> <span class="nav-text">Pcre</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Regular-Expression-Syntax"><span class="nav-number">2.</span> <span class="nav-text">Regular Expression Syntax</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#PCRE%E5%87%BD%E6%95%B0%E4%BB%8B%E7%BB%8D"><span class="nav-number">3.</span> <span class="nav-text">PCRE函数介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%B8%80%E4%B8%AA%E4%B8%91%E9%99%8B%E7%9A%84%E5%B0%81%E8%A3%85"><span class="nav-number">4.</span> <span class="nav-text">一个丑陋的封装</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 24
- 16
2015/03/11/Number-Of-1-Bits/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2015/03/11/Number-Of-1-Bits/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2015-03-11T09:02:58.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2015-03-11T09:02:58.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-03-11 17:02:58" itemprop="dateCreated datePublished" datetime="2015-03-11T17:02:58+08:00">2015-03-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,11 +279,25 @@
<div class="post-body" itemprop="articleBody">
<h3 id="Number-of-1-Bits"><a href="#Number-of-1-Bits" class="headerlink" title="Number of 1 Bits "></a><a href="https://leetcode.com/problems/number-of-1-bits/" target="_blank" rel="noopener">Number of 1 Bits </a></h3><h4 id="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 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" 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><a id="more"></a>
<h3 id="Number-of-1-Bits"><a href="#Number-of-1-Bits" class="headerlink" title="Number of 1 Bits "></a><a target="_blank" rel="noopener" href="https://leetcode.com/problems/number-of-1-bits/">Number of 1 Bits </a></h3><h4 id="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 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" 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><span id="more"></span>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p>从1位到2位到4位逐步的交换</p>
<hr>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">hammingWeight</span><span class="params">(<span class="keyword">uint32_t</span> n)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">uint32_t</span> m1 = <span class="number">0x55555555</span>; <span class="comment">//binary: 0101... </span></span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">uint32_t</span> m2 = <span class="number">0x33333333</span>; <span class="comment">//binary: 00110011.. </span></span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">uint32_t</span> m4 = <span class="number">0x0f0f0f0f</span>; <span class="comment">//binary: 4 zeros, 4 ones ... </span></span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">uint32_t</span> m8 = <span class="number">0x00ff00ff</span>; <span class="comment">//binary: 8 zeros, 8 ones ... </span></span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">uint32_t</span> m16 = <span class="number">0x0000ffff</span>; <span class="comment">//binary: 16 zeros, 16 ones ... </span></span><br><span class="line"> </span><br><span class="line"> n = (n &amp; m1 ) + ((n &gt;&gt; <span class="number">1</span>) &amp; m1 ); <span class="comment">//put count of each 2 bits into those 2 bits </span></span><br><span class="line"> n = (n &amp; m2 ) + ((n &gt;&gt; <span class="number">2</span>) &amp; m2 ); <span class="comment">//put count of each 4 bits into those 4 bits </span></span><br><span class="line"> n = (n &amp; m4 ) + ((n &gt;&gt; <span class="number">4</span>) &amp; m4 ); <span class="comment">//put count of each 8 bits into those 8 bits </span></span><br><span class="line"> n = (n &amp; m8 ) + ((n &gt;&gt; <span class="number">8</span>) &amp; m8 ); <span class="comment">//put count of each 16 bits into those 16 bits </span></span><br><span class="line"> n = (n &amp; m16) + ((n &gt;&gt; <span class="number">16</span>) &amp; m16); <span class="comment">//put count of each 32 bits into those 32 bits </span></span><br><span class="line"> <span class="keyword">return</span> n; </span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">int hammingWeight(uint32_t n) &#123;
const uint32_t m1 &#x3D; 0x55555555; &#x2F;&#x2F;binary: 0101...
const uint32_t m2 &#x3D; 0x33333333; &#x2F;&#x2F;binary: 00110011..
const uint32_t m4 &#x3D; 0x0f0f0f0f; &#x2F;&#x2F;binary: 4 zeros, 4 ones ...
const uint32_t m8 &#x3D; 0x00ff00ff; &#x2F;&#x2F;binary: 8 zeros, 8 ones ...
const uint32_t m16 &#x3D; 0x0000ffff; &#x2F;&#x2F;binary: 16 zeros, 16 ones ...
n &#x3D; (n &amp; m1 ) + ((n &gt;&gt; 1) &amp; m1 ); &#x2F;&#x2F;put count of each 2 bits into those 2 bits
n &#x3D; (n &amp; m2 ) + ((n &gt;&gt; 2) &amp; m2 ); &#x2F;&#x2F;put count of each 4 bits into those 4 bits
n &#x3D; (n &amp; m4 ) + ((n &gt;&gt; 4) &amp; m4 ); &#x2F;&#x2F;put count of each 8 bits into those 8 bits
n &#x3D; (n &amp; m8 ) + ((n &gt;&gt; 8) &amp; m8 ); &#x2F;&#x2F;put count of each 16 bits into those 16 bits
n &#x3D; (n &amp; m16) + ((n &gt;&gt; 16) &amp; m16); &#x2F;&#x2F;put count of each 32 bits into those 32 bits
return n;
&#125;<span aria-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></code></pre>
</div>
@ -299,19 +307,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/13/Reverse-Integer/" rel="bookmark">Reverse Integer</a></div>
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2016/10/12/summary-ranges-228/" rel="bookmark">summary-ranges-228</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
<div class="popular-posts-title"><a href="/2016/10/11/minimum-size-subarray-sum-209/" rel="bookmark">minimum-size-subarray-sum-209</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Reverse-Bits/" rel="bookmark">Reverse Bits</a></div>
<div class="popular-posts-title"><a href="/2015/06/22/invert-binary-tree/" rel="bookmark">invert-binary-tree</a></div>
</li>
</ul>
@ -437,7 +445,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#Number-of-1-Bits"><span class="nav-number">1.</span> <span class="nav-text">Number of 1 Bits </span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="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"><span class="nav-number">1.1.</span> <span class="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><li class="nav-item nav-level-3"><a class="nav-link" href="#分析"><span class="nav-number">2.</span> <span class="nav-text">分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#code"><span class="nav-number">3.</span> <span class="nav-text">code</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#Number-of-1-Bits"><span class="nav-number">1.</span> <span class="nav-text">Number of 1 Bits </span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="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"><span class="nav-number">1.1.</span> <span class="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><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#code"><span class="nav-number">3.</span> <span class="nav-text">code</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 18
- 14
2015/03/11/Reverse-Bits/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2015/03/11/Reverse-Bits/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2015-03-11T09:35:20.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2015-03-11T09:35:20.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-03-11 17:35:20" itemprop="dateCreated datePublished" datetime="2015-03-11T17:35:20+08:00">2015-03-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,11 +279,21 @@
<div class="post-body" itemprop="articleBody">
<h3 id="Reverse-Bits"><a href="#Reverse-Bits" class="headerlink" title="Reverse Bits "></a><a href="https://leetcode.com/problems/reverse-bits/" target="_blank" rel="noopener">Reverse Bits </a></h3><h4 id="Reverse-bits-of-a-given-32-bits-unsigned-integer"><a href="#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>
<a id="more"></a>
<h3 id="Reverse-Bits"><a href="#Reverse-Bits" class="headerlink" title="Reverse Bits "></a><a target="_blank" rel="noopener" href="https://leetcode.com/problems/reverse-bits/">Reverse Bits </a></h3><h4 id="Reverse-bits-of-a-given-32-bits-unsigned-integer"><a href="#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>
<span id="more"></span>
<p>Follow up:<br>If this function is called many times, how would you optimize it?</p>
<hr>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">uint32_t</span> <span class="title">reverseBits</span><span class="params">(<span class="keyword">uint32_t</span> n)</span> </span>&#123;</span><br><span class="line"> n = ((n &gt;&gt; <span class="number">1</span>) &amp; <span class="number">0x55555555</span>) | ((n &amp; <span class="number">0x55555555</span>) &lt;&lt; <span class="number">1</span>);</span><br><span class="line"> n = ((n &gt;&gt; <span class="number">2</span>) &amp; <span class="number">0x33333333</span>) | ((n &amp; <span class="number">0x33333333</span>) &lt;&lt; <span class="number">2</span>);</span><br><span class="line"> n = ((n &gt;&gt; <span class="number">4</span>) &amp; <span class="number">0x0f0f0f0f</span>) | ((n &amp; <span class="number">0x0f0f0f0f</span>) &lt;&lt; <span class="number">4</span>);</span><br><span class="line"> n = ((n &gt;&gt; <span class="number">8</span>) &amp; <span class="number">0x00ff00ff</span>) | ((n &amp; <span class="number">0x00ff00ff</span>) &lt;&lt; <span class="number">8</span>);</span><br><span class="line"> n = ((n &gt;&gt; <span class="number">16</span>) &amp; <span class="number">0x0000ffff</span>) | ((n &amp; <span class="number">0x0000ffff</span>) &lt;&lt; <span class="number">16</span>);</span><br><span class="line"> <span class="keyword">return</span> n;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
uint32_t reverseBits(uint32_t n) &#123;
n &#x3D; ((n &gt;&gt; 1) &amp; 0x55555555) | ((n &amp; 0x55555555) &lt;&lt; 1);
n &#x3D; ((n &gt;&gt; 2) &amp; 0x33333333) | ((n &amp; 0x33333333) &lt;&lt; 2);
n &#x3D; ((n &gt;&gt; 4) &amp; 0x0f0f0f0f) | ((n &amp; 0x0f0f0f0f) &lt;&lt; 4);
n &#x3D; ((n &gt;&gt; 8) &amp; 0x00ff00ff) | ((n &amp; 0x00ff00ff) &lt;&lt; 8);
n &#x3D; ((n &gt;&gt; 16) &amp; 0x0000ffff) | ((n &amp; 0x0000ffff) &lt;&lt; 16);
return n;
&#125;
&#125;;<span aria-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></code></pre>
</div>
@ -306,10 +310,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>


+ 32
- 14
2015/03/13/Reverse-Integer/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2015/03/13/Reverse-Integer/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="Reverse IntegerReverse digits of an integer.Example1: x &#x3D; 123, return 321Example2: x &#x3D; -123, return -321">
<meta property="og:locale">
<meta property="article:published_time" content="2015-03-13T09:22:20.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2015-03-13T09:22:20.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-03-13 17:22:20" itemprop="dateCreated datePublished" datetime="2015-03-13T17:22:20+08:00">2015-03-13</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,14 +279,38 @@
<div class="post-body" itemprop="articleBody">
<h3 id="Reverse-Integer"><a href="#Reverse-Integer" class="headerlink" title="Reverse Integer"></a><a href="https://leetcode.com/problems/reverse-integer/" target="_blank" rel="noopener">Reverse Integer</a></h3><h4 id="Reverse-digits-of-an-integer"><a href="#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>
<a id="more"></a>
<h3 id="Reverse-Integer"><a href="#Reverse-Integer" class="headerlink" title="Reverse Integer"></a><a target="_blank" rel="noopener" href="https://leetcode.com/problems/reverse-integer/">Reverse Integer</a></h3><h4 id="Reverse-digits-of-an-integer"><a href="#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>
<span id="more"></span>
<h4 id="spoilers"><a href="#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>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>
<hr>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">reverse</span><span class="params">(<span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">max</span> = <span class="number">1</span> &lt;&lt; <span class="number">31</span> - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> ret = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">max</span> = (<span class="built_in">max</span> - <span class="number">1</span>) * <span class="number">2</span> + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">min</span> = <span class="number">1</span> &lt;&lt; <span class="number">31</span>;</span><br><span class="line"> <span class="keyword">if</span>(x &lt; <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">while</span>(x != <span class="number">0</span>)&#123;</span><br><span class="line"> <span class="keyword">if</span>(ret &lt; (<span class="built_in">min</span> - x % <span class="number">10</span>) / <span class="number">10</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> ret = ret * <span class="number">10</span> + x % <span class="number">10</span>;</span><br><span class="line"> x = x / <span class="number">10</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">while</span>(x != <span class="number">0</span>)&#123;</span><br><span class="line"> <span class="keyword">if</span>(ret &gt; (<span class="built_in">max</span> -x % <span class="number">10</span>) / <span class="number">10</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> ret = ret * <span class="number">10</span> + x % <span class="number">10</span>;</span><br><span class="line"> x = x / <span class="number">10</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="code"><a href="#code" class="headerlink" title="code"></a>code</h3><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
int reverse(int x) &#123;
int max &#x3D; 1 &lt;&lt; 31 - 1;
int ret &#x3D; 0;
max &#x3D; (max - 1) * 2 + 1;
int min &#x3D; 1 &lt;&lt; 31;
if(x &lt; 0)
while(x !&#x3D; 0)&#123;
if(ret &lt; (min - x % 10) &#x2F; 10)
return 0;
ret &#x3D; ret * 10 + x % 10;
x &#x3D; x &#x2F; 10;
&#125;
else
while(x !&#x3D; 0)&#123;
if(ret &gt; (max -x % 10) &#x2F; 10)
return 0;
ret &#x3D; ret * 10 + x % 10;
x &#x3D; x &#x2F; 10;
&#125;
return ret;
&#125;
&#125;;<span aria-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></code></pre>
</div>
@ -309,10 +327,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>


+ 93
- 16
2015/04/14/Add-Two-Number/index.html
File diff suppressed because it is too large
View File


+ 22
- 17
2015/04/15/Leetcode-No-3/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,14 +26,15 @@
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>
<meta name="description" content="*Longest Substring Without Repeating Characters *">
<meta name="description" content="**Longest Substring Without Repeating Characters **">
<meta property="og:type" content="article">
<meta property="og:title" content="leetcode no.3">
<meta property="og:url" content="https://nicksxs.me/2015/04/15/Leetcode-No-3/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="*Longest Substring Without Repeating Characters *">
<meta property="og:description" content="**Longest Substring Without Repeating Characters **">
<meta property="og:locale">
<meta property="article:published_time" content="2015-04-15T05:49:00.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2015-04-15T05:49:00.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-04-15 13:49:00" itemprop="dateCreated datePublished" datetime="2015-04-15T13:49:00+08:00">2015-04-15</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,11 +279,22 @@
<div class="post-body" itemprop="articleBody">
<p>*<em>Longest Substring Without Repeating Characters *</em></p>
<a id="more"></a>
<p>**Longest Substring Without Repeating Characters **</p>
<span id="more"></span>
<h3 id="description"><a href="#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>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p><a href="http://www.cnblogs.com/dollarzhaole/p/3155712.html" target="_blank" rel="noopener">源码</a>这次是参考了这个代码,<br>tail 表示的当前子串的起始点位置,tail从-1开始就包括的串的长度是1的边界。其实我<br>也是猜的(逃</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> ct[<span class="number">256</span>];</span><br><span class="line"> <span class="built_in">memset</span>(ct, <span class="number">-1</span>, <span class="keyword">sizeof</span>(ct));</span><br><span class="line"> <span class="keyword">int</span> tail = <span class="number">-1</span>;</span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">max</span> = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; s.<span class="built_in">size</span>(); i++)&#123;</span><br><span class="line"> <span class="keyword">if</span> (ct[s[i]] &gt; tail)</span><br><span class="line"> tail = ct[s[i]];</span><br><span class="line"> <span class="keyword">if</span> (i - tail &gt; <span class="built_in">max</span>)</span><br><span class="line"> <span class="built_in">max</span> = i - tail;</span><br><span class="line"> ct[s[i]] = i;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">max</span>;</span><br></pre></td></tr></table></figure>
<h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><p><a target="_blank" rel="noopener" href="http://www.cnblogs.com/dollarzhaole/p/3155712.html">源码</a>这次是参考了这个代码,<br>tail 表示的当前子串的起始点位置,tail从-1开始就包括的串的长度是1的边界。其实我<br>也是猜的(逃</p>
<pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">int ct[256];
memset(ct, -1, sizeof(ct));
int tail &#x3D; -1;
int max &#x3D; 0;
for (int i &#x3D; 0; i &lt; s.size(); i++)&#123;
if (ct[s[i]] &gt; tail)
tail &#x3D; ct[s[i]];
if (i - tail &gt; max)
max &#x3D; i - tail;
ct[s[i]] &#x3D; i;
&#125;
return max;<span aria-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></code></pre>
</div>
@ -300,7 +305,7 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
@ -438,7 +443,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#description"><span class="nav-number">1.</span> <span class="nav-text">description</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#分析"><span class="nav-number">2.</span> <span class="nav-text">分析</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#description"><span class="nav-number">1.</span> <span class="nav-text">description</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">分析</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 33
- 16
2015/06/22/invert-binary-tree/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,14 +26,15 @@
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>
<meta name="description" content="Invert a binary tree 4 &#x2F; \ 2 7 &#x2F; \ &#x2F; \ 1 3 6 9to 4 &#x2F; \ 7 2 &#x2F; \ &#x2F; \ 9 6 3 1Trivia:This problem was inspired by this original tweet by Max Howell: Google:">
<meta name="description" content="Invert a binary tree 4 &#x2F; \ 2 7 &#x2F; \ &#x2F; \ 1 3 6 9 to 4 &#x2F; \ 7 2 &#x2F; \ &#x2F; \ 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Goog">
<meta property="og:type" content="article">
<meta property="og:title" content="invert-binary-tree">
<meta property="og:url" content="https://nicksxs.me/2015/06/22/invert-binary-tree/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="Invert a binary tree 4 &#x2F; \ 2 7 &#x2F; \ &#x2F; \ 1 3 6 9to 4 &#x2F; \ 7 2 &#x2F; \ &#x2F; \ 9 6 3 1Trivia:This problem was inspired by this original tweet by Max Howell: Google:">
<meta property="og:description" content="Invert a binary tree 4 &#x2F; \ 2 7 &#x2F; \ &#x2F; \ 1 3 6 9 to 4 &#x2F; \ 7 2 &#x2F; \ &#x2F; \ 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Goog">
<meta property="og:locale">
<meta property="article:published_time" content="2015-06-22T02:29:44.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2015-06-22T02:29:44.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2015-06-22 10:29:44" itemprop="dateCreated datePublished" datetime="2015-06-22T10:29:44+08:00">2015-06-22</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -290,16 +284,39 @@
/ \
2 7
/ \ / \
1 3 6 9</code></pre><p>to</p>
1 3 6 9
</code></pre>
<p>to</p>
<pre><code> 4
/ \
7 2
/ \ / \
9 6 3 1</code></pre><p><strong>Trivia:</strong><br>This problem was inspired by <a href="https://twitter.com/mxcl/status/608682016205344768" target="_blank" rel="noopener">this original tweet</a> by <a href="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 <a target="_blank" rel="noopener" href="https://twitter.com/mxcl/status/608682016205344768">this original tweet</a> by <a target="_blank" rel="noopener" href="https://twitter.com/mxcl">Max Howell</a>:</p>
<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>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for a binary tree node.</span></span><br><span class="line"><span class="comment"> * struct TreeNode &#123;</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * TreeNode *left;</span></span><br><span class="line"><span class="comment"> * TreeNode *right;</span></span><br><span class="line"><span class="comment"> * TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;</span></span><br><span class="line"><span class="comment"> * &#125;;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function">TreeNode* <span class="title">invertTree</span><span class="params">(TreeNode* root)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span>(root == <span class="literal">NULL</span>) <span class="keyword">return</span> root;</span><br><span class="line"> TreeNode* temp;</span><br><span class="line"> temp = invertTree(root-&gt;left);</span><br><span class="line"> root-&gt;left = invertTree(root-&gt;right);</span><br><span class="line"> root-&gt;right = temp;</span><br><span class="line"> <span class="keyword">return</span> root;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">&#x2F;**
* Definition for a binary tree node.
* struct TreeNode &#123;
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) &#123;&#125;
* &#125;;
*&#x2F;
class Solution &#123;
public:
TreeNode* invertTree(TreeNode* root) &#123;
if(root &#x3D;&#x3D; NULL) return root;
TreeNode* temp;
temp &#x3D; invertTree(root-&gt;left);
root-&gt;left &#x3D; invertTree(root-&gt;right);
root-&gt;right &#x3D; temp;
return root;
&#125;
&#125;;<span aria-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></code></pre>
</div>
@ -315,10 +332,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>


+ 100
- 21
2016/07/13/swoole-websocket-test/index.html
File diff suppressed because it is too large
View File


+ 35
- 13
2016/08/14/34-Search-for-a-Range/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2016/08/14/34-Search-for-a-Range/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2016-08-14T13:33:24.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2016-08-14T13:33:24.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2016-08-14 21:33:24" itemprop="dateCreated datePublished" datetime="2016-08-14T21:33:24+08:00">2016-08-14</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,13 +279,41 @@
<div class="post-body" itemprop="articleBody">
<h2 id="question"><a href="#question" class="headerlink" title="question"></a>question</h2><h3 id="34-Search-for-a-Range"><a href="#34-Search-for-a-Range" class="headerlink" title="34. Search for a Range"></a>34. Search for a Range</h3><p><a href="https://leetcode.com/problems/search-for-a-range/" target="_blank" rel="noopener">Original Page</a></p>
<h2 id="question"><a href="#question" class="headerlink" title="question"></a>question</h2><h3 id="34-Search-for-a-Range"><a href="#34-Search-for-a-Range" class="headerlink" title="34. Search for a Range"></a>34. Search for a Range</h3><p><a target="_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>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>For example,<br>Given <code>[5, 7, 7, 8, 8, 10]</code> and target value 8,<br>return <code>[3, 4]</code>.</p>
<h2 id="analysis"><a href="#analysis" class="headerlink" title="analysis"></a>analysis</h2><p>一开始就想到了二分查找,但是原来做二分查找的时候一般都是找到确定的那个数就完成了,<br>这里的情况比较特殊,需要找到整个区间,所以需要两遍查找,并且一个是找到小于target<br>的最大索引,一个是找到大于target的最大索引,代码参考<a href="https://discuss.leetcode.com/topic/5891/clean-iterative-solution-with-two-binary-searches-with-explanation/2" target="_blank" rel="noopener">leetcode discuss</a>,这位仁<br>兄也做了详细的分析解释。 </p>
<h2 id="code"><a href="#code" class="headerlink" title="code"></a>code</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; <span class="title">searchRange</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line"> <span class="function"><span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt; <span class="title">ret</span><span class="params">(<span class="number">2</span>, <span class="number">-1</span>)</span></span>;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>, j = nums.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> mid;</span><br><span class="line"> <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line"> mid = (i + j) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">if</span>(nums[mid] &lt; target) i = mid + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> j = mid;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span>(nums[i] != target) <span class="keyword">return</span> ret;</span><br><span class="line"> <span class="keyword">else</span> &#123;</span><br><span class="line"> ret[<span class="number">0</span>] = i;</span><br><span class="line"> <span class="keyword">if</span>((i+<span class="number">1</span>) &lt; (nums.<span class="built_in">size</span>() - <span class="number">1</span>) &amp;&amp; nums[i+<span class="number">1</span>] &gt; target)&#123;</span><br><span class="line"> ret[<span class="number">1</span>] = i;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125; <span class="comment">//一点小优化</span></span><br><span class="line"> j = nums.<span class="built_in">size</span>() - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(i &lt; j)&#123;</span><br><span class="line"> mid = (i + j) / <span class="number">2</span> + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(nums[mid] &gt; target) j = mid - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> i = mid;</span><br><span class="line"> &#125;</span><br><span class="line"> ret[<span class="number">1</span>] = j;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h2 id="analysis"><a href="#analysis" class="headerlink" title="analysis"></a>analysis</h2><p>一开始就想到了二分查找,但是原来做二分查找的时候一般都是找到确定的那个数就完成了,<br>这里的情况比较特殊,需要找到整个区间,所以需要两遍查找,并且一个是找到小于target<br>的最大索引,一个是找到大于target的最大索引,代码参考<a target="_blank" rel="noopener" href="https://discuss.leetcode.com/topic/5891/clean-iterative-solution-with-two-binary-searches-with-explanation/2">leetcode discuss</a>,这位仁<br>兄也做了详细的分析解释。 </p>
<h2 id="code"><a href="#code" class="headerlink" title="code"></a>code</h2><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
vector&lt;int&gt; searchRange(vector&lt;int&gt;&amp; nums, int target) &#123;
vector&lt;int&gt; ret(2, -1);
int i &#x3D; 0, j &#x3D; nums.size() - 1;
int mid;
while(i &lt; j)&#123;
mid &#x3D; (i + j) &#x2F; 2;
if(nums[mid] &lt; target) i &#x3D; mid + 1;
else j &#x3D; mid;
&#125;
if(nums[i] !&#x3D; target) return ret;
else &#123;
ret[0] &#x3D; i;
if((i+1) &lt; (nums.size() - 1) &amp;&amp; nums[i+1] &gt; target)&#123;
ret[1] &#x3D; i;
return ret;
&#125;
&#125; &#x2F;&#x2F;一点小优化
j &#x3D; nums.size() - 1;
while(i &lt; j)&#123;
mid &#x3D; (i + j) &#x2F; 2 + 1;
if(nums[mid] &gt; target) j &#x3D; mid - 1;
else i &#x3D; mid;
&#125;
ret[1] &#x3D; j;
return ret;
&#125;
&#125;;<span aria-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></span><span></span></span></code></pre>
</div>
@ -301,7 +323,7 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>


+ 18
- 16
2016/08/14/docker-mysql-cluster/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,10 +32,11 @@
<meta property="og:url" content="https://nicksxs.me/2016/08/14/docker-mysql-cluster/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="docker-mysql-cluster基于docker搭了个mysql集群,稍微记一下,首先是新建mysql主库容">
<meta property="og:locale">
<meta property="og:image" content="https://ooo.0o0.ooo/2016/08/10/57aac43029559.png">
<meta property="og:image" content="https://ooo.0o0.ooo/2016/08/10/57aac63fd02f1.png">
<meta property="article:published_time" content="2016-08-14T08:51:00.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2016-08-14T08:51:00.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="docker">
<meta property="article:tag" content="mysql">
@ -232,13 +233,6 @@
<time title="Created: 2016-08-14 16:51:00" itemprop="dateCreated datePublished" datetime="2016-08-14T16:51:00+08:00">2016-08-14</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -288,13 +282,21 @@
<div class="post-body" itemprop="articleBody">
<h3 id="docker-mysql-cluster"><a href="#docker-mysql-cluster" class="headerlink" title="docker-mysql-cluster"></a>docker-mysql-cluster</h3><p>基于docker搭了个mysql集群,稍微记一下,<br>首先是新建mysql主库容<br> <a id="more"></a><br><code>docker run -d -e MYSQL_ROOT_PASSWORD=admin --name mysql-master -p 3307:3306 mysql:latest</code><br><code>-d</code>表示容器运行在后台,<code>-e</code>表示设置环境变量,即<code>MYSQL_ROOT_PASSWORD=admin</code>,设置了mysql的root密码,<br><code>--name</code>表示容器名,<code>-p</code>表示端口映射,将内部mysql:3306映射为外部的3307,最后的<code>mysql:latest</code>表示镜像名<br>此外还可以用<code>-v /local_path/my-master.cnf:/etc/mysql/my.cnf</code>来映射配置文件<br>然后同理启动从库<br><code>docker run -d -e MYSQL_ROOT_PASSWORD=admin --name mysql-slave -p 3308:3306 mysql:latest</code><br>然后进入主库改下配置文件<br><code>docker-enter mysql-master</code>如果无法进入就用<code>docker ps -a</code>看下容器是否在正常运行,如果status显示<br>未正常运行,则用<code>docker logs mysql-master</code>看下日志哪里出错了。<br>进入容器后,我这边使用的镜像的mysqld配置文件是在<code>/etc/mysql</code>下面,这个最新版本的mysql的配置文件包含<br>三部分,<code>/etc/mysql/my.cnf</code><code>/etc/mysql/conf.d/mysql.cnf</code>,还有<code>/etc/mysql/mysql.conf.d/mysqld.cnf</code><br>这里需要改的是最后一个,加上</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">log-bin &#x3D; mysql-bin</span><br><span class="line">server_id &#x3D; 1</span><br></pre></td></tr></table></figure>
<h3 id="docker-mysql-cluster"><a href="#docker-mysql-cluster" class="headerlink" title="docker-mysql-cluster"></a>docker-mysql-cluster</h3><p>基于docker搭了个mysql集群,稍微记一下,<br>首先是新建mysql主库容<br> <span id="more"></span><br><code>docker run -d -e MYSQL_ROOT_PASSWORD=admin --name mysql-master -p 3307:3306 mysql:latest</code><br><code>-d</code>表示容器运行在后台,<code>-e</code>表示设置环境变量,即<code>MYSQL_ROOT_PASSWORD=admin</code>,设置了mysql的root密码,<br><code>--name</code>表示容器名,<code>-p</code>表示端口映射,将内部mysql:3306映射为外部的3307,最后的<code>mysql:latest</code>表示镜像名<br>此外还可以用<code>-v /local_path/my-master.cnf:/etc/mysql/my.cnf</code>来映射配置文件<br>然后同理启动从库<br><code>docker run -d -e MYSQL_ROOT_PASSWORD=admin --name mysql-slave -p 3308:3306 mysql:latest</code><br>然后进入主库改下配置文件<br><code>docker-enter mysql-master</code>如果无法进入就用<code>docker ps -a</code>看下容器是否在正常运行,如果status显示<br>未正常运行,则用<code>docker logs mysql-master</code>看下日志哪里出错了。<br>进入容器后,我这边使用的镜像的mysqld配置文件是在<code>/etc/mysql</code>下面,这个最新版本的mysql的配置文件包含<br>三部分,<code>/etc/mysql/my.cnf</code><code>/etc/mysql/conf.d/mysql.cnf</code>,还有<code>/etc/mysql/mysql.conf.d/mysqld.cnf</code><br>这里需要改的是最后一个,加上</p>
<pre class="line-numbers language-none"><code class="language-none">log-bin &#x3D; mysql-bin
server_id &#x3D; 1<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>保存后退出容器重启主库容器,然后进入从库更改相同文件,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">log-bin &#x3D; mysql-bin</span><br><span class="line">server_id &#x3D; 2</span><br></pre></td></tr></table></figure>
<h3 id="主从配置"><a href="#主从配置" class="headerlink" title="主从配置"></a>主从配置</h3><p>同样退出重启容器,然后是配置主从,首先进入主库,用命令mysql -u root -pxxxx进入mysql,然后赋予一个同步<br>权限<code>GRANT REPLICATION SLAVE ON *.* to &#39;backup&#39;@&#39;%&#39; identified by &#39;123456&#39;;</code>还是同样说明下,ON <em>.</em>表示了数<br>据库全部的权限,如果要指定数据库/表的话可以使用类似<code>testDb/testTable</code>,然后是<code>&#39;backup&#39;@&#39;%&#39;</code>表示给予同步<br>权限的用户名及其主机ip,%表示不限制ip,当然如果有防火墙的话还是会有限制的,最后的<code>identified by &#39;123456&#39;</code><br>表示同步用户的密码,然后就查看下主库的状态信息<code>show master status</code>,如下图:<br><img data-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>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">change master to</span><br><span class="line">master_host&#x3D;&#39;xxx.xxx.xxx.xxx&#39;, &#x2F;&#x2F;如果主从库的容器都在同一个宿主机上,这里的ip是docker容器的ip</span><br><span class="line">master_user&#x3D;&#39;backup&#39;, &#x2F;&#x2F;就是上面的赋予权限的用户</span><br><span class="line">master_password&#x3D;&#39;123456&#39;,</span><br><span class="line">master_log_file&#x3D;&#39;mysql-bin.000004&#39;, &#x2F;&#x2F;主库中查看到的file</span><br><span class="line">master_log_pos&#x3D;312, &#x2F;&#x2F;主库中查看到的position</span><br><span class="line">master_port&#x3D;3306; &#x2F;&#x2F;如果是同一宿主机,这里使用真实的3306端口,3308及主库的3307是给外部连接使用的</span><br></pre></td></tr></table></figure>
<p>通过<code>docker-ip mysql-master</code>可以查看容器的ip<br><img data-src="https://ooo.0o0.ooo/2016/08/10/57aac63fd02f1.png" alt="S(GP)P(M$N3~N1764@OW3E0.png"><br>这里有一点是要注意的,也是我踩的坑,就是如果是同一宿主机下两个mysql容器互联,我这里只能通过docker-ip和真实<br>的3306端口能够连接成功。<br>本文参考了<a href="http://blog.csdn.net/qq362228416/article/details/48569293" target="_blank" rel="noopener">这位同学的文章</a></p>
<pre class="line-numbers language-none"><code class="language-none">log-bin &#x3D; mysql-bin
server_id &#x3D; 2<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h3 id="主从配置"><a href="#主从配置" class="headerlink" title="主从配置"></a>主从配置</h3><p>同样退出重启容器,然后是配置主从,首先进入主库,用命令mysql -u root -pxxxx进入mysql,然后赋予一个同步<br>权限<code>GRANT REPLICATION SLAVE ON *.* to &#39;backup&#39;@&#39;%&#39; identified by &#39;123456&#39;;</code>还是同样说明下,ON *.*表示了数<br>据库全部的权限,如果要指定数据库/表的话可以使用类似<code>testDb/testTable</code>,然后是<code>&#39;backup&#39;@&#39;%&#39;</code>表示给予同步<br>权限的用户名及其主机ip,%表示不限制ip,当然如果有防火墙的话还是会有限制的,最后的<code>identified by &#39;123456&#39;</code><br>表示同步用户的密码,然后就查看下主库的状态信息<code>show master status</code>,如下图:<br><img data-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>
<pre class="line-numbers language-none"><code class="language-none">change master to
master_host&#x3D;&#39;xxx.xxx.xxx.xxx&#39;, &#x2F;&#x2F;如果主从库的容器都在同一个宿主机上,这里的ip是docker容器的ip
master_user&#x3D;&#39;backup&#39;, &#x2F;&#x2F;就是上面的赋予权限的用户
master_password&#x3D;&#39;123456&#39;,
master_log_file&#x3D;&#39;mysql-bin.000004&#39;, &#x2F;&#x2F;主库中查看到的file
master_log_pos&#x3D;312, &#x2F;&#x2F;主库中查看到的position
master_port&#x3D;3306; &#x2F;&#x2F;如果是同一宿主机,这里使用真实的3306端口,3308及主库的3307是给外部连接使用的<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>通过<code>docker-ip mysql-master</code>可以查看容器的ip<br><img data-src="https://ooo.0o0.ooo/2016/08/10/57aac63fd02f1.png" alt="S(GP)P(M$N3~N1764@OW3E0.png"><br>这里有一点是要注意的,也是我踩的坑,就是如果是同一宿主机下两个mysql容器互联,我这里只能通过docker-ip和真实<br>的3306端口能够连接成功。<br>本文参考了<a target="_blank" rel="noopener" href="http://blog.csdn.net/qq362228416/article/details/48569293">这位同学的文章</a></p>
</div>
@ -440,7 +442,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#docker-mysql-cluster"><span class="nav-number">1.</span> <span class="nav-text">docker-mysql-cluster</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#主从配置"><span class="nav-number">2.</span> <span class="nav-text">主从配置</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#docker-mysql-cluster"><span class="nav-number">1.</span> <span class="nav-text">docker-mysql-cluster</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%B8%BB%E4%BB%8E%E9%85%8D%E7%BD%AE"><span class="nav-number">2.</span> <span class="nav-text">主从配置</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 24
- 16
2016/09/29/binary-watch/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,9 +32,10 @@
<meta property="og:url" content="https://nicksxs.me/2016/09/29/binary-watch/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="og:image" content="http://7sbp1g.com1.z0.glb.clouddn.com/Binary_clock_samui_moon.jpg?imageView2/2/w/620">
<meta property="article:published_time" content="2016-09-29T15:16:06.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2016-09-29T15:16:06.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -231,13 +232,6 @@
<time title="Created: 2016-09-29 23:16:06" itemprop="dateCreated datePublished" datetime="2016-09-29T23:16:06+08:00">2016-09-29</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -289,17 +283,31 @@
<h3 id="problem"><a href="#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><img data-src="http://7sbp1g.com1.z0.glb.clouddn.com/Binary_clock_samui_moon.jpg?imageView2/2/w/620" alt=""></p>
<p><img data-src="http://7sbp1g.com1.z0.glb.clouddn.com/Binary_clock_samui_moon.jpg?imageView2/2/w/620"></p>
<p>For example, the above binary watch reads “3:25”. </p>
<p>Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent. </p>
<h4 id="Example"><a href="#Example" class="headerlink" title="Example:"></a>Example:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input: n &#x3D; 1</span><br><span class="line">Return: [&quot;1:00&quot;, &quot;2:00&quot;, &quot;4:00&quot;, &quot;8:00&quot;, &quot;0:01&quot;, &quot;0:02&quot;, &quot;0:04&quot;, &quot;0:08&quot;, &quot;0:16&quot;, &quot;0:32&quot;]</span><br></pre></td></tr></table></figure>
<h4 id="Example"><a href="#Example" class="headerlink" title="Example:"></a>Example:</h4><pre class="line-numbers language-none"><code class="language-none">Input: n &#x3D; 1
Return: [&quot;1:00&quot;, &quot;2:00&quot;, &quot;4:00&quot;, &quot;8:00&quot;, &quot;0:01&quot;, &quot;0:02&quot;, &quot;0:04&quot;, &quot;0:08&quot;, &quot;0:16&quot;, &quot;0:32&quot;]<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h4 id="Note"><a href="#Note" class="headerlink" title="Note:"></a>Note:</h4><ul>
<li>The order of output does not matter.</li>
<li>The hour must not contain a leading zero, for example “01:00” is not valid, it should be “1:00”.</li>
<li>The minute must be consist of two digits and may contain a leading zero, for example “10:2” is not valid, it should be “10:02”.</li>
</ul>
<h3 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h3><p>又是参(chao)考(xi)别人的代码,嗯,就是这么不要脸,<a href="http://www.cnblogs.com/grandyang/p/5896454.html" target="_blank" rel="noopener">链接</a></p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; <span class="title">readBinaryWatch</span><span class="params">(<span class="keyword">int</span> num)</span> </span>&#123;</span><br><span class="line"> <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> h = <span class="number">0</span>; h &lt; <span class="number">12</span>; ++h) &#123;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> m = <span class="number">0</span>; m &lt; <span class="number">60</span>; ++m) &#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">bitset</span>&lt;<span class="number">10</span>&gt;((h &lt;&lt; <span class="number">6</span>) + m).count() == num) &#123;</span><br><span class="line"> res.push_back(to_string(h) + (m &lt; <span class="number">10</span> ? <span class="string">":0"</span> : <span class="string">":"</span>) + to_string(m));</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> res;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h3 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h3><p>又是参(chao)考(xi)别人的代码,嗯,就是这么不要脸,<a target="_blank" rel="noopener" href="http://www.cnblogs.com/grandyang/p/5896454.html">链接</a></p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
vector&lt;string&gt; readBinaryWatch(int num) &#123;
vector&lt;string&gt; res;
for (int h &#x3D; 0; h &lt; 12; ++h) &#123;
for (int m &#x3D; 0; m &lt; 60; ++m) &#123;
if (bitset&lt;10&gt;((h &lt;&lt; 6) + m).count() &#x3D;&#x3D; num) &#123;
res.push_back(to_string(h) + (m &lt; 10 ? &quot;:0&quot; : &quot;:&quot;) + to_string(m));
&#125;
&#125;
&#125;
return res;
&#125;
&#125;;<span aria-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></code></pre>
</div>
@ -315,10 +323,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
@ -447,7 +455,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Example"><span class="nav-number">1.1.</span> <span class="nav-text">Example:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Note"><span class="nav-number">1.2.</span> <span class="nav-text">Note:</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#题解"><span class="nav-number">2.</span> <span class="nav-text">题解</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">2.1.</span> <span class="nav-text">Code</span></a></li></ol></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Example"><span class="nav-number">1.1.</span> <span class="nav-text">Example:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Note"><span class="nav-number">1.2.</span> <span class="nav-text">Note:</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A2%98%E8%A7%A3"><span class="nav-number">2.</span> <span class="nav-text">题解</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">2.1.</span> <span class="nav-text">Code</span></a></li></ol></li></ol></div>
</div>
<!--/noindex-->


+ 30
- 14
2016/10/11/minimum-size-subarray-sum-209/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2016/10/11/minimum-size-subarray-sum-209/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2016-10-11T14:04:28.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2016-10-11T14:04:28.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2016-10-11 22:04:28" itemprop="dateCreated datePublished" datetime="2016-10-11T22:04:28+08:00">2016-10-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -287,8 +281,30 @@
<h3 id="problem"><a href="#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>
<h4 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h4><p>参考,滑动窗口,跟之前Data Structure课上的online算法有点像,<a href="http://blog.csdn.net/lisonglisonglisong/article/details/45666975" target="_blank" rel="noopener">链接</a> </p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">minSubArrayLen</span><span class="params">(<span class="keyword">int</span> s, <span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">int</span> len = nums.<span class="built_in">size</span>();</span><br><span class="line"> <span class="keyword">if</span>(len == <span class="number">0</span>) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> minlen = INT_MAX;</span><br><span class="line"> <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> right = <span class="number">-1</span>;</span><br><span class="line"> <span class="keyword">while</span>(right &lt; len)</span><br><span class="line"> &#123;</span><br><span class="line"> <span class="keyword">while</span>(sum &lt; s &amp;&amp; right &lt; len)</span><br><span class="line"> sum += nums[++right];</span><br><span class="line"> <span class="keyword">if</span>(sum &gt;= s)</span><br><span class="line"> &#123;</span><br><span class="line"> minlen = minlen &lt; right - left + <span class="number">1</span> ? minlen : right - left + <span class="number">1</span>;</span><br><span class="line"> sum -= nums[left++];</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> minlen &gt; len ? <span class="number">0</span> : minlen;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h4 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h4><p>参考,滑动窗口,跟之前Data Structure课上的online算法有点像,<a target="_blank" rel="noopener" href="http://blog.csdn.net/lisonglisonglisong/article/details/45666975">链接</a> </p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
int minSubArrayLen(int s, vector&lt;int&gt;&amp; nums) &#123;
int len &#x3D; nums.size();
if(len &#x3D;&#x3D; 0) return 0;
int minlen &#x3D; INT_MAX;
int sum &#x3D; 0;
int left &#x3D; 0;
int right &#x3D; -1;
while(right &lt; len)
&#123;
while(sum &lt; s &amp;&amp; right &lt; len)
sum +&#x3D; nums[++right];
if(sum &gt;&#x3D; s)
&#123;
minlen &#x3D; minlen &lt; right - left + 1 ? minlen : right - left + 1;
sum -&#x3D; nums[left++];
&#125;
&#125;
return minlen &gt; len ? 0 : minlen;
&#125;
&#125;;<span aria-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>
</div>
@ -305,10 +321,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
@ -437,7 +453,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#题解"><span class="nav-number">1.1.</span> <span class="nav-text">题解</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">1.2.</span> <span class="nav-text">Code</span></a></li></ol></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#%E9%A2%98%E8%A7%A3"><span class="nav-number">1.1.</span> <span class="nav-text">题解</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">1.2.</span> <span class="nav-text">Code</span></a></li></ol></li></ol></div>
</div>
<!--/noindex-->


+ 22
- 14
2016/10/12/summary-ranges-228/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2016/10/12/summary-ranges-228/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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 [&quot;0-&gt;2&quot;,&quot;4-&gt;5&quot;,&quot;7&quot;]. 题解每一个区间的起点nu">
<meta property="og:locale">
<meta property="article:published_time" content="2016-10-12T15:25:17.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2016-10-12T15:25:17.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="c++">
@ -229,13 +230,6 @@
<time title="Created: 2016-10-12 23:25:17" itemprop="dateCreated datePublished" datetime="2016-10-12T23:25:17+08:00">2016-10-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -287,8 +281,22 @@
<h4 id="problem"><a href="#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>[&quot;0-&gt;2&quot;,&quot;4-&gt;5&quot;,&quot;7&quot;]</code>.</p>
<h4 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h4><p>每一个区间的起点<code>nums[i]</code>加上<code>j</code>是否等于<code>nums[i+j]</code><br><a href="http://www.cnblogs.com/grandyang/p/4603555.html" target="_blank" rel="noopener">参考</a></p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> &#123;</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; <span class="title">summaryRanges</span><span class="params">(<span class="built_in">vector</span>&lt;<span class="keyword">int</span>&gt;&amp; nums)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>, j = <span class="number">1</span>, n;</span><br><span class="line"> <span class="built_in">vector</span>&lt;<span class="built_in">string</span>&gt; res;</span><br><span class="line"> n = nums.<span class="built_in">size</span>();</span><br><span class="line"> <span class="keyword">while</span>(i &lt; n)&#123;</span><br><span class="line"> j = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(j &lt; n &amp;&amp; nums[i+j] - nums[i] == j) j++;</span><br><span class="line"> res.push_back(j &lt;= <span class="number">1</span> ? to_string(nums[i]) : to_string(nums[i]) + <span class="string">"-&gt;"</span> + to_string(nums[i + j - <span class="number">1</span>]));</span><br><span class="line"> i += j;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> res;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<h4 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h4><p>每一个区间的起点<code>nums[i]</code>加上<code>j</code>是否等于<code>nums[i+j]</code><br><a target="_blank" rel="noopener" href="http://www.cnblogs.com/grandyang/p/4603555.html">参考</a></p>
<h4 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h4><pre class="line-numbers language-C++" data-language="C++"><code class="language-C++">class Solution &#123;
public:
vector&lt;string&gt; summaryRanges(vector&lt;int&gt;&amp; nums) &#123;
int i &#x3D; 0, j &#x3D; 1, n;
vector&lt;string&gt; res;
n &#x3D; nums.size();
while(i &lt; n)&#123;
j &#x3D; 1;
while(j &lt; n &amp;&amp; nums[i+j] - nums[i] &#x3D;&#x3D; j) j++;
res.push_back(j &lt;&#x3D; 1 ? to_string(nums[i]) : to_string(nums[i]) + &quot;-&gt;&quot; + to_string(nums[i + j - 1]));
i +&#x3D; j;
&#125;
return res;
&#125;
&#125;;<span aria-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></code></pre>
</div>
@ -304,10 +312,10 @@
<div class="popular-posts-title"><a href="/2016/08/14/34-Search-for-a-Range/" rel="bookmark">34_Search_for_a_Range</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/03/11/Number-Of-1-Bits/" rel="bookmark">Number of 1 Bits</a></div>
<div class="popular-posts-title"><a href="/2015/04/14/Add-Two-Number/" rel="bookmark">add-two-number</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2015/01/04/Path-Sum/" rel="bookmark">Path Sum</a></div>
@ -436,7 +444,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#题解"><span class="nav-number">2.</span> <span class="nav-text">题解</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">3.</span> <span class="nav-text">Code</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#problem"><span class="nav-number">1.</span> <span class="nav-text">problem</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E9%A2%98%E8%A7%A3"><span class="nav-number">2.</span> <span class="nav-text">题解</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Code"><span class="nav-number">3.</span> <span class="nav-text">Code</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 38
- 15
2016/11/10/php-abstract-class-and-interface/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,14 +26,15 @@
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>
<meta name="description" content="PHP抽象类和接口 抽象类与接口 抽象类内可以包含非抽象函数,即可实现函数 抽象类内必须包含至少一个抽象方法,抽象类和接口均不能实例化 抽象类可以设置访问级别,接口默认都是public 类可以实现多个接口但不能继承多个抽象类 类必须实现抽象类和接口里的抽象方法,不一定要实现抽象类的非抽象方法 接口内不能定义变量,但是可以定义常量 示例代码12345678910111213141516171819">
<meta name="description" content="PHP抽象类和接口 抽象类与接口 抽象类内可以包含非抽象函数,即可实现函数 抽象类内必须包含至少一个抽象方法,抽象类和接口均不能实例化 抽象类可以设置访问级别,接口默认都是public 类可以实现多个接口但不能继承多个抽象类 类必须实现抽象类和接口里的抽象方法,不一定要实现抽象类的非抽象方法 接口内不能定义变量,但是可以定义常量 示例代码&lt;?php interface int1&amp;#123;">
<meta property="og:type" content="article">
<meta property="og:title" content="php-abstract-class-and-interface">
<meta property="og:url" content="https://nicksxs.me/2016/11/10/php-abstract-class-and-interface/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="PHP抽象类和接口 抽象类与接口 抽象类内可以包含非抽象函数,即可实现函数 抽象类内必须包含至少一个抽象方法,抽象类和接口均不能实例化 抽象类可以设置访问级别,接口默认都是public 类可以实现多个接口但不能继承多个抽象类 类必须实现抽象类和接口里的抽象方法,不一定要实现抽象类的非抽象方法 接口内不能定义变量,但是可以定义常量 示例代码12345678910111213141516171819">
<meta property="og:description" content="PHP抽象类和接口 抽象类与接口 抽象类内可以包含非抽象函数,即可实现函数 抽象类内必须包含至少一个抽象方法,抽象类和接口均不能实例化 抽象类可以设置访问级别,接口默认都是public 类可以实现多个接口但不能继承多个抽象类 类必须实现抽象类和接口里的抽象方法,不一定要实现抽象类的非抽象方法 接口内不能定义变量,但是可以定义常量 示例代码&lt;?php interface int1&amp;#123;">
<meta property="og:locale">
<meta property="article:published_time" content="2016-11-10T02:42:35.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2016-11-10T02:42:35.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="php">
<meta name="twitter:card" content="summary">
@ -228,13 +229,6 @@
<time title="Created: 2016-11-10 10:42:35" itemprop="dateCreated datePublished" datetime="2016-11-10T10:42:35+08:00">2016-11-10</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -293,9 +287,38 @@
<li>类必须实现抽象类和接口里的抽象方法,不一定要实现抽象类的非抽象方法</li>
<li>接口内不能定义变量,但是可以定义常量</li>
</ul>
<h2 id="示例代码"><a href="#示例代码" class="headerlink" title="示例代码"></a>示例代码</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">&lt;?php</span><br><span class="line">interface int1&#123;</span><br><span class="line"> const INTER1 &#x3D; 111;</span><br><span class="line"> function inter1();</span><br><span class="line">&#125;</span><br><span class="line">interface int2&#123;</span><br><span class="line"> const INTER1 &#x3D; 222;</span><br><span class="line"> function inter2();</span><br><span class="line">&#125;</span><br><span class="line">abstract class abst1&#123;</span><br><span class="line"> public function abstr1()&#123;</span><br><span class="line"> echo 1111;</span><br><span class="line"> &#125;</span><br><span class="line"> abstract function abstra1()&#123;</span><br><span class="line"> echo &#39;ahahahha&#39;;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line">abstract class abst2&#123;</span><br><span class="line"> public function abstr2()&#123;</span><br><span class="line"> echo 1111;</span><br><span class="line"> &#125;</span><br><span class="line"> abstract function abstra2();</span><br><span class="line">&#125;</span><br><span class="line">class normal1 extends abst1&#123;</span><br><span class="line"> protected function abstr2()&#123;</span><br><span class="line"> echo 222;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="result"><a href="#result" class="headerlink" title="result"></a>result</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">PHP Fatal error: Abstract function abst1::abstra1() cannot contain body in new.php on line 17</span><br><span class="line"></span><br><span class="line">Fatal error: Abstract function abst1::abstra1() cannot contain body in php on line 17</span><br></pre></td></tr></table></figure>
<h2 id="示例代码"><a href="#示例代码" class="headerlink" title="示例代码"></a>示例代码</h2><pre class="line-numbers language-none"><code class="language-none">&lt;?php
interface int1&#123;
const INTER1 &#x3D; 111;
function inter1();
&#125;
interface int2&#123;
const INTER1 &#x3D; 222;
function inter2();
&#125;
abstract class abst1&#123;
public function abstr1()&#123;
echo 1111;
&#125;
abstract function abstra1()&#123;
echo &#39;ahahahha&#39;;
&#125;
&#125;
abstract class abst2&#123;
public function abstr2()&#123;
echo 1111;
&#125;
abstract function abstra2();
&#125;
class normal1 extends abst1&#123;
protected function abstr2()&#123;
echo 222;
&#125;
&#125;<span aria-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></span></span></code></pre>
<h2 id="result"><a href="#result" class="headerlink" title="result"></a>result</h2><pre class="line-numbers language-none"><code class="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<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
</div>
@ -431,7 +454,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#PHP抽象类和接口"><span class="nav-number">1.</span> <span class="nav-text">PHP抽象类和接口</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#示例代码"><span class="nav-number">2.</span> <span class="nav-text">示例代码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#result"><span class="nav-number">3.</span> <span class="nav-text">result</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#PHP%E6%8A%BD%E8%B1%A1%E7%B1%BB%E5%92%8C%E6%8E%A5%E5%8F%A3"><span class="nav-number">1.</span> <span class="nav-text">PHP抽象类和接口</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81"><span class="nav-number">2.</span> <span class="nav-text">示例代码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#result"><span class="nav-number">3.</span> <span class="nav-text">result</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 13
- 12
2017/03/28/spark-little-tips/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2017/03/28/spark-little-tips/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="spark 的一些粗浅使用经验工作中学习使用了一下Spark做数据分析,主要是用spark的python接口,首先是pyspark.SparkContext(appName&#x3D;xxx),这是初始化一个Spark应用实例或者说会话,不能重复,返回的实例句柄就可以调用textFile(path)读取文本文件,这里的文本文件可以是HDFS上的文本文件,也可以普通文本文件,但是需要在Spark的所有集群上都">
<meta property="og:locale">
<meta property="article:published_time" content="2017-03-28T11:20:56.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2017-03-28T11:20:56.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="spark">
<meta property="article:tag" content="python">
@ -229,13 +230,6 @@
<time title="Created: 2017-03-28 19:20:56" itemprop="dateCreated datePublished" datetime="2017-03-28T19:20:56+08:00">2017-03-28</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -286,10 +280,17 @@
<h2 id="spark-的一些粗浅使用经验"><a href="#spark-的一些粗浅使用经验" class="headerlink" title="spark 的一些粗浅使用经验"></a>spark 的一些粗浅使用经验</h2><p>工作中学习使用了一下Spark做数据分析,主要是用spark的python接口,首先是<code>pyspark.SparkContext(appName=xxx)</code>,这是初始化一个Spark应用实例或者说会话,不能重复,<br>返回的实例句柄就可以调用<code>textFile(path)</code>读取文本文件,这里的文本文件可以是HDFS上的文本文件,也可以普通文本文件,但是需要在Spark的所有集群上都存在,否则会<br>读取失败,<code>parallelize</code>则可以将python生成的集合数据读取后转换成rdd(A Resilient Distributed Dataset (RDD),一种spark下的基本抽象数据集),基于这个RDD就可以做<br>数据的流式计算,例如<code>map reduce</code>,在Spark中可以非常方便地实现 </p>
<h3 id="简单的mapreduce-word-count示例"><a href="#简单的mapreduce-word-count示例" class="headerlink" title="简单的mapreduce word count示例"></a>简单的mapreduce word count示例</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">textFile = sc.parallelize([(<span class="number">1</span>,<span class="number">1</span>), (<span class="number">2</span>,<span class="number">1</span>), (<span class="number">3</span>,<span class="number">1</span>), (<span class="number">4</span>,<span class="number">1</span>), (<span class="number">5</span>,<span class="number">1</span>),(<span class="number">1</span>,<span class="number">1</span>), (<span class="number">2</span>,<span class="number">1</span>), (<span class="number">3</span>,<span class="number">1</span>), (<span class="number">4</span>,<span class="number">1</span>), (<span class="number">5</span>,<span class="number">1</span>)])</span><br><span class="line">data = textFile.reduceByKey(<span class="keyword">lambda</span> x, y: x + y).collect()</span><br><span class="line"><span class="keyword">for</span> _ <span class="keyword">in</span> data:</span><br><span class="line"> print(_)</span><br></pre></td></tr></table></figure>
<h3 id="简单的mapreduce-word-count示例"><a href="#简单的mapreduce-word-count示例" class="headerlink" title="简单的mapreduce word count示例"></a>简单的mapreduce word count示例</h3><pre class="line-numbers language-Python" data-language="Python"><code class="language-Python">textFile &#x3D; sc.parallelize([(1,1), (2,1), (3,1), (4,1), (5,1),(1,1), (2,1), (3,1), (4,1), (5,1)])
data &#x3D; textFile.reduceByKey(lambda x, y: x + y).collect()
for _ in data:
print(_)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h3 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">(3, 2)</span><br><span class="line">(1, 2)</span><br><span class="line">(4, 2)</span><br><span class="line">(2, 2)</span><br><span class="line">(5, 2)</span><br></pre></td></tr></table></figure>
<h3 id="结果"><a href="#结果" class="headerlink" title="结果"></a>结果</h3><pre class="line-numbers language-none"><code class="language-none">(3, 2)
(1, 2)
(4, 2)
(2, 2)
(5, 2)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</div>
@ -420,7 +421,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#spark-的一些粗浅使用经验"><span class="nav-number">1.</span> <span class="nav-text">spark 的一些粗浅使用经验</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#简单的mapreduce-word-count示例"><span class="nav-number">1.1.</span> <span class="nav-text">简单的mapreduce word count示例</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#结果"><span class="nav-number">1.2.</span> <span class="nav-text">结果</span></a></li></ol></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#spark-%E7%9A%84%E4%B8%80%E4%BA%9B%E7%B2%97%E6%B5%85%E4%BD%BF%E7%94%A8%E7%BB%8F%E9%AA%8C"><span class="nav-number">1.</span> <span class="nav-text">spark 的一些粗浅使用经验</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E7%9A%84mapreduce-word-count%E7%A4%BA%E4%BE%8B"><span class="nav-number">1.1.</span> <span class="nav-text">简单的mapreduce word count示例</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BB%93%E6%9E%9C"><span class="nav-number">1.2.</span> <span class="nav-text">结果</span></a></li></ol></li></ol></div>
</div>
<!--/noindex-->


+ 18
- 15
2017/04/25/rabbitmq-tips/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2017/04/25/rabbitmq-tips/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="rabbitmq 介绍接触了一下rabbitmq,原来在选型的时候是在rabbitmq跟kafka之间做选择,网上搜了一下之后发现kafka的优势在于吞吐量,而rabbitmq相对注重可靠性,因为应用在im上,需要保证消息不能丢失所以就暂时选定rabbitmq,Message Queue的需求由来已久,80年代最早在金融交易中,高盛等公司采用Teknekron公司的产品,当时的Message qu">
<meta property="og:locale">
<meta property="article:published_time" content="2017-04-25T13:46:55.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:26.000Z">
<meta property="article:modified_time" content="2017-04-25T13:46:55.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="php">
<meta property="article:tag" content="mq">
@ -230,13 +231,6 @@
<time title="Created: 2017-04-25 21:46:55" itemprop="dateCreated datePublished" datetime="2017-04-25T21:46:55+08:00">2017-04-25</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:26" itemprop="dateModified" datetime="2020-01-12T21:08:26+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -286,14 +280,23 @@
<div class="post-body" itemprop="articleBody">
<h2 id="rabbitmq-介绍"><a href="#rabbitmq-介绍" class="headerlink" title="rabbitmq 介绍"></a>rabbitmq 介绍</h2><p>接触了一下rabbitmq,原来在选型的时候是在rabbitmq跟kafka之间做选择,网上搜了一下之后发现kafka的优势在于吞吐量,而rabbitmq相对注重可靠性,因为应用在im上,需要保证消息不能丢失所以就暂时选定rabbitmq,<br>Message Queue的需求由来已久,80年代最早在金融交易中,高盛等公司采用Teknekron公司的产品,当时的Message queuing软件叫做:the information bus(TIB)。 TIB被电信和通讯公司采用,路透社收购了Teknekron公司。之后,IBM开发了MQSeries,微软开发了Microsoft Message Queue(MSMQ)。这些商业MQ供应商的问题是厂商锁定,价格高昂。2001年,Java Message queuing试图解决锁定和交互性的问题,但对应用来说反而更加麻烦了。<br>RabbitMQ采用Erlang语言开发。Erlang语言由Ericson设计,专门为开发concurrent和distribution系统的一种语言,在电信领域使用广泛。OTP(Open Telecom Platform)作为Erlang语言的一部分,包含了很多基于Erlang开发的中间件/库/工具,如mnesia/SASL,极大方便了Erlang应用的开发。OTP就类似于Python语言中众多的module,用户借助这些module可以很方便的开发应用。<br>于是2004年,摩根大通和iMatrix开始着手<a href="https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol" target="_blank" rel="noopener">Advanced Message Queuing Protocol (AMQP)</a>开放标准的开发。2006年,AMQP规范发布。2007年,Rabbit技术公司基于AMQP标准开发的RabbitMQ 1.0 发布。所有主要的编程语言均有与代理接口通讯的客户端库。</p>
<h2 id="rabbitmq-介绍"><a href="#rabbitmq-介绍" class="headerlink" title="rabbitmq 介绍"></a>rabbitmq 介绍</h2><p>接触了一下rabbitmq,原来在选型的时候是在rabbitmq跟kafka之间做选择,网上搜了一下之后发现kafka的优势在于吞吐量,而rabbitmq相对注重可靠性,因为应用在im上,需要保证消息不能丢失所以就暂时选定rabbitmq,<br>Message Queue的需求由来已久,80年代最早在金融交易中,高盛等公司采用Teknekron公司的产品,当时的Message queuing软件叫做:the information bus(TIB)。 TIB被电信和通讯公司采用,路透社收购了Teknekron公司。之后,IBM开发了MQSeries,微软开发了Microsoft Message Queue(MSMQ)。这些商业MQ供应商的问题是厂商锁定,价格高昂。2001年,Java Message queuing试图解决锁定和交互性的问题,但对应用来说反而更加麻烦了。<br>RabbitMQ采用Erlang语言开发。Erlang语言由Ericson设计,专门为开发concurrent和distribution系统的一种语言,在电信领域使用广泛。OTP(Open Telecom Platform)作为Erlang语言的一部分,包含了很多基于Erlang开发的中间件/库/工具,如mnesia/SASL,极大方便了Erlang应用的开发。OTP就类似于Python语言中众多的module,用户借助这些module可以很方便的开发应用。<br>于是2004年,摩根大通和iMatrix开始着手<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol">Advanced Message Queuing Protocol (AMQP)</a>开放标准的开发。2006年,AMQP规范发布。2007年,Rabbit技术公司基于AMQP标准开发的RabbitMQ 1.0 发布。所有主要的编程语言均有与代理接口通讯的客户端库。</p>
<h2 id="简单的使用经验"><a href="#简单的使用经验" class="headerlink" title="简单的使用经验"></a>简单的使用经验</h2><h3 id="通俗的理解"><a href="#通俗的理解" class="headerlink" title="通俗的理解"></a>通俗的理解</h3><p>这里介绍下其中的一些概念,connection表示和队列服务器的连接,一般情况下是tcp连接, channel表示通道,可以在一个连接上建立多个通道,这里主要是节省了tcp连接握手的成本,exchange可以理解成一个路由器,将消息推送给对应的队列queue,其实是像一个订阅的模式。</p>
<h3 id="集群经验"><a href="#集群经验" class="headerlink" title="集群经验"></a>集群经验</h3><p><code>rabbitmqctl stop</code>这个是关闭rabbitmq,在搭建集群时候先关闭服务,然后使用<code>rabbitmq-server -detached</code>静默启动,这时候使用<code>rabbitmqctl cluster_status</code>查看集群状态,因为还没将节点加入集群,所以只能看到类似</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Cluster status of node rabbit@rabbit1 ...</span><br><span class="line">[&#123;nodes,[&#123;disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]&#125;]&#125;,</span><br><span class="line"> &#123;running_nodes,[rabbit@rabbit2,rabbit@rabbit1]&#125;]</span><br><span class="line">...done.</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">Cluster status of node rabbit@rabbit1 ...
[&#123;nodes,[&#123;disc,[rabbit@rabbit1,rabbit@rabbit2,rabbit@rabbit3]&#125;]&#125;,
&#123;running_nodes,[rabbit@rabbit2,rabbit@rabbit1]&#125;]
...done.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>然后就可以把当前节点加入集群,</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">rabbit2$</span><span class="bash"> rabbitmqctl stop_app <span class="comment">#这个stop_app与stop的区别是前者停的是rabbitmq应用,保留erlang节点,</span></span></span><br><span class="line"> #后者是停止了rabbitmq和erlang节点</span><br><span class="line">Stopping node rabbit@rabbit2 ...done.</span><br><span class="line"><span class="meta">rabbit2$</span><span class="bash"> rabbitmqctl join_cluster rabbit@rabbit1 <span class="comment">#这里可以用--ram指定将当前节点作为内存节点加入集群</span></span></span><br><span class="line">Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.</span><br><span class="line"><span class="meta">rabbit2$</span><span class="bash"> rabbitmqctl start_app</span></span><br><span class="line">Starting node rabbit@rabbit2 ...done.</span><br></pre></td></tr></table></figure>
<p>其他可以参考<a href="http://www.rabbitmq.com/clustering.html" target="_blank" rel="noopener">官方文档</a></p>
<h2 id="一些坑"><a href="#一些坑" class="headerlink" title="一些坑"></a>一些坑</h2><h3 id="消息丢失"><a href="#消息丢失" 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 &quot;orange&quot; or &quot;quick.orange.male.rabbit&quot;? Well, these messages won&#39;t match any bindings and will be lost.</code><a href="http://www.rabbitmq.com/tutorials/tutorial-five-python.html" target="_blank" rel="noopener">对应链接</a>,而当使用空的exchange时,会保留消息,当出现消费者的时候就可以将收到之前生产者所推送的消息<a href="http://www.rabbitmq.com/tutorials/tutorial-two-python.html" target="_blank" rel="noopener">对应链接</a>,这里就是用了空的exchange。</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">rabbit2$ rabbitmqctl stop_app #这个stop_app与stop的区别是前者停的是rabbitmq应用,保留erlang节点,
#后者是停止了rabbitmq和erlang节点
Stopping node rabbit@rabbit2 ...done.
rabbit2$ rabbitmqctl join_cluster rabbit@rabbit1 #这里可以用--ram指定将当前节点作为内存节点加入集群
Clustering node rabbit@rabbit2 with [rabbit@rabbit1] ...done.
rabbit2$ rabbitmqctl start_app
Starting node rabbit@rabbit2 ...done.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>其他可以参考<a target="_blank" rel="noopener" href="http://www.rabbitmq.com/clustering.html">官方文档</a></p>
<h2 id="一些坑"><a href="#一些坑" class="headerlink" title="一些坑"></a>一些坑</h2><h3 id="消息丢失"><a href="#消息丢失" 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 &quot;orange&quot; or &quot;quick.orange.male.rabbit&quot;? Well, these messages won&#39;t match any bindings and will be lost.</code><a target="_blank" rel="noopener" href="http://www.rabbitmq.com/tutorials/tutorial-five-python.html">对应链接</a>,而当使用空的exchange时,会保留消息,当出现消费者的时候就可以将收到之前生产者所推送的消息<a target="_blank" rel="noopener" href="http://www.rabbitmq.com/tutorials/tutorial-two-python.html">对应链接</a>,这里就是用了空的exchange。</p>
<h3 id="集群搭建"><a href="#集群搭建" class="headerlink" title="集群搭建"></a>集群搭建</h3><p>集群搭建的时候有个erlang vm生成的random cookie,这个是用来做集群之间认证的,相同的cookie才能连接,但是如果通过vim打开复制后在其他几点新建文件写入会多一个换行,导致集群建立是报错,所以这里最好使用scp等传输命令直接传输cookie文件,同时要注意下cookie的文件权限。<br>另外在集群搭建的时候如果更改过hostname,那么要把rabbitmq的数据库删除,否则启动后会马上挂掉</p>
</div>
@ -432,7 +435,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#rabbitmq-介绍"><span class="nav-number">1.</span> <span class="nav-text">rabbitmq 介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#简单的使用经验"><span class="nav-number">2.</span> <span class="nav-text">简单的使用经验</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#通俗的理解"><span class="nav-number">2.1.</span> <span class="nav-text">通俗的理解</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#集群经验"><span class="nav-number">2.2.</span> <span class="nav-text">集群经验</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#一些坑"><span class="nav-number">3.</span> <span class="nav-text">一些坑</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#消息丢失"><span class="nav-number">3.1.</span> <span class="nav-text">消息丢失</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#集群搭建"><span class="nav-number">3.2.</span> <span class="nav-text">集群搭建</span></a></li></ol></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#rabbitmq-%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">rabbitmq 介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E7%9A%84%E4%BD%BF%E7%94%A8%E7%BB%8F%E9%AA%8C"><span class="nav-number">2.</span> <span class="nav-text">简单的使用经验</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%80%9A%E4%BF%97%E7%9A%84%E7%90%86%E8%A7%A3"><span class="nav-number">2.1.</span> <span class="nav-text">通俗的理解</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%9B%86%E7%BE%A4%E7%BB%8F%E9%AA%8C"><span class="nav-number">2.2.</span> <span class="nav-text">集群经验</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E4%BA%9B%E5%9D%91"><span class="nav-number">3.</span> <span class="nav-text">一些坑</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B6%88%E6%81%AF%E4%B8%A2%E5%A4%B1"><span class="nav-number">3.1.</span> <span class="nav-text">消息丢失</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA"><span class="nav-number">3.2.</span> <span class="nav-text">集群搭建</span></a></li></ol></li></ol></div>
</div>
<!--/noindex-->


+ 8
- 14
2017/05/09/ambari-summary/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2017/05/09/ambari-summary/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="初识ambariambari是一个大数据平台的管理工具,包含了hadoop, yarn, hive, hbase, spark等大数据的基础架构和工具,简化了数据平台的搭建,之前只是在同事搭建好平台后的一些使用,这次有机会从头开始用ambari来搭建一个测试的数据平台,过程中也踩到不少坑,简单记录下。 简单过程 第一个坑在刚开始是按照官网的指南,用maven构建,因为GFW的原因,导致反复失败等待">
<meta property="og:locale">
<meta property="article:published_time" content="2017-05-09T15:53:05.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2017-05-09T15:53:05.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="hadoop">
<meta property="article:tag" content="cluster">
@ -229,13 +230,6 @@
<time title="Created: 2017-05-09 23:53:05" itemprop="dateCreated datePublished" datetime="2017-05-09T23:53:05+08:00">2017-05-09</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -285,12 +279,12 @@
<div class="post-body" itemprop="articleBody">
<h2 id="初识ambari"><a href="#初识ambari" class="headerlink" title="初识ambari"></a>初识ambari</h2><p><a href="http://ambari.apache.org/" target="_blank" rel="noopener">ambari</a>是一个大数据平台的管理工具,包含了<code>hadoop</code>, <code>yarn</code>, <code>hive</code>, <code>hbase</code>, <code>spark</code>等大数据的基础架构和工具,简化了数据平台的搭建,之前只是在同事搭建好平台后的一些使用,这次有机会从头开始用<code>ambari</code>来搭建一个测试的数据平台,过程中也踩到不少坑,简单记录下。</p>
<h2 id="初识ambari"><a href="#初识ambari" class="headerlink" title="初识ambari"></a>初识ambari</h2><p><a target="_blank" rel="noopener" href="http://ambari.apache.org/">ambari</a>是一个大数据平台的管理工具,包含了<code>hadoop</code>, <code>yarn</code>, <code>hive</code>, <code>hbase</code>, <code>spark</code>等大数据的基础架构和工具,简化了数据平台的搭建,之前只是在同事搭建好平台后的一些使用,这次有机会从头开始用<code>ambari</code>来搭建一个测试的数据平台,过程中也踩到不少坑,简单记录下。</p>
<h2 id="简单过程"><a href="#简单过程" class="headerlink" title="简单过程"></a>简单过程</h2><ul>
<li>第一个坑<br>在刚开始是按照官网的指南,用maven构建,因为GFW的原因,导致反复失败等待,也就是这个<a href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.0" target="_blank" rel="noopener">guide</a>,因为对maven不熟悉导致有些按图索骥,浪费了很多时间,之后才知道可以直接加repo用yum安装,然而用yum安装马上就出现了第二个坑。</li>
<li>第二个坑<br>因为在线的repo还是因为网络原因很慢很慢,用proxychains勉强把ambari-server本身安装好了,<a href="http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.5.0.3/ambari.repo" target="_blank" rel="noopener">ambari.repo</a>将这个放进<code>/etc/yum.repos.d/</code>路径下,然后<code>yum update &amp;&amp; yum install ambari-server</code>安装即可,如果有条件就用proxychains走下代理。</li>
<li>第一个坑<br>在刚开始是按照官网的指南,用maven构建,因为GFW的原因,导致反复失败等待,也就是这个<a target="_blank" rel="noopener" href="https://cwiki.apache.org/confluence/display/AMBARI/Installation+Guide+for+Ambari+2.5.0">guide</a>,因为对maven不熟悉导致有些按图索骥,浪费了很多时间,之后才知道可以直接加repo用yum安装,然而用yum安装马上就出现了第二个坑。</li>
<li>第二个坑<br>因为在线的repo还是因为网络原因很慢很慢,用proxychains勉强把ambari-server本身安装好了,<a target="_blank" rel="noopener" href="http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.5.0.3/ambari.repo">ambari.repo</a>将这个放进<code>/etc/yum.repos.d/</code>路径下,然后<code>yum update &amp;&amp; yum install ambari-server</code>安装即可,如果有条件就用proxychains走下代理。</li>
<li>第三步<br>安装好ambari-server后先执行<code>ambari-server setup</code>做一些初始化设置,其中包含了JDK路径的设置,数据库设置,设置好就OK了,然后执行<code>ambari-server start</code>启动服务,这里有个小插曲,因为<code>ambari-server</code>涉及到这么多服务,所以管理控制监控之类的模块是必不可少的,这部分可以在<code>ambari-server</code>的web ui界面安装,也可以命令行提前安装,这部分被称为<code>HDF Management Pack</code>,运行```ambari-server install-mpack \</li>
<li>-mpack=<a href="http://public-repo-1.hortonworks.com/HDF/centos7/2.x/updates/2.1.4.0/tars/hdf_ambari_mp/hdf-ambari-mpack-2.1.4.0-5.tar.gz" target="_blank" rel="noopener">http://public-repo-1.hortonworks.com/HDF/centos7/2.x/updates/2.1.4.0/tars/hdf_ambari_mp/hdf-ambari-mpack-2.1.4.0-5.tar.gz</a> \</li>
<li>-mpack=<a target="_blank" rel="noopener" href="http://public-repo-1.hortonworks.com/HDF/centos7/2.x/updates/2.1.4.0/tars/hdf_ambari_mp/hdf-ambari-mpack-2.1.4.0-5.tar.gz">http://public-repo-1.hortonworks.com/HDF/centos7/2.x/updates/2.1.4.0/tars/hdf_ambari_mp/hdf-ambari-mpack-2.1.4.0-5.tar.gz</a> \</li>
<li>-purge \</li>
<li>-verbose```<br>安装,当然这个压缩包可以下载之后指到本地路径安装,然后就可以重启<code>ambari-server</code></li>
</ul>
@ -424,7 +418,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#初识ambari"><span class="nav-number">1.</span> <span class="nav-text">初识ambari</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#简单过程"><span class="nav-number">2.</span> <span class="nav-text">简单过程</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%9D%E8%AF%86ambari"><span class="nav-number">1.</span> <span class="nav-text">初识ambari</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E8%BF%87%E7%A8%8B"><span class="nav-number">2.</span> <span class="nav-text">简单过程</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 32
- 16
2019/06/18/openresty/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2019/06/18/openresty/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="目前公司要对一些新的产品功能做灰度测试,因为在后端业务代码层面添加判断比较麻烦,所以想在nginx上做点手脚,就想到了openresty前后也踩了不少坑,这边先写一点 首先是日志error_log logs&#x2F;error.log debug;需要nginx开启日志的debug才能看到日志 使用 lua_code_cache off即可, 另外注意只有使用 content_by_lua_file 才会">
<meta property="og:locale">
<meta property="article:published_time" content="2019-06-18T11:03:05.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2019-06-18T11:03:05.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="openresty">
<meta property="article:tag" content="nginx">
@ -229,13 +230,6 @@
<time title="Created: 2019-06-18 19:03:05" itemprop="dateCreated datePublished" datetime="2019-06-18T19:03:05+08:00">2019-06-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -288,13 +282,20 @@
<p>目前公司要对一些新的产品功能做灰度测试,因为在后端业务代码层面添加判断比较麻烦,所以想在nginx上做点手脚,就想到了openresty<br>前后也踩了不少坑,这边先写一点</p>
<p>首先是日志<br><code>error_log logs/error.log debug;</code><br>需要nginx开启日志的debug才能看到日志</p>
<p>使用 <code>lua_code_cache off</code>即可, 另外注意只有使用 <code>content_by_lua_file</code> 才会生效</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">http &#123;</span><br><span class="line"> lua_code_cache off;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">location ~* /(\d+-.*)/api/orgunits/load_all(.*) &#123;</span><br><span class="line"> default_type <span class="string">'application/json;charset=utf-8'</span>;</span><br><span class="line"> content_by_lua_file /data/projects/xxx/current/lua/controller/load_data.lua;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-lua" data-language="lua"><code class="language-lua"><span class="token function">http</span> <span class="token punctuation">&#123;</span>
lua_code_cache off<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
location <span class="token operator">~</span><span class="token operator">*</span> <span class="token operator">/</span><span class="token punctuation">(</span>\d<span class="token operator">+</span><span class="token operator">-</span><span class="token punctuation">.</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token operator">/</span>api<span class="token operator">/</span>orgunits<span class="token operator">/</span><span class="token function">load_all</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
default_type <span class="token string">'application/json;charset=utf-8'</span><span class="token punctuation">;</span>
content_by_lua_file <span class="token operator">/</span>data<span class="token operator">/</span>projects<span class="token operator">/</span>xxx<span class="token operator">/</span>current<span class="token operator">/</span>lua<span class="token operator">/</span>controller<span class="token operator">/</span>load_data<span class="token punctuation">.</span>lua<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>使用lua给nginx请求response头添加内容可以用这个</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ngx.header[<span class="string">'response'</span>] = <span class="string">'header'</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-lua" data-language="lua"><code class="language-lua">ngx<span class="token punctuation">.</span>header<span class="token punctuation">[</span><span class="token string">'response'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'header'</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><a href="http://cyukang.com/2017/05/22/try-on-openresty.html" target="_blank" rel="noopener">使用总结</a></p>
<p><a target="_blank" rel="noopener" href="http://cyukang.com/2017/05/22/try-on-openresty.html">使用总结</a></p>
<p>后续:</p>
<ol>
<li>一开始在本地环境的时候使用content_by_lua_file只关注了头,后来发到测试环境发现请求内容都没代理转发到后端服务上<br>网上查了下发现content_by_lua_file是将请求的所有内容包括response都用这里面的lua脚本生成了,content这个词就表示是请求内容<br>后来改成了access_by_lua_file就正常了,只是要去获取请求内容和修改响应头,并不是要完整的接管请求</li>
@ -303,18 +304,33 @@
<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>
<li><p>还有就是lua的异常捕获,网上看一般是用pcall和xpcall来进行保护调用,因为问题主要出在cjson的decode,这里有两个解决方案,一个就是将cjson.decode使用pcall封装,</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">local</span> decode = <span class="built_in">require</span>(<span class="string">"cjson"</span>).decode</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">json_decode</span><span class="params">( str )</span></span></span><br><span class="line"> <span class="keyword">local</span> ok, t = <span class="built_in">pcall</span>(decode, str)</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> ok <span class="keyword">then</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> t</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-lua" data-language="lua"><code class="language-lua"><span class="token keyword">local</span> decode <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"cjson"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>decode
<span class="token keyword">function</span> <span class="token function">json_decode</span><span class="token punctuation">(</span> str <span class="token punctuation">)</span>
<span class="token keyword">local</span> ok<span class="token punctuation">,</span> t <span class="token operator">=</span> <span class="token function">pcall</span><span class="token punctuation">(</span>decode<span class="token punctuation">,</span> str<span class="token punctuation">)</span>
<span class="token keyword">if</span> <span class="token keyword">not</span> ok <span class="token keyword">then</span>
<span class="token keyword">return</span> <span class="token keyword">nil</span>
<span class="token keyword">end</span>
<span class="token keyword">return</span> t
<span class="token keyword">end</span><span aria-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></code></pre>
<p> 这个是使用了pcall,称为保护调用,会在内部错误后返回两个参数,第一个是false,第二个是错误信息<br> 还有一种是使用cjson.safe包</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">local</span> json = <span class="built_in">require</span>(<span class="string">"cjson.safe"</span>)</span><br><span class="line"><span class="keyword">local</span> str = <span class="string">[[ &#123;"key:"value"&#125; ]]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">local</span> t = json.decode(str)</span><br><span class="line"><span class="keyword">if</span> t <span class="keyword">then</span></span><br><span class="line"> ngx.say(<span class="string">" --&gt; "</span>, <span class="built_in">type</span>(t))</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-lua" data-language="lua"><code class="language-lua"><span class="token keyword">local</span> json <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">"cjson.safe"</span><span class="token punctuation">)</span>
<span class="token keyword">local</span> str <span class="token operator">=</span> <span class="token string">[[ &#123;"key:"value"&#125; ]]</span>
<span class="token keyword">local</span> t <span class="token operator">=</span> json<span class="token punctuation">.</span><span class="token function">decode</span><span class="token punctuation">(</span>str<span class="token punctuation">)</span>
<span class="token keyword">if</span> t <span class="token keyword">then</span>
ngx<span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">" --> "</span><span class="token punctuation">,</span> <span class="token function">type</span><span class="token punctuation">(</span>t<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token keyword">end</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p> cjson.safe包会在解析失败的时候返回nil</p>
</li>
<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>
<li><p>还有一点补充下<br>就是业务在使用redis的时候使用了db的特性,所以在lua访问redis的时候也需要执行db,这里lua的redis库也支持了这个特性,可以使用instance:select(config:get(‘db’))来切换db</p>
</li>
<li><p>性能优化tips<br><a href="https://juejin.im/entry/5b0e8fcef265da09210072a3#openresty" target="_blank" rel="noopener">建议是尽量少使用阶段钩子,例如content_by_lua_file,*_by_lua</a></p>
<li><p>性能优化tips<br><a target="_blank" rel="noopener" href="https://juejin.im/entry/5b0e8fcef265da09210072a3#openresty">建议是尽量少使用阶段钩子,例如content_by_lua_file,*_by_lua</a></p>
</li>
<li><p>发现一个不错的openresty站点<br><a href="http://orhub.org/" target="_blank" rel="noopener">地址</a></p>
<li><p>发现一个不错的openresty站点<br><a target="_blank" rel="noopener" href="http://orhub.org/">地址</a></p>
</li>
</ol>


+ 62
- 19
2019/09/23/AbstractQueuedSynchronizer/index.html
File diff suppressed because it is too large
View File


+ 587
- 9
2019/12/07/JVM-G1-Part-1/index.html
File diff suppressed because it is too large
View File


+ 10
- 12
2019/12/10/Redis-Part-1/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2019/12/10/Redis-Part-1/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="今天看了一下 redis 分布式锁 redlock 的实现,简单记录下, 加锁原先我对 redis 锁的概念就是加锁使用 setnx,解锁使用 lua 脚本,但是 setnx 具体是啥,lua 脚本是啥不是很清楚首先简单思考下这个问题,首先为啥不是先 get 一下 key 存不存在,然后再 set 一个 key value,因为加锁这个操作我们是要保证两点,一个是不能中途被打断,也就是说要原子性,">
<meta property="og:locale">
<meta property="article:published_time" content="2019-12-10T15:26:26.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2019-12-10T15:26:26.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="C">
<meta property="article:tag" content="Redis">
@ -231,13 +232,6 @@
<time title="Created: 2019-12-10 23:26:26" itemprop="dateCreated datePublished" datetime="2019-12-10T23:26:26+08:00">2019-12-10</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -303,11 +297,15 @@
<h2 id="加锁"><a href="#加锁" class="headerlink" title="加锁"></a>加锁</h2><p>原先我对 <code>redis</code> 锁的概念就是加锁使用 <code>setnx</code>,解锁使用 <code>lua</code> 脚本,但是 <code>setnx</code> 具体是啥,<code>lua</code> 脚本是啥不是很清楚<br>首先简单思考下这个问题,首先为啥不是先 <code>get</code> 一下 <code>key</code> 存不存在,然后再 <code>set</code> 一个 <code>key value</code>,因为加锁这个操作我们是要保证两点,一个是不能中途被打断,也就是说要原子性,如果是先 <code>get</code> 一下 <code>key</code>,如果不存在再 <code>set</code> 值的话,那就不是原子操作了;第二个是可不可以直接 <code>set</code> 值呢,显然不行,锁要保证唯一性,有且只能有一个线程或者其他应用单位获得该锁,正好 <code>setnx</code> 给了我们这种原子命令</p>
<p>然后是 <code>setnx</code> 的键和值分别是啥,键比较容易想到是要锁住的资源,比如 <code>user_id</code>, 这里有个我自己之前比较容易陷进去的误区,但是这个误区后<br>面再说,这里其实是把<code>user_id</code> 作为要锁住的资源,在我获得锁的时候别的线程不允许操作,以此保证业务的正确性,不会被多个线程同时修改,确定了键,再来看看值是啥,其实原先我认为值是啥都没关系,我只要锁住了,光键就够我用了,但是考虑下多个线程的问题,如果我这个线程加了锁,然后我因为 <code>gc</code> 停顿等原因卡死了,这个时候<code>redis</code> 的锁或者说就是 <code>redis</code> 的缓存已经过期了,这时候另一个线程获得锁成功,然后我这个线程又活过来了,然后我就仍然认为我拿着锁,我去对数据进行修改或者释放锁,是不是就出现问题了,所以是不是我们还需要一个东西来区分这个锁是哪个线程加的,所以我们可以将值设置成为一个线程独有识别的值,至少在相对长的一段时间内不会重复。</p>
<p>上面其实还有两个问题,一个是当 <code>gc</code> 超时时,我这个线程如何知道我手里的锁已经过期了,一种方法是我在加好锁之后就维护一个超时时间,这里其实还有个问题,不过跟第二个问题相关,就一起说了,就是设置超时时间,有些对于不是锁的 <code>redis</code> 缓存操作可以是先设置好值,然后在设置过期时间,那么这就又有上面说到的不是原子性的问题,那么就需要在同一条指令里把超时时间也设置了,幸好 <code>redis</code> 提供了这种支持</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">SET resource_name my_random_value NX PX 30000</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">SET resource_name my_random_value NX PX 30000<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>这里借鉴一下解释下,<code>resource_name</code>就是 key,代表要锁住的东西,<code>my_random_value</code>就是识别我这个线程的,<code>NX</code>代表只有在不存在的时候才设置,然后<code>PX 30000</code>表示超时时间是 30秒自动过期</p>
<p>PS:记录下我原先有的一个误区,是不是要用 key 来区分加锁的线程,这样只有一个用处,就是自身线程可以识别是否是自己加的锁,但是最大的问题是别的线程不知道,其实这个用户的出发点是我在担心前面提过的一个问题,就是当 gc 停顿后,我要去判断当前的这个锁是否是我加的,还有就是当释放锁的时候,如果保证不会错误释放了其他线程加的锁,但是这样附带很多其他问题,最大的就是其他线程怎么知道能不能加这个锁。</p>
<h2 id="解锁"><a href="#解锁" class="headerlink" title="解锁"></a>解锁</h2><p>当线程在锁过期之前就处理完了业务逻辑,那就可以提前释放这个锁,那么提前释放要怎么操作,直接<code>del key</code>显然是不行的,因为这样就是我前面想用线程随机值加资源名作为锁的初衷,我不能去释放别的线程加的锁,那么我要怎么办呢,先 <code>get</code> 一下看是不是我的?那又变成非原子的操作了,幸好redis 也考虑到了这个问题,给了<code>lua</code> 脚本来操作这种</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> redis.call(<span class="string">"get"</span>,KEYS[<span class="number">1</span>]) == ARGV[<span class="number">1</span>] <span class="keyword">then</span></span><br><span class="line"> <span class="keyword">return</span> redis.call(<span class="string">"del"</span>,KEYS[<span class="number">1</span>])</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-lua" data-language="lua"><code class="language-lua"><span class="token keyword">if</span> redis<span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token string">"get"</span><span class="token punctuation">,</span>KEYS<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">==</span> ARGV<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token keyword">then</span>
<span class="token keyword">return</span> redis<span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token string">"del"</span><span class="token punctuation">,</span>KEYS<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token keyword">else</span>
<span class="token keyword">return</span> <span class="token number">0</span>
<span class="token keyword">end</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这里的<code>KEYS[1]</code>就是前面加锁的<code>resource_name</code>,<code>ARGV[1]</code>就是线程的随机值<code>my_random_value</code></p>
<h2 id="多节点"><a href="#多节点" class="headerlink" title="多节点"></a>多节点</h2><p>前面说的其实是单节点 <code>redis</code> 作为分布式锁的情况,那么当我们的 <code>redis</code> 有多节点的情况呢,如果多节点下处于加锁或者解锁或者锁有效情况下<br><code>redis</code> 的某个节点宕掉了怎么办,这里就有一些需要思考的地方,是否单独搞一个单节点的 <code>redis</code>作为分布式锁专用的,但是如果这个单节点的挂了呢,还有就是成本问题,所以我们需要一个多节点的分布式锁方案<br>这里就引出了开头说到的<code>redlock</code>,这个可是 <code>redis</code>的作者写的, 他的加锁过程是分以下几步去做这个事情</p>
<ul>
@ -455,7 +453,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#加锁"><span class="nav-number">1.</span> <span class="nav-text">加锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#解锁"><span class="nav-number">2.</span> <span class="nav-text">解锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#多节点"><span class="nav-number">3.</span> <span class="nav-text">多节点</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8A%A0%E9%94%81"><span class="nav-number">1.</span> <span class="nav-text">加锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%A7%A3%E9%94%81"><span class="nav-number">2.</span> <span class="nav-text">解锁</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%A4%9A%E8%8A%82%E7%82%B9"><span class="nav-number">3.</span> <span class="nav-text">多节点</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 2
- 1
2019/12/18/1Q84读后感/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,6 +32,7 @@
<meta property="og:url" content="https://nicksxs.me/2019/12/18/1Q84%E8%AF%BB%E5%90%8E%E6%84%9F/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="看完了村上春树的《1Q84》,这应该是第五本看的他的书了,继 跑步,挪威的森林,刺杀骑士团长,海边的卡夫卡之后,不是其中最长的,好像是海边的卡夫卡还是刺杀骑士团长比较长一点,都是在微信读书上看的,比较方便,最开始在上面看的是高晓松的《鱼羊野史》,不知道为啥取这个名字,但是还是满吸引我的,不过由于去年的种种,没有很多心思把它看完,而且本身的组织形式就是比较松散的,看到哪算哪,其实一些野史部分是我比较">
<meta property="og:locale">
<meta property="article:published_time" content="2019-12-17T16:33:09.000Z">
<meta property="article:modified_time" content="2019-12-18T16:08:42.000Z">
<meta property="article:author" content="Nicksxs">


+ 58
- 11
2019/12/21/聊聊Java中的单例模式/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,16 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2019/12/21/%E8%81%8A%E8%81%8AJava%E4%B8%AD%E7%9A%84%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="这是个 Java 面试的高频问题,我也遇到过,以往都是觉得这类题没意思,网上一搜一大堆,也不愿意记,其实说回来,主要还是没静下心来好好去理解,今天无意中看到一个课程,基本帮我把一些疑惑的点讲清楚了,首先单例是啥意思,这个其实是有范围一说,比如我起了个Spring Boot应用,在这个应用范围内,我的常规 bean 是单例的,意味着 getBean 的时候其实永远只会拿到那一个对象,那要怎么来写一个">
<meta property="og:locale">
<meta property="article:published_time" content="2019-12-20T17:03:09.000Z">
<meta property="article:modified_time" content="2019-12-22T00:46:11.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Design Patterns">
<meta property="article:tag" content="设计模式">
<meta property="article:tag" content="Design Patterns">
<meta property="article:tag" content="单例">
<meta property="article:tag" content="Double Check Lock">
<meta property="article:tag" content="枚举单例">
<meta property="article:tag" content="DCL">
<meta property="article:tag" content="Singleton">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2019/12/21/%E8%81%8A%E8%81%8AJava%E4%B8%AD%E7%9A%84%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/">
@ -299,14 +297,63 @@
<p>这是个 Java 面试的高频问题,我也遇到过,以往都是觉得这类题没意思,网上一搜一大堆,也不愿意记,其实说回来,主要还是没静下心来好好去理解,今天无意中看到一个课程,基本帮我把一些疑惑的点讲清楚了,首先单例是啥意思,这个其实是有范围一说,比如我起了个<code>Spring Boot</code>应用,在这个应用范围内,我的常规 bean 是单例的,意味着 getBean 的时候其实永远只会拿到那一个对象,那要怎么来写一个单例呢,首先就是传说中的饿汉模式,也是最简单的</p>
<h2 id="饿汉模式"><a href="#饿汉模式" class="headerlink" title="饿汉模式"></a>饿汉模式</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton1</span> </span>&#123;</span><br><span class="line"> <span class="comment">// 首先,将构造方法变成私有的</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="title">Singleton1</span><span class="params">()</span> </span>&#123;&#125;;</span><br><span class="line"> <span class="comment">// 创建私有静态实例,这样第一次使用的时候就会进行创建</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Singleton instance = <span class="keyword">new</span> Singleton1();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 使用这个对象都是通过这个 getInstance 来获取</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton1 <span class="title">getInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> instance;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 瞎写一个静态方法。这里想说的是,如果我们只是要调用 Singleton.getDate(...),</span></span><br><span class="line"> <span class="comment">// 本来是不想要生成 Singleton 实例的,不过没办法,已经生成了</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Date <span class="title">getDate</span><span class="params">(String mode)</span> </span>&#123;<span class="keyword">return</span> <span class="keyword">new</span> Date();&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="饿汉模式"><a href="#饿汉模式" class="headerlink" title="饿汉模式"></a>饿汉模式</h2><pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">public class Singleton1 &#123;
&#x2F;&#x2F; 首先,将构造方法变成私有的
private Singleton1() &#123;&#125;;
&#x2F;&#x2F; 创建私有静态实例,这样第一次使用的时候就会进行创建
private static Singleton instance &#x3D; new Singleton1();
&#x2F;&#x2F; 使用这个对象都是通过这个 getInstance 来获取
public static Singleton1 getInstance() &#123;
return instance;
&#125;
&#x2F;&#x2F; 瞎写一个静态方法。这里想说的是,如果我们只是要调用 Singleton.getDate(...),
&#x2F;&#x2F; 本来是不想要生成 Singleton 实例的,不过没办法,已经生成了
public static Date getDate(String mode) &#123;return new Date();&#125;
&#125;<span aria-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></code></pre>
<p>上面借鉴了一些代码,其实这是最基本,也不会错的方法,但是正如其中<code>getDate</code>方法里说的问题,有时候并没有想那这个对象,但是因为我调用了这个类的静态方法,导致对象已经生成了,可能这也是饿汉模式名字的来由,不管三七二十一给你生成个单例就完事了,不管有没有用,但是这种个人觉得也没啥大问题,如果是面试的话最好说出来它的缺点</p>
<h2 id="饱汉模式"><a href="#饱汉模式" class="headerlink" title="饱汉模式"></a>饱汉模式</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton2</span> </span>&#123;</span><br><span class="line"> <span class="comment">// 首先,也是先堵死 new Singleton() 这条路,将构造方法变成私有</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="title">Singleton2</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line"> <span class="comment">// 和饿汉模式相比,这边不需要先实例化出来,注意这里的 volatile,它是必须的</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">volatile</span> Singleton2 instance = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">int</span> m = <span class="number">9</span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton <span class="title">getInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (instance == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="comment">// 加锁</span></span><br><span class="line"> <span class="keyword">synchronized</span> (Singleton2<span class="class">.<span class="keyword">class</span>) </span>&#123;</span><br><span class="line"> <span class="comment">// 这一次判断也是必须的,不然会有并发问题</span></span><br><span class="line"> <span class="keyword">if</span> (instance == <span class="keyword">null</span>) &#123;</span><br><span class="line"> instance = <span class="keyword">new</span> Singleton2();</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> instance;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="饱汉模式"><a href="#饱汉模式" class="headerlink" title="饱汉模式"></a>饱汉模式</h2><pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">public class Singleton2 &#123;
&#x2F;&#x2F; 首先,也是先堵死 new Singleton() 这条路,将构造方法变成私有
private Singleton2() &#123;&#125;
&#x2F;&#x2F; 和饿汉模式相比,这边不需要先实例化出来,注意这里的 volatile,它是必须的
private static volatile Singleton2 instance &#x3D; null;
private int m &#x3D; 9;
public static Singleton getInstance() &#123;
if (instance &#x3D;&#x3D; null) &#123;
&#x2F;&#x2F; 加锁
synchronized (Singleton2.class) &#123;
&#x2F;&#x2F; 这一次判断也是必须的,不然会有并发问题
if (instance &#x3D;&#x3D; null) &#123;
instance &#x3D; new Singleton2();
&#125;
&#125;
&#125;
return instance;
&#125;
&#125;<span aria-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></code></pre>
<p>这里容易错的有三点,理解了其实就比较好记了</p>
<p>第一点,为啥不在 getInstance 上整个代码块加 <code>synchronized</code>,这个其实比较容易理解,就是锁的力度太大,性能太差了,这点其实也要去理解,可以举个夸张的例子,比如我一个电商的服务,如果为了避免一个人的订单出现问题,是不是可以从请求入口就把他锁住,到请求结束释放,那么里面做的事情都有保障,然而这显然不可能,因为我们想要这种竞态条件抢占资源的时间尽量减少,防止其他线程等待。<br>第二点,为啥<code>synchronized</code>之已经检查了 <code>instance == null</code>,还要在里面再检查一次,这个有个术语,叫 <code>double check lock</code>,但是为啥要这么做呢,其实很简单,想象当有两个线程,都过了第一步为空判断,这个时候只有一个线程能拿到这个锁,另一个线程就等待了,如果不再判断一次,那么第一个线程新建完对象释放锁之后,第二个线程又能拿到锁,再去创建一个对象。<br>第三点,为啥要<code>volatile</code>关键字,原先对它的理解是它修饰的变量在 JMM 中能及时将变量值写到主存中,但是它还有个很重要的作用,就是防止指令重排序,<code>instance = new Singleton();</code>这行代码其实在底层是分成三条指令执行的,第一条是在堆上申请了一块内存放这个对象,但是对象的字段啥的都还是默认值,第二条是设置对象的值,比如上面的 m 是 9,然后第三条是将这个对象和虚拟机栈上的指针建立引用关联,那么如果我不用<code>volatile</code>关键字,这三条指令就有可能出现重排,比如变成了 1-3-2 这种顺序,当执行完第二步时,有个线程来访问这个对象了,先判断是不是空,发现不是空的,就拿去直接用了,是不是就出现问题了,所以这个<code>volatile</code>也是不可缺少的</p>
<h2 id="嵌套类"><a href="#嵌套类" class="headerlink" title="嵌套类"></a>嵌套类</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Singleton3</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="title">Singleton3</span><span class="params">()</span> </span>&#123;&#125;</span><br><span class="line"> <span class="comment">// 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">Holder</span> </span>&#123;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Singleton3 instance = <span class="keyword">new</span> Singleton3();</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Singleton3 <span class="title">getInstance</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> Holder.instance;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="嵌套类"><a href="#嵌套类" class="headerlink" title="嵌套类"></a>嵌套类</h2><pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">public class Singleton3 &#123;
private Singleton3() &#123;&#125;
&#x2F;&#x2F; 主要是使用了 嵌套类可以访问外部类的静态属性和静态方法 的特性
private static class Holder &#123;
private static Singleton3 instance &#x3D; new Singleton3();
&#125;
public static Singleton3 getInstance() &#123;
return Holder.instance;
&#125;
&#125;<span aria-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></code></pre>
<p>这个我个人感觉是饿汉模式的升级版,可以在调用<code>getInstance</code>的时候去实例化对象,也是比较推荐的</p>
<h2 id="枚举单例"><a href="#枚举单例" class="headerlink" title="枚举单例"></a>枚举单例</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">enum</span> Singleton &#123;</span><br><span class="line"> INSTANCE;</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">doSomething</span><span class="params">()</span></span>&#123;</span><br><span class="line"> <span class="comment">//todo doSomething</span></span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="枚举单例"><a href="#枚举单例" class="headerlink" title="枚举单例"></a>枚举单例</h2><pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">public enum Singleton &#123;
INSTANCE;
public void doSomething()&#123;
&#x2F;&#x2F;todo doSomething
&#125;
&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>枚举很特殊,它在类加载的时候会初始化里面的所有的实例,而且 JVM 保证了它们不会再被实例化,所以它天生就是单例的。</p>
</div>
@ -440,7 +487,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#饿汉模式"><span class="nav-number">1.</span> <span class="nav-text">饿汉模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#饱汉模式"><span class="nav-number">2.</span> <span class="nav-text">饱汉模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#嵌套类"><span class="nav-number">3.</span> <span class="nav-text">嵌套类</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#枚举单例"><span class="nav-number">4.</span> <span class="nav-text">枚举单例</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A5%BF%E6%B1%89%E6%A8%A1%E5%BC%8F"><span class="nav-number">1.</span> <span class="nav-text">饿汉模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A5%B1%E6%B1%89%E6%A8%A1%E5%BC%8F"><span class="nav-number">2.</span> <span class="nav-text">饱汉模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B5%8C%E5%A5%97%E7%B1%BB"><span class="nav-number">3.</span> <span class="nav-text">嵌套类</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9E%9A%E4%B8%BE%E5%8D%95%E4%BE%8B"><span class="nav-number">4.</span> <span class="nav-text">枚举单例</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 70
- 24
2019/12/26/redis数据结构介绍/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,20 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2019/12/26/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="redis是现在服务端很常用的缓存中间件,其实原来还有memcache之类的竞品,但是现在貌似 redis 快一统江湖,这里当然不是在吹,只是个人角度的一个感觉,不权威只是主观感觉。redis 主要有五种数据结构,Strings,Lists,Sets,Hashes,Sorted Sets,这五种数据结构先简单介绍下,Strings类型的其实就是我们最常用的 key-value,实际开发中也会用的最">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2019/12/29/UL4AR1HSEKOh9Qm.png">
<meta property="article:published_time" content="2019-12-25T16:03:49.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2019-12-25T16:03:49.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="redis">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="SDS">
<meta property="article:tag" content="链表">
<meta property="article:tag" content="linked list">
<meta property="article:tag" content="字典">
<meta property="article:tag" content="dict">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2019/12/29/UL4AR1HSEKOh9Qm.png">
@ -239,13 +233,6 @@
<time title="Created: 2019-12-26 00:03:49" itemprop="dateCreated datePublished" datetime="2019-12-26T00:03:49+08:00">2019-12-26</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -313,14 +300,73 @@
<p>redis是现在服务端很常用的缓存中间件,其实原来还有<code>memcache</code>之类的竞品,但是现在貌似 redis 快一统江湖,这里当然不是在吹,只是个人角度的一个感觉,不权威只是主观感觉。<br>redis 主要有五种数据结构,<code>Strings</code><code>Lists</code><code>Sets</code><code>Hashes</code><code>Sorted Sets</code>,这五种数据结构先简单介绍下,<code>Strings</code>类型的其实就是我们最常用的 key-value,实际开发中也会用的最多;<code>Lists</code>是列表,这个有些会用来做队列,因为 redis 目前常用的版本支持丰富的列表操作;还有是<code>Sets</code>集合,这个主要的特点就是集合中元素不重复,可以用在有这类需求的场景里;<code>Hashes</code>是叫散列,类似于 Python 中的字典结构;还有就是<code>Sorted Sets</code>这个是个有序集合;一眼看这些其实没啥特别的,除了最后这个有序集合,不过去了解背后的实现方式还是比较有意思的。</p>
<h2 id="SDS-简单动态字符串"><a href="#SDS-简单动态字符串" class="headerlink" title="SDS 简单动态字符串"></a>SDS 简单动态字符串</h2><p>先从<code>Strings</code>开始说,了解过 C 语言的应该知道,C 语言中的字符串其实是个 <code>char[]</code> 字符数组,redis 也不例外,只是最开始的版本就对这个做了一丢丢的优化,而正是这一丢丢的优化,让这个 redis 的使用效率提升了数倍</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sdshdr</span> &#123;</span></span><br><span class="line"> <span class="comment">// 字符串长度</span></span><br><span class="line"> <span class="keyword">int</span> len;</span><br><span class="line"> <span class="comment">// 字符串空余字符数</span></span><br><span class="line"> <span class="keyword">int</span> <span class="built_in">free</span>;</span><br><span class="line"> <span class="comment">// 字符串内容</span></span><br><span class="line"> <span class="keyword">char</span> buf[];</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">struct sdshdr &#123;
&#x2F;&#x2F; 字符串长度
int len;
&#x2F;&#x2F; 字符串空余字符数
int free;
&#x2F;&#x2F; 字符串内容
char buf[];
&#125;;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<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>
<h2 id="链表"><a href="#链表" class="headerlink" title="链表"></a>链表</h2><p>链表是比较常见的数据结构了,但是因为 redis 是用 C 写的,所以在不依赖第三方库的情况下只能自己写一个了,redis 的链表是个有头的链表,而且是无环的,具体的结构我也找了 github 上最早版本的代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">listNode</span> &#123;</span></span><br><span class="line"> <span class="comment">// 前置节点</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">listNode</span> *<span class="title">prev</span>;</span></span><br><span class="line"> <span class="comment">// 后置节点</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">listNode</span> *<span class="title">next</span>;</span></span><br><span class="line"> <span class="comment">// 值</span></span><br><span class="line"> <span class="keyword">void</span> *value;</span><br><span class="line">&#125; listNode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">list</span> &#123;</span></span><br><span class="line"> <span class="comment">// 链表表头</span></span><br><span class="line"> listNode *head;</span><br><span class="line"> <span class="comment">// 当前节点,也可以说是最后节点</span></span><br><span class="line"> listNode *tail;</span><br><span class="line"> <span class="comment">// 节点复制函数</span></span><br><span class="line"> <span class="keyword">void</span> *(*dup)(<span class="keyword">void</span> *ptr);</span><br><span class="line"> <span class="comment">// 节点值释放函数</span></span><br><span class="line"> <span class="keyword">void</span> (*<span class="built_in">free</span>)(<span class="keyword">void</span> *ptr);</span><br><span class="line"> <span class="comment">// 节点值比较函数</span></span><br><span class="line"> <span class="keyword">int</span> (*match)(<span class="keyword">void</span> *ptr, <span class="keyword">void</span> *key);</span><br><span class="line"> <span class="comment">// 链表包含的节点数量</span></span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">int</span> len;</span><br><span class="line">&#125; <span class="built_in">list</span>;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">typedef struct listNode &#123;
&#x2F;&#x2F; 前置节点
struct listNode *prev;
&#x2F;&#x2F; 后置节点
struct listNode *next;
&#x2F;&#x2F;
void *value;
&#125; listNode;
typedef struct list &#123;
&#x2F;&#x2F; 链表表头
listNode *head;
&#x2F;&#x2F; 当前节点,也可以说是最后节点
listNode *tail;
&#x2F;&#x2F; 节点复制函数
void *(*dup)(void *ptr);
&#x2F;&#x2F; 节点值释放函数
void (*free)(void *ptr);
&#x2F;&#x2F; 节点值比较函数
int (*match)(void *ptr, void *key);
&#x2F;&#x2F; 链表包含的节点数量
unsigned int len;
&#125; list;<span aria-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>代码地址是这个<code>https://github.com/antirez/redis/blob/2.2/src/adlist.h</code><br>可以看下节点是由listNode承载的,包括值和一个指向前节点跟一个指向后一节点的两个指针,然后值是 void 指针类型,所以可以承载不同类型的值<br>然后是 list结构用来承载一个链表,包含了表头,和表尾,复制函数,释放函数和比较函数,还有链表长度,因为包含了前两个节点,找到表尾节点跟表头都是 <code>O(1)</code>的时间复杂度,还有节点数量,其实这个跟 SDS 是同一个做法,就是空间换时间,这也是写代码里比较常见的做法,以此让一些高频的操作提速。</p>
<h2 id="字典"><a href="#字典" class="headerlink" title="字典"></a>字典</h2><p>字典也是个常用的数据结构,其实只是叫法不同,数据结构中叫 hash 散列,Java 中叫 Map,PHP 中是数组 array,Python 中也叫字典 dict,因为纯 C 语言本身不带这些数据结构,所以这也是个痛并快乐着的过程,享受 C 语言的高性能的同时也要接受它只提供了语言的基本功能的现实,各种轮子都需要自己造,redis 同样实现了自己的字典<br>下面来看看代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">dictEntry</span> &#123;</span></span><br><span class="line"> <span class="keyword">void</span> *key;</span><br><span class="line"> <span class="keyword">void</span> *val;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">dictEntry</span> *<span class="title">next</span>;</span></span><br><span class="line">&#125; dictEntry;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">dictType</span> &#123;</span></span><br><span class="line"> <span class="function"><span class="keyword">unsigned</span> <span class="title">int</span> <span class="params">(*hashFunction)</span><span class="params">(<span class="keyword">const</span> <span class="keyword">void</span> *key)</span></span>;</span><br><span class="line"> <span class="keyword">void</span> *(*keyDup)(<span class="keyword">void</span> *privdata, <span class="keyword">const</span> <span class="keyword">void</span> *key);</span><br><span class="line"> <span class="keyword">void</span> *(*valDup)(<span class="keyword">void</span> *privdata, <span class="keyword">const</span> <span class="keyword">void</span> *obj);</span><br><span class="line"> <span class="keyword">int</span> (*keyCompare)(<span class="keyword">void</span> *privdata, <span class="keyword">const</span> <span class="keyword">void</span> *key1, <span class="keyword">const</span> <span class="keyword">void</span> *key2);</span><br><span class="line"> <span class="keyword">void</span> (*keyDestructor)(<span class="keyword">void</span> *privdata, <span class="keyword">void</span> *key);</span><br><span class="line"> <span class="keyword">void</span> (*valDestructor)(<span class="keyword">void</span> *privdata, <span class="keyword">void</span> *obj);</span><br><span class="line">&#125; dictType;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* This is our hash table structure. Every dictionary has two of this as we</span></span><br><span class="line"><span class="comment"> * implement incremental rehashing, for the old to the new table. */</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">dictht</span> &#123;</span></span><br><span class="line"> dictEntry **table;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="built_in">size</span>;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> sizemask;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> used;</span><br><span class="line">&#125; dictht;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">dict</span> &#123;</span></span><br><span class="line"> dictType *type;</span><br><span class="line"> <span class="keyword">void</span> *privdata;</span><br><span class="line"> dictht ht[<span class="number">2</span>];</span><br><span class="line"> <span class="keyword">int</span> rehashidx; <span class="comment">/* rehashing not in progress if rehashidx == -1 */</span></span><br><span class="line"> <span class="keyword">int</span> iterators; <span class="comment">/* number of iterators currently running */</span></span><br><span class="line">&#125; dict;</span><br></pre></td></tr></table></figure>
<p>看了下这个 2.2 版本的代码跟最新版的其实也差的不是很多,所以还是照旧用老代码,可以看到上面四个结构体中,其实只有三个是存储数据用的,dictType 是用来放操作函数的,那么三个存放数据的结构体分别是干嘛的,这时候感觉需要一个图来说明比较好,稍等,我去画个图~<br><img data-src="https://i.loli.net/2019/12/29/UL4AR1HSEKOh9Qm.png" alt=""><br>这个图看着应该比较清楚这些都是用来干嘛的了,dict 是我们的主体结构,它有一个指向 dictType 的指针,这里面包含了字典的操作函数,然后是一个私有数据指针,接下来是一个 dictht 的数组,包含两个dictht,这个就是用来存数据的了,然后是 rehashidx 表示重哈希的状态,当是-1 的时候表示当前没有重哈希,iterators 表示正在遍历的迭代器的数量。<br>首先说说为啥需要有两个 dictht,这是因为字典 dict 这个数据结构随着数据量的增减,会需要在中途做扩容或者缩容操作,如果只有一个的话,对它进行扩容缩容时会影响正常的访问和修改操作,或者说保证正常查询,修改的正确性会比较复杂,并且因为需要高效利用空间,不能一下子申请一个非常大的空间来存很少的数据。当 dict 中 dictht 中的数据量超过 size 的时候负载就超过了 1,就需要进行扩容,这里的其实跟 Java 中的 HashMap 比较类似,超过一定的负载之后进行扩容。这里为啥 size 会超过 1 呢,可能有部分不了解这类结构的同学会比较奇怪,其实就是上图中画的,在数据结构中对于散列的冲突有几类解决方法,比如转换成链表,二次散列,找下个空槽等,这里就使用了链表法,或者说拉链法。当一个新元素通过 hashFunction 得出的 key 跟 sizemask 取模之后的值相同了,那就将其放在原来的节点之前,变成链表挂在数组 dictht.table下面,放在原有节点前是考虑到可能会优先访问。<br>忘了说明下 dictht 跟 dictEntry 的关系了,dictht 就是个哈希表,它里面是个dictEntry 的二维数组,而 dictEntry 是个包含了 key-value 结构之外还有一个 next 指针,因此可以将哈希冲突的以链表的形式保存下来。<br>在重点说下重哈希,可能同样写 Java 的同学对这个比较有感觉,跟 HashMap 一样,会以 2 的 N 次方进行扩容,那么扩容的方法就会比较简单,每个键重哈希要不就在原来这个槽,要不就在原来的槽加原 dictht.size 的位置;然后是重头戏,具体是怎么做扩容呢,其实这里就把第二个 ht 用上了,其实这两个hashtable 的具体作用有点类似于 jvm 中的两个 survival 区,但是又不全一样,因为 redis 在扩容的时候是采用的渐进式地重哈希,什么叫渐进式的呢,就是它不是像 jvm 那种标记复制的模式直接将一个 eden 区和原来的 survival 区存活的对象复制到另一个 survival 区,而是在每一次添加,删除,查找或者更新操作时,都会额外的帮忙搬运一部分的原 dictht 中的数据,这里会根据 rehashidx 的值来判断,如果是-1 表示并没有在重哈希中,如果是 0 表示开始重哈希了,然后rehashidx 还会随着每次的帮忙搬运往上加,但全部被搬运完成后 rehashidx 又变回了-1,又可以扯到Java 中的 Concurrent HashMap, 他在扩容的时候也使用了类似的操作。</p>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">typedef struct dictEntry &#123;
void *key;
void *val;
struct dictEntry *next;
&#125; dictEntry;
typedef struct dictType &#123;
unsigned int (*hashFunction)(const void *key);
void *(*keyDup)(void *privdata, const void *key);
void *(*valDup)(void *privdata, const void *obj);
int (*keyCompare)(void *privdata, const void *key1, const void *key2);
void (*keyDestructor)(void *privdata, void *key);
void (*valDestructor)(void *privdata, void *obj);
&#125; dictType;
&#x2F;* This is our hash table structure. Every dictionary has two of this as we
* implement incremental rehashing, for the old to the new table. *&#x2F;
typedef struct dictht &#123;
dictEntry **table;
unsigned long size;
unsigned long sizemask;
unsigned long used;
&#125; dictht;
typedef struct dict &#123;
dictType *type;
void *privdata;
dictht ht[2];
int rehashidx; &#x2F;* rehashing not in progress if rehashidx &#x3D;&#x3D; -1 *&#x2F;
int iterators; &#x2F;* number of iterators currently running *&#x2F;
&#125; dict;<span aria-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></span><span></span><span></span><span></span></span></code></pre>
<p>看了下这个 2.2 版本的代码跟最新版的其实也差的不是很多,所以还是照旧用老代码,可以看到上面四个结构体中,其实只有三个是存储数据用的,dictType 是用来放操作函数的,那么三个存放数据的结构体分别是干嘛的,这时候感觉需要一个图来说明比较好,稍等,我去画个图~<br><img data-src="https://i.loli.net/2019/12/29/UL4AR1HSEKOh9Qm.png"><br>这个图看着应该比较清楚这些都是用来干嘛的了,dict 是我们的主体结构,它有一个指向 dictType 的指针,这里面包含了字典的操作函数,然后是一个私有数据指针,接下来是一个 dictht 的数组,包含两个dictht,这个就是用来存数据的了,然后是 rehashidx 表示重哈希的状态,当是-1 的时候表示当前没有重哈希,iterators 表示正在遍历的迭代器的数量。<br>首先说说为啥需要有两个 dictht,这是因为字典 dict 这个数据结构随着数据量的增减,会需要在中途做扩容或者缩容操作,如果只有一个的话,对它进行扩容缩容时会影响正常的访问和修改操作,或者说保证正常查询,修改的正确性会比较复杂,并且因为需要高效利用空间,不能一下子申请一个非常大的空间来存很少的数据。当 dict 中 dictht 中的数据量超过 size 的时候负载就超过了 1,就需要进行扩容,这里的其实跟 Java 中的 HashMap 比较类似,超过一定的负载之后进行扩容。这里为啥 size 会超过 1 呢,可能有部分不了解这类结构的同学会比较奇怪,其实就是上图中画的,在数据结构中对于散列的冲突有几类解决方法,比如转换成链表,二次散列,找下个空槽等,这里就使用了链表法,或者说拉链法。当一个新元素通过 hashFunction 得出的 key 跟 sizemask 取模之后的值相同了,那就将其放在原来的节点之前,变成链表挂在数组 dictht.table下面,放在原有节点前是考虑到可能会优先访问。<br>忘了说明下 dictht 跟 dictEntry 的关系了,dictht 就是个哈希表,它里面是个dictEntry 的二维数组,而 dictEntry 是个包含了 key-value 结构之外还有一个 next 指针,因此可以将哈希冲突的以链表的形式保存下来。<br>在重点说下重哈希,可能同样写 Java 的同学对这个比较有感觉,跟 HashMap 一样,会以 2 的 N 次方进行扩容,那么扩容的方法就会比较简单,每个键重哈希要不就在原来这个槽,要不就在原来的槽加原 dictht.size 的位置;然后是重头戏,具体是怎么做扩容呢,其实这里就把第二个 ht 用上了,其实这两个hashtable 的具体作用有点类似于 jvm 中的两个 survival 区,但是又不全一样,因为 redis 在扩容的时候是采用的渐进式地重哈希,什么叫渐进式的呢,就是它不是像 jvm 那种标记复制的模式直接将一个 eden 区和原来的 survival 区存活的对象复制到另一个 survival 区,而是在每一次添加,删除,查找或者更新操作时,都会额外的帮忙搬运一部分的原 dictht 中的数据,这里会根据 rehashidx 的值来判断,如果是-1 表示并没有在重哈希中,如果是 0 表示开始重哈希了,然后rehashidx 还会随着每次的帮忙搬运往上加,但全部被搬运完成后 rehashidx 又变回了-1,又可以扯到Java 中的 Concurrent HashMap, 他在扩容的时候也使用了类似的操作。</p>
</div>
@ -340,10 +386,10 @@
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩</a></div>
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快</a></div>
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩</a></div>
</li>
</ul>
@ -470,7 +516,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#SDS-简单动态字符串"><span class="nav-number">1.</span> <span class="nav-text">SDS 简单动态字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#链表"><span class="nav-number">2.</span> <span class="nav-text">链表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#字典"><span class="nav-number">3.</span> <span class="nav-text">字典</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#SDS-%E7%AE%80%E5%8D%95%E5%8A%A8%E6%80%81%E5%AD%97%E7%AC%A6%E4%B8%B2"><span class="nav-number">1.</span> <span class="nav-text">SDS 简单动态字符串</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%93%BE%E8%A1%A8"><span class="nav-number">2.</span> <span class="nav-text">链表</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AD%97%E5%85%B8"><span class="nav-number">3.</span> <span class="nav-text">字典</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 39
- 23
2020/01/04/redis数据结构介绍二/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,19 +32,16 @@
<meta property="og:url" content="https://nicksxs.me/2020/01/04/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D%E4%BA%8C/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="跳表 skiplist跳表是个在我们日常的代码中不太常用到的数据结构,相对来讲就没有像数组,链表,字典,散列,树等结构那么熟悉,所以就从头开始分析下,首先是链表,跳表跟链表都有个表字(太硬扯了我🤦‍♀️),注意这是个有序链表如上图,在这个链表里如果我要找到 23,是不是我需要从3,5,9开始一直往后找直到找到 23,也就是说时间复杂度是 O(N),N 的一次幂复杂度,那么我们来看看第二个这个结构">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/01/03/Og9i3pCIfxrMhja.png">
<meta property="og:image" content="https://i.loli.net/2020/01/03/81P2baupiedOmNf.png">
<meta property="og:image" content="https://i.loli.net/2020/01/03/NBguAphilKjs2MO.png">
<meta property="article:published_time" content="2020-01-03T16:03:05.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2020-01-03T16:03:05.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="redis">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="跳表">
<meta property="article:tag" content="skip list">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/01/03/Og9i3pCIfxrMhja.png">
@ -238,13 +235,6 @@
<time title="Created: 2020-01-04 00:03:05" itemprop="dateCreated datePublished" datetime="2020-01-04T00:03:05+08:00">2020-01-04</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -310,10 +300,36 @@
<div class="post-body" itemprop="articleBody">
<h2 id="跳表-skiplist"><a href="#跳表-skiplist" class="headerlink" title="跳表 skiplist"></a>跳表 skiplist</h2><p>跳表是个在我们日常的代码中不太常用到的数据结构,相对来讲就没有像数组,链表,字典,散列,树等结构那么熟悉,所以就从头开始分析下,首先是链表,跳表跟链表都有个表字(太硬扯了我🤦‍♀️),注意这是个有序链表<br><img data-src="https://i.loli.net/2020/01/03/Og9i3pCIfxrMhja.png" alt=""><br>如上图,在这个链表里如果我要找到 23,是不是我需要从3,5,9开始一直往后找直到找到 23,也就是说时间复杂度是 O(N),N 的一次幂复杂度,那么我们来看看第二个<br><img data-src="https://i.loli.net/2020/01/03/81P2baupiedOmNf.png" alt=""><br>这个结构跟原先有点不一样,它给链表中偶数位的节点又加了一个指针把它们链接起来,这样子当我们要寻找 23 的时候就可以从原来的一个个往下找变成跳着找,先找到 5,然后是 10,接着是 19,然后是 28,这时候发现 28 比 23 大了,那我在退回到 19,然后从下一层原来的链表往前找,<br><img data-src="https://i.loli.net/2020/01/03/NBguAphilKjs2MO.png" alt=""><br>这里毛估估是不是前面的节点我就少找了一半,有那么点二分法的意思。<br>前面的其实是跳表的引子,真正的跳表其实不是这样,因为上面的其实有个比较大的问题,就是插入一个元素后需要调整每个元素的指针,在 redis 中的跳表其实是做了个随机层数的优化,因为沿着前面的例子,其实当数据量很大的时候,是不是层数越多,其查询效率越高,但是随着层数变多,要保持这种严格的层数规则其实也会增大处理复杂度,所以 redis 插入每个元素的时候都是使用随机的方式,看一眼代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* ZSETs use a specialized version of Skiplists */</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplistNode</span> &#123;</span></span><br><span class="line"> sds ele;</span><br><span class="line"> <span class="keyword">double</span> score;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplistNode</span> *<span class="title">backward</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplistLevel</span> &#123;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplistNode</span> *<span class="title">forward</span>;</span></span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> span;</span><br><span class="line"> &#125; level[];</span><br><span class="line">&#125; zskiplistNode;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplist</span> &#123;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">zskiplistNode</span> *<span class="title">header</span>, *<span class="title">tail</span>;</span></span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> length;</span><br><span class="line"> <span class="keyword">int</span> level;</span><br><span class="line">&#125; zskiplist;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">zset</span> &#123;</span></span><br><span class="line"> dict *dict;</span><br><span class="line"> zskiplist *zsl;</span><br><span class="line">&#125; zset;</span><br></pre></td></tr></table></figure>
<h2 id="跳表-skiplist"><a href="#跳表-skiplist" class="headerlink" title="跳表 skiplist"></a>跳表 skiplist</h2><p>跳表是个在我们日常的代码中不太常用到的数据结构,相对来讲就没有像数组,链表,字典,散列,树等结构那么熟悉,所以就从头开始分析下,首先是链表,跳表跟链表都有个表字(太硬扯了我🤦‍♀️),注意这是个有序链表<br><img data-src="https://i.loli.net/2020/01/03/Og9i3pCIfxrMhja.png"><br>如上图,在这个链表里如果我要找到 23,是不是我需要从3,5,9开始一直往后找直到找到 23,也就是说时间复杂度是 O(N),N 的一次幂复杂度,那么我们来看看第二个<br><img data-src="https://i.loli.net/2020/01/03/81P2baupiedOmNf.png"><br>这个结构跟原先有点不一样,它给链表中偶数位的节点又加了一个指针把它们链接起来,这样子当我们要寻找 23 的时候就可以从原来的一个个往下找变成跳着找,先找到 5,然后是 10,接着是 19,然后是 28,这时候发现 28 比 23 大了,那我在退回到 19,然后从下一层原来的链表往前找,<br><img data-src="https://i.loli.net/2020/01/03/NBguAphilKjs2MO.png"><br>这里毛估估是不是前面的节点我就少找了一半,有那么点二分法的意思。<br>前面的其实是跳表的引子,真正的跳表其实不是这样,因为上面的其实有个比较大的问题,就是插入一个元素后需要调整每个元素的指针,在 redis 中的跳表其实是做了个随机层数的优化,因为沿着前面的例子,其实当数据量很大的时候,是不是层数越多,其查询效率越高,但是随着层数变多,要保持这种严格的层数规则其实也会增大处理复杂度,所以 redis 插入每个元素的时候都是使用随机的方式,看一眼代码</p>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">&#x2F;* ZSETs use a specialized version of Skiplists *&#x2F;
typedef struct zskiplistNode &#123;
sds ele;
double score;
struct zskiplistNode *backward;
struct zskiplistLevel &#123;
struct zskiplistNode *forward;
unsigned long span;
&#125; level[];
&#125; zskiplistNode;
typedef struct zskiplist &#123;
struct zskiplistNode *header, *tail;
unsigned long length;
int level;
&#125; zskiplist;
typedef struct zset &#123;
dict *dict;
zskiplist *zsl;
&#125; zset;<span aria-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></code></pre>
<p>忘了说了,redis 是把 skiplist 跳表用在 zset 里,zset 是个有序的集合,可以看到 zskiplist 就是个跳表的结构,里面用 header 保存跳表的表头,tail 保存表尾,还有长度和最大层级,具体的跳表节点元素使用 zskiplistNode 表示,里面包含了 sds 类型的元素值,double 类型的分值,用来排序,一个 backward 后向指针和一个 zskiplistLevel 数组,每个 level 包含了一个前向指针,和一个 span,span 表示的是跳表前向指针的跨度,这里再补充一点,前面说了为了灵活这个跳表的新增修改,redis 使用了随机层高的方式插入新节点,但是如果所有节点都随机到很高的层级或者所有都很低的话,跳表的效率优势就会减小,所以 redis 使用了个小技巧,贴下代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ZSKIPLIST_P 0.25 <span class="comment">/* Skiplist P = 1/4 */</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">zslRandomLevel</span><span class="params">(<span class="keyword">void</span>)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">int</span> level = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> ((<span class="built_in">random</span>()&amp;<span class="number">0xFFFF</span>) &lt; (ZSKIPLIST_P * <span class="number">0xFFFF</span>))</span><br><span class="line"> level += <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> (level&lt;ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">#define ZSKIPLIST_P 0.25 &#x2F;* Skiplist P &#x3D; 1&#x2F;4 *&#x2F;
int zslRandomLevel(void) &#123;
int level &#x3D; 1;
while ((random()&amp;0xFFFF) &lt; (ZSKIPLIST_P * 0xFFFF))
level +&#x3D; 1;
return (level&lt;ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>当随机值跟0xFFFF进行与操作小于ZSKIPLIST_P * 0xFFFF时才会增大 level 的值,因此保持了一个相对递减的概率<br>可以简单分析下,当 random() 的值小于 0xFFFF 的 1/4,才会 level + 1,就意味着当有 1 - 1/4也就是3/4的概率是直接跳出,所以一层的概率是3/4,也就是 1-P,二层的概率是 P*(1-P),三层的概率是 P² * (1-P) 依次递推。</p>
</div>
@ -325,19 +341,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩表</a></div>
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快</a></div>
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩</a></div>
</li>
</ul>
@ -464,7 +480,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#跳表-skiplist"><span class="nav-number">1.</span> <span class="nav-text">跳表 skiplist</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%B7%B3%E8%A1%A8-skiplist"><span class="nav-number">1.</span> <span class="nav-text">跳表 skiplist</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 31
- 25
2020/01/10/redis数据结构介绍三/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,23 +26,20 @@
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>
<meta name="description" content="redis中对于 set 其实有两种处理,对于元素均为整型,并且元素数目较少时,使用 intset 作为底层数据结构,否则使用 dict 作为底层数据结构,先看一下代码先 1234567891011121314typedef struct intset &amp;#123; &#x2F;&#x2F; 编码方式 uint32_t encoding; &#x2F;&#x2F; 集合包含的元素数量 uint32_t lengt">
<meta name="description" content="redis中对于 set 其实有两种处理,对于元素均为整型,并且元素数目较少时,使用 intset 作为底层数据结构,否则使用 dict 作为底层数据结构,先看一下代码先 typedef struct intset &amp;#123; &#x2F;&#x2F; 编码方式 uint32_t encoding; &#x2F;&#x2F; 集合包含的元素数量 uint32_t">
<meta property="og:type" content="article">
<meta property="og:title" content="redis数据结构介绍三-第三部分 整数集合">
<meta property="og:url" content="https://nicksxs.me/2020/01/10/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D%E4%B8%89/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="redis中对于 set 其实有两种处理,对于元素均为整型,并且元素数目较少时,使用 intset 作为底层数据结构,否则使用 dict 作为底层数据结构,先看一下代码先 1234567891011121314typedef struct intset &amp;#123; &#x2F;&#x2F; 编码方式 uint32_t encoding; &#x2F;&#x2F; 集合包含的元素数量 uint32_t lengt">
<meta property="og:description" content="redis中对于 set 其实有两种处理,对于元素均为整型,并且元素数目较少时,使用 intset 作为底层数据结构,否则使用 dict 作为底层数据结构,先看一下代码先 typedef struct intset &amp;#123; &#x2F;&#x2F; 编码方式 uint32_t encoding; &#x2F;&#x2F; 集合包含的元素数量 uint32_t">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/01/10/qIc6HgP7wfCLipN.png">
<meta property="article:published_time" content="2020-01-09T16:54:04.000Z">
<meta property="article:modified_time" content="2020-01-12T13:08:27.000Z">
<meta property="article:modified_time" content="2020-01-09T16:54:04.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="redis">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="集合">
<meta property="article:tag" content="intset">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/01/10/qIc6HgP7wfCLipN.png">
@ -236,13 +233,6 @@
<time title="Created: 2020-01-10 00:54:04" itemprop="dateCreated datePublished" datetime="2020-01-10T00:54:04+08:00">2020-01-10</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-01-12 21:08:27" itemprop="dateModified" datetime="2020-01-12T21:08:27+08:00">2020-01-12</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -309,13 +299,29 @@
<p>redis中对于 set 其实有两种处理,对于元素均为整型,并且元素数目较少时,使用 intset 作为底层数据结构,否则使用 dict 作为底层数据结构,先看一下代码先</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">intset</span> &#123;</span></span><br><span class="line"> <span class="comment">// 编码方式</span></span><br><span class="line"> <span class="keyword">uint32_t</span> encoding;</span><br><span class="line"> <span class="comment">// 集合包含的元素数量</span></span><br><span class="line"> <span class="keyword">uint32_t</span> length;</span><br><span class="line"> <span class="comment">// 保存元素的数组</span></span><br><span class="line"> <span class="keyword">int8_t</span> contents[];</span><br><span class="line">&#125; intset;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Note that these encodings are ordered, so:</span></span><br><span class="line"><span class="comment"> * INTSET_ENC_INT16 &lt; INTSET_ENC_INT32 &lt; INTSET_ENC_INT64. */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> INTSET_ENC_INT16 (sizeof(int16_t))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> INTSET_ENC_INT32 (sizeof(int32_t))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> INTSET_ENC_INT64 (sizeof(int64_t))</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">typedef struct intset &#123;
&#x2F;&#x2F; 编码方式
uint32_t encoding;
&#x2F;&#x2F; 集合包含的元素数量
uint32_t length;
&#x2F;&#x2F; 保存元素的数组
int8_t contents[];
&#125; intset;
&#x2F;* Note that these encodings are ordered, so:
* INTSET_ENC_INT16 &lt; INTSET_ENC_INT32 &lt; INTSET_ENC_INT64. *&#x2F;
#define INTSET_ENC_INT16 (sizeof(int16_t))
#define INTSET_ENC_INT32 (sizeof(int32_t))
#define INTSET_ENC_INT64 (sizeof(int64_t))<span aria-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></code></pre>
<p>一眼看,为啥整型还需要编码,然后 int8_t 怎么能存下大整形呢,带着这些疑问,我们一步步分析下去,这里的编码其实指的是这个整型集合里存的究竟是多大的整型,16 位,还是 32 位,还是 64 位,结构体下面的宏定义就是表示了 encoding 的可能取值,INTSET_ENC_INT16 表示每个元素用2个字节存储,INTSET_ENC_INT32 表示每个元素用4个字节存储,INTSET_ENC_INT64 表示每个元素用8个字节存储。因此,intset中存储的整数最多只能占用64bit。length 就是正常的表示集合中元素的数量。最奇怪的应该就是这个 contents 了,是个 int8_t 的数组,那放毛线数据啊,最小的都有 16 位,这里我在看代码和《redis 设计与实现》的时候也有点懵逼,后来查了下发现这是个比较取巧的用法,这里我用自己的理解表述一下,先看看 8,16,32,64 的关系,一眼看就知道都是 2 的 N 次,并且呈两倍关系,而且 8 位刚好一个字节,所以呢其实这里的contents 不是个常规意义上的 int8_t 类型的数组,而是个柔性数组。看下 wiki 的定义</p>
<blockquote>
<p>Flexible array members<a href="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-1" target="_blank" rel="noopener">1</a> were introduced in the <a href="https://en.wikipedia.org/wiki/C99" target="_blank" rel="noopener">C99</a> standard of the <a href="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).<a href="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<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Flexible_array_member#cite_note-1">1</a> were introduced in the <a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/C99">C99</a> standard of the <a target="_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).<a target="_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>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">vectord</span> &#123;</span></span><br><span class="line"> <span class="keyword">size_t</span> len;</span><br><span class="line"> <span class="keyword">double</span> arr[]; <span class="comment">// the flexible array member must be last</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>在初始化这个 intset 的时候,这个contents数组是不占用空间的,后面的反正用到了申请,那么这里就有一个问题,给出了三种可能的 encoding 值,他们能随便换吗,显然不行,首先在 intset 中数据的存放是有序的,这个有部分原因是方便二分查找,然后存放数据其实随着数据的大小不同会有一个升级的过程,看下图<br><img data-src="https://i.loli.net/2020/01/10/qIc6HgP7wfCLipN.png" alt=""><br>新创建的intset只有一个header,总共8个字节。其中encoding = 2, length = 0, 类型都是uint32_t,各占 4 字节,添加15, 5两个元素之后,因为它们是比较小的整数,都能使用2个字节表示,所以encoding不变,值还是2,也就是默认的 <code>INTSET_ENC_INT16</code>,当添加32768的时候,它不再能用2个字节来表示了(2个字节能表达的数据范围是-215~215-1,而32768等于215,超出范围了),因此encoding必须升级到INTSET_ENC_INT32(值为4),即用4个字节表示一个元素。在添加每个元素的过程中,intset始终保持从小到大有序。与ziplist类似,intset也是按小端(little endian)模式存储的(参见维基百科词条<a href="https://en.wikipedia.org/wiki/Endianness" target="_blank" rel="noopener">Endianness</a>)。比如,在上图中intset添加完所有数据之后,表示encoding字段的4个字节应该解释成0x00000004,而第4个数据应该解释成0x00008000 = 32768</p>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">struct vectord &#123;
size_t len;
double arr[]; &#x2F;&#x2F; the flexible array member must be last
&#125;;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<p>在初始化这个 intset 的时候,这个contents数组是不占用空间的,后面的反正用到了申请,那么这里就有一个问题,给出了三种可能的 encoding 值,他们能随便换吗,显然不行,首先在 intset 中数据的存放是有序的,这个有部分原因是方便二分查找,然后存放数据其实随着数据的大小不同会有一个升级的过程,看下图<br><img data-src="https://i.loli.net/2020/01/10/qIc6HgP7wfCLipN.png"><br>新创建的intset只有一个header,总共8个字节。其中encoding = 2, length = 0, 类型都是uint32_t,各占 4 字节,添加15, 5两个元素之后,因为它们是比较小的整数,都能使用2个字节表示,所以encoding不变,值还是2,也就是默认的 <code>INTSET_ENC_INT16</code>,当添加32768的时候,它不再能用2个字节来表示了(2个字节能表达的数据范围是-215~215-1,而32768等于215,超出范围了),因此encoding必须升级到INTSET_ENC_INT32(值为4),即用4个字节表示一个元素。在添加每个元素的过程中,intset始终保持从小到大有序。与ziplist类似,intset也是按小端(little endian)模式存储的(参见维基百科词条<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Endianness">Endianness</a>)。比如,在上图中intset添加完所有数据之后,表示encoding字段的4个字节应该解释成0x00000004,而第4个数据应该解释成0x00008000 = 32768</p>
</div>
@ -326,19 +332,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/04/redis数据结构介绍二/" rel="bookmark">redis数据结构介绍二-第二部分 跳表</a></div>
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
<div class="popular-posts-title"><a href="/2020/01/04/redis数据结构介绍二/" rel="bookmark">redis数据结构介绍二-第二部分 跳表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩表</a></div>
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快</a></div>
<div class="popular-posts-title"><a href="/2020/01/19/redis数据结构介绍四/" rel="bookmark">redis数据结构介绍四-第四部分 压缩</a></div>
</li>
</ul>


+ 37
- 13
2020/01/19/redis数据结构介绍四/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,16 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2020/01/19/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D%E5%9B%9B/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="在 redis 中还有一类表型数据结构叫压缩表,ziplist,它的目的是替代链表,链表是个很容易理解的数据结构,双向链表有前后指针,有带头结点的有的不带,但是链表有个比较大的问题是相对于普通的数组,它的内存不连续,碎片化的存储,内存利用效率不高,而且指针寻址相对于直接使用偏移量的话,也有一定的效率劣势,当然这不是主要的原因,ziplist 设计的主要目的是让链表的内存使用更高效 The zip">
<meta property="og:locale">
<meta property="article:published_time" content="2020-01-18T16:00:22.000Z">
<meta property="article:modified_time" content="2020-01-18T16:00:22.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="redis">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="压缩表">
<meta property="article:tag" content="ziplist">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/01/19/redis%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%BB%8B%E7%BB%8D%E5%9B%9B/">
@ -303,13 +300,40 @@
<blockquote>
<p>The ziplist is a specially encoded dually linked list that is designed to be very memory efficient.<br>这是摘自 redis 源码中ziplist.c 文件的注释,也说明了原因,它的大概结构是这样子</p>
</blockquote>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;zlbytes&gt; &lt;zltail&gt; &lt;zllen&gt; &lt;entry&gt; &lt;entry&gt; ... &lt;entry&gt; &lt;zlend&gt;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">&lt;zlbytes&gt; &lt;zltail&gt; &lt;zllen&gt; &lt;entry&gt; &lt;entry&gt; ... &lt;entry&gt; &lt;zlend&gt;<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>其中<br><code>&lt;zlbytes&gt;</code>表示 ziplist 占用的字节总数,类型是uint32_t,32 位的无符号整型,当然表示的字节数也包含自己本身占用的 4 个<br><code>&lt;zltail&gt;</code> 类型也是是uint32_t,表示ziplist表中最后一项(entry)在ziplist中的偏移字节数。<code>&lt;zltail&gt;</code>的存在,使得我们可以很方便地找到最后一项(不用遍历整个ziplist),从而可以在ziplist尾端快速地执行push或pop操作。<br><code>&lt;uint16_t zllen&gt;</code> 表示ziplist 中的数据项个数,因为是 16 位,所以当数量超过所能表示的最大的数量,它的 16 位全会置为 1,但是真实的数量需要遍历整个 ziplist 才能知道<br><code>&lt;entry&gt;</code>是具体的数据项,后面解释<br><code>&lt;zlend&gt;</code> ziplist 的最后一个字节,固定是255。<br>再看一下<code>&lt;entry&gt;</code>中的具体结构,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;prevlen&gt; &lt;encoding&gt; &lt;entry-data&gt;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">&lt;prevlen&gt; &lt;encoding&gt; &lt;entry-data&gt;<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>首先这个<code>&lt;prevlen&gt;</code>有两种情况,一种是前面的元素的长度,如果是小于等于 253的时候就用一个uint8_t 来表示前一元素的长度,如果大于的话他将占用五个字节,第一个字节是 254,即表示这个字节已经表示不下了,需要后面的四个字节帮忙表示<br><code>&lt;encoding&gt;</code>这个就比较复杂,把源码的注释放下面先看下</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">* |00pppppp| - 1 byte</span><br><span class="line">* String value with length less than or equal to 63 bytes (6 bits).</span><br><span class="line">* &quot;pppppp&quot; represents the unsigned 6 bit length.</span><br><span class="line">* |01pppppp|qqqqqqqq| - 2 bytes</span><br><span class="line">* String value with length less than or equal to 16383 bytes (14 bits).</span><br><span class="line">* IMPORTANT: The 14 bit number is stored in big endian.</span><br><span class="line">* |10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes</span><br><span class="line">* String value with length greater than or equal to 16384 bytes.</span><br><span class="line">* Only the 4 bytes following the first byte represents the length</span><br><span class="line">* up to 32^2-1. The 6 lower bits of the first byte are not used and</span><br><span class="line">* are set to zero.</span><br><span class="line">* IMPORTANT: The 32 bit number is stored in big endian.</span><br><span class="line">* |11000000| - 3 bytes</span><br><span class="line">* Integer encoded as int16_t (2 bytes).</span><br><span class="line">* |11010000| - 5 bytes</span><br><span class="line">* Integer encoded as int32_t (4 bytes).</span><br><span class="line">* |11100000| - 9 bytes</span><br><span class="line">* Integer encoded as int64_t (8 bytes).</span><br><span class="line">* |11110000| - 4 bytes</span><br><span class="line">* Integer encoded as 24 bit signed (3 bytes).</span><br><span class="line">* |11111110| - 2 bytes</span><br><span class="line">* Integer encoded as 8 bit signed (1 byte).</span><br><span class="line">* |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer.</span><br><span class="line">* Unsigned integer from 0 to 12. The encoded value is actually from</span><br><span class="line">* 1 to 13 because 0000 and 1111 can not be used, so 1 should be</span><br><span class="line">* subtracted from the encoded 4 bit value to obtain the right value.</span><br><span class="line">* |11111111| - End of ziplist special entry.</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">* |00pppppp| - 1 byte
* String value with length less than or equal to 63 bytes (6 bits).
* &quot;pppppp&quot; represents the unsigned 6 bit length.
* |01pppppp|qqqqqqqq| - 2 bytes
* String value with length less than or equal to 16383 bytes (14 bits).
* IMPORTANT: The 14 bit number is stored in big endian.
* |10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes
* 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.<span aria-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>
<p>首先如果 encoding 的前两位是 00 的话代表这个元素是个 6 位的字符串,即直接将数据保存在 encoding 中,不消耗额外的<code>&lt;entry-data&gt;</code>,如果前两位是 01 的话表示是个 14 位的字符串,如果是 10 的话表示encoding 块之后的四个字节是存放字符串类型的数据,encoding 的剩余 6 位置 0。<br>如果 encoding 的前两位是 11 的话表示这是个整型,具体的如果后两位是00的话,表示后面是个2字节的 int16_t 类型,如果是01的话,后面是个4字节的int32_t,如果是10的话后面是8字节的int64_t,如果是 11 的话后面是 3 字节的有符号整型,这些都要最后 4 位都是 0 的情况噢<br>剩下当是<code>11111110</code>时,则表示是一个1 字节的有符号数,如果是 <code>1111xxxx</code>,其中<code>xxxx</code>在0000 到 1101 表示实际的 1 到 13,为啥呢,因为 0000 前面已经用过了,而 1110 跟 1111 也都有用了。<br>看个具体的例子(上下有点对不齐,将就看)</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[0f 00 00 00] [0c 00 00 00] [02 00] [00 f3] [02 f6] [ff]</span><br><span class="line">|**zlbytes***| |***zltail***| |*zllen*| |entry1 entry2| |zlend|</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">[0f 00 00 00] [0c 00 00 00] [02 00] [00 f3] [02 f6] [ff]
|**zlbytes***| |***zltail***| |*zllen*| |entry1 entry2| |zlend|<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>第一部分代表整个 ziplist 有 15 个字节,zlbytes 自己占了 4 个 zltail 表示最后一个元素的偏移量,第 13 个字节起,zllen 表示有 2 个元素,第一个元素是<code>00f3</code>,00表示前一个元素长度是 0,本来前面就没元素(不过不知道这个能不能优化这一字节),然后是 f3,换成二进制就是11110011,对照上面的注释,是落在|1111xxxx|这个类型里,注意这个其实是用 0001 到 1101 也就是 1到 13 来表示 0到 12,所以 f3 应该就是 2,第一个元素是 2,第二个元素呢,02 代表前一个元素也就是刚才说的这个,占用 2 字节,f6 展开也是刚才的类型,实际是 5,ff 表示 ziplist 的结尾,所以这个 ziplist 里面是两个元素,2 跟 5</p>
</div>
@ -320,6 +344,9 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
</li>
@ -329,9 +356,6 @@
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/22/redis数据结构介绍六/" rel="bookmark">redis数据结构介绍六 快表</a></div>
</li>


+ 44
- 12
2020/01/20/redis数据结构介绍五/index.html
File diff suppressed because it is too large
View File


+ 189
- 23
2020/01/22/redis数据结构介绍六/index.html
File diff suppressed because it is too large
View File


+ 9
- 9
2020/02/01/2019年终总结/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,11 +32,12 @@
<meta property="og:url" content="https://nicksxs.me/2020/02/01/2019%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="今天是农历初八了,年前一个月的时候就准备做下今年的年终总结,可是写了一点觉得太情绪化了,希望后面写个平淡点的,正好最近技术方面还没有看到一个完整成文的内容,就来写一下这一年的总结,尽量少写一点太情绪化的东西。 跳槽年初换了个公司,也算换了个环境,跟前公司不太一样,做的事情方向也不同,可能是侧重点不同,一开始有些不适应,主要是压力上,会觉得压力比较大,但是总体来说与人相处的部分还是不错的,做的技术方">
<meta property="og:locale">
<meta property="article:published_time" content="2020-02-01T14:23:53.000Z">
<meta property="article:modified_time" content="2020-02-01T14:41:22.000Z">
<meta property="article:modified_time" content="2020-02-01T14:23:53.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="年终总结">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="年终总结">
<meta property="article:tag" content="2019">
<meta name="twitter:card" content="summary">
@ -227,9 +228,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-02-01 22:23:53 / Modified: 22:41:22" itemprop="dateCreated datePublished" datetime="2020-02-01T22:23:53+08:00">2020-02-01</time>
<time title="Created: 2020-02-01 22:23:53" itemprop="dateCreated datePublished" datetime="2020-02-01T22:23:53+08:00">2020-02-01</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -318,13 +318,13 @@
<div class="popular-posts-title"><a href="/2020/09/26/在老丈人家的小工记四/" rel="bookmark">在老丈人家的小工记四</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/13/在老丈人家的小工记三/" rel="bookmark">在老丈人家的小工记三</a></div>
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
</li>
</ul>
@ -451,7 +451,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#跳槽"><span class="nav-number">1.</span> <span class="nav-text">跳槽</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#面试"><span class="nav-number">2.</span> <span class="nav-text">面试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#技术方向"><span class="nav-number">3.</span> <span class="nav-text">技术方向</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#生活"><span class="nav-number">4.</span> <span class="nav-text">生活</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#期待"><span class="nav-number">5.</span> <span class="nav-text">期待</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B7%B3%E6%A7%BD"><span class="nav-number">1.</span> <span class="nav-text">跳槽</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95"><span class="nav-number">2.</span> <span class="nav-text">面试</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8A%80%E6%9C%AF%E6%96%B9%E5%90%91"><span class="nav-number">3.</span> <span class="nav-text">技术方向</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%94%9F%E6%B4%BB"><span class="nav-number">4.</span> <span class="nav-text">生活</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%9C%9F%E5%BE%85"><span class="nav-number">5.</span> <span class="nav-text">期待</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 65
- 9
2020/02/09/G1收集器概述/index.html
File diff suppressed because it is too large
View File


+ 52
- 12
2020/02/16/Maven实用小技巧/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/02/16/Maven%E5%AE%9E%E7%94%A8%E5%B0%8F%E6%8A%80%E5%B7%A7/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="Maven 翻译为”专家”、”内行”,是 Apache 下的一个纯 Java 开发的开源项目。基于项目对象模型(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。 Maven 是一个项目管理工具,可以对 Java 项目进行构建、依赖管理。 Maven 也可被用于构建和管理各种项目,例如 C#,Ruby,Scala 和其他语言编写的项目。Maven 曾是 Ja">
<meta property="og:locale">
<meta property="article:published_time" content="2020-02-16T02:39:42.000Z">
<meta property="article:modified_time" content="2020-02-16T06:36:56.000Z">
<meta property="article:modified_time" content="2020-02-16T02:39:42.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Maven">
@ -226,9 +227,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-02-16 10:39:42 / Modified: 14:36:56" itemprop="dateCreated datePublished" datetime="2020-02-16T10:39:42+08:00">2020-02-16</time>
<time title="Created: 2020-02-16 10:39:42" itemprop="dateCreated datePublished" datetime="2020-02-16T10:39:42+08:00">2020-02-16</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -297,15 +297,55 @@
<li><code>mvn deploy</code><br> 将打出来的 jar 包上传到远程仓库里</li>
</ul>
<h3 id="与-composer-对比"><a href="#与-composer-对比" class="headerlink" title="与 composer 对比"></a>与 composer 对比</h3><p>因为我也是个 PHP 程序员,所以对比一下两种语言,很容易想到在 PHP 的 composer 跟 Java 的 maven 是比较类似的作用,有一点两者是非常相似的,就是原仓库都是因为某些原因连接拉取都会很慢,所以像 composer 会有一些国内源,前阵子阿里也出了一个,类似的 maven 一般也会使用阿里的镜像仓库,通过在 setting.xml 文件中的设置</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">&lt;mirrors&gt;</span><br><span class="line"> &lt;mirror&gt;</span><br><span class="line"> &lt;id&gt;aliyun&lt;&#x2F;id&gt;</span><br><span class="line"> &lt;name&gt;aliyun maven&lt;&#x2F;name&gt;</span><br><span class="line"> &lt;url&gt;http:&#x2F;&#x2F;maven.aliyun.com&#x2F;nexus&#x2F;content&#x2F;groups&#x2F;public&#x2F;&lt;&#x2F;url&gt;</span><br><span class="line"> &lt;mirrorOf&gt;central&lt;&#x2F;mirrorOf&gt;</span><br><span class="line"> &lt;&#x2F;mirror&gt; </span><br><span class="line">&lt;&#x2F;mirrors&gt;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none">&lt;mirrors&gt;
&lt;mirror&gt;
&lt;id&gt;aliyun&lt;&#x2F;id&gt;
&lt;name&gt;aliyun maven&lt;&#x2F;name&gt;
&lt;url&gt;http:&#x2F;&#x2F;maven.aliyun.com&#x2F;nexus&#x2F;content&#x2F;groups&#x2F;public&#x2F;&lt;&#x2F;url&gt;
&lt;mirrorOf&gt;central&lt;&#x2F;mirrorOf&gt;
&lt;&#x2F;mirror&gt;
&lt;&#x2F;mirrors&gt;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这算是个尴尬的共同点,然后因为 PHP 是解释型脚本语言,所以 php 打出来的 composer 包其实就是个 php 代码包,使用SPL Autoload等方式加载代码包,maven 包则是经过编译的 class 包,还有一点是 composer 也可以直接使用 github 地址作为包代码的拉取源,这点也是比较大的区别,maven使用 pom 文件管理依赖</p>
<h3 id="maven-的个人小技巧"><a href="#maven-的个人小技巧" class="headerlink" title="maven 的个人小技巧"></a>maven 的个人小技巧</h3><ul>
<li>maven 拉取依赖时,同时将 snapshot 也更新了,就是 <code>mvn compile</code>加个<code>-U</code>参数,如果还不行就需要将本地仓库的 snapshot 删掉,<br>这个命令的 help 命令解释是 -U,–update-snapshots Forces a check for missing releases and updated snapshots on<br>remote repositories,这个在日常使用中还是很经常使用的</li>
<li>maven 出现依赖冲突的时候的解决方法<br>首先是依赖分析,使用<code>mvn dependency:tree</code>分析下依赖关系,如果要找具体某个包的依赖引用关系可以使用<code>mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-webmvc</code>命令进行分析,如果发现有冲突的依赖关系,本身 maven 中依赖引用有相对的顺序,大致来说是引用路径短的优先,pom 文件中定义的顺序优先,如果要把冲突的包排除掉可以在 pom 中用<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;exclusions&gt;</span><br><span class="line"> &lt;exclusion&gt;</span><br><span class="line"> &lt;groupId&gt;ch.qos.logback&lt;&#x2F;groupId&gt;</span><br><span class="line"> &lt;artifactId&gt;logback-classic&lt;&#x2F;artifactId&gt;</span><br><span class="line"> &lt;&#x2F;exclusion&gt;</span><br><span class="line">&lt;&#x2F;exclusions&gt;</span><br></pre></td></tr></table></figure>
<li>maven 出现依赖冲突的时候的解决方法<br>首先是依赖分析,使用<code>mvn dependency:tree</code>分析下依赖关系,如果要找具体某个包的依赖引用关系可以使用<code>mvn dependency:tree -Dverbose -Dincludes=org.springframework:spring-webmvc</code>命令进行分析,如果发现有冲突的依赖关系,本身 maven 中依赖引用有相对的顺序,大致来说是引用路径短的优先,pom 文件中定义的顺序优先,如果要把冲突的包排除掉可以在 pom 中用<pre class="line-numbers language-none"><code class="language-none">&lt;exclusions&gt;
&lt;exclusion&gt;
&lt;groupId&gt;ch.qos.logback&lt;&#x2F;groupId&gt;
&lt;artifactId&gt;logback-classic&lt;&#x2F;artifactId&gt;
&lt;&#x2F;exclusion&gt;
&lt;&#x2F;exclusions&gt;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
将冲突的包排除掉</li>
<li>maven 依赖的 jdk 版本管理<br>前面介绍的<code>mvn -v</code>可以查看 maven 的安装信息<br>比如<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)</span><br><span class="line">Maven home: &#x2F;usr&#x2F;local&#x2F;Cellar&#x2F;maven&#x2F;3.6.3_1&#x2F;libexec</span><br><span class="line">Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: &#x2F;Library&#x2F;Java&#x2F;JavaVirtualMachines&#x2F;jdk1.8.0_201.jdk&#x2F;Contents&#x2F;Home&#x2F;jre</span><br><span class="line">Default locale: zh_CN, platform encoding: UTF-8</span><br><span class="line">OS name: &quot;mac os x&quot;, version: &quot;10.14.6&quot;, arch: &quot;x86_64&quot;, family: &quot;mac&quot;</span><br></pre></td></tr></table></figure>
这里可以看到用了 mac 自带的 jdk1.8,结合我之前碰到的一个问题,因为使用 homebrew 升级了 gradle,而 gradle 又依赖了 jdk13,因为这个 mvn 的 Java version 也变成 jdk13 了,然后 mvn 编译的时候出现了 <code>java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags</code>这个问题,所以需要把这个版本给改回来,但是咋改呢,网上搜来的一大堆都是在 pom 文件里的<br>source和 target 版本<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;build&gt;</span><br><span class="line"> &lt;plugins&gt;</span><br><span class="line">&lt;plugin&gt;</span><br><span class="line"> &lt;groupId&gt;org.apache.maven.plugins&lt;&#x2F;groupId&gt;</span><br><span class="line"> &lt;artifactId&gt;maven-compiler-plugin&lt;&#x2F;artifactId&gt;</span><br><span class="line"> &lt;configuration&gt;</span><br><span class="line"> &lt;source&gt;1.8&lt;&#x2F;source&gt;</span><br><span class="line"> &lt;target&gt;1.8&lt;&#x2F;target&gt;</span><br><span class="line"> &lt;encoding&gt;UTF-8&lt;&#x2F;encoding&gt;</span><br><span class="line"> &lt;&#x2F;configuration&gt;</span><br><span class="line">&lt;&#x2F;plugin&gt;</span><br><span class="line"> &lt;&#x2F;plugins&gt;</span><br><span class="line">&lt;build&gt;</span><br></pre></td></tr></table></figure>
或者修改 maven 的 setting.xml中的<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">&lt;profiles&gt;</span><br><span class="line"> &lt;profile&gt;</span><br><span class="line"> &lt;id&gt;ngmm-nexus&lt;&#x2F;id&gt;</span><br><span class="line"> &lt;activation&gt;</span><br><span class="line"> &lt;jdk&gt;1.8&lt;&#x2F;jdk&gt;</span><br><span class="line"> &lt;&#x2F;activation&gt;</span><br><span class="line"> &lt;properties&gt;</span><br><span class="line"> &lt;maven.compiler.source&gt;1.8&lt;&#x2F;maven.compiler.source&gt;</span><br><span class="line"> &lt;maven.compiler.target&gt;1.8&lt;&#x2F;maven.compiler.target&gt;</span><br><span class="line"> &lt;maven.compiler.compilerVersion&gt;1.8&lt;&#x2F;maven.compiler.compilerVersion&gt;</span><br><span class="line"> &lt;&#x2F;properties&gt;</span><br><span class="line"> &lt;&#x2F;profile&gt;</span><br><span class="line">&lt;&#x2F;profiles&gt;</span><br></pre></td></tr></table></figure>
<li>maven 依赖的 jdk 版本管理<br>前面介绍的<code>mvn -v</code>可以查看 maven 的安装信息<br>比如<pre class="line-numbers language-none"><code class="language-none">Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: &#x2F;usr&#x2F;local&#x2F;Cellar&#x2F;maven&#x2F;3.6.3_1&#x2F;libexec
Java version: 1.8.0_201, vendor: Oracle Corporation, runtime: &#x2F;Library&#x2F;Java&#x2F;JavaVirtualMachines&#x2F;jdk1.8.0_201.jdk&#x2F;Contents&#x2F;Home&#x2F;jre
Default locale: zh_CN, platform encoding: UTF-8
OS name: &quot;mac os x&quot;, version: &quot;10.14.6&quot;, arch: &quot;x86_64&quot;, family: &quot;mac&quot;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
这里可以看到用了 mac 自带的 jdk1.8,结合我之前碰到的一个问题,因为使用 homebrew 升级了 gradle,而 gradle 又依赖了 jdk13,因为这个 mvn 的 Java version 也变成 jdk13 了,然后 mvn 编译的时候出现了 <code>java.lang.ExceptionInInitializerError: com.sun.tools.javac.code.TypeTags</code>这个问题,所以需要把这个版本给改回来,但是咋改呢,网上搜来的一大堆都是在 pom 文件里的<br>source和 target 版本<pre class="line-numbers language-none"><code class="language-none">&lt;build&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;&#x2F;groupId&gt;
&lt;artifactId&gt;maven-compiler-plugin&lt;&#x2F;artifactId&gt;
&lt;configuration&gt;
&lt;source&gt;1.8&lt;&#x2F;source&gt;
&lt;target&gt;1.8&lt;&#x2F;target&gt;
&lt;encoding&gt;UTF-8&lt;&#x2F;encoding&gt;
&lt;&#x2F;configuration&gt;
&lt;&#x2F;plugin&gt;
&lt;&#x2F;plugins&gt;
&lt;build&gt;<span aria-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></code></pre>
或者修改 maven 的 setting.xml中的<pre class="line-numbers language-none"><code class="language-none">&lt;profiles&gt;
&lt;profile&gt;
&lt;id&gt;ngmm-nexus&lt;&#x2F;id&gt;
&lt;activation&gt;
&lt;jdk&gt;1.8&lt;&#x2F;jdk&gt;
&lt;&#x2F;activation&gt;
&lt;properties&gt;
&lt;maven.compiler.source&gt;1.8&lt;&#x2F;maven.compiler.source&gt;
&lt;maven.compiler.target&gt;1.8&lt;&#x2F;maven.compiler.target&gt;
&lt;maven.compiler.compilerVersion&gt;1.8&lt;&#x2F;maven.compiler.compilerVersion&gt;
&lt;&#x2F;properties&gt;
&lt;&#x2F;profile&gt;
&lt;&#x2F;profiles&gt;<span aria-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></code></pre>
但是这些都没啥用啊,真正有办法的是建个 <code>.mavenrc</code>,这个顾名思义就是 maven 的资源文件,类似于 <code>.bashrc</code><code>.zshrc</code>,在里面添加 MAVEN_HOME 和 JAVA_HOME,然后执行 <code>source .mavenrc</code>就 OK 啦</li>
</ul>
@ -318,7 +358,7 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/05/22/聊聊我刚学会的应用诊断方法/" rel="bookmark">聊聊我刚学会的应用诊断方法</a></div>
<div class="popular-posts-title"><a href="/2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/" rel="bookmark">聊聊 Dubbo 的 SPI 续之自适应拓展</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/01/Apollo-的-value-注解是怎么自动更新的/" rel="bookmark">Apollo 的 value 注解是怎么自动更新的</a></div>
@ -330,7 +370,7 @@
<div class="popular-posts-title"><a href="/2020/09/06/mybatis-的-和-是有啥区别/" rel="bookmark">mybatis 的 $ 和 # 是有啥区别</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/" rel="bookmark">聊聊 Dubbo 的 SPI 续之自适应拓展</a></div>
<div class="popular-posts-title"><a href="/2020/10/03/mybatis-的缓存是怎么回事/" rel="bookmark">mybatis 的缓存是怎么回事</a></div>
</li>
</ul>
@ -456,7 +496,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#maven的基本操作"><span class="nav-number">1.</span> <span class="nav-text">maven的基本操作</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#与-composer-对比"><span class="nav-number">2.</span> <span class="nav-text">与 composer 对比</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#maven-的个人小技巧"><span class="nav-number">3.</span> <span class="nav-text">maven 的个人小技巧</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#maven%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%93%8D%E4%BD%9C"><span class="nav-number">1.</span> <span class="nav-text">maven的基本操作</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%B8%8E-composer-%E5%AF%B9%E6%AF%94"><span class="nav-number">2.</span> <span class="nav-text">与 composer 对比</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#maven-%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%B0%8F%E6%8A%80%E5%B7%A7"><span class="nav-number">3.</span> <span class="nav-text">maven 的个人小技巧</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 75
- 17
2020/02/22/gogs使用webhook部署react单页应用/index.html
File diff suppressed because it is too large
View File


+ 8
- 8
2020/03/01/寄生虫观后感/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,12 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2020/03/01/%E5%AF%84%E7%94%9F%E8%99%AB%E8%A7%82%E5%90%8E%E6%84%9F/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="寄生虫这部电影在获得奥斯卡之前就有关注了,豆瓣评分很高,一开始看到这个片名以为是像《铁线虫入侵》那种灾难片,后来看到男主,宋康昊,也是老面孔了,从高中时候在学校操场组织看的《汉江怪物》,有点二的感觉,后来在大学寝室电脑上重新看的时候,室友跟我说是韩国国宝级演员,真人不可貌相,感觉是个呆子的形象。 但是你说这不是个灾难片,而是个反映社会问题的,就业比较容易往这个方向猜,只是剧情会是怎么样的,一时也没">
<meta property="og:locale">
<meta property="article:published_time" content="2020-03-01T14:56:02.000Z">
<meta property="article:modified_time" content="2020-03-01T14:57:29.000Z">
<meta property="article:modified_time" content="2020-03-01T14:56:02.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="影评">
<meta property="article:tag" content="寄生虫">
<meta property="article:tag" content="2020">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/03/01/%E5%AF%84%E7%94%9F%E8%99%AB%E8%A7%82%E5%90%8E%E6%84%9F/">
@ -227,9 +228,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-03-01 22:56:02 / Modified: 22:57:29" itemprop="dateCreated datePublished" datetime="2020-03-01T22:56:02+08:00">2020-03-01</time>
<time title="Created: 2020-03-01 22:56:02" itemprop="dateCreated datePublished" datetime="2020-03-01T22:56:02+08:00">2020-03-01</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -307,16 +307,16 @@
<div class="popular-posts-title"><a href="/2020/10/18/在老丈人家的小工记五/" rel="bookmark">在老丈人家的小工记五</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/02/01/2019年终总结/" rel="bookmark">2019年终总结</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/03/31/2020-年终总结/" rel="bookmark">2020 年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
</ul>


+ 23
- 27
2020/03/08/docker比一般多一点的初学者介绍/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,6 +32,7 @@
<meta property="og:url" content="https://nicksxs.me/2020/03/08/docker%E6%AF%94%E4%B8%80%E8%88%AC%E5%A4%9A%E4%B8%80%E7%82%B9%E7%9A%84%E5%88%9D%E5%AD%A6%E8%80%85%E4%BB%8B%E7%BB%8D/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="因为最近想搭一个phabricator用来做看板和任务管理,一开始了解这个是Easy大大有在微博推荐过,后来苏洋也在群里和博客里说到了,看上去还不错的样子,因为主角是docker所以就不介绍太多,后面有机会写一下。 docker最开始是之前在某位大佬的博客看到的,看上去有点神奇,感觉是一种轻量级的虚拟机,但是能做的事情好像差不多,那时候是在Ubuntu系统的vps里起一个Ubuntu的docker">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/03/08/IJP157hLqlgo4Ow.png">
<meta property="og:image" content="https://i.loli.net/2020/03/08/7dO2JWbf3wVLPsN.png">
<meta property="og:image" content="https://i.loli.net/2020/03/08/G3ltzyVLqheDRgo.png">
@ -41,7 +42,7 @@
<meta property="og:image" content="https://i.loli.net/2020/03/08/RJAvlhEMD7VfbXz.png">
<meta property="og:image" content="https://i.loli.net/2020/03/08/L4YRni95lBzEmFh.png">
<meta property="article:published_time" content="2020-03-08T15:25:40.000Z">
<meta property="article:modified_time" content="2020-03-15T12:25:02.000Z">
<meta property="article:modified_time" content="2020-03-08T15:25:40.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="namespace">
@ -239,13 +240,6 @@
<time title="Created: 2020-03-08 23:25:40" itemprop="dateCreated datePublished" datetime="2020-03-08T23:25:40+08:00">2020-03-08</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-03-15 20:25:02" itemprop="dateModified" datetime="2020-03-15T20:25:02+08:00">2020-03-15</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -304,41 +298,43 @@
<p>之前写的 mysql 集群,一主二备,这种架构在很多小型应用里都是这么配置的,而且一般是直接在三台 vps 里启动三个 mysql 实例,但是如果换成 docker 会有什么好处呢,其实就是方便部署,比如其中一台备库挂了,我要加一台,或者说备库的 qps 太高了,需要再加一个,如果要在 vps 上搭建的话,首先要买一台机器,等初始化,然后在上面修改源,更新,装 mysql ,然后配置主从,可能还要处理防火墙等等,如果把这些打包成一个 docker 镜像,并且放在自己的 docker registry,那就直接run 一下就可以了;还有比如在公司要给一个新同学整一套开发测试环境,以 Java 开发为例,要装 git,maven,jdk,配置 maven settings 和各种 rc,整合在一个镜像里的话,就会很方便了;再比如微服务的水平扩展。</p>
<p>但是为啥 docker 会有这种优势,听起来好像虚拟机也可以干这个事,但是虚拟机动辄上 G,而且需要 VMware,virtual box 等支持,不适合在Linux服务器环境使用,而且占用资源也会非常大。说得这么好,那么 docker 是啥呢</p>
<p>docker 主要使用 Linux 中已经存在的两种技术的一个整合升级,一个是 namespace,一个是cgroups,相比于虚拟机需要完整虚拟出一个操作系统运行基础,docker 基于宿主机内核,通过 namespace 和 cgroups 分隔进程,理念就是提供一个隔离的最小化运行依赖,这样子相对于虚拟机就有了巨大的便利性,具体的 namespace 和 cgroups 就先不展开讲,可以参考耗子叔的文章</p>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>那么我们先安装下 docker,参考官方的教程,<a href="https://docs.docker.com/install/linux/docker-ce/ubuntu/" target="_blank" rel="noopener">安装</a>,我的系统是 ubuntu 的,就贴了 ubuntu 的链接,用其他系统的可以找到对应的系统文档安装,安装完了的话看看 docker 的信息</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker info</span><br></pre></td></tr></table></figure>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>那么我们先安装下 docker,参考官方的教程,<a target="_blank" rel="noopener" href="https://docs.docker.com/install/linux/docker-ce/ubuntu/">安装</a>,我的系统是 ubuntu 的,就贴了 ubuntu 的链接,用其他系统的可以找到对应的系统文档安装,安装完了的话看看 docker 的信息</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">sudo docker info<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>输出以下信息<br><img data-src="https://i.loli.net/2020/03/08/IJP157hLqlgo4Ow.png" alt=""></p>
<p>输出以下信息<br><img data-src="https://i.loli.net/2020/03/08/IJP157hLqlgo4Ow.png"></p>
<h2 id="简单运行"><a href="#简单运行" class="headerlink" title="简单运行"></a>简单运行</h2><p>然后再来运行个 hello world 呗,</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker run hello-world</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">sudo docker run hello-world<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>输出了这些<br><img data-src="https://i.loli.net/2020/03/08/7dO2JWbf3wVLPsN.png" alt=""></p>
<p>输出了这些<br><img data-src="https://i.loli.net/2020/03/08/7dO2JWbf3wVLPsN.png"></p>
<p>看看这个运行命令是怎么用的,一般都会看到这样子的,sudo docker run -it ubuntu bash<code>, 前面的 docker run 反正就是运行一个容器的意思,</code>-it<code>是啥呢,还有这个什么 ubuntu bash,来看看</code>docker run`的命令帮助信息</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-i, --interactive Keep STDIN open even if not attached</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">-i, --interactive Keep STDIN open even if not attached<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>就是要有输入,我们运行的时候能输入</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-t, --tty Allocate a pseudo-TTY</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">-t, --tty Allocate a pseudo-TTY<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>要有个虚拟终端,</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]</span><br><span class="line"></span><br><span class="line">Run a command in a new container</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h2 id="镜像"><a href="#镜像" class="headerlink" title="镜像"></a>镜像</h2><p>上面说的-it 就是这里的 options,后面那个 ubuntu 就是 image 辣,image 是啥呢</p>
<p><strong>Docker 把应用程序及其依赖,打包在 image 文件里面</strong>,可以把它理解成为类似于虚拟机的镜像或者运行一个进程的代码,跑起来了的叫docker 容器或者进程,比如我们将要运行的<code>docker run -it ubuntu bash</code>的ubuntu 就是个 ubuntu 容器的镜像,将这个镜像运行起来后,我们可以进入容器像使用 ubuntu 一样使用它,来看下我们的镜像,使用<code>sudo docker image ls</code>就能列出我们宿主机上的 docker 镜像了</p>
<p><img data-src="https://i.loli.net/2020/03/08/G3ltzyVLqheDRgo.png" alt=""></p>
<p><img data-src="https://i.loli.net/2020/03/08/G3ltzyVLqheDRgo.png"></p>
<p>一个 ubuntu 镜像才 64MB,非常小巧,然后是后面的<code>bash</code>,我通过交互式启动了一个 ubuntu 容器,然后在这个启动的容器里运行了 bash 命令,这样就可以在容器里玩一下了</p>
<h2 id="在容器里看下进程,"><a href="#在容器里看下进程," class="headerlink" title="在容器里看下进程,"></a>在容器里看下进程,</h2><p><img data-src="https://i.loli.net/2020/03/08/2qQFPbxB9uEzcrJ.png" alt=""></p>
<h2 id="在容器里看下进程,"><a href="#在容器里看下进程," class="headerlink" title="在容器里看下进程,"></a>在容器里看下进程,</h2><p><img data-src="https://i.loli.net/2020/03/08/2qQFPbxB9uEzcrJ.png"></p>
<p>只有刚才运行容器的 bash 进程和我刚执行的 ps,这里有个可以注意下的,bash 这个进程的 pid 是 1,其实这里就用到了 linux 中的PID Namespace,容器会隔离出一个 pid 的名字空间,这里面的进程跟外部的 pid 命名独立</p>
<h2 id="查看宿主机上的容器"><a href="#查看宿主机上的容器" class="headerlink" title="查看宿主机上的容器"></a>查看宿主机上的容器</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker ps -a</span><br></pre></td></tr></table></figure>
<h2 id="查看宿主机上的容器"><a href="#查看宿主机上的容器" class="headerlink" title="查看宿主机上的容器"></a>查看宿主机上的容器</h2><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">sudo docker ps -a<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://i.loli.net/2020/03/08/spGtzcDXKv3ORU7.png" alt=""></p>
<p><img data-src="https://i.loli.net/2020/03/08/spGtzcDXKv3ORU7.png"></p>
<h2 id="如何进入一个正在运行中的-docker-容器"><a href="#如何进入一个正在运行中的-docker-容器" class="headerlink" title="如何进入一个正在运行中的 docker 容器"></a>如何进入一个正在运行中的 docker 容器</h2><p>这个应该是比较常用的,因为比如是一个微服务容器,有时候就像看下运行状态,日志啥的</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker exec -it [containerID] bash</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">sudo docker exec -it [containerID] bash<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://i.loli.net/2020/03/08/uswmh3Izp65kc9n.png" alt=""></p>
<h2 id="查看日志"><a href="#查看日志" class="headerlink" title="查看日志"></a>查看日志</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo docker logs [containerID]</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2020/03/08/uswmh3Izp65kc9n.png"></p>
<h2 id="查看日志"><a href="#查看日志" class="headerlink" title="查看日志"></a>查看日志</h2><pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">sudo docker logs [containerID]<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>我在运行容器的终端里胡乱输入点啥,然后通过上面的命令就可以看到啦</p>
<p><img data-src="https://i.loli.net/2020/03/08/RJAvlhEMD7VfbXz.png" alt=""></p>
<p><img data-src="https://i.loli.net/2020/03/08/L4YRni95lBzEmFh.png" alt=""></p>
<p><img data-src="https://i.loli.net/2020/03/08/RJAvlhEMD7VfbXz.png"></p>
<p><img data-src="https://i.loli.net/2020/03/08/L4YRni95lBzEmFh.png"></p>
</div>
@ -482,7 +478,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#安装"><span class="nav-number">1.</span> <span class="nav-text">安装</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#简单运行"><span class="nav-number">2.</span> <span class="nav-text">简单运行</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#镜像"><span class="nav-number">3.</span> <span class="nav-text">镜像</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#在容器里看下进程,"><span class="nav-number">4.</span> <span class="nav-text">在容器里看下进程,</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#查看宿主机上的容器"><span class="nav-number">5.</span> <span class="nav-text">查看宿主机上的容器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#如何进入一个正在运行中的-docker-容器"><span class="nav-number">6.</span> <span class="nav-text">如何进入一个正在运行中的 docker 容器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#查看日志"><span class="nav-number">7.</span> <span class="nav-text">查看日志</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%89%E8%A3%85"><span class="nav-number">1.</span> <span class="nav-text">安装</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E8%BF%90%E8%A1%8C"><span class="nav-number">2.</span> <span class="nav-text">简单运行</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%95%9C%E5%83%8F"><span class="nav-number">3.</span> <span class="nav-text">镜像</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%9C%A8%E5%AE%B9%E5%99%A8%E9%87%8C%E7%9C%8B%E4%B8%8B%E8%BF%9B%E7%A8%8B%EF%BC%8C"><span class="nav-number">4.</span> <span class="nav-text">在容器里看下进程,</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9F%A5%E7%9C%8B%E5%AE%BF%E4%B8%BB%E6%9C%BA%E4%B8%8A%E7%9A%84%E5%AE%B9%E5%99%A8"><span class="nav-number">5.</span> <span class="nav-text">查看宿主机上的容器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%A6%82%E4%BD%95%E8%BF%9B%E5%85%A5%E4%B8%80%E4%B8%AA%E6%AD%A3%E5%9C%A8%E8%BF%90%E8%A1%8C%E4%B8%AD%E7%9A%84-docker-%E5%AE%B9%E5%99%A8"><span class="nav-number">6.</span> <span class="nav-text">如何进入一个正在运行中的 docker 容器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9F%A5%E7%9C%8B%E6%97%A5%E5%BF%97"><span class="nav-number">7.</span> <span class="nav-text">查看日志</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 27
- 20
2020/03/15/docker比一般多一点的初学者介绍二/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,12 +26,13 @@
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>
<meta name="description" content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 1234567#include &lt;stdio.h&gt;int main(void)&amp;#123; int i &#x3D; 0; for(;;) i++; return 0;&amp;#125; 就是一个最简单的死循环,然后在容器里跑起来 12$ gcc 1.c">
<meta name="description" content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 #include &lt;stdio.h&gt; int main(void) &amp;#123; int i &#x3D; 0; for(;;) i++; return 0; &amp;#125; 就是一个最简单的死循环,然后在容器里跑起来 $ gcc 1">
<meta property="og:type" content="article">
<meta property="og:title" content="docker比一般多一点的初学者介绍二">
<meta property="og:url" content="https://nicksxs.me/2020/03/15/docker%E6%AF%94%E4%B8%80%E8%88%AC%E5%A4%9A%E4%B8%80%E7%82%B9%E7%9A%84%E5%88%9D%E5%AD%A6%E8%80%85%E4%BB%8B%E7%BB%8D%E4%BA%8C/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 1234567#include &lt;stdio.h&gt;int main(void)&amp;#123; int i &#x3D; 0; for(;;) i++; return 0;&amp;#125; 就是一个最简单的死循环,然后在容器里跑起来 12$ gcc 1.c">
<meta property="og:description" content="限制下 docker 的 cpu 使用率这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码 #include &lt;stdio.h&gt; int main(void) &amp;#123; int i &#x3D; 0; for(;;) i++; return 0; &amp;#125; 就是一个最简单的死循环,然后在容器里跑起来 $ gcc 1">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/03/09/Xs562iawhHyMxeO.png">
<meta property="og:image" content="https://i.loli.net/2020/03/09/ecqH8XJ4k7rKhzu.png">
<meta property="og:image" content="https://i.loli.net/2020/03/15/x2oGCPQr9Mm8ZYj.png">
@ -42,12 +43,11 @@
<meta property="og:image" content="https://i.loli.net/2020/03/14/ALWIobjchnu1Rvi.png">
<meta property="og:image" content="https://i.loli.net/2020/03/14/grcMNVxTabDPipu.png">
<meta property="article:published_time" content="2020-03-15T14:33:55.000Z">
<meta property="article:modified_time" content="2020-03-16T14:16:28.000Z">
<meta property="article:modified_time" content="2020-03-15T14:33:55.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="namespace">
<meta property="article:tag" content="cgroup">
<meta property="article:tag" content="docker-image">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/03/09/Xs562iawhHyMxeO.png">
@ -241,13 +241,6 @@
<time title="Created: 2020-03-15 22:33:55" itemprop="dateCreated datePublished" datetime="2020-03-15T22:33:55+08:00">2020-03-15</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-03-16 22:16:28" itemprop="dateModified" datetime="2020-03-16T22:16:28+08:00">2020-03-16</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -302,17 +295,31 @@
<h2 id="限制下-docker-的-cpu-使用率"><a href="#限制下-docker-的-cpu-使用率" class="headerlink" title="限制下 docker 的 cpu 使用率"></a>限制下 docker 的 cpu 使用率</h2><p>这里我们开始玩一点有意思的,我们在容器里装下 vim 和 gcc,然后写这样一段 c 代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(;;) i++;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">#include &lt;stdio.h&gt;
int main(void)
&#123;
int i &#x3D; 0;
for(;;) i++;
return 0;
&#125;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>就是一个最简单的死循环,然后在容器里跑起来</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> gcc 1.c </span></span><br><span class="line"><span class="meta">$</span><span class="bash"> ./a.out</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">$ gcc 1.c
$ .&#x2F;a.out<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>然后我们来看下系统资源占用(CPU)<br><img data-src="https://i.loli.net/2020/03/09/Xs562iawhHyMxeO.png" alt="Xs562iawhHyMxeO"><br>上图是在容器里的,可以看到 cpu 已经 100%了<br>然后看看容器外面的<br><img data-src="https://i.loli.net/2020/03/09/ecqH8XJ4k7rKhzu.png" alt="ecqH8XJ4k7rKhzu"><br>可以看到一个核的 cpu 也被占满了,因为是个双核的机器,并且代码是单线程的<br>然后呢我们要做点啥<br>因为已经在这个 ubuntu 容器中装了 vim 和 gcc,考虑到国内的网络,所以我们先把这个容器 commit 一下,</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker commit -a "nick" -m "my ubuntu" f63c5607df06 my_ubuntu:v1</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">docker commit -a &quot;nick&quot; -m &quot;my ubuntu&quot; f63c5607df06 my_ubuntu:v1<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>然后再运行起来</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --cpus=0.1 my_ubuntu:v1 bash</span><br></pre></td></tr></table></figure>
<p><img data-src="https://i.loli.net/2020/03/15/x2oGCPQr9Mm8ZYj.png" alt=""><br>我们的代码跟可执行文件都还在,要的就是这个效果,然后再运行一下<br><img data-src="https://i.loli.net/2020/03/10/3EgzYxpqlwobNRj.png" alt=""><br>结果是这个样子的,有点神奇是不,关键就在于 run 的时候的<code>--cpus=0.1</code>这个参数,它其实就是基于我前一篇说的 cgroup 技术,能将进程之间的cpu,内存等资源进行隔离</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">docker run -it --cpus&#x3D;0.1 my_ubuntu:v1 bash<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://i.loli.net/2020/03/15/x2oGCPQr9Mm8ZYj.png"><br>我们的代码跟可执行文件都还在,要的就是这个效果,然后再运行一下<br><img data-src="https://i.loli.net/2020/03/10/3EgzYxpqlwobNRj.png"><br>结果是这个样子的,有点神奇是不,关键就在于 run 的时候的<code>--cpus=0.1</code>这个参数,它其实就是基于我前一篇说的 cgroup 技术,能将进程之间的cpu,内存等资源进行隔离</p>
<h2 id="开始第一个-Dockerfile"><a href="#开始第一个-Dockerfile" class="headerlink" title="开始第一个 Dockerfile"></a>开始第一个 Dockerfile</h2><p>上一面为了复用那个我装了 vim 跟 gcc 的容器,我把它提交到了本地,使用了<code>docker commit</code>命令,有点类似于 git 的 commit,但是这个不是个很好的操作方式,需要手动介入,这里更推荐使用 Dockerfile 来构建镜像</p>
<figure class="highlight docker"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">From</span> ubuntu:latest</span><br><span class="line"><span class="keyword">MAINTAINER</span> Nicksxs <span class="string">"nicksxs@hotmail.com"</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> apt-get clean</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> apt-get update &amp;&amp; apt install -y nginx</span></span><br><span class="line"><span class="keyword">RUN</span><span class="bash"> <span class="built_in">echo</span> <span class="string">'Hi, i am in container'</span> \</span></span><br><span class="line"><span class="bash"> &gt; /usr/share/nginx/html/index.html</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">80</span></span><br></pre></td></tr></table></figure>
<p>先解释下这是在干嘛,首先是这个<code>From ubuntu:latest</code>基于的 ubuntu 的最新版本的镜像,然后第二行是维护人的信息,第三四行么作为墙内人你懂的,把 ubuntu 的源换成阿里云的,不然就有的等了,然后就是装下 nginx,往默认的 nginx 的入口 html 文件里输入一行欢迎语,然后暴露 80 端口<br>然后我们使用<code>sudo docker build -t=&quot;nicksxs/static_web&quot; .</code>命令来基于这个 Dockerfile 构建我们自己的镜像,过程中是这样的<br><img data-src="https://i.loli.net/2020/03/15/aiIMrhy9WHetDSl.png" alt=""><br><img data-src="https://i.loli.net/2020/03/11/RC6yjImFZps4HWl.png" alt=""><br>可以看到图中,我的 Dockerfile 是 7 行,里面就执行了 7 步,并且每一步都有一个类似于容器 id 的层 id 出来,这里就是一个比较重要的东西,docker 在构建的时候其实是有这个层的概念,Dockerfile 里的每一行都会往上加一层,这里有还注意下命令后面的<code>.</code>,代表当前目录下会自行去寻找 Dockerfile 进行构建,构建完了之后我们再看下我们的本地镜像<br><img data-src="https://i.loli.net/2020/03/11/op5c7UGTbhjwPOI.png" alt=""><br>我们自己的镜像出现啦<br>然后有个问题,如果这个构建中途报了错咋办呢,来试试看,我们把 nginx 改成随便的一个错误名,nginxx(不知道会不会运气好真的有这玩意),再来 build 一把<br><img data-src="https://i.loli.net/2020/03/14/ALWIobjchnu1Rvi.png" alt=""><br>找不到 nginxx 包,是不是这个镜像就完全不能用呢,当然也不是,因为前面说到了,docker 是基于层去构建的,可以看到前面的 4 个 step 都没报错,那我们基于最后的成功步骤创建下容器看看<br>也就是<code>sudo docker run -t -i bd26f991b6c8 /bin/bash</code><br>答案是可以的,只是没装成功 nginx<br><img data-src="https://i.loli.net/2020/03/14/grcMNVxTabDPipu.png" alt=""><br>还有一点注意到没,前面的几个 step 都有一句 <code>Using cache</code>,说明 docker 在构建镜像的时候是有缓存的,这也更能说明 docker 是基于层去构建镜像,同样的底包,同样的步骤,这些层是可以被复用的,这就是 docker 的构建缓存,当然我们也可以在 build 的时候加上<code>--no-cache</code>去把构建缓存禁用掉。</p>
<pre class="line-numbers language-Docker" data-language="Docker"><code class="language-Docker">From ubuntu:latest
MAINTAINER Nicksxs &quot;nicksxs@hotmail.com&quot;
RUN sed -i s@&#x2F;archive.ubuntu.com&#x2F;@&#x2F;mirrors.aliyun.com&#x2F;@g &#x2F;etc&#x2F;apt&#x2F;sources.list
RUN apt-get clean
RUN apt-get update &amp;&amp; apt install -y nginx
RUN echo &#39;Hi, i am in container&#39; \
&gt; &#x2F;usr&#x2F;share&#x2F;nginx&#x2F;html&#x2F;index.html
EXPOSE 80<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>先解释下这是在干嘛,首先是这个<code>From ubuntu:latest</code>基于的 ubuntu 的最新版本的镜像,然后第二行是维护人的信息,第三四行么作为墙内人你懂的,把 ubuntu 的源换成阿里云的,不然就有的等了,然后就是装下 nginx,往默认的 nginx 的入口 html 文件里输入一行欢迎语,然后暴露 80 端口<br>然后我们使用<code>sudo docker build -t=&quot;nicksxs/static_web&quot; .</code>命令来基于这个 Dockerfile 构建我们自己的镜像,过程中是这样的<br><img data-src="https://i.loli.net/2020/03/15/aiIMrhy9WHetDSl.png"><br><img data-src="https://i.loli.net/2020/03/11/RC6yjImFZps4HWl.png"><br>可以看到图中,我的 Dockerfile 是 7 行,里面就执行了 7 步,并且每一步都有一个类似于容器 id 的层 id 出来,这里就是一个比较重要的东西,docker 在构建的时候其实是有这个层的概念,Dockerfile 里的每一行都会往上加一层,这里有还注意下命令后面的<code>.</code>,代表当前目录下会自行去寻找 Dockerfile 进行构建,构建完了之后我们再看下我们的本地镜像<br><img data-src="https://i.loli.net/2020/03/11/op5c7UGTbhjwPOI.png"><br>我们自己的镜像出现啦<br>然后有个问题,如果这个构建中途报了错咋办呢,来试试看,我们把 nginx 改成随便的一个错误名,nginxx(不知道会不会运气好真的有这玩意),再来 build 一把<br><img data-src="https://i.loli.net/2020/03/14/ALWIobjchnu1Rvi.png"><br>找不到 nginxx 包,是不是这个镜像就完全不能用呢,当然也不是,因为前面说到了,docker 是基于层去构建的,可以看到前面的 4 个 step 都没报错,那我们基于最后的成功步骤创建下容器看看<br>也就是<code>sudo docker run -t -i bd26f991b6c8 /bin/bash</code><br>答案是可以的,只是没装成功 nginx<br><img data-src="https://i.loli.net/2020/03/14/grcMNVxTabDPipu.png"><br>还有一点注意到没,前面的几个 step 都有一句 <code>Using cache</code>,说明 docker 在构建镜像的时候是有缓存的,这也更能说明 docker 是基于层去构建镜像,同样的底包,同样的步骤,这些层是可以被复用的,这就是 docker 的构建缓存,当然我们也可以在 build 的时候加上<code>--no-cache</code>去把构建缓存禁用掉。</p>
</div>
@ -456,7 +463,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#限制下-docker-的-cpu-使用率"><span class="nav-number">1.</span> <span class="nav-text">限制下 docker 的 cpu 使用率</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#开始第一个-Dockerfile"><span class="nav-number">2.</span> <span class="nav-text">开始第一个 Dockerfile</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%99%90%E5%88%B6%E4%B8%8B-docker-%E7%9A%84-cpu-%E4%BD%BF%E7%94%A8%E7%8E%87"><span class="nav-number">1.</span> <span class="nav-text">限制下 docker 的 cpu 使用率</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%BC%80%E5%A7%8B%E7%AC%AC%E4%B8%80%E4%B8%AA-Dockerfile"><span class="nav-number">2.</span> <span class="nav-text">开始第一个 Dockerfile</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 17
- 18
2020/03/21/docker比一般多一点的初学者介绍三/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,12 +26,13 @@
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>
<meta name="description" content="运行第一个 Dockerfile上一篇的 Dockerfile 我们停留在构建阶段,现在来把它跑起来 12docker run -d -p 80 --name static_web nicksxs&#x2F;static_web \nginx -g &quot;daemon off;&quot; 这里的-d表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放给宿主机,然后容器名就叫 s">
<meta name="description" content="运行第一个 Dockerfile上一篇的 Dockerfile 我们停留在构建阶段,现在来把它跑起来 docker run -d -p 80 --name static_web nicksxs&#x2F;static_web \ nginx -g &quot;daemon off;&quot; 这里的-d表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放">
<meta property="og:type" content="article">
<meta property="og:title" content="docker比一般多一点的初学者介绍三">
<meta property="og:url" content="https://nicksxs.me/2020/03/21/docker%E6%AF%94%E4%B8%80%E8%88%AC%E5%A4%9A%E4%B8%80%E7%82%B9%E7%9A%84%E5%88%9D%E5%AD%A6%E8%80%85%E4%BB%8B%E7%BB%8D%E4%B8%89/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="运行第一个 Dockerfile上一篇的 Dockerfile 我们停留在构建阶段,现在来把它跑起来 12docker run -d -p 80 --name static_web nicksxs&#x2F;static_web \nginx -g &quot;daemon off;&quot; 这里的-d表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放给宿主机,然后容器名就叫 s">
<meta property="og:description" content="运行第一个 Dockerfile上一篇的 Dockerfile 我们停留在构建阶段,现在来把它跑起来 docker run -d -p 80 --name static_web nicksxs&#x2F;static_web \ nginx -g &quot;daemon off;&quot; 这里的-d表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/03/21/VCEuf5BTopXNkcA.png">
<meta property="og:image" content="https://i.loli.net/2020/03/21/Cx1JYGBrHRqojpz.png">
<meta property="og:image" content="https://i.loli.net/2020/03/21/xhAcQlX5iP9KnYB.png">
@ -40,16 +41,11 @@
<meta property="og:image" content="https://i.loli.net/2020/03/21/56cuKf1ObvkBSG3.png">
<meta property="og:image" content="https://i.loli.net/2020/03/21/qDd2LVhz1Po4McX.png">
<meta property="article:published_time" content="2020-03-21T06:43:39.000Z">
<meta property="article:modified_time" content="2020-03-21T08:19:01.000Z">
<meta property="article:modified_time" content="2020-03-21T06:43:39.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="namespace">
<meta property="article:tag" content="cgroup">
<meta property="article:tag" content="docker-image">
<meta property="article:tag" content="Dockerfile">
<meta property="article:tag" content="nginx">
<meta property="article:tag" content="alpine">
<meta property="article:tag" content="php">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/03/21/VCEuf5BTopXNkcA.png">
@ -240,9 +236,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-03-21 14:43:39 / Modified: 16:19:01" itemprop="dateCreated datePublished" datetime="2020-03-21T14:43:39+08:00">2020-03-21</time>
<time title="Created: 2020-03-21 14:43:39" itemprop="dateCreated datePublished" datetime="2020-03-21T14:43:39+08:00">2020-03-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -298,15 +293,19 @@
<h2 id="运行第一个-Dockerfile"><a href="#运行第一个-Dockerfile" class="headerlink" title="运行第一个 Dockerfile"></a>运行第一个 Dockerfile</h2><p>上一篇的 Dockerfile 我们停留在构建阶段,现在来把它跑起来</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker run -d -p 80 --name static_web nicksxs/static_web \</span><br><span class="line">nginx -g "daemon off;"</span><br></pre></td></tr></table></figure>
<p>这里的<code>-d</code>表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放给宿主机,然后容器名就叫 static_web,使用了我们上次构建的 static_web 镜像,后面的是让 nginx 在前台运行<br><img data-src="https://i.loli.net/2020/03/21/VCEuf5BTopXNkcA.png" alt=""><br>可以看到返回了个容器 id,但是具体情况没出现,也没连上去,那我们想看看怎么访问在 Dockerfile 里写的静态页面,我们来看下docker 进程<br><img data-src="https://i.loli.net/2020/03/21/Cx1JYGBrHRqojpz.png" alt=""><br>发现为我们随机分配了一个宿主机的端口,32768,去服务器的防火墙把这个外网端口开一下,看看是不是符合我们的预期呢<br><img data-src="https://i.loli.net/2020/03/21/xhAcQlX5iP9KnYB.png" alt=""><br>好像不太对额,应该是 ubuntu 安装的 nginx 的默认工作目录不对,我们来进容器看看,再熟悉下命令<code>docker exec -it 4792455ca2ed /bin/bash</code><br>记得容器 id 换成自己的,进入容器后得找找 nginx 的配置文件,通常在<code>/etc/nginx</code>,<code>/usr/local/etc</code>等目录下,然后找到我们的目录是在这<br><img data-src="https://i.loli.net/2020/03/21/wE8TfkbC2d9pNuv.png" alt=""><br>所以把刚才的内容复制过去再试试<br><img data-src="https://i.loli.net/2020/03/21/qNkpHn3GW8aiwIr.png" alt=""><br>目标达成,give me five✌️</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">docker run -d -p 80 --name static_web nicksxs&#x2F;static_web \
nginx -g &quot;daemon off;&quot;<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>这里的<code>-d</code>表示以分离模型运行docker (detached),然后-p 是表示将容器的 80 端口开放给宿主机,然后容器名就叫 static_web,使用了我们上次构建的 static_web 镜像,后面的是让 nginx 在前台运行<br><img data-src="https://i.loli.net/2020/03/21/VCEuf5BTopXNkcA.png"><br>可以看到返回了个容器 id,但是具体情况没出现,也没连上去,那我们想看看怎么访问在 Dockerfile 里写的静态页面,我们来看下docker 进程<br><img data-src="https://i.loli.net/2020/03/21/Cx1JYGBrHRqojpz.png"><br>发现为我们随机分配了一个宿主机的端口,32768,去服务器的防火墙把这个外网端口开一下,看看是不是符合我们的预期呢<br><img data-src="https://i.loli.net/2020/03/21/xhAcQlX5iP9KnYB.png"><br>好像不太对额,应该是 ubuntu 安装的 nginx 的默认工作目录不对,我们来进容器看看,再熟悉下命令<code>docker exec -it 4792455ca2ed /bin/bash</code><br>记得容器 id 换成自己的,进入容器后得找找 nginx 的配置文件,通常在<code>/etc/nginx</code>,<code>/usr/local/etc</code>等目录下,然后找到我们的目录是在这<br><img data-src="https://i.loli.net/2020/03/21/wE8TfkbC2d9pNuv.png"><br>所以把刚才的内容复制过去再试试<br><img data-src="https://i.loli.net/2020/03/21/qNkpHn3GW8aiwIr.png"><br>目标达成,give me five✌️</p>
<h2 id="第二个-Dockerfile"><a href="#第二个-Dockerfile" class="headerlink" title="第二个 Dockerfile"></a>第二个 Dockerfile</h2><p>然后就想来动态一点的,毕竟写过 PHP,就来试试 PHP<br>再建一个目录叫 dynamic_web,里面创建 src 目录,放一个 index.php<br>内容是</p>
<figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="keyword">echo</span> <span class="string">"Hello World!"</span>;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-php" data-language="php"><code class="language-php"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
<span class="token keyword">echo</span> <span class="token string double-quoted-string">"Hello World!"</span><span class="token punctuation">;</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>然后在 dynamic_web 目录下创建 Dockerfile,</p>
<figure class="highlight dockerfile"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">FROM</span> trafex/alpine-nginx-php7:latest</span><br><span class="line"><span class="keyword">COPY</span><span class="bash"> src/ /var/www/html</span></span><br><span class="line"><span class="keyword">EXPOSE</span> <span class="number">80</span></span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-Dockerfile" data-language="Dockerfile"><code class="language-Dockerfile">FROM trafex&#x2F;alpine-nginx-php7:latest
COPY src&#x2F; &#x2F;var&#x2F;www&#x2F;html
EXPOSE 80<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>Dockerfile 虽然只有三行,不过要着重说明下,这个底包其实不是docker 官方的,有两点考虑,一点是官方的基本都是 php apache 的镜像,还有就是 alpine这个,截取一段中文介绍</p>
<blockquote>
<p>Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 <a href="https://pkgs.alpinelinux.org/packages" target="_blank" rel="noopener">https://pkgs.alpinelinux.org/packages</a> 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。<br>Alpine 由非商业组织维护的,支持广泛场景的 Linux发行版,它特别为资深/重度Linux用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。</p>
<p>Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过 <a target="_blank" rel="noopener" href="https://pkgs.alpinelinux.org/packages">https://pkgs.alpinelinux.org/packages</a> 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。<br>Alpine 由非商业组织维护的,支持广泛场景的 Linux发行版,它特别为资深/重度Linux用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。</p>
</blockquote>
<blockquote>
<p>Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。</p>
@ -314,7 +313,7 @@
<blockquote>
<p>目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。 </p>
</blockquote>
<p>一方面在没有镜像的情况下,拉取 docker 镜像还是比较费力的,第二个就是也能节省硬盘空间,所以目前有大部分的 docker 镜像都将 alpine 作为基础镜像了<br>然后再来构建下<br><img data-src="https://i.loli.net/2020/03/21/56cuKf1ObvkBSG3.png" alt=""><br>这里还有个点,就是上面的那个镜像我们也是 EXPOSE 80端口,然后外部宿主机会随机映射一个端口,为了偷个懒,我们就直接指定外部端口了<br><code>docker run -d -p 80:80 dynamic_web</code>打开浏览器发现访问不了,咋回事呢<br>因为我们没看<code>trafex/alpine-nginx-php7:latest</code>这个镜像<a href="https://hub.docker.com/r/trafex/alpine-nginx-php7" target="_blank" rel="noopener">说明</a>,它内部的服务是 8080 端口的,所以我们映射的暴露端口应该是 8080,再用<code>docker run -d -p 80:8080 dynamic_web</code>这个启动,<br><img data-src="https://i.loli.net/2020/03/21/qDd2LVhz1Po4McX.png" alt=""></p>
<p>一方面在没有镜像的情况下,拉取 docker 镜像还是比较费力的,第二个就是也能节省硬盘空间,所以目前有大部分的 docker 镜像都将 alpine 作为基础镜像了<br>然后再来构建下<br><img data-src="https://i.loli.net/2020/03/21/56cuKf1ObvkBSG3.png"><br>这里还有个点,就是上面的那个镜像我们也是 EXPOSE 80端口,然后外部宿主机会随机映射一个端口,为了偷个懒,我们就直接指定外部端口了<br><code>docker run -d -p 80:80 dynamic_web</code>打开浏览器发现访问不了,咋回事呢<br>因为我们没看<code>trafex/alpine-nginx-php7:latest</code>这个镜像<a target="_blank" rel="noopener" href="https://hub.docker.com/r/trafex/alpine-nginx-php7">说明</a>,它内部的服务是 8080 端口的,所以我们映射的暴露端口应该是 8080,再用<code> docker run -d -p 80:8080 dynamic_web</code>这个启动,<br><img data-src="https://i.loli.net/2020/03/21/qDd2LVhz1Po4McX.png"></p>
</div>
@ -458,7 +457,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#运行第一个-Dockerfile"><span class="nav-number">1.</span> <span class="nav-text">运行第一个 Dockerfile</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#第二个-Dockerfile"><span class="nav-number">2.</span> <span class="nav-text">第二个 Dockerfile</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%BF%90%E8%A1%8C%E7%AC%AC%E4%B8%80%E4%B8%AA-Dockerfile"><span class="nav-number">1.</span> <span class="nav-text">运行第一个 Dockerfile</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AC%AC%E4%BA%8C%E4%B8%AA-Dockerfile"><span class="nav-number">2.</span> <span class="nav-text">第二个 Dockerfile</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 8
- 10
2020/03/29/echo命令的一个小技巧/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,18 +32,16 @@
<meta property="og:url" content="https://nicksxs.me/2020/03/29/echo%E5%91%BD%E4%BB%A4%E7%9A%84%E4%B8%80%E4%B8%AA%E5%B0%8F%E6%8A%80%E5%B7%A7/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="最近做 docker 系列,会经常进到 docker 内部,如上一篇介绍的,这些镜像一般都有用 ubuntu 或者alpine 这样的 Linux 系统作为底包,如果构建镜像的时候没有替换源的话,因为你懂的原因,在内部想编辑下东西要安装 vim 就会很慢很慢,thousand years later~而且如果在容器内部想改源配置的话也要编辑器,就陷入了一个鸡生蛋,跟蛋生鸡的问题中,对于 linux">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/03/23/4vlxSOuR2DdF5kp.png">
<meta property="og:image" content="https://i.loli.net/2020/03/29/mh5YxdDnX3VSkg8.png">
<meta property="article:published_time" content="2020-03-29T13:48:50.000Z">
<meta property="article:modified_time" content="2020-03-29T13:48:50.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="linux">
<meta property="article:tag" content="Docker">
<meta property="article:tag" content="Linux">
<meta property="article:tag" content="echo">
<meta property="article:tag" content="apt">
<meta property="article:tag" content="包管理">
<meta property="article:tag" content="uname">
<meta property="article:tag" content="alpine">
<meta property="article:tag" content="发行版">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/03/23/4vlxSOuR2DdF5kp.png">
@ -248,11 +246,11 @@
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Linux/%E5%91%BD%E4%BB%A4/" itemprop="url" rel="index"><span itemprop="name">命令</span></a>
<a href="/categories/Docker/" itemprop="url" rel="index"><span itemprop="name">Docker</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/Docker/" itemprop="url" rel="index"><span itemprop="name">Docker</span></a>
<a href="/categories/Linux/%E5%91%BD%E4%BB%A4/" itemprop="url" rel="index"><span itemprop="name">命令</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
@ -303,7 +301,7 @@
<div class="post-body" itemprop="articleBody">
<p>最近做 docker 系列,会经常进到 docker 内部,如上一篇介绍的,这些镜像一般都有用 ubuntu 或者alpine 这样的 Linux 系统作为底包,如果构建镜像的时候没有替换源的话,因为你懂的原因,在内部想编辑下东西要安装 vim 就会很慢很慢,thousand years later~<br>而且如果在容器内部想改源配置的话也要编辑器,就陷入了一个鸡生蛋,跟蛋生鸡的问题中,对于 linux 大神来说应该有一万种方法解决这个问题,对于我这个渣渣来说可能只想到了这个土方法,先 cp backup 一下 sources.list, 再 echo “xxx” &gt; sources.list, 这里就碰到了一个问题,这个 sources.list 一般不止一行,直接 echo 的话就解析不了了,不过 echo 可以支持”\n”转义,就是加-e<br>看一下解释和示例<br><img data-src="https://i.loli.net/2020/03/23/4vlxSOuR2DdF5kp.png" alt=""><br>还有一点也是在这个时候要安装 vim 之类的,得知道是什么镜像底包,如果是用 uname 指令,其实看到的是宿主机的系统,得用<code>cat /etc/issue</code><br><img data-src="https://i.loli.net/2020/03/29/mh5YxdDnX3VSkg8.png" alt=""><br>这里稍稍记一下</p>
<p>最近做 docker 系列,会经常进到 docker 内部,如上一篇介绍的,这些镜像一般都有用 ubuntu 或者alpine 这样的 Linux 系统作为底包,如果构建镜像的时候没有替换源的话,因为你懂的原因,在内部想编辑下东西要安装 vim 就会很慢很慢,thousand years later~<br>而且如果在容器内部想改源配置的话也要编辑器,就陷入了一个鸡生蛋,跟蛋生鸡的问题中,对于 linux 大神来说应该有一万种方法解决这个问题,对于我这个渣渣来说可能只想到了这个土方法,先 cp backup 一下 sources.list, 再 echo “xxx” &gt; sources.list, 这里就碰到了一个问题,这个 sources.list 一般不止一行,直接 echo 的话就解析不了了,不过 echo 可以支持”\n”转义,就是加-e<br>看一下解释和示例<br><img data-src="https://i.loli.net/2020/03/23/4vlxSOuR2DdF5kp.png"><br>还有一点也是在这个时候要安装 vim 之类的,得知道是什么镜像底包,如果是用 uname 指令,其实看到的是宿主机的系统,得用<code>cat /etc/issue</code><br><img data-src="https://i.loli.net/2020/03/29/mh5YxdDnX3VSkg8.png"><br>这里稍稍记一下</p>
</div>
@ -320,10 +318,10 @@
<div class="popular-posts-title"><a href="/2021/03/28/聊聊-Linux-下的-top-命令/" rel="bookmark">聊聊 Linux 下的 top 命令</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/03/21/docker比一般多一点的初学者介绍三/" rel="bookmark">docker比一般多一点的初学者介绍</a></div>
<div class="popular-posts-title"><a href="/2020/03/08/docker比一般多一点的初学者介绍/" rel="bookmark">docker比一般多一点的初学者介绍</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/03/08/docker比一般多一点的初学者介绍/" rel="bookmark">docker比一般多一点的初学者介绍</a></div>
<div class="popular-posts-title"><a href="/2020/03/21/docker比一般多一点的初学者介绍三/" rel="bookmark">docker比一般多一点的初学者介绍</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/03/15/docker比一般多一点的初学者介绍二/" rel="bookmark">docker比一般多一点的初学者介绍二</a></div>


+ 84
- 19
2020/04/05/Comparator使用小记/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,24 +26,23 @@
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>
<meta name="description" content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity 12345678910111213141516171819202122public class Entity &amp;#123; private Long id; private Long sortValue; pu">
<meta name="description" content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity public class Entity &amp;#123; private Long id; private Long sortValue; public Long getId() &amp;#123;">
<meta property="og:type" content="article">
<meta property="og:title" content="Comparator使用小记">
<meta property="og:url" content="https://nicksxs.me/2020/04/05/Comparator%E4%BD%BF%E7%94%A8%E5%B0%8F%E8%AE%B0/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity 12345678910111213141516171819202122public class Entity &amp;#123; private Long id; private Long sortValue; pu">
<meta property="og:description" content="在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator, 比如这样子 我的对象是Entity public class Entity &amp;#123; private Long id; private Long sortValue; public Long getId() &amp;#123;">
<meta property="og:locale">
<meta property="og:image" content="https://i.loli.net/2020/04/05/8VfjeOSmcvx4dyk.png">
<meta property="article:published_time" content="2020-04-05T13:41:41.000Z">
<meta property="article:modified_time" content="2020-04-05T13:42:20.000Z">
<meta property="article:modified_time" content="2020-04-05T13:41:41.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Collections">
<meta property="article:tag" content="sort">
<meta property="article:tag" content="Comparator">
<meta property="article:tag" content="nullsFirst">
<meta property="article:tag" content="Stream">
<meta property="article:tag" content="NPE">
<meta property="article:tag" content="NUll">
<meta property="article:tag" content="Comparator">
<meta property="article:tag" content="排序">
<meta property="article:tag" content="sort">
<meta property="article:tag" content="nullsfirst">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://i.loli.net/2020/04/05/8VfjeOSmcvx4dyk.png">
@ -234,9 +233,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-04-05 21:41:41 / Modified: 21:42:20" itemprop="dateCreated datePublished" datetime="2020-04-05T21:41:41+08:00">2020-04-05</time>
<time title="Created: 2020-04-05 21:41:41" itemprop="dateCreated datePublished" datetime="2020-04-05T21:41:41+08:00">2020-04-05</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -294,18 +292,85 @@
<p>在Java8的stream之前,将对象进行排序的时候,可能需要对象实现Comparable接口,或者自己实现一个Comparator,</p>
<p>比如这样子</p>
<p>我的对象是Entity</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Entity</span> </span>&#123;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Long id;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Long sortValue;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Long <span class="title">getId</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> id;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setId</span><span class="params">(Long id)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">this</span>.id = id;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Long <span class="title">getSortValue</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> sortValue;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setSortValue</span><span class="params">(Long sortValue)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">this</span>.sortValue = sortValue;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Entity</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token class-name">Long</span> sortValue<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token class-name">Long</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> id<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span><span class="token class-name">Long</span> id<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">public</span> <span class="token class-name">Long</span> <span class="token function">getSortValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> sortValue<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSortValue</span><span class="token punctuation">(</span><span class="token class-name">Long</span> sortValue<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>sortValue <span class="token operator">=</span> sortValue<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>Comparator</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyComparator</span> <span class="keyword">implements</span> <span class="title">Comparator</span> </span>&#123;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(Object o1, Object o2)</span> </span>&#123;</span><br><span class="line"> Entity e1 = (Entity) o1;</span><br><span class="line"> Entity e2 = (Entity) o2;</span><br><span class="line"> <span class="keyword">if</span> (e1.getSortValue() &lt; e2.getSortValue()) &#123;</span><br><span class="line"> <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line"> &#125; <span class="keyword">else</span> <span class="keyword">if</span> (e1.getSortValue().equals(e2.getSortValue())) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyComparator</span> <span class="token keyword">implements</span> <span class="token class-name">Comparator</span> <span class="token punctuation">&#123;</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token class-name">Object</span> o1<span class="token punctuation">,</span> <span class="token class-name">Object</span> o2<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">Entity</span> e1 <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Entity</span><span class="token punctuation">)</span> o1<span class="token punctuation">;</span>
<span class="token class-name">Entity</span> e2 <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Entity</span><span class="token punctuation">)</span> o2<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>e1<span class="token punctuation">.</span><span class="token function">getSortValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&lt;</span> e2<span class="token punctuation">.</span><span class="token function">getSortValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>e1<span class="token punctuation">.</span><span class="token function">getSortValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>e2<span class="token punctuation">.</span><span class="token function">getSortValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>比较代码</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> MyComparator myComparator = <span class="keyword">new</span> MyComparator();</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line"> List&lt;Entity&gt; list = <span class="keyword">new</span> ArrayList&lt;Entity&gt;();</span><br><span class="line"> Entity e1 = <span class="keyword">new</span> Entity();</span><br><span class="line"> e1.setId(<span class="number">1L</span>);</span><br><span class="line"> e1.setSortValue(<span class="number">1L</span>);</span><br><span class="line"> list.add(e1);</span><br><span class="line"> Entity e2 = <span class="keyword">new</span> Entity();</span><br><span class="line"> e2.setId(<span class="number">2L</span>);</span><br><span class="line"> e2.setSortValue(<span class="keyword">null</span>);</span><br><span class="line"> list.add(e2);</span><br><span class="line"> Collections.sort(list, myComparator);</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token class-name">MyComparator</span> myComparator <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">MyComparator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Entity</span><span class="token punctuation">></span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Entity</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">Entity</span> e1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Entity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
e1<span class="token punctuation">.</span><span class="token function">setId</span><span class="token punctuation">(</span><span class="token number">1L</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
e1<span class="token punctuation">.</span><span class="token function">setSortValue</span><span class="token punctuation">(</span><span class="token number">1L</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>e1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">Entity</span> e2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Entity</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
e2<span class="token punctuation">.</span><span class="token function">setId</span><span class="token punctuation">(</span><span class="token number">2L</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
e2<span class="token punctuation">.</span><span class="token function">setSortValue</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>e2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">Collections</span><span class="token punctuation">.</span><span class="token function">sort</span><span class="token punctuation">(</span>list<span class="token punctuation">,</span> myComparator<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-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></code></pre>
<p>看到这里的e2的排序值是null,在Comparator中如果要正常运行的话,就得判空之类的,这里有两点需要,一个是不想写这个MyComparator,然后也没那么好排除掉list里排序值,那么有什么办法能解决这种问题呢,应该说java的这方面真的是很强大</p>
<p><img data-src="https://i.loli.net/2020/04/05/8VfjeOSmcvx4dyk.png" alt=""></p>
<p><img data-src="https://i.loli.net/2020/04/05/8VfjeOSmcvx4dyk.png"></p>
<p>看一下nullsFirst的实现</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">final</span> <span class="keyword">static</span> <span class="class"><span class="keyword">class</span> <span class="title">NullComparator</span>&lt;<span class="title">T</span>&gt; <span class="keyword">implements</span> <span class="title">Comparator</span>&lt;<span class="title">T</span>&gt;, <span class="title">Serializable</span> </span>&#123;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = -<span class="number">7569533591570686392L</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> <span class="keyword">boolean</span> nullFirst;</span><br><span class="line"> <span class="comment">// if null, non-null Ts are considered equal</span></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> Comparator&lt;T&gt; real;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"> NullComparator(<span class="keyword">boolean</span> nullFirst, Comparator&lt;? <span class="keyword">super</span> T&gt; real) &#123;</span><br><span class="line"> <span class="keyword">this</span>.nullFirst = nullFirst;</span><br><span class="line"> <span class="keyword">this</span>.real = (Comparator&lt;T&gt;) real;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compare</span><span class="params">(T a, T b)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (a == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> (b == <span class="keyword">null</span>) ? <span class="number">0</span> : (nullFirst ? -<span class="number">1</span> : <span class="number">1</span>);</span><br><span class="line"> &#125; <span class="keyword">else</span> <span class="keyword">if</span> (b == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> nullFirst ? <span class="number">1</span>: -<span class="number">1</span>;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> (real == <span class="keyword">null</span>) ? <span class="number">0</span> : real.compare(a, b);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">final</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">NullComparator</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">T</span><span class="token punctuation">></span></span> <span class="token keyword">implements</span> <span class="token class-name">Comparator</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">T</span><span class="token punctuation">></span></span><span class="token punctuation">,</span> <span class="token class-name">Serializable</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">long</span> serialVersionUID <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">7569533591570686392L</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token keyword">boolean</span> nullFirst<span class="token punctuation">;</span>
<span class="token comment">// if null, non-null Ts are considered equal</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Comparator</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">T</span><span class="token punctuation">></span></span> real<span class="token punctuation">;</span>
<span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">"unchecked"</span><span class="token punctuation">)</span>
<span class="token class-name">NullComparator</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> nullFirst<span class="token punctuation">,</span> <span class="token class-name">Comparator</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span> <span class="token keyword">super</span> <span class="token class-name">T</span><span class="token punctuation">></span></span> real<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>nullFirst <span class="token operator">=</span> nullFirst<span class="token punctuation">;</span>
<span class="token keyword">this</span><span class="token punctuation">.</span>real <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Comparator</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">T</span><span class="token punctuation">></span></span><span class="token punctuation">)</span> real<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">compare</span><span class="token punctuation">(</span><span class="token class-name">T</span> a<span class="token punctuation">,</span> <span class="token class-name">T</span> b<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>a <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>b <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token operator">:</span> <span class="token punctuation">(</span>nullFirst <span class="token operator">?</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>b <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> nullFirst <span class="token operator">?</span> <span class="token number">1</span><span class="token operator">:</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span>real <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token number">0</span> <span class="token operator">:</span> real<span class="token punctuation">.</span><span class="token function">compare</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>核心代码就是下面这段,其实就是帮我们把前面要做的事情做掉了,是不是挺方便的,小记一下哈</p>
@ -318,7 +383,7 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/04/04/聊聊-dubbo-的线程池/" rel="bookmark">聊聊 dubbo 的线程池</a></div>
<div class="popular-posts-title"><a href="/2020/11/22/聊聊-Dubbo-的容错机制/" rel="bookmark">聊聊 Dubbo 的容错机制</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/01/Apollo-的-value-注解是怎么自动更新的/" rel="bookmark">Apollo 的 value 注解是怎么自动更新的</a></div>
@ -330,7 +395,7 @@
<div class="popular-posts-title"><a href="/2020/09/06/mybatis-的-和-是有啥区别/" rel="bookmark">mybatis 的 $ 和 # 是有啥区别</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/" rel="bookmark">聊聊 Dubbo 的 SPI 续之自适应拓展</a></div>
<div class="popular-posts-title"><a href="/2020/10/03/mybatis-的缓存是怎么回事/" rel="bookmark">mybatis 的缓存是怎么回事</a></div>
</li>
</ul>


+ 416
- 18
2020/04/12/redis系列介绍七/index.html
File diff suppressed because it is too large
View File


+ 512
- 43
2020/04/18/redis系列介绍八/index.html
File diff suppressed because it is too large
View File


+ 52
- 21
2020/04/26/聊聊-mysql-的-MVCC/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,16 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2020/04/26/%E8%81%8A%E8%81%8A-mysql-%E7%9A%84-MVCC/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="很久以前,有位面试官问到,你知道 mysql 的事务隔离级别吗,“额 O__O …,不太清楚”,完了之后我就去网上找相关的文章,找到了这篇MySQL 四种事务隔离级的说明, 文章写得特别好,看了这个就懂了各个事务隔离级别都是啥,不过看了这个之后多思考一下的话还是会发现问题,这么神奇的事务隔离级别是怎么实现的呢 其中 innodb 的事务隔离用到了标题里说到的 mvcc,Multiversion c">
<meta property="og:locale">
<meta property="article:published_time" content="2020-04-26T14:14:01.000Z">
<meta property="article:modified_time" content="2020-05-02T11:46:21.000Z">
<meta property="article:modified_time" content="2020-04-26T14:14:01.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Mysql">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="mysql">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="事务隔离级别">
<meta property="article:tag" content="MVCC">
<meta property="article:tag" content="mvcc">
<meta property="article:tag" content="read view">
<meta name="twitter:card" content="summary">
@ -235,13 +233,6 @@
<time title="Created: 2020-04-26 22:14:01" itemprop="dateCreated datePublished" datetime="2020-04-26T22:14:01+08:00">2020-04-26</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-05-02 19:46:21" itemprop="dateModified" datetime="2020-05-02T19:46:21+08:00">2020-05-02</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -307,10 +298,26 @@
<div class="post-body" itemprop="articleBody">
<p>很久以前,有位面试官问到,你知道 mysql 的事务隔离级别吗,“额 O__O …,不太清楚”,完了之后我就去网上找相关的文章,找到了这篇<a href="https://www.cnblogs.com/zhoujinyi/p/3437475.html" target="_blank" rel="noopener">MySQL 四种事务隔离级的说明</a>, 文章写得特别好,看了这个就懂了各个事务隔离级别都是啥,不过看了这个之后多思考一下的话还是会发现问题,这么神奇的事务隔离级别是怎么实现的呢</p>
<p>其中 innodb 的事务隔离用到了标题里说到的 mvcc,<a href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control" target="_blank" rel="noopener"><strong>Multiversion concurrency control</strong></a>, 直译过来就是多版本并发控制,先不讲这个究竟是个啥,考虑下如果纯猜测,这个事务隔离级别应该会是怎么样实现呢,愚钝的我想了下,可以在事务开始的时候拷贝一个表,这个可以支持 RR 级别,RC 级别就不支持了,而且要是个非常大的表,想想就不可行</p>
<p>腆着脸说虽然这个不可行,但是思路是对的,具体实行起来需要做一系列(肥肠多)的改动,首先根据我的理解,其实这个拷贝一个表是变成拷贝一条记录,但是如果有多个事务,那就得拷贝多次,这个问题其实可以借助版本管理系统来解释,在用版本管理系统,git 之类的之前,很原始的可能是开发完一个功能后,就打个压缩包用时间等信息命名,然后如果后面要找回这个就直接用这个压缩包的就行了,后来有了 svn,git 中心式和分布式的版本管理系统,它的一个特点是粒度可以控制到文件和代码行级别,对应的我们的 mysql 事务是不是也可以从一开始预想的表级别细化到行的级别,可能之前很多人都了解过,数据库的一行记录除了我们用户自定义的字段,还有一些额外的字段,去源码<a href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/data0type.h#L170" target="_blank" rel="noopener">data0type.h</a>里捞一下</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Precise data types for system columns and the length of those columns;</span></span><br><span class="line"><span class="comment"><span class="doctag">NOTE:</span> the values must run from 0 up in the order given! All codes must</span></span><br><span class="line"><span class="comment">be less than 256 */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> DATA_ROW_ID 0 <span class="comment">/* row id: a 48-bit integer */</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> DATA_ROW_ID_LEN 6 <span class="comment">/* stored length for row id */</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/** Transaction id: 6 bytes */</span></span><br><span class="line"><span class="keyword">constexpr</span> <span class="keyword">size_t</span> DATA_TRX_ID = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Transaction ID type size in bytes. */</span></span><br><span class="line"><span class="keyword">constexpr</span> <span class="keyword">size_t</span> DATA_TRX_ID_LEN = <span class="number">6</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Rollback data pointer: 7 bytes */</span></span><br><span class="line"><span class="keyword">constexpr</span> <span class="keyword">size_t</span> DATA_ROLL_PTR = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** Rollback data pointer type size in bytes. */</span></span><br><span class="line"><span class="keyword">constexpr</span> <span class="keyword">size_t</span> DATA_ROLL_PTR_LEN = <span class="number">7</span>;</span><br></pre></td></tr></table></figure>
<p>很久以前,有位面试官问到,你知道 mysql 的事务隔离级别吗,“额 O__O …,不太清楚”,完了之后我就去网上找相关的文章,找到了这篇<a target="_blank" rel="noopener" href="https://www.cnblogs.com/zhoujinyi/p/3437475.html">MySQL 四种事务隔离级的说明</a>, 文章写得特别好,看了这个就懂了各个事务隔离级别都是啥,不过看了这个之后多思考一下的话还是会发现问题,这么神奇的事务隔离级别是怎么实现的呢</p>
<p>其中 innodb 的事务隔离用到了标题里说到的 mvcc,<a target="_blank" rel="noopener" href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control"><strong>Multiversion concurrency control</strong></a>, 直译过来就是多版本并发控制,先不讲这个究竟是个啥,考虑下如果纯猜测,这个事务隔离级别应该会是怎么样实现呢,愚钝的我想了下,可以在事务开始的时候拷贝一个表,这个可以支持 RR 级别,RC 级别就不支持了,而且要是个非常大的表,想想就不可行</p>
<p>腆着脸说虽然这个不可行,但是思路是对的,具体实行起来需要做一系列(肥肠多)的改动,首先根据我的理解,其实这个拷贝一个表是变成拷贝一条记录,但是如果有多个事务,那就得拷贝多次,这个问题其实可以借助版本管理系统来解释,在用版本管理系统,git 之类的之前,很原始的可能是开发完一个功能后,就打个压缩包用时间等信息命名,然后如果后面要找回这个就直接用这个压缩包的就行了,后来有了 svn,git 中心式和分布式的版本管理系统,它的一个特点是粒度可以控制到文件和代码行级别,对应的我们的 mysql 事务是不是也可以从一开始预想的表级别细化到行的级别,可能之前很多人都了解过,数据库的一行记录除了我们用户自定义的字段,还有一些额外的字段,去源码<a target="_blank" rel="noopener" href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/data0type.h#L170">data0type.h</a>里捞一下</p>
<pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="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
be less than 256 */</span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DATA_ROW_ID</span> <span class="token expression"><span class="token number">0</span> </span><span class="token comment">/* row id: a 48-bit integer */</span></span>
<span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">define</span> <span class="token macro-name">DATA_ROW_ID_LEN</span> <span class="token expression"><span class="token number">6</span> </span><span class="token comment">/* stored length for row id */</span></span>
<span class="token comment">/** Transaction id: 6 bytes */</span>
constexpr <span class="token class-name">size_t</span> DATA_TRX_ID <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span>
<span class="token comment">/** Transaction ID type size in bytes. */</span>
constexpr <span class="token class-name">size_t</span> DATA_TRX_ID_LEN <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span>
<span class="token comment">/** Rollback data pointer: 7 bytes */</span>
constexpr <span class="token class-name">size_t</span> DATA_ROLL_PTR <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token comment">/** Rollback data pointer type size in bytes. */</span>
constexpr <span class="token class-name">size_t</span> DATA_ROLL_PTR_LEN <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span><span aria-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></code></pre>
<p>一个是 <code>DATA_ROW_ID</code>,这个是在数据没指定主键的时候会生成一个隐藏的,如果用户有指定主键就是主键了</p>
<p>一个是 <code>DATA_TRX_ID</code>,这个表示这条记录的事务 ID</p>
@ -325,7 +332,31 @@
<li>当记录的事务 <code>id</code> 小于最小活跃事务 id,说明是可见的,</li>
<li>如果记录的事务 <code>id</code> 等于当前事务 id,说明是自己的更改,可见</li>
<li>如果记录的事务 <code>id</code> 大于最大的活跃事务 <code>id</code>, 不可见</li>
<li>如果记录的事务 <code>id</code> 介于 <code>m_low_limit_id</code><code>m_up_limit_id</code> 之间,则要判断它是否在 <code>m_ids</code> 中,如果在,不可见,如果不在,表示已提交,可见<br>具体的<a href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/read0types.h#L160" target="_blank" rel="noopener">代码</a>捞一下看看<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/** Check whether the changes by id are visible.</span></span><br><span class="line"><span class="comment"> @param[in] id transaction id to check against the view</span></span><br><span class="line"><span class="comment"> @param[in] name table name</span></span><br><span class="line"><span class="comment"> @return whether the view sees the modifications of id. */</span></span><br><span class="line"> <span class="function"><span class="keyword">bool</span> <span class="title">changes_visible</span><span class="params">(<span class="keyword">trx_id_t</span> id, <span class="keyword">const</span> <span class="keyword">table_name_t</span> &amp;name)</span> <span class="keyword">const</span></span></span><br><span class="line"><span class="function"> <span class="title">MY_ATTRIBUTE</span><span class="params">((warn_unused_result))</span> </span>&#123;</span><br><span class="line"> ut_ad(id &gt; <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (id &lt; m_up_limit_id || id == m_creator_trx_id) &#123;</span><br><span class="line"> <span class="keyword">return</span> (<span class="literal">true</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> check_trx_id_sanity(id, name);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (id &gt;= m_low_limit_id) &#123;</span><br><span class="line"> <span class="keyword">return</span> (<span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line"> &#125; <span class="keyword">else</span> <span class="keyword">if</span> (m_ids.empty()) &#123;</span><br><span class="line"> <span class="keyword">return</span> (<span class="literal">true</span>);</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">ids_t</span>::value_type *p = m_ids.data();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> (!<span class="built_in">std</span>::binary_search(p, p + m_ids.<span class="built_in">size</span>(), id));</span><br><span class="line"> &#125;</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>具体的<a target="_blank" rel="noopener" href="https://github.com/mysql/mysql-server/blob/8.0/storage/innobase/include/read0types.h#L160">代码</a>捞一下看看<pre class="line-numbers language-C" data-language="C"><code class="language-C">&#x2F;** 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. *&#x2F;
bool changes_visible(trx_id_t id, const table_name_t &amp;name) const
MY_ATTRIBUTE((warn_unused_result)) &#123;
ut_ad(id &gt; 0);
if (id &lt; m_up_limit_id || id &#x3D;&#x3D; m_creator_trx_id) &#123;
return (true);
&#125;
check_trx_id_sanity(id, name);
if (id &gt;&#x3D; m_low_limit_id) &#123;
return (false);
&#125; else if (m_ids.empty()) &#123;
return (true);
&#125;
const ids_t::value_type *p &#x3D; m_ids.data();
return (!std::binary_search(p, p + m_ids.size(), id));
&#125;<span aria-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></code></pre>
剩下来一点是啥呢,就是 <code>Read Committed</code><code>Repeated Read</code> 也不一样,那前面说的 <code>read view</code> 都能支持吗,又是怎么支持呢,假如这个 <code>read view</code> 是在事务一开始就创建,那好像能支持的只是 RR 事务隔离级别,其实呢,这是通过创建 <code>read view</code>的时机,对于 RR 级别,就是在事务的第一个 <code>select</code> 语句是创建,对于 RC 级别,是在每个 <code>select</code> 语句执行前都是创建一次,那样就可以保证能读到所有已提交的数据</li>
</ol>
@ -344,13 +375,13 @@
<div class="popular-posts-title"><a href="/2020/05/02/聊聊-mysql-的-MVCC-续篇/" rel="bookmark">聊聊 mysql 的 MVCC 续篇</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
<div class="popular-posts-title"><a href="/2020/01/04/redis数据结构介绍二/" rel="bookmark">redis数据结构介绍二-第二部分 跳表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/04/12/redis系列介绍七/" rel="bookmark">redis系列介绍七-过期策略</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
</ul>


+ 21
- 22
2020/05/02/聊聊-mysql-的-MVCC-续篇/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,28 +26,24 @@
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>
<meta name="description" content="上一篇聊了mysql 的 innodb 引擎基于 read view 实现的 mvcc 和事务隔离级别,可能有些细心的小伙伴会发现一些问题,第一个是在 RC 级别下的事务提交后的可见性,这里涉及到了三个参数,m_low_limit_id,m_up_limit_id,m_ids,之前看到知乎的一篇写的非常不错的文章,但是就在这一点上似乎有点疑惑,这里基于源码和注释来解释下这个问题 123456789">
<meta name="description" content="上一篇聊了mysql 的 innodb 引擎基于 read view 实现的 mvcc 和事务隔离级别,可能有些细心的小伙伴会发现一些问题,第一个是在 RC 级别下的事务提交后的可见性,这里涉及到了三个参数,m_low_limit_id,m_up_limit_id,m_ids,之前看到知乎的一篇写的非常不错的文章,但是就在这一点上似乎有点疑惑,这里基于源码和注释来解释下这个问题 &#x2F;**">
<meta property="og:type" content="article">
<meta property="og:title" content="聊聊 mysql 的 MVCC 续篇">
<meta property="og:url" content="https://nicksxs.me/2020/05/02/%E8%81%8A%E8%81%8A-mysql-%E7%9A%84-MVCC-%E7%BB%AD%E7%AF%87/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="上一篇聊了mysql 的 innodb 引擎基于 read view 实现的 mvcc 和事务隔离级别,可能有些细心的小伙伴会发现一些问题,第一个是在 RC 级别下的事务提交后的可见性,这里涉及到了三个参数,m_low_limit_id,m_up_limit_id,m_ids,之前看到知乎的一篇写的非常不错的文章,但是就在这一点上似乎有点疑惑,这里基于源码和注释来解释下这个问题 123456789">
<meta property="og:description" content="上一篇聊了mysql 的 innodb 引擎基于 read view 实现的 mvcc 和事务隔离级别,可能有些细心的小伙伴会发现一些问题,第一个是在 RC 级别下的事务提交后的可见性,这里涉及到了三个参数,m_low_limit_id,m_up_limit_id,m_ids,之前看到知乎的一篇写的非常不错的文章,但是就在这一点上似乎有点疑惑,这里基于源码和注释来解释下这个问题 &#x2F;**">
<meta property="og:locale">
<meta property="article:published_time" content="2020-05-02T06:46:35.000Z">
<meta property="article:modified_time" content="2020-05-03T14:26:29.000Z">
<meta property="article:modified_time" content="2020-05-02T06:46:35.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Mysql">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="mysql">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="事务隔离级别">
<meta property="article:tag" content="MVCC">
<meta property="article:tag" content="mvcc">
<meta property="article:tag" content="read view">
<meta property="article:tag" content="gap lock">
<meta property="article:tag" content="next-key lock">
<meta property="article:tag" content="幻读">
<meta property="article:tag" content="间隙锁">
<meta property="article:tag" content="行锁">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/05/02/%E8%81%8A%E8%81%8A-mysql-%E7%9A%84-MVCC-%E7%BB%AD%E7%AF%87/">
@ -240,13 +236,6 @@
<time title="Created: 2020-05-02 14:46:35" itemprop="dateCreated datePublished" datetime="2020-05-02T14:46:35+08:00">2020-05-02</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-05-03 22:26:29" itemprop="dateModified" datetime="2020-05-03T22:26:29+08:00">2020-05-03</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -313,7 +302,17 @@
<p>上一篇聊了mysql 的 innodb 引擎基于 read view 实现的 mvcc 和事务隔离级别,可能有些细心的小伙伴会发现一些问题,第一个是在 RC 级别下的事务提交后的可见性,这里涉及到了三个参数,m_low_limit_id,m_up_limit_id,m_ids,之前看到知乎的一篇写的非常不错的文章,但是就在这一点上似乎有点疑惑,这里基于源码和注释来解释下这个问题</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">Opens a read view where exactly the transactions serialized before this</span></span><br><span class="line"><span class="comment">point in time are seen in the view.</span></span><br><span class="line"><span class="comment">@param id Creator transaction id */</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">ReadView::prepare</span><span class="params">(<span class="keyword">trx_id_t</span> id)</span> </span>&#123;</span><br><span class="line"> ut_ad(mutex_own(&amp;trx_sys-&gt;mutex));</span><br><span class="line"></span><br><span class="line"> m_creator_trx_id = id;</span><br><span class="line"></span><br><span class="line"> m_low_limit_no = m_low_limit_id = m_up_limit_id = trx_sys-&gt;max_trx_id;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-C" data-language="C"><code class="language-C">&#x2F;**
Opens a read view where exactly the transactions serialized before this
point in time are seen in the view.
@param id Creator transaction id *&#x2F;
void ReadView::prepare(trx_id_t id) &#123;
ut_ad(mutex_own(&amp;trx_sys-&gt;mutex));
m_creator_trx_id &#x3D; id;
m_low_limit_no &#x3D; m_low_limit_id &#x3D; m_up_limit_id &#x3D; trx_sys-&gt;max_trx_id;<span aria-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></code></pre>
<p>m_low_limit_id赋的值是trx_sys-&gt;max_trx_id,代表的是当前系统最小的未分配的事务 id,所以呢,举个例子,当前有三个活跃事务,事务 id 分别是 100,200,300,而 m_up_limit_id = 100, m_low_limit_id = 301,当事务 id 是 200 的提交之后,它的更新就是可以被 100 和 300 看到,而不是说 m_ids 里没了 200,并且 200 比 100 大就应该不可见了</p>
<h2 id="幻读"><a href="#幻读" class="headerlink" title="幻读"></a>幻读</h2><p>还有一个问题是幻读的问题,这貌似也是个高频面试题,啥意思呢,或者说跟它最常拿来比较的脏读,脏读是指读到了别的事务未提交的数据,因为未提交,严格意义上来讲,不一定是会被最后落到库里,可能会回滚,也就是在 read uncommitted 级别下会出现的问题,但是幻读不太一样,幻读是指两次查询的结果数量不一样,比如我查了第一次是 <code>select * from table1 where id &lt; 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>
@ -336,13 +335,13 @@
<div class="popular-posts-title"><a href="/2020/04/26/聊聊-mysql-的-MVCC/" rel="bookmark">聊聊 mysql 的 MVCC</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
<div class="popular-posts-title"><a href="/2020/01/04/redis数据结构介绍二/" rel="bookmark">redis数据结构介绍二-第二部分 跳表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/04/12/redis系列介绍七/" rel="bookmark">redis系列介绍七-过期策略</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
</ul>
@ -474,7 +473,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#幻读"><span class="nav-number">1.</span> <span class="nav-text">幻读</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B9%BB%E8%AF%BB"><span class="nav-number">1.</span> <span class="nav-text">幻读</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 9
- 14
2020/05/10/聊聊-mysql-的-MVCC-续续篇之加锁分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,23 +32,19 @@
<meta property="og:url" content="https://nicksxs.me/2020/05/10/%E8%81%8A%E8%81%8A-mysql-%E7%9A%84-MVCC-%E7%BB%AD%E7%BB%AD%E7%AF%87%E4%B9%8B%E5%8A%A0%E9%94%81%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="看完前面两篇水文之后,感觉不得不来分析下 mysql 的锁了,其实前面说到幻读的时候是有个前提没提到的,比如一个select * from table1 where id &#x3D; 1这种查询语句其实是不会加传说中的锁的,当然这里是指在 RR 或者 RC 隔离级别下,看一段 mysql官方文档 SELECT ... FROM is a consistent read, reading a snaps">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200510-1126082x.png">
<meta property="article:published_time" content="2020-05-10T01:55:10.000Z">
<meta property="article:modified_time" content="2020-05-10T14:26:13.000Z">
<meta property="article:modified_time" content="2020-05-10T01:55:10.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Mysql">
<meta property="article:tag" content="C语言">
<meta property="article:tag" content="mysql">
<meta property="article:tag" content="数据结构">
<meta property="article:tag" content="源码">
<meta property="article:tag" content="源码分析">
<meta property="article:tag" content="事务隔离级别">
<meta property="article:tag" content="MVCC">
<meta property="article:tag" content="mvcc">
<meta property="article:tag" content="read view">
<meta property="article:tag" content="gap lock">
<meta property="article:tag" content="next-key lock">
<meta property="article:tag" content="幻读">
<meta property="article:tag" content="间隙锁">
<meta property="article:tag" content="行锁">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200510-1126082x.png">
@ -239,9 +235,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-05-10 09:55:10 / Modified: 22:26:13" itemprop="dateCreated datePublished" datetime="2020-05-10T09:55:10+08:00">2020-05-10</time>
<time title="Created: 2020-05-10 09:55:10" itemprop="dateCreated datePublished" datetime="2020-05-10T09:55:10+08:00">2020-05-10</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -320,7 +315,7 @@
<li><code>update table set ? where ?;</code></li>
<li><code>delete from table where ?;</code> </li>
</ul>
<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><img data-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><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200510-1126082x.png"><br>其实核心的目的还是不让这个 id=10 的记录不会出现幻读,那么就需要在 id 这个索引上加上三个 gap 锁,主键索引上就不用了,在 id 索引上已经控制住了id = 10 不会出现幻读,主键索引上这两条对应的记录已经锁了,所以就这样 OK 了</p>
</div>
@ -337,13 +332,13 @@
<div class="popular-posts-title"><a href="/2020/04/26/聊聊-mysql-的-MVCC/" rel="bookmark">聊聊 mysql 的 MVCC</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/20/redis数据结构介绍五/" rel="bookmark">redis数据结构介绍五-第五部分 对象</a></div>
<div class="popular-posts-title"><a href="/2020/01/04/redis数据结构介绍二/" rel="bookmark">redis数据结构介绍二-第二部分 跳表</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/04/12/redis系列介绍七/" rel="bookmark">redis系列介绍七-过期策略</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/01/10/redis数据结构介绍三/" rel="bookmark">redis数据结构介绍三-第三部分 整数集合</a></div>
<div class="popular-posts-title"><a href="/2019/12/26/redis数据结构介绍/" rel="bookmark">redis数据结构介绍-第一部分 SDS,链表,字典</a></div>
</li>
</ul>


+ 12
- 18
2020/05/17/聊聊我理解的分布式事务/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,9 +32,10 @@
<meta property="og:url" content="https://nicksxs.me/2020/05/17/%E8%81%8A%E8%81%8A%E6%88%91%E7%90%86%E8%A7%A3%E7%9A%84%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="前面说了mysql数据库的事务相关的,那事务是用来干嘛的,这里得补一下ACID, ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。 Atomicity">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200517-2127322x.png">
<meta property="article:published_time" content="2020-05-17T15:56:01.000Z">
<meta property="article:modified_time" content="2020-05-24T14:18:43.000Z">
<meta property="article:modified_time" content="2020-05-17T15:56:01.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="分布式事务">
<meta property="article:tag" content="两阶段提交">
@ -234,13 +235,6 @@
<time title="Created: 2020-05-17 23:56:01" itemprop="dateCreated datePublished" datetime="2020-05-17T23:56:01+08:00">2020-05-17</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-05-24 22:18:43" itemprop="dateModified" datetime="2020-05-24T22:18:43+08:00">2020-05-24</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -300,25 +294,25 @@
<p>前面说了mysql数据库的事务相关的,那事务是用来干嘛的,这里得补一下ACID,</p>
<blockquote>
<p><a href="https://zh.wikipedia.org/wiki/ACID" target="_blank" rel="noopener"><strong>ACID</strong></a>,是指<a href="https://zh.wikipedia.org/wiki/数据库管理系统" target="_blank" rel="noopener">数据库管理系统</a><a href="https://zh.wikipedia.org/wiki/DBMS" target="_blank" rel="noopener">DBMS</a>)在写入或更新资料的过程中,为保证<a href="https://zh.wikipedia.org/wiki/数据库事务" target="_blank" rel="noopener">事务</a>(transaction)是正确可靠的,所必须具备的四个特性:<a href="https://zh.wikipedia.org/w/index.php?title=原子性&action=edit&redlink=1" target="_blank" rel="noopener">原子性</a>(atomicity,或称不可分割性)、<a href="https://zh.wikipedia.org/w/index.php?title=一致性_(数据库系统)&action=edit&redlink=1" target="_blank" rel="noopener">一致性</a>(consistency)、<a href="https://zh.wikipedia.org/wiki/隔離性" target="_blank" rel="noopener">隔离性</a>(isolation,又称独立性)、<a href="https://zh.wikipedia.org/w/index.php?title=持久性&action=edit&redlink=1" target="_blank" rel="noopener">持久性</a>(durability)。</p>
<p><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID"><strong>ACID</strong></a>,是指<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F">数据库管理系统</a><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/DBMS">DBMS</a>)在写入或更新资料的过程中,为保证<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1">事务</a>(transaction)是正确可靠的,所必须具备的四个特性:<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/w/index.php?title=%E5%8E%9F%E5%AD%90%E6%80%A7&action=edit&redlink=1">原子性</a>(atomicity,或称不可分割性)、<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/w/index.php?title=%E4%B8%80%E8%87%B4%E6%80%A7_(%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F)&action=edit&redlink=1">一致性</a>(consistency)、<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E9%9A%94%E9%9B%A2%E6%80%A7">隔离性</a>(isolation,又称独立性)、<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/w/index.php?title=%E6%8C%81%E4%B9%85%E6%80%A7&action=edit&redlink=1">持久性</a>(durability)。</p>
</blockquote>
<ul>
<li><p>Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被<a href="https://zh.wikipedia.org/wiki/回滚_(数据管理)" target="_blank" rel="noopener">回滚</a>(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。<a href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1" target="_blank" rel="noopener">[1]</a></p>
<li><p>Atomicity(原子性):一个事务(transaction)中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E5%9B%9E%E6%BB%9A_(%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86)">回滚</a>(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。即,事务不可分割、不可约简。[<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1">1]</a></p>
</li>
<li><p>Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设<a href="https://zh.wikipedia.org/wiki/数据完整性" target="_blank" rel="noopener">约束</a><a href="https://zh.wikipedia.org/wiki/触发器_(数据库)" target="_blank" rel="noopener">触发器</a><a href="https://zh.wikipedia.org/wiki/级联回滚" target="_blank" rel="noopener">级联回滚</a>等。<a href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1" target="_blank" rel="noopener">[1]</a></p>
<li><p>Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%AE%8C%E6%95%B4%E6%80%A7">约束</a><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E8%A7%A6%E5%8F%91%E5%99%A8_(%E6%95%B0%E6%8D%AE%E5%BA%93)">触发器</a><a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E7%BA%A7%E8%81%94%E5%9B%9E%E6%BB%9A">级联回滚</a>等。[<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1">1]</a></p>
</li>
<li><p>Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。<a href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1" target="_blank" rel="noopener">[1]</a></p>
<li><p>Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括未提交读(Read uncommitted)、提交读(read committed)、可重复读(repeatable read)和串行化(Serializable)。[<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1">1]</a></p>
</li>
<li><p>Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。<a href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1" target="_blank" rel="noopener">[1]</a></p>
<li><p>Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。[<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID#cite_note-acid-1">1]</a></p>
</li>
</ul>
<p>在mysql中,借助于MVCC,各种级别的锁,日志等特性来实现了事务的ACID,但是这个我们通常是对于一个数据库服务的定义,常见的情况下我们的数据库随着业务发展也会从单实例变成多实例,组成主从Master-Slave架构,这个时候其实会有一些问题随之出现,比如说主从同步延迟,假如在业务代码中做了读写分离,对于一些敏感度较低的数据其实问题不是很大,只要主从延迟不到特别夸张的地步一般都是可以忍受的,但是对于一些核心的业务数据,比如订单之类的,不能忍受数据不一致,下了单了,付了款了,一刷订单列表,发现这个订单还没支付,甚至订单都没在,这对于用户来讲是恨不能容忍的错误,那么这里就需要一些措施,要不就不读写分离,要不就在 redis 这类缓存下订单,或者支付后加个延时等,这些都是一些补偿措施,并且这也是一个不太切当的例子,比较合适的例子也可以用这个下单来说,一般在电商平台下单会有挺多要做的事情,比如像下面这个图</p>
<p><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200517-2127322x.png" alt=""></p>
<p>下单的是后要冻结核销优惠券,如果账户里有钱要冻结扣除账户里的钱,如果使用了J 豆也一样,可能还有 E 卡,忽略我借用的平台,因为目前一般后台服务化之后,可能每一项都是对应的一个后台服务,我们期望的执行过程是要不全成功,要不就全保持执行前状态,不能是部分扣减核销成功了,部分还不行,所以我们处理这种情况会引入一些通用的方案,第一种叫<a href="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><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/WX20200517-2127322x.png"></p>
<p>下单的是后要冻结核销优惠券,如果账户里有钱要冻结扣除账户里的钱,如果使用了J 豆也一样,可能还有 E 卡,忽略我借用的平台,因为目前一般后台服务化之后,可能每一项都是对应的一个后台服务,我们期望的执行过程是要不全成功,要不就全保持执行前状态,不能是部分扣减核销成功了,部分还不行,所以我们处理这种情况会引入一些通用的方案,第一种叫<a target="_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>
<blockquote>
<p><strong>二阶段提交</strong>(英语:Two-phase Commit)是指在<a href="https://zh.wikipedia.org/wiki/计算机网络" target="_blank" rel="noopener">计算机网络</a>以及<a href="https://zh.wikipedia.org/wiki/数据库" target="_blank" rel="noopener">数据库</a>领域内,为了使基于<a href="https://zh.wikipedia.org/wiki/分布式系统" target="_blank" rel="noopener">分布式系统</a>架构下的所有节点在进行<a href="https://zh.wikipedia.org/wiki/数据库事务" target="_blank" rel="noopener">事务</a>提交时保持一致性而设计的一种<a href="https://zh.wikipedia.org/wiki/演算法" target="_blank" rel="noopener">算法</a>。通常,<strong>二阶段提交</strong>也被称为是一种<strong>协议</strong>(Protocol)。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的<a href="https://zh.wikipedia.org/wiki/ACID" target="_blank" rel="noopener">ACID</a>特性,需要引入一个作为<strong>协调者</strong>的组件来统一掌控所有节点(称作<strong>参与者</strong>)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。</p>
<p><strong>二阶段提交</strong>(英语:Two-phase Commit)是指在<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C">计算机网络</a>以及<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93">数据库</a>领域内,为了使基于<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E7%BB%9F">分布式系统</a>架构下的所有节点在进行<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BA%8B%E5%8A%A1">事务</a>提交时保持一致性而设计的一种<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E6%B3%95">算法</a>。通常,<strong>二阶段提交</strong>也被称为是一种<strong>协议</strong>(Protocol)。在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的<a target="_blank" rel="noopener" href="https://zh.wikipedia.org/wiki/ACID">ACID</a>特性,需要引入一个作为<strong>协调者</strong>的组件来统一掌控所有节点(称作<strong>参与者</strong>)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。</p>
</blockquote>
<p>对于上面的例子,我们将整个过程分成两个阶段,首先是提交请求阶段,这个阶段大概需要做的是确定资源存在,锁定资源,可能还要做好失败后回滚的准备,如果这些都 ok 了那么就响应成功,这里其实用到了一个叫事务的协调者的角色,类似于裁判员,每个节点都反馈第一阶段成功后,开始执行第二阶段,也就是实际执行操作,这里也是需要所有节点都反馈成功后才是执行成功,要不就是失败回滚。其实常用的分布式事务的解决方案主要也是基于此方案的改进,比如后面介绍的<a href="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 了那么就响应成功,这里其实用到了一个叫事务的协调者的角色,类似于裁判员,每个节点都反馈第一阶段成功后,开始执行第二阶段,也就是实际执行操作,这里也是需要所有节点都反馈成功后才是执行成功,要不就是失败回滚。其实常用的分布式事务的解决方案主要也是基于此方案的改进,比如后面介绍的<a target="_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>
<ul>
<li>第一是对于两阶段提交,其中默认只有协调者有超时时间,当一个参与者进入卡死状态时只能依赖协调者的超时来结束任务,这中间的时间参与者都是锁定着资源</li>
<li>第二是协调者的单点问题,万一挂了,参与者就会在那傻等着</li>


+ 11
- 16
2020/05/22/聊聊我刚学会的应用诊断方法/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,17 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2020/05/22/%E8%81%8A%E8%81%8A%E6%88%91%E5%88%9A%E5%AD%A6%E4%BC%9A%E7%9A%84%E5%BA%94%E7%94%A8%E8%AF%8A%E6%96%AD%E6%96%B9%E6%B3%95/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="因为传说中的出身问题,我以前写的是PHP,在使用 swoole 之前,基本的应用调试手段就是简单粗暴的 var_dump,exit,对于单进程模型的 PHP 也是简单有效,技术栈换成 Java 之后,就变得没那么容易,一方面是需要编译,另一方面是一般都是基于 spring 的项目,如果问题定位比较模糊,那框架层的是很难靠简单的 System.out.println 或者打 log 解决,(PS:我">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png">
<meta property="article:published_time" content="2020-05-22T15:26:50.000Z">
<meta property="article:modified_time" content="2020-05-24T13:51:43.000Z">
<meta property="article:modified_time" content="2020-05-22T15:26:50.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Jps">
<meta property="article:tag" content="Jstack">
<meta property="article:tag" content="Thread dump">
<meta property="article:tag" content="工具">
<meta property="article:tag" content="问题定位">
<meta property="article:tag" content="疑难问题">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png">
@ -236,13 +232,6 @@
<time title="Created: 2020-05-22 23:26:50" itemprop="dateCreated datePublished" datetime="2020-05-22T23:26:50+08:00">2020-05-22</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-05-24 21:51:43" itemprop="dateModified" datetime="2020-05-24T21:51:43+08:00">2020-05-24</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -304,8 +293,14 @@
<div class="post-body" itemprop="articleBody">
<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)[<a href="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><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png" alt=""><br>如果在idea 中运行或者调试时,可以直接点击这个照相机一样的按钮,右边就会出现了左边会显示所有的线程,右边会显示线程栈,</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&quot;main@1&quot; prio&#x3D;5 tid&#x3D;0x1 nid&#x3D;NA runnable</span><br><span class="line"> java.lang.Thread.State: RUNNABLE</span><br><span class="line"> at TreeDistance.treeDist(TreeDistance.java:64)</span><br><span class="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><span class="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><span class="line"> at TreeDistance.treeDist(TreeDistance.java:65)</span><br><span class="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)[<a target="_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><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/GPYHjd.png"><br>如果在idea 中运行或者调试时,可以直接点击这个照相机一样的按钮,右边就会出现了左边会显示所有的线程,右边会显示线程栈,</p>
<pre class="line-numbers language-none"><code class="language-none">&quot;main@1&quot; prio&#x3D;5 tid&#x3D;0x1 nid&#x3D;NA runnable
java.lang.Thread.State: RUNNABLE
at TreeDistance.treeDist(TreeDistance.java:64)
at TreeDistance.treeDist(TreeDistance.java:65)
at TreeDistance.treeDist(TreeDistance.java:65)
at TreeDistance.treeDist(TreeDistance.java:65)
at TreeDistance.main(TreeDistance.java:45)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这就是我们主线程的堆栈信息了,main 表示这个线程名,prio表示优先级,默认是 5,tid 表示线程 id,nid 表示对应的系统线程,后面的runnable 表示目前线程状态,因为是被我打了断点,所以是就许状态,然后下面就是对应的线程栈内容了,在<code>TreeDistance</code>类的 <code>treeDist</code>方法中,对应的文件行数是 64 行。<br>这里使用 thread dump一般也不会是上面我截图代码里的这种代码量很少的,一般是大型项目,有时候跑着跑着没反应,又不知道跑到哪了,特别是一些刚接触的大项目或者需要定位一个大项目的一个疑难问题,一时没思路时,可以使用这个方法,个人觉得非常有帮助。</p>
</div>


+ 74
- 9
2020/05/31/聊聊-Dubbo-的-SPI/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,15 +32,16 @@
<meta property="og:url" content="https://nicksxs.me/2020/05/31/%E8%81%8A%E8%81%8A-Dubbo-%E7%9A%84-SPI/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="SPI全称是Service Provider Interface,咋眼看跟api是不是有点相似,api是application interface,这两个其实在某些方面有类似的地方,也有蛮大的区别,比如我们基于 dubbo 的微服务,一般我们可以提供服务,然后非泛化调用的话,我们可以把 api 包提供给应用调用方,他们根据接口签名传对应参数并配置好对应的服务发现如 zk 等就可以调用我们的服务了,">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/3sKdpg.png">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/1590735097909.jpg">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/bqxWMp.png">
<meta property="article:published_time" content="2020-05-31T13:06:13.000Z">
<meta property="article:modified_time" content="2020-05-31T13:09:38.000Z">
<meta property="article:modified_time" content="2020-05-31T13:06:13.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Dubbo">
<meta property="article:tag" content="RPC">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="SPI">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/3sKdpg.png">
@ -232,9 +233,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-05-31 21:06:13 / Modified: 21:09:38" itemprop="dateCreated datePublished" datetime="2020-05-31T21:06:13+08:00">2020-05-31</time>
<time title="Created: 2020-05-31 21:06:13" itemprop="dateCreated datePublished" datetime="2020-05-31T21:06:13+08:00">2020-05-31</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -304,11 +304,76 @@
<p>简单介绍了 Java的 SPI,再来说说 dubbo 的,dubbo 中为啥要用 SPI 呢,主要是为了框架的可扩展性和性能方面的考虑,比如协议层 dubbo 默认使用 dubbo 协议,同时也支持很多其他协议,也支持用户自己实现协议,那么跟 Java 的 SPI 会有什么区别呢,我们也来看个文件</p>
<p><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/bqxWMp.png" alt="bqxWMp"></p>
<p>是不是看着很想,又有点不一样,在 Java 的 SPI 配置文件里每一行只有一个实现类的全限定名,在 Dubbo的 SPI配置文件中是 key=value 的形式,我们只需要对应的 key 就能加载对应的实现,</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 返回指定名字的扩展。如果指定名字的扩展不存在,则抛异常 &#123;<span class="doctag">@link</span> IllegalStateException&#125;.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> name</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">public</span> T <span class="title">getExtension</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (name == <span class="keyword">null</span> || name.length() == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"Extension name == null"</span>);</span><br><span class="line"> <span class="keyword">if</span> (<span class="string">"true"</span>.equals(name)) &#123;</span><br><span class="line"> <span class="keyword">return</span> getDefaultExtension();</span><br><span class="line"> &#125;</span><br><span class="line"> Holder&lt;Object&gt; holder = cachedInstances.get(name);</span><br><span class="line"> <span class="keyword">if</span> (holder == <span class="keyword">null</span>) &#123;</span><br><span class="line"> cachedInstances.putIfAbsent(name, <span class="keyword">new</span> Holder&lt;Object&gt;());</span><br><span class="line"> holder = cachedInstances.get(name);</span><br><span class="line"> &#125;</span><br><span class="line"> Object instance = holder.get();</span><br><span class="line"> <span class="keyword">if</span> (instance == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">synchronized</span> (holder) &#123;</span><br><span class="line"> instance = holder.get();</span><br><span class="line"> <span class="keyword">if</span> (instance == <span class="keyword">null</span>) &#123;</span><br><span class="line"> instance = createExtension(name);</span><br><span class="line"> holder.set(instance);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> (T) instance;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">/**
* 返回指定名字的扩展。如果指定名字的扩展不存在,则抛异常 &#123;@link IllegalStateException&#125;.
*
* @param name
* @return
*/</span>
<span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">"unchecked"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token class-name">T</span> <span class="token function">getExtension</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>name <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> name<span class="token punctuation">.</span><span class="token function">length</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">IllegalArgumentException</span><span class="token punctuation">(</span><span class="token string">"Extension name == null"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">"true"</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token function">getDefaultExtension</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">Holder</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">></span></span> holder <span class="token operator">=</span> cachedInstances<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>holder <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
cachedInstances<span class="token punctuation">.</span><span class="token function">putIfAbsent</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Holder</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Object</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
holder <span class="token operator">=</span> cachedInstances<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">Object</span> instance <span class="token operator">=</span> holder<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>instance <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">synchronized</span> <span class="token punctuation">(</span>holder<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
instance <span class="token operator">=</span> holder<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>instance <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
instance <span class="token operator">=</span> <span class="token function">createExtension</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
holder<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>instance<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></span><span></span><span></span></span></code></pre>
<p>这里其实就可以看出来第二个不同点了,就是这个<code>cachedInstances</code>,第一个是不用像 Java 原生的 SPI 那样去遍历加载对应的服务类,只需要通过 key 去寻找,并且寻找的时候会先从缓存的对象里去取,还有就是注意下这里的 DCL(double check lock)</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@SuppressWarnings</span>(<span class="string">"unchecked"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">private</span> T <span class="title">createExtension</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line"> Class&lt;?&gt; clazz = getExtensionClasses().get(name);</span><br><span class="line"> <span class="keyword">if</span> (clazz == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">throw</span> findException(name);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> T instance = (T) EXTENSION_INSTANCES.get(clazz);</span><br><span class="line"> <span class="keyword">if</span> (instance == <span class="keyword">null</span>) &#123;</span><br><span class="line"> EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());</span><br><span class="line"> instance = (T) EXTENSION_INSTANCES.get(clazz);</span><br><span class="line"> &#125;</span><br><span class="line"> injectExtension(instance);</span><br><span class="line"> Set&lt;Class&lt;?&gt;&gt; wrapperClasses = cachedWrapperClasses;</span><br><span class="line"> <span class="keyword">if</span> (wrapperClasses != <span class="keyword">null</span> &amp;&amp; wrapperClasses.size() &gt; <span class="number">0</span>) &#123;</span><br><span class="line"> <span class="keyword">for</span> (Class&lt;?&gt; wrapperClass : wrapperClasses) &#123;</span><br><span class="line"> instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> instance;</span><br><span class="line"> &#125; <span class="keyword">catch</span> (Throwable t) &#123;</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalStateException(<span class="string">"Extension instance(name: "</span> + name + <span class="string">", class: "</span> +</span><br><span class="line"> type + <span class="string">") could not be instantiated: "</span> + t.getMessage(), t);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@SuppressWarnings</span><span class="token punctuation">(</span><span class="token string">"unchecked"</span><span class="token punctuation">)</span>
<span class="token keyword">private</span> <span class="token class-name">T</span> <span class="token function">createExtension</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">Class</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">></span></span> clazz <span class="token operator">=</span> <span class="token function">getExtensionClasses</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>clazz <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">throw</span> <span class="token function">findException</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">T</span> instance <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> EXTENSION_INSTANCES<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>clazz<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>instance <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
EXTENSION_INSTANCES<span class="token punctuation">.</span><span class="token function">putIfAbsent</span><span class="token punctuation">(</span>clazz<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> clazz<span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
instance <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> EXTENSION_INSTANCES<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>clazz<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token function">injectExtension</span><span class="token punctuation">(</span>instance<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">Set</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Class</span><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">></span><span class="token punctuation">></span></span> wrapperClasses <span class="token operator">=</span> cachedWrapperClasses<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>wrapperClasses <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> wrapperClasses<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Class</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">></span></span> wrapperClass <span class="token operator">:</span> wrapperClasses<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
instance <span class="token operator">=</span> <span class="token function">injectExtension</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token class-name">T</span><span class="token punctuation">)</span> wrapperClass<span class="token punctuation">.</span><span class="token function">getConstructor</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span>instance<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> instance<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Throwable</span> t<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">IllegalStateException</span><span class="token punctuation">(</span><span class="token string">"Extension instance(name: "</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">", class: "</span> <span class="token operator">+</span>
type <span class="token operator">+</span> <span class="token string">") could not be instantiated: "</span> <span class="token operator">+</span> t<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> t<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>然后就是创建扩展了,这里如果 wrapperClasses 就会遍历生成wrapper实例,并做 setter 依赖注入,但是这里cachedWrapperClasses的来源还是有点搞不清楚,得再看下 com.alibaba.dubbo.common.extension.ExtensionLoader#loadFile的具体逻辑<br>又看了遍新的代码,这个函数被抽出来了</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * test if clazz is a wrapper class</span></span><br><span class="line"><span class="comment"> * &lt;p&gt;</span></span><br><span class="line"><span class="comment"> * which has Constructor with given class type as its only argument</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">private</span> <span class="keyword">boolean</span> <span class="title">isWrapperClass</span><span class="params">(Class&lt;?&gt; clazz)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">try</span> &#123;</span><br><span class="line"> clazz.getConstructor(type);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> &#125; <span class="keyword">catch</span> (NoSuchMethodException e) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">/**
* test if clazz is a wrapper class
* &lt;p>
* which has Constructor with given class type as its only argument
*/</span>
<span class="token keyword">private</span> <span class="token keyword">boolean</span> <span class="token function">isWrapperClass</span><span class="token punctuation">(</span><span class="token class-name">Class</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">></span></span> clazz<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
clazz<span class="token punctuation">.</span><span class="token function">getConstructor</span><span class="token punctuation">(</span>type<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">NoSuchMethodException</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>是否是 wrapperClass 其实就看构造函数的。</p>
</div>
@ -329,7 +394,7 @@
<div class="popular-posts-title"><a href="/2021/04/04/聊聊-dubbo-的线程池/" rel="bookmark">聊聊 dubbo 的线程池</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/05/22/聊聊我刚学会的应用诊断方法/" rel="bookmark">聊聊我刚学会的应用诊断方法</a></div>
<div class="popular-posts-title"><a href="/2020/02/16/Maven实用小技巧/" rel="bookmark">Maven实用小技巧</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/06/mybatis-的-和-是有啥区别/" rel="bookmark">mybatis 的 $ 和 # 是有啥区别</a></div>


+ 125
- 11
2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/index.html
File diff suppressed because it is too large
View File


+ 25
- 14
2020/06/13/聊聊一次-brew-update-引发的血案/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,9 +32,10 @@
<meta property="og:url" content="https://nicksxs.me/2020/06/13/%E8%81%8A%E8%81%8A%E4%B8%80%E6%AC%A1-brew-update-%E5%BC%95%E5%8F%91%E7%9A%84%E8%A1%80%E6%A1%88/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="熟悉我的人(谁熟悉你啊🙄)知道我以前写过 PHP,虽然现在在工作中没用到了,但是自己的一些小工具还是会用 PHP 来写,但是在 Mac 碰到了一个环境相关的问题,因为我也是个更新狂魔,用了 brew 之后因为 gfw 的原因,如果长时间不更新,有时候要装一个用它装一个软件的话,前置的更新耗时就会让人非常头大,所以我基本会隔天 update 一下,但是这样会带来一个很心烦的问题,就是像这样,因为我">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/YzS7vN.png">
<meta property="article:published_time" content="2020-06-13T14:28:56.000Z">
<meta property="article:modified_time" content="2020-06-13T14:31:35.000Z">
<meta property="article:modified_time" content="2020-06-13T14:28:56.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Mac">
<meta property="article:tag" content="PHP">
@ -231,9 +232,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-06-13 22:28:56 / Modified: 22:31:35" itemprop="dateCreated datePublished" datetime="2020-06-13T22:28:56+08:00">2020-06-13</time>
<time title="Created: 2020-06-13 22:28:56" itemprop="dateCreated datePublished" datetime="2020-06-13T22:28:56+08:00">2020-06-13</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -297,27 +297,38 @@
<p>熟悉我的人(谁熟悉你啊🙄)知道我以前写过 PHP,虽然现在在工作中没用到了,但是自己的一些小工具还是会用 PHP 来写,但是在 Mac 碰到了一个环境相关的问题,因为我也是个更新狂魔,用了 brew 之后因为 gfw 的原因,如果长时间不更新,有时候要装一个用它装一个软件的话,前置的更新耗时就会让人非常头大,所以我基本会隔天 update 一下,但是这样会带来一个很心烦的问题,就是像这样,因为我是要用一个固定版本的 PHP,如果一直升需要一直配扩展啥的也很麻烦,如果一直升级 PHP 到最新版可能会比较少碰到这个问题</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">dyld: Library not loaded: &#x2F;usr&#x2F;local&#x2F;opt&#x2F;icu4c&#x2F;lib&#x2F;libicui18n.64.dylib<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>这是什么鬼啊,然后我去这个目录下看了下,已经都是libicui18n.67.dylib了,而且它没有把原来的版本保留下来,首先这个是个叫 icu4c是啥玩意,谷歌了一下</p>
<blockquote>
<p>ICU4C是ICU在C/C++平台下的版本, ICU(International Component for Unicode)是基于”IBM公共许可证”的,与开源组织合作研究的, 用于支持软件国际化的开源项目。ICU4C提供了C/C++平台强大的国际化开发能力,软件开发者几乎可以使用ICU4C解决任何国际化的问题,根据各地的风俗和语言习惯,实现对数字、货币、时间、日期、和消息的格式化、解析,对字符串进行大小写转换、整理、搜索和排序等功能,必须一提的是,ICU4C提供了强大的BIDI算法,对阿拉伯语等BIDI语言提供了完善的支持。</p>
</blockquote>
<p>然后首先想到的解决方案就是能不能我使用<code>brew install icu4c@64</code>来重装下原来的版本,发现不行,并木有,之前的做法就只能是去网上把 64 的下载下来,然后放到这个目录,比较麻烦不智能,虽然没抱着希望在谷歌着,不过这次竟然给我找到了一个我认为非常 nice 的解决方案,因为是在 Stack Overflow 找到的,本着写给像我这样的小小白看的,那就稍微翻译一下<br>第一步,我们到 brew的目录下</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cd $(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-core/Formula</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">cd $(brew --prefix)&#x2F;Homebrew&#x2F;Library&#x2F;Taps&#x2F;homebrew&#x2F;homebrew-core&#x2F;Formula<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>这个可以理解为是 maven 的 pom 文件,不过有很多不同之处,使用ruby 写的,然后一个文件对应一个组件或者软件,那我们看下有个叫icu4c.rb的文件,<br>第二步看看它的提交历史</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git log --follow icu4c.rb</span><br></pre></td></tr></table></figure>
<p>在 git log 的海洋中寻找,寻找它的(64版本)的身影<br><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/YzS7vN.png" alt=""><br>第三步注意这三个红框,Stack Overflow 给出来的答案这一步是找到这个 commit id 直接切出一个新分支</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout -b icu4c-63 e7f0f10dc63b1dc1061d475f1a61d01b70ef2cb7</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">git log --follow icu4c.rb<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>在 git log 的海洋中寻找,寻找它的(64版本)的身影<br><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/YzS7vN.png"><br>第三步注意这三个红框,Stack Overflow 给出来的答案这一步是找到这个 commit id 直接切出一个新分支</p>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">git checkout -b icu4c-63 e7f0f10dc63b1dc1061d475f1a61d01b70ef2cb7<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>其实注意 commit id 旁边的红框,这个是有tag 的,可以直接</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout icu4c-64</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">git checkout icu4c-64<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>PS: 因为我的问题是出在 64 的问题,Stack Overflow 回答的是 63 的,反正是一样的解决方法<br>第四部,切回去之后我们就可以用 brew 提供的基于文件的安装命令来重新装上 64 版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew reinstall ./icu4c.rb</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">brew reinstall .&#x2F;icu4c.rb<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>然后就是第五步,切换版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew switch icu4c 64.2</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">brew switch icu4c 64.2<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>最后把分支切回来</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git checkout master</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">git checkout master<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p>是不是感觉很厉害的解决方法,大佬还提供了一个更牛的,直接写个 zsh 方法</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> zsh</span></span><br><span class="line">function hiicu64() &#123;</span><br><span class="line"> local last_dir=$(pwd)</span><br><span class="line"></span><br><span class="line"> cd $(brew --prefix)/Homebrew/Library/Taps/homebrew/homebrew-core/Formula</span><br><span class="line"> git checkout icu4c-4</span><br><span class="line"> brew reinstall ./icu4c.rb</span><br><span class="line"> brew switch icu4c 64.2</span><br><span class="line"> git checkout master</span><br><span class="line"></span><br><span class="line"> cd $last_dir</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell"># zsh
function hiicu64() &#123;
local last_dir&#x3D;$(pwd)
cd $(brew --prefix)&#x2F;Homebrew&#x2F;Library&#x2F;Taps&#x2F;homebrew&#x2F;homebrew-core&#x2F;Formula
git checkout icu4c-4
brew reinstall .&#x2F;icu4c.rb
brew switch icu4c 64.2
git checkout master
cd $last_dir
&#125;<span aria-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></code></pre>
<p>对应自己的版本改改版本号就可以了,非常好用。</p>
</div>


+ 6
- 6
2020/06/21/介绍一下-RocketMQ/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,9 +32,10 @@
<meta property="og:url" content="https://nicksxs.me/2020/06/21/%E4%BB%8B%E7%BB%8D%E4%B8%80%E4%B8%8B-RocketMQ/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="说起消息队列一般Web后端做过一段时间开发的肯定会用过,在前司的时候用的是改良版的 NSQ,有点像 NOSQL 的简写版🙄,其实是个go 语言写的消息队列,nsq 看代码提交感觉最近更新的不是很勤,不过因为前司有专门的中间件团队,所以还是挺好用的,而且中间件团队的大牛也很厉害,一次都没碰到过丢消息之类的错误,然后现在公司用的是 RocketMQ,本着总还是要了解下的,并且消息队列也是服务端开发中">
<meta property="og:locale">
<meta property="og:image" content="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/6073827-a998e005dd13967c.png">
<meta property="article:published_time" content="2020-06-21T13:25:22.000Z">
<meta property="article:modified_time" content="2020-06-21T13:35:12.000Z">
<meta property="article:modified_time" content="2020-06-21T13:25:22.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="MQ">
<meta property="article:tag" content="消息队列">
@ -231,9 +232,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-06-21 21:25:22 / Modified: 21:35:12" itemprop="dateCreated datePublished" datetime="2020-06-21T21:25:22+08:00">2020-06-21</time>
<time title="Created: 2020-06-21 21:25:22" itemprop="dateCreated datePublished" datetime="2020-06-21T21:25:22+08:00">2020-06-21</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -304,7 +304,7 @@
<div class="post-body" itemprop="articleBody">
<p>说起消息队列一般Web后端做过一段时间开发的肯定会用过,在前司的时候用的是改良版的 NSQ,有点像 NOSQL 的简写版🙄,其实是个go 语言写的消息队列,<a href="https://github.com/nsqio/nsq" target="_blank" rel="noopener">nsq</a> 看代码提交感觉最近更新的不是很勤,不过因为前司有专门的中间件团队,所以还是挺好用的,而且中间件团队的大牛也很厉害,一次都没碰到过丢消息之类的错误,然后现在公司用的是 RocketMQ,本着总还是要了解下的,并且消息队列也是服务端开发中一个很重要的中间件,因为不太有不需要用消息队列的后端团队了吧,原来对 nsq 也不是特别了解原理,就打算了解下 RocketMQ。</p>
<p>说起消息队列一般Web后端做过一段时间开发的肯定会用过,在前司的时候用的是改良版的 NSQ,有点像 NOSQL 的简写版🙄,其实是个go 语言写的消息队列,<a target="_blank" rel="noopener" href="https://github.com/nsqio/nsq">nsq</a> 看代码提交感觉最近更新的不是很勤,不过因为前司有专门的中间件团队,所以还是挺好用的,而且中间件团队的大牛也很厉害,一次都没碰到过丢消息之类的错误,然后现在公司用的是 RocketMQ,本着总还是要了解下的,并且消息队列也是服务端开发中一个很重要的中间件,因为不太有不需要用消息队列的后端团队了吧,原来对 nsq 也不是特别了解原理,就打算了解下 RocketMQ。</p>
<p>还是像我这样的小白专属,消息队列用来干啥,很多都是标准答案,用来削峰填谷的,这个完全对,只是我想结合场景说给像我这样的小白同学听,想想一个电商的下单功能,除了 AT 两家之外应该大部分都是接入的支付,那么下单支付完成后一般都是等支付回调,告诉你支付完成了(也有可能是失败了,或者超时了咱们主动去查),然后这个回调里我们自己的业务代码干点啥,首先比如是把订单状态改掉了,然后会有各类的操作,比如把优惠券核销了,把其他金钱相关的也核销了,把购物车里对应的商品给删了,还有更次要的,比如发个客服消息,让用户确认下地址的,给用户加积分的等等等等,想象下如果这些都是回调里一股脑儿做掉了,那可能你的代码健壮性跟相关服务的稳定性还有性能要达到一个非常高的水平才能让业务不出现异常,并且万一流量打起来了,这些重要的不重要的操作都会阻塞着,所以需要用一个消息队列,在接到回调后只处理极少的几个核心操作,完了就把这个消息丢进消息队列里,让各个业务方去消费这个消息,把客服消息发一下,给用户加个积分等等,这样子主要的业务流程需要处理的事情就少了,速度也加快了,这个例子呢不能严格算是削峰填谷的例子,不过也算是消息队列的比较典型的使用场景了,要说真实的削峰填谷的话其实可以这么理解,假如短时间内有 1w 个请求进来,系统能支持的 QPS 才 1000,那么正常情况下服务就挂了,或者被限流了,为了让服务正常,那么可以把这些请求先放进消息队列里,我服务端以拉的模式按我的处理能力来消费,这样就没啥问题了</p>
<p>扯了这么多来聊聊 RocketMQ 长啥样</p>
<p><img data-src="https://mystore-1255223546.cos.ap-chengdu.myqcloud.com/uPic/6073827-a998e005dd13967c.png" alt="6073827-a998e005dd13967c"></p>
@ -498,7 +498,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#NameServer"><span class="nav-number">1.</span> <span class="nav-text">NameServer</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Broker"><span class="nav-number">2.</span> <span class="nav-text">Broker</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#Broker的特点"><span class="nav-number">2.0.1.</span> <span class="nav-text">Broker的特点</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Producer"><span class="nav-number">3.</span> <span class="nav-text">Producer</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#生产者端的负载均衡"><span class="nav-number">3.0.1.</span> <span class="nav-text">生产者端的负载均衡</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Consumer"><span class="nav-number">4.</span> <span class="nav-text">Consumer</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#消费者端的负载均衡"><span class="nav-number">4.0.1.</span> <span class="nav-text">消费者端的负载均衡</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#补充一些概念"><span class="nav-number">5.</span> <span class="nav-text">补充一些概念</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-4"><a class="nav-link" href="#NameServer"><span class="nav-number">1.</span> <span class="nav-text">NameServer</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Broker"><span class="nav-number">2.</span> <span class="nav-text">Broker</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#Broker%E7%9A%84%E7%89%B9%E7%82%B9"><span class="nav-number">2.0.1.</span> <span class="nav-text">Broker的特点</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Producer"><span class="nav-number">3.</span> <span class="nav-text">Producer</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#%E7%94%9F%E4%BA%A7%E8%80%85%E7%AB%AF%E7%9A%84%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1"><span class="nav-number">3.0.1.</span> <span class="nav-text">生产者端的负载均衡</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Consumer"><span class="nav-number">4.</span> <span class="nav-text">Consumer</span></a><ol class="nav-child"><li class="nav-item nav-level-6"><a class="nav-link" href="#%E6%B6%88%E8%B4%B9%E8%80%85%E7%AB%AF%E7%9A%84%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1"><span class="nav-number">4.0.1.</span> <span class="nav-text">消费者端的负载均衡</span></a></li></ol></li></ol></li><li class="nav-item nav-level-4"><a class="nav-link" href="#%E8%A1%A5%E5%85%85%E4%B8%80%E4%BA%9B%E6%A6%82%E5%BF%B5"><span class="nav-number">5.</span> <span class="nav-text">补充一些概念</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 761
- 28
2020/06/26/聊一下-RocketMQ-的-Consumer/index.html
File diff suppressed because it is too large
View File


+ 584
- 19
2020/07/05/聊一下-RocketMQ-的-NameServer-源码/index.html
File diff suppressed because it is too large
View File


+ 8
- 8
2020/07/11/2020年中总结/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,12 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2020/07/11/2020%E5%B9%B4%E4%B8%AD%E6%80%BB%E7%BB%93/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="很快2020 年就过了一半了,而且是今年这么特殊的一年,很多事情都发生的出乎意料,疫情这个绕不过去的话题,之前写了点比较愤青的文字,感觉不太适合发出来就烂在草稿箱里吧,这个目前一大影响估计是今年都没办法完全摘下口罩了,前面几个月来回杭州都开车,因为彭埠大桥不通行了,实在是非常不方便,每条路都灰常堵,心累,吐槽下杭州的交通规划和交警同志,工作实在做的不咋地。 另外一件是就是蜗壳,从前不知道黝黑蜗壳是">
<meta property="og:locale">
<meta property="article:published_time" content="2020-07-11T15:20:38.000Z">
<meta property="article:modified_time" content="2020-07-11T15:21:22.000Z">
<meta property="article:modified_time" content="2020-07-11T15:20:38.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="年中总结">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="2020">
<meta property="article:tag" content="年中总结">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/07/11/2020%E5%B9%B4%E4%B8%AD%E6%80%BB%E7%BB%93/">
@ -227,9 +228,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-07-11 23:20:38 / Modified: 23:21:22" itemprop="dateCreated datePublished" datetime="2020-07-11T23:20:38+08:00">2020-07-11</time>
<time title="Created: 2020-07-11 23:20:38" itemprop="dateCreated datePublished" datetime="2020-07-11T23:20:38+08:00">2020-07-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -308,13 +308,13 @@
<div class="popular-posts-title"><a href="/2020/09/26/在老丈人家的小工记四/" rel="bookmark">在老丈人家的小工记四</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/13/在老丈人家的小工记三/" rel="bookmark">在老丈人家的小工记三</a></div>
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
</li>
</ul>


+ 461
- 18
2020/07/19/聊聊-RocketMQ-的-Broker-源码/index.html
File diff suppressed because it is too large
View File


+ 4
- 4
2020/07/26/我是如何走上跑步这条不归路的/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/07/26/%E6%88%91%E6%98%AF%E5%A6%82%E4%BD%95%E8%B5%B0%E4%B8%8A%E8%B7%91%E6%AD%A5%E8%BF%99%E6%9D%A1%E4%B8%8D%E5%BD%92%E8%B7%AF%E7%9A%84/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="这周因为没有准备技术方面的内容加之之前有想分享下我和跑步的一些事情,我从小学开始就是个体育渣,因为体重大非常胖,小学的时候要做仰卧起坐,基本是一个都起不来,然后那时候跑步也是要我命那种,跟另外一个比较胖的同学在跑步队尾苟延残喘,只有立定跳远还行。 时光飞逝,我在初中高中的时候因为爱打篮球,以为自己体质已经有了质的变化,所以在体育课跑步的时候妄图跟一位体育非常好的同学一起跑,结果跟的快断气了,最终还">
<meta property="og:locale">
<meta property="article:published_time" content="2020-07-26T15:32:55.000Z">
<meta property="article:modified_time" content="2020-07-26T15:34:01.000Z">
<meta property="article:modified_time" content="2020-07-26T15:32:55.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="运动">
@ -228,9 +229,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-07-26 23:32:55 / Modified: 23:34:01" itemprop="dateCreated datePublished" datetime="2020-07-26T23:32:55+08:00">2020-07-26</time>
<time title="Created: 2020-07-26 23:32:55" itemprop="dateCreated datePublished" datetime="2020-07-26T23:32:55+08:00">2020-07-26</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">


+ 506
- 19
2020/08/02/聊聊-Java-自带的那些逆天工具/index.html
File diff suppressed because it is too large
View File


+ 14
- 13
2020/08/06/Linux-下-grep-命令的一点小技巧/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,22 +26,20 @@
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>
<meta name="description" content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 12grep &#39;xxx&#39; xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\&quot;userId\&quot;:\&quot;123456\&quot;,因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了,如果直接这样">
<meta name="description" content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 grep &#39;xxx&#39; xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\&quot;userId\&quot;:\&quot;123456\&quot;,因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了">
<meta property="og:type" content="article">
<meta property="og:title" content="Linux 下 grep 命令的一点小技巧">
<meta property="og:url" content="https://nicksxs.me/2020/08/06/Linux-%E4%B8%8B-grep-%E5%91%BD%E4%BB%A4%E7%9A%84%E4%B8%80%E7%82%B9%E5%B0%8F%E6%8A%80%E5%B7%A7/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 12grep &#39;xxx&#39; xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\&quot;userId\&quot;:\&quot;123456\&quot;,因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了,如果直接这样">
<meta property="og:description" content="用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志, 譬如 grep &#39;xxx&#39; xxxx.log 然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的 比如这样\&quot;userId\&quot;:\&quot;123456\&quot;,因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/sUdv2K.png">
<meta property="article:published_time" content="2020-08-06T09:07:17.000Z">
<meta property="article:modified_time" content="2020-08-06T13:30:26.000Z">
<meta property="article:modified_time" content="2020-08-06T09:07:17.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Linux">
<meta property="article:tag" content="linux">
<meta property="article:tag" content="grep">
<meta property="article:tag" content="转义">
<meta property="article:tag" content="小技巧">
<meta property="article:tag" content="查日志">
<meta property="article:tag" content="问题排查">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/sUdv2K.png">
@ -232,9 +230,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-08-06 17:07:17 / Modified: 21:30:26" itemprop="dateCreated datePublished" datetime="2020-08-06T17:07:17+08:00">2020-08-06</time>
<time title="Created: 2020-08-06 17:07:17" itemprop="dateCreated datePublished" datetime="2020-08-06T17:07:17+08:00">2020-08-06</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -307,16 +304,20 @@
<p>用了比较久的 grep 命令,其实都只是用了最最基本的功能来查日志,</p>
<p>譬如</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">grep 'xxx' xxxx.log</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">
grep &#39;xxx&#39; xxxx.log
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>然后有挺多情况比如想要找日志里带一些符号什么的,就需要用到一些特殊的</p>
<p>比如这样<code>\&quot;userId\&quot;:\&quot;123456\&quot;</code>,因为比如用户 ID 有时候会跟其他的 id 一样,只用具体的值 123456 来查的话干扰信息太多了,如果直接这样</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">grep '\"userId\":\"123456\"' xxxx.log</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-shell" data-language="shell"><code class="language-shell">
grep &#39;\&quot;userId\&quot;:\&quot;123456\&quot;&#39; xxxx.log
<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>好像不行,盲猜就是符号的问题,特别是<code>\</code><code>&quot;</code>这两个,</p>
<p>之前一直是想试一下,但是没成功,昨天在排查一个问题的时候发现了,只要把这些都转义了就行了</p>
<p><code>grep &#39;\\\&quot;userId\\\&quot;:\\\&quot;123456\\\&quot;&#39; xxxx.log</code></p>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/sUdv2K.png" alt=""></p>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/sUdv2K.png"></p>
</div>


+ 4
- 4
2020/08/16/周末我在老丈人家打了天小工/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/08/16/%E5%91%A8%E6%9C%AB%E6%88%91%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E6%89%93%E4%BA%86%E5%A4%A9%E5%B0%8F%E5%B7%A5/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="这周回家提前约好了要去老丈人家帮下忙,因为在翻修下老房子,活不是特别整的那种,所以大部分都是自己干,或者找个大工临时干几天(我们这那种比较专业的泥工匠叫做大工),像我这样去帮忙的,就是干点小工(把给大工帮忙的,干些偏体力活的叫做小工)的活。从大学毕业以后真的蛮少帮家里干活了,以前上学的时候放假还是帮家里淘个米,简单的扫地拖地啥的,当然刚高考完的时候,还去我爸厂里帮忙干了几天的活,实在是比较累,不过">
<meta property="og:locale">
<meta property="article:published_time" content="2020-08-16T15:01:09.000Z">
<meta property="article:modified_time" content="2020-08-16T15:48:08.000Z">
<meta property="article:modified_time" content="2020-08-16T15:01:09.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="运动">
@ -229,9 +230,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-08-16 23:01:09 / Modified: 23:48:08" itemprop="dateCreated datePublished" datetime="2020-08-16T23:01:09+08:00">2020-08-16</time>
<time title="Created: 2020-08-16 23:01:09" itemprop="dateCreated datePublished" datetime="2020-08-16T23:01:09+08:00">2020-08-16</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">


+ 442
- 17
2020/08/22/Filter-Intercepter-Aop-啥-啥-啥-这些都是啥/index.html
File diff suppressed because it is too large
View File


+ 4
- 4
2020/08/30/这周末我又在老丈人家打了天小工/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/08/30/%E8%BF%99%E5%91%A8%E6%9C%AB%E6%88%91%E5%8F%88%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E6%89%93%E4%BA%86%E5%A4%A9%E5%B0%8F%E5%B7%A5/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="因为活实在比较多,也不太好叫大工(活比较杂散),相比上一次我跟 LD 俩人晚起了一点,我真的是只要有事,早上就醒的很早,准备八点出发的,六点就醒了,然后想继续睡就一直做梦🤦‍♂️,差不多八点半多到的丈人家,他们应该已经干了有一会了,我们到了以后就分配给我撬地板的活,上次说的那个敲掉柜子的房间里,还铺着质地还不错的木地板,但是也不想要了,得撬掉重新铺。拿着撬棍和榔头就上楼去干了,浙江这几天的天气,">
<meta property="og:locale">
<meta property="article:published_time" content="2020-08-30T15:22:57.000Z">
<meta property="article:modified_time" content="2020-08-30T15:31:08.000Z">
<meta property="article:modified_time" content="2020-08-30T15:22:57.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="运动">
@ -229,9 +230,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-08-30 23:22:57 / Modified: 23:31:08" itemprop="dateCreated datePublished" datetime="2020-08-30T23:22:57+08:00">2020-08-30</time>
<time title="Created: 2020-08-30 23:22:57" itemprop="dateCreated datePublished" datetime="2020-08-30T23:22:57+08:00">2020-08-30</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">


+ 85
- 19
2020/09/06/mybatis-的-和-是有啥区别/index.html
File diff suppressed because it is too large
View File


+ 6
- 5
2020/09/13/在老丈人家的小工记三/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,14 +32,16 @@
<meta property="og:url" content="https://nicksxs.me/2020/09/13/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E4%B8%89/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="小工记三前面这两周周末也都去老丈人家帮忙了,上上周周六先是去了那个在装修的旧房子那,把三楼收拾了下,因为要搬进来住,来不及等二楼装修好,就要把三楼里的东西都整理干净,这个活感觉是比较 easy,原来是就准备把三楼当放东西仓储的地方了,我们乡下大部分三层楼都是这么用的,这次也是没办法,之前搬进来的木头什么的都搬出去,主要是这上面灰尘太多,后面清理鼻孔的时候都是黑色的了,把东西都搬出去以后主要是地还是">
<meta property="og:locale">
<meta property="article:published_time" content="2020-09-13T15:37:21.000Z">
<meta property="article:modified_time" content="2020-09-13T15:39:01.000Z">
<meta property="article:modified_time" content="2020-09-13T15:37:21.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="运动">
<meta property="article:tag" content="减肥">
<meta property="article:tag" content="跑步">
<meta property="article:tag" content="干活">
<meta property="article:tag" content="小技巧">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/09/13/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E4%B8%89/">
@ -229,9 +231,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-09-13 23:37:21 / Modified: 23:39:01" itemprop="dateCreated datePublished" datetime="2020-09-13T23:37:21+08:00">2020-09-13</time>
<time title="Created: 2020-09-13 23:37:21" itemprop="dateCreated datePublished" datetime="2020-09-13T23:37:21+08:00">2020-09-13</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -447,7 +448,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#小工记三"><span class="nav-number">1.</span> <span class="nav-text">小工记三</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B0%8F%E5%B7%A5%E8%AE%B0%E4%B8%89"><span class="nav-number">1.</span> <span class="nav-text">小工记三</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 62
- 22
2020/09/20/Leetcode-3-Longest-Substring-Without-Repeating-Characters-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,19 +26,20 @@
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>
<meta name="description" content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:123Input: s &#x3D; &quot;abcab">
<meta name="description" content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:Input: s &#x3D; &quot;abcabcbb">
<meta property="og:type" content="article">
<meta property="og:title" content="Leetcode 3 Longest Substring Without Repeating Characters 题解分析">
<meta property="og:url" content="https://nicksxs.me/2020/09/20/Leetcode-3-Longest-Substring-Without-Repeating-Characters-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:123Input: s &#x3D; &quot;abcab">
<meta property="og:description" content="又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差 简要介绍Given a string s, find the length of the longest substring without repeating characters. 样例Example 1:Input: s &#x3D; &quot;abcabcbb">
<meta property="og:locale">
<meta property="article:published_time" content="2020-09-20T13:40:23.000Z">
<meta property="article:modified_time" content="2020-09-20T13:45:17.000Z">
<meta property="article:modified_time" content="2020-09-20T13:40:23.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="题解">
<meta property="article:tag" content="string">
<meta property="article:tag" content="代码题解">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/09/20/Leetcode-3-Longest-Substring-Without-Repeating-Characters-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -228,9 +229,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-09-20 21:40:23 / Modified: 21:45:17" itemprop="dateCreated datePublished" datetime="2020-09-20T21:40:23+08:00">2020-09-20</time>
<time title="Created: 2020-09-20 21:40:23" itemprop="dateCreated datePublished" datetime="2020-09-20T21:40:23+08:00">2020-09-20</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -246,11 +246,11 @@
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
<a href="/categories/%E5%AD%97%E7%AC%A6%E4%B8%B2-online/" itemprop="url" rel="index"><span itemprop="name">字符串 - online</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E5%AD%97%E7%AC%A6%E4%B8%B2-online/" itemprop="url" rel="index"><span itemprop="name">字符串 - online</span></a>
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
@ -299,14 +299,54 @@
<p>又做了个题,看记录是以前用 C++写过的,现在捋一捋思路,用 Java 再写了一下,思路还是比较清晰的,但是边界细节处理得比较差</p>
<h2 id="简要介绍"><a href="#简要介绍" 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>
<h2 id="样例"><a href="#样例" class="headerlink" title="样例"></a>样例</h2><h4 id="Example-1"><a href="#Example-1" class="headerlink" title="Example 1:"></a>Example 1:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Input: s &#x3D; &quot;abcabcbb&quot;</span><br><span class="line">Output: 3</span><br><span class="line">Explanation: The answer is &quot;abc&quot;, with the length of 3.</span><br></pre></td></tr></table></figure>
<h4 id="Example-2"><a href="#Example-2" class="headerlink" title="Example 2:"></a>Example 2:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Input: s &#x3D; &quot;bbbbb&quot;</span><br><span class="line">Output: 1</span><br><span class="line">Explanation: The answer is &quot;b&quot;, with the length of 1.</span><br></pre></td></tr></table></figure>
<h4 id="Example-3"><a href="#Example-3" class="headerlink" title="Example 3:"></a>Example 3:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Input: s &#x3D; &quot;pwwkew&quot;</span><br><span class="line">Output: 3</span><br><span class="line">Explanation: The answer is &quot;wke&quot;, with the length of 3.</span><br><span class="line">Notice that the answer must be a substring, &quot;pwke&quot; is a subsequence and not a substring.</span><br></pre></td></tr></table></figure>
<h4 id="Example-4"><a href="#Example-4" class="headerlink" title="Example 4:"></a>Example 4:</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input: s &#x3D; &quot;&quot;</span><br><span class="line">Output: 0</span><br></pre></td></tr></table></figure>
<h2 id="样例"><a href="#样例" class="headerlink" title="样例"></a>样例</h2><h4 id="Example-1"><a href="#Example-1" class="headerlink" title="Example 1:"></a>Example 1:</h4><pre class="line-numbers language-none"><code class="language-none">Input: s &#x3D; &quot;abcabcbb&quot;
Output: 3
Explanation: The answer is &quot;abc&quot;, with the length of 3.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h4 id="Example-2"><a href="#Example-2" class="headerlink" title="Example 2:"></a>Example 2:</h4><pre class="line-numbers language-none"><code class="language-none">Input: s &#x3D; &quot;bbbbb&quot;
Output: 1
Explanation: The answer is &quot;b&quot;, with the length of 1.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h4 id="Example-3"><a href="#Example-3" class="headerlink" title="Example 3:"></a>Example 3:</h4><pre class="line-numbers language-none"><code class="language-none">Input: s &#x3D; &quot;pwwkew&quot;
Output: 3
Explanation: The answer is &quot;wke&quot;, with the length of 3.
Notice that the answer must be a substring, &quot;pwke&quot; is a subsequence and not a substring.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre>
<h4 id="Example-4"><a href="#Example-4" class="headerlink" title="Example 4:"></a>Example 4:</h4><pre class="line-numbers language-none"><code class="language-none">Input: s &#x3D; &quot;&quot;
Output: 0<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>就是一个最长不重复的字符串长度,因为也是中等难度的题,不太需要特别复杂的思考,最基本的就是O(N*N)两重循环,不过显然不太好,万一超时间,还有一种就是线性复杂度的了,这个就是需要搞定一个思路,比如字符串时 <code>a</code>bcdefg<code>a</code>qwrty,比如遍历到第二个<code>a</code>的时候其实不用再从头去遍历了,只要把前面那个<code>a</code>给排除掉,继续往下算就好了</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"> Map&lt;String, Integer&gt; counter = <span class="keyword">new</span> HashMap&lt;&gt;();</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">lengthOfLongestSubstring</span><span class="params">(String s)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">int</span> length = s.length();</span><br><span class="line"> <span class="comment">// 当前的长度</span></span><br><span class="line"> <span class="keyword">int</span> subStringLength = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 最长的长度</span></span><br><span class="line"> <span class="keyword">int</span> maxSubStringLength = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 考虑到重复的位置已经被跳过的情况,即已经在当前长度的字符串范围之前的重复字符不需要回溯</span></span><br><span class="line"> <span class="keyword">int</span> lastDuplicatePos = -<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; length; i++) &#123;</span><br><span class="line"> <span class="comment">// 使用 map 存储字符和上一次出现的位置,如果存在并且大于上一次重复位置</span></span><br><span class="line"> <span class="keyword">if</span> (counter.get(String.valueOf(s.charAt(i))) != <span class="keyword">null</span> &amp;&amp; counter.get(String.valueOf(s.charAt(i))) &gt; lastDuplicatePos) &#123;</span><br><span class="line"> <span class="comment">// 记录重复位置</span></span><br><span class="line"> lastDuplicatePos = counter.get(String.valueOf(s.charAt(i)));</span><br><span class="line"> <span class="comment">// 重置不重复子串的长度,减去重复起点</span></span><br><span class="line"> subStringLength = i - counter.get(String.valueOf(s.charAt(i))) - <span class="number">1</span>;</span><br><span class="line"> <span class="comment">// 替换当前位置</span></span><br><span class="line"> counter.replace(String.valueOf(s.charAt(i)), i);</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="comment">// 如果不存在就直接 put</span></span><br><span class="line"> counter.put(String.valueOf(s.charAt(i)), i);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 长度累加</span></span><br><span class="line"> subStringLength++;</span><br><span class="line"> <span class="keyword">if</span> (subStringLength &gt; maxSubStringLength) &#123;</span><br><span class="line"> <span class="comment">// 简单替换</span></span><br><span class="line"> maxSubStringLength = subStringLength;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> maxSubStringLength;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-Java" data-language="Java"><code class="language-Java">class Solution &#123;
Map&lt;String, Integer&gt; counter &#x3D; new HashMap&lt;&gt;();
public int lengthOfLongestSubstring(String s) &#123;
int length &#x3D; s.length();
&#x2F;&#x2F; 当前的长度
int subStringLength &#x3D; 0;
&#x2F;&#x2F; 最长的长度
int maxSubStringLength &#x3D; 0;
&#x2F;&#x2F; 考虑到重复的位置已经被跳过的情况,即已经在当前长度的字符串范围之前的重复字符不需要回溯
int lastDuplicatePos &#x3D; -1;
for (int i &#x3D; 0; i &lt; length; i++) &#123;
&#x2F;&#x2F; 使用 map 存储字符和上一次出现的位置,如果存在并且大于上一次重复位置
if (counter.get(String.valueOf(s.charAt(i))) !&#x3D; null &amp;&amp; counter.get(String.valueOf(s.charAt(i))) &gt; lastDuplicatePos) &#123;
&#x2F;&#x2F; 记录重复位置
lastDuplicatePos &#x3D; counter.get(String.valueOf(s.charAt(i)));
&#x2F;&#x2F; 重置不重复子串的长度,减去重复起点
subStringLength &#x3D; i - counter.get(String.valueOf(s.charAt(i))) - 1;
&#x2F;&#x2F; 替换当前位置
counter.replace(String.valueOf(s.charAt(i)), i);
&#125; else &#123;
&#x2F;&#x2F; 如果不存在就直接 put
counter.put(String.valueOf(s.charAt(i)), i);
&#125;
&#x2F;&#x2F; 长度累加
subStringLength++;
if (subStringLength &gt; maxSubStringLength) &#123;
&#x2F;&#x2F; 简单替换
maxSubStringLength &#x3D; subStringLength;
&#125;
&#125;
return maxSubStringLength;
&#125;
&#125;<span aria-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></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>注释应该写的比较清楚了。</p>
</div>
@ -318,19 +358,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
</ul>
@ -458,7 +498,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#简要介绍"><span class="nav-number">1.</span> <span class="nav-text">简要介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#样例"><span class="nav-number">2.</span> <span class="nav-text">样例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-1"><span class="nav-number">2.0.1.</span> <span class="nav-text">Example 1:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-2"><span class="nav-number">2.0.2.</span> <span class="nav-text">Example 2:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-3"><span class="nav-number">2.0.3.</span> <span class="nav-text">Example 3:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-4"><span class="nav-number">2.0.4.</span> <span class="nav-text">Example 4:</span></a></li></ol></li></ol></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">简要介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A0%B7%E4%BE%8B"><span class="nav-number">2.</span> <span class="nav-text">样例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-1"><span class="nav-number">2.0.1.</span> <span class="nav-text">Example 1:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-2"><span class="nav-number">2.0.2.</span> <span class="nav-text">Example 2:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-3"><span class="nav-number">2.0.3.</span> <span class="nav-text">Example 3:</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#Example-4"><span class="nav-number">2.0.4.</span> <span class="nav-text">Example 4:</span></a></li></ol></li></ol></li></ol></div>
</div>
<!--/noindex-->


+ 4
- 2
2020/09/26/在老丈人家的小工记四/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,6 +32,7 @@
<meta property="og:url" content="https://nicksxs.me/2020/09/26/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E5%9B%9B/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="小工记四第四周去的时候让我们去了现在在住的房子里,去三楼整理东西了,蛮多的东西需要收拾整理,有些需要丢一下,以前往往是把不太要用的东西就放三楼了,但是后面就不会再去收拾整理,LD 跟丈母娘负责收拾,我不太知道哪些还要的,哪些不要了,而且本来也不擅长这种收拾🤦‍♂️,然后就变成她们收拾出来废纸箱,我负责拆掉,压平,这时候终于觉得体重还算是有点作用,总体来说这个事情我其实也不擅长,不擅长的主要是捆起">
<meta property="og:locale">
<meta property="article:published_time" content="2020-09-26T15:48:05.000Z">
<meta property="article:modified_time" content="2020-09-26T15:48:05.000Z">
<meta property="article:author" content="Nicksxs">
@ -40,6 +41,7 @@
<meta property="article:tag" content="减肥">
<meta property="article:tag" content="跑步">
<meta property="article:tag" content="干活">
<meta property="article:tag" content="小技巧">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/09/26/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E5%9B%9B/">
@ -446,7 +448,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#小工记四"><span class="nav-number">1.</span> <span class="nav-text">小工记四</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B0%8F%E5%B7%A5%E8%AE%B0%E5%9B%9B"><span class="nav-number">1.</span> <span class="nav-text">小工记四</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 222
- 24
2020/10/03/mybatis-的缓存是怎么回事/index.html
File diff suppressed because it is too large
View File


+ 53
- 23
2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,15 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2020/10/11/Leetcode-2-Add-Two-Numbers-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2020-10-11T15:22:45.000Z">
<meta property="article:modified_time" content="2020-10-11T15:23:51.000Z">
<meta property="article:modified_time" content="2020-10-11T15:22:45.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="题解">
<meta property="article:tag" content="linked list">
<meta property="article:tag" content="代码题解">
<meta property="article:tag" content="Add Two Numbers">
<meta property="article:tag" content="leetcode 002">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/10/11/Leetcode-2-Add-Two-Numbers-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -230,9 +229,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-10-11 23:22:45 / Modified: 23:23:51" itemprop="dateCreated datePublished" datetime="2020-10-11T23:22:45+08:00">2020-10-11</time>
<time title="Created: 2020-10-11 23:22:45" itemprop="dateCreated datePublished" datetime="2020-10-11T23:22:45+08:00">2020-10-11</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -248,11 +246,11 @@
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
<a href="/categories/linked-list/" itemprop="url" rel="index"><span itemprop="name">linked list</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/linked-list/" itemprop="url" rel="index"><span itemprop="name">linked list</span></a>
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
@ -302,13 +300,45 @@
<p>又 roll 到了一个以前做过的题,不过现在用 Java 也来写一下,是 easy 级别的,所以就简单说下</p>
<h2 id="简要介绍"><a href="#简要介绍" 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>
<h2 id="样例"><a href="#样例" class="headerlink" title="样例"></a>样例</h2><h4 id="example-1"><a href="#example-1" class="headerlink" title="example 1"></a>example 1</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Input: l1 &#x3D; [2,4,3], l2 &#x3D; [5,6,4]</span><br><span class="line">Output: [7,0,8]</span><br><span class="line">Explanation: 342 + 465 &#x3D; 807.</span><br></pre></td></tr></table></figure>
<h4 id="example-2"><a href="#example-2" class="headerlink" title="example 2"></a>example 2</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input: l1 &#x3D; [0], l2 &#x3D; [0]</span><br><span class="line">Output: [0]</span><br></pre></td></tr></table></figure>
<h4 id="example-3"><a href="#example-3" class="headerlink" title="example 3"></a>example 3</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Input: l1 &#x3D; [9,9,9,9,9,9,9], l2 &#x3D; [9,9,9,9]</span><br><span class="line">Output: [8,9,9,9,0,0,0,1]</span><br></pre></td></tr></table></figure>
<h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> ListNode <span class="title">addTwoNumbers</span><span class="params">(ListNode l1, ListNode l2)</span> </span>&#123;</span><br><span class="line"> ListNode root = <span class="keyword">new</span> ListNode();</span><br><span class="line"> <span class="keyword">if</span> (l1 == <span class="keyword">null</span> &amp;&amp; l2 == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> root;</span><br><span class="line"> &#125;</span><br><span class="line"> ListNode tail = root;</span><br><span class="line"> <span class="keyword">int</span> entered = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 这个条件加了 entered,就是还有进位的数</span></span><br><span class="line"> <span class="keyword">while</span> (l1 != <span class="keyword">null</span> || l2 != <span class="keyword">null</span> || entered != <span class="number">0</span>) &#123;</span><br><span class="line"> <span class="keyword">int</span> temp = entered;</span><br><span class="line"> <span class="keyword">if</span> (l1 != <span class="keyword">null</span>) &#123;</span><br><span class="line"> temp += l1.val;</span><br><span class="line"> l1 = l1.next;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (l2 != <span class="keyword">null</span>) &#123;</span><br><span class="line"> temp += l2.val;</span><br><span class="line"> l2 = l2.next;</span><br><span class="line"> &#125;</span><br><span class="line"> entered = (temp - temp % <span class="number">10</span>) / <span class="number">10</span>;</span><br><span class="line"> tail.val = temp % <span class="number">10</span>;</span><br><span class="line"> <span class="comment">// 循环内部的控制是为了排除最后的空节点</span></span><br><span class="line"> <span class="keyword">if</span> (l1 != <span class="keyword">null</span> || l2 != <span class="keyword">null</span> || entered != <span class="number">0</span>) &#123;</span><br><span class="line"> tail.next = <span class="keyword">new</span> ListNode();</span><br><span class="line"> tail = tail.next;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"><span class="comment">// tail = null;</span></span><br><span class="line"> <span class="keyword">return</span> root;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<h2 id="样例"><a href="#样例" class="headerlink" title="样例"></a>样例</h2><h4 id="example-1"><a href="#example-1" class="headerlink" title="example 1"></a>example 1</h4><pre class="line-numbers language-none"><code class="language-none">Input: l1 &#x3D; [2,4,3], l2 &#x3D; [5,6,4]
Output: [7,0,8]
Explanation: 342 + 465 &#x3D; 807.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<h4 id="example-2"><a href="#example-2" class="headerlink" title="example 2"></a>example 2</h4><pre class="line-numbers language-none"><code class="language-none">Input: l1 &#x3D; [0], l2 &#x3D; [0]
Output: [0]<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h4 id="example-3"><a href="#example-3" class="headerlink" title="example 3"></a>example 3</h4><pre class="line-numbers language-none"><code class="language-none">Input: l1 &#x3D; [9,9,9,9,9,9,9], l2 &#x3D; [9,9,9,9]
Output: [8,9,9,9,0,0,0,1]<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token class-name">ListNode</span> <span class="token function">addTwoNumbers</span><span class="token punctuation">(</span><span class="token class-name">ListNode</span> l1<span class="token punctuation">,</span> <span class="token class-name">ListNode</span> l2<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">ListNode</span> root <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ListNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>l1 <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">&amp;&amp;</span> l2 <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> root<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">ListNode</span> tail <span class="token operator">=</span> root<span class="token punctuation">;</span>
<span class="token keyword">int</span> entered <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// 这个条件加了 entered,就是还有进位的数</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span>l1 <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">||</span> l2 <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">||</span> entered <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">int</span> temp <span class="token operator">=</span> entered<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>l1 <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
temp <span class="token operator">+=</span> l1<span class="token punctuation">.</span>val<span class="token punctuation">;</span>
l1 <span class="token operator">=</span> l1<span class="token punctuation">.</span>next<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>l2 <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
temp <span class="token operator">+=</span> l2<span class="token punctuation">.</span>val<span class="token punctuation">;</span>
l2 <span class="token operator">=</span> l2<span class="token punctuation">.</span>next<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
entered <span class="token operator">=</span> <span class="token punctuation">(</span>temp <span class="token operator">-</span> temp <span class="token operator">%</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">10</span><span class="token punctuation">;</span>
tail<span class="token punctuation">.</span>val <span class="token operator">=</span> temp <span class="token operator">%</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token comment">// 循环内部的控制是为了排除最后的空节点</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>l1 <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">||</span> l2 <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">||</span> entered <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
tail<span class="token punctuation">.</span>next <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ListNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
tail <span class="token operator">=</span> tail<span class="token punctuation">.</span>next<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// tail = null;</span>
<span class="token keyword">return</span> root<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></span><span></span></span></code></pre>
<p>这里唯二需要注意的就是两个点,一个是循环条件需要包含进位值还存在的情况,还有一个是最后一个节点,如果是空的了,就不要在 new 一个出来了,写的比较挫</p>
</div>
@ -320,19 +350,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/05/01/Leetcode-48-旋转图像-Rotate-Image-题解分析/" rel="bookmark">Leetcode 48 旋转图像(Rotate Image) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
</ul>
@ -460,7 +490,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#简要介绍"><span class="nav-number">1.</span> <span class="nav-text">简要介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#样例"><span class="nav-number">2.</span> <span class="nav-text">样例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#example-1"><span class="nav-number">2.0.1.</span> <span class="nav-text">example 1</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#example-2"><span class="nav-number">2.0.2.</span> <span class="nav-text">example 2</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#example-3"><span class="nav-number">2.0.3.</span> <span class="nav-text">example 3</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#题解"><span class="nav-number">3.</span> <span class="nav-text">题解</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E8%A6%81%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">简要介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A0%B7%E4%BE%8B"><span class="nav-number">2.</span> <span class="nav-text">样例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#example-1"><span class="nav-number">2.0.1.</span> <span class="nav-text">example 1</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#example-2"><span class="nav-number">2.0.2.</span> <span class="nav-text">example 2</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#example-3"><span class="nav-number">2.0.3.</span> <span class="nav-text">example 3</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A2%98%E8%A7%A3"><span class="nav-number">3.</span> <span class="nav-text">题解</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 5
- 4
2020/10/18/在老丈人家的小工记五/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,14 +32,16 @@
<meta property="og:url" content="https://nicksxs.me/2020/10/18/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E4%BA%94/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="终于回忆起来了,年纪大了写这种东西真的要立马写,不然很容易想不起来,那天应该是 9 月 12 日,也就是上周六,因为我爸也去了,而且娘亲(丈母娘,LD 这么叫,我也就随了她这么叫,当然是背后,当面就叫妈)也在那,早上一到那二爹就给我爸指挥了活,要挖一条院子的出水道,自己想出来的词,因为觉得下水道是竖的,在那稍稍帮了一会会忙,然后我还是比较惯例的跟着 LD 还有娘亲去住的家里,主要是老丈人可能也不太">
<meta property="og:locale">
<meta property="article:published_time" content="2020-10-18T15:14:52.000Z">
<meta property="article:modified_time" content="2020-10-18T15:15:50.000Z">
<meta property="article:modified_time" content="2020-10-18T15:14:52.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="运动">
<meta property="article:tag" content="减肥">
<meta property="article:tag" content="跑步">
<meta property="article:tag" content="干活">
<meta property="article:tag" content="小技巧">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/10/18/%E5%9C%A8%E8%80%81%E4%B8%88%E4%BA%BA%E5%AE%B6%E7%9A%84%E5%B0%8F%E5%B7%A5%E8%AE%B0%E4%BA%94/">
@ -229,9 +231,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-10-18 23:14:52 / Modified: 23:15:50" itemprop="dateCreated datePublished" datetime="2020-10-18T23:14:52+08:00">2020-10-18</time>
<time title="Created: 2020-10-18 23:14:52" itemprop="dateCreated datePublished" datetime="2020-10-18T23:14:52+08:00">2020-10-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">


+ 39
- 16
2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,21 +26,22 @@
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>
<meta name="description" content="题目介绍给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例:给定二叉树 [3,9,20,null,null,15,7], 12345 3 &#x2F; \9 20 &#x2F; \ 15 7 返回它的最大深度 3 。 代码12345678910111213141516171819&#x2F;&#x2F; 主体是个递归的应">
<meta name="description" content="题目介绍给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例:给定二叉树 [3,9,20,null,null,15,7], 3 &#x2F; \ 9 20 &#x2F; \ 15 7 返回它的最大深度 3 。 代码&#x2F;&#x2F; 主体是个递归的应用 public int maxDepth(TreeNode">
<meta property="og:type" content="article">
<meta property="og:title" content="Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析">
<meta property="og:url" content="https://nicksxs.me/2020/10/25/Leetcode-104-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6-Maximum-Depth-of-Binary-Tree-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="题目介绍给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例:给定二叉树 [3,9,20,null,null,15,7], 12345 3 &#x2F; \9 20 &#x2F; \ 15 7 返回它的最大深度 3 。 代码12345678910111213141516171819&#x2F;&#x2F; 主体是个递归的应">
<meta property="og:description" content="题目介绍给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例:给定二叉树 [3,9,20,null,null,15,7], 3 &#x2F; \ 9 20 &#x2F; \ 15 7 返回它的最大深度 3 。 代码&#x2F;&#x2F; 主体是个递归的应用 public int maxDepth(TreeNode">
<meta property="og:locale">
<meta property="article:published_time" content="2020-10-25T15:43:29.000Z">
<meta property="article:modified_time" content="2020-10-25T15:43:29.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="Binary Tree">
<meta property="article:tag" content="代码题解">
<meta property="article:tag" content="Maximum Depth of Binary Tree">
<meta property="article:tag" content="leetcode 104">
<meta property="article:tag" content="DFS">
<meta property="article:tag" content="二叉树">
<meta property="article:tag" content="题解">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/10/25/Leetcode-104-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%9C%80%E5%A4%A7%E6%B7%B1%E5%BA%A6-Maximum-Depth-of-Binary-Tree-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -304,11 +305,33 @@
<h2 id="题目介绍"><a href="#题目介绍" class="headerlink" title="题目介绍"></a>题目介绍</h2><p>给定一个二叉树,找出其最大深度。</p>
<p>二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。</p>
<p>说明: 叶子节点是指没有子节点的节点。</p>
<p>说明: 叶子节点是指没有子节点的节点。</p>
<p>示例:<br>给定二叉树 [3,9,20,null,null,15,7],</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> 3</span><br><span class="line"> &#x2F; \</span><br><span class="line">9 20</span><br><span class="line"> &#x2F; \</span><br><span class="line"> 15 7</span><br></pre></td></tr></table></figure>
<p>返回它的最大深度 3 。</p>
<h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 主体是个递归的应用</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxDepth</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line"> <span class="comment">// 节点的退出条件之一</span></span><br><span class="line"> <span class="keyword">if</span> (root == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> right = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 存在左子树,就递归左子树</span></span><br><span class="line"> <span class="keyword">if</span> (root.left != <span class="keyword">null</span>) &#123;</span><br><span class="line"> left = maxDepth(root.left);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 存在右子树,就递归右子树</span></span><br><span class="line"> <span class="keyword">if</span> (root.right != <span class="keyword">null</span>) &#123;</span><br><span class="line"> right = maxDepth(root.right);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 前面返回后,左右取大者</span></span><br><span class="line"> <span class="keyword">return</span> Math.max(left + <span class="number">1</span>, right + <span class="number">1</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none"> 3
&#x2F; \
9 20
&#x2F; \
15 7<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>返回它的最大深度 3 。</p>
<h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">// 主体是个递归的应用</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">maxDepth</span><span class="token punctuation">(</span><span class="token class-name">TreeNode</span> root<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 节点的退出条件之一</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>root <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">int</span> left <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> right <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// 存在左子树,就递归左子树</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>root<span class="token punctuation">.</span>left <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
left <span class="token operator">=</span> <span class="token function">maxDepth</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>left<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 存在右子树,就递归右子树</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>root<span class="token punctuation">.</span>right <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
right <span class="token operator">=</span> <span class="token function">maxDepth</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>right<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 前面返回后,左右取大者</span>
<span class="token keyword">return</span> <span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>left <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> right <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<h2 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h2><p>其实对于树这类题,一般是以递归形式比较方便,只是要注意退出条件</p>
</div>
@ -320,19 +343,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/05/01/Leetcode-48-旋转图像-Rotate-Image-题解分析/" rel="bookmark">Leetcode 48 旋转图像(Rotate Image) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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>
</li>
</ul>
@ -462,7 +485,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#题目介绍"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#代码"><span class="nav-number">2.</span> <span class="nav-text">代码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#分析"><span class="nav-number">3.</span> <span class="nav-text">分析</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A2%98%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%A3%E7%A0%81"><span class="nav-number">2.</span> <span class="nav-text">代码</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%86%E6%9E%90"><span class="nav-number">3.</span> <span class="nav-text">分析</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 72
- 9
2020/11/01/Apollo-的-value-注解是怎么自动更新的/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/11/01/Apollo-%E7%9A%84-value-%E6%B3%A8%E8%A7%A3%E6%98%AF%E6%80%8E%E4%B9%88%E8%87%AA%E5%8A%A8%E6%9B%B4%E6%96%B0%E7%9A%84/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来">
<meta property="og:locale">
<meta property="article:published_time" content="2020-11-01T15:26:43.000Z">
<meta property="article:modified_time" content="2020-11-01T15:29:20.000Z">
<meta property="article:modified_time" content="2020-11-01T15:26:43.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Apollo">
@ -229,9 +230,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-11-01 23:26:43 / Modified: 23:29:20" itemprop="dateCreated datePublished" datetime="2020-11-01T23:26:43+08:00">2020-11-01</time>
<time title="Created: 2020-11-01 23:26:43" itemprop="dateCreated datePublished" datetime="2020-11-01T23:26:43+08:00">2020-11-01</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -291,11 +291,74 @@
<p>在前司和目前公司,用的配置中心都是使用的 Apollo,经过了业界验证,比较强大的配置管理系统,特别是在0.10 后开始支持对使用 value 注解的配置值进行自动更新,今天刚好有个同学问到我,就顺便写篇文章记录下,其实也是借助于 spring 强大的 bean 生命周期管理,可以实现BeanPostProcessor接口,使用postProcessBeforeInitialization方法,来对bean 内部的属性和方法进行判断,是否有 value 注解,如果有就是将它注册到一个 map 中,可以看到这个方法<code>com.ctrip.framework.apollo.spring.annotation.SpringValueProcessor#processField</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">processField</span><span class="params">(Object bean, String beanName, Field field)</span> </span>&#123;</span><br><span class="line"> <span class="comment">// register @Value on field</span></span><br><span class="line"> Value value = field.getAnnotation(Value<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> <span class="keyword">if</span> (value == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> Set&lt;String&gt; keys = placeholderHelper.extractPlaceholderKeys(value.value());</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (keys.isEmpty()) &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (String key : keys) &#123;</span><br><span class="line"> SpringValue springValue = <span class="keyword">new</span> SpringValue(key, value.value(), bean, beanName, field, <span class="keyword">false</span>);</span><br><span class="line"> springValueRegistry.register(beanFactory, key, springValue);</span><br><span class="line"> logger.debug(<span class="string">"Monitoring &#123;&#125;"</span>, springValue);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Override</span>
<span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">processField</span><span class="token punctuation">(</span><span class="token class-name">Object</span> bean<span class="token punctuation">,</span> <span class="token class-name">String</span> beanName<span class="token punctuation">,</span> <span class="token class-name">Field</span> field<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// register @Value on field</span>
<span class="token class-name">Value</span> value <span class="token operator">=</span> field<span class="token punctuation">.</span><span class="token function">getAnnotation</span><span class="token punctuation">(</span><span class="token class-name">Value</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">Set</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">></span></span> keys <span class="token operator">=</span> placeholderHelper<span class="token punctuation">.</span><span class="token function">extractPlaceholderKeys</span><span class="token punctuation">(</span>value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>keys<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">String</span> key <span class="token operator">:</span> keys<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">SpringValue</span> springValue <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SpringValue</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> value<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> bean<span class="token punctuation">,</span> beanName<span class="token punctuation">,</span> field<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
springValueRegistry<span class="token punctuation">.</span><span class="token function">register</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">,</span> key<span class="token punctuation">,</span> springValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
logger<span class="token punctuation">.</span><span class="token function">debug</span><span class="token punctuation">(</span><span class="token string">"Monitoring &#123;&#125;"</span><span class="token punctuation">,</span> springValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>然后我们看下这个<code>springValueRegistry</code>是啥玩意</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SpringValueRegistry</span> </span>&#123;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> CLEAN_INTERVAL_IN_SECONDS = <span class="number">5</span>;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> Map&lt;BeanFactory, Multimap&lt;String, SpringValue&gt;&gt; registry = Maps.newConcurrentMap();</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> AtomicBoolean initialized = <span class="keyword">new</span> AtomicBoolean(<span class="keyword">false</span>);</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">final</span> Object LOCK = <span class="keyword">new</span> Object();</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">register</span><span class="params">(BeanFactory beanFactory, String key, SpringValue springValue)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (!registry.containsKey(beanFactory)) &#123;</span><br><span class="line"> <span class="keyword">synchronized</span> (LOCK) &#123;</span><br><span class="line"> <span class="keyword">if</span> (!registry.containsKey(beanFactory)) &#123;</span><br><span class="line"> registry.put(beanFactory, LinkedListMultimap.&lt;String, SpringValue&gt;create());</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> registry.get(beanFactory).put(key, springValue);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// lazy initialize</span></span><br><span class="line"> <span class="keyword">if</span> (initialized.compareAndSet(<span class="keyword">false</span>, <span class="keyword">true</span>)) &#123;</span><br><span class="line"> initialize();</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SpringValueRegistry</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">final</span> <span class="token keyword">long</span> CLEAN_INTERVAL_IN_SECONDS <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">BeanFactory</span><span class="token punctuation">,</span> <span class="token class-name">Multimap</span><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">SpringValue</span><span class="token punctuation">></span><span class="token punctuation">></span></span> registry <span class="token operator">=</span> <span class="token class-name">Maps</span><span class="token punctuation">.</span><span class="token function">newConcurrentMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">AtomicBoolean</span> initialized <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AtomicBoolean</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Object</span> LOCK <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">register</span><span class="token punctuation">(</span><span class="token class-name">BeanFactory</span> beanFactory<span class="token punctuation">,</span> <span class="token class-name">String</span> key<span class="token punctuation">,</span> <span class="token class-name">SpringValue</span> springValue<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>registry<span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">synchronized</span> <span class="token punctuation">(</span>LOCK<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>registry<span class="token punctuation">.</span><span class="token function">containsKey</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
registry<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">,</span> <span class="token class-name">LinkedListMultimap</span><span class="token punctuation">.</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">SpringValue</span><span class="token punctuation">></span></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
registry<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span>key<span class="token punctuation">,</span> springValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// lazy initialize</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>initialized<span class="token punctuation">.</span><span class="token function">compareAndSet</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">initialize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>这类其实就是个 map 来存放 springvalue,然后有<code>com.ctrip.framework.apollo.spring.property.AutoUpdateConfigChangeListener</code>来监听更新操作,当有变更时</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onChange</span><span class="params">(ConfigChangeEvent changeEvent)</span> </span>&#123;</span><br><span class="line"> Set&lt;String&gt; keys = changeEvent.changedKeys();</span><br><span class="line"> <span class="keyword">if</span> (CollectionUtils.isEmpty(keys)) &#123;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">for</span> (String key : keys) &#123;</span><br><span class="line"> <span class="comment">// 1. check whether the changed key is relevant</span></span><br><span class="line"> Collection&lt;SpringValue&gt; targetValues = springValueRegistry.get(beanFactory, key);</span><br><span class="line"> <span class="keyword">if</span> (targetValues == <span class="keyword">null</span> || targetValues.isEmpty()) &#123;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 2. check whether the value is really changed or not (since spring property sources have hierarchies)</span></span><br><span class="line"> <span class="comment">// 这里其实有一点比较绕,是因为 Apollo 里的 namespace 划分,会出现 key 相同,但是 namespace 不同的情况,所以会有个优先级存在,所以需要去校验 environment 里面的是否已经更新,如果未更新则表示不需要更新</span></span><br><span class="line"> <span class="keyword">if</span> (!shouldTriggerAutoUpdate(changeEvent, key)) &#123;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> &#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 3. update the value</span></span><br><span class="line"> <span class="keyword">for</span> (SpringValue val : targetValues) &#123;</span><br><span class="line"> updateSpringValue(val);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onChange</span><span class="token punctuation">(</span><span class="token class-name">ConfigChangeEvent</span> changeEvent<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">Set</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">></span></span> keys <span class="token operator">=</span> changeEvent<span class="token punctuation">.</span><span class="token function">changedKeys</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token class-name">CollectionUtils</span><span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>keys<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">String</span> key <span class="token operator">:</span> keys<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 1. check whether the changed key is relevant</span>
<span class="token class-name">Collection</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">SpringValue</span><span class="token punctuation">></span></span> targetValues <span class="token operator">=</span> springValueRegistry<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>beanFactory<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>targetValues <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> targetValues<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 2. check whether the value is really changed or not (since spring property sources have hierarchies)</span>
<span class="token comment">// 这里其实有一点比较绕,是因为 Apollo 里的 namespace 划分,会出现 key 相同,但是 namespace 不同的情况,所以会有个优先级存在,所以需要去校验 environment 里面的是否已经更新,如果未更新则表示不需要更新</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">shouldTriggerAutoUpdate</span><span class="token punctuation">(</span>changeEvent<span class="token punctuation">,</span> key<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 3. update the value</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">SpringValue</span> val <span class="token operator">:</span> targetValues<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">updateSpringValue</span><span class="token punctuation">(</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>其实原理很简单,就是得了解知道下</p>
</div>
@ -307,7 +370,7 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/05/22/聊聊我刚学会的应用诊断方法/" rel="bookmark">聊聊我刚学会的应用诊断方法</a></div>
<div class="popular-posts-title"><a href="/2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/" rel="bookmark">聊聊 Dubbo 的 SPI 续之自适应拓展</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/04/05/Comparator使用小记/" rel="bookmark">Comparator使用小记</a></div>
@ -319,7 +382,7 @@
<div class="popular-posts-title"><a href="/2020/09/06/mybatis-的-和-是有啥区别/" rel="bookmark">mybatis 的 $ 和 # 是有啥区别</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/06/06/聊聊-Dubbo-的-SPI-续之自适应拓展/" rel="bookmark">聊聊 Dubbo 的 SPI 续之自适应拓展</a></div>
<div class="popular-posts-title"><a href="/2020/10/03/mybatis-的缓存是怎么回事/" rel="bookmark">mybatis 的缓存是怎么回事</a></div>
</li>
</ul>


+ 7
- 14
2020/11/08/聊聊-Java-的类加载机制/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,17 +32,11 @@
<meta property="og:url" content="https://nicksxs.me/2020/11/08/%E8%81%8A%E8%81%8A-Java-%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="一说到这个主题,想到的应该是双亲委派模型,不过讲的包括但不限于这个,主要内容是参考深入理解 Java 虚拟机书中的介绍,一个类型的生命周期包含了七个阶段,加载,验证,准备,解析,初始化,使用,卸载。 加载 通过一个类的全限定名来获取定义此类的二进制字节流 将这个字节流代表的静态存储结构转化为方法区的运行时数据结构 在内存中生成了一个代表这个类的 java.lang.Class 对象,作为方法">
<meta property="og:locale">
<meta property="article:published_time" content="2020-11-08T14:53:19.000Z">
<meta property="article:modified_time" content="2020-11-08T14:55:23.000Z">
<meta property="article:modified_time" content="2020-11-08T14:53:19.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="类加载">
<meta property="article:tag" content="加载">
<meta property="article:tag" content="验证">
<meta property="article:tag" content="准备">
<meta property="article:tag" content="解析">
<meta property="article:tag" content="初始化">
<meta property="article:tag" content="链接">
<meta property="article:tag" content="Nicksxs,史学森,米方方,米方方的男朋友,森哥">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/11/08/%E8%81%8A%E8%81%8A-Java-%E7%9A%84%E7%B1%BB%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6/">
@ -232,9 +226,8 @@
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">Posted on</span>
<time title="Created: 2020-11-08 22:53:19 / Modified: 22:55:23" itemprop="dateCreated datePublished" datetime="2020-11-08T22:53:19+08:00">2020-11-08</time>
<time title="Created: 2020-11-08 22:53:19" itemprop="dateCreated datePublished" datetime="2020-11-08T22:53:19+08:00">2020-11-08</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
@ -313,7 +306,7 @@
<li><h2 id="解析"><a href="#解析" class="headerlink" title="解析"></a>解析</h2><p>解析阶段是 Java 虚拟机将常量池内的符号引用替换为直接引用的过程</p>
</li>
</ul>
<p>以上<a href="##链接">验证</a><a href="##准备">准备</a><a href="##解析">解析</a> 三个阶段又合称为链接阶段,链接阶段要做的是将加载到JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中。</p>
<p>以上<a href="##%E9%93%BE%E6%8E%A5">验证</a><a href="##%E5%87%86%E5%A4%87">准备</a><a href="##%E8%A7%A3%E6%9E%90">解析</a> 三个阶段又合称为链接阶段,链接阶段要做的是将加载到JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中。</p>
<ul>
<li><h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2>类的初始化阶段是类加载过程的最后一个步骤,也是除了自定义类加载器之外将主动权交给了应用程序,其实就是执行类构造器<clinit>()方法的过程,<clinit>()并不是我们在 Java 代码中直接编写的方法,它是 Javac编译器的自动生成物,<clinit>()方法是由编译器自动收集类中的所有类变量的复制动作和静态句块(static{}块)中的语句合并产生的,编译器收集的顺序是由语句在原文件中出现的顺序决定的,静态语句块中只能访问定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以复制,但是不能访问,同时还要保证父类的执行先于子类,然后保证多线程下的并发问题</li>
</ul>
@ -444,7 +437,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#加载"><span class="nav-number">1.</span> <span class="nav-text">加载</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#验证"><span class="nav-number">2.</span> <span class="nav-text">验证</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#准备"><span class="nav-number">3.</span> <span class="nav-text">准备</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#解析"><span class="nav-number">4.</span> <span class="nav-text">解析</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#初始化"><span class="nav-number">5.</span> <span class="nav-text">初始化</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8A%A0%E8%BD%BD"><span class="nav-number">1.</span> <span class="nav-text">加载</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%AA%8C%E8%AF%81"><span class="nav-number">2.</span> <span class="nav-text">验证</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%87%86%E5%A4%87"><span class="nav-number">3.</span> <span class="nav-text">准备</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%A7%A3%E6%9E%90"><span class="nav-number">4.</span> <span class="nav-text">解析</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%88%9D%E5%A7%8B%E5%8C%96"><span class="nav-number">5.</span> <span class="nav-text">初始化</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 43
- 18
2020/11/15/Leetcode-234-回文联表-Palindrome-Linked-List-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,15 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2020/11/15/Leetcode-234-%E5%9B%9E%E6%96%87%E8%81%94%E8%A1%A8-Palindrome-Linked-List-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="题目介绍Given a singly linked list, determine if it is a palindrome.给定一个单向链表,判断是否是回文链表 例一 Example 1:Input: 1-&gt;2Output: false 例二 Example 2:Input: 1-&gt;2-&gt;2-&gt;1Output: true 挑战下自己Follow up:Could you">
<meta property="og:locale">
<meta property="article:published_time" content="2020-11-15T15:47:20.000Z">
<meta property="article:modified_time" content="2020-12-13T12:59:06.873Z">
<meta property="article:modified_time" content="2020-11-15T15:47:20.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="题解">
<meta property="article:tag" content="Linked List">
<meta property="article:tag" content="代码题解">
<meta property="article:tag" content="Palindrome Linked List">
<meta property="article:tag" content="leetcode 234">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/11/15/Leetcode-234-%E5%9B%9E%E6%96%87%E8%81%94%E8%A1%A8-Palindrome-Linked-List-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -233,13 +232,6 @@
<time title="Created: 2020-11-15 23:47:20" itemprop="dateCreated datePublished" datetime="2020-11-15T23:47:20+08:00">2020-11-15</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-12-13 20:59:06" itemprop="dateModified" datetime="2020-12-13T20:59:06+08:00">2020-12-13</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -310,7 +302,40 @@
<h3 id="例二-Example-2"><a href="#例二-Example-2" class="headerlink" title="例二 Example 2:"></a>例二 Example 2:</h3><p>Input: 1-&gt;2-&gt;2-&gt;1<br>Output: true</p>
<h3 id="挑战下自己"><a href="#挑战下自己" class="headerlink" title="挑战下自己"></a>挑战下自己</h3><p>Follow up:<br>Could you do it in O(n) time and O(1) space?</p>
<h2 id="简要分析"><a href="#简要分析" class="headerlink" title="简要分析"></a>简要分析</h2><p>首先这是个单向链表,如果是双向的就可以一个从头到尾,一个从尾到头,显然那样就没啥意思了,然后想过要不找到中点,然后用一个栈,把前一半塞进栈里,但是这种其实也比较麻烦,比如长度是奇偶数,然后如何找到中点,这倒是可以借助于双指针,还是比较麻烦,再想一想,回文链表,就跟最开始的一样,链表只有单向的,我用个栈不就可以逆向了么,先把链表整个塞进栈里,然后在一个个 pop 出来跟链表从头开始比较,全对上了就是回文了</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Definition for singly-linked list.</span></span><br><span class="line"><span class="comment"> * public class ListNode &#123;</span></span><br><span class="line"><span class="comment"> * int val;</span></span><br><span class="line"><span class="comment"> * ListNode next;</span></span><br><span class="line"><span class="comment"> * ListNode() &#123;&#125;</span></span><br><span class="line"><span class="comment"> * ListNode(int val) &#123; this.val = val; &#125;</span></span><br><span class="line"><span class="comment"> * ListNode(int val, ListNode next) &#123; this.val = val; this.next = next; &#125;</span></span><br><span class="line"><span class="comment"> * &#125;</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isPalindrome</span><span class="params">(ListNode head)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (head == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> ListNode tail = head;</span><br><span class="line"> LinkedList&lt;Integer&gt; stack = <span class="keyword">new</span> LinkedList&lt;&gt;();</span><br><span class="line"> <span class="comment">// 这里就是一个循环,将所有元素依次压入栈</span></span><br><span class="line"> <span class="keyword">while</span> (tail != <span class="keyword">null</span>) &#123;</span><br><span class="line"> stack.push(tail.val);</span><br><span class="line"> tail = tail.next;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 在逐个 pop 出来,其实这个出来的顺序就等于链表从尾到头遍历,同时跟链表从头到尾遍历进行逐对对比</span></span><br><span class="line"> <span class="keyword">while</span> (!stack.isEmpty()) &#123;</span><br><span class="line"> <span class="keyword">if</span> (stack.peekFirst() == head.val) &#123;</span><br><span class="line"> stack.pollFirst();</span><br><span class="line"> head = head.next;</span><br><span class="line"> &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token comment">/**
* Definition for singly-linked list.
* public class ListNode &#123;
* int val;
* ListNode next;
* ListNode() &#123;&#125;
* ListNode(int val) &#123; this.val = val; &#125;
* ListNode(int val, ListNode next) &#123; this.val = val; this.next = next; &#125;
* &#125;
*/</span>
<span class="token keyword">class</span> <span class="token class-name">Solution</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isPalindrome</span><span class="token punctuation">(</span><span class="token class-name">ListNode</span> head<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>head <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token class-name">ListNode</span> tail <span class="token operator">=</span> head<span class="token punctuation">;</span>
<span class="token class-name">LinkedList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">></span></span> stack <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">LinkedList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 这里就是一个循环,将所有元素依次压入栈</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span>tail <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
stack<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>tail<span class="token punctuation">.</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
tail <span class="token operator">=</span> tail<span class="token punctuation">.</span>next<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 在逐个 pop 出来,其实这个出来的顺序就等于链表从尾到头遍历,同时跟链表从头到尾遍历进行逐对对比</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>stack<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>stack<span class="token punctuation">.</span><span class="token function">peekFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> head<span class="token punctuation">.</span>val<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
stack<span class="token punctuation">.</span><span class="token function">pollFirst</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
head <span class="token operator">=</span> head<span class="token punctuation">.</span>next<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span> <span class="token keyword">else</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
</div>
@ -326,13 +351,13 @@
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
</ul>
@ -460,7 +485,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#题目介绍"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#例一-Example-1"><span class="nav-number">1.1.</span> <span class="nav-text">例一 Example 1:</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#例二-Example-2"><span class="nav-number">1.2.</span> <span class="nav-text">例二 Example 2:</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#挑战下自己"><span class="nav-number">1.3.</span> <span class="nav-text">挑战下自己</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#简要分析"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A2%98%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BE%8B%E4%B8%80-Example-1"><span class="nav-number">1.1.</span> <span class="nav-text">例一 Example 1:</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BE%8B%E4%BA%8C-Example-2"><span class="nav-number">1.2.</span> <span class="nav-text">例二 Example 2:</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8C%91%E6%88%98%E4%B8%8B%E8%87%AA%E5%B7%B1"><span class="nav-number">1.3.</span> <span class="nav-text">挑战下自己</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E8%A6%81%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 105
- 9
2020/11/22/聊聊-Dubbo-的容错机制/index.html
File diff suppressed because it is too large
View File


+ 7
- 6
2020/11/29/从清华美院学姐聊聊我们身边的恶人/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,10 +32,11 @@
<meta property="og:url" content="https://nicksxs.me/2020/11/29/%E4%BB%8E%E6%B8%85%E5%8D%8E%E7%BE%8E%E9%99%A2%E5%AD%A6%E5%A7%90%E8%81%8A%E8%81%8A%E6%88%91%E4%BB%AC%E8%BA%AB%E8%BE%B9%E7%9A%84%E6%81%B6%E4%BA%BA/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的本来其实也没什么想聊这个的,是在 B 站看了个吐槽这个的,然后刚好晚上乘公交的时候又碰到了有点类似的问题故事描述下,我们从始发站做了公交,这辆公交司机上次碰到过一回,就是会比较关注乘客的佩戴情况,主要考虑到目前国">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/ZovTIK.jpg">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/%E6%91%B8%E5%B1%81%E8%82%A1.png">
<meta property="article:published_time" content="2020-11-29T15:55:41.000Z">
<meta property="article:modified_time" content="2020-11-29T15:55:41.170Z">
<meta property="article:modified_time" content="2020-11-29T15:55:41.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="吐槽">
@ -297,7 +298,7 @@
<div class="post-body" itemprop="articleBody">
<p>前几天清华美院学姐的热点火了,然后仔细看了下,其实是个学姐诬陷以为其貌不扬的男同学摸她屁股<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/ZovTIK.jpg" alt=""><br>然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的<br><img data-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><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/ZovTIK.jpg"><br>然后还在朋友圈发文想让他社死,我也是挺晚才知道这个词什么意思,然后后面我看到了这个图片,挺有意思的<br><img data-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>
</div>
@ -311,16 +312,16 @@
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/26/在老丈人家的小工记四/" rel="bookmark">在老丈人家的小工记</a></div>
<div class="popular-posts-title"><a href="/2020/10/18/在老丈人家的小工记五/" rel="bookmark">在老丈人家的小工记</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/03/31/2020-年终总结/" rel="bookmark">2020 年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/13/在老丈人家的小工记三/" rel="bookmark">在老丈人家的小工记三</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
</ul>


+ 69
- 15
2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/index.html
File diff suppressed because it is too large
View File


+ 49
- 15
2020/12/13/Leetcode-105-从前序与中序遍历序列构造二叉树-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,26 +26,26 @@
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>
<meta name="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">
<meta name="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">
<meta property="og:type" content="article">
<meta property="og:title" content="Leetcode 105 从前序与中序遍历序列构造二叉树(Construct Binary Tree from Preorder and Inorder Traversal) 题解分析">
<meta property="og:url" content="https://nicksxs.me/2020/12/13/Leetcode-105-%E4%BB%8E%E5%89%8D%E5%BA%8F%E4%B8%8E%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2020-12-13T13:19:43.000Z">
<meta property="article:modified_time" content="2020-12-13T13:19:43.353Z">
<meta property="article:modified_time" content="2020-12-13T13:19:43.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="Binary Tree">
<meta property="article:tag" content="代码题解">
<meta property="article:tag" content="Construct Binary Tree from Preorder and Inorder Traversal">
<meta property="article:tag" content="leetcode 105">
<meta property="article:tag" content="二叉树">
<meta property="article:tag" content="题解">
<meta property="article:tag" content="递归">
<meta property="article:tag" content="Preorder Traversal">
<meta property="article:tag" content="Inorder Traversal">
<meta property="article:tag" content="前序">
<meta property="article:tag" content="中序">
<meta property="article:tag" content="递归">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2020/12/13/Leetcode-105-%E4%BB%8E%E5%89%8D%E5%BA%8F%E4%B8%8E%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91-Construct-Binary-Tree-from-Preorder-and-Inorder-Traversal-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -309,13 +309,47 @@
<h2 id="题目介绍"><a href="#题目介绍" class="headerlink" title="题目介绍"></a>题目介绍</h2><p>Given preorder and inorder traversal of a tree, construct the binary tree.<br>给定一棵树的前序和中序遍历,构造出一棵二叉树</p>
<h3 id="注意"><a href="#注意" class="headerlink" title="注意"></a>注意</h3><p>You may assume that duplicates do not exist in the tree.<br>你可以假设树中没有重复的元素。(PS: 不然就没法做了呀)</p>
<h3 id="例子"><a href="#例子" class="headerlink" title="例子:"></a>例子:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">preorder &#x3D; [3,9,20,15,7]</span><br><span class="line">inorder &#x3D; [9,3,15,20,7]</span><br></pre></td></tr></table></figure>
<h3 id="例子"><a href="#例子" class="headerlink" title="例子:"></a>例子:</h3><pre class="line-numbers language-none"><code class="language-none">preorder &#x3D; [3,9,20,15,7]
inorder &#x3D; [9,3,15,20,7]<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>
<p>返回的二叉树</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> 3</span><br><span class="line"> &#x2F; \</span><br><span class="line">9 20</span><br><span class="line"> &#x2F; \</span><br><span class="line"> 15 7</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-none"><code class="language-none"> 3
&#x2F; \
9 20
&#x2F; \
15 7<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h2 id="简要分析"><a href="#简要分析" class="headerlink" title="简要分析"></a>简要分析</h2><p>看到这个题可以想到一个比较常规的解法就是递归拆树,前序就是根左右,中序就是左根右,然后就是通过前序已经确定的根在中序中找到,然后去划分左右子树,这个例子里是 3,找到中序中的位置,那么就可以确定,9 是左子树,15,20,7是右子树,然后对应的可以根据左右子树的元素数量在前序中划分左右子树,再继续递归就行</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> TreeNode <span class="title">buildTree</span><span class="params">(<span class="keyword">int</span>[] preorder, <span class="keyword">int</span>[] inorder)</span> </span>&#123;</span><br><span class="line"> <span class="comment">// 获取下数组长度</span></span><br><span class="line"> <span class="keyword">int</span> n = preorder.length;</span><br><span class="line"> <span class="comment">// 排除一下异常和边界</span></span><br><span class="line"> <span class="keyword">if</span> (n != inorder.length) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">0</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> TreeNode(preorder[<span class="number">0</span>]);</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 获得根节点</span></span><br><span class="line"> TreeNode node = <span class="keyword">new</span> TreeNode(preorder[<span class="number">0</span>]);</span><br><span class="line"> <span class="keyword">int</span> pos = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 找到中序中的位置</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; inorder.length; i++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (node.val == inorder[i]) &#123;</span><br><span class="line"> pos = i;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 划分左右再进行递归,注意下`Arrays.copyOfRange`的用法</span></span><br><span class="line"> node.left = buildTree(Arrays.copyOfRange(preorder, <span class="number">1</span>, pos + <span class="number">1</span>), Arrays.copyOfRange(inorder, <span class="number">0</span>, pos));</span><br><span class="line"> node.right = buildTree(Arrays.copyOfRange(preorder, pos + <span class="number">1</span>, n), Arrays.copyOfRange(inorder, pos + <span class="number">1</span>, n));</span><br><span class="line"> <span class="keyword">return</span> node;</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">class</span> <span class="token class-name">Solution</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">public</span> <span class="token class-name">TreeNode</span> <span class="token function">buildTree</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> preorder<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> inorder<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 获取下数组长度</span>
<span class="token keyword">int</span> n <span class="token operator">=</span> preorder<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token comment">// 排除一下异常和边界</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">!=</span> inorder<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">TreeNode</span><span class="token punctuation">(</span>preorder<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 获得根节点</span>
<span class="token class-name">TreeNode</span> node <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TreeNode</span><span class="token punctuation">(</span>preorder<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> pos <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token comment">// 找到中序中的位置</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> inorder<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>node<span class="token punctuation">.</span>val <span class="token operator">==</span> inorder<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
pos <span class="token operator">=</span> i<span class="token punctuation">;</span>
<span class="token keyword">break</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 划分左右再进行递归,注意下`Arrays.copyOfRange`的用法</span>
node<span class="token punctuation">.</span>left <span class="token operator">=</span> <span class="token function">buildTree</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">copyOfRange</span><span class="token punctuation">(</span>preorder<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">copyOfRange</span><span class="token punctuation">(</span>inorder<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> pos<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
node<span class="token punctuation">.</span>right <span class="token operator">=</span> <span class="token function">buildTree</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">copyOfRange</span><span class="token punctuation">(</span>preorder<span class="token punctuation">,</span> pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">copyOfRange</span><span class="token punctuation">(</span>inorder<span class="token punctuation">,</span> pos <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> node<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-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></span><span></span><span></span></span></code></pre>
</div>
@ -334,10 +368,10 @@
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/05/01/Leetcode-48-旋转图像-Rotate-Image-题解分析/" rel="bookmark">Leetcode 48 旋转图像(Rotate Image) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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>
</li>
</ul>
@ -471,7 +505,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#题目介绍"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#注意"><span class="nav-number">1.1.</span> <span class="nav-text">注意</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#例子"><span class="nav-number">1.2.</span> <span class="nav-text">例子:</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#简要分析"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%A2%98%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B3%A8%E6%84%8F"><span class="nav-number">1.1.</span> <span class="nav-text">注意</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BE%8B%E5%AD%90"><span class="nav-number">1.2.</span> <span class="nav-text">例子:</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E8%A6%81%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 5
- 4
2020/12/20/从丁仲礼被美国制裁聊点啥/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2020/12/20/%E4%BB%8E%E4%B8%81%E4%BB%B2%E7%A4%BC%E8%A2%AB%E7%BE%8E%E5%9B%BD%E5%88%B6%E8%A3%81%E8%81%8A%E7%82%B9%E5%95%A5/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="几年前看了柴静的《穹顶之下》觉得这个记者调查得很深入,挺有水平,然后再看到了她跟丁仲礼的采访,其实没看完整,也没试着去理解,就觉得环境问题挺严重的,为啥柴静这个对面的这位好像对这个很不屑的样子,最近因为丁仲礼上了美国制裁名单,B 站又有人把这个视频发了出来,就完整看了下,就觉得自己挺惭愧的,就抱着对柴静的好感而没来由的否定了丁老的看法和说法,所以人也需要不断地学习,改正之前错误的观点,当然不是说我">
<meta property="og:locale">
<meta property="article:published_time" content="2020-12-20T15:18:50.000Z">
<meta property="article:modified_time" content="2020-12-20T15:18:50.349Z">
<meta property="article:modified_time" content="2020-12-20T15:18:50.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="吐槽">
@ -314,10 +315,10 @@
<div class="popular-posts-title"><a href="/2021/03/31/2020-年终总结/" rel="bookmark">2020 年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/02/01/2019年终总结/" rel="bookmark">2019年终总结</a></div>
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
</li>
</ul>


+ 50
- 23
2020/12/27/聊聊-mysql-索引的一些细节/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,21 +26,22 @@
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>
<meta name="description" content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 12345678910CREATE TABLE &#96;null_index_t&#96; ( &#96;id&#96; int(10) unsigned NOT NULL AUTO_INCREMENT, &#96;">
<meta name="description" content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 CREATE TABLE &#96;null_index_t&#96; ( &#96;id&#96; int(10) unsigned NOT NULL AUTO_INCREMENT, &#96;null_key&#96;">
<meta property="og:type" content="article">
<meta property="og:title" content="聊聊 mysql 索引的一些细节">
<meta property="og:url" content="https://nicksxs.me/2020/12/27/%E8%81%8A%E8%81%8A-mysql-%E7%B4%A2%E5%BC%95%E7%9A%84%E4%B8%80%E4%BA%9B%E7%BB%86%E8%8A%82/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 12345678910CREATE TABLE &#96;null_index_t&#96; ( &#96;id&#96; int(10) unsigned NOT NULL AUTO_INCREMENT, &#96;">
<meta property="og:description" content="前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验 CREATE TABLE &#96;null_index_t&#96; ( &#96;id&#96; int(10) unsigned NOT NULL AUTO_INCREMENT, &#96;null_key&#96;">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/IejArR.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/vwttcE.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/McIoej.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/i4ki84.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/1HKVQH.png">
<meta property="article:published_time" content="2020-12-27T15:49:05.000Z">
<meta property="article:modified_time" content="2020-12-27T16:16:08.313Z">
<meta property="article:modified_time" content="2020-12-27T15:49:05.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Mysql">
<meta property="article:tag" content="mysql">
<meta property="article:tag" content="索引">
<meta property="article:tag" content="is null">
<meta property="article:tag" content="is not null">
@ -238,13 +239,6 @@
<time title="Created: 2020-12-27 23:49:05" itemprop="dateCreated datePublished" datetime="2020-12-27T23:49:05+08:00">2020-12-27</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2020-12-28 00:16:08" itemprop="dateModified" datetime="2020-12-28T00:16:08+08:00">2020-12-28</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -307,19 +301,52 @@
<p>前几天同事问了我个 mysql 索引的问题,虽然大概知道,但是还是想来实践下,就是 is null,is not null 这类查询是否能用索引,可能之前有些网上的文章说都是不能用索引,但是其实不是,我们来看个小试验</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">TABLE</span> <span class="string">`null_index_t`</span> (</span><br><span class="line"> <span class="string">`id`</span> <span class="built_in">int</span>(<span class="number">10</span>) <span class="keyword">unsigned</span> <span class="keyword">NOT</span> <span class="literal">NULL</span> AUTO_INCREMENT,</span><br><span class="line"> <span class="string">`null_key`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="string">`null_key1`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line"> <span class="string">`null_key2`</span> <span class="built_in">varchar</span>(<span class="number">255</span>) <span class="keyword">DEFAULT</span> <span class="literal">NULL</span>,</span><br><span class="line"> PRIMARY <span class="keyword">KEY</span> (<span class="string">`id`</span>),</span><br><span class="line"> <span class="keyword">KEY</span> <span class="string">`idx_1`</span> (<span class="string">`null_key`</span>) <span class="keyword">USING</span> BTREE,</span><br><span class="line"> <span class="keyword">KEY</span> <span class="string">`idx_2`</span> (<span class="string">`null_key1`</span>) <span class="keyword">USING</span> BTREE,</span><br><span class="line"> <span class="keyword">KEY</span> <span class="string">`idx_3`</span> (<span class="string">`null_key2`</span>) <span class="keyword">USING</span> BTREE</span><br><span class="line">) <span class="keyword">ENGINE</span>=<span class="keyword">InnoDB</span> <span class="keyword">DEFAULT</span> <span class="keyword">CHARSET</span>=utf8mb4;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> <span class="token punctuation">`</span>null_index_t<span class="token punctuation">`</span> <span class="token punctuation">(</span>
<span class="token punctuation">`</span>id<span class="token punctuation">`</span> <span class="token keyword">int</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token keyword">unsigned</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">AUTO_INCREMENT</span><span class="token punctuation">,</span>
<span class="token punctuation">`</span>null_key<span class="token punctuation">`</span> <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
<span class="token punctuation">`</span>null_key1<span class="token punctuation">`</span> <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
<span class="token punctuation">`</span>null_key2<span class="token punctuation">`</span> <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">255</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
<span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
<span class="token keyword">KEY</span> <span class="token punctuation">`</span>idx_1<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>null_key<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">USING</span> <span class="token keyword">BTREE</span><span class="token punctuation">,</span>
<span class="token keyword">KEY</span> <span class="token punctuation">`</span>idx_2<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>null_key1<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">USING</span> <span class="token keyword">BTREE</span><span class="token punctuation">,</span>
<span class="token keyword">KEY</span> <span class="token punctuation">`</span>idx_3<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>null_key2<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">USING</span> <span class="token keyword">BTREE</span>
<span class="token punctuation">)</span> <span class="token keyword">ENGINE</span><span class="token operator">=</span><span class="token keyword">InnoDB</span> <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span><span class="token operator">=</span>utf8mb4<span class="token punctuation">;</span><span aria-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></code></pre>
<p>用个存储过程来插入数据</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">delimiter $ <span class="comment">#以delimiter来标记用$表示存储过程结束</span></span><br><span class="line"><span class="keyword">create</span> <span class="keyword">procedure</span> nullIndex1()</span><br><span class="line"><span class="keyword">begin</span></span><br><span class="line"><span class="keyword">declare</span> i <span class="built_in">int</span>; </span><br><span class="line"><span class="keyword">declare</span> j <span class="built_in">int</span>; </span><br><span class="line"><span class="keyword">set</span> i=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">set</span> j=<span class="number">1</span>;</span><br><span class="line">while(i&lt;=100) do </span><br><span class="line"> while(j&lt;=100) do </span><br><span class="line"> IF (i % 3 = 0) THEN</span><br><span class="line"> <span class="keyword">INSERT</span> <span class="keyword">INTO</span> null_index_t ( <span class="string">`null_key`</span>, <span class="string">`null_key1`</span>, <span class="string">`null_key2`</span> ) <span class="keyword">VALUES</span> (<span class="literal">null</span> , <span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>), <span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>));</span><br><span class="line"> ELSEIF (i % 3 = 1) THEN</span><br><span class="line"> <span class="keyword">INSERT</span> <span class="keyword">INTO</span> null_index_t ( <span class="string">`null_key`</span>, <span class="string">`null_key1`</span>, <span class="string">`null_key2`</span> ) <span class="keyword">VALUES</span> (<span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>), <span class="literal">NULL</span>, <span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>));</span><br><span class="line"> ELSE</span><br><span class="line"> <span class="keyword">INSERT</span> <span class="keyword">INTO</span> null_index_t ( <span class="string">`null_key`</span>, <span class="string">`null_key1`</span>, <span class="string">`null_key2`</span> ) <span class="keyword">VALUES</span> (<span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>), <span class="keyword">LEFT</span>(<span class="keyword">MD5</span>(<span class="keyword">RAND</span>()), <span class="number">8</span>), <span class="literal">NULL</span>);</span><br><span class="line"> <span class="keyword">END</span> <span class="keyword">IF</span>;</span><br><span class="line"> <span class="keyword">set</span> j=j+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">end</span> <span class="keyword">while</span>;</span><br><span class="line"> <span class="keyword">set</span> i=i+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">set</span> j=<span class="number">1</span>; </span><br><span class="line"><span class="keyword">end</span> <span class="keyword">while</span>;</span><br><span class="line"><span class="keyword">end</span> </span><br><span class="line">$</span><br><span class="line"><span class="keyword">call</span> nullIndex1();</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql">
<span class="token keyword">delimiter</span> $ <span class="token comment">#以delimiter来标记用$表示存储过程结束</span>
<span class="token keyword">create</span> <span class="token keyword">procedure</span> nullIndex1<span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">begin</span>
<span class="token keyword">declare</span> i <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">declare</span> j <span class="token keyword">int</span><span class="token punctuation">;</span>
<span class="token keyword">set</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">set</span> j<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">while</span><span class="token punctuation">(</span>i<span class="token operator">&lt;=</span><span class="token number">100</span><span class="token punctuation">)</span> <span class="token keyword">do</span>
<span class="token keyword">while</span><span class="token punctuation">(</span>j<span class="token operator">&lt;=</span><span class="token number">100</span><span class="token punctuation">)</span> <span class="token keyword">do</span>
<span class="token keyword">IF</span> <span class="token punctuation">(</span>i <span class="token operator">%</span> <span class="token number">3</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token keyword">THEN</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> null_index_t <span class="token punctuation">(</span> <span class="token punctuation">`</span>null_key<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key1<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key2<span class="token punctuation">`</span> <span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token boolean">null</span> <span class="token punctuation">,</span> <span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">ELSEIF</span> <span class="token punctuation">(</span>i <span class="token operator">%</span> <span class="token number">3</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token keyword">THEN</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> null_index_t <span class="token punctuation">(</span> <span class="token punctuation">`</span>null_key<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key1<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key2<span class="token punctuation">`</span> <span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">ELSE</span>
<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> null_index_t <span class="token punctuation">(</span> <span class="token punctuation">`</span>null_key<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key1<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>null_key2<span class="token punctuation">`</span> <span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">LEFT</span><span class="token punctuation">(</span>MD5<span class="token punctuation">(</span>RAND<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token boolean">NULL</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">END</span> <span class="token keyword">IF</span><span class="token punctuation">;</span>
<span class="token keyword">set</span> j<span class="token operator">=</span>j<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">end</span> <span class="token keyword">while</span><span class="token punctuation">;</span>
<span class="token keyword">set</span> i<span class="token operator">=</span>i<span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">set</span> j<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span>
<span class="token keyword">end</span> <span class="token keyword">while</span><span class="token punctuation">;</span>
<span class="token keyword">end</span>
$
<span class="token keyword">call</span> nullIndex1<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-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></code></pre>
<p>然后看下我们的 is null 查询</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">EXPLAIN</span> <span class="keyword">select</span> * <span class="keyword">from</span> null_index_t <span class="keyword">WHERE</span> null_key <span class="keyword">is</span> <span class="literal">null</span>;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/IejArR.png" alt=""><br>再来看看另一个</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">EXPLAIN</span> <span class="keyword">select</span> * <span class="keyword">from</span> null_index_t <span class="keyword">WHERE</span> null_key <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">null</span>;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/vwttcE.png" alt=""><br>从这里能看出来啥呢,可以思考下</p>
<p>从上面可以发现,<code>is null</code>应该是用上了索引了,所以至少不是一刀切不能用,但是看着<code>is not null</code>好像不太行额<br>我们在做一点小改动,把这个表里的数据改成 9100 条是 null,剩下 900 条是有值的,然后再执行下<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/McIoej.png" alt=""><br>然后再来看看执行结果</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">EXPLAIN</span> <span class="keyword">select</span> * <span class="keyword">from</span> null_index_t <span class="keyword">WHERE</span> null_key <span class="keyword">is</span> <span class="literal">null</span>;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/i4ki84.png" alt=""></p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">EXPLAIN</span> <span class="keyword">select</span> * <span class="keyword">from</span> null_index_t <span class="keyword">WHERE</span> null_key <span class="keyword">is</span> <span class="keyword">not</span> <span class="literal">null</span>;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/1HKVQH.png" alt=""><br>是不是不一样了,这里再补充下我试验使用的 mysql 是 5.7 的,不保证在其他版本的一致性,<br>其实可以看出随着数据量的变化,mysql 会不会使用索引是会变化的,不是说 is not null 一定会使用,也不是一定不会使用,而是优化器会根据查询成本做个预判,这个预判尽可能会减小查询成本,主要包括回表啥的,但是也不一定完全准确。</p>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> null_index_t <span class="token keyword">WHERE</span> null_key <span class="token operator">is</span> <span class="token boolean">null</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/IejArR.png"><br>再来看看另一个</p>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> null_index_t <span class="token keyword">WHERE</span> null_key <span class="token operator">is</span> <span class="token operator">not</span> <span class="token boolean">null</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/vwttcE.png"><br>从这里能看出来啥呢,可以思考下</p>
<p>从上面可以发现,<code>is null</code>应该是用上了索引了,所以至少不是一刀切不能用,但是看着<code>is not null</code>好像不太行额<br>我们在做一点小改动,把这个表里的数据改成 9100 条是 null,剩下 900 条是有值的,然后再执行下<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/McIoej.png"><br>然后再来看看执行结果</p>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> null_index_t <span class="token keyword">WHERE</span> null_key <span class="token operator">is</span> <span class="token boolean">null</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/i4ki84.png"></p>
<pre class="line-numbers language-sql" data-language="sql"><code class="language-sql"><span class="token keyword">EXPLAIN</span> <span class="token keyword">select</span> <span class="token operator">*</span> <span class="token keyword">from</span> null_index_t <span class="token keyword">WHERE</span> null_key <span class="token operator">is</span> <span class="token operator">not</span> <span class="token boolean">null</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/1HKVQH.png"><br>是不是不一样了,这里再补充下我试验使用的 mysql 是 5.7 的,不保证在其他版本的一致性,<br>其实可以看出随着数据量的变化,mysql 会不会使用索引是会变化的,不是说 is not null 一定会使用,也不是一定不会使用,而是优化器会根据查询成本做个预判,这个预判尽可能会减小查询成本,主要包括回表啥的,但是也不一定完全准确。</p>
</div>


+ 30
- 11
2021/01/03/聊聊-Java-的-equals-和-hashCode-方法/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,20 +26,17 @@
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>
<meta name="description" content="Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下简单看下代码java.lang.Object#equals 123public boolean equals(Object obj) &amp;#123; return (this &#x3D;&#x3D; obj); &amp;#125; 对于所有对象的父类,equals 方法其实对比的就是对象的地址,也就">
<meta name="description" content="Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下简单看下代码java.lang.Object#equals public boolean equals(Object obj) &amp;#123; return (this &#x3D;&#x3D; obj); &amp;#125; 对于所有对象的父类,equals 方法其实对比的就是对象的地址,也就">
<meta property="og:type" content="article">
<meta property="og:title" content="聊聊 Java 的 equals 和 hashCode 方法">
<meta property="og:url" content="https://nicksxs.me/2021/01/03/%E8%81%8A%E8%81%8A-Java-%E7%9A%84-equals-%E5%92%8C-hashCode-%E6%96%B9%E6%B3%95/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下简单看下代码java.lang.Object#equals 123public boolean equals(Object obj) &amp;#123; return (this &#x3D;&#x3D; obj); &amp;#125; 对于所有对象的父类,equals 方法其实对比的就是对象的地址,也就">
<meta property="og:description" content="Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下简单看下代码java.lang.Object#equals public boolean equals(Object obj) &amp;#123; return (this &#x3D;&#x3D; obj); &amp;#125; 对于所有对象的父类,equals 方法其实对比的就是对象的地址,也就是">
<meta property="og:locale">
<meta property="article:published_time" content="2021-01-03T14:26:35.000Z">
<meta property="article:modified_time" content="2021-01-03T14:26:35.828Z">
<meta property="article:modified_time" content="2021-01-03T14:26:35.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Nicksxs">
<meta property="article:tag" content="史学森">
<meta property="article:tag" content="米方方">
<meta property="article:tag" content="米方方的男朋友">
<meta property="article:tag" content="森哥">
<meta property="article:tag" content="Nicksxs,史学森,米方方,米方方的男朋友,森哥">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2021/01/03/%E8%81%8A%E8%81%8A-Java-%E7%9A%84-equals-%E5%92%8C-hashCode-%E6%96%B9%E6%B3%95/">
@ -273,9 +270,31 @@
<p>Java 中的这个话题也是比较常遇到的,关于这块原先也是比较忽略的,但是仔细想想又有点遗忘了就在这里记一下<br>简单看下代码<br><code>java.lang.Object#equals</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object obj)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">return</span> (<span class="keyword">this</span> == obj);</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">equals</span><span class="token punctuation">(</span><span class="token class-name">Object</span> obj<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">==</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre>
<p>对于所有对象的父类,<code>equals</code> 方法其实对比的就是对象的地址,也就是是否是同一个对象,试想如果像 Integer 或者 String 这种,我们没有重写 <code>equals</code>,那其实就等于是在用<code>==</code>,可能就没法达到我们的目的,所以像 String 这种常用的 jdk 类都是默认重写了<br><code>java.lang.String#equals</code></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object anObject)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span> == anObject) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (anObject <span class="keyword">instanceof</span> String) &#123;</span><br><span class="line"> String anotherString = (String)anObject;</span><br><span class="line"> <span class="keyword">int</span> n = value.length;</span><br><span class="line"> <span class="keyword">if</span> (n == anotherString.value.length) &#123;</span><br><span class="line"> <span class="keyword">char</span> v1[] = value;</span><br><span class="line"> <span class="keyword">char</span> v2[] = anotherString.value;</span><br><span class="line"> <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span> (n-- != <span class="number">0</span>) &#123;</span><br><span class="line"> <span class="keyword">if</span> (v1[i] != v2[i])</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> i++;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">equals</span><span class="token punctuation">(</span><span class="token class-name">Object</span> anObject<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">==</span> anObject<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>anObject <span class="token keyword">instanceof</span> <span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">String</span> anotherString <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">)</span>anObject<span class="token punctuation">;</span>
<span class="token keyword">int</span> n <span class="token operator">=</span> value<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>n <span class="token operator">==</span> anotherString<span class="token punctuation">.</span>value<span class="token punctuation">.</span>length<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">char</span> v1<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> value<span class="token punctuation">;</span>
<span class="token keyword">char</span> v2<span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> anotherString<span class="token punctuation">.</span>value<span class="token punctuation">;</span>
<span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">while</span> <span class="token punctuation">(</span>n<span class="token operator">--</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>v1<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">!=</span> v2<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
i<span class="token operator">++</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>然后呢就是为啥一些书或者 <code>effective java</code> 中写了 <code>equals</code><code>hashCode</code> 要一起重写,这里涉及到当对象作为 <code>HashMap</code><code>key</code> 的时候<br>首先 <code>HashMap</code> 会使用 <code>hashCode</code> 去判断是否在同一个槽里,然后在通过 <code>equals</code> 去判断是否是同一个 <code>key</code>,是的话就替换,不是的话就链表接下去,如果不重写 <code>hashCode</code> 的话,默认的 <code>object</code><code>hashCode</code><code>native</code> 方法,根据对象的地址生成的,这样其实对象的值相同的话,因为地址不同,<code>HashMap</code> 也会出现异常,所以需要重写,同时也需要重写 <code>equals</code> 方法,才能确认是同一个 <code>key</code>,而不是落在同一个槽的不同 <code>key</code>.</p>
</div>


+ 57
- 21
2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/index.html
File diff suppressed because it is too large
View File


+ 8
- 8
2021/01/17/聊聊那些加塞狗/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,13 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2021/01/17/%E8%81%8A%E8%81%8A%E9%82%A3%E4%BA%9B%E5%8A%A0%E5%A1%9E%E7%8B%97/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="今天真的是被气得不轻,情况是碰到一个有 70 多秒的直行红灯,然后直行就排了很长的队,但是左转车道没车,就有好几辆车占着左转车道,准备往直行车道插队加塞,一般这种加塞的,会挑个不太计较的,如果前面一辆不让的话就再等等,我因为赶着回家,就不想让,结果那辆车几次车头直接往里冲,当时怒气值基本已经蓄满了,我真的是分毫都不想让,如果路上都是让着这种人的,那么这种情况只会越来越严重,我理解的这种心态,就赌你">
<meta property="og:locale">
<meta property="article:published_time" content="2021-01-17T15:29:09.000Z">
<meta property="article:modified_time" content="2021-01-17T15:29:09.250Z">
<meta property="article:modified_time" content="2021-01-17T15:29:09.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="开车">
<meta property="article:tag" content="加塞">
<meta property="article:tag" content="2021">
<meta property="article:tag" content="糟心事">
<meta property="article:tag" content="规则">
<meta name="twitter:card" content="summary">
@ -297,19 +297,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
<div class="popular-posts-title"><a href="/2021/02/28/闲聊下乘公交的用户体验/" rel="bookmark">闲聊下乘公交的用户体验</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/02/28/闲聊下乘公交的用户体验/" rel="bookmark">闲聊下乘公交的用户体验</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/18/在老丈人家的小工记五/" rel="bookmark">在老丈人家的小工记五</a></div>
<div class="popular-posts-title"><a href="/2021/03/31/2020-年终总结/" rel="bookmark">2020 年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
</ul>


+ 35
- 12
2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,17 +32,17 @@
<meta property="og:url" content="https://nicksxs.me/2021/01/24/Leetcode-124-%E4%BA%8C%E5%8F%89%E6%A0%91%E4%B8%AD%E7%9A%84%E6%9C%80%E5%A4%A7%E8%B7%AF%E5%BE%84%E5%92%8C-Binary-Tree-Maximum-Path-Sum-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/SfxIEy.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/iipgv0.png">
<meta property="article:published_time" content="2021-01-24T14:45:03.000Z">
<meta property="article:modified_time" content="2021-01-24T14:45:03.748Z">
<meta property="article:modified_time" content="2021-01-24T14:45:03.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="Binary Tree">
<meta property="article:tag" content="代码题解">
<meta property="article:tag" content="Binary Tree Maximum Path Sum">
<meta property="article:tag" content="leetcode 124">
<meta property="article:tag" content="二叉树">
<meta property="article:tag" content="题解">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/SfxIEy.png">
@ -307,11 +307,34 @@
<p><strong>路径</strong> 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。该路径 <strong>至少包含一个</strong> 节点,且不一定经过根节点。</p>
<p><strong>路径和</strong> 是路径中各节点值的总和。</p>
<p>给你一个二叉树的根节点 <code>root</code> ,返回其 <strong>最大路径和</strong></p>
<h3 id="简要分析"><a href="#简要分析" class="headerlink" title="简要分析"></a>简要分析</h3><p>其实这个题目会被误解成比较简单,左子树最大的,或者右子树最大的,或者两边加一下,仔细想想都不对,其实有可能是产生于左子树中,或者右子树中,这两个都是指跟左子树根还有右子树根没关系的,这么说感觉不太容易理解,画个图<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/SfxIEy.png" alt=""><br>可以看到图里,其实最长路径和是左边这个子树组成的,跟根节点还有右子树完全没关系,然后再想一种情况,如果是整棵树就是图中的左子树,那么这个最长路径和就是左子树加右子树加根节点了,所以不是我一开始想得那么简单,在代码实现中也需要一些技巧</p>
<h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> ansNew = Integer.MIN_VALUE;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxPathSum</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line"> maxSumNew(root);</span><br><span class="line"> <span class="keyword">return</span> ansNew;</span><br><span class="line"> &#125;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxSumNew</span><span class="params">(TreeNode root)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (root == <span class="keyword">null</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="comment">// 这里是个简单的递归,就是去递归左右子树,但是这里其实有个概念,当这样处理时,其实相当于把子树的内部的最大路径和已经算出来了</span></span><br><span class="line"> <span class="keyword">int</span> left = maxSumNew(root.left);</span><br><span class="line"> <span class="keyword">int</span> right = maxSumNew(root.right);</span><br><span class="line"> <span class="comment">// 这里前面我有点没想明白,但是看到 ansNew 的比较,其实相当于,返回的是三种情况里的最大值,一个是左子树+根,一个是右子树+根,一个是单独根节点,</span></span><br><span class="line"> <span class="comment">// 这样这个递归的返回才会有意义,不然像原来的方法,它可能是跳着的,但是这种情况其实是借助于 ansNew 这个全局的最大值,因为原来我觉得要比较的是</span></span><br><span class="line"> <span class="comment">// left, right, left + root , right + root, root, left + right + root 这些的最大值,这里是分成了两个阶段,left 跟 right 的最大值已经在上面的</span></span><br><span class="line"> <span class="comment">// 调用过程中赋值给 ansNew 了 </span></span><br><span class="line"> <span class="keyword">int</span> currentSum = Math.max(Math.max(root.val + left , root.val + right), root.val);</span><br><span class="line"> <span class="comment">// 这边返回的是 currentSum,然后再用它跟 left + right + root 进行对比,然后再去更新 ans</span></span><br><span class="line"> <span class="comment">// PS: 有个小点也是这边的破局点,就是这个 ansNew</span></span><br><span class="line"> <span class="keyword">int</span> res = Math.max(left + right + root.val, currentSum);</span><br><span class="line"> ans = Math.max(res, ans);</span><br><span class="line"> <span class="keyword">return</span> currentSum;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="简要分析"><a href="#简要分析" class="headerlink" title="简要分析"></a>简要分析</h3><p>其实这个题目会被误解成比较简单,左子树最大的,或者右子树最大的,或者两边加一下,仔细想想都不对,其实有可能是产生于左子树中,或者右子树中,这两个都是指跟左子树根还有右子树根没关系的,这么说感觉不太容易理解,画个图<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/SfxIEy.png"><br>可以看到图里,其实最长路径和是左边这个子树组成的,跟根节点还有右子树完全没关系,然后再想一种情况,如果是整棵树就是图中的左子树,那么这个最长路径和就是左子树加右子树加根节点了,所以不是我一开始想得那么简单,在代码实现中也需要一些技巧</p>
<h3 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h3><pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">int</span> ansNew <span class="token operator">=</span> <span class="token class-name">Integer</span><span class="token punctuation">.</span>MIN_VALUE<span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">maxPathSum</span><span class="token punctuation">(</span><span class="token class-name">TreeNode</span> root<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token function">maxSumNew</span><span class="token punctuation">(</span>root<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> ansNew<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">maxSumNew</span><span class="token punctuation">(</span><span class="token class-name">TreeNode</span> root<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>root <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token comment">// 这里是个简单的递归,就是去递归左右子树,但是这里其实有个概念,当这样处理时,其实相当于把子树的内部的最大路径和已经算出来了</span>
<span class="token keyword">int</span> left <span class="token operator">=</span> <span class="token function">maxSumNew</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>left<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> right <span class="token operator">=</span> <span class="token function">maxSumNew</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>right<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 这里前面我有点没想明白,但是看到 ansNew 的比较,其实相当于,返回的是三种情况里的最大值,一个是左子树+根,一个是右子树+根,一个是单独根节点,</span>
<span class="token comment">// 这样这个递归的返回才会有意义,不然像原来的方法,它可能是跳着的,但是这种情况其实是借助于 ansNew 这个全局的最大值,因为原来我觉得要比较的是</span>
<span class="token comment">// left, right, left + root , right + root, root, left + right + root 这些的最大值,这里是分成了两个阶段,left 跟 right 的最大值已经在上面的</span>
<span class="token comment">// 调用过程中赋值给 ansNew 了 </span>
<span class="token keyword">int</span> currentSum <span class="token operator">=</span> <span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span><span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>root<span class="token punctuation">.</span>val <span class="token operator">+</span> left <span class="token punctuation">,</span> root<span class="token punctuation">.</span>val <span class="token operator">+</span> right<span class="token punctuation">)</span><span class="token punctuation">,</span> root<span class="token punctuation">.</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 这边返回的是 currentSum,然后再用它跟 left + right + root 进行对比,然后再去更新 ans</span>
<span class="token comment">// PS: 有个小点也是这边的破局点,就是这个 ansNew</span>
<span class="token keyword">int</span> res <span class="token operator">=</span> <span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>left <span class="token operator">+</span> right <span class="token operator">+</span> root<span class="token punctuation">.</span>val<span class="token punctuation">,</span> currentSum<span class="token punctuation">)</span><span class="token punctuation">;</span>
ans <span class="token operator">=</span> <span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>res<span class="token punctuation">,</span> ans<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> currentSum<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>这里非常重要的就是 ansNew 是最后的一个结果,而对于 maxSumNew 这个函数的返回值其实是需要包含了一个连续结果,因为要返回继续去算路径和,所以返回的是 currentSum,最终结果是 ansNew</p>
<h3 id="结果图"><a href="#结果图" class="headerlink" title="结果图"></a>结果图</h3><p>难得有个 100%,贴个图哈哈<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/iipgv0.png" alt=""></p>
<h3 id="结果图"><a href="#结果图" class="headerlink" title="结果图"></a>结果图</h3><p>难得有个 100%,贴个图哈哈<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/iipgv0.png"></p>
</div>
@ -331,10 +354,10 @@
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/05/01/Leetcode-48-旋转图像-Rotate-Image-题解分析/" rel="bookmark">Leetcode 48 旋转图像(Rotate Image) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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>
</li>
</ul>
@ -463,7 +486,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#题目介绍"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#简要分析"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#代码"><span class="nav-number">3.</span> <span class="nav-text">代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#结果图"><span class="nav-number">4.</span> <span class="nav-text">结果图</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A2%98%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%AE%80%E8%A6%81%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">简要分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BB%A3%E7%A0%81"><span class="nav-number">3.</span> <span class="nav-text">代码</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BB%93%E6%9E%9C%E5%9B%BE"><span class="nav-number">4.</span> <span class="nav-text">结果图</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 4
- 3
2021/01/31/聊聊-redis-缓存的应用问题/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,8 +32,9 @@
<meta property="og:url" content="https://nicksxs.me/2021/01/31/%E8%81%8A%E8%81%8A-redis-%E7%BC%93%E5%AD%98%E7%9A%84%E5%BA%94%E7%94%A8%E9%97%AE%E9%A2%98/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="前面写过一系列的 redis 源码分析的,但是实际上很多的问题还是需要结合实际的使用,然后其实就避不开缓存使用的三个著名问题,穿透,击穿和雪崩,这三个概念也是有着千丝万缕的关系, 缓存穿透缓存穿透是指当数据库中本身就不存在这个数据的时候,使用一般的缓存策略时访问不到缓存后就访问数据库,但是因为数据库也没数据,所以如果不做任何策略优化的话,这类数据就每次都会访问一次数据库,对数据库压力也会比较大。">
<meta property="og:locale">
<meta property="article:published_time" content="2021-01-31T15:02:44.000Z">
<meta property="article:modified_time" content="2021-01-31T15:02:44.242Z">
<meta property="article:modified_time" content="2021-01-31T15:02:44.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Redis">
<meta property="article:tag" content="缓存穿透">
@ -456,7 +457,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#缓存穿透"><span class="nav-number">1.</span> <span class="nav-text">缓存穿透</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#缓存击穿"><span class="nav-number">2.</span> <span class="nav-text">缓存击穿</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#缓存雪崩"><span class="nav-number">3.</span> <span class="nav-text">缓存雪崩</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#解决缓存穿透"><span class="nav-number">4.</span> <span class="nav-text">解决缓存穿透</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#解决缓存击穿"><span class="nav-number">5.</span> <span class="nav-text">解决缓存击穿</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#解决缓存雪崩"><span class="nav-number">6.</span> <span class="nav-text">解决缓存雪崩</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F"><span class="nav-number">1.</span> <span class="nav-text">缓存穿透</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF"><span class="nav-number">2.</span> <span class="nav-text">缓存击穿</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9"><span class="nav-number">3.</span> <span class="nav-text">缓存雪崩</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E7%A9%BF%E9%80%8F"><span class="nav-number">4.</span> <span class="nav-text">解决缓存穿透</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E5%87%BB%E7%A9%BF"><span class="nav-number">5.</span> <span class="nav-text">解决缓存击穿</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%A7%A3%E5%86%B3%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9"><span class="nav-number">6.</span> <span class="nav-text">解决缓存雪崩</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 4
- 3
2021/02/07/关于读书打卡与分享/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,13 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2021/02/07/%E5%85%B3%E4%BA%8E%E8%AF%BB%E4%B9%A6%E6%89%93%E5%8D%A1%E4%B8%8E%E5%88%86%E4%BA%AB/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="最近群里大佬发起了一个读书打卡活动,需要每天读一会书,在群里打卡分享感悟,争取一个月能读完一本书,说实话一天十分钟的读书时间倒是问题不大,不过每天都要打卡,而且一个月要读完一本书,其实难度还是有点大的,不过也想试试看。之前某某老大给自己立了个 flag,说要读一百本书,这对我来说挺难实现的,一则我也不喜欢书只读一小半,二则感觉对于喜欢看的内容范围还是比较有限制,可能也算是比较矫情,不爱追热门的各类">
<meta property="og:locale">
<meta property="article:published_time" content="2021-02-07T15:13:39.000Z">
<meta property="article:modified_time" content="2021-02-07T15:13:39.017Z">
<meta property="article:modified_time" content="2021-02-07T15:13:39.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="读后感">
<meta property="article:tag" content="读书">
<meta property="article:tag" content="打卡">
<meta property="article:tag" content="幸福了吗">
<meta property="article:tag" content="读后感">
<meta property="article:tag" content="足球">
<meta name="twitter:card" content="summary">


+ 209
- 22
2021/02/14/AQS篇一/index.html
File diff suppressed because it is too large
View File


+ 477
- 20
2021/02/21/AQS-之-Condition-浅析笔记/index.html
File diff suppressed because it is too large
View File


+ 6
- 6
2021/02/28/闲聊下乘公交的用户体验/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,20 +32,20 @@
<meta property="og:url" content="https://nicksxs.me/2021/02/28/%E9%97%B2%E8%81%8A%E4%B8%8B%E4%B9%98%E5%85%AC%E4%BA%A4%E7%9A%84%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="新年开工开车来杭州,因为没有车位加限行今天来就没开车来了,从东站做公交回住的地方,这班神奇的车我之前也吐槽过了,有神奇的乘客和神奇的司机,因为基本上这班车是从我毕业就开始乘了,所以也算是比较熟悉了,以前总体感觉不太好的是乘坐时间太长了,不过这个也不能怪车,是我自己住得远(离东站),后来住到了现在的地方,也算是直达,并且 LD 比较喜欢直达的,不爱更快却要换乘的地铁,所以坐的频率比较高,也说过前面那">
<meta property="og:locale">
<meta property="article:published_time" content="2021-02-28T13:56:42.000Z">
<meta property="article:modified_time" content="2021-02-28T13:56:42.363Z">
<meta property="article:modified_time" content="2021-02-28T13:56:42.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="开车">
<meta property="article:tag" content="加塞">
<meta property="article:tag" content="2021">
<meta property="article:tag" content="糟心事">
<meta property="article:tag" content="规则">
<meta property="article:tag" content="公交">
<meta property="article:tag" content="路政规划">
<meta property="article:tag" content="高速">
<meta property="article:tag" content="基础设施">
<meta property="article:tag" content="杭州">
<meta property="article:tag" content="高速">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2021/02/28/%E9%97%B2%E8%81%8A%E4%B8%8B%E4%B9%98%E5%85%AC%E4%BA%A4%E7%9A%84%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C/">
@ -311,10 +311,10 @@
<div class="popular-posts-title"><a href="/2021/04/11/聊聊厦门旅游的好与不好/" rel="bookmark">聊聊厦门旅游的好与不好</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/10/18/在老丈人家的小工记五/" rel="bookmark">在老丈人家的小工记五</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
</ul>


+ 11
- 10
2021/03/07/《垃圾回收算法手册读书》笔记之整理算法/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,11 +32,12 @@
<meta property="og:url" content="https://nicksxs.me/2021/03/07/%E3%80%8A%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%AE%97%E6%B3%95%E6%89%8B%E5%86%8C%E8%AF%BB%E4%B9%A6%E3%80%8B%E7%AC%94%E8%AE%B0%E4%B9%8B%E6%95%B4%E7%90%86%E7%AE%97%E6%B3%95/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="最近看了下这本垃圾回收算法手册,看到了第三章的标记-整理回收算法,做个简单的读书笔记 双指针整理算法对于一块待整理区域,通过两个指针,free 在区域的起始端,scan 指针在区域的末端,free 指针从前往后知道找到空闲区域,scan 从后往前一直找到存活对象,当 free 指针未与 scan 指针交叉时,会给 scan 位置的对象特定位置标记上 free 的地址,即将要转移的地址,不过这里有个">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/yLQlgj.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/6yeA7n.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/Jqtuzu.png">
<meta property="article:published_time" content="2021-03-07T12:37:06.000Z">
<meta property="article:modified_time" content="2021-03-07T12:37:06.387Z">
<meta property="article:modified_time" content="2021-03-07T12:37:06.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="java">
<meta property="article:tag" content="gc">
@ -294,10 +295,10 @@
<p>最近看了下这本垃圾回收算法手册,看到了第三章的标记-整理回收算法,做个简单的读书笔记</p>
<h3 id="双指针整理算法"><a href="#双指针整理算法" class="headerlink" title="双指针整理算法"></a>双指针整理算法</h3><p>对于一块待整理区域,通过两个指针,free 在区域的起始端,scan 指针在区域的末端,free 指针从前往后知道找到空闲区域,scan 从后往前一直找到存活对象,当 free 指针未与 scan 指针交叉时,会给 scan 位置的对象特定位置标记上 free 的地址,即将要转移的地址,不过这里有个限制,这种整理算法一般会用于对象大小统一的情况,否则 free 指针扫描时还需要匹配scan 指针扫描到的存活对象的大小。<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/yLQlgj.png" alt=""></p>
<h3 id="双指针整理算法"><a href="#双指针整理算法" class="headerlink" title="双指针整理算法"></a>双指针整理算法</h3><p>对于一块待整理区域,通过两个指针,free 在区域的起始端,scan 指针在区域的末端,free 指针从前往后知道找到空闲区域,scan 从后往前一直找到存活对象,当 free 指针未与 scan 指针交叉时,会给 scan 位置的对象特定位置标记上 free 的地址,即将要转移的地址,不过这里有个限制,这种整理算法一般会用于对象大小统一的情况,否则 free 指针扫描时还需要匹配scan 指针扫描到的存活对象的大小。<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/yLQlgj.png"></p>
<h3 id="Lisp-2-整理算法"><a href="#Lisp-2-整理算法" class="headerlink" title="Lisp 2 整理算法"></a>Lisp 2 整理算法</h3><p>需要三次完整遍历堆区域<br>第一遍是遍历后将计算出所有对象的最终地址(转发地址)<br>第二遍是使用转发地址更新赋值器线程根以及被标记对象中的引用,该操作将确保它们指向对象的新位置<br>第三次遍历是relocate最终将存活对象移动到其新的目标位置</p>
<h3 id="引线整理算法"><a href="#引线整理算法" class="headerlink" title="引线整理算法"></a>引线整理算法</h3><p>这个真的长见识了,<br><img data-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>
<h3 id="单次遍历算法"><a href="#单次遍历算法" class="headerlink" title="单次遍历算法"></a>单次遍历算法</h3><p>这个一直提到过位图的实现方式,<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/Jqtuzu.png" alt=""><br>可以看到在第一步会先通过位图标记,标记的方式是位图的每一位对应的堆内存的一个字(这里可能指的是 byte 吧),然后将一个存活对象的内存区域的第一个字跟最后一个字标记,这里如果在通过普通的方式就还需要一个地方在存转发地址,但是因为具体的位置可以通过位图算出来,也就不需要额外记录了</p>
<h3 id="引线整理算法"><a href="#引线整理算法" class="headerlink" title="引线整理算法"></a>引线整理算法</h3><p>这个真的长见识了,<br><img data-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>
<h3 id="单次遍历算法"><a href="#单次遍历算法" class="headerlink" title="单次遍历算法"></a>单次遍历算法</h3><p>这个一直提到过位图的实现方式,<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/Jqtuzu.png"><br>可以看到在第一步会先通过位图标记,标记的方式是位图的每一位对应的堆内存的一个字(这里可能指的是 byte 吧),然后将一个存活对象的内存区域的第一个字跟最后一个字标记,这里如果在通过普通的方式就还需要一个地方在存转发地址,但是因为具体的位置可以通过位图算出来,也就不需要额外记录了</p>
</div>
@ -308,19 +309,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/05/01/Leetcode-48-旋转图像-Rotate-Image-题解分析/" rel="bookmark">Leetcode 48 旋转图像(Rotate Image) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2019/09/23/AbstractQueuedSynchronizer/" rel="bookmark">AbstractQueuedSynchronizer</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
</ul>
@ -449,7 +450,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#双指针整理算法"><span class="nav-number">1.</span> <span class="nav-text">双指针整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Lisp-2-整理算法"><span class="nav-number">2.</span> <span class="nav-text">Lisp 2 整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#引线整理算法"><span class="nav-number">3.</span> <span class="nav-text">引线整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#单次遍历算法"><span class="nav-number">4.</span> <span class="nav-text">单次遍历算法</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%8C%E6%8C%87%E9%92%88%E6%95%B4%E7%90%86%E7%AE%97%E6%B3%95"><span class="nav-number">1.</span> <span class="nav-text">双指针整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#Lisp-2-%E6%95%B4%E7%90%86%E7%AE%97%E6%B3%95"><span class="nav-number">2.</span> <span class="nav-text">Lisp 2 整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BC%95%E7%BA%BF%E6%95%B4%E7%90%86%E7%AE%97%E6%B3%95"><span class="nav-number">3.</span> <span class="nav-text">引线整理算法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8D%95%E6%AC%A1%E9%81%8D%E5%8E%86%E7%AE%97%E6%B3%95"><span class="nav-number">4.</span> <span class="nav-text">单次遍历算法</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 35
- 14
2021/03/14/Leetcode-121-买卖股票的最佳时机-Best-Time-to-Buy-and-Sell-Stock-题解分析/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,14 +32,14 @@
<meta property="og:url" content="https://nicksxs.me/2021/03/14/Leetcode-121-%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA-Best-Time-to-Buy-and-Sell-Stock-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="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">
<meta property="og:locale">
<meta property="article:published_time" content="2021-03-14T14:34:30.000Z">
<meta property="article:modified_time" content="2021-03-14T14:34:30.343Z">
<meta property="article:modified_time" content="2021-03-14T14:34:30.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="leetcode">
<meta property="article:tag" content="java">
<meta property="article:tag" content="DP">
<meta property="article:tag" content="题解">
<meta property="article:tag" content="leetcode 121">
<meta property="article:tag" content="DP">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://nicksxs.me/2021/03/14/Leetcode-121-%E4%B9%B0%E5%8D%96%E8%82%A1%E7%A5%A8%E7%9A%84%E6%9C%80%E4%BD%B3%E6%97%B6%E6%9C%BA-Best-Time-to-Buy-and-Sell-Stock-%E9%A2%98%E8%A7%A3%E5%88%86%E6%9E%90/">
@ -246,11 +246,11 @@
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
<a href="/categories/DP/" itemprop="url" rel="index"><span itemprop="name">DP</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/DP/" itemprop="url" rel="index"><span itemprop="name">DP</span></a>
<a href="/categories/leetcode/java/" itemprop="url" rel="index"><span itemprop="name">java</span></a>
</span>
,
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
@ -300,11 +300,32 @@
<h3 id="题目介绍"><a href="#题目介绍" 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>Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return <code>0</code>.</p>
<p>给定一个数组 <code>prices</code> ,它的第 <code>i</code> 个元素 <code>prices[i]</code> 表示一支给定股票第 <code>i</code> 天的价格。</p>
<p>给定一个数组 <code>prices</code> ,它的第 <code>i</code> 个元素 <code>prices[i]</code> 表示一支给定股票第 <code>i</code> 天的价格。</p>
<p>你只能选择 <strong>某一天</strong> 买入这只股票,并选择在 <strong>未来的某一个不同的日子</strong> 卖出该股票。设计一个算法来计算你所能获取的最大利润。</p>
<p>返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 <code>0</code></p>
<h3 id="简单分析"><a href="#简单分析" class="headerlink" title="简单分析"></a>简单分析</h3><p>其实这个跟二叉树的最长路径和有点类似,需要找到整体的最大收益,但是在迭代过程中需要一个当前的值</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> maxSofar = <span class="number">0</span>;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxProfit</span><span class="params">(<span class="keyword">int</span>[] prices)</span> </span>&#123;</span><br><span class="line"> <span class="keyword">if</span> (prices.length &lt;= <span class="number">1</span>) &#123;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">int</span> maxIn = prices[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">int</span> maxOut = prices[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; prices.length; i++) &#123;</span><br><span class="line"> <span class="keyword">if</span> (maxIn &gt; prices[i]) &#123;</span><br><span class="line"> <span class="comment">// 当循环当前值小于之前的买入值时就当成买入值,同时卖出也要更新</span></span><br><span class="line"> maxIn = prices[i];</span><br><span class="line"> maxOut = prices[i];</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">if</span> (prices[i] &gt; maxOut) &#123;</span><br><span class="line"> <span class="comment">// 表示一个可卖出点,即比买入值高时</span></span><br><span class="line"> maxOut = prices[i];</span><br><span class="line"> <span class="comment">// 需要设置一个历史值</span></span><br><span class="line"> maxSofar = Math.max(maxSofar, maxOut - maxIn);</span><br><span class="line"> &#125;</span><br><span class="line"> &#125;</span><br><span class="line"> <span class="keyword">return</span> maxSofar;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">int</span> maxSofar <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">maxProfit</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> prices<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>prices<span class="token punctuation">.</span>length <span class="token operator">&lt;=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">int</span> maxIn <span class="token operator">=</span> prices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> maxOut <span class="token operator">=</span> prices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> prices<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>maxIn <span class="token operator">></span> prices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 当循环当前值小于之前的买入值时就当成买入值,同时卖出也要更新</span>
maxIn <span class="token operator">=</span> prices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
maxOut <span class="token operator">=</span> prices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>prices<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">></span> maxOut<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token comment">// 表示一个可卖出点,即比买入值高时</span>
maxOut <span class="token operator">=</span> prices<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token comment">// 需要设置一个历史值</span>
maxSofar <span class="token operator">=</span> <span class="token class-name">Math</span><span class="token punctuation">.</span><span class="token function">max</span><span class="token punctuation">(</span>maxSofar<span class="token punctuation">,</span> maxOut <span class="token operator">-</span> maxIn<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">return</span> maxSofar<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<h3 id="总结下"><a href="#总结下" class="headerlink" title="总结下"></a>总结下</h3><p>一开始看到 easy 就觉得是很简单,就没有 maxSofar ,但是一提交就出现问题了<br>对于<code>[2, 4, 1]</code>这种就会变成 0,所以还是需要一个历史值来存放历史最大值,这题有点动态规划的意思</p>
@ -317,19 +338,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/10/25/Leetcode-104-二叉树的最大深度-Maximum-Depth-of-Binary-Tree-题解分析/" rel="bookmark">Leetcode 104 二叉树的最大深度(Maximum Depth of Binary Tree) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2021/01/10/Leetcode-160-相交链表-intersection-of-two-linked-lists-题解分析/" rel="bookmark">Leetcode 160 相交链表(intersection-of-two-linked-lists) 题解分析</a></div>
<div class="popular-posts-title"><a href="/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 class="popular-posts-item">
<div class="popular-posts-title"><a href="/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>
<div class="popular-posts-title"><a href="/2021/01/24/Leetcode-124-二叉树中的最大路径和-Binary-Tree-Maximum-Path-Sum-题解分析/" rel="bookmark">Leetcode 124 二叉树中的最大路径和(Binary Tree Maximum Path Sum) 题解分析</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/10/11/Leetcode-2-Add-Two-Numbers-题解分析/" rel="bookmark">Leetcode 2 Add Two Numbers 题解分析</a></div>
<div class="popular-posts-title"><a href="/2020/12/06/Leetcode-155-最小栈-Min-Stack-题解分析/" rel="bookmark">Leetcode 155 最小栈(Min Stack) 题解分析</a></div>
</li>
</ul>
@ -457,7 +478,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#题目介绍"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#简单分析"><span class="nav-number">2.</span> <span class="nav-text">简单分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#总结下"><span class="nav-number">3.</span> <span class="nav-text">总结下</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%A2%98%E7%9B%AE%E4%BB%8B%E7%BB%8D"><span class="nav-number">1.</span> <span class="nav-text">题目介绍</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E5%88%86%E6%9E%90"><span class="nav-number">2.</span> <span class="nav-text">简单分析</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%80%BB%E7%BB%93%E4%B8%8B"><span class="nav-number">3.</span> <span class="nav-text">总结下</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 5
- 5
2021/03/21/关于公共交通再吐个槽/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,13 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2021/03/21/%E5%85%B3%E4%BA%8E%E5%85%AC%E5%85%B1%E4%BA%A4%E9%80%9A%E5%86%8D%E5%90%90%E4%B8%AA%E6%A7%BD/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="事情源于周末来回家发生的两件事情,先是回去的时候从高铁下车要坐公交,现在算是有个比较好的临时候车点了,但是可能由于疫情好转,晚上都不用检查健康码就可以进候车点,但是上公交的时候还是需要看健康码,一般情况下从高铁下来的,各个地方的人都有,而且也不太清楚这边上公交车需要查验健康码,我的一个看法是候车的时候就应该放个横幅告示,或者再配合喇叭循环播放,请提前准备好健康码,上车前需要查验,因为像这周的情况,">
<meta property="og:locale">
<meta property="article:published_time" content="2021-03-21T15:23:40.000Z">
<meta property="article:modified_time" content="2021-03-21T15:23:40.505Z">
<meta property="article:modified_time" content="2021-03-21T15:23:40.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="开车">
<meta property="article:tag" content="加塞">
<meta property="article:tag" content="2021">
<meta property="article:tag" content="糟心事">
<meta property="article:tag" content="规则">
<meta property="article:tag" content="公交">
@ -311,10 +311,10 @@
<div class="popular-posts-title"><a href="/2021/04/11/聊聊厦门旅游的好与不好/" rel="bookmark">聊聊厦门旅游的好与不好</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
</li>
</ul>


+ 34
- 11
2021/03/28/聊聊-Linux-下的-top-命令/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,23 +26,22 @@
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>
<meta name="description" content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 123-H :Threads-mode operation Instructs top to display indiv">
<meta name="description" content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 -H :Threads-mode operation Instructs top to display individ">
<meta property="og:type" content="article">
<meta property="og:title" content="聊聊 Linux 下的 top 命令">
<meta property="og:url" content="https://nicksxs.me/2021/03/28/%E8%81%8A%E8%81%8A-Linux-%E4%B8%8B%E7%9A%84-top-%E5%91%BD%E4%BB%A4/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 123-H :Threads-mode operation Instructs top to display indiv">
<meta property="og:description" content="top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加-H进入线程模式 -H :Threads-mode operation Instructs top to display individ">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/1xD6VM.png">
<meta property="article:published_time" content="2021-03-28T15:06:21.000Z">
<meta property="article:modified_time" content="2021-03-28T15:06:21.180Z">
<meta property="article:modified_time" content="2021-03-28T15:06:21.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Linux">
<meta property="article:tag" content="top">
<meta property="article:tag" content="排序">
<meta property="article:tag" content="linux">
<meta property="article:tag" content="小技巧">
<meta property="article:tag" content="线程模式">
<meta property="article:tag" content="问题排查">
<meta property="article:tag" content="top">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png">
@ -306,9 +305,33 @@
<p>top 命令在日常的 Linux 使用中,特别是做一些服务器的简单状态查看,排查故障都起了比较大的作用,但是由于这个命令看到的东西比较多,一般只会看部分,或者说像我这样就会比较片面地看一些信息,比如默认是进程维度的,可以在启动命令的时候加<code>-H</code>进入线程模式</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">-H :Threads-mode operation</span><br><span class="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><span class="line"> this can be changed with the &#96;H&#39; interactive command.</span><br></pre></td></tr></table></figure>
<p>这样就能用在 Java 中去 jstack 中找到对应的线程<br>其实还有比较重要的两个操作,<br>一个是在 top 启动状态下,按<code>c</code>键,这样能把比如说是一个 Java 进程,具体的进程命令显示出来<br>像这样<br>执行前是这样<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png" alt=""><br>执行后是这样<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/1xD6VM.png" alt=""><br>第二个就是排序了</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">SORTING of task window</span><br><span class="line"></span><br><span class="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><span class="line"> do not appear on any help screen.</span><br><span class="line"> command sorted-field supported</span><br><span class="line"> A start time (non-display) No</span><br><span class="line"> M %MEM Yes</span><br><span class="line"> N PID Yes</span><br><span class="line"> P %CPU Yes</span><br><span class="line"> T TIME+ Yes</span><br><span class="line"></span><br><span class="line"> Before using any of the following sort provisions, top suggests that you temporarily turn on column highlighting using the &#96;x&#39; interactive com‐</span><br><span class="line"> mand. That will help ensure that the actual sort environment matches your intent.</span><br><span class="line"></span><br><span class="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><span class="line"> 1) there is insufficient Screen Width</span><br><span class="line"> 2) the &#96;f&#39; interactive command turned it Off</span><br><span class="line"></span><br><span class="line"> &lt; :Move-Sort-Field-Left</span><br><span class="line"> Moves the sort column to the left unless the current sort field is the first field being displayed.</span><br><span class="line"></span><br><span class="line"> &gt; :Move-Sort-Field-Right</span><br><span class="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>
<pre class="line-numbers language-none"><code class="language-none">-H :Threads-mode operation
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 &#96;H&#39; interactive command.<span aria-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><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/LKn8Bs.png"><br>执行后是这样<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/1xD6VM.png"><br>第二个就是排序了</p>
<pre class="line-numbers language-none"><code class="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 &#96;x&#39; 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 &#96;f&#39; interactive command turned it Off
&lt; :Move-Sort-Field-Left
Moves the sort column to the left unless the current sort field is the first field being displayed.
&gt; :Move-Sort-Field-Right
Moves the sort column to the right unless the current sort field is the last field being displayed.<span aria-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>&lt;</code><code>&gt;</code>直接左右移动排序列</p>
</div>


+ 11
- 20
2021/03/31/2020-年终总结/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,15 +32,13 @@
<meta property="og:url" content="https://nicksxs.me/2021/03/31/2020-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="拖更原因这篇年终总结本来应该在农历过完年就出来的,结果是对没有受疫情影响的春节放假时间空闲情况预估太良好,虽然公司调了几天假,但是因为春节期间疫情状况比较好,本来酒店都不让接待聚餐什么的,后来统统放开,结果就是从初一到初六每天要不就是去亲戚家,要不就是去酒店饭店吃饭,计划很丰满,现实很骨感,时间感觉一下就没了,然后年后感觉有点犯懒了,所以才拖到现在。 生活-健身跑步去年(19 年)的时候跑步突破了">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/WechatIMG546-1.png">
<meta property="article:published_time" content="2021-03-31T15:37:28.000Z">
<meta property="article:modified_time" content="2021-04-01T12:13:24.747Z">
<meta property="article:modified_time" content="2021-03-31T15:37:28.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="年终总结">
<meta property="article:tag" content="学习">
<meta property="article:tag" content="跑步">
<meta property="article:tag" content="技术">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="年终总结">
<meta property="article:tag" content="2020">
<meta property="article:tag" content="2021">
<meta property="article:tag" content="拖更">
@ -237,13 +235,6 @@
<time title="Created: 2021-03-31 23:37:28" itemprop="dateCreated datePublished" datetime="2021-03-31T23:37:28+08:00">2021-03-31</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2021-04-01 20:13:24" itemprop="dateModified" datetime="2021-04-01T20:13:24+08:00">2021-04-01</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -311,7 +302,7 @@
<h2 id="拖更原因"><a href="#拖更原因" class="headerlink" title="拖更原因"></a>拖更原因</h2><p>这篇年终总结本来应该在农历过完年就出来的,结果是对没有受疫情影响的春节放假时间空闲情况预估太良好,虽然公司调了几天假,但是因为春节期间疫情状况比较好,本来酒店都不让接待聚餐什么的,后来统统放开,结果就是从初一到初六每天要不就是去亲戚家,要不就是去酒店饭店吃饭,计划很丰满,现实很骨感,时间感觉一下就没了,然后年后感觉有点犯懒了,所以才拖到现在。</p>
<h2 id="生活-健身跑步"><a href="#生活-健身跑步" class="headerlink" title="生活-健身跑步"></a>生活-健身跑步</h2><p>去年(19 年)的时候跑步突破了 300 公里,然后20 年给自己定了个 400 公里的目标,结果意料之中的没成功,原因可能疫情算一点吧,后面买了跑步机之后,基本周末回家都能跑一下,但是最后还是只跑了300 多公里,总的keep 记录跑量也没超过 1000 公里,所以跑步这个目标还是没成功的,不过还算是比去年多跑一点,这样也算后面好突破点,后面的目标就不定的太高了,每年能比前一年多一点就好,其实跑步已经从一种减肥方式变成一种习惯了,一周一次的跑步已经比较难有效减重了,但是对于保持精力和身体状态还是很有效和重要的,只是对于目前的体重还是要多减下去一些跑步才好,太重了对膝盖负担太大了,可惜还是时间呐,游泳骑车什么的都需要更苛刻的条件和时间,饮食呢控制起来比较难(贪吃<br>终于在 3 月底之前跑到了 1000 公里,迟了三个月,不过也总算达到了,只是体重控制还是不行,有试着走走楼梯,但是感觉对膝盖负担比较大,得再想想用什么方式</p>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/WechatIMG546-1.png" alt=""></p>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/WechatIMG546-1.png"></p>
<h2 id="技术成长"><a href="#技术成长" class="headerlink" title="技术成长"></a>技术成长</h2><p>一直提不起笔来写这篇年终总结还有个比较大的原因是觉得20 年的成长不如预期,大小目标都没怎么完成,比如深入了解 jvm,是想能有些深入的见解,而不再是某些点的比较片面的理解,系统性的归纳总结也比较少,每个方向或多或少有些看法和理解,但是不全面,一些东西看过了也会忘记,需要温故而知新,比如 AQS 的内容,第一次读其实理解比较浅,后面就强迫自己去读,去写,才有了一些比之前更深入的理解,因为很多文章都是带有作者思路的引导,适不适合自己都要看是否能从他的思路把它看懂,有些就差别很大,这个跟看书也一样,有些书大众一致推荐,一般情况下大多是经典的好的,但是也有可能是不太适合自己的,可能有时候机缘巧合看到的反而让人茅塞顿开,在 todo 里已经积攒了好多的点和面需要去学习实践,一方面是自己懒,一方面是时间也相对偏少,看看 21 年能不能有所提升,加强“时间管理”,哈哈</p>
<p>技术上主要是看了 mysql 的 mvcc 相关内容,rocketmq 的,redis 的代码,还有 mybatis 等,其实每一个都能写很多,也有很多值得学习的,需要全面系统学习,之前想好好画一个思维导图,将整个技术体系都梳理下,还只做了一点点,方式也有点问题,应该从大到小,而不是深度优先,细节有很多,每一个方面都有自己比较熟悉擅长的,也有不太了解的,可以做一个评分,这个也是亟待改善的,希望今年能完成。</p>
<h2 id="博客"><a href="#博客" class="headerlink" title="博客"></a>博客</h2><p>博客方面 20 年一年整是写了 53 篇,差不多是一周一篇的节奏,这个还是不错的,虽然博客质量参差不齐,但是这个更新频率还是比较好的,并且也定了个潜规则,可以一周技术一周生活,这样能缓解水文的频率,提高些技术文章的质量,虽然结果并没有好多少,不过感觉还是可以这么坚持的,能提高一些技术文章的质量那就更好了</p>
@ -325,19 +316,19 @@
<div class="popular-posts-header">Related Posts</div>
<ul class="popular-posts">
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/02/01/2019年终总结/" rel="bookmark">2019年终总结</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
<div class="popular-posts-title"><a href="/2020/02/01/2019年终总结/" rel="bookmark">2019年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2021/03/21/关于公共交通再吐个槽/" rel="bookmark">关于公共交通再吐个槽</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/09/13/在老丈人家的小工记三/" rel="bookmark">在老丈人家的小工记三</a></div>
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
</li>
</ul>
@ -466,7 +457,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#拖更原因"><span class="nav-number">1.</span> <span class="nav-text">拖更原因</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#生活-健身跑步"><span class="nav-number">2.</span> <span class="nav-text">生活-健身跑步</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#技术成长"><span class="nav-number">3.</span> <span class="nav-text">技术成长</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#博客"><span class="nav-number">4.</span> <span class="nav-text">博客</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8B%96%E6%9B%B4%E5%8E%9F%E5%9B%A0"><span class="nav-number">1.</span> <span class="nav-text">拖更原因</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%94%9F%E6%B4%BB-%E5%81%A5%E8%BA%AB%E8%B7%91%E6%AD%A5"><span class="nav-number">2.</span> <span class="nav-text">生活-健身跑步</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8A%80%E6%9C%AF%E6%88%90%E9%95%BF"><span class="nav-number">3.</span> <span class="nav-text">技术成长</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8D%9A%E5%AE%A2"><span class="nav-number">4.</span> <span class="nav-text">博客</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 39
- 10
2021/04/04/聊聊-dubbo-的线程池/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,19 +26,20 @@
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>
<meta name="description" content="之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题看下代码目录主要是这几个 FixedThreadPool:创建一个复用固定个数线程的线程池。简单看下代码123456public Ex">
<meta name="description" content="之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题看下代码目录主要是这几个 FixedThreadPool:创建一个复用固定个数线程的线程池。简单看下代码public Executor">
<meta property="og:type" content="article">
<meta property="og:title" content="聊聊 dubbo 的线程池">
<meta property="og:url" content="https://nicksxs.me/2021/04/04/%E8%81%8A%E8%81%8A-dubbo-%E7%9A%84%E7%BA%BF%E7%A8%8B%E6%B1%A0/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题看下代码目录主要是这几个 FixedThreadPool:创建一个复用固定个数线程的线程池。简单看下代码123456public Ex">
<meta property="og:description" content="之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题看下代码目录主要是这几个 FixedThreadPool:创建一个复用固定个数线程的线程池。简单看下代码public Executor">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/3qIllK.png">
<meta property="article:published_time" content="2021-04-04T14:14:57.000Z">
<meta property="article:modified_time" content="2021-04-04T14:14:57.278Z">
<meta property="article:modified_time" content="2021-04-04T14:14:57.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="Dubbo">
<meta property="article:tag" content="ThreadPool">
<meta property="article:tag" content="Java">
<meta property="article:tag" content="线程池">
<meta property="article:tag" content="FixedThreadPool">
<meta property="article:tag" content="LimitedThreadPool">
@ -302,15 +303,43 @@
<div class="post-body" itemprop="articleBody">
<p>之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题<br>看下代码目录主要是这几个<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/3qIllK.png" alt=""></p>
<p>之前没注意到这一块,只是比较模糊的印象 dubbo 自己基于 ThreadPoolExecutor 定义了几个线程池,但是没具体看过,主要是觉得就是为了避免使用 jdk 自带的那几个(java.util.concurrent.Executors),防止出现那些问题<br>看下代码目录主要是这几个<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/3qIllK.png"></p>
<ul>
<li>FixedThreadPool:创建一个复用固定个数线程的线程池。<br>简单看下代码<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Executor <span class="title">getExecutor</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line"> String name = url.getParameter(<span class="string">"threadname"</span>, <span class="string">"Dubbo"</span>);</span><br><span class="line"> <span class="keyword">int</span> threads = url.getParameter(<span class="string">"threads"</span>, <span class="number">200</span>);</span><br><span class="line"> <span class="keyword">int</span> queues = url.getParameter(<span class="string">"queues"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> ThreadPoolExecutor(threads, threads, <span class="number">0L</span>, TimeUnit.MILLISECONDS, (BlockingQueue)(queues == <span class="number">0</span> ? <span class="keyword">new</span> SynchronousQueue() : (queues &lt; <span class="number">0</span> ? <span class="keyword">new</span> LinkedBlockingQueue() : <span class="keyword">new</span> LinkedBlockingQueue(queues))), <span class="keyword">new</span> NamedThreadFactory(name, <span class="keyword">true</span>), <span class="keyword">new</span> AbortPolicyWithReport(name, url));</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<li>FixedThreadPool:创建一个复用固定个数线程的线程池。<br>简单看下代码<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token class-name">Executor</span> <span class="token function">getExecutor</span><span class="token punctuation">(</span><span class="token class-name">URL</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">String</span> name <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threadname"</span><span class="token punctuation">,</span> <span class="token string">"Dubbo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> threads <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threads"</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> queues <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"queues"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ThreadPoolExecutor</span><span class="token punctuation">(</span>threads<span class="token punctuation">,</span> threads<span class="token punctuation">,</span> <span class="token number">0L</span><span class="token punctuation">,</span> <span class="token class-name">TimeUnit</span><span class="token punctuation">.</span>MILLISECONDS<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">BlockingQueue</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queues <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">SynchronousQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token punctuation">(</span>queues <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span>queues<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">NamedThreadFactory</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">AbortPolicyWithReport</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
可以看到核心线程数跟最大线程数一致,也就是说就不会在核心线程数和最大线程数之间动态变化了</li>
<li>LimitedThreadPool:创建一个线程池,这个线程池中线程个数随着需要量动态增加,但是数量不超过配置的阈值的个数,另外空闲线程不会被回收,会一直存在。<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Executor <span class="title">getExecutor</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line"> String name = url.getParameter(<span class="string">"threadname"</span>, <span class="string">"Dubbo"</span>);</span><br><span class="line"> <span class="keyword">int</span> cores = url.getParameter(<span class="string">"corethreads"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> threads = url.getParameter(<span class="string">"threads"</span>, <span class="number">200</span>);</span><br><span class="line"> <span class="keyword">int</span> queues = url.getParameter(<span class="string">"queues"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> ThreadPoolExecutor(cores, threads, <span class="number">9223372036854775807L</span>, TimeUnit.MILLISECONDS, (BlockingQueue)(queues == <span class="number">0</span> ? <span class="keyword">new</span> SynchronousQueue() : (queues &lt; <span class="number">0</span> ? <span class="keyword">new</span> LinkedBlockingQueue() : <span class="keyword">new</span> LinkedBlockingQueue(queues))), <span class="keyword">new</span> NamedThreadFactory(name, <span class="keyword">true</span>), <span class="keyword">new</span> AbortPolicyWithReport(name, url));</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<li>LimitedThreadPool:创建一个线程池,这个线程池中线程个数随着需要量动态增加,但是数量不超过配置的阈值的个数,另外空闲线程不会被回收,会一直存在。<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token class-name">Executor</span> <span class="token function">getExecutor</span><span class="token punctuation">(</span><span class="token class-name">URL</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">String</span> name <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threadname"</span><span class="token punctuation">,</span> <span class="token string">"Dubbo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> cores <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"corethreads"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> threads <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threads"</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> queues <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"queues"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ThreadPoolExecutor</span><span class="token punctuation">(</span>cores<span class="token punctuation">,</span> threads<span class="token punctuation">,</span> <span class="token number">9223372036854775807L</span><span class="token punctuation">,</span> <span class="token class-name">TimeUnit</span><span class="token punctuation">.</span>MILLISECONDS<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">BlockingQueue</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queues <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">SynchronousQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token punctuation">(</span>queues <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span>queues<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">NamedThreadFactory</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">AbortPolicyWithReport</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
这个特点主要是创建了保活时间特别长,即可以认为不会被回收了</li>
<li>EagerThreadPool :创建一个线程池,这个线程池当所有核心线程都处于忙碌状态时候,创建新的线程来执行新任务,而不是把任务放入线程池阻塞队列。<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Executor <span class="title">getExecutor</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line"> String name = url.getParameter(<span class="string">"threadname"</span>, <span class="string">"Dubbo"</span>);</span><br><span class="line"> <span class="keyword">int</span> cores = url.getParameter(<span class="string">"corethreads"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> threads = url.getParameter(<span class="string">"threads"</span>, <span class="number">2147483647</span>);</span><br><span class="line"> <span class="keyword">int</span> queues = url.getParameter(<span class="string">"queues"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> alive = url.getParameter(<span class="string">"alive"</span>, <span class="number">60000</span>);</span><br><span class="line"> TaskQueue&lt;Runnable&gt; taskQueue = <span class="keyword">new</span> TaskQueue(queues &lt;= <span class="number">0</span> ? <span class="number">1</span> : queues);</span><br><span class="line"> EagerThreadPoolExecutor executor = <span class="keyword">new</span> EagerThreadPoolExecutor(cores, threads, (<span class="keyword">long</span>)alive, TimeUnit.MILLISECONDS, taskQueue, <span class="keyword">new</span> NamedThreadFactory(name, <span class="keyword">true</span>), <span class="keyword">new</span> AbortPolicyWithReport(name, url));</span><br><span class="line"> taskQueue.setExecutor(executor);</span><br><span class="line"> <span class="keyword">return</span> executor;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<li>EagerThreadPool :创建一个线程池,这个线程池当所有核心线程都处于忙碌状态时候,创建新的线程来执行新任务,而不是把任务放入线程池阻塞队列。<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token class-name">Executor</span> <span class="token function">getExecutor</span><span class="token punctuation">(</span><span class="token class-name">URL</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">String</span> name <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threadname"</span><span class="token punctuation">,</span> <span class="token string">"Dubbo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> cores <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"corethreads"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> threads <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threads"</span><span class="token punctuation">,</span> <span class="token number">2147483647</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> queues <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"queues"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> alive <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"alive"</span><span class="token punctuation">,</span> <span class="token number">60000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">TaskQueue</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Runnable</span><span class="token punctuation">></span></span> taskQueue <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TaskQueue</span><span class="token punctuation">(</span>queues <span class="token operator">&lt;=</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token number">1</span> <span class="token operator">:</span> queues<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token class-name">EagerThreadPoolExecutor</span> executor <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EagerThreadPoolExecutor</span><span class="token punctuation">(</span>cores<span class="token punctuation">,</span> threads<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span>alive<span class="token punctuation">,</span> <span class="token class-name">TimeUnit</span><span class="token punctuation">.</span>MILLISECONDS<span class="token punctuation">,</span> taskQueue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">NamedThreadFactory</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">AbortPolicyWithReport</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
taskQueue<span class="token punctuation">.</span><span class="token function">setExecutor</span><span class="token punctuation">(</span>executor<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> executor<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
这个是改动最多的一个了,因为需要实现这个机制,有兴趣的可以详细看下</li>
<li>CachedThreadPool: 创建一个自适应线程池,当线程处于空闲1分钟时候,线程会被回收,当有新请求到来时候会创建新线程<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Executor <span class="title">getExecutor</span><span class="params">(URL url)</span> </span>&#123;</span><br><span class="line"> String name = url.getParameter(<span class="string">"threadname"</span>, <span class="string">"Dubbo"</span>);</span><br><span class="line"> <span class="keyword">int</span> cores = url.getParameter(<span class="string">"corethreads"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> threads = url.getParameter(<span class="string">"threads"</span>, <span class="number">2147483647</span>);</span><br><span class="line"> <span class="keyword">int</span> queues = url.getParameter(<span class="string">"queues"</span>, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> alive = url.getParameter(<span class="string">"alive"</span>, <span class="number">60000</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> ThreadPoolExecutor(cores, threads, (<span class="keyword">long</span>)alive, TimeUnit.MILLISECONDS, (BlockingQueue)(queues == <span class="number">0</span> ? <span class="keyword">new</span> SynchronousQueue() : (queues &lt; <span class="number">0</span> ? <span class="keyword">new</span> LinkedBlockingQueue() : <span class="keyword">new</span> LinkedBlockingQueue(queues))), <span class="keyword">new</span> NamedThreadFactory(name, <span class="keyword">true</span>), <span class="keyword">new</span> AbortPolicyWithReport(name, url));</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>
<li>CachedThreadPool: 创建一个自适应线程池,当线程处于空闲1分钟时候,线程会被回收,当有新请求到来时候会创建新线程<pre class="line-numbers language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token class-name">Executor</span> <span class="token function">getExecutor</span><span class="token punctuation">(</span><span class="token class-name">URL</span> url<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token class-name">String</span> name <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threadname"</span><span class="token punctuation">,</span> <span class="token string">"Dubbo"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> cores <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"corethreads"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> threads <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"threads"</span><span class="token punctuation">,</span> <span class="token number">2147483647</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> queues <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"queues"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">int</span> alive <span class="token operator">=</span> url<span class="token punctuation">.</span><span class="token function">getParameter</span><span class="token punctuation">(</span><span class="token string">"alive"</span><span class="token punctuation">,</span> <span class="token number">60000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ThreadPoolExecutor</span><span class="token punctuation">(</span>cores<span class="token punctuation">,</span> threads<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">long</span><span class="token punctuation">)</span>alive<span class="token punctuation">,</span> <span class="token class-name">TimeUnit</span><span class="token punctuation">.</span>MILLISECONDS<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token class-name">BlockingQueue</span><span class="token punctuation">)</span><span class="token punctuation">(</span>queues <span class="token operator">==</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">SynchronousQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token punctuation">(</span>queues <span class="token operator">&lt;</span> <span class="token number">0</span> <span class="token operator">?</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">new</span> <span class="token class-name">LinkedBlockingQueue</span><span class="token punctuation">(</span>queues<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">NamedThreadFactory</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">AbortPolicyWithReport</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> url<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
这里可以看到线程池的配置,核心是 0,最大线程数是 2147483647,保活时间是一分钟<br>只是非常简略的介绍下,有兴趣可以自行阅读代码。</li>
</ul>


+ 7
- 6
2021/04/11/聊聊厦门旅游的好与不好/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -32,10 +32,12 @@
<meta property="og:url" content="https://nicksxs.me/2021/04/11/%E8%81%8A%E8%81%8A%E5%8E%A6%E9%97%A8%E6%97%85%E6%B8%B8%E7%9A%84%E5%A5%BD%E4%B8%8E%E4%B8%8D%E5%A5%BD/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="这几天去了趟厦门,原来几年前就想去了,本来都请好假了,后面因为一些事情没去成,这次刚好公司组织,就跟 LD 一起去了厦门,也不洋洋洒洒地写游记了,后面可能会有,今天先来总结下好的地方和比较坑的地方。这次主要去了中山路、鼓浪屿、曾厝(cuo)垵、植物园、灵玲马戏团,因为住的离环岛路比较近,还有幸现场看了下厦门马拉松,其中 中山路这里看上去是有点民国时期的建筑风格,部分像那种电视里的租界啥的,不过这次">
<meta property="og:locale">
<meta property="article:published_time" content="2021-04-11T15:38:07.000Z">
<meta property="article:modified_time" content="2021-04-11T15:38:07.755Z">
<meta property="article:modified_time" content="2021-04-11T15:38:07.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="生活">
<meta property="article:tag" content="杭州">
<meta property="article:tag" content="旅游">
<meta property="article:tag" content="厦门">
<meta property="article:tag" content="中山路">
@ -44,7 +46,6 @@
<meta property="article:tag" content="曾厝垵">
<meta property="article:tag" content="植物园">
<meta property="article:tag" content="马戏团">
<meta property="article:tag" content="杭州">
<meta property="article:tag" content="沙茶面">
<meta property="article:tag" content="海蛎煎">
<meta name="twitter:card" content="summary">
@ -318,10 +319,10 @@
<div class="popular-posts-title"><a href="/2021/03/31/2020-年终总结/" rel="bookmark">2020 年终总结</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/08/16/周末我在老丈人家打了天小工/" rel="bookmark">周末我在老丈人家打了天小工</a></div>
<div class="popular-posts-title"><a href="/2020/12/20/从丁仲礼被美国制裁聊点啥/" rel="bookmark">从丁仲礼被美国制裁聊点啥</a></div>
</li>
<li class="popular-posts-item">
<div class="popular-posts-title"><a href="/2020/11/29/从清华美院学姐聊聊我们身边的恶人/" rel="bookmark">从清华美院学姐聊聊我们身边的恶人</a></div>
<div class="popular-posts-title"><a href="/2020/07/11/2020年中总结/" rel="bookmark">2020年中总结</a></div>
</li>
</ul>
@ -457,7 +458,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#中山路"><span class="nav-number">1.</span> <span class="nav-text">中山路</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#鼓浪屿"><span class="nav-number">2.</span> <span class="nav-text">鼓浪屿</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#曾厝垵"><span class="nav-number">3.</span> <span class="nav-text">曾厝垵</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#植物园"><span class="nav-number">4.</span> <span class="nav-text">植物园</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#灵玲马戏团"><span class="nav-number">5.</span> <span class="nav-text">灵玲马戏团</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#总结"><span class="nav-number">6.</span> <span class="nav-text">总结</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%AD%E5%B1%B1%E8%B7%AF"><span class="nav-number">1.</span> <span class="nav-text">中山路</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%BC%93%E6%B5%AA%E5%B1%BF"><span class="nav-number">2.</span> <span class="nav-text">鼓浪屿</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%9B%BE%E5%8E%9D%E5%9E%B5"><span class="nav-number">3.</span> <span class="nav-text">曾厝垵</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A4%8D%E7%89%A9%E5%9B%AD"><span class="nav-number">4.</span> <span class="nav-text">植物园</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%81%B5%E7%8E%B2%E9%A9%AC%E6%88%8F%E5%9B%A2"><span class="nav-number">5.</span> <span class="nav-text">灵玲马戏团</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%80%BB%E7%BB%93"><span class="nav-number">6.</span> <span class="nav-text">总结</span></a></li></ol></div>
</div>
<!--/noindex-->


+ 61
- 24
2021/04/18/rust学习笔记-所有权二/index.html View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 4.2.0">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
@ -26,12 +26,13 @@
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>
<meta name="description" content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 123456789fn main() &amp;#123; let s1 &#x3D; String::from(&quot;hello&quot;); let len &#x3D; calcu">
<meta name="description" content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 fn main() &amp;#123; let s1 &#x3D; String::from(&quot;hello&quot;); let len &#x3D; calculate_le">
<meta property="og:type" content="article">
<meta property="og:title" content="rust学习笔记-所有权二">
<meta property="og:url" content="https://nicksxs.me/2021/04/18/rust%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-%E6%89%80%E6%9C%89%E6%9D%83%E4%BA%8C/index.html">
<meta property="og:site_name" content="Nicksxs&#39;s Blog">
<meta property="og:description" content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 123456789fn main() &amp;#123; let s1 &#x3D; String::from(&quot;hello&quot;); let len &#x3D; calcu">
<meta property="og:description" content="这里需要说道函数和返回值了可以看书上的这个例子对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组 引用此时我们就可以用引用来解决这个问题 fn main() &amp;#123; let s1 &#x3D; String::from(&quot;hello&quot;); let len &#x3D; calculate_le">
<meta property="og:locale">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/fnlsui.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/6vBWwi.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/nniiIt.png">
@ -39,13 +40,12 @@
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/k3jjNn.png">
<meta property="og:image" content="https://gitee.com/nicksxs/images/raw/master/uPic/JtrXSW.png">
<meta property="article:published_time" content="2021-04-18T14:03:10.000Z">
<meta property="article:modified_time" content="2021-04-25T12:22:00.083Z">
<meta property="article:modified_time" content="2021-04-18T14:03:10.000Z">
<meta property="article:author" content="Nicksxs">
<meta property="article:tag" content="Rust">
<meta property="article:tag" content="所有权">
<meta property="article:tag" content="内存分布">
<meta property="article:tag" content="新语言">
<meta property="article:tag" content="引用">
<meta property="article:tag" content="可变引用">
<meta property="article:tag" content="不可变引用">
<meta name="twitter:card" content="summary">
@ -241,13 +241,6 @@
<time title="Created: 2021-04-18 22:03:10" itemprop="dateCreated datePublished" datetime="2021-04-18T22:03:10+08:00">2021-04-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2021-04-25 20:22:00" itemprop="dateModified" datetime="2021-04-25T20:22:00+08:00">2021-04-25</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
@ -301,24 +294,68 @@
<div class="post-body" itemprop="articleBody">
<p>这里需要说道函数和返回值了<br>可以看书上的这个例子<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/fnlsui.png" alt=""><br>对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/6vBWwi.png" alt=""></p>
<p>这里需要说道函数和返回值了<br>可以看书上的这个例子<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/fnlsui.png"><br>对于这种情况,当进入函数内部时,会把传入的变量的所有权转移进函数内部,如果最后还是要返回该变量,但是如果此时还要返回别的计算结果,就可能需要笨拙地使用元组<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/6vBWwi.png"></p>
<h3 id="引用"><a href="#引用" class="headerlink" title="引用"></a>引用</h3><p>此时我们就可以用引用来解决这个问题</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> s1 = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> <span class="keyword">let</span> len = calculate_length(&amp;s1);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">println!</span>(<span class="string">"The length of '&#123;&#125;' is &#123;&#125;"</span>, s1, len);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">calculate_length</span></span>(s: &amp;<span class="built_in">String</span>) -&gt; <span class="built_in">usize</span> &#123;</span><br><span class="line"> s.len()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这里的&amp;符号就是引用的语义,它们允许你在不获得所有权的前提下使用值<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/nniiIt.png" alt=""><br>由于引用不持有值的所有权,所以当引用离开当前作用域时,它指向的值也不会被丢弃</p>
<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> s1 <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> len <span class="token operator">=</span> <span class="token function">calculate_length</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token macro property">println!</span><span class="token punctuation">(</span><span class="token string">"The length of '&#123;&#125;' is &#123;&#125;"</span><span class="token punctuation">,</span> s1<span class="token punctuation">,</span> len<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">calculate_length</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token keyword">usize</span> <span class="token punctuation">&#123;</span>
s<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>这里的&amp;符号就是引用的语义,它们允许你在不获得所有权的前提下使用值<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/nniiIt.png"><br>由于引用不持有值的所有权,所以当引用离开当前作用域时,它指向的值也不会被丢弃</p>
<h3 id="可变引用"><a href="#可变引用" class="headerlink" title="可变引用"></a>可变引用</h3><p>而当我们尝试对引用的字符串进行修改时</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> s1 = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> change(&amp;s1);</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">change</span></span>(s: &amp;<span class="built_in">String</span>) &#123;</span><br><span class="line"> s.push_str(<span class="string">", world"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>就会有以下报错,<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/LVWURi.png" alt=""><br>其实也很容易发现,毕竟没有 mut 指出这是可变引用,同时需要将 s1 改成 mut 可变的</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut</span> s1 = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> change(&amp;<span class="keyword">mut</span> s1);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">change</span></span>(s: &amp;<span class="keyword">mut</span> <span class="built_in">String</span>) &#123;</span><br><span class="line"> s.push_str(<span class="string">", world"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> s1 <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">change</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>s1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">change</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
s<span class="token punctuation">.</span><span class="token function">push_str</span><span class="token punctuation">(</span><span class="token string">", world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>就会有以下报错,<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/LVWURi.png"><br>其实也很容易发现,毕竟没有 mut 指出这是可变引用,同时需要将 s1 改成 mut 可变的</p>
<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> s1 <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">change</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> s1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">change</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
s<span class="token punctuation">.</span><span class="token function">push_str</span><span class="token punctuation">(</span><span class="token string">", world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p>再看一个例子</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut</span> s1 = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> <span class="keyword">let</span> r1 = &amp;<span class="keyword">mut</span> s1;</span><br><span class="line"> <span class="keyword">let</span> r2 = &amp;<span class="keyword">mut</span> s1;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> s1 <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> r1 <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> s1<span class="token punctuation">;</span>
<span class="token keyword">let</span> r2 <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> s1<span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<p>这个例子在书里是会报错的,因为同时存在一个以上的可变引用,但是在我运行的版本里前面这段没有报错,只有当我真的要去更改的时候</p>
<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut</span> s1 = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut</span> r1 = &amp;<span class="keyword">mut</span> s1;</span><br><span class="line"> <span class="keyword">let</span> <span class="keyword">mut</span> r2 = &amp;<span class="keyword">mut</span> s1;</span><br><span class="line"> change(&amp;<span class="keyword">mut</span> r1);</span><br><span class="line"> change(&amp;<span class="keyword">mut</span> r2);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">change</span></span>(s: &amp;<span class="keyword">mut</span> <span class="built_in">String</span>) &#123;</span><br><span class="line"> s.push_str(<span class="string">", world"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/k3jjNn.png" alt=""><br>这里可能就是具体版本在实现上的一个差异,我用的 rustc 是 1.44.0 版本<br>其实上面的主要是由 rust 想要避免这类多重可变更导致的异常问题,总结下就是三个点</p>
<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> s1 <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> r1 <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> s1<span class="token punctuation">;</span>
<span class="token keyword">let</span> <span class="token keyword">mut</span> r2 <span class="token operator">=</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> s1<span class="token punctuation">;</span>
<span class="token function">change</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> r1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">change</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">mut</span> r2<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">change</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">String</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
s<span class="token punctuation">.</span><span class="token function">push_str</span><span class="token punctuation">(</span><span class="token string">", world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span><span aria-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></code></pre>
<p><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/k3jjNn.png"><br>这里可能就是具体版本在实现上的一个差异,我用的 rustc 是 1.44.0 版本<br>其实上面的主要是由 rust 想要避免这类多重可变更导致的异常问题,总结下就是三个点</p>
<ul>
<li>两个或两个以上的指针同时同时访问同一空间</li>
<li>其中至少有一个指针会想空间中写入数据</li>
<li>没有同步数据访问的机制<br>并且我们不能在拥有不可变引用的情况下创建可变引用<h3 id="悬垂引用"><a href="#悬垂引用" class="headerlink" title="悬垂引用"></a>悬垂引用</h3>还有一点需要注意的就是悬垂引用<figure class="highlight rust"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">main</span></span>() &#123;</span><br><span class="line"> <span class="keyword">let</span> reference_to_nothing = dangle();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">fn</span> <span class="title">dangle</span></span>() -&gt; &amp;<span class="built_in">String</span> &#123;</span><br><span class="line"> <span class="keyword">let</span> s = <span class="built_in">String</span>::from(<span class="string">"hello"</span>);</span><br><span class="line"> &amp;s</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
这里可以看到其实在 dangle函数返回后,这里的 s 理论上就离开了作用域,但是由于返回了 s 的引用,在 main 函数中就会拿着这个引用,就会出现如下错误<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/JtrXSW.png" alt=""><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3>最后总结下</li>
<li>没有同步数据访问的机制<br>并且我们不能在拥有不可变引用的情况下创建可变引用<h3 id="悬垂引用"><a href="#悬垂引用" class="headerlink" title="悬垂引用"></a>悬垂引用</h3>还有一点需要注意的就是悬垂引用<pre class="line-numbers language-rust" data-language="rust"><code class="language-rust"><span class="token keyword">fn</span> <span class="token function-definition function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> reference_to_nothing <span class="token operator">=</span> <span class="token function">dangle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">fn</span> <span class="token function-definition function">dangle</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">-></span> <span class="token operator">&amp;</span><span class="token class-name">String</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">let</span> s <span class="token operator">=</span> <span class="token class-name">String</span><span class="token punctuation">::</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">&amp;</span>s
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
这里可以看到其实在 dangle函数返回后,这里的 s 理论上就离开了作用域,但是由于返回了 s 的引用,在 main 函数中就会拿着这个引用,就会出现如下错误<br><img data-src="https://gitee.com/nicksxs/images/raw/master/uPic/JtrXSW.png"><h3 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h3>最后总结下</li>
<li>在任何一个段给定的时间里,你要么只能拥有一个可变引用,要么只能拥有任意数量的不可变引用。</li>
<li>引用总是有效的。</li>
</ul>
@ -462,7 +499,7 @@
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#引用"><span class="nav-number">1.</span> <span class="nav-text">引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#可变引用"><span class="nav-number">2.</span> <span class="nav-text">可变引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#悬垂引用"><span class="nav-number">3.</span> <span class="nav-text">悬垂引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#总结"><span class="nav-number">4.</span> <span class="nav-text">总结</span></a></li></ol></div>
<div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BC%95%E7%94%A8"><span class="nav-number">1.</span> <span class="nav-text">引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8F%AF%E5%8F%98%E5%BC%95%E7%94%A8"><span class="nav-number">2.</span> <span class="nav-text">可变引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%82%AC%E5%9E%82%E5%BC%95%E7%94%A8"><span class="nav-number">3.</span> <span class="nav-text">悬垂引用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%80%BB%E7%BB%93"><span class="nav-number">4.</span> <span class="nav-text">总结</span></a></li></ol></div>
</div>
<!--/noindex-->


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save