<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>𝓕𝓻𝓪𝓷𝓴.𝓗&#39;s blog</title>
  
  <subtitle>精力分配决定层次</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://hefengxian.github.io/"/>
  <updated>2020-07-28T01:03:37.343Z</updated>
  <id>https://hefengxian.github.io/</id>
  
  <author>
    <name>𝓕𝓻𝓪𝓷𝓴.𝓗</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>如何养成习惯性自律-潇峰学长的回答-阅读笔记</title>
    <link href="https://hefengxian.github.io/2020/07/28/%E5%A6%82%E4%BD%95%E5%85%BB%E6%88%90%E4%B9%A0%E6%83%AF%E6%80%A7%E8%87%AA%E5%BE%8B-%E6%BD%87%E5%B3%B0%E5%AD%A6%E9%95%BF%E7%9A%84%E5%9B%9E%E7%AD%94-%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/"/>
    <id>https://hefengxian.github.io/2020/07/28/如何养成习惯性自律-潇峰学长的回答-阅读笔记/</id>
    <published>2020-07-28T00:46:11.000Z</published>
    <updated>2020-07-28T01:03:37.343Z</updated>
    
    <content type="html"><![CDATA[<h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>笔记为阅读知乎问题《如何养成习惯性自律》潇峰学长的回答<a id="more"></a></p><ul><li>链接：<a href="https://www.zhihu.com/question/37226968/answer/620415603" target="_blank" rel="noopener">https://www.zhihu.com/question/37226968/answer/620415603</a></li><li>时间：2020-07-27 星期一</li><li>来源：知乎</li></ul><h2 id="内容"><a href="#内容" class="headerlink" title="内容"></a>内容</h2><p>回答分为 2 个部分，前半部分主要是讲他自己的经历，后半部分讲具体的方法和理论。</p><h3 id="作者的经历"><a href="#作者的经历" class="headerlink" title="作者的经历"></a>作者的经历</h3><p>看起来确实非常了不起；大二开始觉醒，到大四以系院第一毕业并且成功拿到剑桥 offer，讲述这期间的坚持与斗争。当然这里也提出一些没有说到的点，作者没有说明他之前的院校是什么，家庭的背景也没有交代；从描述来看，作者至少上的是一线大学，家庭条件比较优越，留学也并不是有成绩就够了的，经济实力也非常重要（这里作一个猜测，如果作者家境贫寒应该会将这些纳入写作，可以获得更好的效果）</p><p>自律的 7 个技巧</p><h3 id="相信自己可以做到自律"><a href="#相信自己可以做到自律" class="headerlink" title="相信自己可以做到自律"></a>相信自己可以做到自律</h3><p>“吹牛不犯法，牛皮先吹出来，吹着吹着你自己就信了，吹着吹着大家就信了，吹着吹着就不是牛皮了”</p><p>例如，每天开始早起去图书馆学习，这个行动会影响其他人对你的看法和反应，比如不会再约你一起熬夜吃鸡，然后他们的改观反过来增强我们的自律信念，在一轮一轮的正向循环中，自律从想法变成现实</p><h3 id="管理精力比管理时间重要"><a href="#管理精力比管理时间重要" class="headerlink" title="管理精力比管理时间重要"></a>管理精力比管理时间重要</h3><p>比如把每天的时间切成一块一块，精准的完成每一项；但这样往往忽略了结果，就像风靡一时的打卡，很多人打着打着就变成了为了打卡而打卡，成了一种形式主义</p><p>2/8 法则无处不在，80% 的成功往往来自 20% 的关键事件。张一鸣说：“更大的效率来自于重要的事情上做得好，而不是在处处做得好，管理精力比管理时间更重要”。自律的本质是提高效率而不是把每个小时都填满。</p><p>不要看起来很忙，做着没有目标的，没有意义的努力，不要用战术上的勤奋来掩盖战略上的懒惰，具体方法：四象限法</p><ol><li>重要、紧急<ul><li>处理方法：立即去做</li><li>饱和后果：压力无限增大、危机</li><li>原则：越少越好，很多第一象限的事情是因为它们在第二象限时没有被很好的利用</li></ul></li><li>重要、不紧急<ul><li>处理方法：有计划的去做</li><li>饱和后果：忙碌但是盲目</li><li>原则：集中精力处理，投资于第二象限，做好计划，先紧后松</li></ul></li><li>不重要、紧急<ul><li>处理方法：交给别人去做</li><li>饱和后果：忙碌且盲目</li><li>原则：放权给别人去做</li></ul></li><li>不重要、不紧急<ul><li>处理方法：尽量去做</li><li>饱和后果：浪费生命</li><li>原则：可当做调节身心，但是一定不能沉溺于这个象限</li></ul></li></ol><h3 id="健康饮食规律作息"><a href="#健康饮食规律作息" class="headerlink" title="健康饮食规律作息"></a>健康饮食规律作息</h3><p>这个其实几乎人人都知道，早起成功可以给你带来自律的成就感，提高一天的效率；简单粗暴的技巧：养成 11 点前上床的习惯，同时隔离手机</p><p>重要的事说三遍：<strong>不要把手机放在床的四周，不要把手机放在床的四周，不要把手机放在床的四周</strong></p><h3 id="意志力告急时想想你的长远目标"><a href="#意志力告急时想想你的长远目标" class="headerlink" title="意志力告急时想想你的长远目标"></a>意志力告急时想想你的长远目标</h3><p>人非圣贤，总有那么一些时刻，意志力会亮红灯</p><p>北极星指标 North Star Metric 又做 OMTM One metric that matters, 意思是唯一重要的指标，之所以叫北极星指标，是因为这个指标一旦确立，就像北极星一样，搞搞闪耀在天空中，绝不动摇，指引者你前进的方向。当你想要放弃的时候，可以想一想那些北极星一样的 Flag，往往可以给你重新打满鸡血</p><h3 id="延迟满足感"><a href="#延迟满足感" class="headerlink" title="延迟满足感"></a>延迟满足感</h3><p>“就等 10 分钟”，总有一些时刻，想要即时奖励的生理冲动让你是去理性，北极星也无法阻拦你了，这个时候延迟自己的满足感，等待 10 分钟，这是有魔力的 10 分钟，往往等了 10 分钟之后，内心开始慢慢的平复，突然就没有那么想去做这件事了</p><h3 id="避免影响你目标的因素"><a href="#避免影响你目标的因素" class="headerlink" title="避免影响你目标的因素"></a>避免影响你目标的因素</h3><p>当一件事的瘾特别大，屡屡打破自己的 flag，这个时候要避免影响你目标的因素；例如，打游戏瘾特别大，熔了自己的符文，刷微博瘾特别大，换一个老爷机，如果对甜品瘾特别大，那么原理甜品一切相关的东西</p><h3 id="自律是挣扎出来的"><a href="#自律是挣扎出来的" class="headerlink" title="自律是挣扎出来的"></a>自律是挣扎出来的</h3><p>罗·赫里克说：命运三女神等待着每一个罪恶；大姐是恐惧，二姐是耻辱，老三是内疚。</p><p>通往自律的道路不是一帆风顺的，过程中有很多起起伏伏。很多人做不到自律的根源是一受到打击就放弃了。他们不知道自律其实一次次挣扎出来的，最可怕的不是打破自律，而是因为<strong>内疚开始自暴自弃，陷入懊悔的深渊。</strong></p><p>一天早上起迟了，你就觉得一天都毁了，于是干脆什么都不干。一次忘记学了，你就觉得整个学习计划都毁了，于是干脆去浪浪浪</p><p>内疚带来的是内伤，抽走你整个人的精气，让你浑浑噩噩，让你心神俱疲。内疚是最没有生产力的事情。去内疚还不如调整心情，重新上路</p><h2 id="感想"><a href="#感想" class="headerlink" title="感想"></a>感想</h2><p>在写之前折腾了一系列的工具:</p><ul><li>手机</li><li>购买了代理工具（iOS Shadowrocket）</li><li>笔记软件（有道、为知）</li><li>顺带搞了一下 WIFI 共享（因为下载不动）</li></ul><p>这些事前后花了 3-4 个小时！其实这就已经犯了精力管理的错误了，没有把好钢用在刀刃上；这些本应该空闲的时候做的事，却花在了效率最好的时间段。</p><p>然后就陷入了第 7 条描述的问题，陷入内疚、懊悔的深渊。时间和精力就这么浪费了。</p><p>另外，每天晚上熬夜到很晚与把手机拿上床有很大的关系</p><blockquote><p>这个笔记应该经常来温习！给自己提个醒。</p></blockquote>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;概述&quot;&gt;&lt;a href=&quot;#概述&quot; class=&quot;headerlink&quot; title=&quot;概述&quot;&gt;&lt;/a&gt;概述&lt;/h2&gt;&lt;p&gt;笔记为阅读知乎问题《如何养成习惯性自律》潇峰学长的回答
    
    </summary>
    
      <category term="阅读笔记" scheme="https://hefengxian.github.io/categories/%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="自律" scheme="https://hefengxian.github.io/tags/%E8%87%AA%E5%BE%8B/"/>
    
      <category term="效率" scheme="https://hefengxian.github.io/tags/%E6%95%88%E7%8E%87/"/>
    
  </entry>
  
  <entry>
    <title>MySQL开启主从复制</title>
    <link href="https://hefengxian.github.io/2018/08/31/MySQL%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6/"/>
    <id>https://hefengxian.github.io/2018/08/31/MySQL主从复制/</id>
    <published>2018-08-31T08:32:13.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<h2 id="必要条件"><a href="#必要条件" class="headerlink" title="必要条件"></a>必要条件</h2><ul><li>在主库上要开启 bin log</li><li>从库的 server-id 必须和主库不一样</li><li>主库创建一个专门的主从复制的用户</li><li>从主库获得 binlog 的位置</li><li>从库设置同步</li></ul><p>创建用户<figure class="highlight sql"><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="keyword">CREATE</span> <span class="keyword">USER</span> <span class="string">'slave'</span>@<span class="string">'%'</span> <span class="keyword">IDENTIFIED</span> <span class="keyword">WITH</span> mysql_native_password <span class="keyword">BY</span> <span class="string">'password'</span>;</span><br><span class="line"><span class="keyword">GRANT</span> <span class="keyword">REPLICATION</span> <span class="keyword">SLAVE</span> <span class="keyword">ON</span> *.* <span class="keyword">TO</span> <span class="string">'slave'</span>@<span class="string">'%'</span>;</span><br></pre></td></tr></table></figure></p><p>获取 binlog 位置<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></pre></td><td class="code"><pre><span class="line"><span class="keyword">FLUSH</span> <span class="keyword">TABLES</span> <span class="keyword">WITH</span> <span class="keyword">READ</span> <span class="keyword">LOCK</span>;</span><br><span class="line"><span class="keyword">SHOW</span> <span class="keyword">MASTER</span> <span class="keyword">STATUS</span>;</span><br><span class="line"><span class="keyword">UNLOCK</span> <span class="keyword">TABLES</span>;</span><br></pre></td></tr></table></figure></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></pre></td><td class="code"><pre><span class="line"><span class="keyword">CHANGE</span> <span class="keyword">MASTER</span> <span class="keyword">TO</span></span><br><span class="line">    MASTER_HOST=<span class="string">'master_host_name'</span>,</span><br><span class="line">    MASTER_USER=<span class="string">'replication_user_name'</span>,</span><br><span class="line">    MASTER_PASSWORD=<span class="string">'replication_password'</span>,</span><br><span class="line">    MASTER_LOG_FILE=<span class="string">'recorded_log_file_name'</span>,</span><br><span class="line">    MASTER_LOG_POS=recorded_log_position;</span><br></pre></td></tr></table></figure></p><p>参考文档：</p><ul><li><a href="https://dev.mysql.com/doc/refman/8.0/en/replication-howto.html" target="_blank" rel="noopener">Setting Up Binary Log File Position Based Replication</a></li></ul><a id="more"></a>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;必要条件&quot;&gt;&lt;a href=&quot;#必要条件&quot; class=&quot;headerlink&quot; title=&quot;必要条件&quot;&gt;&lt;/a&gt;必要条件&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;在主库上要开启 bin log&lt;/li&gt;
&lt;li&gt;从库的 server-id 必须和主库不一样&lt;/li&gt;
&lt;li&gt;主库创建一个专门的主从复制的用户&lt;/li&gt;
&lt;li&gt;从主库获得 binlog 的位置&lt;/li&gt;
&lt;li&gt;从库设置同步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;创建用户
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;USER&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&#39;slave&#39;&lt;/span&gt;@&lt;span class=&quot;string&quot;&gt;&#39;%&#39;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;IDENTIFIED&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WITH&lt;/span&gt; mysql_native_password &lt;span class=&quot;keyword&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&#39;password&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;GRANT&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;REPLICATION&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;SLAVE&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;ON&lt;/span&gt; *.* &lt;span class=&quot;keyword&quot;&gt;TO&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&#39;slave&#39;&lt;/span&gt;@&lt;span class=&quot;string&quot;&gt;&#39;%&#39;&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;获取 binlog 位置
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;FLUSH&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;TABLES&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;WITH&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;READ&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;LOCK&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;SHOW&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;MASTER&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;STATUS&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;UNLOCK&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;TABLES&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;配置从库
&lt;figure class=&quot;highlight sql&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;CHANGE&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;MASTER&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;TO&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    MASTER_HOST=&lt;span class=&quot;string&quot;&gt;&#39;master_host_name&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    MASTER_USER=&lt;span class=&quot;string&quot;&gt;&#39;replication_user_name&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    MASTER_PASSWORD=&lt;span class=&quot;string&quot;&gt;&#39;replication_password&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    MASTER_LOG_FILE=&lt;span class=&quot;string&quot;&gt;&#39;recorded_log_file_name&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    MASTER_LOG_POS=recorded_log_position;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;参考文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/replication-howto.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Setting Up Binary Log File Position Based Replication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
      <category term="DB" scheme="https://hefengxian.github.io/categories/DB/"/>
    
    
      <category term="MySQL" scheme="https://hefengxian.github.io/tags/MySQL/"/>
    
      <category term="MySQL Replication" scheme="https://hefengxian.github.io/tags/MySQL-Replication/"/>
    
  </entry>
  
  <entry>
    <title>PHP7 编译安装 + pthreads 编译</title>
    <link href="https://hefengxian.github.io/2018/06/12/PHP7-%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85-pthreads-%E7%BC%96%E8%AF%91/"/>
    <id>https://hefengxian.github.io/2018/06/12/PHP7-编译安装-pthreads-编译/</id>
    <published>2018-06-12T12:36:59.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>编译环境 Ubuntu 18.04 LTS Server 版本，使用 <code>sudo lsb_release -a</code> 查看编译的 PHP 版本为 <code>7.2.6</code></p></blockquote><h2 id="Apache-安装"><a href="#Apache-安装" class="headerlink" title="Apache 安装"></a>Apache 安装</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install apache2 apache2-dev</span><br></pre></td></tr></table></figure><h2 id="构建环境"><a href="#构建环境" class="headerlink" title="构建环境"></a>构建环境</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install build-essential</span><br></pre></td></tr></table></figure><h2 id="获取源码"><a href="#获取源码" class="headerlink" title="获取源码"></a>获取源码</h2><p>去 PHP 官网 <a href="http://php.net/downloads.php" target="_blank" rel="noopener">http://php.net/downloads.php</a> 下载源码（可以选择离自己近的镜像），这里选择的是 <code>*.xz</code> 版本，体积更小</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wget http://hk2.php.net/get/php-7.2.6.tar.xz/from/this/mirror -O <span class="string">"php-7.2.6.tar.xz"</span></span><br></pre></td></tr></table></figure><p>解压：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">xz -d php-7.2.6.tar.xz</span><br><span class="line">tar -xvf php-7.2.6.tar</span><br></pre></td></tr></table></figure><p>这个时候可以得到源码的目录 <code>php-7.2.6/</code></p><h2 id="额外的依赖包"><a href="#额外的依赖包" class="headerlink" title="额外的依赖包"></a>额外的依赖包</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install libxml2-dev \</span><br><span class="line">libcurl4-openssl-dev \</span><br><span class="line">pkg-config \</span><br><span class="line">libssl-dev \</span><br><span class="line">libtidy-dev \</span><br><span class="line">libxslt1-dev \</span><br><span class="line">libreadline-dev</span><br></pre></td></tr></table></figure><blockquote><p>可能不同的机器、启用不同的 PHP 模块需要的依赖是不一样的，可以按照抛出的错误进行安装（也可以 Google 错误再安装），缺啥装啥！</p></blockquote><h2 id="构建"><a href="#构建" class="headerlink" title="构建"></a>构建</h2><p>准备编译 PHP，这里需要注意的是，CLI 需要多线程功能 <code>pthreads</code>，而 <code>pthreads</code> 是不支持 CGI 的（见项目说明 <a href="https://github.com/krakjoe/pthreads#sapi-support" target="_blank" rel="noopener">https://github.com/krakjoe/pthreads#sapi-support</a>）；所以要分开编译，分别指定不同的 <code>php.ini</code> 路径从而实现 CLI 单独配置 <code>pthreads</code> CGI 不需要</p><blockquote><p>开始踩了坑一起编译，使用统一的配置，导致 Apache 无法启动，查看 Apache 的配置却没有问题，最后看 <code>/var/log/apache2/error.log</code> 才知道是加载 PHP 模块的时候出错了（看文档要仔细！！！）</p></blockquote><h3 id="编译-PHP-CGI"><a href="#编译-PHP-CGI" class="headerlink" title="编译 PHP CGI"></a>编译 PHP CGI</h3><h4 id="configure"><a href="#configure" class="headerlink" title="configure"></a>configure</h4><p>编译参数和 CLI 的会有一点点区别，后面会给出相关的解释</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="comment"># CGI 不需要线程安全</span></span><br><span class="line"></span><br><span class="line">./configure --prefix=/opt/php \</span><br><span class="line">--<span class="built_in">enable</span>-calendar \</span><br><span class="line">--with-curl \</span><br><span class="line">--<span class="built_in">enable</span>-exif \</span><br><span class="line">--<span class="built_in">enable</span>-ftp \</span><br><span class="line">--with-gettext \</span><br><span class="line">--<span class="built_in">enable</span>-mbstring \</span><br><span class="line">--<span class="built_in">enable</span>-mysqlnd \</span><br><span class="line">--with-mysqli=mysqlnd \</span><br><span class="line">--with-pdo-mysql=mysqlnd \</span><br><span class="line">--with-oci8=instantclient,/opt/oracle/instantclient_12_1 \</span><br><span class="line">--with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1 \</span><br><span class="line">--with-openssl \</span><br><span class="line">--<span class="built_in">enable</span>-pcntl \</span><br><span class="line">--with-readline \</span><br><span class="line">--<span class="built_in">enable</span>-shmop \</span><br><span class="line">--<span class="built_in">enable</span>-sockets \</span><br><span class="line">--with-tidy \</span><br><span class="line">--<span class="built_in">enable</span>-wddx \</span><br><span class="line">--with-xsl \</span><br><span class="line">--with-xmlrpc \</span><br><span class="line">--<span class="built_in">enable</span>-zip \</span><br><span class="line">--with-zlib \</span><br><span class="line">--with-config-file-scan-dir=/opt/php/etc \</span><br><span class="line">--with-apxs2=/usr/bin/apxs2 \</span><br><span class="line">--with-config-file-path=/opt/php/cgi \</span><br><span class="line">--<span class="built_in">disable</span>-cli</span><br></pre></td></tr></table></figure><blockquote><p>如果自己输入模块请检查 <code>./configure</code> 运行完成之后有没有 Warnings 很有可能会拼写错误或者配置名字已经改变</p></blockquote><blockquote><p>使用将帮助信息 <code>./configure --help &gt; youfile.txt</code> 来进行对照查看比较方便</p></blockquote><blockquote><p>需要注意的是，这里配置了的模块是不需要再在 <code>php.ini</code> 配置的，相当于把这些模块打包进了 PHP 而不是从外部加载，如果强行配置可能会导致警告说在共享模块中找不到该模块</p></blockquote><blockquote><p><code>apxs2</code> 这个是 <code>apxs - APache eXtenSion tool</code> （使用 <code>man apxs2</code> 得到）可以通过 <code>whereis apxs2</code> 找到位置</p></blockquote><blockquote><p>指定 <code>--prefix</code> 在 <em>nix 是一个好习惯，方便卸载（</em>nix 和 Windows 在应用方面架构的差距！）</p></blockquote><h4 id="make"><a href="#make" class="headerlink" title="make"></a>make</h4><p>直接执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">make</span><br></pre></td></tr></table></figure><p>一般来说参数填写对了执行就不会有错误，看到最后出现了 <code>Build Complete</code> 就运行完了</p><blockquote><p>执行 <code>make</code> 的时候需要很长的时间等待使用 <code>htop</code> 查看资源使用情况；发现是单核跑的，经过查询 <code>make</code> 是可以实现多进程运行的，这样时间可以大大减少。</p></blockquote><blockquote><p>使用 <code>make -j8</code> （编译的机器 CPU 是 Core-i7 有 8 个逻辑核心所以使用 8 个进程，根据各自情况应该设置合适的数字）</p></blockquote><blockquote><p>如果是第二次或者多次运行 <code>make</code> 的时候，应该在运行 <code>make</code> 之前运行 <code>make clean</code>；否则可能会出现一些奇奇怪怪的错误</p></blockquote><h4 id="make-install"><a href="#make-install" class="headerlink" title="make install"></a>make install</h4><p><code>make</code> 执行完成之后，执行</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo make install</span><br></pre></td></tr></table></figure><p>一般从输出的信息中我们可以知道安装到了 <code>/opt/php</code> 下</p><blockquote><p>如果没有指定 <code>--prefix</code> ，可以在这里把输出重定向到一个文件，将来要彻底删除的时候有用</p></blockquote><h4 id="配置-php-ini"><a href="#配置-php-ini" class="headerlink" title="配置 php.ini"></a>配置 php.ini</h4><p>我们在配置里写了 <code>--with-config-file-path=/opt/php/cgi</code> 所以把源码目录下的 <code>php.ini-development</code> （也可以拷贝生产环境的） 拷贝到 <code>/opt/php/cgi/php.ini</code></p><h4 id="配置-PHP-到-Apache"><a href="#配置-PHP-到-Apache" class="headerlink" title="配置 PHP 到 Apache"></a>配置 PHP 到 Apache</h4><p>由于我们配置了 <code>--with-apxs2=/usr/bin/apxs2</code> Apache 需要的模块已经自动放好了，通过命令可以启用 PHP7 模块</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo a2enmod php7</span><br></pre></td></tr></table></figure><p>重启 Apache 这个时候发现，HTML 解析正常 PHP 却输出了源码，这表示 PHP 并没有被正确的解析。这个时候去 <code>/etc/apache2/mods-available/</code> 看发现只有 <code>php7.load</code> 没有发现 <code>php7.conf</code> （这里是通过对比我的 Ubuntu Desktop 发现的，上面是通过 <code>apt</code> 安装的）；当然经过搜索也有人在 Gist 中说了这个问题 <a href="https://gist.github.com/m1st0/1c41b8d0eb42169ce71a" target="_blank" rel="noopener">https://gist.github.com/m1st0/1c41b8d0eb42169ce71a</a>，所以在目录下创建文件 <code>php7.conf</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">sudo vim /etc/apache2/mods-available/php7.conf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 从 Ubuntu Desktop 的文件复制了如下内容</span></span><br><span class="line">&lt;FilesMatch <span class="string">".+\.ph(p[3457]?|t|tml)$"</span>&gt;</span><br><span class="line">    SetHandler application/x-httpd-php</span><br><span class="line">&lt;/FilesMatch&gt;</span><br><span class="line">&lt;FilesMatch <span class="string">".+\.phps$"</span>&gt;</span><br><span class="line">    SetHandler application/x-httpd-php-source</span><br><span class="line">    <span class="comment"># Deny access to raw php sources by default</span></span><br><span class="line">    <span class="comment"># To re-enable it's recommended to enable access to the files</span></span><br><span class="line">    <span class="comment"># only in specific virtual host or directory</span></span><br><span class="line">    Require all denied</span><br><span class="line">&lt;/FilesMatch&gt;</span><br><span class="line"><span class="comment"># Deny access to files without filename (e.g. '.php')</span></span><br><span class="line">&lt;FilesMatch <span class="string">"^\.ph(p[3457]?|t|tml|ps)$"</span>&gt;</span><br><span class="line">    Require all denied</span><br><span class="line">&lt;/FilesMatch&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># Running PHP scripts in user directories is disabled by default</span></span><br><span class="line"><span class="comment"># </span></span><br><span class="line"><span class="comment"># To re-enable PHP in user directories comment the following lines</span></span><br><span class="line"><span class="comment"># (from &lt;IfModule ...&gt; to &lt;/IfModule&gt;.) Do NOT set it to On as it</span></span><br><span class="line"><span class="comment"># prevents .htaccess files from disabling it.</span></span><br><span class="line">&lt;IfModule mod_userdir.c&gt;</span><br><span class="line">    &lt;Directory /home/*/public_html&gt;</span><br><span class="line">        php_admin_flag engine Off</span><br><span class="line">    &lt;/Directory&gt;</span><br><span class="line">&lt;/IfModule&gt;</span><br></pre></td></tr></table></figure><p>重新开启一下 PHP 扩展 <code>sudo a2enmod php7</code> 重启 Apache 发现 PHP 已经可以正常解析；到此 PHP CGI 编译完成！</p><h3 id="编译-PHP-CLI"><a href="#编译-PHP-CLI" class="headerlink" title="编译 PHP CLI"></a>编译 PHP CLI</h3><p>这里我们需要 <code>pthreads</code> 多线程支持（其实配置和 CGI 几乎可以通用，只要改动一下配置文件的位置参数）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="comment"># CLI 需要线程安全，要使用 pthreads，并且不需要 Apache 配置</span></span><br><span class="line"></span><br><span class="line">./configure --prefix=/opt/php \</span><br><span class="line">--<span class="built_in">enable</span>-calendar \</span><br><span class="line">--with-curl \</span><br><span class="line">--<span class="built_in">enable</span>-exif \</span><br><span class="line">--<span class="built_in">enable</span>-ftp \</span><br><span class="line">--with-gettext \</span><br><span class="line">--<span class="built_in">enable</span>-mbstring \</span><br><span class="line">--<span class="built_in">enable</span>-mysqlnd \</span><br><span class="line">--with-mysqli=mysqlnd \</span><br><span class="line">--with-pdo-mysql=mysqlnd \</span><br><span class="line">--with-oci8=instantclient,/opt/oracle/instantclient_12_1 \</span><br><span class="line">--with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1 \</span><br><span class="line">--with-openssl \</span><br><span class="line">--<span class="built_in">enable</span>-pcntl \</span><br><span class="line">--with-readline \</span><br><span class="line">--<span class="built_in">enable</span>-shmop \</span><br><span class="line">--<span class="built_in">enable</span>-sockets \</span><br><span class="line">--with-tidy \</span><br><span class="line">--<span class="built_in">enable</span>-wddx \</span><br><span class="line">--with-xsl \</span><br><span class="line">--with-xmlrpc \</span><br><span class="line">--<span class="built_in">enable</span>-zip \</span><br><span class="line">--with-zlib \</span><br><span class="line">--with-config-file-scan-dir=/opt/php/etc \</span><br><span class="line">--with-config-file-path=/opt/php/cli \</span><br><span class="line">--<span class="built_in">enable</span>-maintainer-zts \</span><br><span class="line">--<span class="built_in">disable</span>-cgi</span><br></pre></td></tr></table></figure><ul><li>去掉了 Apache 相关的配置 <code>apxs2</code></li><li>禁用 <code>cli</code> 改成了 <code>cgi</code></li><li>配置文件的路径改为 <code>/opt/php/cli</code></li></ul><p>其他的配置均保持一致，后面的步骤和上面一致，直到 <code>sudo make install</code> 完成，PHP CLI 部分也已经编译完成，不要忘了将 <code>php.ini</code> 拷贝一份到 <code>cli</code> 目录。</p><h4 id="建立符号链接"><a href="#建立符号链接" class="headerlink" title="建立符号链接"></a>建立符号链接</h4><p>使用符号连接我们可以直接在命令行中使用 <code>php</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ln --symbolic /opt/php/bin/php /usr/bin/php</span><br></pre></td></tr></table></figure><p>当然这里也可以把 <code>bin</code> 目录下的其他可执行文件进行设置，看个人需求</p><p>到这里基本上 PHP 已经编译好了并可以在命令行中使用了。</p><h2 id="编译-pthreads"><a href="#编译-pthreads" class="headerlink" title="编译 pthreads"></a>编译 pthreads</h2><p>PHP 的多线程特性不是官方实现的，这个项目在 <a href="https://github.com/krakjoe/pthreads" target="_blank" rel="noopener">Github</a></p><p>从页面上找到 master 分支的 zip 下载链接（clone 也可以）</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 下载</span></span><br><span class="line">wget https://github.com/krakjoe/pthreads/archive/master.zip -O pthreads-master.zip</span><br><span class="line"><span class="comment"># 解压</span></span><br><span class="line">unzip pthreads-master.zip</span><br><span class="line"><span class="comment"># 复制到 ext 目录下</span></span><br><span class="line">mv pthreads-master ext/pthreads</span><br><span class="line"><span class="comment"># 进入 pthreads 的目录</span></span><br><span class="line"><span class="built_in">cd</span> ext/pthreads/</span><br></pre></td></tr></table></figure><p>接下来运行 <code>phpize</code> 生成 <code>configure</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/opt/php/bin/phpize</span><br></pre></td></tr></table></figure><p>运行 <code>configure</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./configure --with-php-config=/opt/php/bin/php-config --prefix=/opt/php</span><br></pre></td></tr></table></figure><p>运行完成之后和上面一样的运行 <code>make &amp;&amp; make install</code>，这个时候应该会生成文件 <code>/opt/php/lib/php/extensions/no-debug-zts-20170718/pthreads.so</code></p><p>加载 <code>pthreads</code> 模块到 PHP，编辑 <code>php.ini</code></p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">sudo vim /opt/php/conf.d/php.ini</span><br><span class="line"></span><br><span class="line"><span class="comment"># 加入如下的行</span></span><br><span class="line">extension=pthread</span><br></pre></td></tr></table></figure><p>检查 PHP 已经加载的模块，使用 <code>php -m</code> 查看已经加载的模块列表，应该 <code>pthreads</code> 已经出现在列表中了</p><p>到此基本上所有的安装都完成了</p><a id="more"></a>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;编译环境 Ubuntu 18.04 LTS Server 版本，使用 &lt;code&gt;sudo lsb_release -a&lt;/code&gt; 查看
编译的 PHP 版本为 &lt;code&gt;7.2.6&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;Apache-安装&quot;&gt;&lt;a href=&quot;#Apache-安装&quot; class=&quot;headerlink&quot; title=&quot;Apache 安装&quot;&gt;&lt;/a&gt;Apache 安装&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo apt install apache2 apache2-dev&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;构建环境&quot;&gt;&lt;a href=&quot;#构建环境&quot; class=&quot;headerlink&quot; title=&quot;构建环境&quot;&gt;&lt;/a&gt;构建环境&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo apt install build-essential&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h2 id=&quot;获取源码&quot;&gt;&lt;a href=&quot;#获取源码&quot; class=&quot;headerlink&quot; title=&quot;获取源码&quot;&gt;&lt;/a&gt;获取源码&lt;/h2&gt;&lt;p&gt;去 PHP 官网 &lt;a href=&quot;http://php.net/downloads.php&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://php.net/downloads.php&lt;/a&gt; 下载源码（可以选择离自己近的镜像），这里选择的是 &lt;code&gt;*.xz&lt;/code&gt; 版本，体积更小&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;wget http://hk2.php.net/get/php-7.2.6.tar.xz/from/this/mirror -O &lt;span class=&quot;string&quot;&gt;&quot;php-7.2.6.tar.xz&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;解压：&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;xz -d php-7.2.6.tar.xz&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;tar -xvf php-7.2.6.tar&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这个时候可以得到源码的目录 &lt;code&gt;php-7.2.6/&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;额外的依赖包&quot;&gt;&lt;a href=&quot;#额外的依赖包&quot; class=&quot;headerlink&quot; title=&quot;额外的依赖包&quot;&gt;&lt;/a&gt;额外的依赖包&lt;/h2&gt;&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo apt install libxml2-dev \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;libcurl4-openssl-dev \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;pkg-config \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;libssl-dev \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;libtidy-dev \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;libxslt1-dev \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;libreadline-dev&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;可能不同的机器、启用不同的 PHP 模块需要的依赖是不一样的，可以按照抛出的错误进行安装（也可以 Google 错误再安装），缺啥装啥！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;构建&quot;&gt;&lt;a href=&quot;#构建&quot; class=&quot;headerlink&quot; title=&quot;构建&quot;&gt;&lt;/a&gt;构建&lt;/h2&gt;&lt;p&gt;准备编译 PHP，这里需要注意的是，CLI 需要多线程功能 &lt;code&gt;pthreads&lt;/code&gt;，而 &lt;code&gt;pthreads&lt;/code&gt; 是不支持 CGI 的（见项目说明 &lt;a href=&quot;https://github.com/krakjoe/pthreads#sapi-support&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/krakjoe/pthreads#sapi-support&lt;/a&gt;）；所以要分开编译，
分别指定不同的 &lt;code&gt;php.ini&lt;/code&gt; 路径从而实现 CLI 单独配置 &lt;code&gt;pthreads&lt;/code&gt; CGI 不需要&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;开始踩了坑一起编译，使用统一的配置，导致 Apache 无法启动，查看 Apache 的配置却没有问题，最后看 &lt;code&gt;/var/log/apache2/error.log&lt;/code&gt; 才知道是加载 PHP 模块的时候出错了（看文档要仔细！！！）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;编译-PHP-CGI&quot;&gt;&lt;a href=&quot;#编译-PHP-CGI&quot; class=&quot;headerlink&quot; title=&quot;编译 PHP CGI&quot;&gt;&lt;/a&gt;编译 PHP CGI&lt;/h3&gt;&lt;h4 id=&quot;configure&quot;&gt;&lt;a href=&quot;#configure&quot; class=&quot;headerlink&quot; title=&quot;configure&quot;&gt;&lt;/a&gt;configure&lt;/h4&gt;&lt;p&gt;编译参数和 CLI 的会有一点点区别，后面会给出相关的解释&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# CGI 不需要线程安全&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;./configure --prefix=/opt/php \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-calendar \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-curl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-exif \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-ftp \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-gettext \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-mbstring \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-mysqli=mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-pdo-mysql=mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-oci8=instantclient,/opt/oracle/instantclient_12_1 \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1 \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-openssl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-pcntl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-readline \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-shmop \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-sockets \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-tidy \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-wddx \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-xsl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-xmlrpc \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-zip \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-zlib \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-config-file-scan-dir=/opt/php/etc \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-apxs2=/usr/bin/apxs2 \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-config-file-path=/opt/php/cgi \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;disable&lt;/span&gt;-cli&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;blockquote&gt;
&lt;p&gt;如果自己输入模块请检查 &lt;code&gt;./configure&lt;/code&gt; 运行完成之后有没有 Warnings 很有可能会拼写错误或者配置名字已经改变&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;使用将帮助信息 &lt;code&gt;./configure --help &amp;gt; youfile.txt&lt;/code&gt; 来进行对照查看比较方便&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是，这里配置了的模块是不需要再在 &lt;code&gt;php.ini&lt;/code&gt; 配置的，相当于把这些模块打包进了 PHP 而不是从外部加载，如果强行配置可能会导致警告说在共享模块中找不到该模块&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;apxs2&lt;/code&gt; 这个是 &lt;code&gt;apxs - APache eXtenSion tool&lt;/code&gt; （使用 &lt;code&gt;man apxs2&lt;/code&gt; 得到）可以通过 &lt;code&gt;whereis apxs2&lt;/code&gt; 找到位置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;指定 &lt;code&gt;--prefix&lt;/code&gt; 在 &lt;em&gt;nix 是一个好习惯，方便卸载（&lt;/em&gt;nix 和 Windows 在应用方面架构的差距！）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;make&quot;&gt;&lt;a href=&quot;#make&quot; class=&quot;headerlink&quot; title=&quot;make&quot;&gt;&lt;/a&gt;make&lt;/h4&gt;&lt;p&gt;直接执行&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;make&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;一般来说参数填写对了执行就不会有错误，看到最后出现了 &lt;code&gt;Build Complete&lt;/code&gt; 就运行完了&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;执行 &lt;code&gt;make&lt;/code&gt; 的时候需要很长的时间等待使用 &lt;code&gt;htop&lt;/code&gt; 查看资源使用情况；发现是单核跑的，经过查询 &lt;code&gt;make&lt;/code&gt; 是可以实现多进程运行的，这样时间可以大大减少。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;使用 &lt;code&gt;make -j8&lt;/code&gt; （编译的机器 CPU 是 Core-i7 有 8 个逻辑核心所以使用 8 个进程，根据各自情况应该设置合适的数字）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果是第二次或者多次运行 &lt;code&gt;make&lt;/code&gt; 的时候，应该在运行 &lt;code&gt;make&lt;/code&gt; 之前运行 &lt;code&gt;make clean&lt;/code&gt;；否则可能会出现一些奇奇怪怪的错误&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;make-install&quot;&gt;&lt;a href=&quot;#make-install&quot; class=&quot;headerlink&quot; title=&quot;make install&quot;&gt;&lt;/a&gt;make install&lt;/h4&gt;&lt;p&gt;&lt;code&gt;make&lt;/code&gt; 执行完成之后，执行&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo make install&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;一般从输出的信息中我们可以知道安装到了 &lt;code&gt;/opt/php&lt;/code&gt; 下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果没有指定 &lt;code&gt;--prefix&lt;/code&gt; ，可以在这里把输出重定向到一个文件，将来要彻底删除的时候有用&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;配置-php-ini&quot;&gt;&lt;a href=&quot;#配置-php-ini&quot; class=&quot;headerlink&quot; title=&quot;配置 php.ini&quot;&gt;&lt;/a&gt;配置 php.ini&lt;/h4&gt;&lt;p&gt;我们在配置里写了 &lt;code&gt;--with-config-file-path=/opt/php/cgi&lt;/code&gt; 所以把源码目录下的 &lt;code&gt;php.ini-development&lt;/code&gt; （也可以拷贝生产环境的） 拷贝到 &lt;code&gt;/opt/php/cgi/php.ini&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;配置-PHP-到-Apache&quot;&gt;&lt;a href=&quot;#配置-PHP-到-Apache&quot; class=&quot;headerlink&quot; title=&quot;配置 PHP 到 Apache&quot;&gt;&lt;/a&gt;配置 PHP 到 Apache&lt;/h4&gt;&lt;p&gt;由于我们配置了 &lt;code&gt;--with-apxs2=/usr/bin/apxs2&lt;/code&gt; Apache 需要的模块已经自动放好了，通过命令可以启用 PHP7 模块&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo a2enmod php7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;重启 Apache 这个时候发现，HTML 解析正常 PHP 却输出了源码，这表示 PHP 并没有被正确的解析。这个时候去 &lt;code&gt;/etc/apache2/mods-available/&lt;/code&gt; 
看发现只有 &lt;code&gt;php7.load&lt;/code&gt; 没有发现 &lt;code&gt;php7.conf&lt;/code&gt; （这里是通过对比我的 Ubuntu Desktop 发现的，上面是通过 &lt;code&gt;apt&lt;/code&gt; 安装的）；
当然经过搜索也有人在 Gist 中说了这个问题 &lt;a href=&quot;https://gist.github.com/m1st0/1c41b8d0eb42169ce71a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gist.github.com/m1st0/1c41b8d0eb42169ce71a&lt;/a&gt;，
所以在目录下创建文件 &lt;code&gt;php7.conf&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo vim /etc/apache2/mods-available/php7.conf&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 从 Ubuntu Desktop 的文件复制了如下内容&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;FilesMatch &lt;span class=&quot;string&quot;&gt;&quot;.+\.ph(p[3457]?|t|tml)$&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    SetHandler application/x-httpd-php&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;/FilesMatch&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;FilesMatch &lt;span class=&quot;string&quot;&gt;&quot;.+\.phps$&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    SetHandler application/x-httpd-php-source&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;# Deny access to raw php sources by default&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;# To re-enable it&#39;s recommended to enable access to the files&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;comment&quot;&gt;# only in specific virtual host or directory&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    Require all denied&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;/FilesMatch&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Deny access to files without filename (e.g. &#39;.php&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;FilesMatch &lt;span class=&quot;string&quot;&gt;&quot;^\.ph(p[3457]?|t|tml|ps)$&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    Require all denied&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;/FilesMatch&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Running PHP scripts in user directories is disabled by default&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# &lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# To re-enable PHP in user directories comment the following lines&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# (from &amp;lt;IfModule ...&amp;gt; to &amp;lt;/IfModule&amp;gt;.) Do NOT set it to On as it&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# prevents .htaccess files from disabling it.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;IfModule mod_userdir.c&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;Directory /home/*/public_html&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        php_admin_flag engine Off&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;/Directory&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;lt;/IfModule&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;重新开启一下 PHP 扩展 &lt;code&gt;sudo a2enmod php7&lt;/code&gt; 重启 Apache 发现 PHP 已经可以正常解析；到此 PHP CGI 编译完成！&lt;/p&gt;
&lt;h3 id=&quot;编译-PHP-CLI&quot;&gt;&lt;a href=&quot;#编译-PHP-CLI&quot; class=&quot;headerlink&quot; title=&quot;编译 PHP CLI&quot;&gt;&lt;/a&gt;编译 PHP CLI&lt;/h3&gt;&lt;p&gt;这里我们需要 &lt;code&gt;pthreads&lt;/code&gt; 多线程支持（其实配置和 CGI 几乎可以通用，只要改动一下配置文件的位置参数）&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# CLI 需要线程安全，要使用 pthreads，并且不需要 Apache 配置&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;./configure --prefix=/opt/php \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-calendar \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-curl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-exif \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-ftp \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-gettext \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-mbstring \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-mysqli=mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-pdo-mysql=mysqlnd \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-oci8=instantclient,/opt/oracle/instantclient_12_1 \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1 \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-openssl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-pcntl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-readline \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-shmop \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-sockets \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-tidy \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-wddx \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-xsl \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-xmlrpc \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-zip \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-zlib \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-config-file-scan-dir=/opt/php/etc \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--with-config-file-path=/opt/php/cli \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;enable&lt;/span&gt;-maintainer-zts \&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;--&lt;span class=&quot;built_in&quot;&gt;disable&lt;/span&gt;-cgi&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;去掉了 Apache 相关的配置 &lt;code&gt;apxs2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;禁用 &lt;code&gt;cli&lt;/code&gt; 改成了 &lt;code&gt;cgi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置文件的路径改为 &lt;code&gt;/opt/php/cli&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他的配置均保持一致，后面的步骤和上面一致，直到 &lt;code&gt;sudo make install&lt;/code&gt; 完成，PHP CLI 部分也已经编译完成，不要忘了将 &lt;code&gt;php.ini&lt;/code&gt; 拷贝一份到 &lt;code&gt;cli&lt;/code&gt; 目录。&lt;/p&gt;
&lt;h4 id=&quot;建立符号链接&quot;&gt;&lt;a href=&quot;#建立符号链接&quot; class=&quot;headerlink&quot; title=&quot;建立符号链接&quot;&gt;&lt;/a&gt;建立符号链接&lt;/h4&gt;&lt;p&gt;使用符号连接我们可以直接在命令行中使用 &lt;code&gt;php&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo ln --symbolic /opt/php/bin/php /usr/bin/php&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;当然这里也可以把 &lt;code&gt;bin&lt;/code&gt; 目录下的其他可执行文件进行设置，看个人需求&lt;/p&gt;
&lt;p&gt;到这里基本上 PHP 已经编译好了并可以在命令行中使用了。&lt;/p&gt;
&lt;h2 id=&quot;编译-pthreads&quot;&gt;&lt;a href=&quot;#编译-pthreads&quot; class=&quot;headerlink&quot; title=&quot;编译 pthreads&quot;&gt;&lt;/a&gt;编译 pthreads&lt;/h2&gt;&lt;p&gt;PHP 的多线程特性不是官方实现的，这个项目在 &lt;a href=&quot;https://github.com/krakjoe/pthreads&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;从页面上找到 master 分支的 zip 下载链接（clone 也可以）&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 下载&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;wget https://github.com/krakjoe/pthreads/archive/master.zip -O pthreads-master.zip&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 解压&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;unzip pthreads-master.zip&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 复制到 ext 目录下&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;mv pthreads-master ext/pthreads&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 进入 pthreads 的目录&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;cd&lt;/span&gt; ext/pthreads/&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;接下来运行 &lt;code&gt;phpize&lt;/code&gt; 生成 &lt;code&gt;configure&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;/opt/php/bin/phpize&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;运行 &lt;code&gt;configure&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;./configure --with-php-config=/opt/php/bin/php-config --prefix=/opt/php&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;运行完成之后和上面一样的运行 &lt;code&gt;make &amp;amp;&amp;amp; make install&lt;/code&gt;，这个时候应该会生成文件 &lt;code&gt;/opt/php/lib/php/extensions/no-debug-zts-20170718/pthreads.so&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;加载 &lt;code&gt;pthreads&lt;/code&gt; 模块到 PHP，编辑 &lt;code&gt;php.ini&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;sudo vim /opt/php/conf.d/php.ini&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 加入如下的行&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;extension=pthread&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;检查 PHP 已经加载的模块，使用 &lt;code&gt;php -m&lt;/code&gt; 查看已经加载的模块列表，应该 &lt;code&gt;pthreads&lt;/code&gt; 已经出现在列表中了&lt;/p&gt;
&lt;p&gt;到此基本上所有的安装都完成了&lt;/p&gt;
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="Ubuntu" scheme="https://hefengxian.github.io/tags/Ubuntu/"/>
    
      <category term="PHP7" scheme="https://hefengxian.github.io/tags/PHP7/"/>
    
      <category term="pthreads" scheme="https://hefengxian.github.io/tags/pthreads/"/>
    
  </entry>
  
  <entry>
    <title>浅谈我国2018年的市场变化</title>
    <link href="https://hefengxian.github.io/2017/11/28/%E6%B5%85%E8%B0%88%E6%88%91%E5%9B%BD2018%E5%B9%B4%E7%9A%84%E5%B8%82%E5%9C%BA%E5%8F%98%E5%8C%96/"/>
    <id>https://hefengxian.github.io/2017/11/28/浅谈我国2018年的市场变化/</id>
    <published>2017-11-28T10:17:22.000Z</published>
    <updated>2020-07-27T09:57:42.151Z</updated>
    
    <content type="html"><![CDATA[<p>目测2018年我国市场上会发生以下翻天覆地的变化：</p><h3 id="一、-化妆品市场份额持续增长"><a href="#一、-化妆品市场份额持续增长" class="headerlink" title="一、 化妆品市场份额持续增长"></a>一、 化妆品市场份额持续增长</h3><p>化妆品市场份额持续增长。原因为：1.我国消费水平提高；2.化妆品以口红为引爆点在女性中掀起化妆风暴，培养了用户化妆消费习惯；3.化妆的潜在用户群在使用入门级化妆品后向更高端一点的化妆品升级。（第一点第二点的原因有很多类似点，可联系上下文一起看）</p><h3 id="二、-中高端消费品市场逐步复苏"><a href="#二、-中高端消费品市场逐步复苏" class="headerlink" title="二、 中高端消费品市场逐步复苏"></a>二、 中高端消费品市场逐步复苏</h3><p>中高端消费品市场逐步复苏，并由海淘市场慢慢回归国内市场。原因类似上文第一点，但更重要的一个原因是我国消费品自2017年12月1日起进口关税大幅度降低，由原来的平均17.3%降至7.7%，而化妆品的关税更是降至5%，此政策更是将直接影响国内化妆品销售额的上升（国内外价差缩小，从而吸引海淘、找代购者回流国内市场）。</p><h3 id="三、-跨界范围继续扩大"><a href="#三、-跨界范围继续扩大" class="headerlink" title="三、 跨界范围继续扩大"></a>三、 跨界范围继续扩大</h3><p>跨界范围继续扩大，且强弱吞并、强强联合将进一步发展。市场将不单单只是阿里和腾讯的角逐，更多有实力的公司或者风投将加入其中。</p><p>单拿支付市场来说，11月22日，中国移动、中信银行信用卡中心、网易考拉、丰巣、花间堂、罗森、什么值得买、小猪短租、翼支付等9家企业在杭州宣布共同成立“美好生活联盟”。而另一边，联通也在虎视眈眈，大力推广沃钱包，以及生活缴费、电子券等其他金融服务。同时，电信也没闲着，打着翼支付的名号卷土而来。虽然目前国内支付市场已经形成支付宝和微信支付两分天下的局面，但是通信三巨头手握直达每台智能手机主人的生命线这样一手好牌，后发力，能否分得一块蛋糕也未可知。与此同时，央行牵头成立的线上支付统一清算平台（业内简称“网联”）的方案也在蠢蠢欲动。</p><p>再来说说大热的医美、化妆品市场，又有几家能不想分一杯羹？全球最大的连锁便利店7-Eleven带着名为“Simply Me Beauty”的美妆线正式进军美妆领域。此外，以服装闻名的朗姿集团加快推进构建“泛时尚产业互联生态圈”的战略构想，提出了要在“女装、婴童、化妆品、医美”四大板块继续布局。7月15日，全国第一家苏宁易购汽车超市开业。11月26日，农夫泉及其所在的养生堂集团在杭州发布了养生堂天然桦树汁补水系列护肤品，包括含面膜、清爽型、滋润型化妆水，2018年还将推出精华、面霜等产品线。便利店、服装公司、</p><p>此外，10月份，苏宁汽车正式入局互联网造车领域。近日，苏宁易购汽车公司成立，其中野心可见一斑。再看打车领域滴滴独大，共享单车领域摩拜和OFO基本形成两分天下局面，阿里买下大润发36.16%股份……强强联合、强弱合并的案例随处可见，未来大公司的根将会越扎越深。</p><a id="more"></a>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;目测2018年我国市场上会发生以下翻天覆地的变化：&lt;/p&gt;
&lt;h3 id=&quot;一、-化妆品市场份额持续增长&quot;&gt;&lt;a href=&quot;#一、-化妆品市场份额持续增长&quot; class=&quot;headerlink&quot; title=&quot;一、 化妆品市场份额持续增长&quot;&gt;&lt;/a&gt;一、 化妆品市场份额持续增长&lt;/h3&gt;&lt;p&gt;化妆品市场份额持续增长。原因为：1.我国消费水平提高；2.化妆品以口红为引爆点在女性中掀起化妆风暴，培养了用户化妆消费习惯；3.化妆的潜在用户群在使用入门级化妆品后向更高端一点的化妆品升级。（第一点第二点的原因有很多类似点，可联系上下文一起看）&lt;/p&gt;
&lt;h3 id=&quot;二、-中高端消费品市场逐步复苏&quot;&gt;&lt;a href=&quot;#二、-中高端消费品市场逐步复苏&quot; class=&quot;headerlink&quot; title=&quot;二、 中高端消费品市场逐步复苏&quot;&gt;&lt;/a&gt;二、 中高端消费品市场逐步复苏&lt;/h3&gt;&lt;p&gt;中高端消费品市场逐步复苏，并由海淘市场慢慢回归国内市场。原因类似上文第一点，但更重要的一个原因是我国消费品自2017年12月1日起进口关税大幅度降低，由原来的平均17.3%降至7.7%，而化妆品的关税更是降至5%，此政策更是将直接影响国内化妆品销售额的上升（国内外价差缩小，从而吸引海淘、找代购者回流国内市场）。&lt;/p&gt;
&lt;h3 id=&quot;三、-跨界范围继续扩大&quot;&gt;&lt;a href=&quot;#三、-跨界范围继续扩大&quot; class=&quot;headerlink&quot; title=&quot;三、 跨界范围继续扩大&quot;&gt;&lt;/a&gt;三、 跨界范围继续扩大&lt;/h3&gt;&lt;p&gt;跨界范围继续扩大，且强弱吞并、强强联合将进一步发展。市场将不单单只是阿里和腾讯的角逐，更多有实力的公司或者风投将加入其中。&lt;/p&gt;
&lt;p&gt;单拿支付市场来说，11月22日，中国移动、中信银行信用卡中心、网易考拉、丰巣、花间堂、罗森、什么值得买、小猪短租、翼支付等9家企业在杭州宣布共同成立“美好生活联盟”。而另一边，联通也在虎视眈眈，大力推广沃钱包，以及生活缴费、电子券等其他金融服务。同时，电信也没闲着，打着翼支付的名号卷土而来。虽然目前国内支付市场已经形成支付宝和微信支付两分天下的局面，但是通信三巨头手握直达每台智能手机主人的生命线这样一手好牌，后发力，能否分得一块蛋糕也未可知。与此同时，央行牵头成立的线上支付统一清算平台（业内简称“网联”）的方案也在蠢蠢欲动。&lt;/p&gt;
&lt;p&gt;再来说说大热的医美、化妆品市场，又有几家能不想分一杯羹？全球最大的连锁便利店7-Eleven带着名为“Simply Me Beauty”的美妆线正式进军美妆领域。此外，以服装闻名的朗姿集团加快推进构建“泛时尚产业互联生态圈”的战略构想，提出了要在“女装、婴童、化妆品、医美”四大板块继续布局。7月15日，全国第一家苏宁易购汽车超市开业。11月26日，农夫泉及其所在的养生堂集团在杭州发布了养生堂天然桦树汁补水系列护肤品，包括含面膜、清爽型、滋润型化妆水，2018年还将推出精华、面霜等产品线。便利店、服装公司、&lt;/p&gt;
&lt;p&gt;此外，10月份，苏宁汽车正式入局互联网造车领域。近日，苏宁易购汽车公司成立，其中野心可见一斑。再看打车领域滴滴独大，共享单车领域摩拜和OFO基本形成两分天下局面，阿里买下大润发36.16%股份……强强联合、强弱合并的案例随处可见，未来大公司的根将会越扎越深。&lt;/p&gt;
    
    </summary>
    
      <category term="By 罗V" scheme="https://hefengxian.github.io/categories/By-%E7%BD%97V/"/>
    
    
      <category term="By 罗V" scheme="https://hefengxian.github.io/tags/By-%E7%BD%97V/"/>
    
  </entry>
  
  <entry>
    <title>第2章 - 算法分析</title>
    <link href="https://hefengxian.github.io/2017/09/16/data-structures-and-algorithm-analysis-in-c-02/"/>
    <id>https://hefengxian.github.io/2017/09/16/data-structures-and-algorithm-analysis-in-c-02/</id>
    <published>2017-09-16T15:11:05.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<p><strong>算法（algorithm）</strong> 是为求解一个问题需要遵循、被清楚地指定的简单指令集合。对于一个问题，一旦给定某种算法并且（以某种方式）确定其是正确的，那么重要的一步就是就是确定该算法将需要多少时间或空间等资源量的问题。如果一个问题的求解算法需要长达一年时间，那么这种算法就很难有什么用处。同样，一个需要 1GB内存的算法在当前的大多数机器上面也是没法使用的。</p><p>在这一章中将讨论：</p><ul><li>如何估计一个程序所需要的时间。</li><li>如何将一个程序的运行时间从天或年降低到秒</li><li>粗心使用递归的后果</li><li>将一个数自乘得到其幂以及计算两个数的最大公因数的非常有效的算法。</li></ul><a id="more"></a><h2 id="数学基础"><a href="#数学基础" class="headerlink" title="数学基础"></a>数学基础</h2><p><strong>定义</strong>：如果存在正常数 $c$ 和 $n_0$ 使得当 $N \geq n_o$ 时 $T(N) \leq cf(N)$，则记为 $T(N) = O(f(N))$</p><p><strong>定义</strong>：如果存在正常数 $c$ 和 $n_0$ 使得当 $N \geq n_o$ 时 $T(N) \geq cg(N)$，则记为 $T(N) = \Omega(g(N))$</p><p><strong>定义</strong>：$T(N) = \Theta(h(N))$ 当且仅当 $T(N) = O(h(N))$ 且 $T(N) = \Omega(h(N))$</p><p><strong>定义</strong>：如果 $T(N) = O(p(N))$ 且 $T(N) \neq \Theta(p(N))$ ， 则 $T(N) = o(p(N))$</p><p>这些定义的目的是要在函数之间建立一种相对的级别。给定两个函数，通常存在一些点，在这些点 上一个函数的值小于另一个函数的值，因此，像 $f(N) &lt; g(N)$ 这样的声明是没有意义的。 于是，我们比较它们的<strong>相对增长率（relative rate of growth）</strong>。当将相对增长率应用到算法分析的时候，我们将会明白为什么它是重要的度量。</p><p>虽然 $N$ 较小时，$1000N$ 要比 $N^2$，但 $N^2$ 以更快的速度增长，因此 $N^2$ 最终将更大。在这种情况下，$N = 1000$ 是转折点。第一个定义是说，最后总会存在某点 $n_0$，从它以后 $c \cdot f(N)$ 总是至少与 $T(N)$ 一样大，从而若忽略常数因子，则 $f(N)$ 至少与 $T(N)$ 一样大。在例子中，$T(N) = 1000N, f(N) = N^2, n_0 = 1000$ 而 $c = 1$。我们也可以让 $n_0 = 10$ 而 $c = 100$。因此，我们可以说 $1000N = O(N^2)$（$N$ 平方级）。这种记法称为大 $O$ 记法。常常不说“…级的”，而是说“大 $O$ …”</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;strong&gt;算法（algorithm）&lt;/strong&gt; 是为求解一个问题需要遵循、被清楚地指定的简单指令集合。对于一个问题，一旦给定某种算法并且（以某种方式）确定其是正确的，
那么重要的一步就是就是确定该算法将需要多少时间或空间等资源量的问题。如果一个问题的求解算法需要长达一年时间，那么这种算法就很难有什么用处。同样，一个需要 1GB
内存的算法在当前的大多数机器上面也是没法使用的。&lt;/p&gt;
&lt;p&gt;在这一章中将讨论：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何估计一个程序所需要的时间。&lt;/li&gt;
&lt;li&gt;如何将一个程序的运行时间从天或年降低到秒&lt;/li&gt;
&lt;li&gt;粗心使用递归的后果&lt;/li&gt;
&lt;li&gt;将一个数自乘得到其幂以及计算两个数的最大公因数的非常有效的算法。&lt;/li&gt;
&lt;/ul&gt;
    
    </summary>
    
      <category term="《数据结构与算法分析》笔记" scheme="https://hefengxian.github.io/categories/%E3%80%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90%E3%80%8B%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="数据结构与算法分析" scheme="https://hefengxian.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90/"/>
    
  </entry>
  
  <entry>
    <title>PHP json_decode 遇到的坑</title>
    <link href="https://hefengxian.github.io/2017/08/03/2017-08-02-Php-json-decode/"/>
    <id>https://hefengxian.github.io/2017/08/03/2017-08-02-Php-json-decode/</id>
    <published>2017-08-02T17:11:47.000Z</published>
    <updated>2020-07-27T09:57:42.148Z</updated>
    
    <content type="html"><![CDATA[<p>场景：某项目客户反馈，输出的结果 JSON 中有个要求为对象的数据字段，在某些情况下返回的是 <code>[]</code> 而不是 <code>{}</code>；数据由公司其他部门提供，查看原始数据的时候，没有发现任何问题；后来因为要加入某些预处理，在获取到其他部门的 JSON 数据之后进行解码并对某个字段进行处理；然而，在处理完之后再次使用 JSON 输出，发现结果已经不是我们想要的了。</p><p>原始数据<figure class="highlight"><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">&#123;</span><br><span class="line">  ...,</span><br><span class="line">  "foo": "",</span><br><span class="line">  "bar": &#123;&#125;,</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>其中 <code>foo</code> 是我要进行处理的字段，处理完成之后再次使用 <code>json_encode($data)</code> 进行 JSON 编码。</p><p>编码完成之后的结果却是这样的</p><figure class="highlight"><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">&#123;</span><br><span class="line">  ...,</span><br><span class="line">  "foo": "",</span><br><span class="line">  "bar": [],</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>空对象编程了空数组，而且我并没有处理过字段 <code>bar</code></p><p>通过对模拟数据的实测，发现是因为在对 JSON 进行解码的时候，是这么解的</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$data = json_decode($jsonString, <span class="keyword">true</span>)</span><br></pre></td></tr></table></figure><p>问题就出在这里，由于 PHP 自身的特性，在 PHP 中 <code>array</code> 是可以代表强类型语言，如 Java 中的 List 和 Map 的。</p><p>来看 PHP 中 <code>json_decode()</code> 方法是如何定义的</p><pre><code class="php">mixed json_decode ( string $json [, bool $assoc = <span class="keyword">false</span> [, int $depth = <span class="number">512</span> [, int $options = <span class="number">0</span> ]]] )</code></pre><blockquote><p>来源 <a href="http://php.net/manual/zh/function.json-decode.php" target="_blank" rel="noopener">http://php.net/manual/zh/function.json-decode.php</a></p></blockquote><p>当第二个参数 <code>$assoc</code> 为 <code>true</code> 时，返回的类型是 <code>array</code>，所以问题就来了，当 JSON 中空对象 <code>{}</code> 和 <code>[]</code> 空数组，使用这种方式解码出来的结果表现是一致的；即 <code>array()</code>；当再次 <code>json_encode()</code> 编码的时候就出现了 <code>{}</code> 变 <code>[]</code> 了。</p><p>所以正确的做法是在解码 JSON 的时候 <code>json_decode</code> 不要传递第二个参数；让解码结果是一个对象，然后操作对象的属性，操作完成之后再次编码就不会出现偏差。</p><p>这种问题最突出在于强类型语言和弱类型语言的 API 对接上，由于项目的下家是使用 Java 语言，所以导致了 BUG</p><a id="more"></a>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;场景：某项目客户反馈，输出的结果 JSON 中有个要求为对象的数据字段，在某些情况下返回的是 &lt;code&gt;[]&lt;/code&gt; 而不是 &lt;code&gt;{}&lt;/code&gt;；数据由公司其他部门提供，查看原始数据的时候，没有发现任何问题；后来因为要加入某些预处理，在获取到其他部门的 JSON 数据之后进行解码并对某个字段进行处理；然而，在处理完之后再次使用 JSON 输出，发现结果已经不是我们想要的了。&lt;/p&gt;
&lt;p&gt;原始数据
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  ...,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &quot;foo&quot;: &quot;&quot;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &quot;bar&quot;: &amp;#123;&amp;#125;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  ...&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;其中 &lt;code&gt;foo&lt;/code&gt; 是我要进行处理的字段，处理完成之后再次使用 &lt;code&gt;json_encode($data)&lt;/code&gt; 进行 JSON 编码。&lt;/p&gt;
&lt;p&gt;编码完成之后的结果却是这样的&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  ...,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &quot;foo&quot;: &quot;&quot;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  &quot;bar&quot;: [],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;  ...&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;空对象编程了空数组，而且我并没有处理过字段 &lt;code&gt;bar&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;通过对模拟数据的实测，发现是因为在对 JSON 进行解码的时候，是这么解的&lt;/p&gt;
&lt;figure class=&quot;highlight php&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;$data = json_decode($jsonString, &lt;span class=&quot;keyword&quot;&gt;true&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;问题就出在这里，由于 PHP 自身的特性，在 PHP 中 &lt;code&gt;array&lt;/code&gt; 是可以代表强类型语言，如 Java 中的 List 和 Map 的。&lt;/p&gt;
&lt;p&gt;来看 PHP 中 &lt;code&gt;json_decode()&lt;/code&gt; 方法是如何定义的&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;php&quot;&gt;mixed json_decode ( string $json [, bool $assoc = &lt;span class=&quot;keyword&quot;&gt;false&lt;/span&gt; [, int $depth = &lt;span class=&quot;number&quot;&gt;512&lt;/span&gt; [, int $options = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt; ]]] )
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;来源 &lt;a href=&quot;http://php.net/manual/zh/function.json-decode.php&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://php.net/manual/zh/function.json-decode.php&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当第二个参数 &lt;code&gt;$assoc&lt;/code&gt; 为 &lt;code&gt;true&lt;/code&gt; 时，返回的类型是 &lt;code&gt;array&lt;/code&gt;，所以问题就来了，当 JSON 中空对象 &lt;code&gt;{}&lt;/code&gt; 和 &lt;code&gt;[]&lt;/code&gt; 空数组，使用这种方式解码出来的结果表现是一致的；即 &lt;code&gt;array()&lt;/code&gt;；当再次 &lt;code&gt;json_encode()&lt;/code&gt; 编码的时候就出现了 &lt;code&gt;{}&lt;/code&gt; 变 &lt;code&gt;[]&lt;/code&gt; 了。&lt;/p&gt;
&lt;p&gt;所以正确的做法是在解码 JSON 的时候 &lt;code&gt;json_decode&lt;/code&gt; 不要传递第二个参数；让解码结果是一个对象，然后操作对象的属性，操作完成之后再次编码就不会出现偏差。&lt;/p&gt;
&lt;p&gt;这种问题最突出在于强类型语言和弱类型语言的 API 对接上，由于项目的下家是使用 Java 语言，所以导致了 BUG&lt;/p&gt;
    
    </summary>
    
      <category term="PHP" scheme="https://hefengxian.github.io/categories/PHP/"/>
    
    
      <category term="PHP" scheme="https://hefengxian.github.io/tags/PHP/"/>
    
  </entry>
  
  <entry>
    <title>nvm-npm加速</title>
    <link href="https://hefengxian.github.io/2017/03/26/nvm-npm%E5%8A%A0%E9%80%9F/"/>
    <id>https://hefengxian.github.io/2017/03/26/nvm-npm加速/</id>
    <published>2017-03-26T13:17:57.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<h2 id="NVM-加速"><a href="#NVM-加速" class="headerlink" title="NVM 加速"></a>NVM 加速</h2><p>安装 Node.js 一般都是用 <a href="https://github.com/creationix/nvm" target="_blank" rel="noopener">nvm</a></p><p>但是安装之后使用体验就不咋地了，由于某些不可变原因，国内网络就不好吐槽了；就连执行一下 <code>nvm ls-remote</code> 都要很久。</p><p>当然“道”高一尺“魔”高一丈，聪明的国人肯定也想出了对应的解决方案，就是建立了各种各样的镜像；比如淘宝源 <a href="https://npm.taobao.org/" target="_blank" rel="noopener">淘宝 NPM 镜像</a></p><p>所以加速 nvm 的方法就是使用 NPM 淘宝的 node.js 镜像。</p><h3 id="临时方案："><a href="#临时方案：" class="headerlink" title="临时方案："></a>临时方案：</h3><p>在运行 <code>nvm</code> 命令之前执行设置一个变量的命令</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node</span><br></pre></td></tr></table></figure><p>再执行 <code>nvm</code> 命令，那么速度就非常快了；这种方案就是每次使用你都要手工执行设置变量的命令，所以也就有了永久的方案。</p><h3 id="永久方案："><a href="#永久方案：" class="headerlink" title="永久方案："></a>永久方案：</h3><p>其实很简单，就是在 <code>.bashrc</code> 中加入上面的设置变量的命令，这样就可以保证每次一开机，系统就自动执行了这个命令了。</p><h2 id="NPM-加速"><a href="#NPM-加速" class="headerlink" title="NPM 加速"></a>NPM 加速</h2><p>如果在安装完 node 之后，使用 <code>npm install</code> 速度也是非常感人的；所以同样的我们也需要使用镜像来加速依赖的安装。</p><p>设置也比较简单，只需要设置 npm 的全局配置即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看默认的 registry 地址</span></span><br><span class="line">npm config -g get registry</span><br><span class="line">https://registry.npmjs.org/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置 npm 淘宝镜像</span></span><br><span class="line">npm config -g <span class="built_in">set</span> registry https://registry.npm.taobao.org</span><br></pre></td></tr></table></figure><p>这样设置之后安装就非常快了</p><a id="more"></a>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;NVM-加速&quot;&gt;&lt;a href=&quot;#NVM-加速&quot; class=&quot;headerlink&quot; title=&quot;NVM 加速&quot;&gt;&lt;/a&gt;NVM 加速&lt;/h2&gt;&lt;p&gt;安装 Node.js 一般都是用 &lt;a href=&quot;https://github.com/creationix/nvm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;nvm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但是安装之后使用体验就不咋地了，由于某些不可变原因，国内网络就不好吐槽了；就连执行一下 &lt;code&gt;nvm ls-remote&lt;/code&gt; 都要很久。&lt;/p&gt;
&lt;p&gt;当然“道”高一尺“魔”高一丈，聪明的国人肯定也想出了对应的解决方案，就是建立了各种各样的镜像；比如淘宝源 &lt;a href=&quot;https://npm.taobao.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;淘宝 NPM 镜像&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;所以加速 nvm 的方法就是使用 NPM 淘宝的 node.js 镜像。&lt;/p&gt;
&lt;h3 id=&quot;临时方案：&quot;&gt;&lt;a href=&quot;#临时方案：&quot; class=&quot;headerlink&quot; title=&quot;临时方案：&quot;&gt;&lt;/a&gt;临时方案：&lt;/h3&gt;&lt;p&gt;在运行 &lt;code&gt;nvm&lt;/code&gt; 命令之前执行设置一个变量的命令&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;再执行 &lt;code&gt;nvm&lt;/code&gt; 命令，那么速度就非常快了；这种方案就是每次使用你都要手工执行设置变量的命令，所以也就有了永久的方案。&lt;/p&gt;
&lt;h3 id=&quot;永久方案：&quot;&gt;&lt;a href=&quot;#永久方案：&quot; class=&quot;headerlink&quot; title=&quot;永久方案：&quot;&gt;&lt;/a&gt;永久方案：&lt;/h3&gt;&lt;p&gt;其实很简单，就是在 &lt;code&gt;.bashrc&lt;/code&gt; 中加入上面的设置变量的命令，这样就可以保证每次一开机，系统就自动执行了这个命令了。&lt;/p&gt;
&lt;h2 id=&quot;NPM-加速&quot;&gt;&lt;a href=&quot;#NPM-加速&quot; class=&quot;headerlink&quot; title=&quot;NPM 加速&quot;&gt;&lt;/a&gt;NPM 加速&lt;/h2&gt;&lt;p&gt;如果在安装完 node 之后，使用 &lt;code&gt;npm install&lt;/code&gt; 速度也是非常感人的；所以同样的我们也需要使用镜像来加速依赖的安装。&lt;/p&gt;
&lt;p&gt;设置也比较简单，只需要设置 npm 的全局配置即可&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 查看默认的 registry 地址&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;npm config -g get registry&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;https://registry.npmjs.org/&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 设置 npm 淘宝镜像&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;npm config -g &lt;span class=&quot;built_in&quot;&gt;set&lt;/span&gt; registry https://registry.npm.taobao.org&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这样设置之后安装就非常快了&lt;/p&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="https://hefengxian.github.io/categories/JavaScript/"/>
    
    
      <category term="npm" scheme="https://hefengxian.github.io/tags/npm/"/>
    
      <category term="nvm" scheme="https://hefengxian.github.io/tags/nvm/"/>
    
      <category term="node.js" scheme="https://hefengxian.github.io/tags/node-js/"/>
    
  </entry>
  
  <entry>
    <title>ES6学习笔记</title>
    <link href="https://hefengxian.github.io/2016/12/13/ES6%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    <id>https://hefengxian.github.io/2016/12/13/ES6学习笔记/</id>
    <published>2016-12-13T07:13:02.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<p>ES6（ECMAScript 6.0）已经使用了很久了，但是有很多的东西还是没有学会；学东西不应该浅尝而止，应该系统的学习；记录一些自己的理解。</p><p>笔记主要是依据阮一峰老师的教程<a href="http://es6.ruanyifeng.com/" target="_blank" rel="noopener">ECMAScript 6入门</a>学习所得<a id="more"></a></p><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><p>如何运行ES6代码呢？因为要测试和运行新的特性；所以并不需要转换代码到ES5，我们这里直接使用<code>Node.js</code>来运行我们的 ES6 编写的代码；安装<code>Node.js</code>可以使用<code>nvm</code>非常的方便（上Github搜索nvm）。</p><p>假设已经拥有如下的环境</p><ul><li>Ubuntu 16.04</li><li>Node.js v5.12.0</li></ul><p>直接使用<code>node path/to/*.js</code>命令运行如下代码<figure class="highlight js"><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="keyword">let</span> foo = <span class="string">"Hello ES6"</span></span><br><span class="line"><span class="built_in">console</span>.log(foo)</span><br></pre></td></tr></table></figure></p><p>会报如下错误<figure class="highlight xquery"><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">let</span> foo = <span class="string">"Hello ES6"</span></span><br><span class="line">^^^</span><br><span class="line"></span><br><span class="line">SyntaxError: Block-scoped declarations (<span class="keyword">let</span>, const, <span class="keyword">function</span>, class)<span class="built_in"> not</span> yet supported outside <span class="keyword">strict</span> mode</span><br><span class="line">    <span class="keyword">at</span> exports.runInThisContext (vm.js:<span class="number">53</span>:<span class="number">16</span>)</span><br><span class="line">    <span class="keyword">at</span> Module._compile (<span class="keyword">module</span>.js:<span class="number">387</span>:<span class="number">25</span>)</span><br><span class="line">    <span class="keyword">at</span> Object.Module._extensions..js (<span class="keyword">module</span>.js:<span class="number">422</span>:<span class="number">10</span>)</span><br><span class="line">    <span class="keyword">at</span> Module.load (<span class="keyword">module</span>.js:<span class="number">357</span>:<span class="number">32</span>)</span><br><span class="line">    <span class="keyword">at</span> Function.Module._load (<span class="keyword">module</span>.js:<span class="number">314</span>:<span class="number">12</span>)</span><br><span class="line">    <span class="keyword">at</span> Function.Module.runMain (<span class="keyword">module</span>.js:<span class="number">447</span>:<span class="number">10</span>)</span><br><span class="line">    <span class="keyword">at</span> startup (<span class="type">node</span>.js:<span class="number">148</span>:<span class="number">18</span>)</span><br><span class="line">    <span class="keyword">at</span> <span class="type">node</span>.js:<span class="number">405</span>:<span class="number">3</span></span><br></pre></td></tr></table></figure></p><p>提示说我们不能在非严格模式下使用<code>let, const, function, class</code>；所以我们在脚本修改一下<figure class="highlight js"><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="meta">"use strict"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> foo = <span class="string">"Hello ES6"</span></span><br><span class="line"><span class="built_in">console</span>.log(foo)</span><br></pre></td></tr></table></figure></p><p><del>这样就可以正确的运行 ES6 代码了，以后代码默认前面都加了<code>&quot;use strict&quot;</code></del></p><p><strong>已经将node升级为当前最新版<code>v7.2.1</code></strong></p><h2 id="let和const"><a href="#let和const" class="headerlink" title="let和const"></a>let和const</h2><h3 id="let"><a href="#let" class="headerlink" title="let"></a>let</h3><h4 id="基本用法"><a href="#基本用法" class="headerlink" title="基本用法"></a>基本用法</h4><p>ES6 新增的关键字，用法就是用于声明变量，和<code>var</code>类似；区别在于声明的变量是局部的，只在<code>let</code>所在的代码块内有效。</p><p>比如<code>for</code>循环的计数器就可以很适合使用<code>let</code><figure class="highlight js"><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">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt;= <span class="number">10</span>; i++) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(i)      <span class="comment">// 有效</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 如果使用的var声明将可以打印出 10</span></span><br><span class="line"><span class="built_in">console</span>.log(i)          <span class="comment">// 无效 ReferenceError</span></span><br></pre></td></tr></table></figure></p><h4 id="不存在变量提升"><a href="#不存在变量提升" class="headerlink" title="不存在变量提升"></a>不存在变量提升</h4><figure class="highlight js"><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="built_in">console</span>.log(foo)            <span class="comment">// undefined</span></span><br><span class="line"><span class="built_in">console</span>.log(bar)            <span class="comment">// ReferenceError: bar is not defined</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> foo</span><br><span class="line"><span class="keyword">let</span> bar</span><br></pre></td></tr></table></figure><p>上面代码中，<code>foo</code>用<code>var</code>声明，会发生变量提升，脚本开始运行的时，变量<code>foo</code>就已经存在了，只是没有值所以输出<code>undefined</code>；而使用<code>let</code>声明的变量并不会发生变量提升，所以在声明之前变量<code>bar</code>都是不存在的，这个时候使用它就会报错。</p><h4 id="暂时性死区（temporal-dead-zone-TDZ）"><a href="#暂时性死区（temporal-dead-zone-TDZ）" class="headerlink" title="暂时性死区（temporal dead zone, TDZ）"></a>暂时性死区（temporal dead zone, TDZ）</h4><p>只要块级作用域内，存在<code>let</code>命令，它声明的变量就是绑定（binding）在这个区域，不受外部影响<figure class="highlight js"><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="keyword">var</span> foo = <span class="number">123</span>           <span class="comment">// 全局变量</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(foo)    <span class="comment">// ReferenceError: foo is not defined</span></span><br><span class="line">    <span class="keyword">let</span> foo</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>ES6中规定，如果区块中存在<code>let</code>和<code>const</code>关键字，这个区块对这些关键字声明的变量从一开始就形成了封闭的作用域；如果在声明之前使用这个变量那么就会报错。<figure class="highlight js"><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">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">    <span class="comment">// 变量 foo 的 TDZ 开始</span></span><br><span class="line">    foo = <span class="number">123</span></span><br><span class="line">    <span class="built_in">console</span>.log(foo)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">let</span> foo = <span class="number">234</span>   <span class="comment">// 变量 foo 的 TDZ 结束</span></span><br><span class="line">    <span class="built_in">console</span>.log(foo)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>以前<code>typeof variable</code>是一个绝对安全的操作，现在有了 TDZ，这个操作就不再是绝对安全的操作了<figure class="highlight js"><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="keyword">typeof</span> foo      <span class="comment">// ReferenceError: bar is not defined</span></span><br><span class="line"><span class="keyword">let</span> foo</span><br></pre></td></tr></table></figure></p><p>有些 TDZ 还不容易发现，例如<figure class="highlight js"><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">function</span> <span class="title">foo</span>(<span class="params">x = y, y = <span class="number">2</span></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> [x, y]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(foo())  <span class="comment">// ReferenceError: y is not defined</span></span><br></pre></td></tr></table></figure></p><blockquote><p>发现这段代码并不能在node下运行，因为当前版本v5.12.0不能支持参数解构赋值；参见<a href="http://wwsun.github.io/posts/nodejs-v6.html" target="_blank" rel="noopener">Node V6支持的新特性</a>，所以这里升级一下（当前最新版已经是v7.2.1）<code>nvm install v7</code>安装最新的v7.2.1，<code>nvm alias default v7</code>设置默认的版本为v7.2.1；另外v7是不需要严格模式才能执行ES6代码了，直接写ES6代码既可</p></blockquote><p>因为在给<code>x</code>赋值的时候，<code>y</code>并没有定义；如果令<code>x = 2, y = x</code>这样就可以正常运行了<figure class="highlight js"><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">function</span> <span class="title">foo</span>(<span class="params">x = <span class="number">2</span>, y = x</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> [x, y]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(foo())      <span class="comment">// [ 2, 2 ]</span></span><br></pre></td></tr></table></figure></p><p>据说 ES6 这样做的目的是为了让大家养成良好的变成习惯（其实我是拒绝的！）</p><h4 id="不允许重复声明"><a href="#不允许重复声明" class="headerlink" title="不允许重复声明"></a>不允许重复声明</h4><figure class="highlight js"><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="comment">// SyntaxError: Identifier 'a' has already been declared</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> a = <span class="number">234</span></span><br><span class="line">    <span class="keyword">var</span> a = <span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// SyntaxError: Identifier 'a' has already been declared</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> a = <span class="number">123</span></span><br><span class="line">    <span class="keyword">let</span> a = <span class="number">34</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// SyntaxError: Identifier 'a' has already been declared</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">a</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> a = <span class="number">1</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 正确运行</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params">a</span>) </span>&#123;</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">let</span> a = <span class="number">123</span></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>ES5 只有全局作用域和函数作用域，没有块级作用域，这会带来一些不合理的问题</p><p>第一种，内层变量覆盖外层变量<figure class="highlight js"><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">var</span> foo = <span class="keyword">new</span> <span class="built_in">Date</span>()</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(foo)</span><br><span class="line">    <span class="keyword">if</span> (<span class="literal">false</span>) &#123;</span><br><span class="line">        <span class="keyword">var</span> foo = <span class="number">123</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">bar()       <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure></p><p>第二种，for循环中内层的变量泄露成全局变量<figure class="highlight js"><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="keyword">var</span> string = <span class="string">'Hello'</span></span><br><span class="line"><span class="keyword">var</span> arr = []</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; string.length; i++) &#123;</span><br><span class="line">    arr[i] = string[i]</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">console</span>.log(i)          <span class="comment">// 5</span></span><br></pre></td></tr></table></figure></p><h4 id="ES6的块级作用域"><a href="#ES6的块级作用域" class="headerlink" title="ES6的块级作用域"></a>ES6的块级作用域</h4><p><code>let</code>实际上为JavaScript增加了块级作用域<figure class="highlight js"><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">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> n = <span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">        <span class="keyword">let</span> n = <span class="number">10</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(n)      <span class="comment">// 1</span></span><br><span class="line">&#125;</span><br><span class="line">foo()</span><br></pre></td></tr></table></figure></p><p>ES6 允许块级作用域任意嵌套，不同块可以定义名称相同的变量<figure class="highlight js"><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">&#123;&#123;</span><br><span class="line">    &#123;<span class="keyword">let</span> i = <span class="number">1</span>&#125;</span><br><span class="line">    <span class="built_in">console</span>.log(i)  <span class="comment">// ReferenceError: i is not defined</span></span><br><span class="line">&#125;&#125;</span><br><span class="line"></span><br><span class="line">&#123;&#123;  <span class="keyword">let</span> i = <span class="number">2</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">let</span> i = <span class="number">1</span></span><br><span class="line">        <span class="built_in">console</span>.log(i)      <span class="comment">// 1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(i)          <span class="comment">// 2</span></span><br><span class="line">&#125;&#125;</span><br></pre></td></tr></table></figure></p><p>另外 ES6 的块级作用域的出现，使得广泛使用的“立即执行函数表达式 IIFE (Immediately Invoked Function Expression) ”不再必要了<figure class="highlight js"><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="comment">// IIFE 写法</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 逻辑</span></span><br><span class="line">&#125;())</span><br><span class="line"></span><br><span class="line"><span class="comment">// 块级作用域写法</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="comment">// 逻辑</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h4 id="do-表达式"><a href="#do-表达式" class="headerlink" title="do 表达式"></a>do 表达式</h4><p>不赘述，只是提案，Node.js v7 都不支持</p><h3 id="const关键字"><a href="#const关键字" class="headerlink" title="const关键字"></a>const关键字</h3><p><code>const</code>声明的是一个只读的常量。一旦声明值便不可以改动。因为<code>const</code>声明的值并不能改变，所以声明的时候必须初始化<figure class="highlight js"><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="keyword">const</span> PI = <span class="number">3.1415926</span></span><br><span class="line"><span class="built_in">console</span>.log(PI)     <span class="comment">// 3.1415926</span></span><br><span class="line">PI = <span class="number">3</span>              <span class="comment">// TypeError: Assignment to constant variable.</span></span><br><span class="line"><span class="keyword">const</span> MAX           <span class="comment">// SyntaxError: Missing initializer in const declaration</span></span><br></pre></td></tr></table></figure></p><p><code>const</code>的特点和<code>let</code>一样，只在声明的块级作用域中有效；<code>const</code>声明的变量也不会提升，所以也是存在 TDZ 的；不能重复声明</p><p>另外：如果<code>const</code>声明的变量是引用型数据，那么常量只是保证引用数据的地址不变而不能保证内容不变<figure class="highlight js"><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="keyword">const</span> ARR = []</span><br><span class="line">ARR.push(<span class="string">'Hello'</span>)</span><br><span class="line"><span class="built_in">console</span>.log(ARR)        <span class="comment">// [ 'Hello' ]</span></span><br><span class="line">ARR = []                <span class="comment">// TypeError: Assignment to constant variable.</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> OBJ = &#123;&#125;</span><br><span class="line">OBJ.age = <span class="number">20</span></span><br><span class="line"><span class="built_in">console</span>.log(OBJ.age)    <span class="comment">// 20</span></span><br><span class="line">OBJ = &#123;&#125;                <span class="comment">// TypeError: Assignment to constant variable.</span></span><br></pre></td></tr></table></figure></p><p>如果想将对象也冻结，应该使用<code>Object.freeze</code>方法<figure class="highlight js"><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">const</span> foo = <span class="built_in">Object</span>.freeze(&#123;&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 常规模式时，下面一行不起作用；</span></span><br><span class="line"><span class="comment">// 严格模式时，该行会报错</span></span><br><span class="line">foo.prop = <span class="number">123</span>;</span><br></pre></td></tr></table></figure></p><p>ES5 只有两种变量声明的方法：<code>var</code>和<code>function</code>关键字；ES6 却还添加了<code>let</code>,<code>const</code>,<code>import</code>,<code>class</code>；所以 ES6 一共有6种声明变量的方法</p><h3 id="顶层对象的属性"><a href="#顶层对象的属性" class="headerlink" title="顶层对象的属性"></a>顶层对象的属性</h3><p>顶层对象，在浏览器环境表示的是<code>window</code>对象，在node中表示<code>global</code>对象；在 ES5 中顶层对象的属性和全局变量是等价的<figure class="highlight js"><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="comment">// 在浏览器环境下</span></span><br><span class="line"><span class="built_in">window</span>.i = <span class="number">1</span></span><br><span class="line"><span class="built_in">console</span>.log(i)           <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line">i = <span class="number">2</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="built_in">window</span>.i)   <span class="comment">// 2</span></span><br></pre></td></tr></table></figure></p><p>ES6 改变了这一点；一方面规定，为了保持兼容性，<code>var</code>和<code>function</code>关键字声明的是全局变量，依旧是顶层对象的属性；另一方面规定，<code>let</code>，<code>const</code>，<code>class</code>声明的全局变量不属于顶层对象的属性。意味着ES越往后面走全局变量将逐渐和顶层对象的属性分离</p><h3 id="global对象"><a href="#global对象" class="headerlink" title="global对象"></a>global对象</h3><p>ES5 的顶层对象，本身也是一个问题，因为它在各种实现里不一致</p><ul><li>浏览器中，顶层对象是<code>window</code>，但 node 和 Web worker 中没有<code>window</code></li><li>浏览器和 Web Worker 里面，<code>self</code>也指向顶层对象，但是Node没有<code>self</code>。</li><li>Node 里面，顶层对象是<code>global</code>，但其他环境都不支持。</li></ul><p>ES6 中只是一个提案，不赘述。</p><h2 id="变量的解构赋值"><a href="#变量的解构赋值" class="headerlink" title="变量的解构赋值"></a>变量的解构赋值</h2><h3 id="基本用法-1"><a href="#基本用法-1" class="headerlink" title="基本用法"></a>基本用法</h3><p>ES6允许安装一定的模式，从数组和对象中提取值，对变量进行赋值，这杯称为解构（Destructuring），以前变量赋值只能这样<figure class="highlight js"><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">var</span> a = <span class="number">1</span></span><br><span class="line"><span class="keyword">var</span> b = <span class="number">2</span></span><br><span class="line"><span class="keyword">var</span> c = <span class="number">3</span></span><br></pre></td></tr></table></figure></p><p>ES6 中我们可以这样写<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> [a, b, c] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br></pre></td></tr></table></figure></p><p>本质上这种写法属于“模式匹配”，只要等号两边的模式相同，左边的变量就会被赋予对应的值；下面是一些解构赋值的例子<figure class="highlight js"><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">let</span> [foo, [[bar], baz]] = [<span class="number">1</span>, [[<span class="number">2</span>], <span class="number">3</span>]]</span><br><span class="line"><span class="built_in">console</span>.log(foo, bar, baz)                  <span class="comment">// 1 2 3</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [,, third] = [<span class="string">'A'</span>, <span class="string">'B'</span>, <span class="string">'C'</span>]</span><br><span class="line"><span class="built_in">console</span>.log(third)                          <span class="comment">// C</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [x, , y] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="built_in">console</span>.log(x, y)                           <span class="comment">// 1 3</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [head, ...tail] = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>]</span><br><span class="line"><span class="built_in">console</span>.log(head, tail)                     <span class="comment">// 1 [ 2, 3, 4, 5 ]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [i, j, ...k] = [<span class="string">'A'</span>]</span><br><span class="line"><span class="built_in">console</span>.log(i, j, k)                        <span class="comment">// A undefined []</span></span><br></pre></td></tr></table></figure></p><p>解构不成功，变量的值就会变成<code>undefined</code>；另外不完全解构，左边只是匹配右边一部分，这种情况依然是解构成功的。</p><p>如果等号右边不是可遍历的结构那么解构会报错。<figure class="highlight js"><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="keyword">let</span> [foo1] = <span class="number">1</span>              <span class="comment">// TypeError: undefined is not a function</span></span><br><span class="line"><span class="keyword">let</span> [foo2] = <span class="literal">false</span>          <span class="comment">// TypeError: undefined is not a function</span></span><br><span class="line"><span class="keyword">let</span> [foo3] = <span class="literal">NaN</span>            <span class="comment">// TypeError: undefined is not a function</span></span><br><span class="line"><span class="keyword">let</span> [foo4] = <span class="literal">undefined</span>      <span class="comment">// TypeError: undefined is not a function</span></span><br><span class="line"><span class="keyword">let</span> [foo5] = <span class="literal">null</span>           <span class="comment">// TypeError: undefined is not a function</span></span><br><span class="line"><span class="keyword">let</span> [foo6] = &#123;&#125;             <span class="comment">// TypeError: undefined is not a function</span></span><br></pre></td></tr></table></figure></p><p>因为右边的值要么不具备Iterator接口（最后 1 个），要么就是转成对象之后不具备Iterator接口（前面 5 个）。另外解构适用于<code>var</code>、<code>let</code>、<code>const</code>。</p><p>对于Set结构，也可以使用数组解构赋值。事实上只要某种数据具有 Iterator 接口，都可以采用数组形式的结构赋值。<figure class="highlight js"><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="comment">// Generator 写法</span></span><br><span class="line"><span class="function"><span class="keyword">function</span>* <span class="title">fibs</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> a = <span class="number">0</span>,</span><br><span class="line">        b = <span class="number">1</span></span><br><span class="line">    <span class="keyword">while</span> (<span class="literal">true</span>) &#123;</span><br><span class="line">        <span class="keyword">yield</span> a;                    <span class="comment">// 不知道为啥这里一定要加分好才能生效</span></span><br><span class="line">        [a, b] = [b, a + b]</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">let</span> [first, second, third, fourth, fifth, sixth, seven] = fibs()</span><br><span class="line"><span class="built_in">console</span>.log(first, second, third, fourth, fifth, sixth, seven)</span><br></pre></td></tr></table></figure></p><h3 id="默认值"><a href="#默认值" class="headerlink" title="默认值"></a>默认值</h3><p>结构赋值允许指定默认值<figure class="highlight js"><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">let</span> [a, b = <span class="string">'y'</span>] = [<span class="string">'x'</span>],</span><br><span class="line">    [foo = <span class="literal">true</span>] = []</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(a, b, foo);             <span class="comment">// x y true</span></span><br><span class="line"></span><br><span class="line">[a, b = <span class="string">'a'</span>] = [<span class="string">'b'</span>, <span class="literal">undefined</span>]</span><br><span class="line"><span class="built_in">console</span>.log(a, b)                   <span class="comment">// b a</span></span><br></pre></td></tr></table></figure></p><p>另外，ES6 内部使用严格相等运算符 <code>===</code>，所以如果不是严格等于<code>undefined</code>默认值是不会生效的。比如<code>null</code>是可以正确赋值的，默认值不会生效。</p><p>如果默认值是一个表达式，那么这个表达式是惰性求职的，再用到的时候才会求值<figure class="highlight js"><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">function</span> <span class="title">f</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'f() is executed.'</span>)</span><br><span class="line">    <span class="keyword">return</span> <span class="string">'Hello'</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [a = f()] = [<span class="string">'World'</span>]</span><br><span class="line"><span class="built_in">console</span>.log(a)      <span class="comment">// World</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [b = f()] = [<span class="literal">undefined</span>]</span><br><span class="line"><span class="built_in">console</span>.log(b)</span><br><span class="line"><span class="comment">// f() is executed.</span></span><br><span class="line"><span class="comment">// Hello</span></span><br></pre></td></tr></table></figure></p><p>默认值可以引用结构赋值的其他变量，但是被引用的变量必须已经声明<figure class="highlight js"><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="keyword">let</span> [x = <span class="number">1</span>, y = x] = [];     <span class="comment">// x=1; y=1</span></span><br><span class="line"><span class="keyword">let</span> [x = <span class="number">1</span>, y = x] = [<span class="number">2</span>];    <span class="comment">// x=2; y=2</span></span><br><span class="line"><span class="keyword">let</span> [x = <span class="number">1</span>, y = x] = [<span class="number">1</span>, <span class="number">2</span>]; <span class="comment">// x=1; y=2</span></span><br><span class="line"><span class="keyword">let</span> [x = y, y = <span class="number">1</span>] = [];     <span class="comment">// ReferenceError</span></span><br></pre></td></tr></table></figure></p><h3 id="对象的结构赋值"><a href="#对象的结构赋值" class="headerlink" title="对象的结构赋值"></a>对象的结构赋值</h3><p>对象也可以用于对象，不同之处在于，数组必须按顺序赋值，对应的位置赋值对应的位置；而对象只需要属性名相同，就可以正确赋值。<figure class="highlight js"><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">let</span> &#123;foo, bar&#125; = &#123;<span class="attr">bar</span>: <span class="string">'World'</span>, <span class="attr">foo</span>: <span class="string">'Hello'</span>&#125;</span><br><span class="line"><span class="built_in">console</span>.log(foo, bar)       <span class="comment">// Hello World</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123;baz&#125; = &#123;<span class="attr">bar</span>: <span class="string">'World'</span>, <span class="attr">foo</span>: <span class="string">'Hello'</span>&#125;</span><br><span class="line"><span class="built_in">console</span>.log(baz)            <span class="comment">// undefined</span></span><br></pre></td></tr></table></figure></p><p>如果变量名和属性名不一致，应该写成如下这样<figure class="highlight js"><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="keyword">let</span> &#123;<span class="attr">foo</span>: f, <span class="attr">bar</span>: b&#125; = &#123;<span class="attr">bar</span>: <span class="string">'World'</span>, <span class="attr">foo</span>: <span class="string">'Hello'</span>&#125;</span><br><span class="line"><span class="built_in">console</span>.log(f, b)           <span class="comment">// Hello World</span></span><br></pre></td></tr></table></figure></p><p>这就说明对象解构赋值就是下面形式的简写<figure class="highlight js"><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="keyword">let</span> &#123;<span class="attr">foo</span>: foo, <span class="attr">bar</span>: bar&#125; = &#123;<span class="attr">bar</span>: <span class="string">'World'</span>, <span class="attr">foo</span>: <span class="string">'Hello'</span>&#125;</span><br><span class="line"><span class="built_in">console</span>.log(foo, bar)           <span class="comment">// Hello World</span></span><br></pre></td></tr></table></figure></p><p>也就是说，对象的结构赋值的内部机制，是先找到同名属性，然后再给对应的变量赋值，真正被赋值的是后者，而不是前者。<figure class="highlight js"><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">let</span> &#123;<span class="attr">foo</span>: bar&#125; = &#123;<span class="attr">foo</span>: <span class="string">'aaa'</span>, <span class="attr">bar</span>: <span class="string">'bbb'</span>&#125;</span><br><span class="line"><span class="built_in">console</span>.log(bar)            <span class="comment">// aaa</span></span><br><span class="line"><span class="built_in">console</span>.log(foo)            <span class="comment">// ReferenceError: foo is not defined</span></span><br></pre></td></tr></table></figure></p><p>采用这种写法的时候，变量的声明和赋值的一体的，<code>let</code> 和 <code>const</code>来说，变量不能重复声明，如果赋值的变量以前声明过，就会报错。<figure class="highlight js"><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">let</span> foo</span><br><span class="line"><span class="keyword">let</span> &#123;foo&#125; = &#123;<span class="attr">foo</span>: <span class="number">1</span>&#125;            <span class="comment">// Identifier 'foo' has already been declared</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> baz</span><br><span class="line"><span class="keyword">let</span> &#123;<span class="attr">bar</span>: baz&#125; = &#123;<span class="attr">bar</span>: <span class="number">1</span>&#125;       <span class="comment">// Identifier 'baz' has already been declared</span></span><br></pre></td></tr></table></figure></p><p><code>var</code>命令允许重复声明，则没有这个问题</p><figure class="highlight js"><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">let</span> foo</span><br><span class="line">(&#123;foo&#125; = &#123;<span class="attr">foo</span>: <span class="number">1</span>&#125;)      <span class="comment">// 括号是必须的，否则&#123;&#125;会被认为是代码块</span></span><br><span class="line"><span class="built_in">console</span>.log(foo)        <span class="comment">// 1</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> baz</span><br><span class="line">(&#123;<span class="attr">bar</span>: baz&#125; = &#123;<span class="attr">bar</span>: <span class="number">1</span>&#125;)</span><br><span class="line"><span class="built_in">console</span>.log(baz)        <span class="comment">// 1</span></span><br></pre></td></tr></table></figure><p>括号是必须的，否则会报错，因为解析器将会把开头的大括号理解成一个代码块。</p><p>另外，和数组一样，结构也可以用于嵌套结构的对象<figure class="highlight js"><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="keyword">let</span> obj = &#123;</span><br><span class="line">    p: [</span><br><span class="line">        <span class="string">'hello'</span>,</span><br><span class="line">        &#123;<span class="attr">y</span>: <span class="string">'world'</span>&#125;</span><br><span class="line">    ]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123;<span class="attr">p</span>: [x, &#123;y&#125;]&#125; = obj</span><br><span class="line"><span class="built_in">console</span>.log(x, y)       <span class="comment">// hello world</span></span><br></pre></td></tr></table></figure></p><p>注意，这时<code>p</code>是模式，不是变量，因此不会被赋值。</p><p>另外对象解构也可以指定默认值，依然使用严格属性等于<code>undefined</code>来判断是否赋值；解构失败变量的值就是<code>undefined</code></p><p>如果要将一个已经声明的变量用于结构赋值，就需要加上圆括号，和上面一样，开始的大括号会被解析成代码块</p><p>对象的解构赋值，可以很方便的将现有对象的方法，赋值到某个变量。<figure class="highlight js"><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">let</span> &#123;log, sin, cos, pow&#125; = <span class="built_in">Math</span></span><br><span class="line"><span class="built_in">console</span>.log(log(pow(<span class="built_in">Math</span>.E, <span class="number">20</span>)))       <span class="comment">// 2</span></span><br><span class="line"><span class="built_in">console</span>.log(sin(<span class="built_in">Math</span>.PI / <span class="number">2</span>))           <span class="comment">// 1</span></span><br></pre></td></tr></table></figure></p><p>由于数组的 本质是特殊的对象，因此对数组进行对象属性的解构。<figure class="highlight js"><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">let</span> arr = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line"><span class="keyword">let</span> &#123;<span class="number">0</span>: f, [arr.length - <span class="number">1</span>]: l&#125; = arr</span><br><span class="line"><span class="built_in">console</span>.log(f, l)       <span class="comment">// 1 3</span></span><br></pre></td></tr></table></figure></p><p>另外：方括号这种写法，属于“属性名表达式”</p><h3 id="字符串解构赋值"><a href="#字符串解构赋值" class="headerlink" title="字符串解构赋值"></a>字符串解构赋值</h3><p>字符串也可以解构赋值，字符串被转换成了一个类似数组的对象。<figure class="highlight js"><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="keyword">let</span> [a, b, c, d, e] = <span class="string">'hello'</span></span><br><span class="line"><span class="built_in">console</span>.log(a, b, c, d, e)      <span class="comment">// h e l l o</span></span><br></pre></td></tr></table></figure></p><p>数组对象还有一个<code>length</code>对象，因此还可以对象解构赋值。<figure class="highlight js"><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="keyword">let</span> &#123;<span class="attr">length</span>: foo&#125; = <span class="string">'hello'</span></span><br><span class="line"><span class="built_in">console</span>.log(foo)        <span class="comment">// 5</span></span><br></pre></td></tr></table></figure></p><h3 id="数值和布尔值的解构赋值"><a href="#数值和布尔值的解构赋值" class="headerlink" title="数值和布尔值的解构赋值"></a>数值和布尔值的解构赋值</h3><p>解构赋值时，如果等号右边是数值和布尔值，则会首先转换为对象。<figure class="highlight js"><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">let</span> &#123;<span class="attr">toString</span>: s&#125; = <span class="number">123</span></span><br><span class="line"><span class="built_in">console</span>.log(s === <span class="built_in">Number</span>.prototype.toString)        <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(s)                                      <span class="comment">// [Function: toString]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123;<span class="attr">toString</span>: t&#125; = <span class="literal">true</span></span><br><span class="line"><span class="built_in">console</span>.log(t === <span class="built_in">Boolean</span>.prototype.toString)       <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(t)                                      <span class="comment">// [Function: toString]</span></span><br></pre></td></tr></table></figure></p><p>解构赋值的规则是，只要等号的右边的值不是对象，就先将其转换为对象。由于<code>undefined</code>和<code>null</code>无法转换为对象，所以对他们进行结构赋值都会报错。<figure class="highlight js"><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="keyword">let</span> &#123;<span class="attr">prop</span>: x&#125; = <span class="literal">undefined</span>       <span class="comment">// Cannot match against 'undefined' or 'null'.</span></span><br><span class="line"><span class="keyword">let</span> &#123;<span class="attr">prop</span>: y&#125; = <span class="literal">null</span>            <span class="comment">// Cannot match against 'undefined' or 'null'.</span></span><br></pre></td></tr></table></figure></p><h3 id="函数参数的解构赋值"><a href="#函数参数的解构赋值" class="headerlink" title="函数参数的解构赋值"></a>函数参数的解构赋值</h3><p>函数的参数也可以使用解构赋值<figure class="highlight js"><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">function</span> <span class="title">add</span>(<span class="params">[x, y]</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> x + y</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(add([<span class="number">1</span>, <span class="number">3</span>]))                                    <span class="comment">// 4</span></span><br><span class="line"><span class="built_in">console</span>.log([[<span class="number">1</span>, <span class="number">2</span>], [<span class="number">3</span>, <span class="number">4</span>]].map(<span class="function">(<span class="params">[x, y]</span>) =&gt;</span> x + y))        <span class="comment">// [ 3, 7 ]</span></span><br></pre></td></tr></table></figure></p><p>函数参数的解构也可以使用默认值。<figure class="highlight js"><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">function</span> <span class="title">move</span>(<span class="params">&#123;x = <span class="number">0</span>, y = <span class="number">0</span>&#125; = &#123;&#125;</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> [x,  y]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(move(&#123;<span class="attr">x</span>: <span class="number">1</span>, <span class="attr">y</span>: <span class="number">2</span>&#125;))         <span class="comment">// [ 1, 2 ]</span></span><br><span class="line"><span class="built_in">console</span>.log(move(&#123;<span class="attr">x</span>: <span class="number">1</span>&#125;))               <span class="comment">// [ 1, 0 ]</span></span><br><span class="line"><span class="built_in">console</span>.log(move(&#123;&#125;))                   <span class="comment">// [ 0, 0 ]</span></span><br><span class="line"><span class="built_in">console</span>.log(move())                     <span class="comment">// [ 0, 0 ]</span></span><br></pre></td></tr></table></figure></p><p>另外，<code>undefined</code>就会触发默认值<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">console</span>.log([<span class="number">1</span>, <span class="literal">undefined</span>, <span class="number">3</span>].map(<span class="function">(<span class="params">x = <span class="string">'YES'</span></span>) =&gt;</span> x))        <span class="comment">// [ 1, 'YES', 3 ]</span></span><br></pre></td></tr></table></figure></p><h3 id="用途"><a href="#用途" class="headerlink" title="用途"></a>用途</h3><p>变量解构赋值的用途很多</p><h4 id="交换变量"><a href="#交换变量" class="headerlink" title="交换变量"></a>交换变量</h4><figure class="highlight js"><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="keyword">let</span> x = <span class="string">'a'</span>,</span><br><span class="line">    y = <span class="string">'b'</span>;</span><br><span class="line">[x, y] = [y, x]</span><br><span class="line"><span class="built_in">console</span>.log(x, y)       <span class="comment">// b a</span></span><br></pre></td></tr></table></figure><h4 id="函数返回多个值"><a href="#函数返回多个值" class="headerlink" title="函数返回多个值"></a>函数返回多个值</h4><p>函数只能返回一个值，如果要返回多个值，只能将它们放在数组或者对象里返回，有了解构赋值，取出这些值就非常方便了。<figure class="highlight js"><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">function</span> <span class="title">fun1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> [a, b, c] = fun1()</span><br><span class="line"><span class="built_in">console</span>.log(a, b, c)            <span class="comment">// 1 2 3</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fun2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        foo: <span class="string">'foo'</span>,</span><br><span class="line">        bar: <span class="string">'bar'</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> &#123;foo, bar&#125; = fun2()</span><br><span class="line"><span class="built_in">console</span>.log(foo, bar)           <span class="comment">// foo bar</span></span><br></pre></td></tr></table></figure></p><h4 id="函数参数的定义"><a href="#函数参数的定义" class="headerlink" title="函数参数的定义"></a>函数参数的定义</h4><p>解构赋值可以方便地将一组参数与变量名对应起来。<figure class="highlight js"><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="function"><span class="keyword">function</span> <span class="title">f1</span>(<span class="params">[x, y, z]</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br><span class="line">f1([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment">// 无序的参数</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">f2</span>(<span class="params">&#123;x, y, z&#125;</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">&#125;</span><br><span class="line">f2(&#123;<span class="attr">z</span>: <span class="number">1</span>, <span class="attr">y</span>: <span class="number">2</span>, <span class="attr">x</span>: <span class="number">3</span>&#125;)</span><br></pre></td></tr></table></figure></p><h4 id="提取JSON数据"><a href="#提取JSON数据" class="headerlink" title="提取JSON数据"></a>提取JSON数据</h4><p>解构赋值对提取JSON对象中的数据，尤其有用<figure class="highlight js"><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">let</span> json = &#123;</span><br><span class="line">    id: <span class="number">12</span>,</span><br><span class="line">    msg: <span class="string">'Hello world!'</span>,</span><br><span class="line">    status: [<span class="number">100</span>, <span class="number">200</span>]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> &#123;id, msg, status&#125; = json</span><br><span class="line"><span class="built_in">console</span>.log(id, msg, status)        <span class="comment">// 12 'Hello world!' [ 100, 200 ]</span></span><br></pre></td></tr></table></figure></p><h4 id="函数参数的默认值"><a href="#函数参数的默认值" class="headerlink" title="函数参数的默认值"></a>函数参数的默认值</h4><p>指定参数的默认值，就避免了在函数体内部再写<code>var foo = config.foo || &#39;default foo&#39;;</code>这样的语句。<figure class="highlight js"><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">jQuery.ajax = <span class="function"><span class="keyword">function</span> (<span class="params">url, &#123;</span></span></span><br><span class="line"><span class="function"><span class="params">    async = true,</span></span></span><br><span class="line"><span class="function"><span class="params">    beforeSend = function (</span>) </span>&#123;&#125;,</span><br><span class="line">    cache = <span class="literal">true</span>,</span><br><span class="line">    complete = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;,</span><br><span class="line">    crossDomain = <span class="literal">false</span>,</span><br><span class="line">    global = <span class="literal">true</span>,</span><br><span class="line">    <span class="comment">// ... more config</span></span><br><span class="line">&#125;) &#123;</span><br><span class="line">    <span class="comment">// ... do stuff</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h4 id="遍历Map解构"><a href="#遍历Map解构" class="headerlink" title="遍历Map解构"></a>遍历Map解构</h4><p>任何部署了 Iterator 接口的对象，都可以使用<code>for ... of</code>遍历<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> map = <span class="keyword">new</span> <span class="built_in">Map</span>()</span><br><span class="line">map.set(<span class="string">'a'</span>, <span class="string">'Hello'</span>)</span><br><span class="line">map.set(<span class="string">'b'</span>, <span class="string">'World'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取键和值</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> [k, v] <span class="keyword">of</span> map) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(k, v)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 只获取键名</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> [k] <span class="keyword">of</span> map) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(k)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 只获取值</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">let</span> [, v] <span class="keyword">of</span> map) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(v)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><h4 id="输入模块指定的方法"><a href="#输入模块指定的方法" class="headerlink" title="输入模块指定的方法"></a>输入模块指定的方法</h4><p>加载模块时，往往需要指定输入那些方法。解构赋值使得输入语句非常清晰。<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> &#123; SourceMapConsumer, SourceNode &#125; = <span class="built_in">require</span>(<span class="string">"source-map"</span>);</span><br></pre></td></tr></table></figure></p><h2 id="todo-字符串的扩展"><a href="#todo-字符串的扩展" class="headerlink" title="[todo]字符串的扩展"></a>[todo]字符串的扩展</h2><h2 id="todo-正则的扩展"><a href="#todo-正则的扩展" class="headerlink" title="[todo]正则的扩展"></a>[todo]正则的扩展</h2><h2 id="todo-数值的扩展"><a href="#todo-数值的扩展" class="headerlink" title="[todo]数值的扩展"></a>[todo]数值的扩展</h2><h2 id="todo-数组的扩展"><a href="#todo-数组的扩展" class="headerlink" title="[todo]数组的扩展"></a>[todo]数组的扩展</h2><h2 id="todo-函数的扩展"><a href="#todo-函数的扩展" class="headerlink" title="[todo]函数的扩展"></a>[todo]函数的扩展</h2><h2 id="todo-对象的扩展"><a href="#todo-对象的扩展" class="headerlink" title="[todo]对象的扩展"></a>[todo]对象的扩展</h2><h2 id="todo-Symbol"><a href="#todo-Symbol" class="headerlink" title="[todo]Symbol"></a>[todo]Symbol</h2><h2 id="todo-Set和Map数据结构"><a href="#todo-Set和Map数据结构" class="headerlink" title="[todo]Set和Map数据结构"></a>[todo]Set和Map数据结构</h2><h2 id="todo-Proxy和Reflect"><a href="#todo-Proxy和Reflect" class="headerlink" title="[todo]Proxy和Reflect"></a>[todo]Proxy和Reflect</h2><h2 id="todo-Iterator-和-for-…-of-循环"><a href="#todo-Iterator-和-for-…-of-循环" class="headerlink" title="[todo]Iterator 和 for … of 循环"></a>[todo]Iterator 和 for … of 循环</h2><h2 id="todo-Generator函数"><a href="#todo-Generator函数" class="headerlink" title="[todo]Generator函数"></a>[todo]Generator函数</h2><h2 id="todo-Promise函数"><a href="#todo-Promise函数" class="headerlink" title="[todo]Promise函数"></a>[todo]Promise函数</h2><h2 id="todo-异步操作和Async函数"><a href="#todo-异步操作和Async函数" class="headerlink" title="[todo]异步操作和Async函数"></a>[todo]异步操作和Async函数</h2><h2 id="todo-Class"><a href="#todo-Class" class="headerlink" title="[todo]Class"></a>[todo]Class</h2><h2 id="todo-Decorator"><a href="#todo-Decorator" class="headerlink" title="[todo]Decorator"></a>[todo]Decorator</h2><h2 id="todo-Module"><a href="#todo-Module" class="headerlink" title="[todo]Module"></a>[todo]Module</h2><h2 id="todo-编程风格"><a href="#todo-编程风格" class="headerlink" title="[todo]编程风格"></a>[todo]编程风格</h2><h2 id="todo-规则"><a href="#todo-规则" class="headerlink" title="[todo]规则"></a>[todo]规则</h2><h2 id="todo-二进制"><a href="#todo-二进制" class="headerlink" title="[todo]二进制"></a>[todo]二进制</h2><h2 id="todo-SIMD"><a href="#todo-SIMD" class="headerlink" title="[todo]SIMD"></a>[todo]SIMD</h2>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;ES6（ECMAScript 6.0）已经使用了很久了，但是有很多的东西还是没有学会；学东西不应该浅尝而止，应该系统的学习；记录一些自己的理解。&lt;/p&gt;
&lt;p&gt;笔记主要是依据阮一峰老师的教程&lt;a href=&quot;http://es6.ruanyifeng.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;ECMAScript 6入门&lt;/a&gt;学习所得
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="JavaScript" scheme="https://hefengxian.github.io/tags/JavaScript/"/>
    
      <category term="ES6" scheme="https://hefengxian.github.io/tags/ES6/"/>
    
  </entry>
  
  <entry>
    <title>Ubuntu 常用命令记录</title>
    <link href="https://hefengxian.github.io/2016/11/22/Ubuntu-%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E8%AE%B0%E5%BD%95/"/>
    <id>https://hefengxian.github.io/2016/11/22/Ubuntu-常用命令记录/</id>
    <published>2016-11-22T02:09:38.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<p>Linux有太多的命令，很多经常用却没有记住；这里统一收集一下平常用到的一些命令</p><a id="more"></a><h3 id="查看文件详情"><a href="#查看文件详情" class="headerlink" title="查看文件详情"></a>查看文件详情</h3><p>一般用<code>ls</code>可以查看文件<code>la</code>（<code>ls -A</code>的别名）查看所有文件；但是一老没记住怎么查看文件的大小啊、权限啊什么的鬼；通过查看帮助<code>ls --help</code><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看详情（帮助解释为：使用较长格式列出信息）</span></span><br><span class="line">ls -l</span><br></pre></td></tr></table></figure></p><p>但是这样有个问题，文件的大小是使用Byte为单位的，根本无法直接看出一个文件有多大；如果我们想要更好的可读性呢？<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># -h 帮助解释为：--human-readable with -l and/or -s, print human readable sizes (e.g., 1K 234M 2G)</span></span><br><span class="line">ls -lh</span><br></pre></td></tr></table></figure></p><h3 id="设置别名"><a href="#设置别名" class="headerlink" title="设置别名"></a>设置别名</h3><p>比如我知道了<code>ls -lhA</code>很好使，我但是每次都输入这么多参数很不方便，那么我们怎么是其简单化呢？就像<code>la</code>一样；我们先看一下用户主目录下的<code>.bashrc</code>文件<code>sudo  vim ~/.bashrc</code><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># some more ls aliases</span></span><br><span class="line"><span class="built_in">alias</span> ll=<span class="string">'ls -alF'</span></span><br><span class="line"><span class="built_in">alias</span> la=<span class="string">'ls -A'</span></span><br><span class="line"><span class="built_in">alias</span> l=<span class="string">'ls -CF'</span></span><br></pre></td></tr></table></figure></p><p>看到这里应该明白怎么回事了，所以依葫芦画瓢，在上诉位置追加如下的命令，保存<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">alias</span> lh=<span class="string">'ls -lhA'</span></span><br></pre></td></tr></table></figure></p><p>立即使用<code>lh</code>发现并没有什么用，因为<code>.bashrc</code>是启动时加载的，所以我们手动加载一下<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">source</span> ~/.bashrc</span><br></pre></td></tr></table></figure></p><p>现在用就看到效果了。另外，设置别名的时候要注意有没有冲突，一个简单粗暴的验证方法是直接在命令行中输入你要准备使用的别名，如果还没使用，那么会提示你。</p><h3 id="查看路由表"><a href="#查看路由表" class="headerlink" title="查看路由表"></a>查看路由表</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">netstat -r</span><br><span class="line"></span><br><span class="line">内核 IP 路由表</span><br><span class="line">Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface</span><br><span class="line">0.0.0.0         192.168.1.1     0.0.0.0         UG        0 0          0 enp2s0</span><br><span class="line">0.0.0.0         192.168.2.1     0.0.0.0         UG        0 0          0 enp2s0</span><br><span class="line">169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 docker0</span><br><span class="line">172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0</span><br><span class="line">192.168.1.0     0.0.0.0         255.255.255.0   U         0 0          0 enp2s0</span><br><span class="line">192.168.2.0     0.0.0.0         255.255.255.0   U         0 0          0 enp2s0</span><br></pre></td></tr></table></figure><p>其他选项可以使用<code>netstat --help</code></p><h3 id="删除和设置默认网关"><a href="#删除和设置默认网关" class="headerlink" title="删除和设置默认网关"></a>删除和设置默认网关</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 删除默认路由</span></span><br><span class="line">sudo route del default</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置默认路由</span></span><br><span class="line">sudo route add default gw 192.168.x.1</span><br></pre></td></tr></table></figure><h3 id="Ubuntu桌面版的IP设置"><a href="#Ubuntu桌面版的IP设置" class="headerlink" title="Ubuntu桌面版的IP设置"></a>Ubuntu桌面版的IP设置</h3><p>现在网上的Ubuntu IP设置教程，一般都是在Server版下的；然而桌面版的除了使用图形界面设置，如果要想直接编辑对应的配置文件呢？</p><p>一般Server版的IP设置都在<code>/etc/network</code>目录下（当然桌面版也有），而桌面版除了这个还有另外的设置在目录<code>/etc/network</code>；在界面上设置的内容都是保存在这个目录下的。</p><p>比如我们打开主要的配置文件目录<code>/etc/NetworkManager/system-connections/</code>，里面可能有你设置的VPN，有线连接等等，一般我们都是默认叫有线连接，当然我们也可以叫其他的名字，你只要改一下这个配置文件名，那么你会看到右上角的网络里的名字页对于的改了</p><p>一般里面的内容都是类似如下的配置（文件是只读的，需要管理员权限），我们可以更改我们想改的配置。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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></pre></td><td class="code"><pre><span class="line">[connection]</span><br><span class="line">id=wired</span><br><span class="line">uuid=5b6d5907-3636-401c-a4a0-cf0cc473f306</span><br><span class="line"><span class="built_in">type</span>=ethernet</span><br><span class="line">autoconnect-priority=-999</span><br><span class="line">permissions=</span><br><span class="line">secondaries=</span><br><span class="line">timestamp=1480391347</span><br><span class="line"></span><br><span class="line">[ethernet]</span><br><span class="line">duplex=full</span><br><span class="line">mac-address=B0:83:FE:BA:A0:1D</span><br><span class="line">mac-address-blacklist=</span><br><span class="line"></span><br><span class="line">[ipv4]</span><br><span class="line">address1=192.168.1.45/24,192.168.1.1</span><br><span class="line">address2=192.168.2.45/24,192.168.2.1</span><br><span class="line">dns=202.96.134.33;</span><br><span class="line">dns-search=</span><br><span class="line">method=manual</span><br><span class="line"></span><br><span class="line">[ipv6]</span><br><span class="line">addr-gen-mode=stable-privacy</span><br><span class="line">dns-search=</span><br><span class="line">ip6-privacy=0</span><br><span class="line">method=auto</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Linux有太多的命令，很多经常用却没有记住；这里统一收集一下平常用到的一些命令&lt;/p&gt;
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="Ubuntu" scheme="https://hefengxian.github.io/tags/Ubuntu/"/>
    
      <category term="Linux" scheme="https://hefengxian.github.io/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>《TCP/IP详解》第一章 概述</title>
    <link href="https://hefengxian.github.io/2016/08/22/TCP-IP%E8%AF%A6%E8%A7%A3%E7%AC%AC%E4%B8%80%E7%AB%A0/"/>
    <id>https://hefengxian.github.io/2016/08/22/TCP-IP详解第一章/</id>
    <published>2016-08-22T09:58:15.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>很多不同的厂家生产各种型号的计算机，它们运行完全不同的操作系统，但TCP/IP协议族允许它们通信。它是一个真正开放的系统，因为协议族的定义及其多种实现可以不用花钱或花很少的钱就可以公开的得到。它被称作“全球互联网”或“因特网（Internet）”的基础，该广域网（WAN）已包含遍布世界的计算机。</p><p>本章主要对TCP/IP协议族进行概述，其目的是为本书的其余章节提供充分的背景知识。</p><a id="more"></a><h2 id="分层"><a href="#分层" class="headerlink" title="分层"></a>分层</h2><p>网络协议通常分不同层次进行开发，每一层分别负责不同的通信功能。一个协议族，比如TCP/IP，是一组不同层次上的多个协议的组合。TCP/IP通常被任务是一个四层协议系统。</p><table><thead><tr><th>层</th><th>应用</th></tr></thead><tbody><tr><td>应用层</td><td>Telnet、FTP和e-mail等</td></tr><tr><td>运输层</td><td>TCP和UDP</td></tr><tr><td>网络层</td><td>IP、ICMP和IGMP</td></tr><tr><td>链路层</td><td>设备驱动程序以及接口卡</td></tr></tbody></table><p>每一层负责不同的功能：</p><ol><li><p><strong>链路层</strong>，有时也成为数据链路层或网络接口层，通常包括操作兄台哪个中的设备驱动程序和计算机中对应网络接口卡。它们一起处理与电缆（或其他任何的传输媒介）的物理接口细节。</p></li><li><p><strong>网络层</strong>，有时也称作互联网层，处理分组咋网络中的活动，例如分组的选路。在TCP/IP协议族中，网络层协议包括IP协议（网际协议），ICMP协议（Internet互联网控制报文协议），以及IGMP协议（Internet组管理协议）。</p></li><li><p><strong>运输层</strong>，主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中，有两个互不相同的传输协议：TCP（传输控制协议）和UDP（用户数据报协议）。TCP为两台主机提供高可靠的数据通信。它所做的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层，确认接收到的分组，设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端通信，因此应用层可以忽略所有这些细节。UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机，但并不保证该数据报能到达另一端。任何必需的可靠性必须由应用层来提供。</p></li><li><p><strong>应用层</strong>，负责处理特定的应用程序细节。几乎各种不同的TCP/IP实现都会提供下面这些通用的应用程序。</p><ul><li>Telnet 远程登录。</li><li>FTP 文件传输协议。</li><li>SMTP 简单右键传送协议。</li><li>SNMP 简单网络管理协议。</li></ul></li></ol><p>构造互联网最简单的方法是把两个或者多个网络通过路由器进行连接。它是一种特殊的用于网络互联的硬件盒。路由器的好处是为不同的物理网络提供连接：以太网、令牌环网、点对点的连接和FDDI（光纤分布式数据接口）等等。</p><h2 id="TCP-IP的分层"><a href="#TCP-IP的分层" class="headerlink" title="TCP/IP的分层"></a>TCP/IP的分层</h2><p>TCP和UDP是两种最为著名的运输层协议，二者豆使用IP作为网络层协议。</p><ul><li><strong>TCP</strong>，虽然TCP使用不可靠的IP服务，但它阙提供一种可靠的运输层服务。</li><li><strong>UDP</strong>，为应用程序发送和接收数据报。一个数据是指从发送方传输到接收方的一个信息单元。但是与TCP不同的是，UDP是不可靠的，它不能保证数据报能安全无误的到达最终目的地。</li><li><strong>IP</strong>，是网络层上主要协议，同时被TCP和UDP使用。TCP和UDP的每族数据都通过端系统和每个中间路由器中的IP层在互联网中进行传输。</li><li><strong>ICMP</strong>，是IP协议的附属协议，IP层用它来与其他主机或路由器交换错误报文和其他重要信息。</li><li><strong>IGMP</strong>，是Internet组管理协议。它用来把一个UDP数据报多到多个主机。</li><li><strong>ARP</strong>，地址解析协议和RARP（逆地址解析协议）是某些网络接口（如以太网和令牌环网）使用的特殊协议，用来转换IP层和网络接口层使用的地址。</li></ul><h2 id="互联网的地址"><a href="#互联网的地址" class="headerlink" title="互联网的地址"></a>互联网的地址</h2><p>互联网上的每个接口必有有个唯一的Internet地址（也称作IP地址）。IP地址长32bit。Internet地址并不采用平面形式的地址空间，如1、2、3等。IP地址是具有一定结构的，五类不同的互联网地址格式如下:</p><table><thead><tr><th style="text-align:center">类别</th><th style="text-align:left">固定位（二进制）</th><th style="text-align:left">网络号长度</th><th style="text-align:left">主机号长度</th></tr></thead><tbody><tr><td style="text-align:center">A类</td><td style="text-align:left">0</td><td style="text-align:left">7 bit</td><td style="text-align:left">24 bit</td></tr><tr><td style="text-align:center">B类</td><td style="text-align:left">10</td><td style="text-align:left">14 bit</td><td style="text-align:left">16 bit</td></tr><tr><td style="text-align:center">C类</td><td style="text-align:left">110</td><td style="text-align:left">21 bit</td><td style="text-align:left">8 bit</td></tr><tr><td style="text-align:center">D类</td><td style="text-align:left">1110</td><td style="text-align:left">28 bit（多播组号）</td></tr><tr><td style="text-align:center">E类</td><td style="text-align:left">11110</td><td style="text-align:left">27 bit（留待后用）</td></tr></tbody></table><p>这些32位的地址通写成4个十进制的数，其中每个整数对应一个字节。这种表示方法称作“点分十进制表示法（Dotted decimal notation）”。区分各类地址的最简单方法就是看它的第一个十进制整数。如下表，其中第一个十进制整数用粗体表示。</p><table><thead><tr><th>类型</th><th style="text-align:right">范围</th></tr></thead><tbody><tr><td>A类</td><td style="text-align:right"><strong>0</strong>.0.0.0 - <strong>127</strong>.255.255.255</td></tr><tr><td>B类</td><td style="text-align:right"><strong>128</strong>.0.0.0 - <strong>191</strong>.255.255.255</td></tr><tr><td>C类</td><td style="text-align:right"><strong>192</strong>.0.0.0 - <strong>223</strong>.255.255.255</td></tr><tr><td>D类</td><td style="text-align:right"><strong>224</strong>.0.0.0 - <strong>239</strong>.255.255.255</td></tr><tr><td>E类</td><td style="text-align:right"><strong>240</strong>.0.0.0 - <strong>255</strong>.255.255.255</td></tr></tbody></table><p>需要指出的是，多接口主机具有多个IP地址，其中每个接口对对应一个IP地址（比如笔记本电脑的WIFI和网线有不同的IP）。</p><p>由于互联网上的每个接口都必须有一个唯一的IP地址，因此必须要有一个管理机构为接入互联网的网络分配IP地址。这个管理机构就是互联网信息中心（Internet Network Information Center），称作InterNIC。InterNIC只分配网络号。主机号的分配由系统管理员来负责。</p><p>有三类IP地址：</p><ul><li>单播地址，目的端为单个主机。</li><li>广播地址，目的端为给定网路上的所有主机。</li><li>多播地址，目的端为同一个组内的所有主机。</li></ul><h2 id="域名系统"><a href="#域名系统" class="headerlink" title="域名系统"></a>域名系统</h2><p>尽管通过IP地址可以识别主机上的网络接口，进而访问主机，但是人们最喜欢使用的还是主机名，在TCP/IP领域中，域名系统（DNS）是一个分布的数据库，由它来提供IP地址和主机名之间的映射信息。</p><p>我们可以理解为，任何应用程序都可以调用一个标准的库函数来查看给定名字的主机IP地址，反之，系统也提供一个逆函数——给定主机的IP地址，查看它所对应的主机名。例如，当我们使用Telnet进行远程登录时，既可以指定IP也可以指定主机名。</p><h2 id="封装"><a href="#封装" class="headerlink" title="封装"></a>封装</h2><p>当应用程序用TCP传送数据时，数据被送入协议栈中，然后逐个通过每一层知道被当作一串比特流送入网络。其中每一层对收到的数据都要增加一些首部或者尾部信息。过程如下图，TCP传给IP的数据单元称作TCP报文段或简成为TCP段（TCP segment）。IP传给网络接口的数据单元称作IP数据报（IP datagram）。通过以太网传输的比特流称作为帧（Frame）。<img src="http://7d9jd9.com1.z0.glb.clouddn.com/TCP_IP%E8%AF%A6%E8%A7%A3_IP%E5%B0%81%E8%A3%85_new.svg" alt="IP封装">UDP数据与TCP的数据基本一致。唯一不同的是UDP传给IP的信息单元称作UDP数据报（UDP datagram），而且UDP的首部长为8字节。</p><p>由于TCP、UDP、ICMP、IGMP都要像IP传送数据，一次IP必须在IP的首部加入某种标识，以表明数据属于哪一层。为此，IP在首部加入一个长度为8bit的数值，称之为协议域。其中</p><ul><li><strong>1</strong>表示为ICMP协议。</li><li><strong>2</strong>表示为IGMP协议。</li><li><strong>6</strong>表示为TCP协议。</li><li><strong>17</strong>表示为UDP协议。</li></ul><p>类似的，许多的应用程序都可以使用TCP或者UDP来传送数据。运输层协议在生成报文首部时要存入一个应用程序的标识符。TCP和UDP都用一个16bit的端口号来表示不同的应用程序。TCP和UDP把端口号和目的端口号分别存入报文首部中。</p><p>网络接口分别要发送和接收IP、ARP和RARP数据，因此也必须在以太网的帧首部加入某种形式的标识，以指明生成数据的网络层协议。为此，以太网的帧首部也有一个16bit的帧类型域。</p><h2 id="分用"><a href="#分用" class="headerlink" title="分用"></a>分用</h2><p>当目的主机收到一个以太网数据帧时，数据就开始从协议栈中由底向上升，同时去掉各层协议加上的报文首部。每层协议都要检查报文首部中的协议标识，以确定接收数据的上层协议。这个过程被称作分用（Demultiplexing）<img src="http://7d9jd9.com1.z0.glb.clouddn.com/TCP_IP%E8%AF%A6%E8%A7%A3%E7%AC%94%E8%AE%B0%E6%8E%A8%E5%9B%BE%E2%80%94%E2%80%94%E5%88%86%E7%94%A8.svg" alt="分用"></p><h2 id="客户-服务器模型"><a href="#客户-服务器模型" class="headerlink" title="客户-服务器模型"></a>客户-服务器模型</h2><p>大部分网络应用程序在编写时都假设一端是客户，一端是服务器，目的是为了让服务器为客户提供某些服务。</p><p>可以将这种服务分为两种类型：重复型或并发型。简而言之，重复型一般是同步当线程的；并发是异步多线程的。</p><h2 id="端口号"><a href="#端口号" class="headerlink" title="端口号"></a>端口号</h2><h2 id="标准化过程"><a href="#标准化过程" class="headerlink" title="标准化过程"></a>标准化过程</h2><h2 id="RFC"><a href="#RFC" class="headerlink" title="RFC"></a>RFC</h2><h2 id="标准的简单服务"><a href="#标准的简单服务" class="headerlink" title="标准的简单服务"></a>标准的简单服务</h2><h2 id="互联网"><a href="#互联网" class="headerlink" title="互联网"></a>互联网</h2><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><h2 id="应用编程接口"><a href="#应用编程接口" class="headerlink" title="应用编程接口"></a>应用编程接口</h2><h2 id="测试网络"><a href="#测试网络" class="headerlink" title="测试网络"></a>测试网络</h2><h2 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h2>]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;引言&quot;&gt;&lt;a href=&quot;#引言&quot; class=&quot;headerlink&quot; title=&quot;引言&quot;&gt;&lt;/a&gt;引言&lt;/h2&gt;&lt;p&gt;很多不同的厂家生产各种型号的计算机，它们运行完全不同的操作系统，但TCP/IP协议族允许它们通信。它是一个真正开放的系统，因为协议族的定义及其多种实现
可以不用花钱或花很少的钱就可以公开的得到。它被称作“全球互联网”或“因特网（Internet）”的基础，该广域网（WAN）已包含遍布世界的计算机。&lt;/p&gt;
&lt;p&gt;本章主要对TCP/IP协议族进行概述，其目的是为本书的其余章节提供充分的背景知识。&lt;/p&gt;
    
    </summary>
    
      <category term="《TCP/IP详解》笔记" scheme="https://hefengxian.github.io/categories/%E3%80%8ATCP-IP%E8%AF%A6%E8%A7%A3%E3%80%8B%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="读书笔记" scheme="https://hefengxian.github.io/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    
      <category term="TCP/IP详解" scheme="https://hefengxian.github.io/tags/TCP-IP%E8%AF%A6%E8%A7%A3/"/>
    
  </entry>
  
  <entry>
    <title>第二章 算法基础</title>
    <link href="https://hefengxian.github.io/2016/08/19/ItA-Chapter-02%E7%AE%97%E6%B3%95%E5%9F%BA%E7%A1%80/"/>
    <id>https://hefengxian.github.io/2016/08/19/ItA-Chapter-02算法基础/</id>
    <published>2016-08-19T14:00:01.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<p>本章将要介绍一个贯穿本书的框架，后续的算法设计与分析都是在这个框架的=中进行的。<a id="more"></a></p><h2 id="插入排序"><a href="#插入排序" class="headerlink" title="插入排序"></a>插入排序</h2><p>我们的第一个算法（插入排序）求解第1章中引入的<strong>排序问题</strong>：</p><ul><li><strong>输入</strong>：$n$ 个数的一个序列 $\langle a_1, a_2, \dotsm, a_n \rangle$ 。</li><li><strong>输出</strong>：输入序列的一个排列 $\langle a’_{1}, a’_{2}, \dotsm, a’_{n} \rangle$ ，满足 $a’_{1} \leq a’_{2} \leq \dotsm \leq a’_{n}$</li></ul><p>我们希望排序的数也称为<strong>关键词</strong>。虽然概念上我们在排序一个序列，但是输入是以 $n$ 个元素的数组的形式出现的。</p><p>我们通常将算法描述为用一种<strong>伪代码</strong>书写的程序，该伪代码在许多方面类似于C、C++、Java、Python或Pascal。伪代码和真代码的区别在于，伪代码使用最清晰、最简介的表示方法来说明给定的算法。</p><p>插入排序，对于少量的元素排序，它是一个有效的算法。插入排序的工作方式像大家排序扑克牌一样。开始时，我们的左手为空并且桌面的牌面朝下。然后，我们每次从桌上拿一张牌，插入左手上正确的位置。为了找到一张牌的正确位置，我们从左到右将它与已经在手中的牌进行比较。这样拿在左手上的牌总是排序好的，原来这些牌都是桌子上牌堆中顶部的牌。</p><p>对于插入排序，我们将其伪代码过程命名为<code>INSERTION-SORT</code>，其中参数是一个数组 $A[1 \dotsm n]$，包含长度为 $n$ 的要排序的一个序列。（在代码中，$A$ 中元素的数目 $n$ 用 $A.length$ 表示）该算法<strong>原址</strong>排序输入的数：算法在数组 $A$ 中重排这些数，在任何时候，最多只有其中的常数个数字存储在数组外。在过程<code>INSERTION-SORT</code>结束时，输入数组 $A$ 包含排序好的输出序列。<figure class="highlight stylus"><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="title">INSERTION-SORT</span><span class="params">(A)</span></span></span><br><span class="line">    <span class="keyword">for</span> j = <span class="number">2</span> to A.length</span><br><span class="line">        key = A[j]</span><br><span class="line">        <span class="comment">// Insert A[j] into the sorted sequence A[1...j - 1]</span></span><br><span class="line">        <span class="selector-tag">i</span> = j - <span class="number">1</span></span><br><span class="line">        while <span class="selector-tag">i</span> &gt; <span class="number">0</span> and A[i] &gt; key</span><br><span class="line">            A[<span class="selector-tag">i</span> + <span class="number">1</span>] = A[i]</span><br><span class="line">            <span class="selector-tag">i</span> = <span class="selector-tag">i</span> - <span class="number">1</span></span><br><span class="line">        A[<span class="selector-tag">i</span> + <span class="number">1</span>] = key</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;本章将要介绍一个贯穿本书的框架，后续的算法设计与分析都是在这个框架的=中进行的。
    
    </summary>
    
      <category term="《算法导论》笔记" scheme="https://hefengxian.github.io/categories/%E3%80%8A%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA%E3%80%8B%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="算法导论" scheme="https://hefengxian.github.io/tags/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
    
      <category term="读书笔记" scheme="https://hefengxian.github.io/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>第一章 算法在计算中的作用</title>
    <link href="https://hefengxian.github.io/2016/08/17/ItA-Chapter-01%E7%AE%97%E6%B3%95%E5%9C%A8%E8%AE%A1%E7%AE%97%E4%B8%AD%E7%9A%84%E4%BD%9C%E7%94%A8/"/>
    <id>https://hefengxian.github.io/2016/08/17/ItA-Chapter-01算法在计算中的作用/</id>
    <published>2016-08-17T14:52:45.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<p>什么是是算法？为什么算法值得研究？相对于计算机中使用的其他技术来说算法的作用是什么？</p><a id="more"></a><h2 id="算法"><a href="#算法" class="headerlink" title="算法"></a>算法</h2><p>非形式的说，<strong>算法(algorithm)</strong>就是任何良定义的计算过程，该过程取某个值或者值的集合作为<strong>输入</strong>并产生某个值或者值的集合作为<strong>输出</strong>。这样算法就是把输入转换成输出的计算步骤的一个序列。</p><p>我们也可以把算法看成是用于求解良说明的计算问题的工具。一般来说，问题陈述说明了期望输入/输出关系。算法则描述一个特定的计算过程来实现该输入/输出关系。</p><p>例如，我们可能需要把一个数列排成递增序。实际上，这个问题经常出现，并且为引入许多标准的设计和分析工具提供了足够的理由。下面是我们关于<strong>排序问题</strong>的形式定义。</p><ul><li><strong>输入</strong>：$n$ 个数的一个序列 $\langle a_1, a_2, \dotsm, a_n \rangle$ 。</li><li><strong>输出</strong>：输入序列的一个排列 $\langle a’_{1}, a’_{2}, \dotsm, a’_{n} \rangle$ ，满足 $a’_{1} \leq a’_{2} \leq \dotsm \leq a’_{n}$</li></ul><p>例如，给定输入序列 $\langle 31, 41, 59, 26, 41, 58 \rangle$ ，排序算法将返回序列 $\langle 26, 31, 41,  41, 58, 59 \rangle$ 作为输出。这样的输入序列称为排序问题的一个<strong>实例(instance)</strong>。一般来说，<strong>问题实例</strong>由计算该问题所必需的（满足问题陈述中强加的各种约束的）的输入组成。</p><p>若对每个输入实例，算法都以正确的输出停机，则称该算法是<strong>正确的</strong>，并称正确的算法<strong>解决了</strong>给定的计算问题。不正确的算法对某些输入可能根本不停机，也可能以不正确的回答停机。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;什么是是算法？为什么算法值得研究？相对于计算机中使用的其他技术来说算法的作用是什么？&lt;/p&gt;
    
    </summary>
    
      <category term="《算法导论》笔记" scheme="https://hefengxian.github.io/categories/%E3%80%8A%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA%E3%80%8B%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="算法导论" scheme="https://hefengxian.github.io/tags/%E7%AE%97%E6%B3%95%E5%AF%BC%E8%AE%BA/"/>
    
      <category term="读书笔记" scheme="https://hefengxian.github.io/tags/%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>Ubuntu Apahce2.4无法访问javascript目录的问题</title>
    <link href="https://hefengxian.github.io/2016/08/16/Ubuntu-Apahce2-4%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AEjavascript%E7%9B%AE%E5%BD%95%E7%9A%84%E9%97%AE%E9%A2%98/"/>
    <id>https://hefengxian.github.io/2016/08/16/Ubuntu-Apahce2-4无法访问javascript目录的问题/</id>
    <published>2016-08-16T06:29:46.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<h4 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h4><p>今天调试一个项目，项目放在<code>webroot</code>下面的<code>javascript</code>目录，无论怎么设置都是<code>403 You don&#39;t have permission to access /javascript/ on this server.</code></p><a id="more"></a><h4 id="思考过程"><a href="#思考过程" class="headerlink" title="思考过程"></a>思考过程</h4><p>首先第一反应，Google了错误<code>You don&#39;t have permission to access /javascript/ on this server.</code>，然后发现大部分答案都说到了配置文件中的<code>Directory</code>设置。比如<figure class="highlight apache"><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="section">&lt;Directory /&gt;</span></span><br><span class="line">   <span class="attribute"><span class="nomarkup">Options</span></span> FollowSymLinks</span><br><span class="line">   <span class="attribute">AllowOverride</span> <span class="literal">All</span></span><br><span class="line">   <span class="attribute"><span class="nomarkup">Order</span></span> deny,allow</span><br><span class="line">   <span class="attribute"><span class="nomarkup">Allow</span></span> from <span class="literal">all</span></span><br><span class="line"><span class="section">&lt;/Directory&gt;</span></span><br></pre></td></tr></table></figure></p><p>而我并不是整个<code>webroot</code>都不能访问，其他所有的文件夹都可以访问，就是目录<code>javascript</code>文件夹没有权限访问，我的设置是<figure class="highlight apache"><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="section">&lt;Directory /home/hfx/workspace/&gt;</span></span><br><span class="line">       <span class="attribute"><span class="nomarkup">Options</span></span> Indexes FollowSymLinks</span><br><span class="line"><span class="comment">#       AllowOverride None</span></span><br><span class="line">       <span class="attribute">AllowOverride</span> <span class="literal">All</span></span><br><span class="line">       <span class="attribute">Require</span> <span class="literal">all</span> granted</span><br><span class="line"><span class="section">&lt;/Directory&gt;</span></span><br></pre></td></tr></table></figure></p><p>所以按理来说也是没有问题的，可以单单就是<code>javascript</code>目录无法访问，并且我尝试重新给<code>javascript</code>目录设置权限<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">chmod 777 -R javascript</span><br></pre></td></tr></table></figure></p><p>然而还是并没有什么卵用，于是我尝试更改<code>javascript</code>变成<code>javaScript</code>或者新建其他的名字的文件夹，而它们均可以正常访问，所以猜想症结应该是那里的配置禁止了web根路径下名字为<code>javascript</code>的路径。</p><h4 id="发现问题"><a href="#发现问题" class="headerlink" title="发现问题"></a>发现问题</h4><p>于是我看apache的所有配置文件，打开<code>/etc/apache2/conf-enable/</code>目录，发现了一个名为<code>javascript-common.conf</code>的配置文件，打开一看<figure class="highlight dts"><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">Alias /javascript <span class="meta-keyword">/usr/</span>share<span class="meta-keyword">/javascript/</span></span><br><span class="line"></span><br><span class="line"><span class="params">&lt;Directory "/usr/share/javascript/"&gt;</span></span><br><span class="line">       Options FollowSymLinks MultiViews</span><br><span class="line"><span class="params">&lt;/Directory&gt;</span></span><br></pre></td></tr></table></figure></p><p>其实我并不知道具体是什么意思，可是从字面意思大概看出，配置里面指定了一个别名<code>/javascript</code>到目录<code>/usr/share/javascript/</code>，应该访问<code>/javascript</code>就变成了访问目录<code>/usr/share/javascript/</code>而不是我们在web根目录下创建的<code>javascript</code>目录。</p><h4 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h4><p>于是google一下<code>javascript-common.conf</code>，这才发现了很多真正与此相关的问题，所以真正的解决方案有很多种，有的直接修改别名的名称为<code>/javascript-common</code>，而我觉得最好的解决方案应该是</p><blockquote><p>You don’t need to edit the conf file or purge the package just disable it.</p><pre><code>a2disconf javascript-commonservice apache2 reload</code></pre><p>If for some reason you want to use that conf:</p><pre><code>a2enconf javascript-commonservice apache2 reload</code></pre></blockquote><p>另外解释一下<code>a2disconf</code>和<code>a2enconf</code>的作用，官方的介绍是</p><blockquote><p>a2enconf, a2disconf - enable or disable an apache2 configuration file</p></blockquote><p>从介绍就直接明了它的作用了。快捷的启用或者禁用一个apache模块。</p><p>另外还有类似的几个命令：</p><ul><li>apache2ctl - Apache HTTP server control interface</li><li>a2enmod, a2dismod - enable or disable an apache2 module</li></ul><h4 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h4><ul><li><a href="http://stackoverflow.com/questions/21706067/apache-doesnt-serve-files-in-javascript-directory-why" target="_blank" rel="noopener">Apache doesn’t serve files in “javascript” directory. Why?</a></li><li><a href="http://manpages.ubuntu.com/manpages/trusty/man8/a2enconf.8.html" target="_blank" rel="noopener">a2enconf</a></li><li><a href="http://manpages.ubuntu.com/manpages/trusty/man8/apache2ctl.8.html" target="_blank" rel="noopener">apache2ctl</a></li><li><a href="http://manpages.ubuntu.com/manpages/trusty/man8/a2dismod.8.html" target="_blank" rel="noopener">a2dismod</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;h4 id=&quot;问题描述&quot;&gt;&lt;a href=&quot;#问题描述&quot; class=&quot;headerlink&quot; title=&quot;问题描述&quot;&gt;&lt;/a&gt;问题描述&lt;/h4&gt;&lt;p&gt;今天调试一个项目，项目放在&lt;code&gt;webroot&lt;/code&gt;下面的&lt;code&gt;javascript&lt;/code&gt;目录，无论怎么设置都是&lt;code&gt;403 You don&amp;#39;t have permission to access /javascript/ on this server.&lt;/code&gt;&lt;/p&gt;
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="Ubuntu" scheme="https://hefengxian.github.io/tags/Ubuntu/"/>
    
      <category term="Apache2.4" scheme="https://hefengxian.github.io/tags/Apache2-4/"/>
    
  </entry>
  
  <entry>
    <title>Ubuntu 16.04安装PHP7</title>
    <link href="https://hefengxian.github.io/2016/07/16/16-04%E5%AE%89%E8%A3%85PHP7/"/>
    <id>https://hefengxian.github.io/2016/07/16/16-04安装PHP7/</id>
    <published>2016-07-16T08:23:55.000Z</published>
    <updated>2020-07-27T09:57:42.148Z</updated>
    
    <content type="html"><![CDATA[<p>由于换了硬盘重装了（升级）系统到Ubuntu16.04之后，开发环境也要重新安装，其实16.04源里面默认的PHP版本就是7.x，但是有个问题就是没有OCI扩展，有项目需要使用到Oracle数据库。<a id="more"></a></p><h3 id="准备编译环境"><a href="#准备编译环境" class="headerlink" title="准备编译环境"></a>准备编译环境</h3><p>由于全部编译太过于繁琐，而且很多依赖会有问题，所以我们选择另外一种方案，能使用<code>apt-get</code>安装都使用<code>apt-get</code>安装。不能使用apt-get才自己编译，这样可以节省大量的时间。因为有的依赖真的是很头疼。</p><p>由于在Ubuntu16.04上，默认的PHP版本就是7.x。由于我们要使用Apache2.4+PHP，所以安装如下模块即可直接解析PHP。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install php-dev libapache2-mod-php</span><br></pre></td></tr></table></figure></p><p>这样最基本的模块就安装好了，如果还需要其他的模块，可以通过<code>apt-get</code>快捷安装；比如还需要MySQL和mb_string相关的模块。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install php-mysql php-mbstring</span><br></pre></td></tr></table></figure></p><p>这样就会自动安装好相关的模块。</p><h3 id="安装Oracle-Client"><a href="#安装Oracle-Client" class="headerlink" title="安装Oracle Client"></a>安装Oracle Client</h3><p>由于要编译OCI扩展，我们需要Oracle客户端，这里我们下载<a href="http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html" target="_blank" rel="noopener">Oracle Instant Client</a>，选择Instant Client for Linux x86-64 basic版本下载。</p><p>另外要编译OCI必须还需要instant client SDK 包，下载解压之后合并到Base。</p><p>给出的网页最后面也有安装步骤，这里简述一下</p><ol><li>解压zip包，放置到某个目录下</li><li>为当前版本的Instant Client创建合适的链接</li><li>设置环境变量</li></ol><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">sudo unzip instantclient-basic-linux.x64-12.1.0.2.0.zip</span><br><span class="line">sudo unzip instantclient-sdk-linux.x64-12.1.0.2.0.zip</span><br><span class="line">sudo mv instantclient_12_1/ /opt/oracle/</span><br><span class="line"><span class="built_in">cd</span> /opt/oracle/instantclient_12_1/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 建立符号链接</span></span><br><span class="line">sudo ln -s libclntsh.so.12.1 libclntsh.so</span><br><span class="line">sudo ln -s libocci.so.12.1 libocci.so</span><br><span class="line"></span><br><span class="line"><span class="comment"># 打开 /etc/profile 在最后面加入</span></span><br><span class="line"><span class="built_in">export</span> LD_LIBRARY_PATH=/opt/oracle/instantclient_12_1:<span class="variable">$LD_LIBRARY_PATH</span></span><br><span class="line"><span class="built_in">export</span> PATH=/opt/oracle/instantclient_12_1:<span class="variable">$PATH</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 最后source一下，使配置生效</span></span><br><span class="line"><span class="built_in">source</span> /etc/profile</span><br></pre></td></tr></table></figure><h3 id="下载PHP源码"><a href="#下载PHP源码" class="headerlink" title="下载PHP源码"></a>下载PHP源码</h3><p>首先我们要确定已经安装的PHP的版本，由于使用<code>apt-get</code>安装，版本可能不是PHP官网放的最新的版本，使用下面的 命令既可查看<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php -v</span><br></pre></td></tr></table></figure></p><p>发现我的安装的版本是<code>7.0.4</code>，那么我们对应的下载PHP-7.0.4版本的源码。两种方式可以下载到源码。</p><ul><li>从官网下载源码包</li><li>从GitHub 仓库 <code>clone</code></li></ul><p>官网下载源码很简单，打开<a href="http://php.net/downloads.php" target="_blank" rel="noopener">php.net</a>的Download页面，选择要下载的版本。或者从GitHub仓库<code>clone</code>指定版本（或者先<code>clone</code>再<code>checkout</code>想要的版本），如</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> -b PHP-7.0.4 https://github.com/php/php-src &amp;&amp; <span class="built_in">cd</span> php-src</span><br></pre></td></tr></table></figure><h3 id="编译OCI8-PDO-OCI"><a href="#编译OCI8-PDO-OCI" class="headerlink" title="编译OCI8/PDO_OCI"></a>编译OCI8/PDO_OCI</h3><p>经过如上的步骤我们已经进入到下载的PHP源码根目录了，那么我们开始编译。</p><h4 id="编译oci8"><a href="#编译oci8" class="headerlink" title="编译oci8"></a>编译oci8</h4><p>进入到扩展oci8的源码目录，使用phpize</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ext/oci8</span><br><span class="line">phpize</span><br><span class="line">./configure --with-oci8=instantclient,/opt/oracle/instantclient_12_1</span><br><span class="line">sudo make</span><br></pre></td></tr></table></figure><p>执行完上面的步骤，应该会生成一个<code>modules</code>文件夹，里面就有我们想要的extension。</p><h4 id="编译pdo-oci"><a href="#编译pdo-oci" class="headerlink" title="编译pdo_oci"></a>编译pdo_oci</h4><p>步骤和编译oci8是一样的，但是configure参数不一样，所以还是写一下。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ../../ext/pdo_oci</span><br><span class="line">phpize</span><br><span class="line"><span class="comment"># 最后面要指定版本号</span></span><br><span class="line">./configure --with-pdo-oci=instantclient,/opt/oracle/instantclient_12_1,12.1</span><br><span class="line">sudo make</span><br></pre></td></tr></table></figure></p><p>结果也和上面一样。</p><h4 id="使用我们编译的扩展"><a href="#使用我们编译的扩展" class="headerlink" title="使用我们编译的扩展"></a>使用我们编译的扩展</h4><p>首先我们要知道现行PHP的ext目录在哪里<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">php -i | grep <span class="string">"extension_dir"</span></span><br></pre></td></tr></table></figure></p><p>我这里显示的是<code>extension_dir =&gt; /usr/lib/php/20151012 =&gt; /usr/lib/php/20151012</code>，那么我们先把我们编译的扩展复制到<code>/usr/lib/php/20151012</code>下<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先进入对应的modules目录下</span></span><br><span class="line">cp oci8.so /usr/lib/php/20151012</span><br><span class="line">cp pdo_oci.so /usr/lib/php/20151012</span><br></pre></td></tr></table></figure></p><p>然后我们还要在<code>php.ini</code>中添加相关配置项，首先也要知道php.ini的位置<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">p -i | grep <span class="string">"Configuration File"</span></span><br></pre></td></tr></table></figure></p><p>打印出了如下信息</p><figure class="highlight gradle"><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">Configuration <span class="keyword">File</span> (php.ini) Path =&gt; <span class="regexp">/etc/</span>php<span class="regexp">/7.0/</span>cli</span><br><span class="line">Loaded Configuration <span class="keyword">File</span> =&gt; <span class="regexp">/etc/</span>php<span class="regexp">/7.0/</span>cli<span class="regexp">/php.ini</span></span><br></pre></td></tr></table></figure><p>这样我们就知道了php.ini的位置，但是这个是CLI（命令行接口）的配置文件，我们需要使用Apache的（CGI）。我们到目录<code>/etc/php/7.0/</code>下发现还有一个名为<code>apache2</code>的目录，里面也有php.ini文件，那么我们编辑<code>apache2</code>目录下的php.ini</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">sudo</span> <span class="selector-tag">vim</span> <span class="selector-tag">php</span><span class="selector-class">.ini</span></span><br></pre></td></tr></table></figure><p>在里面加入</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">extension=oci8.so</span><br><span class="line">extension=pdo_oci.so</span><br></pre></td></tr></table></figure><p>最后重启Apache<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl restart apache2.service</span><br></pre></td></tr></table></figure></p><p>查看一下<code>phpinfo()</code>发现OCI和PDO_OCI均已安装。到这里安装已经全部完成了。</p><h3 id="Linux小技巧"><a href="#Linux小技巧" class="headerlink" title="Linux小技巧"></a>Linux小技巧</h3><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重启某个服务</span></span><br><span class="line">sudo systemctl restart apache2.service</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看某个服务的状态</span></span><br><span class="line">sudo systemctl status apache2.service</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看php相关的模块（其他的类似）</span></span><br><span class="line">apt-<span class="keyword">cache</span> <span class="keyword">search</span> php- | <span class="keyword">less</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 具体查看某个模块的详细信息</span></span><br><span class="line">apt-<span class="keyword">cache</span> <span class="keyword">show</span> package_name</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;由于换了硬盘重装了（升级）系统到Ubuntu16.04之后，开发环境也要重新安装，其实16.04源里面默认的PHP版本就是7.x，但是有个问题就是没有OCI扩展，有项目需要使用到Oracle数据库。
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="Ubuntu" scheme="https://hefengxian.github.io/tags/Ubuntu/"/>
    
      <category term="PHP7" scheme="https://hefengxian.github.io/tags/PHP7/"/>
    
      <category term="OCI" scheme="https://hefengxian.github.io/tags/OCI/"/>
    
  </entry>
  
  <entry>
    <title>电脑升级SSD记</title>
    <link href="https://hefengxian.github.io/2016/07/07/%E5%85%AC%E5%8F%B8%E7%94%B5%E8%84%91%E5%8D%87%E7%BA%A7SSD%E8%AE%B0/"/>
    <id>https://hefengxian.github.io/2016/07/07/公司电脑升级SSD记/</id>
    <published>2016-07-07T15:19:34.000Z</published>
    <updated>2020-07-27T09:57:42.151Z</updated>
    
    <content type="html"><![CDATA[<p>由于电脑使用的机械硬盘，太卡，所以想办法提升开发体验。电脑的CPU不算差，内存单条8G也还OK。</p><p>先去京东买个很便宜的240G的ADATA SSD。头天晚上下单，第二天早上上班就送到了。京东大城市的速度是毋庸置疑的。</p><p>硬件安装方面换硬盘是相当简单的，我是直接将原来的硬盘取下来不用了；安装过程很简单，不赘诉。<a id="more"></a></p><h3 id="系统安装"><a href="#系统安装" class="headerlink" title="系统安装"></a>系统安装</h3><ul><li>准备一个4G U盘</li><li>去官网下载Ubuntu 16.04</li><li>一个可用的windows + 安装盘制作软件</li></ul><p>这里有个坑，开始用百度搜索出来的16.04的安装教程，推荐使用的制作软件是 Universal USB Installer，然而我制作了不下于5次，都无法正常启动。最终还是使用老牌的Ultraiso，制作过程网上一大把，大致说一下制作流程。</p><blockquote><p>菜单-&gt;文件-&gt;打开下载好的系统-&gt;菜单-&gt;启动-&gt;写入硬盘映像-&gt;选好你的U盘 然后等待制作完成即可</p></blockquote><p>将制作好的U盘插入到电脑，然后启动的时候注意选择启动项为制作的U盘，具体怎么选择启动项不同的电脑不一样，对了，别忘了在BIOS里面开启ACHI。DELL的电脑一般是F12选择启动项。</p><p>启动之后选择install ubuntu 或者 try ubuntu然后安装，安装过程基本上都是下一步，然后等待。</p><p>关于磁盘怎么选择分区这些问题，这里一概默认设置，因为240G并不大，而且我是准备只安装Ubuntu的，所以不考虑其他因素。用户名密码什么的安装步骤设置即可。</p><p>需要注意的是，先选择语言的时候可以不着急选中文（选中文也可以）因为选中文会导致系统菜单的：桌面/下载等目录都是汉字的，到时在命令行的时候会很不好使。等到系统内部在修改语言即可，后面会说到。</p><p>安装完成之后，输入密码即可进入到系统了，SSD速度果然不俗！！！秒进！！！</p><h3 id="基础的设置"><a href="#基础的设置" class="headerlink" title="基础的设置"></a>基础的设置</h3><h4 id="更新软件源"><a href="#更新软件源" class="headerlink" title="更新软件源"></a>更新软件源</h4><p>第一步就是把更新的源给更换了！因为涉及到后面安装软件的速度和依赖问题。</p><blockquote><p>系统设置-&gt;软件和更新-&gt;下拉里选择其他-&gt;自动选择最好的</p></blockquote><h4 id="安装WizNote记录这一切"><a href="#安装WizNote记录这一切" class="headerlink" title="安装WizNote记录这一切"></a>安装WizNote记录这一切</h4><p>搜索为知笔记，找到官网，下载Linux版本。<a href="http://www.wiz.cn/wiznote-linux.html" target="_blank" rel="noopener">为知笔记</a>，安装官方的安装方法安装即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo add-apt-repository ppa:wiznote-team</span><br><span class="line">$ sudo apt-get update</span><br><span class="line">$ sudo apt-get install wiznote</span><br></pre></td></tr></table></figure><p>我开始安装还是遇到了问题，说是有个依赖找不到（因为那个时候我还没有切换源，切换之后再安装就正常了）</p><h4 id="安装搜狗输入法"><a href="#安装搜狗输入法" class="headerlink" title="安装搜狗输入法"></a>安装搜狗输入法</h4><p>安装完了为知笔记，发现没有输入法。那怎么写笔记呢？（英语太烂写不了）</p><blockquote><p>如果开始是选择英文安装的，安装输入法之前应该要先把系统语言切换成中文。因为系统语言为中文的时候，会自动安装iBus和Fcitx（搜狗需要Fcitx），另外还有各种中文字体文件。系统设置-&gt;语言支持（如果此时告诉你语言包不全，要记得让它自动安装）-&gt;然后把中文从最底下拉上来到第一位然后点应用到整个系统，可能需要注销或者重启才能看到效果，那么我们先注销或者重启一下。这里会提示你要不要把文件夹切换成中文，选择不要切换并且不再提示。如果开始选择中文安装的也想把文件夹名字换成英文，此时应该也会提示你切换文件夹，那么你应该切换，然后注销之后再把语言改回来，这次就不要切换即可。</p></blockquote><p>去搜狗官网下载<a href="http://pinyin.sogou.com/linux/help.php" target="_blank" rel="noopener">搜狗输入法</a>，按照安装文档安装（就是双击让软件中心自己安装），然后把输入法切换为Fcitx注销之后，就可以选择搜狗了。对了搜狗还有好看的输入法皮肤！！！</p><h4 id="Google-Chrome浏览器"><a href="#Google-Chrome浏览器" class="headerlink" title="Google Chrome浏览器"></a>Google Chrome浏览器</h4><p>作为Web开发者，Chrome是必不可少的。还有一点就是Chrome内建Flash，可以看某些视频网站。当然，一提到Google，请自备梯子！！！我是有买VPN账号的，当然也可以使用xx-net使用方法可能会比较复杂，可以去GitHub仓库看。</p><p>一般安装Chrome有好几种方法，可以使用第三方源，也可以使用Google提供的DEB包，这个自行选择，我选择使用去官方下载DEB安装包。<a href="https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" target="_blank" rel="noopener">Chrome</a> 直接双击使用软件中心安装即可。</p><p>安装完成之后一般要进行一些设置，使用Chrome的好处就是账号同步功能了，我只要把账号登陆（自备梯子），所有的设置和插件都回来了。</p><h3 id="开发环境的再次搭建"><a href="#开发环境的再次搭建" class="headerlink" title="开发环境的再次搭建"></a>开发环境的再次搭建</h3><h4 id="安装JDK"><a href="#安装JDK" class="headerlink" title="安装JDK"></a>安装JDK</h4><p>由于开发使用的IDE都是Java系列的（JetBrains/Eclipse），有些部分也会使用Java做开发。去Oracle下载<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html" target="_blank" rel="noopener">JDK1.8</a>最新版，进行安装。我把JDK放在<code>/opt/oracle/</code>目录下。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 解压</span></span><br><span class="line">tar -zxvf jdk-8u91-linux-x64.tar.gz</span><br><span class="line">sudo mv jdk1.8.0_91/ /opt/oracle/jdk</span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置环境变量（全局）</span></span><br><span class="line">sudo vim /etc/profile</span><br><span class="line"></span><br><span class="line"><span class="comment"># 在文件的最后面加入如下语句，然后保存</span></span><br><span class="line"><span class="built_in">export</span> JAVA_HOME=/opt/oracle/jdk</span><br><span class="line"><span class="built_in">export</span> CLASSPATH=.:<span class="variable">$CLASSPATH</span>:<span class="variable">$JAVA_HOME</span>/lib</span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:<span class="variable">$JAVA_HOME</span>/bin:<span class="variable">$JAVA_HOME</span>/jre/bin</span><br><span class="line"></span><br><span class="line"><span class="comment"># 然后source一下profile文件，使设置生效</span></span><br><span class="line">sudo <span class="built_in">source</span> /etc/profile</span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试Java是否安装成功</span></span><br><span class="line">java -version</span><br><span class="line"><span class="comment"># 出现版本号则表明安装JDK已经成功了</span></span><br></pre></td></tr></table></figure><h4 id="安装各种IDE"><a href="#安装各种IDE" class="headerlink" title="安装各种IDE"></a>安装各种IDE</h4><p>示例安装PhpStorm，其他的类似</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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="comment"># PhpStorm</span></span><br><span class="line">sudo tar -zxvf PhpStorm-2016.1.2.tar.gz -C /opt/jetbrains/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 到/opt/jetbrains/目录下改名字</span></span><br><span class="line">sudo mv PhpStorm-145.1616.3/ phpstorm</span><br><span class="line"></span><br><span class="line"><span class="comment"># 进入bin目录，执行IDE</span></span><br><span class="line"><span class="built_in">cd</span> /opt/jetbrains/phpstorm/bin</span><br><span class="line">./phpstorm.sh</span><br></pre></td></tr></table></figure><p>另外一个小技巧，如果想让这些常用的IDE固定载导航栏（启动器）上，在第一次执行<code>./phpstorm.sh</code>之后，导航栏会出现一个图标，右键选择锁定到启动器即可。</p><h4 id="安装Node-js"><a href="#安装Node-js" class="headerlink" title="安装Node.js"></a>安装Node.js</h4><p>由于有些项目，和自己的BLOG都是需要Node.js和NPM的，推荐使用<code>nvm</code>来安装，直接上GitHub上搜索nvm按照文档安装即可。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><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">wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.31.2/install.sh | bash</span><br><span class="line"></span><br><span class="line"><span class="comment"># source 一下.bashrc</span></span><br><span class="line"><span class="built_in">source</span> ~/.bashrc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看Node.js的版本，选择安装一个</span></span><br><span class="line">nvm ls-remote</span><br><span class="line"></span><br><span class="line"><span class="comment"># 比如我选择安装了5.12.0</span></span><br><span class="line">nvm install v5.12.0</span><br></pre></td></tr></table></figure></p><h4 id="安装Apache2-4"><a href="#安装Apache2-4" class="headerlink" title="安装Apache2.4"></a>安装Apache2.4</h4><p>依然使用apt安装，安装之后直接范围<code>http://localhost</code>应该就可以看到欢迎界面。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt install a</span><br></pre></td></tr></table></figure></p><h4 id="安装PHP7"><a href="#安装PHP7" class="headerlink" title="安装PHP7"></a>安装PHP7</h4><p>16.04源里面自带的就是PHP7</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install php php7.0-mysql php7.0-tidy php7.0-curl php7.0-mbstring</span><br></pre></td></tr></table></figure><h4 id="安装MySQL-和-MySQL-Work-Branch"><a href="#安装MySQL-和-MySQL-Work-Branch" class="headerlink" title="安装MySQL 和 MySQL Work Branch"></a>安装MySQL 和 MySQL Work Branch</h4><p>直接使用apt安装，安装MySQL途中要设置root密码，设置一个既可。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install mysql-server mysql-workbench</span><br></pre></td></tr></table></figure></p><h4 id="安装GIT"><a href="#安装GIT" class="headerlink" title="安装GIT"></a>安装GIT</h4><p>直接时使用APT安装，安装完成之后直接配置全局信息。<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git config --global user.name hfx</span><br><span class="line">git config --global user.email jssmith883@gamil.com</span><br></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;由于电脑使用的机械硬盘，太卡，所以想办法提升开发体验。电脑的CPU不算差，内存单条8G也还OK。&lt;/p&gt;
&lt;p&gt;先去京东买个很便宜的240G的ADATA SSD。头天晚上下单，第二天早上上班就送到了。京东大城市的速度是毋庸置疑的。&lt;/p&gt;
&lt;p&gt;硬件安装方面换硬盘是相当简单的，我是直接将原来的硬盘取下来不用了；安装过程很简单，不赘诉。
    
    </summary>
    
      <category term="日常笔记" scheme="https://hefengxian.github.io/categories/%E6%97%A5%E5%B8%B8%E7%AC%94%E8%AE%B0/"/>
    
    
      <category term="Ubuntu" scheme="https://hefengxian.github.io/tags/Ubuntu/"/>
    
      <category term="SSD" scheme="https://hefengxian.github.io/tags/SSD/"/>
    
      <category term="折腾" scheme="https://hefengxian.github.io/tags/%E6%8A%98%E8%85%BE/"/>
    
  </entry>
  
  <entry>
    <title>Slim源码阅读（立个Flag）</title>
    <link href="https://hefengxian.github.io/2016/06/29/Slim%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB/"/>
    <id>https://hefengxian.github.io/2016/06/29/Slim源码阅读/</id>
    <published>2016-06-29T09:42:55.000Z</published>
    <updated>2020-07-27T09:57:42.149Z</updated>
    
    <content type="html"><![CDATA[<p>准备阅读Slim源代码，先立各Flag看看自己能不能看下去，最近一件完整的事情都没做完，各种半途而废，各种不完美！</p><a id="more"></a><p>相关技术：</p><ul><li>PHP autoloader</li><li>PHP Namespace</li><li>composer</li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;准备阅读Slim源代码，先立各Flag看看自己能不能看下去，最近一件完整的事情都没做完，各种半途而废，各种不完美！&lt;/p&gt;
    
    </summary>
    
      <category term="立FLAG" scheme="https://hefengxian.github.io/categories/%E7%AB%8BFLAG/"/>
    
    
      <category term="PHP" scheme="https://hefengxian.github.io/tags/PHP/"/>
    
      <category term="RESTful" scheme="https://hefengxian.github.io/tags/RESTful/"/>
    
      <category term="Slim" scheme="https://hefengxian.github.io/tags/Slim/"/>
    
  </entry>
  
  <entry>
    <title>晚睡</title>
    <link href="https://hefengxian.github.io/2016/06/27/%E6%99%9A%E7%9D%A1/"/>
    <id>https://hefengxian.github.io/2016/06/27/晚睡/</id>
    <published>2016-06-27T14:37:47.000Z</published>
    <updated>2020-07-27T09:57:42.151Z</updated>
    
    <content type="html"><![CDATA[<blockquote><p>晚睡，是没有勇气结束这一天；赖床，是没有勇气开始这一天。</p></blockquote><p><img src="http://7d9jd9.com1.z0.glb.clouddn.com/wanshui.jpg" alt></p><p>每天晚睡挤出来的时间，其实第二天都是要还回去的。或许头一天多挤出几个小时活动，可能换来第二天一整天的昏昏沉沉，长期以往，恶性循环！<a id="more"></a></p><p>每天凌晨2点之后睡，然而并不是在做什么有意义的事，只是无聊的看社交软件，就是不想睡，总觉得这一天还有很多事没有做。</p><p>每次想写点什么，却发现胸无点墨！毕业2年了，好似无任何成就。</p><p>白天感觉厌恶工作，晚上睡不着，对任何事情都提不起兴趣。</p><p>其实大神，其实也并没有和我们不一样，别人只是把某件事坚持的做下去了而已。</p><p>每每看到穿衣显瘦，脱衣有肉的人，其实别人只是每天坚持锻炼而已。</p><p>每个人一天都是24小时；都是1440分钟；都是86400秒。为什么有的人碌碌无为，有的人分秒千金。</p><p>或许会说，别人天赋异禀、别人天生丽质；我努力了只能这样了，别人厉害是因为天赋。其实这个世界上99%的人都所做的努力都还没有到达需要拼天赋的程度。</p><p>努力变的优秀！</p><p>努力将优秀变为习惯！</p><p>或许就成功了呢！</p><p><strong><em>所以现在就开始吧！</em></strong></p>]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;晚睡，是没有勇气结束这一天；赖床，是没有勇气开始这一天。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://7d9jd9.com1.z0.glb.clouddn.com/wanshui.jpg&quot; alt&gt;&lt;/p&gt;
&lt;p&gt;每天晚睡挤出来的时间，其实第二天都是要还回去的。或许头一天多挤出几个小时活动，可能换来第二天一整天的昏昏沉沉，长期以往，恶性循环！
    
    </summary>
    
      <category term="发牢骚" scheme="https://hefengxian.github.io/categories/%E5%8F%91%E7%89%A2%E9%AA%9A/"/>
    
    
      <category term="感悟" scheme="https://hefengxian.github.io/tags/%E6%84%9F%E6%82%9F/"/>
    
      <category term="吐槽自己" scheme="https://hefengxian.github.io/tags/%E5%90%90%E6%A7%BD%E8%87%AA%E5%B7%B1/"/>
    
  </entry>
  
  <entry>
    <title>自行修改Hexo主题</title>
    <link href="https://hefengxian.github.io/2016/06/21/%E8%87%AA%E8%A1%8C%E4%BF%AE%E6%94%B9Hexo%E4%B8%BB%E9%A2%98/"/>
    <id>https://hefengxian.github.io/2016/06/21/自行修改Hexo主题/</id>
    <published>2016-06-21T15:46:45.000Z</published>
    <updated>2020-07-27T09:57:42.151Z</updated>
    
    <content type="html"><![CDATA[<p>折腾一下导航栏，相信很多用Hexo搭建博客的小伙伴们都使用了Apollo主题，这个主题配色简单大方，甚是喜爱。可是默认导航栏的样子是这样的<img src="http://7d9jd9.com1.z0.glb.clouddn.com/2016-06-23-org-nav.png" alt="Apollo默认导航栏" title="默认导航栏的样子">生命在于折腾，如何自定义导航栏呢？于是抽时间折腾了一下，变成了下面这样：<img src="http://7d9jd9.com1.z0.glb.clouddn.com/2016-06-23-nav-result.png" alt="修改之后的导航栏" title="修改之后的样子">记录一下如何折腾的，如果有遇到同样困难的小朋友或许可以参考一下<a id="more"></a></p><h4 id="1-删除主题子模块"><a href="#1-删除主题子模块" class="headerlink" title="1. 删除主题子模块"></a>1. 删除主题子模块</h4><p>先说一下博客项目的结构</p><ul><li>博客托管在<a href="https://coding.net" target="_blank" rel="noopener">Coding</a>的，使用<code>hexo generate</code>之后的静态文件是放在<code>coding-pages</code>分支</li><li>而博客的项目源文件我是直接保存在<code>master</code>分支的</li></ul><p>每次使用markdown写完文章，将源文件推送到<code>master</code>，然后将生成的静态页面发布到<code>coding-pages</code>。</p><p>如果按照<a href="https://github.com/pinggod/hexo-theme-apollo" target="_blank" rel="noopener">Apollo</a>主题官方的安装方式，使用<code>git clone</code>到<code>theme</code>文件夹，那么主题是一个匿名子模块（submodule）的方式存在于项目中的。如果是这样，我们修改主题文件会遇到问题，推送到<code>master</code>分支的文件是不包含子模块改动的，如果换一台电脑，<code>git clone/pull</code>下来的文件是不会包含主题改动的。保持子模块的好处是，如果Apollo主题的作者有更新主题，我们可以直接<code>cd</code>到子模块目录使用<code>git pull</code>更新即可。可是现在我们修改主题，那么我们则不再关注原主题是否更新了，所以要先删除主题作为子模块的存在，然后将修改的主题文件直接纳入博客项目源码的管理。删除子模块，在博客项目的根目录，执行如下代码<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git rm --cached themes/apollo</span><br></pre></td></tr></table></figure></p><p>再将主题目录下的文件add到git提交即可。</p><h4 id="2-修改主题配置文件"><a href="#2-修改主题配置文件" class="headerlink" title="2. 修改主题配置文件"></a>2. 修改主题配置文件</h4><p>找到apollo文件夹下的<code>_config.yml</code>文件，打开之后默认的目录数据结构是不满足我们修改要求的<figure class="highlight yaml"><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="attr">menu:</span></span><br><span class="line">    <span class="attr">Blog:</span> <span class="string">/</span></span><br><span class="line">    <span class="attr">Archive:</span> <span class="string">/archives/</span></span><br><span class="line">    <span class="attr">Weibo:</span> <span class="string">http://weibo.com/sunchongsheng</span></span><br><span class="line">    <span class="attr">GitHub:</span> <span class="string">https://github.com/pinggod</span></span><br><span class="line">    <span class="attr">Rss:</span> <span class="string">/atom.xml</span></span><br></pre></td></tr></table></figure></p><p>因为我们要为每个栏目配上图标。</p><p>但是发现这个<code>*.yml</code>有是个什么鬼文件？查一查发现，又有人发明了一个轮子叫<a href="https://zh.wikipedia.org/wiki/YAML" target="_blank" rel="noopener">YAML</a>。经查阅得知，YAML其实是包含JSON的，JSON是属于YAML的一个子集，意思就是我们可以直接写JSON格式；但是为了尊重这个轮子，我们还是用它新创建的语法更新一下我们的菜单结构<figure class="highlight yaml"><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="attr">menu:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Blog</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">fa</span> <span class="string">fa-home</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Archive</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/archives/</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">fa</span> <span class="string">fa-folder-open-o</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Weibo</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">http://weibo.com/fengxianhe</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">fa</span> <span class="string">fa-weibo</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">GitHub</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">https://github.com/hefengxian</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">fa</span> <span class="string">fa-github-alt</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Coding</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">https://coding.net/u/hfx</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">iconfont</span> <span class="string">coding</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">About</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/about/</span></span><br><span class="line">    <span class="attr">icon:</span> <span class="string">fa</span> <span class="string">fa-info-circle</span></span><br></pre></td></tr></table></figure></p><p>代码的意思大致就是一个包含多个对象的数组，其中<code>name</code>表示要菜单要显示的文字，<code>path</code>表示url路径，<code>icon</code>表示我们要使用的图标（Font Awesome 格式）。这样更新之后去看下结果，肯定是菜单都不见了，因为我们改了数据结构。</p><h4 id="3-修改其他相关模板文件"><a href="#3-修改其他相关模板文件" class="headerlink" title="3. 修改其他相关模板文件"></a>3. 修改其他相关模板文件</h4><p>Apollo使用的是JADE，但是我并不懂JADE，但是看看<code>themes/apollo/layout/partial/nav.jade</code>的代码，虽然没接触过，但是凭借对其他编程语言的理解大致可以猜出语法，那么我们做一下改动<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">ul.nav.nav-list</span><br><span class="line">    each value, key in theme.menu</span><br><span class="line">        li.nav-list-item</span><br><span class="line">            - var re = /^(http|https):\/\/*/gi;</span><br><span class="line">            - var tar = re.test(value.path) ? &quot;_blank&quot; : &quot;_self&quot;</span><br><span class="line">            a.nav-list-link(class=&#123;active: is_home() &amp;&amp; value.path === &quot;/&quot;&#125; href=value.path target=tar)</span><br><span class="line">                i(class=value.icon) &amp;nbsp;</span><br><span class="line">                != value.name</span><br></pre></td></tr></table></figure></p><p>使用hexo生成一下文件，看一下效果，发现菜单名字有了，但是还没有图标。</p><p>是因为我们还没有引入Font-Awesome相关的css文件，打开<code>themes/apollo/layout/partial/head.jade</code>，虽然还是不懂JADE是什么鬼，依葫芦画瓢，在原来的apollo.css那句后面或者前面加一句<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">link(rel=&quot;stylesheet&quot;, href=url_for(&quot;//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css&quot;))</span><br><span class="line">link(rel=&quot;stylesheet&quot;, href=url_for(&quot;css/apollo.css&quot;))</span><br></pre></td></tr></table></figure></p><p>在这里我用的是<a href="http://www.bootcdn.cn/" target="_blank" rel="noopener">bootcdn</a>的CDN。</p><p>再看一下，啊，大部分可以了，但是Font-Awesome这个项目并没有Coding的图标，但是我又很喜欢Coding，想把Coding放上去，那咋整呢？</p><p>以前记得淘宝好像有个字体图标的网站<a href="http://iconfont.cn/" target="_blank" rel="noopener">ICONFONT</a>，反正就是无意中发现的这么一个网站，往里面一搜coding，居然还真有人做了这个图标。</p><p>在网站上下载图标，按照文档，将字体文件复制到<code>themes/apollo/source/fonts/</code>目录下，在网站上下载图标，按照文档，将字体文件复制到<code>themes/apollo/source/fonts/</code>目录下,我们在目录<code>themes/apollo/source/css/</code>下加入<code>iconfont.css</code>文件<figure class="highlight css"><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="keyword">@font-face</span> &#123;</span><br><span class="line">    <span class="attribute">font-family</span>: <span class="string">"iconfont"</span>;</span><br><span class="line">    <span class="attribute">src</span>: <span class="built_in">url</span>(<span class="string">'../fonts/iconfont.eot?t=1466522057'</span>); <span class="comment">/* IE9*/</span></span><br><span class="line">    <span class="attribute">src</span>: <span class="built_in">url</span>(<span class="string">'../fonts/iconfont.eot?t=1466522057#iefix'</span>) <span class="built_in">format</span>(<span class="string">'embedded-opentype'</span>), <span class="comment">/* IE6-IE8 */</span></span><br><span class="line">    <span class="built_in">url</span>(<span class="string">'../fonts/iconfont.woff?t=1466522057'</span>) <span class="built_in">format</span>(<span class="string">'woff'</span>), <span class="comment">/* chrome, firefox */</span></span><br><span class="line">    <span class="built_in">url</span>(<span class="string">'../fonts/iconfont.ttf?t=1466522057'</span>) <span class="built_in">format</span>(<span class="string">'truetype'</span>), <span class="comment">/* chrome, firefox, opera, Safari, Android, iOS 4.2+*/</span></span><br><span class="line">    <span class="built_in">url</span>(<span class="string">'../fonts/iconfont.svg?t=1466522057#iconfont'</span>) <span class="built_in">format</span>(<span class="string">'svg'</span>); <span class="comment">/* iOS 4.1- */</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.iconfont</span> &#123;</span><br><span class="line">    <span class="attribute">font-family</span>:<span class="string">"iconfont"</span> <span class="meta">!important</span>;</span><br><span class="line">    <span class="attribute">font-size</span>:<span class="number">16px</span>;</span><br><span class="line">    <span class="attribute">font-style</span>:normal;</span><br><span class="line">    <span class="attribute">-webkit-font-smoothing</span>: antialiased;</span><br><span class="line">    <span class="attribute">-webkit-text-stroke-width</span>: <span class="number">0.2px</span>;</span><br><span class="line">    <span class="attribute">-moz-osx-font-smoothing</span>: grayscale;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.coding</span><span class="selector-pseudo">:before</span> &#123; <span class="attribute">content</span>: <span class="string">"\e604"</span>; &#125;</span><br></pre></td></tr></table></figure></p><p>我们将新加css文件引入到页面，打开<code>themes/apollo/layout/partial/head.jade</code>，和前面引入Font-Awesome一样<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">link(rel=&quot;stylesheet&quot;, href=url_for(&quot;//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css&quot;))</span><br><span class="line">link(rel=&quot;stylesheet&quot;, href=url_for(&quot;css/iconfont.css&quot;))</span><br><span class="line">link(rel=&quot;stylesheet&quot;, href=url_for(&quot;css/apollo.css&quot;))</span><br></pre></td></tr></table></figure></p><p>这个时候再看一下效果，发现图标已经有了，可是大小好像有问题，很小…，于是我们打开Chrome调试工具，调整<code>.iconfont</code>样式的字体大小，发现<code>20px</code>差不多，那么再次修改一下文件<code>iconfont.css</code><figure class="highlight css"><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="selector-class">.iconfont</span> &#123;</span><br><span class="line">    <span class="attribute">font-family</span>:<span class="string">"iconfont"</span> <span class="meta">!important</span>;</span><br><span class="line">    <span class="attribute">font-size</span>:<span class="number">20px</span>;</span><br><span class="line">    <span class="attribute">font-style</span>:normal;</span><br><span class="line">    <span class="attribute">-webkit-font-smoothing</span>: antialiased;</span><br><span class="line">    <span class="attribute">-webkit-text-stroke-width</span>: <span class="number">0.2px</span>;</span><br><span class="line">    <span class="attribute">-moz-osx-font-smoothing</span>: grayscale;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p><p>再刷新一下，终于可以了，得到了我们想要的结果。</p><p>多说一句，博客的Logo自己去找一个图片，保持格式名称一样（其实可以有其他的格式，但是自己可以去查一查favicon支持哪些格式），或者自己画一个替换<code>themes/apollo/source/favicon.png</code></p><p>参考资料：</p><ul><li>YAML <a href="https://zh.wikipedia.org/wiki/YAML" target="_blank" rel="noopener">YAML维基百科</a></li><li>JADE <a href="http://jade-lang.com/" target="_blank" rel="noopener">JADE官网</a></li><li>Font-Awesome <a href="http://fontawesome.io/" target="_blank" rel="noopener">font-awesome</a></li><li>淘宝 ICONFONT <a href="http://iconfont.cn/" target="_blank" rel="noopener">ICONFONT</a></li></ul>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;折腾一下导航栏，相信很多用Hexo搭建博客的小伙伴们都使用了Apollo主题，这个主题配色简单大方，甚是喜爱。可是默认导航栏的样子是这样的
&lt;img src=&quot;http://7d9jd9.com1.z0.glb.clouddn.com/2016-06-23-org-nav.png&quot; alt=&quot;Apollo默认导航栏&quot; title=&quot;默认导航栏的样子&quot;&gt;
生命在于折腾，如何自定义导航栏呢？于是抽时间折腾了一下，变成了下面这样：
&lt;img src=&quot;http://7d9jd9.com1.z0.glb.clouddn.com/2016-06-23-nav-result.png&quot; alt=&quot;修改之后的导航栏&quot; title=&quot;修改之后的样子&quot;&gt;
记录一下如何折腾的，如果有遇到同样困难的小朋友或许可以参考一下
    
    </summary>
    
      <category term="折腾" scheme="https://hefengxian.github.io/categories/%E6%8A%98%E8%85%BE/"/>
    
    
      <category term="折腾" scheme="https://hefengxian.github.io/tags/%E6%8A%98%E8%85%BE/"/>
    
      <category term="Hexo" scheme="https://hefengxian.github.io/tags/Hexo/"/>
    
      <category term="Theme" scheme="https://hefengxian.github.io/tags/Theme/"/>
    
  </entry>
  
  <entry>
    <title>停止完美主义</title>
    <link href="https://hefengxian.github.io/2016/06/21/%E5%81%9C%E6%AD%A2%E5%AE%8C%E7%BE%8E%E4%B8%BB%E4%B9%89/"/>
    <id>https://hefengxian.github.io/2016/06/21/停止完美主义/</id>
    <published>2016-06-21T13:39:33.000Z</published>
    <updated>2020-07-27T09:57:42.151Z</updated>
    
    <content type="html"><![CDATA[<p>为什么一直觉得自己效率低下！因为每次都在项目中钻牛角尖。比如，为了一个小小padding样式，一个小小的动画或者切换效果，调试纠结老半天，一不小心就一个上午过去了，往往导致主要的业务逻辑无法按时完成，项目延期…</p><a id="more"></a><p>在实际项目中往往时间都严重不够，老板/领导/客户可能最希望是再最短的时间出结果，是不是做到最好的架构、最漂亮的界面、最完美的用户体验，大家根本就步不Care。大家关心的是项目能不能在Deadline之前交付，能不能收到钱，你能不能完成任务。</p><p>或许有人会说，Steve Jobs的完美主义和偏执才成就Apple霸主地位，其实真实的是，没有那个金刚钻也揽不了那个活；那种偏执和完美不是一般人一般的公司可以消耗得起的。</p><p>现实是：往往因为追求完美导致工期延误效率低下甚至项目失败，大家得到利益和效率的最大化才是核心重点。</p><p>所以正确的方式应该是： <code>快速迭代</code></p><p>就像画画，先画出骨架！再完善细节。</p><p>项目中，应当先完成主要架构、核心流程和功能。然后发布预览版，与客户和项目经理进行确认；然后根据提出的意见和建议进行修正，迭代开发；而且好处显而易见，避免方向和架构上与实际需求之间的偏差，就算有亦可以早发现早修正，降低开发成本。</p><p>完美主义可能会导致花了大量的时间和精力做出来的功能，却不是需求方想要的，这个时候纠正的成本也非常巨大。</p><p>实际项目中，绝大部分时候，需求方自己其实也不知道自己需要的是什么，这个时候快速迭代的好处就显而易见了，可以进行多次的测试、反馈、修复，达到项目成功交付的目的。</p><blockquote><p>完美主义者有如下问题：</p><ul><li>在一项任务花费的时间比任务要求的时间多</li><li>会选择拖延到最佳的时刻。在企业中，如果这是最完美的时刻，就代表已经太迟了。</li><li>过度聚焦细节却忽略整体</li></ul></blockquote><blockquote><p>如果市场人员等待最好时机，最终将失去机会</p></blockquote><p><strong><em>最好的时机就是现在</em></strong></p><p>所以自己一定要改掉这个毛病！！！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;为什么一直觉得自己效率低下！因为每次都在项目中钻牛角尖。比如，为了一个小小padding样式，一个小小的动画或者切换效果，调试纠结老半天，一不小心就一个上午过去了，往往导致主要的业务逻辑无法按时完成，项目延期…&lt;/p&gt;
    
    </summary>
    
      <category term="发牢骚" scheme="https://hefengxian.github.io/categories/%E5%8F%91%E7%89%A2%E9%AA%9A/"/>
    
    
      <category term="感悟" scheme="https://hefengxian.github.io/tags/%E6%84%9F%E6%82%9F/"/>
    
  </entry>
  
  <entry>
    <title>你的精力分配决定你的层次</title>
    <link href="https://hefengxian.github.io/2016/06/20/%E4%BD%A0%E7%9A%84%E7%B2%BE%E5%8A%9B%E5%88%86%E9%85%8D%E5%86%B3%E5%AE%9A%E4%BD%A0%E7%9A%84%E5%B1%82%E6%AC%A1/"/>
    <id>https://hefengxian.github.io/2016/06/20/你的精力分配决定你的层次/</id>
    <published>2016-06-20T11:45:47.000Z</published>
    <updated>2020-07-27T09:57:42.150Z</updated>
    
    <content type="html"><![CDATA[<p>今天由于重新布置博客的原因，看了一些自己转发的微博，看到了一个长文《你的精力分配觉得你的层次》，文章写的很好我也转发了，而我却并没有印象。结合今天看到 <a href="http://stormzhang.com/" target="_blank" rel="noopener">stormzhang</a> 的文章<a href="http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&amp;mid=2650661932&amp;idx=1&amp;sn=8325f8bd782a376434a5bf69e4f38dee#rd" target="_blank" rel="noopener">少年，别再收藏文章了！</a>才觉得自己原来挺可笑的。</p><p>看了那么多的信息：微博/空间/朋友圈/知乎，原来也只是看了就看了而已；可以总结为“过目即忘”。那我阅读那些的意义在哪里？</p><a id="more"></a><ul><li><p>牺牲了那么多的时间，睡眠的时间，学习的时间；只是看了一些穿肠而过的文字。收藏了那么多，原来都没有去看而已</p></li><li><p>去年买了那么多书，其实一本都没有看，花钱了，只是买了个心安；达到骗自己的目的。</p></li><li><p>每天花3个小时以上在打游戏，导致坐着的时间太长，保持一个姿势不变伤害自己的身体，每天晚睡，每天起床像要命，导致工作效率极度下降。</p></li><li><p>暴饮暴食，体质下降，体重上升</p></li></ul><blockquote><p>经济学有一个概念，叫“机会成本”。“机会成本”是指为了得到某种东西而所要放弃另一些东西的最大价值。比方说你有100块钱，能吃一顿饭，也能看一场电影，你去看电影了你的机会成本就是一顿饭。又如你周末两天可以用来打Dota，也可以用来看《论语》，你去看《论语》了，打Dota及其快乐就是你的机会成本。</p></blockquote><blockquote><p>换句话来说，做的事情价值的多少，是由放弃的事情反映出来的，而放弃事情，也是由做的事情反映出来的。</p></blockquote><blockquote><p>总之什么样的人，什么样的人，价值如何的人或者事，可以从他的选择中判断出来：你放弃了做什么而选择了做什么。你的心中孰轻孰重，孰优孰劣，在你的实际行动诠释下，一切语言都是苍白无力的：你做了什么，你就是什么，值什么。</p></blockquote><p>如果为了一块糖和朋友大打出手，你们俩的友谊和你的好朋友就值这块糖；如果你因为电影票钱和女朋友斤斤计较导致分开，你俩的爱情和你的爱人就值这电影票钱；如果一个廉价花瓶碎了，打得孩子再也 不敢自由的玩耍，你孩子的好奇心也就值这个花瓶。</p><blockquote><p>每个人的时间就这么多，精力就这么少，你分给价值Low的事，为了价值Low的事来回折腾，只能说你没有对你来说没有更有价值的事情投入精力，或者干脆说你就是各价值Low的人</p></blockquote><p>所以每当自己在电脑前没日没夜的打游戏时，甚至为了游戏里的某些事情大发雷霆时，其实自己的价值就是值这些毫无意义的事情。如果仍然觉得薪水没有涨，工作效率还是那么底下，技术水平还是那么Low的时候，或许应该明白原因在哪里了！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;今天由于重新布置博客的原因，看了一些自己转发的微博，看到了一个长文《你的精力分配觉得你的层次》，文章写的很好我也转发了，而我却并没有印象。结合今天看到 &lt;a href=&quot;http://stormzhang.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stormzhang&lt;/a&gt; 的文章&lt;a href=&quot;http://mp.weixin.qq.com/s?__biz=MzA4NTQwNDcyMA==&amp;amp;mid=2650661932&amp;amp;idx=1&amp;amp;sn=8325f8bd782a376434a5bf69e4f38dee#rd&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;少年，别再收藏文章了！&lt;/a&gt;才觉得自己原来挺可笑的。&lt;/p&gt;
&lt;p&gt;看了那么多的信息：微博/空间/朋友圈/知乎，原来也只是看了就看了而已；可以总结为“过目即忘”。那我阅读那些的意义在哪里？&lt;/p&gt;
    
    </summary>
    
      <category term="发牢骚" scheme="https://hefengxian.github.io/categories/%E5%8F%91%E7%89%A2%E9%AA%9A/"/>
    
    
      <category term="感悟" scheme="https://hefengxian.github.io/tags/%E6%84%9F%E6%82%9F/"/>
    
      <category term="心情" scheme="https://hefengxian.github.io/tags/%E5%BF%83%E6%83%85/"/>
    
      <category term="作" scheme="https://hefengxian.github.io/tags/%E4%BD%9C/"/>
    
  </entry>
  
</feed>
