<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>灯半昏月半明</title>
  
  <subtitle>Programming The World...</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://slw.im/"/>
  <updated>2026-06-09T06:04:57.748Z</updated>
  <id>https://slw.im/</id>
  
  <author>
    <name>Ryo Shen</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>2023年阅读书单</title>
    <link href="https://slw.im/2023/09/2023-reading-list/"/>
    <id>https://slw.im/2023/09/2023-reading-list/</id>
    <published>2023-09-10T07:14:22.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/reading.jpg" alt="Photo"></p><h1 id="读完"><a href="#读完" class="headerlink" title="读完"></a>读完</h1><ul><li><a href="https://book.douban.com/subject/35293067/">一人企业</a> - 企业不一定需要盲目扩张，保持小规模，能具有足够的灵活性和适应性。给企业设定上限，而后有自由对别人期待的事或者对你毫无用处的机会说不。</li><li><a href="https://book.douban.com/subject/26576861/">最好的告别</a> - 几度落泪。对于生命的最后一刻，我们该如何正视它，与亲人陪伴，“Being Mortal”。</li></ul><h1 id="在读"><a href="#在读" class="headerlink" title="在读"></a>在读</h1><ul><li><a href="https://book.douban.com/subject/36415996/">金钱心理学</a></li><li><a href="https://book.douban.com/subject/36247470/">寻找百忧解</a></li><li><a href="https://book.douban.com/subject/35594496/">福格行为模型</a></li></ul><blockquote><p>Photo from <a href="https://unsplash.com/photos/XqXJJhK-c08">Unsplash</a></p></blockquote>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;img src=&quot;/images/reading.jpg&quot; alt=&quot;Photo&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;读完&quot;&gt;&lt;a href=&quot;#读完&quot; class=&quot;headerlink&quot; title=&quot;读完&quot;&gt;&lt;/a&gt;读完&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http
      
    
    </summary>
    
    
    
      <category term="阅读" scheme="https://slw.im/tags/%E9%98%85%E8%AF%BB/"/>
    
  </entry>
  
  <entry>
    <title>ANTLR4 笔记</title>
    <link href="https://slw.im/2023/09/antlr4-notes/"/>
    <id>https://slw.im/2023/09/antlr4-notes/</id>
    <published>2023-09-03T15:15:16.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>ANTLR（ANother Tool for Language Recognition）是一个强大的语言识别工具，用于构建语法分析器、解析器和编译器。它能够根据语法规则生成解析器代码，并且能够处理从简单的配置文件到复杂的编程语言的各种语法。</p><p>ANTLR 提供了一个功能丰富的工具集，支持多种编程语言，包括 Java、C#、Python、 JavaScript、TypeScript 等，可以在<a href="https://github.com/antlr/antlr4#authors-and-major-contributors">这里</a>查看支持的语言。ANTLR 使用 LL(*) 解析，可以自动构建解析树，并生成监听器（Listener）和访问者（Visitor），支持上下文无关文法（Context-Free Grammar，CFG）。</p><p>ANTLR 可以处理直接左递归文法，但是无法处理间接左递归文法，例如：S-&gt;A, A-&gt;S。</p><h1 id="主要特点"><a href="#主要特点" class="headerlink" title="主要特点"></a>主要特点</h1><ol><li><p><strong>语法规则定义</strong>：ANTLR 使用类似于 EBNF（扩展巴科斯范式）的语法规则来定义语言的语法结构。它的语法规则清晰易懂，支持嵌套规则、重复和可选元素等。</p></li><li><p><strong>语法分析器生成</strong>：基于语法规则，ANTLR 可以生成解析器代码，可以是针对特定目标语言的解析器。生成的解析器可以将输入的文本解析为抽象语法树（Abstract Syntax Tree，AST）或其他形式的语法结构。</p></li><li><p><strong>语法分析器动作</strong>：ANTLR 支持在语法规则中添加语义动作（semantic action），使用户能够在解析过程中执行自定义的代码逻辑。这样可以将解析和语义处理结合起来。</p></li><li><p><strong>错误处理</strong>：ANTLR 提供灵活的错误处理机制，可以定义和处理语法错误、警告和诊断信息。它可以生成具有恢复能力的解析器，能够在遇到错误时继续解析输入，并收集错误信息。</p></li><li><p><strong>监听器和访问者模式</strong>：ANTLR 支持两种处理解析树的模式，即监听器模式（Listener Pattern）和访问者模式（Visitor Pattern）。这些模式使用户能够以不同的方式遍历和处理解析树。</p></li></ol><h1 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h1><p><img src="/images/antlr-conception.png" alt="基本概念"></p><ol><li><p><strong>词法分析器（Lexer）</strong><br>词法分析器里，每个关键字是一个标记（Token），每个标识符是一个 Token，每个操作符是一个 Token，每个标点符号也都是一个 Token。除此之外，还会过滤掉源程序中的注释和空白字符（换行符、空格、制表符等）。</p></li><li><p><strong>语法解析器（Parser）</strong><br>语法分析会将词法分析出来的 Token 根据某种给定的形式文法对由单词序列（如英语单词序列）构成的输入文本进行分析并确定其语法结构的一种过程，并转化成有语法含义的抽象语法树结构。</p></li><li><p><strong>抽象语法树（Abstract Syntax Tree，AST）</strong><br>抽象语法数是源代码语法结构的一种抽象表示，以树状的形式表现编程语言的语法结构，树上的每个节点都表示源代码中的一种结构。</p></li></ol><p><img src="/images/ast.svg" alt="抽象语法树 AST"></p><h1 id="监听器和访问器"><a href="#监听器和访问器" class="headerlink" title="监听器和访问器"></a>监听器和访问器</h1><p>ANTLR 提供了两种树遍历机制的支持，其实现包含在其运行库中。ANTLR生成的语法分析树 Listener 接口是默认的实现，其中定义了回调方法，用于响应内置树遍历器触发的事件。</p><p>Listener 和 Visitor 都采用深度优先算法，并提供了一种简单且标准的方法来处理解析树。这种标准方法可以避免在文法文件中嵌入繁琐的动作，从而将解析与应用逻辑代码分离。这种方法不仅使文法的定义更加简洁清晰，还能够在不重新编译生成语法分析器的情况下复用相同的语法，并且可以采用不同的程序语言来实现这些动作。</p><p>Listener 和 Visitor 机制之间最大的区别在于，监听器会使用ANTLR提供的遍历器，通过节点监听，调用对应的 Listener 方法，而 Visitor 方法必须显式地调用 visit 方法来主动遍历其子节点。如果在节点的子节点上忘记调用 visit 方法，那么这些子树将无法被访问。</p><h2 id="监听器"><a href="#监听器" class="headerlink" title="监听器"></a>监听器</h2><p>ANTLR 提供了 ParseTreeWalker 类，该类可以自动遍历树并生成事件，然后调用监听器。对于每个语法文件，ANTLR 会生成一个 ParseTreeListener 的子类，其中每个规则都有对应的 enter 方法和 exit 方法，这些方法也称为“事件方法”。这些方法的参数是 xxxContext，提供了该方法所需的所有信息。监听器的操作逻辑可以在这些 enter 和 exit 方法中添加。下图展示了 ParseTreeWalker 对监听器方法的完整调用顺序。</p><p><img src="/images/antlr-listener.jpg" alt="监听器"></p><h2 id="访问器"><a href="#访问器" class="headerlink" title="访问器"></a>访问器</h2><p>有时候我们希望手动控制遍历树的过程，并通过显式调用方法来访问子节点。通过在命令行中添加 -visitor 选项，可以指示 ANTLR 为语法生成访问器接口，其中每个规则对应于接口中的一个 visit 方法。ANTLR 提供了访问器接口和一个默认实现类，这样只需要覆盖接口中需要重写的方法即可。</p><p><img src="/images/antlr-visitor.jpg" alt="访问器"></p><h1 id="ANTLR-案例"><a href="#ANTLR-案例" class="headerlink" title="ANTLR 案例"></a>ANTLR 案例</h1><p>下面的案例将通过一个简单的例子，讲解如何使用访问器（Visitor）对输入的表达式进行加减乘除的运算，例子将使用 Java 的 Decimal 类对数字进行运算。</p><p>案例中<strong>源代码</strong>可以在 GitHub 上获得：<a href="https://github.com/lwshen/antlr-demo">antlr-demo</a></p><h2 id="定义-DSL-语法"><a href="#定义-DSL-语法" class="headerlink" title="定义 DSL 语法"></a>定义 DSL 语法</h2><p>创建<code>Expression.g4</code>文件，其中定义了语法和 Token。</p><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><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs dts"><span class="hljs-comment">// 定义了 grammar 的名字，名字需要与文件名对应</span><br>grammar E<span class="hljs-attr">xpression</span><span class="hljs-punctuation">;</span><br>@<span class="hljs-title class_">header</span> <span class="hljs-punctuation">&#123;</span><br><span class="hljs-comment">// 定义package</span><br>package org.example.<span class="hljs-attr">parser</span><span class="hljs-punctuation">;</span><br><span class="hljs-punctuation">&#125;</span><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * parser</span><br><span class="hljs-comment"> * calc 和 expr 就是定义的语法，会使用到下方定义的词法</span><br><span class="hljs-comment"> * 注意 # 后面的名字，是可以在后续访问和处理的时候使用的。</span><br><span class="hljs-comment"> * 一个语法有多种规则的时候可以使用 | 来进行配置。</span><br><span class="hljs-comment"> */</span><br><br>calc<br>  : expr EOF                                    <span class="hljs-meta"># calculationBlock</span><br>  <span class="hljs-punctuation">;</span><br><span class="hljs-comment">// 四则运算分为了两个非常相似的语句，这样做的原因是为了实现优先级，乘除是优先级高于加减的。</span><br>expr<br>  : BR_OPEN expr BR_CLOSE                                    <span class="hljs-meta"># expressionWithBr</span><br>  | <span class="hljs-attr">sign</span><span class="hljs-operator">=</span>(PLUS|MINUS)? <span class="hljs-attr">num</span><span class="hljs-operator">=</span>(NUMBER|PERCENT_NUMBER)           <span class="hljs-meta"># expressionNumeric</span><br>  | expr <span class="hljs-attr">op</span><span class="hljs-operator">=</span>(TIMES | DIVIDE) expr                            <span class="hljs-meta"># expressionTimesOrDivide</span><br>  | expr <span class="hljs-attr">op</span><span class="hljs-operator">=</span>(PLUS | MINUS) expr                              <span class="hljs-meta"># expressionPlusOrMinus</span><br>  <span class="hljs-punctuation">;</span><br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * lexer</span><br><span class="hljs-comment"> */</span><br><span class="hljs-symbol"></span><br><span class="hljs-symbol">BR_OPEN:</span>   <span class="hljs-string">&#x27;(&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">BR_CLOSE:</span>  <span class="hljs-string">&#x27;)&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">PLUS:</span>      <span class="hljs-string">&#x27;+&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">MINUS:</span>     <span class="hljs-string">&#x27;-&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">TIMES:</span>     <span class="hljs-string">&#x27;*&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">DIVIDE:</span>    <span class="hljs-string">&#x27;/&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">POW:</span>       <span class="hljs-string">&#x27;^&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">PERCENT:</span>   <span class="hljs-string">&#x27;%&#x27;</span><span class="hljs-punctuation">;</span><br><span class="hljs-symbol">POINT:</span>     <span class="hljs-string">&#x27;.&#x27;</span><span class="hljs-punctuation">;</span><br><br><span class="hljs-comment">// 定义百分数</span><br>PERCENT_NUMBER<br>  : NUMBER ((<span class="hljs-string">&#x27; &#x27;</span>)? PERCENT)<br>  <span class="hljs-punctuation">;</span><br><br>NUMBER<br>  : DIGIT+ ( POINT DIGIT+ )?<br>  <span class="hljs-punctuation">;</span><br><br>DIGIT<br>  : [<span class="hljs-number">0</span><span class="hljs-number">-9</span>]+<br>  <span class="hljs-punctuation">;</span><br><br><span class="hljs-comment">// 定义了空白字符，后面的 skip 是一个特殊的标记，标记空白字符会被忽略</span><br>SPACE<br>  : <span class="hljs-string">&#x27; &#x27;</span> -&gt; skip<br>  <span class="hljs-punctuation">;</span><br></code></pre></td></tr></table></figure><h2 id="生成-Visitor-文件"><a href="#生成-Visitor-文件" class="headerlink" title="生成 Visitor 文件"></a>生成 Visitor 文件</h2><p>执行下面的命令，让 ANTLR 生成 Visitor 接口及其默认实现，其中 -o 参数指明输出文件的位置，-vistor 表明需要生成 Visitor 接口，-no-listener 则是表明不需要默认生成的 Listener 相关的代码。</p><figure class="highlight awk"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs awk">antlr4 -o src<span class="hljs-regexp">/main/</span>java<span class="hljs-regexp">/org/</span>example/parser -visitor -no-listener Expression.g4<br></code></pre></td></tr></table></figure><h2 id="实现计算逻辑"><a href="#实现计算逻辑" class="headerlink" title="实现计算逻辑"></a>实现计算逻辑</h2><p>接下来我们需要重写 ANTLR 生成的方法，对输入的数字进行运算。首先新建一个类<code>BigDecimalExpressionVisitor</code>，需要继承 ANTLR 生成的<code>ExpressionBaseVisitor</code>。</p><p>下面的代码将简单展示对加法和减法进行重写，使其支持通过 Decimal 计算出结果。详细的代码和文件可以在<a href="https://github.com/lwshen/antlr-demo/blob/main/src/main/java/org/example/BigDecimalExpressionVisitor.java">GitHub 上</a>获得。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-meta">@Override</span><br><span class="hljs-keyword">public</span> BigDecimal <span class="hljs-title function_">visitExpressionPlusOrMinus</span><span class="hljs-params">(ExpressionParser.ExpressionPlusOrMinusContext ctx)</span> &#123;<br>    <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">left</span> <span class="hljs-operator">=</span> visit(ctx.expr(<span class="hljs-number">0</span>));<br>    <span class="hljs-type">BigDecimal</span> <span class="hljs-variable">right</span> <span class="hljs-operator">=</span> visit(ctx.expr(<span class="hljs-number">1</span>));<br>    <span class="hljs-keyword">switch</span> (ctx.op.getType()) &#123;<br>        <span class="hljs-keyword">case</span> ExpressionLexer.PLUS:<br>        <span class="hljs-keyword">return</span> left.add(right, MATH_CONTEXT);<br>        <span class="hljs-keyword">case</span> ExpressionLexer.MINUS:<br>        <span class="hljs-keyword">return</span> left.subtract(right, MATH_CONTEXT);<br>        <span class="hljs-keyword">default</span>:<br>        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RuntimeException</span>(<span class="hljs-string">&quot;unsupported operator type&quot;</span>);<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="调用代码"><a href="#调用代码" class="headerlink" title="调用代码"></a>调用代码</h2><p>当我们写好计算逻辑后，就可以进行调用了，这里通过 <code>Calculator</code> 的 <code>execute</code> 方法进行调用。代码如下：</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Calculator</span> &#123;<br>  <span class="hljs-keyword">public</span> BigDecimal <span class="hljs-title function_">execute</span><span class="hljs-params">(String expression)</span> &#123;<br>    <span class="hljs-type">CharStream</span> <span class="hljs-variable">cs</span> <span class="hljs-operator">=</span> CharStreams.fromString(expression);<br>    <span class="hljs-type">ExpressionLexer</span> <span class="hljs-variable">lexer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ExpressionLexer</span>(cs);<br>    <span class="hljs-type">CommonTokenStream</span> <span class="hljs-variable">tokens</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">CommonTokenStream</span>(lexer);<br>    <span class="hljs-type">ExpressionParser</span> <span class="hljs-variable">parser</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ExpressionParser</span>(tokens);<br>    ExpressionParser.<span class="hljs-type">CalcContext</span> <span class="hljs-variable">context</span> <span class="hljs-operator">=</span> parser.calc();<br>    <span class="hljs-type">BigDecimalExpressionVisitor</span> <span class="hljs-variable">visitor</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BigDecimalExpressionVisitor</span>();<br>    <span class="hljs-keyword">return</span> visitor.visit(context);<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>当我们输入 <code>1+2</code> 时，就可以得到 <code>3</code> 作为结果。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">String</span> <span class="hljs-variable">expression</span> <span class="hljs-operator">=</span> <span class="hljs-string">&quot;1+2&quot;</span>;<br><span class="hljs-type">Calculator</span> <span class="hljs-variable">calculator</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Calculator</span>();<br>System.out.println(calculator.execute(expression));<br><span class="hljs-comment">// output: 3</span><br></code></pre></td></tr></table></figure><h1 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h1><p>ANTLR 还有很多高级用法，比如 Channel、内嵌代码等，这里就不做介绍了，各位有兴趣可以自行了解。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;简介&quot;&gt;&lt;a href=&quot;#简介&quot; class=&quot;headerlink&quot; title=&quot;简介&quot;&gt;&lt;/a&gt;简介&lt;/h1&gt;&lt;p&gt;ANTLR（ANother Tool for Language Recognition）是一个强大的语言识别工具，用于构建语法分析器、解析器
      
    
    </summary>
    
    
    
  </entry>
  
  <entry>
    <title>Go 小册</title>
    <link href="https://slw.im/2022/01/go-book/"/>
    <id>https://slw.im/2022/01/go-book/</id>
    <published>2022-01-21T15:14:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/images/GoHeader.jpeg" alt="Go小册"></p><h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><h2 id="官网"><a href="#官网" class="headerlink" title="官网"></a>官网</h2><p>最快捷的方法就是去官网 <a href="https://golang.org/">https://golang.org/</a> 下载对应的安装包进行安装，不过官网偶尔会访问不了，因此，也可以通过镜像网站进行下载。</p><ul><li><a href="https://golang.google.cn/dl/">https://golang.google.cn/dl/</a></li><li><a href="https://gomirrors.org/">https://gomirrors.org/</a></li></ul><h2 id="Go-Module-加速镜像"><a href="#Go-Module-加速镜像" class="headerlink" title="Go Module 加速镜像"></a>Go Module 加速镜像</h2><p>以下是几个速度不错的提供者：</p><ul><li>七牛：<a href="https://goproxy.cn/">Goproxy 中国 https://goproxy.cn</a></li><li>阿里： <a href="mirrors.aliyun.com/goproxy/">mirrors.aliyun.com/goproxy/</a></li><li>官方： <a href="https://goproxy.io/">全球 CDN 加速 https://goproxy.io/</a></li></ul><h3 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h3><h4 id="类-Unix"><a href="#类-Unix" class="headerlink" title="类 Unix"></a>类 Unix</h4><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></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-comment"># 启用 Go Modules 功能</span><br>go <span class="hljs-built_in">env</span> -w GO111MODULE=on<br><br><span class="hljs-comment"># 配置 GOPROXY 环境变量，以下三选一</span><br><br><span class="hljs-comment"># 1. 七牛 CDN</span><br>go <span class="hljs-built_in">env</span> -w  GOPROXY=https://goproxy.cn,direct<br><br><span class="hljs-comment"># 2. 阿里云</span><br>go <span class="hljs-built_in">env</span> -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct<br><br><span class="hljs-comment"># 3. 官方</span><br>go <span class="hljs-built_in">env</span> -w  GOPROXY=https://goproxy.io,direct<br></code></pre></td></tr></table></figure><p>确认一下：</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs vim"><span class="hljs-keyword">go</span> env | <span class="hljs-keyword">grep</span> GOPROXY<br>GOPROXY=<span class="hljs-string">&quot;https://goproxy.cn&quot;</span><br></code></pre></td></tr></table></figure><h4 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h4><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs elixir"><span class="hljs-comment"># 启用 Go Modules 功能</span><br><span class="hljs-variable">$env</span><span class="hljs-symbol">:GO111MODULE=<span class="hljs-string">&quot;on&quot;</span></span><br><br><span class="hljs-comment"># 配置 GOPROXY 环境变量，以下三选一</span><br><br><span class="hljs-comment"># 1. 七牛 CDN</span><br><span class="hljs-variable">$env</span><span class="hljs-symbol">:GOPROXY=<span class="hljs-string">&quot;https://goproxy.cn,direct&quot;</span></span><br><br><span class="hljs-comment"># 2. 阿里云</span><br><span class="hljs-variable">$env</span><span class="hljs-symbol">:GOPROXY=<span class="hljs-string">&quot;https://mirrors.aliyun.com/goproxy/,direct&quot;</span></span><br><br><span class="hljs-comment"># 3. 官方</span><br><span class="hljs-variable">$env</span><span class="hljs-symbol">:GOPROXY=<span class="hljs-string">&quot;https://goproxy.io,direct&quot;</span></span><br></code></pre></td></tr></table></figure><h1 id="基础-Go-命令"><a href="#基础-Go-命令" class="headerlink" title="基础 Go 命令"></a>基础 Go 命令</h1><h2 id="初始化"><a href="#初始化" class="headerlink" title="初始化"></a>初始化</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs go"><span class="hljs-keyword">go</span> mod init github.com/lwshen/module-mode<br></code></pre></td></tr></table></figure><h2 id="升级-降级依赖"><a href="#升级-降级依赖" class="headerlink" title="升级/降级依赖"></a>升级/降级依赖</h2><p>查看所有可用版本：</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs vim"><span class="hljs-keyword">go</span> <span class="hljs-keyword">list</span> -<span class="hljs-keyword">m</span> -versions github.<span class="hljs-keyword">com</span>/sirupsen/logrus<br></code></pre></td></tr></table></figure><p>方式一：</p><figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs swift">go <span class="hljs-keyword">get</span> github.com<span class="hljs-regexp">/sirupsen/</span>logrus<span class="hljs-meta">@v1</span>.<span class="hljs-number">7.0</span><br></code></pre></td></tr></table></figure><p>方式二：</p><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs vim"><span class="hljs-keyword">go</span> <span class="hljs-keyword">mod</span> <span class="hljs-keyword">edit</span> -require=github.<span class="hljs-keyword">com</span>/sirupsen/logrus@v1.<span class="hljs-number">7.1</span><br><span class="hljs-keyword">go</span> <span class="hljs-keyword">mod</span> tidy<br></code></pre></td></tr></table></figure><h3 id="删除依赖"><a href="#删除依赖" class="headerlink" title="删除依赖"></a>删除依赖</h3><p><code>go build</code> 不会去删除依赖，因此需要 <code>go mod tidy</code> 对依赖进行整理。</p><figure class="highlight maxima"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs maxima"><span class="hljs-built_in">go</span> <span class="hljs-built_in">mod</span> tidy<br></code></pre></td></tr></table></figure><h3 id="使用-vendor"><a href="#使用-vendor" class="headerlink" title="使用 vendor"></a>使用 vendor</h3><p>如果在内部网络不方便使用 Go Module 进行构建时，依旧可以使用 vendor 进行本地的依赖管理。可以通过以下命令创建 vendor：</p><figure class="highlight maxima"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs maxima"><span class="hljs-built_in">go</span> <span class="hljs-built_in">mod</span> vendor<br></code></pre></td></tr></table></figure><p>如果我们要基于 vendor 构建，而不是基于本地缓存的 Go Module 构建，我们需要在 <code>go build</code> 后面加上 <code>-mod=vendor</code> 参数。</p><p>在 Go 1.14 及以后版本中，如果 Go 项目的顶层目录下存在 vendor 目录，那么 <code>go build</code> 默认也会优先基于 vendor 构建，除非你给 go build 传入 <code>-mod=mod</code> 的参数。</p><h1 id="Go-Module-构建模式"><a href="#Go-Module-构建模式" class="headerlink" title="Go Module 构建模式"></a>Go Module 构建模式</h1><h2 id="语义版本导入机制"><a href="#语义版本导入机制" class="headerlink" title="语义版本导入机制"></a>语义版本导入机制</h2><p><img src="/images/pasted-10.png" alt="Go 语义版本号"></p><p>语义版本号分成 3 部分：主版本号 (major)、次版本号 (minor)和补丁版本号 (patch)。</p><p>Go Module 规定：<strong>如果同一个包的新旧版本是兼容的，那么它们的包导入路径应该是相同的</strong>。</p><p>例如：v1.8.1能够兼容老版本的v1.8.0和v1.7.0，而v2.0.0的包根据语义版本的规则，则与v1.8.1和v1.7.0不兼容。</p><p>因而，我们可以同时依赖一个包的两个不兼容版本：</p><figure class="highlight arcade"><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><code class="hljs arcade"><span class="hljs-keyword">import</span> (<br><span class="hljs-string">&quot;github.com/sirupsen/logrus&quot;</span><br>    logv2 <span class="hljs-string">&quot;github.com/sirupsen/logrus/v2&quot;</span><br>)<br></code></pre></td></tr></table></figure><h2 id="最小版本选择原则"><a href="#最小版本选择原则" class="headerlink" title="最小版本选择原则"></a>最小版本选择原则</h2><p><img src="/images/pasted-11.png" alt="复杂依赖关系的版本原则"></p><p>在这张图中，myproject 有两个直接依赖 A 和 B，A 和 B 有一个共同的依赖包 C，但 A 依赖 C 的 v1.1.0 版本，而 B 依赖的是 C 的 v1.3.0 版本，并且此时 C 包的最新发布版为 v1.7.0。</p><p>其实，当前存在的主流编程语言，以及 Go Module 出现之前的很多 Go 包依赖管理工具都会选择依赖项的<strong>“最新最大 (Latest Greatest) 版本”</strong>，对应到图中的例子，这个版本就是 v1.7.0。</p><p>Go 会在该项目依赖项的所有版本中，选出<strong>符合项目整体要求的“最小版本”</strong>。这个例子中，C v1.3.0 是符合项目整体要求的版本集合中的版本最小的那个，于是 Go 命令选择了 C v1.3.0，而不是最新最大的 C v1.7.0。</p><h1 id="Go-初始化顺序"><a href="#Go-初始化顺序" class="headerlink" title="Go 初始化顺序"></a>Go 初始化顺序</h1><p>Go 包的初始化顺序可以概括为以下三点：</p><ol><li>依赖包从main开始按照”深度优先“的次序进行初始化</li><li>每个包内按照”常量-&gt;变量-&gt;init函数“的顺序进行初始化</li><li>每个包内的可以有多个init函数，按照从上往下的顺序进行自动调用</li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://learnku.com/go/wikis">Go社区Wiki</a></li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;img src=&quot;/images/GoHeader.jpeg&quot; alt=&quot;Go小册&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;安装&quot;&gt;&lt;a href=&quot;#安装&quot; class=&quot;headerlink&quot; title=&quot;安装&quot;&gt;&lt;/a&gt;安装&lt;/h1&gt;&lt;h2 id=&quot;官网&quot;&gt;&lt;a href=&quot;
      
    
    </summary>
    
    
      <category term="go" scheme="https://slw.im/categories/go/"/>
    
    
      <category term="go" scheme="https://slw.im/tags/go/"/>
    
  </entry>
  
  <entry>
    <title>设计模式（1）——单例模式</title>
    <link href="https://slw.im/2021/09/design-pattern-singleton/"/>
    <id>https://slw.im/2021/09/design-pattern-singleton/</id>
    <published>2021-09-19T16:36:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p>单例模式(Singleton Pattern)<strong>保证一个类仅有一个实例，并提供一个访问它的全局访问点</strong>。</p><h2 id="饿汉式"><a href="#饿汉式" class="headerlink" title="饿汉式"></a>饿汉式</h2><p>饿汉式基于 classloader 机制避免了多线程的同步问题，会在第一次调用时就直接初始化，<strong>线程安全</strong>，但是可能会浪费空间。</p><p>可以在使用的时候再创建对象，于是出现了懒汉式。</p><figure class="highlight csharp"><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><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">SingletonGreed</span> &#123;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SingletonGreed</span>()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> final <span class="hljs-keyword">static</span> SingletonGreed SINGLETON = <span class="hljs-keyword">new</span> SingletonGreed();<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> SingletonGreed <span class="hljs-title">getInstance</span>()</span> &#123;<br>        <span class="hljs-keyword">return</span> SINGLETON;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="懒汉式"><a href="#懒汉式" class="headerlink" title="懒汉式"></a>懒汉式</h2><p>这种方式是最基本的实现方式，这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized，所以严格意义上它并不算单例模式，并发下会出现重复创建对象的问题，<strong>线程不安全</strong>。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">SingletonLazy</span> &#123;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SingletonLazy</span>()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> SingletonLazy SINGLETON;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> SingletonLazy <span class="hljs-title">getInstance</span>()</span> &#123;<br>        <span class="hljs-keyword">if</span> (SINGLETON == <span class="hljs-literal">null</span>) &#123;<br>            SINGLETON = <span class="hljs-keyword">new</span> SingletonLazy();<br>        &#125;<br>        <span class="hljs-keyword">return</span> SINGLETON;<br>    &#125;<br></code></pre></td></tr></table></figure><h2 id="双重检测锁"><a href="#双重检测锁" class="headerlink" title="双重检测锁"></a>双重检测锁</h2><p>这里给懒汉式引入了双重检测锁(DCL, Double Checked Locking)，做到<strong>线程安全</strong>。</p><figure class="highlight csharp"><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><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">SingletonLazy</span> &#123;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SingletonLazy</span>()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">private</span> <span class="hljs-keyword">volatile</span> <span class="hljs-keyword">static</span> SingletonLazy SINGLETON;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> SingletonLazy <span class="hljs-title">getInstance</span>()</span> &#123;<br>        <span class="hljs-keyword">if</span> (SINGLETON == <span class="hljs-literal">null</span>) &#123;<br>            synchronized (SingletonLazy.<span class="hljs-keyword">class</span>) &#123;<br>                <span class="hljs-keyword">if</span> (SINGLETON == <span class="hljs-literal">null</span>) &#123;<br>                    SINGLETON = <span class="hljs-keyword">new</span> SingletonLazy();<br>                &#125;<br>            &#125;<br>        &#125;<br>        <span class="hljs-keyword">return</span> SINGLETON;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>其中由于 <code>SINGLETON = new SingletonLazy();</code> 不是原子性操作，分为以下三步：</p><ol><li>分配内存空间</li><li>执行构造函数，初始化对象</li><li>把对象指向这个空间<br>所以我们需要加上 <code>volatile</code> 关键字，防止指令重排。</li></ol><h3 id="反射破坏单例"><a href="#反射破坏单例" class="headerlink" title="反射破坏单例"></a>反射破坏单例</h3><p>懒汉式还有个问题是会被反射破坏掉单例状态，如下演示：</p><figure class="highlight delphi"><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><code class="hljs delphi">SingletonLazy instance1 = SingletonLazy.getInstance();<br><span class="hljs-function"><span class="hljs-keyword">Constructor</span>&lt;<span class="hljs-title">SingletonLazy</span>&gt; <span class="hljs-title">declaredConstructor</span> = <span class="hljs-title">SingletonLazy</span>.<span class="hljs-title">class</span>.<span class="hljs-title">getDeclaredConstructor</span><span class="hljs-params">(null)</span>;</span><br>declaredConstructor.setAccessible(true);<br>SingletonLazy instance2 = declaredConstructor.newInstance();<br><br>System.<span class="hljs-keyword">out</span>.println(instance1);<br>System.<span class="hljs-keyword">out</span>.println(instance2);<br></code></pre></td></tr></table></figure><p><img src="/images/16320685831860.jpg"></p><h2 id="静态内部类"><a href="#静态内部类" class="headerlink" title="静态内部类"></a>静态内部类</h2><p>静态内部类可以实现和双重检测锁一样<strong>线程安全</strong>的效果，实现起来更简单。</p><p>和上面的一样，这个也是不安全的，会被反射破坏单例。</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">SingletonHolder</span> &#123;<br><br>    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">SingletonHolder</span>()</span> &#123;<br>    &#125;<br><br>    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">InnerClass</span> &#123;<br>        <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> final SingletonHolder HOLDER = <span class="hljs-keyword">new</span> SingletonHolder();<br>    &#125;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> SingletonHolder <span class="hljs-title">getInstance</span>()</span> &#123;<br>        <span class="hljs-keyword">return</span> InnerClass.HOLDER;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h2><p>枚举可以很好的防止反射，同样也是<strong>线程安全</strong>的。</p><figure class="highlight csharp"><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><code class="hljs csharp"><span class="hljs-keyword">public</span> <span class="hljs-built_in">enum</span> SingletonEnum &#123;<br><br>    INSTANCE;<br><br>    <span class="hljs-function"><span class="hljs-keyword">public</span> SingletonEnum <span class="hljs-title">getInstance</span>()</span> &#123;<br>        <span class="hljs-keyword">return</span> INSTANCE;<br>    &#125;<br><br>&#125;<br></code></pre></td></tr></table></figure><h3 id="反射测试"><a href="#反射测试" class="headerlink" title="反射测试"></a>反射测试</h3><figure class="highlight delphi"><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><code class="hljs delphi">SingletonEnum instance1 = SingletonEnum.INSTANCE;<br><span class="hljs-function"><span class="hljs-keyword">Constructor</span>&lt;<span class="hljs-title">SingletonEnum</span>&gt; <span class="hljs-title">declaredConstructor</span> = <span class="hljs-title">SingletonEnum</span>.<span class="hljs-title">class</span>.<span class="hljs-title">getDeclaredConstructor</span><span class="hljs-params">(<span class="hljs-keyword">String</span>.<span class="hljs-keyword">class</span>, int.<span class="hljs-keyword">class</span>)</span>;</span><br>declaredConstructor.setAccessible(true);<br>SingletonEnum instance2 = declaredConstructor.newInstance();<br><br>System.<span class="hljs-keyword">out</span>.println(instance1);<br>System.<span class="hljs-keyword">out</span>.println(instance2);<br></code></pre></td></tr></table></figure><p><img src="/images/16320691021882.jpg"></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;单例模式(Singleton Pattern)&lt;strong&gt;保证一个类仅有一个实例，并提供一个访问它的全局访问点&lt;/strong&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;饿汉
      
    
    </summary>
    
    
      <category term="design pattern" scheme="https://slw.im/categories/design-pattern/"/>
    
    
      <category term="design pattern" scheme="https://slw.im/tags/design-pattern/"/>
    
      <category term="java" scheme="https://slw.im/tags/java/"/>
    
  </entry>
  
  <entry>
    <title>开源镜像站点汇总</title>
    <link href="https://slw.im/2021/08/open-source-mirror-sites/"/>
    <id>https://slw.im/2021/08/open-source-mirror-sites/</id>
    <published>2021-08-28T11:31:30.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<h1 id="PyPi-镜像"><a href="#PyPi-镜像" class="headerlink" title="PyPi 镜像"></a>PyPi 镜像</h1><h2 id="临时使用"><a href="#临时使用" class="headerlink" title="临时使用"></a>临时使用</h2><p><code>pip install -i [url] [some-package]</code></p><h2 id="设为默认"><a href="#设为默认" class="headerlink" title="设为默认"></a>设为默认</h2><p><code>pip config set global.index-url [url]</code></p><h2 id="国内镜像地址"><a href="#国内镜像地址" class="headerlink" title="国内镜像地址"></a>国内镜像地址</h2><p>清华大学：<a href="https://pypi.tuna.tsinghua.edu.cn/simple">https://pypi.tuna.tsinghua.edu.cn/simple</a></p><p>阿里：<a href="https://mirrors.aliyun.com/pypi/simple/">https://mirrors.aliyun.com/pypi/simple/</a></p><p>豆瓣：<a href="https://pypi.doubanio.com/simple/">https://pypi.doubanio.com/simple/</a></p><p>北京外国语大学：<a href="https://mirrors.bfsu.edu.cn/pypi/web/simple/">https://mirrors.bfsu.edu.cn/pypi/web/simple/</a></p><h1 id="JDK-镜像"><a href="#JDK-镜像" class="headerlink" title="JDK 镜像"></a>JDK 镜像</h1><h2 id="下载镜像"><a href="#下载镜像" class="headerlink" title="下载镜像"></a>下载镜像</h2><p>清华AdoptOpenJDK镜像：<a href="https://mirrors.tuna.tsinghua.edu.cn/Adoptium/">https://mirrors.tuna.tsinghua.edu.cn/Adoptium/</a></p><p>华为java-jdk镜像：<a href="https://repo.huaweicloud.com/java/jdk/">https://repo.huaweicloud.com/java/jdk/</a></p><p>各种JAVA JDK的镜像分发：<a href="https://www.injdk.cn/">https://www.injdk.cn/</a></p><h1 id="nvm-镜像"><a href="#nvm-镜像" class="headerlink" title="nvm 镜像"></a>nvm 镜像</h1><h2 id="安装-nvm"><a href="#安装-nvm" class="headerlink" title="安装 nvm"></a>安装 nvm</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -sS -o- https://gh.slw.im/raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | sed -e <span class="hljs-string">&quot;s/raw.githubusercontent.com/gh.slw.im\/raw.githubusercontent.com/g&quot;</span> | sed -e <span class="hljs-string">&quot;s/github.com/gh.slw.im\/github.com/g&quot;</span> | bash<br></code></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">wget -qO- https://gh.slw.im/raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | sed -e <span class="hljs-string">&quot;s/raw.githubusercontent.com/gh.slw.im\/raw.githubusercontent.com/g&quot;</span> | sed -e <span class="hljs-string">&quot;s/github.com/gh.slw.im\/github.com/g&quot;</span> | bash<br></code></pre></td></tr></table></figure><h2 id="nvm-镜像（安装node）"><a href="#nvm-镜像（安装node）" class="headerlink" title="nvm 镜像（安装node）"></a>nvm 镜像（安装node）</h2><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-built_in">export</span> <span class="hljs-attribute">NVM_NODEJS_ORG_MIRROR</span>=https://npm.taobao.org/mirrors/node<br></code></pre></td></tr></table></figure><h2 id="nvm-指定默认-node-版本"><a href="#nvm-指定默认-node-版本" class="headerlink" title="nvm 指定默认 node 版本"></a>nvm 指定默认 node 版本</h2><p><code>nvm alias default [node-version]</code></p><h1 id="npm-镜像"><a href="#npm-镜像" class="headerlink" title="npm 镜像"></a>npm 镜像</h1><h2 id="临时使用-1"><a href="#临时使用-1" class="headerlink" title="临时使用"></a>临时使用</h2><p><code>npm install [some-package] --registry [url]</code></p><h2 id="设为默认-1"><a href="#设为默认-1" class="headerlink" title="设为默认"></a>设为默认</h2><p><code>npm config set registry [url]</code></p><p>npmmirror:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm config <span class="hljs-built_in">set</span> registry https://registry.npmmirror.com<br></code></pre></td></tr></table></figure><p>UTSC:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm config <span class="hljs-built_in">set</span> registry https://npmreg.proxy.ustclug.org<br></code></pre></td></tr></table></figure><p>cnpmjs:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">npm config <span class="hljs-built_in">set</span> registry https://r.cnpmjs.org<br></code></pre></td></tr></table></figure><p><em><strong>已废弃</strong></em> <del>淘宝：<a href="https://registry.npm.taobao.org/">https://registry.npm.taobao.org</a></del><br><a href="https://zhuanlan.zhihu.com/p/430580607">淘宝 NPM 镜像站喊你切换新域名啦</a><br><a href="https://zhuanlan.zhihu.com/p/465424728">淘宝 npm 域名即将切换 &amp;&amp; npmmirror 重构升级 &amp;&amp; 微信交流群</a></p><h1 id="Docker-安装"><a href="#Docker-安装" class="headerlink" title="Docker 安装"></a>Docker 安装</h1><p>已配置docker registry镜像，可以直接通过下面的脚本安装。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">curl -sSL https://dl.slw.app/Linux/Shell/docker_install.sh | sh<br></code></pre></td></tr></table></figure><h1 id="Rust-crates-io"><a href="#Rust-crates-io" class="headerlink" title="Rust crates.io"></a>Rust crates.io</h1><p>编辑 <code>~/.cargo/config</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></pre></td><td class="code"><pre><code class="hljs bash">[source.crates-io]<br>registry = <span class="hljs-string">&quot;https://github.com/rust-lang/crates.io-index&quot;</span><br><br>replace-with = <span class="hljs-string">&#x27;tuna&#x27;</span><br><br><span class="hljs-comment"># 清华大学</span><br>[source.tuna]<br>registry = <span class="hljs-string">&quot;https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git&quot;</span><br><br><span class="hljs-comment"># 中国科学技术大学</span><br>[source.ustc]<br>registry = <span class="hljs-string">&quot;git://mirrors.ustc.edu.cn/crates.io-index&quot;</span><br><br><span class="hljs-comment"># 上海交通大学</span><br>[source.sjtu]<br>registry = <span class="hljs-string">&quot;https://mirrors.sjtug.sjtu.edu.cn/git/crates.io-index&quot;</span><br><br><span class="hljs-comment"># rustcc社区</span><br>[source.rustcc]<br>registry = <span class="hljs-string">&quot;git://crates.rustcc.cn/crates.io-index&quot;</span><br></code></pre></td></tr></table></figure><p>默认使用清华镜像源，可以修改<code>replace-with</code>的值使用其他已经定义好的镜像地址。</p><h1 id="Go"><a href="#Go" class="headerlink" title="Go"></a>Go</h1><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs routeros"><span class="hljs-comment"># 启用 Go Modules 功能</span><br>go env -w <span class="hljs-attribute">GO111MODULE</span>=on<br><br><span class="hljs-comment"># 配置 GOPROXY 环境变量，以下三选一</span><br><br><span class="hljs-comment"># 1. 七牛 CDN</span><br>go env -w  <span class="hljs-attribute">GOPROXY</span>=https://goproxy.cn,direct<br><br><span class="hljs-comment"># 2. 阿里云</span><br>go env -w <span class="hljs-attribute">GOPROXY</span>=https://mirrors.aliyun.com/goproxy/,direct<br><br><span class="hljs-comment"># 3. 官方</span><br>go env -w  <span class="hljs-attribute">GOPROXY</span>=https://goproxy.io,direct<br></code></pre></td></tr></table></figure><p>参考链接：<a href="https://learnku.com/go/wikis/38122">Go 国内加速：Go 国内加速镜像</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;PyPi-镜像&quot;&gt;&lt;a href=&quot;#PyPi-镜像&quot; class=&quot;headerlink&quot; title=&quot;PyPi 镜像&quot;&gt;&lt;/a&gt;PyPi 镜像&lt;/h1&gt;&lt;h2 id=&quot;临时使用&quot;&gt;&lt;a href=&quot;#临时使用&quot; class=&quot;headerlink&quot; titl
      
    
    </summary>
    
    
      <category term="学习资料" scheme="https://slw.im/categories/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/"/>
    
    
      <category term="开源软件" scheme="https://slw.im/tags/%E5%BC%80%E6%BA%90%E8%BD%AF%E4%BB%B6/"/>
    
  </entry>
  
  <entry>
    <title>在macOS上使用GPG对GitHub进行签名</title>
    <link href="https://slw.im/2020/09/submit-to-github-with-gpg-on-mac/"/>
    <id>https://slw.im/2020/09/submit-to-github-with-gpg-on-mac/</id>
    <published>2020-09-09T05:41:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p>在GitHub上面我们对自己提交的commit进行签名，通过签名之后GitHub就会知道这个commit是经过签名的、可信的commit，并且会有个绿色的“Verified”显示在旁边。<br><img src="/images/pasted-8.png" alt="github pgp"></p><h1 id="安装PGP"><a href="#安装PGP" class="headerlink" title="安装PGP"></a>安装PGP</h1><p>这里通过homebrew进行安装，没有的话可以通过官网<a href="https://brew.sh/index_zh-cn">https://brew.sh/ </a>先安装homebrew。</p><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mipsasm"><span class="hljs-keyword">brew </span><span class="hljs-keyword">install </span>gpg<br></code></pre></td></tr></table></figure><p>安装完成后可以通过<code>gpg --version</code>查看当前安装的GPG版本号。</p><h1 id="生成GPG秘钥"><a href="#生成GPG秘钥" class="headerlink" title="生成GPG秘钥"></a>生成GPG秘钥</h1><h2 id="GPG版本为2-1-17或者更高"><a href="#GPG版本为2-1-17或者更高" class="headerlink" title="GPG版本为2.1.17或者更高"></a>GPG版本为2.1.17或者更高</h2><figure class="highlight verilog"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs verilog">gpg --full-<span class="hljs-keyword">generate</span>-key<br></code></pre></td></tr></table></figure><h2 id="GPG版本低于2-1-17"><a href="#GPG版本低于2-1-17" class="headerlink" title="GPG版本低于2.1.17"></a>GPG版本低于2.1.17</h2><figure class="highlight processing"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs processing">gpg --<span class="hljs-keyword">default</span>-<span class="hljs-keyword">new</span>-<span class="hljs-built_in">key</span>-algo rsa4096 --gen-<span class="hljs-built_in">key</span><br></code></pre></td></tr></table></figure><h2 id="生成密钥时的参数"><a href="#生成密钥时的参数" class="headerlink" title="生成密钥时的参数"></a>生成密钥时的参数</h2><p>加密方式选择默认的：<code>RSA and DSA</code></p><p>秘钥长度：<code>4096</code></p><p>秘钥有效时间可以根据自己的喜好进行选择。</p><p>在输入用户信息的时候需要输入经过GitHub认证过的邮箱，可以通过连接 <a href="https://github.com/settings/emails">https://github.com/settings/emails</a> 查看。</p><p>接下来就是要输入验证的密码，这里可能会是乱码，但是不影响输入，这里一共需要输入两次密码。</p><h1 id="查看生成的秘钥"><a href="#查看生成的秘钥" class="headerlink" title="查看生成的秘钥"></a>查看生成的秘钥</h1><p>通过命令查看GPG秘钥的ID</p><figure class="highlight brainfuck"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs brainfuck"><span class="hljs-comment">gpg</span> <span class="hljs-literal">--</span><span class="hljs-comment">list</span><span class="hljs-literal">-</span><span class="hljs-comment">secret</span><span class="hljs-literal">-</span><span class="hljs-comment">keys</span> <span class="hljs-literal">--</span><span class="hljs-comment">keyid</span><span class="hljs-literal">-</span><span class="hljs-comment">format LONG</span><br></code></pre></td></tr></table></figure><p>输出如下：</p><figure class="highlight asciidoc"><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><code class="hljs asciidoc">$ gpg --list-secret-keys --keyid-format LONG<br><span class="hljs-section">/Users/hubot/.gnupg/secring.gpg</span><br><span class="hljs-section">------------------------------------</span><br>sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]<br>uid                          Hubot <br>ssb   4096R/42B317FD4BA89E7A 2016-03-10<br></code></pre></td></tr></table></figure><p>这里的<code>3AA5C34371567BD2</code>就是我们需要的秘钥ID，接下来运行下面的命令，将其中的秘钥ID替换为自己的ID</p><figure class="highlight brainfuck"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs brainfuck"><span class="hljs-comment">gpg</span> <span class="hljs-literal">--</span><span class="hljs-comment">armor</span> <span class="hljs-literal">--</span><span class="hljs-comment">export 3AA5C34371567BD2</span><br></code></pre></td></tr></table></figure><p>得到从 <code>-----BEGIN PGP PUBLIC KEY BLOCK-----</code> 开始到 <code>-----END PGP PUBLIC KEY BLOCK-----</code> 结束的公钥。</p><h1 id="添加GPG公钥至GitHub"><a href="#添加GPG公钥至GitHub" class="headerlink" title="添加GPG公钥至GitHub"></a>添加GPG公钥至GitHub</h1><p>打开GitHub的设置页面：<a href="https://github.com/settings/keys">https://github.com/settings/keys</a></p><p>点击 <code>New GPG key</code>，把刚刚得到的公钥粘贴进去。</p><p><img src="/images/pasted-9.png" alt="github gpg keys"></p><h1 id="设置git使用GPG秘钥"><a href="#设置git使用GPG秘钥" class="headerlink" title="设置git使用GPG秘钥"></a>设置git使用GPG秘钥</h1><p>运行命令，需要替换为自己的秘钥ID：</p><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs lua">git <span class="hljs-built_in">config</span> <span class="hljs-comment">--global user.signingkey 3AA5C34371567BD2</span><br></code></pre></td></tr></table></figure><p>如果只需要对当前仓库使用GPG秘钥：</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arduino">git config commit.gpgsign <span class="hljs-literal">true</span><br></code></pre></td></tr></table></figure><p>如果需要对所有仓库使用GPG秘钥：</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arduino">git config --global commit.gpgsign <span class="hljs-literal">true</span><br></code></pre></td></tr></table></figure><h1 id="提交报错"><a href="#提交报错" class="headerlink" title="提交报错"></a>提交报错</h1><p>这个时候如果进行commit，会遇到一下的错误：</p><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs subunit"><span class="hljs-keyword">error: </span>gpg failed to sign the data <br>fatal: failed to write commit object<br></code></pre></td></tr></table></figure><p>经过查询，需要安装 pinentry-mac：</p><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mipsasm"><span class="hljs-keyword">brew </span><span class="hljs-keyword">install </span>pinentry-mac<br></code></pre></td></tr></table></figure><p>然后在文件<code>~/.gnupg/gpg-agent.conf</code>中加入</p><figure class="highlight stata"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs stata">pinentry-<span class="hljs-keyword">program</span> /usr/<span class="hljs-keyword">local</span>/bin/pinentry-<span class="hljs-keyword">mac</span><br></code></pre></td></tr></table></figure><p>最后重启pinentry才能生效：</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs arduino">gpg-connect-agent reloadagent<br></code></pre></td></tr></table></figure><p>这个时候再次进行commit，就可以正常输入密码提交了。</p><h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><ul><li><a href="https://docs.github.com/en/github/authenticating-to-github/generating-a-new-gpg-key">Generating a new GPG key</a></li><li><a href="https://docs.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account">Adding a new GPG key to your GitHub account</a></li><li><a href="https://docs.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key">Telling Git about your signing key</a></li><li><a href="https://presstige.io/p/GPG-424f30c6057f4e2e914c0f2e8fc22c72">Mac 下 配置 Git 使用 GPG</a></li><li><a href="https://morooi.cn/2020/github-gpg/">在 macOS 中使用 GPG 签名提交至 Github</a></li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;在GitHub上面我们对自己提交的commit进行签名，通过签名之后GitHub就会知道这个commit是经过签名的、可信的commit，并且会有个绿色的“Verified”显示在旁边。&lt;br&gt;&lt;img src=&quot;/images/pasted-8.png&quot; alt=&quot;git
      
    
    </summary>
    
    
      <category term="macOS" scheme="https://slw.im/categories/macOS/"/>
    
    
      <category term="github" scheme="https://slw.im/tags/github/"/>
    
      <category term="gpg" scheme="https://slw.im/tags/gpg/"/>
    
      <category term="macOS" scheme="https://slw.im/tags/macOS/"/>
    
  </entry>
  
  <entry>
    <title>[算法] leetcode 题型之 滑动窗口</title>
    <link href="https://slw.im/2020/05/leetcode-sliding-window/"/>
    <id>https://slw.im/2020/05/leetcode-sliding-window/</id>
    <published>2020-05-30T11:49:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<h1 id="理论"><a href="#理论" class="headerlink" title="理论"></a>理论</h1><p>滑动窗口是双指针的其中一种用法，在 leetcode 上面也是不时能看到它的身影。<br>滑动窗口的双指针分别代表的是窗口的左边界和右边界，而我们需要做的，就是在每次循环时，右边界向右移，同时，去判断窗口内的数据是否依旧满足题解，如果不满足，则需要将左边界也向右移。<br>因此，滑动指针的题目可以用类似以下的模板进行改动：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-function"><span class="hljs-type">void</span> <span class="hljs-title">slidingWindow</span><span class="hljs-params">(string s)</span> </span>&#123;<br>    <span class="hljs-type">int</span> left = <span class="hljs-number">0</span>, right = <span class="hljs-number">0</span>;<br><br>    <span class="hljs-keyword">while</span> (right &lt; s.<span class="hljs-built_in">size</span>()) &#123;<br>    <span class="hljs-comment">// c 是窗口中新移入的字符</span><br>        <span class="hljs-type">char</span> c = s[right];<br>        <span class="hljs-comment">// 右边界右移</span><br>        right++;<br>        <span class="hljs-comment">// 进行数据操作（如有）</span><br>        <span class="hljs-built_in">doSomeWork</span>();<br><br>        <span class="hljs-keyword">while</span> (<span class="hljs-built_in">windowTooLarge</span>()) &#123;<br>        <span class="hljs-comment">// d 是窗口中将要移出的字符</span><br>        <span class="hljs-type">char</span> d = s[left];<br>        <span class="hljs-comment">// 左边界右移</span><br>        left++;<br>        <span class="hljs-comment">// 进行数据操作（如有）</span><br>        <span class="hljs-built_in">doAnotherWork</span>();<br>        &#125;<br>    &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p>下面通过 leetcode 实战题来进一步说明如何使用这个模板。</p><h1 id="实战"><a href="#实战" class="headerlink" title="实战"></a>实战</h1><h2 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h2><p><a href="https://leetcode-cn.com/problems/minimum-window-substring/">leetcode 76</a><br>给你一个字符串 S、一个字符串 T，请在字符串 S 里面找出：包含 T 所有字符的最小子串。</p><p>示例：</p><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs excel">输入<span class="hljs-symbol">:</span> S = <span class="hljs-string">&quot;ADOBECODEBANC&quot;</span>, <span class="hljs-built_in">T</span> = <span class="hljs-string">&quot;ABC&quot;</span><br>输出<span class="hljs-symbol">:</span> <span class="hljs-string">&quot;BANC&quot;</span><br></code></pre></td></tr></table></figure><p>说明：</p><ul><li>如果 S 中不存这样的子串，则返回空字符串 “”。</li><li>如果 S 中存在这样的子串，我们保证它是唯一的答案。</li></ul><h2 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h2><p><img src="/images/pasted-2.png" alt="sliding window 1"></p><p>首先，我们有两个指针（在这里，我们用蓝色箭头代表左指针，黑色箭头代表右指针），分别指向开头；然后我们右边的指针不断右移，扩大当前窗口，直到所有字符串 T 中的字母都在窗口中出现。</p><p><img src="/images/pasted-3.png" alt="sliding window 2"></p><p>此时，需要将左指针右移，并记录满足题目条件时最小的窗口大小所对应的左指针和右指针。</p><p><img src="/images/pasted-4.png" alt="sliding window 3"></p><p>左指针右移后，发现不再满足题意，因此要将右指针右移至合适的位置。</p><p><img src="/images/pasted-5.png" alt="sliding window 4"></p><p>此时，窗口内的字符都包含字符串 T 中的字母了，需要移动左指针。</p><p><img src="/images/pasted-6.png" alt="sliding window 5"></p><p>以此类推，不断通过右指针扩大窗口至符合条件，左指针不断缩小窗口，直至不再满足题目条件。直到遍历完整个字符串，得到窗口最小的时候对应的左右指针的下标。</p><p><img src="/images/pasted-7.png" alt="sliding window 6"></p><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">class</span> <span class="hljs-title class_">Solution</span> &#123;<br><span class="hljs-keyword">public</span>:<br>    <span class="hljs-function">string <span class="hljs-title">minWindow</span><span class="hljs-params">(string s, string t)</span> </span>&#123;<br>        unordered_map&lt;<span class="hljs-type">char</span>, <span class="hljs-type">int</span>&gt; need, window;<br>        <span class="hljs-keyword">for</span> (<span class="hljs-type">char</span> c : t) need[c]++;<br>        <br>        <span class="hljs-type">int</span> left = <span class="hljs-number">0</span>, right = <span class="hljs-number">0</span>;<br>        <span class="hljs-type">int</span> valid = <span class="hljs-number">0</span>;<br>        <span class="hljs-type">int</span> start = <span class="hljs-number">0</span>, len = INT_MAX; <br>        <span class="hljs-comment">// len 赋值为极大值，如果所有字符都不满足，则输出空字符串</span><br>        <span class="hljs-keyword">while</span> (right &lt; s.<span class="hljs-built_in">size</span>()) &#123;<br>            <span class="hljs-comment">// c 是将移入窗口的字符</span><br>            <span class="hljs-type">char</span> c = s[right];<br>            <span class="hljs-comment">// 右边界右移</span><br>            right++;<br>            <span class="hljs-comment">// 进行窗口内数据的一系列更新</span><br>            <span class="hljs-comment">// 统计当前窗口中出现所需字母的次数</span><br>            <span class="hljs-comment">// 如果出现了所有字符，那么 valid == need.size()</span><br>            <span class="hljs-keyword">if</span> (need.<span class="hljs-built_in">count</span>(c)) &#123;<br>                window[c]++;<br>                <span class="hljs-keyword">if</span> (need[c] == window[c]) &#123;<br>                    valid++;<br>                &#125;<br>            &#125;<br>            <br>            <span class="hljs-comment">// 判断左侧窗口是否要收缩</span><br>            <span class="hljs-keyword">while</span> (valid == need.<span class="hljs-built_in">size</span>()) &#123;<br>                <span class="hljs-keyword">if</span> (right - left &lt; len) &#123;<br>                    start = left;<br>                    len = right - left;<br>                &#125;<br>                <span class="hljs-comment">// d 是将移出窗口的字符</span><br>                <span class="hljs-type">char</span> d = s[left];<br>                <span class="hljs-comment">// 左移窗口</span><br>                left++;<br>                <span class="hljs-keyword">if</span> (need.<span class="hljs-built_in">count</span>(d)) &#123;<br>                    <span class="hljs-keyword">if</span> (need[d] == window[d]) &#123;<br>                        valid--;<br>                    &#125;<br>                    window[d]--;<br>                &#125;<br>            &#125;<br>        &#125;<br>        <span class="hljs-keyword">return</span> len == INT_MAX ? <span class="hljs-string">&quot;&quot;</span> : s.<span class="hljs-built_in">substr</span>(start, len);<br>    &#125;<br>&#125;;<br></code></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;理论&quot;&gt;&lt;a href=&quot;#理论&quot; class=&quot;headerlink&quot; title=&quot;理论&quot;&gt;&lt;/a&gt;理论&lt;/h1&gt;&lt;p&gt;滑动窗口是双指针的其中一种用法，在 leetcode 上面也是不时能看到它的身影。&lt;br&gt;滑动窗口的双指针分别代表的是窗口的左边界和右边界，
      
    
    </summary>
    
    
      <category term="leetcode" scheme="https://slw.im/categories/leetcode/"/>
    
    
      <category term="sliding window" scheme="https://slw.im/tags/sliding-window/"/>
    
      <category term="algorithm" scheme="https://slw.im/tags/algorithm/"/>
    
      <category term="leetcode" scheme="https://slw.im/tags/leetcode/"/>
    
  </entry>
  
  <entry>
    <title>使用 GitHub Action 自动部署 Hexo</title>
    <link href="https://slw.im/2020/04/github-action-for-hexo/"/>
    <id>https://slw.im/2020/04/github-action-for-hexo/</id>
    <published>2020-04-11T16:33:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p><a href="https://github.com/features/actions">Github Actions</a> 是Github官方推出的 CI/CD 工具，通过它，可以在每次提交代码时，自动编译并部署到 <a href="https://pages.github.com/">Github Pages</a>。这样就不用每次写好博客时，手工部署到服务器上。<br>Github Actions 针对公开仓库永久免费。当然，像博客这样的数据我们一般都是放在私有仓库里的，Github Actions 同样提供每月至少 2000 分钟的运行时长，这个时间对于博客的自动部署是足够了。</p><h1 id="生成Github-Personal-access-token"><a href="#生成Github-Personal-access-token" class="headerlink" title="生成Github Personal access token"></a>生成Github Personal access token</h1><p>在 Settings -&gt; Developer settings -&gt; <a href="https://github.com/settings/tokens">Personal access tokens</a> 中，点击 <code>Generate new token</code>，我们可以生成 token。在生成 token 时，我们要注意勾选上<code>repo</code>权限。需要注意的是，这里生成的token在关闭网页后就没法再次查看了，所以这里一定要保存好，在下一步中我们会用到这个 token。<br><img src="/images/pasted-0.png" alt="Personal access token"></p><h1 id="设置仓库"><a href="#设置仓库" class="headerlink" title="设置仓库"></a>设置仓库</h1><p>我们在这里用的是双仓库的形式，即仓库 A 存放 Hexo 源文件，仓库 B (xxx.github.io) 存放生成的部署文件。对仓库 A 进行 push 之后，会自动更新部署仓库 B。<br>我们需要在仓库 A 中的 Settings -&gt; Secrets -&gt; Add a new  secret 中添加我们刚刚生成的 token，名称 为<code>GITHUB_ACCESS_TOKEN</code>。<br><img src="/images/pasted-1.png" alt="secrets"></p><h1 id="配置-Hexo-的部署方式"><a href="#配置-Hexo-的部署方式" class="headerlink" title="配置 Hexo 的部署方式"></a>配置 Hexo 的部署方式</h1><p>修改 hexo 文件夹中的<code>_config.yml</code>，将下面代码中的<code>YOUR_GITHUB_USERNAME</code>和<code>YOUR_GITHUB_REPO</code>修改为自己的内容。</p><figure class="highlight nix"><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><code class="hljs nix"><span class="hljs-params">deploy:</span><br><span class="hljs-operator">-</span> <span class="hljs-params">type:</span> git<br>  <span class="hljs-params">repo:</span> https:<span class="hljs-operator">//</span>GITHUB_ACCESS_TOKEN@github.com<span class="hljs-symbol">/YOUR_GITHUB_USERNAME/YOUR_GITHUB_REPO.git</span><br>  <span class="hljs-params">branch:</span> master<br></code></pre></td></tr></table></figure><h1 id="配置-Github-Actions"><a href="#配置-Github-Actions" class="headerlink" title="配置 Github Actions"></a>配置 Github Actions</h1><p>在 Hexo 根目录下新建<code>.github/workflow/blogci.yml</code>文件，修改 <code>YOUR_NAME</code>和<code>YOUR_EMAIL</code>为自己的内容。</p><figure class="highlight nix"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs nix"><span class="hljs-params">name:</span> CI<br><br><span class="hljs-params">on:</span> [push]<br><br><span class="hljs-params">jobs:</span><br>  <span class="hljs-params">build:</span><br><br>    <span class="hljs-params">runs-on:</span> ubuntu-latest<br><br>    <span class="hljs-params">steps:</span><br>    <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> Download Source file<br>      <span class="hljs-params">uses:</span> actions<span class="hljs-operator">/</span>checkout@v2<br>      <span class="hljs-params">with:</span><br>        <span class="hljs-params">ref:</span> master <span class="hljs-comment"># 此处修改为自己存放 Hexo 源文件的分支</span><br><br>    <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> Prepare Node env<br>      <span class="hljs-params">uses:</span> actions<span class="hljs-operator">/</span>setup-node@v1<br>      <span class="hljs-params">with:</span><br>        <span class="hljs-params">node-version:</span> <span class="hljs-string">&quot;10.x&quot;</span><br><br>    <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> Set env<br>      <span class="hljs-params">env:</span> <br>        <span class="hljs-params">GITHUB_ACCESS_TOKEN:</span> $&#123;&#123; secrets.GITHUB_ACCESS_TOKEN &#125;&#125;  <br>      <span class="hljs-params">run:</span> |<br>        git config <span class="hljs-operator">-</span>-global user.name &#x27;YOUR_NAME&#x27;<br>        git config <span class="hljs-operator">-</span>-global user.email &#x27;YOUR_EMAIL&#x27;<br>        sed <span class="hljs-operator">-</span>i <span class="hljs-string">&quot;s/GITHUB_ACCESS_TOKEN/$GITHUB_ACCESS_TOKEN/g&quot;</span> <span class="hljs-symbol">./_config.yml</span><br><br>    <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> Hexo Setup<br>      <span class="hljs-params">run:</span> |<br>        npm i <span class="hljs-operator">-</span>g hexo-cli<br>        npm i hexo-deployer-git <span class="hljs-operator">-</span>-save<br><br>    <span class="hljs-operator">-</span> <span class="hljs-params">name:</span> Hexo Deploy<br>      <span class="hljs-params">run:</span> |<br>        hexo clean <span class="hljs-operator">&amp;&amp;</span> hexo g <span class="hljs-operator">&amp;&amp;</span> hexo d<br></code></pre></td></tr></table></figure><h1 id="使用-FTP-进行部署"><a href="#使用-FTP-进行部署" class="headerlink" title="使用 FTP 进行部署"></a>使用 FTP 进行部署</h1><p>Hexo 的 FTP 部署方式会将远程服务器的文件夹清空后，再上传生成的文件。然而，在清空文件夹的步骤中会报错，因而转用 Github Actions 第三方市场中的 Action 进行部署。在<code>blogci.yml</code>文件中添加以下代码，并在<code>Secrets</code>中依次添加 <code>FTP_SERVER</code>、<code>FTP_USERNAME</code>、<code>FTP_PASSWORD</code>。</p><figure class="highlight handlebars"><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><code class="hljs handlebars"><span class="language-xml">- name: Upload ftp</span><br><span class="language-xml">  uses: sebastianpopp/ftp-action@releases/v2</span><br><span class="language-xml">  with:</span><br><span class="language-xml">    host: $</span><span class="hljs-template-variable">&#123;&#123; <span class="hljs-name">secrets.FTP_SERVER</span> &#125;&#125;</span><span class="language-xml"></span><br><span class="language-xml">    user: $</span><span class="hljs-template-variable">&#123;&#123; <span class="hljs-name">secrets.FTP_USERNAME</span> &#125;&#125;</span><span class="language-xml"></span><br><span class="language-xml">    password: $</span><span class="hljs-template-variable">&#123;&#123; <span class="hljs-name">secrets.FTP_PASSWORD</span> &#125;&#125;</span><span class="language-xml"></span><br><span class="language-xml">    localDir: &quot;public&quot;</span><br></code></pre></td></tr></table></figure><p>最后将仓库推送至 Github ，就可以看到 GIthub Actions 会自动部署你的博客了。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;a href=&quot;https://github.com/features/actions&quot;&gt;Github Actions&lt;/a&gt; 是Github官方推出的 CI/CD 工具，通过它，可以在每次提交代码时，自动编译并部署到 &lt;a href=&quot;https://pages.git
      
    
    </summary>
    
    
      <category term="hexo" scheme="https://slw.im/categories/hexo/"/>
    
    
      <category term="hexo" scheme="https://slw.im/tags/hexo/"/>
    
      <category term="github action" scheme="https://slw.im/tags/github-action/"/>
    
  </entry>
  
  <entry>
    <title>在Mac下通过HEXO在Github上搭建博客</title>
    <link href="https://slw.im/2017/08/using-hexo-building-blog-on-mac/"/>
    <id>https://slw.im/2017/08/using-hexo-building-blog-on-mac/</id>
    <published>2017-08-20T12:22:00.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p>经过一番折腾，总算是把Hexo给弄好了。在这期间遇到了各种问题，网上有的教程也有点老了，这里就再写一篇。<strong>最新的教程</strong>可以去<a href="https://hexo.io/zh-cn/docs/index.html">Hexo官网</a>查看。</p><h2 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a><a href="#%E5%89%8D%E6%9C%9F%E5%87%86%E5%A4%87" title="前期准备"></a>前期准备</h2><h3 id="安装Xcode"><a href="#安装Xcode" class="headerlink" title="安装Xcode"></a><a href="#%E5%AE%89%E8%A3%85Xcode" title="安装Xcode"></a>安装Xcode</h3><p>Hexo的编译可能依赖Xcode。这个直接从<a href="http://itunes.apple.com/us/app/xcode/id497799835?ls=1&amp;mt=12">App Store</a>上下载就好了，没什么难度。</p><h3 id="安装node-js"><a href="#安装node-js" class="headerlink" title="安装node.js"></a><a href="#%E5%AE%89%E8%A3%85node-js" title="安装node.js"></a>安装node.js</h3><p>Hexo是基于node.js的，所以要去<a href="https://nodejs.org/">官网</a>上下载下来安装。版本可以选择稳定版(6.11.2)<del>(4.3.1)</del>也可以选择最新版(8.4.0)<del>(5.7.0)</del>。<br>需要注意的是，Hexo 3.1.1测试的最低版本为0.12，所以安装的版本不要太旧，之前看到网上装的0.8.4的版本，我也这么装，结果有一大堆的报错。</p><p><a id="more"></a></p><h3 id="注册Github账户"><a href="#注册Github账户" class="headerlink" title="注册Github账户"></a><a href="#%E6%B3%A8%E5%86%8CGithub%E8%B4%A6%E6%88%B7" title="注册Github账户"></a>注册Github账户</h3><p>在本地搭建好Hexo后可以将内容同步到github上，可以在网上浏览。<br>可以去<a href="https://github.com/">Github官网</a>上去注册，注册的过程我就不罗嗦了，具体的过程可以去<a href="http://ibruce.info/2013/11/22/hexo-your-blog/?utm_source=tuicool">这个页面</a>上跳到Github的那部分去看。<br>其中配置SSH Keys的那部分，可以选择不配制，不配置的话以后每次提交的时候就需要手动输入账号密码，如果配置了的话就不需要了。</p><h2 id="正式安装"><a href="#正式安装" class="headerlink" title="正式安装"></a><a href="#%E6%AD%A3%E5%BC%8F%E5%AE%89%E8%A3%85" title="正式安装"></a>正式安装</h2><p>因为安装包中有些内容在墙外，所以可以换<a href="http://npm.taobao.org/">淘宝源</a>，或者用</p><figure class="highlight coffeescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs coffeescript"><span class="hljs-built_in">npm</span> install -g hexo-cli --<span class="hljs-literal">no</span>-optional<br></code></pre></td></tr></table></figure><p>来安装<br>然后进入你要安装的目录，如</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash"><span class="hljs-built_in">cd</span> ~/Document/hexo<br></code></pre></td></tr></table></figure><p>然后安装</p><figure class="highlight csharp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs csharp">hexo <span class="hljs-keyword">init</span><br></code></pre></td></tr></table></figure><p>安装好之后不要忘记执行</p><figure class="highlight cmake"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cmake">npm <span class="hljs-keyword">install</span><br></code></pre></td></tr></table></figure><p>至此，就已经安装完毕了。是不是很简单呢？</p><h2 id="后期部署"><a href="#后期部署" class="headerlink" title="后期部署"></a><a href="#%E5%90%8E%E6%9C%9F%E9%83%A8%E7%BD%B2" title="后期部署"></a>后期部署</h2><h3 id="添加文章"><a href="#添加文章" class="headerlink" title="添加文章"></a><a href="#%E6%B7%BB%E5%8A%A0%E6%96%87%E7%AB%A0" title="添加文章"></a>添加文章</h3><figure class="highlight actionscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs actionscript">hexo <span class="hljs-keyword">new</span> <span class="hljs-string">&quot;postName&quot;</span><br></code></pre></td></tr></table></figure><p>其中postName是博客名。</p><h3 id="生成静态页面"><a href="#生成静态页面" class="headerlink" title="生成静态页面"></a><a href="#%E7%94%9F%E6%88%90%E9%9D%99%E6%80%81%E9%A1%B5%E9%9D%A2" title="生成静态页面"></a>生成静态页面</h3><figure class="highlight verilog"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs verilog">hexo <span class="hljs-keyword">generate</span><br></code></pre></td></tr></table></figure><p>或者也可以执行缩写</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs css">hexo <span class="hljs-selector-tag">g</span><br></code></pre></td></tr></table></figure><h3 id="本地启动"><a href="#本地启动" class="headerlink" title="本地启动"></a><a href="#%E6%9C%AC%E5%9C%B0%E5%90%AF%E5%8A%A8" title="本地启动"></a>本地启动</h3><p>执行好上面的命令之后就可以在本地启用服务来看效果了。执行下面的命令：</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">hexo sever</span><br></code></pre></td></tr></table></figure><p>或缩写</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">hexo s</span><br></code></pre></td></tr></table></figure><p>看到 <em>INFO  Hexo is running at <a href="http://0.0.0.0:4000/">http://0.0.0.0:4000/</a>. Press Ctrl+C to stop.</em> 之后，就可以在浏览器中打开页面<a href="http://localhost:4000/">http://localhost:4000</a>来看了。</p><h3 id="上传至Github"><a href="#上传至Github" class="headerlink" title="上传至Github"></a><a href="#%E4%B8%8A%E4%BC%A0%E8%87%B3Github" title="上传至Github"></a>上传至Github</h3><h4 id="安装git部署插件"><a href="#安装git部署插件" class="headerlink" title="安装git部署插件"></a><a href="#%E5%AE%89%E8%A3%85git%E9%83%A8%E7%BD%B2%E6%8F%92%E4%BB%B6" title="安装git部署插件"></a>安装git部署插件</h4><p>在部署之前，首先我们要确认在你的Github帐号的Repository中有 <strong>用户名.github.io</strong> 的项目。<br>在确认之后，就可以执行命令</p><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">npm install hexo-deployer-git <span class="hljs-comment">--save</span><br></code></pre></td></tr></table></figure><p>来安装插件</p><h4 id="配置-config-yml-文件"><a href="#配置-config-yml-文件" class="headerlink" title="配置 _config.yml 文件"></a><a href="#%E9%85%8D%E7%BD%AE-config-yml-%E6%96%87%E4%BB%B6" title="配置 _config.yml 文件"></a>配置 _config.yml 文件</h4><p>在Hexo安装的目录，如 <em>~/Document/hexo</em> 中找到 <strong>_config.yml</strong> 文件。打开。<br>翻到最后，找到 <strong>deploy</strong> 字样，改成如下格式：</p><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></pre></td><td class="code"><pre><code class="hljs dts"><span class="hljs-symbol">deploy:</span> <br><span class="hljs-symbol">  type:</span> git <br><span class="hljs-symbol">  repo:</span> https:<span class="hljs-comment">//github.com/用户名/用户名.github.io.git</span><br><span class="hljs-symbol">  branch:</span> master<br></code></pre></td></tr></table></figure><p>需要<strong>注意</strong>的是：冒号后面有一个空格；使用github可以不用写branch那一行。<br>如果要使用多个 deployer，可改成如下样式：</p><figure class="highlight nestedtext"><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><code class="hljs nestedtext"><span class="hljs-attribute">deploy</span><span class="hljs-punctuation">:</span><br><span class="hljs-bullet">-</span> <span class="hljs-string">type: git</span><br>  <span class="hljs-attribute">repo</span><span class="hljs-punctuation">:</span><br><span class="hljs-bullet">-</span> <span class="hljs-string">type: heroku </span><br>  <span class="hljs-attribute">repo</span><span class="hljs-punctuation">:</span><br></code></pre></td></tr></table></figure><h4 id="同步"><a href="#同步" class="headerlink" title="同步"></a><a href="#%E5%90%8C%E6%AD%A5" title="同步"></a>同步</h4><p>输入命令</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">hexo deploy</span><br></code></pre></td></tr></table></figure><p>或者缩写</p><figure class="highlight ebnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ebnf"><span class="hljs-attribute">hexo d</span><br></code></pre></td></tr></table></figure><p>来执行。<br>以后每次执行就可以依次输入下面三行命令：</p><figure class="highlight verilog"><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><code class="hljs verilog">hexo clean<br>hexo <span class="hljs-keyword">generate</span><br>hexo deploy<br></code></pre></td></tr></table></figure><p>或者其缩写。</p><h2 id="最后优化"><a href="#最后优化" class="headerlink" title="最后优化"></a><a href="#%E6%9C%80%E5%90%8E%E4%BC%98%E5%8C%96" title="最后优化"></a>最后优化</h2><h3 id="插件"><a href="#插件" class="headerlink" title="插件"></a><a href="#%E6%8F%92%E4%BB%B6" title="插件"></a>插件</h3><p>我使用了几个常见的插件：</p><h4 id="从Wordpress迁移到Hexo"><a href="#从Wordpress迁移到Hexo" class="headerlink" title="从Wordpress迁移到Hexo"></a><a href="#%E4%BB%8EWordpress%E8%BF%81%E7%A7%BB%E5%88%B0Hexo" title="从Wordpress迁移到Hexo"></a>从Wordpress迁移到Hexo</h4><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">npm install hexo-migrator-wordpress <span class="hljs-comment">--save</span><br></code></pre></td></tr></table></figure><p>在 WordPress 仪表盘中导出数据(“工具(Tools)” → “发布(Export)” → “文章(WordPress)”)<br>插件安装完成后，执行下列命令来迁移所有文章。<code>source</code> 可以是 WordPress 导出的文件路径或网址。</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml">hexo migrate wordpress <span class="hljs-tag">&lt;<span class="hljs-name">source</span>&gt;</span><br></code></pre></td></tr></table></figure><h4 id="站点地图"><a href="#站点地图" class="headerlink" title="站点地图"></a><a href="#%E7%AB%99%E7%82%B9%E5%9C%B0%E5%9B%BE" title="站点地图"></a>站点地图</h4><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">npm install hexo-generator-sitemap <span class="hljs-comment">--save</span><br></code></pre></td></tr></table></figure><p>生成的sitemap.xml可以给搜索引擎收录使用。<br>如果要生成百度的sitemap，使用以下命令：</p><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs mipsasm">npm <span class="hljs-keyword">install </span>hexo-generator-<span class="hljs-keyword">baidu-sitemap </span>--save<br></code></pre></td></tr></table></figure><h4 id="RSS订阅"><a href="#RSS订阅" class="headerlink" title="RSS订阅"></a><a href="#RSS%E8%AE%A2%E9%98%85" title="RSS订阅"></a>RSS订阅</h4><figure class="highlight ada"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs ada">npm install hexo-generator-feed <span class="hljs-comment">--save</span><br></code></pre></td></tr></table></figure><p>配置文件里经常看见的<code>/atom.xml</code>就是由这个插件生成的</p><h3 id="主题"><a href="#主题" class="headerlink" title="主题"></a><a href="#%E4%B8%BB%E9%A2%98" title="主题"></a>主题</h3><p><a href="https://github.com/hexojs/hexo/wiki/Themes">官方</a>给了很多的主题提供参考，默认的是landscape。<br><del>我使用的是<a href="https://github.com/MOxFIVE/hexo-theme-yelee">yelee</a>，<a href="http://slw.coding.me/">这里</a>可以看看样式。</del><br><del>现在用的是<a href="https://luuman.github.io/2015/12/27/Hexo/HexoTheme/">SPFK Hexo 主题</a>，是基于yilia主题修改的，我觉得挺不错的，就拿来使用了。</del><br>现在使用的是<a href="https://github.com/fluid-dev/hexo-theme-fluid">fluid</a>，这是一款 Material Design 风格的主题。</p><h2 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a><a href="#%E5%8F%82%E8%80%83%E6%96%87%E7%AB%A0" title="参考文章"></a>参考文章</h2><p><a href="https://hexo.io/zh-cn/docs/index.html">Hexo官方文档</a><br><a href="http://ibruce.info/2013/11/22/hexo-your-blog/?utm_source=tuicool">hexo你的博客</a><br><a href="http://www.jianshu.com/p/465830080ea9">HEXO+Github,搭建属于自己的博客</a><br><a href="http://www.jianshu.com/p/858ecf233db9">通过Hexo在Github上搭建博客教程</a><br><a href="http://www.jianshu.com/p/739bf1305e66">使用Hexo搭建博客（四），博客的部件和插件</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;经过一番折腾，总算是把Hexo给弄好了。在这期间遇到了各种问题，网上有的教程也有点老了，这里就再写一篇。&lt;strong&gt;最新的教程&lt;/strong&gt;可以去&lt;a href=&quot;https://hexo.io/zh-cn/docs/index.html&quot;&gt;Hexo官网&lt;/a&gt;查看
      
    
    </summary>
    
    
      <category term="hexo" scheme="https://slw.im/categories/hexo/"/>
    
    
      <category term="macOS" scheme="https://slw.im/tags/macOS/"/>
    
      <category term="Hexo" scheme="https://slw.im/tags/Hexo/"/>
    
  </entry>
  
  <entry>
    <title>使用 Google Drive 备份你的数据</title>
    <link href="https://slw.im/2017/04/backup-date-by-google-drive/"/>
    <id>https://slw.im/2017/04/backup-date-by-google-drive/</id>
    <published>2017-04-10T12:11:50.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p>有时候你的 VPS 上运行着一些博客等数据，通常我们为了防止数据突然丢失等意外，都会将数据进行备份，下面我就来说说如何使用 Google Drive 来进行数据备份。在本篇文章中，上传到 Google Drive 的都是已经打包过的压缩包，而不是一些源文件，同时你的 VPS 也需要能够连接到 Google 的服务器。</p><h2 id="下载-gdrive"><a href="#下载-gdrive" class="headerlink" title="下载 gdrive"></a><a href="#%E4%B8%8B%E8%BD%BD-gdrive" title="下载 gdrive"></a>下载 gdrive</h2><p>在这里我们使用 gdrive 来连接 Google Drive ，并通过它来上传文件。gdrive 是一个比较常用的工具，使用 Go 语言编写，这里是它的 <a href="https://github.com/prasmussen/gdrive">GitHub</a> 地址。</p><h3 id="macOS-安装"><a href="#macOS-安装" class="headerlink" title="macOS 安装"></a><a href="#macOS-%E5%AE%89%E8%A3%85" title="macOS 安装"></a>macOS 安装</h3><p>macOS 系统可以使用 brew 来安装，如果机器上没有安装 brew 的话也可以使用下面的二进制文件。<br><code>brew install gdrive</code></p><h3 id="二进制文件下载"><a href="#二进制文件下载" class="headerlink" title="二进制文件下载"></a><a href="#%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD" title="二进制文件下载"></a>二进制文件下载</h3><p>下面列举的是常用的文件，其他系统的文件可前往 <a href="https://dl.slinvent.com/?dir=gdrive">我的镜像网站</a> 或 <a href="https://github.com/prasmussen/gdrive#downloads">GitHub</a> 获取。</p><table><thead><tr><th>文件名</th><th>版本</th><th>适用系统</th><th>Shasum值</th></tr></thead><tbody><tr><td>[gdrive-osx-x64](https://dl.slinvent.com/gdrive/gdrive-osx-x64)</td><td>2.1.0</td><td>OS X 64-bit</td><td>297ccf3c945b364b5d306cef335ba44b0900e927</td></tr><tr><td>[gdrive-linux-x64](https://dl.slinvent.com/gdrive/gdrive-linux-x64)</td><td>2.1.0</td><td>Linux 64-bit</td><td>4fd8391b300cac45963e53da44dcfe68da08d843</td></tr><tr><td>[gdrive-windows-386.exe](https://dl.slinvent.com/gdrive/gdrive-windows-386.exe)</td><td>2.1.0</td><td>Window 32-bit</td><td>1429200631b598543eddc3df3487117cad95adbb</td></tr><tr><td>[gdrive-windows-x64.exe](https://dl.slinvent.com/gdrive/gdrive-windows-x64.exe)</td><td>2.1.0</td><td>Windows 64-bit</td><td>17f692a027a049385af2576503cd376593cc87b7</td></tr></tbody></table><h3 id="源码安装"><a href="#源码安装" class="headerlink" title="源码安装"></a><a href="#%E6%BA%90%E7%A0%81%E5%AE%89%E8%A3%85" title="源码安装"></a>源码安装</h3><p>这里就不过多介绍了，一般不怎么使用，就只放个代码，详细的可前往 <a href="https://github.com/prasmussen/gdrive#compile-from-source">GitHub</a> 查看。<br><code>go get github.com/prasmussen/gdrive</code></p><h2 id="使用-gdrive"><a href="#使用-gdrive" class="headerlink" title="使用 gdrive"></a><a href="#%E4%BD%BF%E7%94%A8-gdrive" title="使用 gdrive"></a>使用 gdrive</h2><h3 id="下载"><a href="#下载" class="headerlink" title="下载"></a><a href="#%E4%B8%8B%E8%BD%BD" title="下载"></a>下载</h3><p>这里以 Linux 64bit 为例，首先是下载 gdrive</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><code class="hljs bash">wget -O gdrive https://dl.slinvent.com/gdrive/gdrive-linux-x64<br><span class="hljs-built_in">chmod</span> +x gdrive<br><span class="hljs-built_in">mv</span> gdrive /usr/bin<br></code></pre></td></tr></table></figure><h3 id="登录"><a href="#登录" class="headerlink" title="登录"></a><a href="#%E7%99%BB%E5%BD%95" title="登录"></a>登录</h3><p>然后运行<code>gdrive about</code>进行登录，我们可以看到如下的提示，将网址复制到浏览器中，Google 授权之后我们会得到授权码，再将授权码粘贴到 ssh 中。<br><img src="/images/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202017-02-22%20%E4%B8%8B%E5%8D%8811.27.58.png" alt="gdrive about 运行界面"></p><h3 id="同步"><a href="#同步" class="headerlink" title="同步"></a><a href="#%E5%90%8C%E6%AD%A5" title="同步"></a>同步</h3><p>之后我们可以在 Google Drive 中创建一个文件夹，然后在终端里运行：<br><code>gdrive list</code>来查看文件夹所代表的id，接下来我们就可以运行同步命令了。<br><code>gdrive sync upload &lt;文件夹所在位置&gt; &lt;文件夹id&gt;</code><br>如：<code>gdrive sync upload /home/backup 0Bx90C1SIFScgcGozNXphQ2FxTXX</code></p><h3 id="帮助"><a href="#帮助" class="headerlink" title="帮助"></a><a href="#%E5%B8%AE%E5%8A%A9" title="帮助"></a>帮助</h3><p>我们主要会使用到的命令就这几个，当然 gdrive 还有更多地命令可供使用，可以运行<code>gdrive help</code>获取更多命令的使用帮助。</p><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a><a href="#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99" title="参考资料"></a>参考资料</h2><p><a href="https://github.com/prasmussen/gdrive">https://github.com/prasmussen/gdrive</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;有时候你的 VPS 上运行着一些博客等数据，通常我们为了防止数据突然丢失等意外，都会将数据进行备份，下面我就来说说如何使用 Google Drive 来进行数据备份。在本篇文章中，上传到 Google Drive 的都是已经打包过的压缩包，而不是一些源文件，同时你的 VPS
      
    
    </summary>
    
    
    
      <category term="backup" scheme="https://slw.im/tags/backup/"/>
    
      <category term="Google Drive" scheme="https://slw.im/tags/Google-Drive/"/>
    
  </entry>
  
  <entry>
    <title>半加器与全加器</title>
    <link href="https://slw.im/2016/11/half-adder-and-full-adder/"/>
    <id>https://slw.im/2016/11/half-adder-and-full-adder/</id>
    <published>2016-11-23T12:48:04.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p><strong>半加器：</strong></p><p>半加器电路是指对两个输入数据位相加，输出一个结果位和进位，没有进位输入的加法器电路。 是实现两个一位二进制数的加法运算电路。</p><p>逻辑图：</p><p><img src="/images/wpid-5a89d3c6d51e3e14a911761ca6130dd0_53110121.png" alt="wpid-5a89d3c6d51e3e14a911761ca6130dd0_53110121"></p><p><a id="more"></a></p><p>真值表：</p><p><img src="/images/wpid-5a89d3c6d51e3e14a911761ca6130dd0_59b9c230-6990-4fb0-8105-69ecbdf23d0c1.png" alt="wpid-5a89d3c6d51e3e14a911761ca6130dd0_59b9c230-6990-4fb0-8105-69ecbdf23d0"></p><p> <strong>全加器：</strong></p><p>全加器英语名称为full-adder，是用门电路实现两个二进制数相加并求出和的组合线路，称为一位全加器。一位全加器可以处理低位进位，并输出本位加法进位。多个一位全加器进行级联可以得到多位全加器。</p><p>逻辑图：</p><p><img src="/images/wpid-5a89d3c6d51e3e14a911761ca6130dd0_131598811.png" alt="wpid-5a89d3c6d51e3e14a911761ca6130dd0_131598811"></p><p>真值表：</p><p><img src="/images/wpid-5a89d3c6d51e3e14a911761ca6130dd0_b2ca6d99-5066-4638-a403-1223886910de1.png" alt="wpid-5a89d3c6d51e3e14a911761ca6130dd0_b2ca6d99-5066-4638-a403-1223886910de1"></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;&lt;strong&gt;半加器：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;半加器电路是指对两个输入数据位相加，输出一个结果位和进位，没有进位输入的加法器电路。 是实现两个一位二进制数的加法运算电路。&lt;/p&gt;
&lt;p&gt;逻辑图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/wpid-5a8
      
    
    </summary>
    
    
    
      <category term="笔记" scheme="https://slw.im/tags/%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>世界，你好！</title>
    <link href="https://slw.im/2016/08/hello-world/"/>
    <id>https://slw.im/2016/08/hello-world/</id>
    <published>2016-08-29T08:45:54.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><p>用 WordPress 搭好了博客，之前的数据库被我搞坏了，又没有备份，所以就新开了一个。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;用 WordPress 搭好了博客，之前的数据库被我搞坏了，又没有备份，所以就新开了一个。&lt;/p&gt;

      
    
    </summary>
    
    
    
      <category term="博客运维" scheme="https://slw.im/tags/%E5%8D%9A%E5%AE%A2%E8%BF%90%E7%BB%B4/"/>
    
  </entry>
  
  <entry>
    <title>C++ 输出时保留的小数位数</title>
    <link href="https://slw.im/2016/08/c-decimal-precision/"/>
    <id>https://slw.im/2016/08/c-decimal-precision/</id>
    <published>2016-08-29T06:43:06.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<p>cout语句中有一个专门用来控制小数位数的函数(setprecison)，可以方便地输出不同的小数位数。</p><p>这个函数需要包含头文件<code>#include &lt;iomanip&gt;</code></p><p>我们来看看用法：</p><blockquote><p>cout &lt;&lt; setprecision(输出位数) &lt;&lt; 变量/数字 &lt;&lt; endl;</p></blockquote><p>例如：</p><p><code>cout &lt;&lt; setprecision(2) &lt;&lt; 3.123 &lt;&lt; endl;</code></p><p>我们得到的结果就是「3.12」。</p><p>但需要注意下一个例子：</p><p><code>cout &lt;&lt; setprecision(4) &lt;&lt; 3.123456 &lt;&lt; endl;</code></p><p>这时输出的结果就是<strong>「3.1235」</strong>。</p><p>因为setprecision函数取到最后一位时，会自动<strong>四舍五入</strong>。（类似于C中printf的%.5f，也会四舍五入）</p><p>那如何不要四舍五入呢？很简单就是加上fixed：</p><blockquote><p>cout &lt;&lt; fixed &lt;&lt; setprecision(输出位数) &lt;&lt; 变量/数字 &lt;&lt; endl;</p></blockquote><p>我们来看刚刚那个例子：</p><p><code>cout &lt;&lt; fixed &lt;&lt; setprecision(4) &lt;&lt; 3.123456 &lt;&lt; endl;</code></p><p>这时输出的结果就是我们想要的「3.1234」了。</p><hr><p>参考文章：</p><p><a href="http://www.cnblogs.com/krisdy/archive/2009/04/17/1438402.html">关于保留小数点后几位数字之我见</a></p><p><a href="http://it-easy.tw/cout-float/">cout控制輸出的小數點位數</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;cout语句中有一个专门用来控制小数位数的函数(setprecison)，可以方便地输出不同的小数位数。&lt;/p&gt;
&lt;p&gt;这个函数需要包含头文件&lt;code&gt;#include &amp;lt;iomanip&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;我们来看看用法：&lt;/p&gt;
&lt;blockqu
      
    
    </summary>
    
    
    
      <category term="C++" scheme="https://slw.im/tags/C/"/>
    
  </entry>
  
  <entry>
    <title>Android入门</title>
    <link href="https://slw.im/2016/08/getting-started-with-android/"/>
    <id>https://slw.im/2016/08/getting-started-with-android/</id>
    <published>2016-08-29T05:43:30.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><p>之前报名了Google举办的Study Jams，现在已经成功结业了，也勉强算是入门了Android。</p><h2 id="VIEW"><a href="#VIEW" class="headerlink" title="VIEW"></a><a href="#VIEW" title="VIEW"></a>VIEW</h2><h3 id="XML，可拓展标记语言。"><a href="#XML，可拓展标记语言。" class="headerlink" title="XML，可拓展标记语言。"></a><a href="#XML%EF%BC%8C%E5%8F%AF%E6%8B%93%E5%B1%95%E6%A0%87%E8%AE%B0%E8%AF%AD%E8%A8%80%E3%80%82" title="XML，可拓展标记语言。"></a>XML，可拓展标记语言。</h3><p>在Android中，使用XML来确定不同的VIEWS。<br>XML中由一个个不同的标签构成，需要注意每个标签结束之后都要关闭标签。如：<code>/&gt;</code>或<code>&lt;/LinearLayout&gt;</code><br>标签中有各种不同的属性。属性可以决定手机上View的行为或外观的特性。</p><h3 id="View的分类"><a href="#View的分类" class="headerlink" title="View的分类"></a><a href="#View%E7%9A%84%E5%88%86%E7%B1%BB" title="View的分类"></a>View的分类</h3><p>常见的VIEW：</p><ol><li> TextView</li><li> ImageView</li><li> Button</li><li> ScrollView</li></ol><h3 id="dp"><a href="#dp" class="headerlink" title="dp"></a><a href="#dp" title="dp"></a>dp</h3><p>dp (density-independent pixles) 密度无关像素</p><h3 id="wrap-content"><a href="#wrap-content" class="headerlink" title="wrap_content"></a><a href="#wrap-content" title="wrap_content"></a>wrap_content</h3><p>自适应宽度或高度</p><h3 id="设置字体大小"><a href="#设置字体大小" class="headerlink" title="设置字体大小"></a><a href="#%E8%AE%BE%E7%BD%AE%E5%AD%97%E4%BD%93%E5%A4%A7%E5%B0%8F" title="设置字体大小"></a>设置字体大小</h3><p>android:textSize=”45sp”<br>android:textAppearance=”?android:textAppearanceLarge”</p><h3 id="设置字体颜色"><a href="#设置字体颜色" class="headerlink" title="设置字体颜色"></a><a href="#%E8%AE%BE%E7%BD%AE%E5%AD%97%E4%BD%93%E9%A2%9C%E8%89%B2" title="设置字体颜色"></a>设置字体颜色</h3><p>android:textColor=”@andorid:color/darker_gray”<br>android:textColor=”#十六进制数”<br>具体配色可在<a href="https://www.google.com/design/spec/material-design/introduction.html">Materal Design</a>上查看</p><h3 id="ImageView"><a href="#ImageView" class="headerlink" title="ImageView"></a><a href="#ImageView" title="ImageView"></a>ImageView</h3><p>@drawable/cake<br><strong>只引用有效文件</strong><br>@:引用<br>drawable:引用类型<br>cake:文件名（不需要后缀）</p><h3 id="ViewGroup"><a href="#ViewGroup" class="headerlink" title="ViewGroup"></a><a href="#ViewGroup" title="ViewGroup"></a>ViewGroup</h3><ul><li><p>  拥有宽度、高度、背景色等属性</p></li><li><p>  ViewGroup里面包含的是其它View</p></li><li><p>ViewGroup也算一个View</p><h3 id="LinearLayout"><a href="#LinearLayout" class="headerlink" title="LinearLayout"></a><a href="#LinearLayout" title="LinearLayout"></a>LinearLayout</h3></li><li><p>  把子视图排成竖直或水平的一排*   可以在其中摆放任意数量的View<br><img src="/images/572b11a394d88.png" alt="572b11a394d88"></p></li></ul><h4 id="match-parent"><a href="#match-parent" class="headerlink" title="match_parent"></a><a href="#match-parent" title="match_parent"></a>match_parent</h4><p>将当前View设置成与父视图等宽或等高<br><img src="/images/572b11a2033d1.png" alt="屏幕快照 2016-05-03 下午9.01.41"></p><h4 id="子视图空间平分"><a href="#子视图空间平分" class="headerlink" title="子视图空间平分"></a><a href="#%E5%AD%90%E8%A7%86%E5%9B%BE%E7%A9%BA%E9%97%B4%E5%B9%B3%E5%88%86" title="子视图空间平分"></a>子视图空间平分</h4><figure class="highlight avrasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs avrasm"><span class="hljs-symbol">android:</span>layout_height=<span class="hljs-string">&quot;0dp&quot;</span><br><span class="hljs-symbol">android:</span>layout_weight=<span class="hljs-string">&quot;1&quot;</span><br></code></pre></td></tr></table></figure><h4 id="View边框"><a href="#View边框" class="headerlink" title="View边框"></a><a href="#View%E8%BE%B9%E6%A1%86" title="View边框"></a>View边框</h4><h5 id="padding"><a href="#padding" class="headerlink" title="padding"></a><a href="#padding" title="padding"></a>padding</h5><p>包含边框<br><img src="/images/572b119ec0a28.png" alt="屏幕快照 2016-05-03 下午9.01.45"></p><ul><li><p>  andorid:padding = “8dp”<br>OR</p></li><li><p>  andorid:paddingLeft = “8dp”</p></li><li><p>  andorid:paddingRight = “8dp”</p></li><li><p>  andorid:paddingTop = “8dp”</p></li><li><p>andorid:paddingBottom = “8dp”</p><h5 id="margin"><a href="#margin" class="headerlink" title="margin"></a><a href="#margin" title="margin"></a>margin</h5><p>不包含边框<br><img src="/images/572b119edf4de.png" alt="屏幕快照 2016-05-03 下午9.01.50"></p></li><li><p>  andorid:layout_margin = “8dp”<br>OR</p></li><li><p>  andorid:layout_marginLeft = “8dp”</p></li><li><p>  andorid:layout_marginRight = “8dp”</p></li><li><p>  andorid:layout_marginTop = “8dp”</p></li><li><p>  andorid:layout_marginBottom = “8dp”<br>LinearLayout例子:</p><figure class="highlight processing"><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><code class="hljs processing">&lt;LinearLayout<br>    xmlns:android=<span class="hljs-string">&quot;http://schemas.android.com/apk/res/android&quot;</span><br>    android:orientation=<span class="hljs-string">&quot;vertical&quot;</span><br>    android:layout_width=<span class="hljs-string">&quot;match_parent&quot;</span><br>    android:layout_height=<span class="hljs-string">&quot;match_parent&quot;</span>&gt;<br>    &lt;ImageView<br>        android:src=<span class="hljs-string">&quot;@drawable/ocean&quot;</span><br>        android:layout_width=<span class="hljs-string">&quot;match_parent&quot;</span><br>        android:layout_height=<span class="hljs-string">&quot;0dp&quot;</span><br>        android:layout_weight=<span class="hljs-string">&quot;1&quot;</span><br>        android:scaleType=<span class="hljs-string">&quot;centerCrop&quot;</span> /&gt;<br>    &lt;TextView<br>        android:<span class="hljs-built_in">text</span>=<span class="hljs-string">&quot;You&#x27;re invited!&quot;</span><br>        android:layout_width=<span class="hljs-string">&quot;match_parent&quot;</span><br>        android:layout_height=<span class="hljs-string">&quot;wrap_content&quot;</span><br>        android:textColor=<span class="hljs-string">&quot;@android:color/white&quot;</span><br>        android:<span class="hljs-built_in">textSize</span>=<span class="hljs-string">&quot;54sp&quot;</span><br>        android:<span class="hljs-built_in">background</span>=<span class="hljs-string">&quot;#009688&quot;</span> /&gt;<br>    &lt;TextView<br>        android:<span class="hljs-built_in">text</span>=<span class="hljs-string">&quot;Bonfire at the beach&quot;</span><br>        android:layout_width=<span class="hljs-string">&quot;match_parent&quot;</span><br>        android:layout_height=<span class="hljs-string">&quot;wrap_content&quot;</span><br>        android:textColor=<span class="hljs-string">&quot;@android:color/white&quot;</span><br>        android:<span class="hljs-built_in">textSize</span>=<span class="hljs-string">&quot;34sp&quot;</span><br>        android:<span class="hljs-built_in">background</span>=<span class="hljs-string">&quot;#009688&quot;</span> /&gt;<br>&lt;/LinearLayout&gt;<br></code></pre></td></tr></table></figure></li></ul><p><img src="/images/572b11a95bee5.png" alt="屏幕快照 2016-05-03 下午9.02.00"></p><h3 id="RelativeLayout"><a href="#RelativeLayout" class="headerlink" title="RelativeLayout"></a><a href="#RelativeLayout" title="RelativeLayout"></a>RelativeLayout</h3><ul><li><p>可以将子视图与父布局或子视图之间相对排列</p><h4 id="View在父视图中摆放位置"><a href="#View在父视图中摆放位置" class="headerlink" title="View在父视图中摆放位置"></a><a href="#View%E5%9C%A8%E7%88%B6%E8%A7%86%E5%9B%BE%E4%B8%AD%E6%91%86%E6%94%BE%E4%BD%8D%E7%BD%AE" title="View在父视图中摆放位置"></a>View在父视图中摆放位置</h4></li><li><p>  android:layout_alignParentTop = “true” or “false”</p></li><li><p>  android:layout_alignParentBottom = “true” or “false”</p></li><li><p>  android:layout_alignParentLeft = “true” or “false”</p></li><li><p>  android:layout_alignParentRight = “true” or “false”</p></li><li><p>  android:layout_centerHorizontal = “true” or “false”</p></li><li><p>android:layout_centerVertical = “true” or “false”</p><h4 id="View之间的相对摆放位置"><a href="#View之间的相对摆放位置" class="headerlink" title="View之间的相对摆放位置"></a><a href="#View%E4%B9%8B%E9%97%B4%E7%9A%84%E7%9B%B8%E5%AF%B9%E6%91%86%E6%94%BE%E4%BD%8D%E7%BD%AE" title="View之间的相对摆放位置"></a>View之间的相对摆放位置</h4></li><li><p>  android:id = “@id+/id_name”</p></li><li><p>  android:layout_toLeftOf = “@id/id_name”</p></li><li><p>  android:layout_above = “@id/id_name”</p></li></ul>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;之前报名了Google举办的Study Jams，现在已经成功结业了，也勉强算是入门了Android。&lt;/p&gt;
&lt;h2 id=&quot;VIEW&quot;&gt;&lt;a href=&quot;#VIEW&quot;
      
    
    </summary>
    
    
    
      <category term="Android" scheme="https://slw.im/tags/Android/"/>
    
  </entry>
  
  <entry>
    <title>从 0 开始在 VPS 上部署 Laravel (Ubuntu 14.04)</title>
    <link href="https://slw.im/2016/08/deploy-lavaral-on-ubuntu/"/>
    <id>https://slw.im/2016/08/deploy-lavaral-on-ubuntu/</id>
    <published>2016-08-25T06:40:32.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a><a href="#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C" title="准备工作"></a>准备工作</h2><p>首先，你需要有一个 VPS，我这里以 Ubuntu 14.04 为例，来说说怎么部署一个最简单的 Laravel 应用。我这里都是以 root 权限运行，如果不是 root 用户，请在命令前加上<code>sudo</code>。</p><h3 id="安装语言包并设置默认语言"><a href="#安装语言包并设置默认语言" class="headerlink" title="安装语言包并设置默认语言"></a><a href="#%E5%AE%89%E8%A3%85%E8%AF%AD%E8%A8%80%E5%8C%85%E5%B9%B6%E8%AE%BE%E7%BD%AE%E9%BB%98%E8%AE%A4%E8%AF%AD%E8%A8%80" title="安装语言包并设置默认语言"></a>安装语言包并设置默认语言</h3><p>这样设置了之后可以防止之后因为编码错误而造成的一系列问题<br><code>apt-get update</code><br><code>apt-get install -y language-pack-en-base unzip</code><br><code>locale-gen en_US.UTF-8</code></p><h3 id="安装-PHP7-的准备工作"><a href="#安装-PHP7-的准备工作" class="headerlink" title="安装 PHP7 的准备工作"></a><a href="#%E5%AE%89%E8%A3%85-PHP7-%E7%9A%84%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C" title="安装 PHP7 的准备工作"></a>安装 PHP7 的准备工作</h3><p><code>apt-get install -y software-properties-common</code><br><code>LC_ALL=en_US.UTF-8 add-apt-repository ppa:ondrej/php</code><br><code>apt-get update</code></p><p><a id="more"></a></p><h3 id="安装-PHP7-amp-nginx-amp-MySQL5-6"><a href="#安装-PHP7-amp-nginx-amp-MySQL5-6" class="headerlink" title="安装 PHP7 &amp; nginx &amp; MySQL5.6"></a><a href="#%E5%AE%89%E8%A3%85-PHP7-amp-nginx-amp-MySQL5-6" title="安装 PHP7 &amp; nginx &amp; MySQL5.6"></a>安装 PHP7 &amp; nginx &amp; MySQL5.6</h3><p><code>apt-get install -y php7.1 php7.1-mysql php7.1-fpm php7.1-curl php7.1-xml php7.1-mcrypt php7.1-json php7.1-gd php7.1-mbstring nginx mysql-server-5.6</code><br>安装 MySQL 的时候要输入 root 密码，记住这个密码<br><img src="/images/mysql-password.png" alt="mysql-password"></p><p>安装完后打开浏览器，输入 VPS 的 IP 地址，看到如下网页，则说明安装成功。<br><img src="/images/nginx-setup.png" alt="nginx-setup"></p><h2 id="配置-PHP-和-nginx"><a href="#配置-PHP-和-nginx" class="headerlink" title="配置 PHP 和 nginx"></a><a href="#%E9%85%8D%E7%BD%AE-PHP-%E5%92%8C-nginx" title="配置 PHP 和 nginx"></a>配置 PHP 和 nginx</h2><h3 id="配置-PHP"><a href="#配置-PHP" class="headerlink" title="配置 PHP"></a><a href="#%E9%85%8D%E7%BD%AE-PHP" title="配置 PHP"></a>配置 PHP</h3><p><code>vi /etc/php/7.1/fpm/php.ini</code><br>将<code>;cgi.fix_pathinfo=1</code>改成<code>cgi.fix_pathinfo=0</code><br><code>vi /etc/php/7.1/fpm/pool.d/www.conf</code><br>配置<code>listen = /var/run/php7.1-fpm.sock</code><br>之后重启 php-fpm <code>service php7.1-fpm restart</code></p><h3 id="配置-nginx"><a href="#配置-nginx" class="headerlink" title="配置 nginx"></a><a href="#%E9%85%8D%E7%BD%AE-nginx" title="配置 nginx"></a>配置 nginx</h3><p><code>vi /etc/nginx/sites-available/default</code><br>参考如下修改 nginx 的配置</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">listen</span> <span class="hljs-number">80</span> default_server;<br><span class="hljs-attribute">listen</span> [::]:<span class="hljs-number">80</span> default_server;<br><span class="hljs-attribute">root</span> /var/www/laravel/public;<br><span class="hljs-attribute">index</span> index.php index.html index.htm;<br><span class="hljs-comment"># Make site accessible from http://localhost/</span><br><span class="hljs-attribute">server_name</span> localhost;<br><span class="hljs-section">location</span> / &#123;<br>        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php?<span class="hljs-variable">$query_string</span>;<br>&#125;<br><span class="hljs-section">location</span> <span class="hljs-regexp">~ \.php$</span> &#123;<br>        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> /index.php =<span class="hljs-number">404</span>;<br>        <span class="hljs-attribute">fastcgi_split_path_info</span><span class="hljs-regexp"> ^(.+\.php)(/.+)$</span>;<br>        <span class="hljs-attribute">fastcgi_pass</span> unix:/var/run/php7.1-fpm.sock;<br>        <span class="hljs-attribute">fastcgi_index</span> index.php;<br>        <span class="hljs-attribute">fastcgi_param</span> SCRIPT_FILENAME <span class="hljs-variable">$document_root</span><span class="hljs-variable">$fastcgi_script_name</span>;<br>        <span class="hljs-attribute">include</span> fastcgi_params;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="部署-Laravel"><a href="#部署-Laravel" class="headerlink" title="部署 Laravel"></a><a href="#%E9%83%A8%E7%BD%B2-Laravel" title="部署 Laravel"></a>部署 Laravel</h2><h3 id="安装-composer"><a href="#安装-composer" class="headerlink" title="安装 composer"></a><a href="#%E5%AE%89%E8%A3%85-composer" title="安装 composer"></a>安装 composer</h3><figure class="highlight scilab"><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><code class="hljs scilab">php -r <span class="hljs-string">&quot;copy(&#x27;</span>https:<span class="hljs-comment">//getcomposer.org/installer&#x27;, &#x27;composer-setup.php&#x27;);&quot;</span><br>php -r <span class="hljs-string">&quot;if (hash_file(&#x27;</span>SHA384&#x27;, <span class="hljs-string">&#x27;composer-setup.php&#x27;</span>) === <span class="hljs-string">&#x27;e115a8dc7871f15d853148a7fbac7da27d6c0030b848d9b3dc09e2a0388afed865e6a3d6b3c0fad45c48e2b5fc1196ae&#x27;</span>) &#123; echo <span class="hljs-string">&#x27;Installer verified&#x27;</span>; &#125; <span class="hljs-keyword">else</span> &#123; echo <span class="hljs-string">&#x27;Installer corrupt&#x27;</span>; unlink(<span class="hljs-string">&#x27;composer-setup.php&#x27;</span>); &#125; echo PHP_EOL;<span class="hljs-string">&quot;</span><br><span class="hljs-string">php composer-setup.php</span><br><span class="hljs-string">php -r &quot;</span>unlink(<span class="hljs-string">&#x27;composer-setup.php&#x27;</span>);<span class="hljs-string">&quot;</span><br><span class="hljs-string">mv composer.phar /usr/local/bin/composer</span><br></code></pre></td></tr></table></figure><h2 id="配置-Laravel"><a href="#配置-Laravel" class="headerlink" title="配置 Laravel"></a><a href="#%E9%85%8D%E7%BD%AE-Laravel" title="配置 Laravel"></a>配置 Laravel</h2><p>把文件<a href="/images/laravel.zip">larave</a>上传至<code>/var/www/</code>目录下<br>修改<code>storage</code>文件夹权限<code>chmod -R 775 /var/www/storage/</code><br>修改 <code>www</code> 文件夹权限 <code>chown www-data:www-data -R /var/www/</code><br>编辑<code>env</code>将<code>DB_PASSWORD=root</code>中的<code>root</code>改为之前设置的密码<br>之后运行命令<code>mv env .env</code><br>运行<code>composer install</code>，在国内的话，安装时间会比较长</p><h2 id="安装完成"><a href="#安装完成" class="headerlink" title="安装完成"></a><a href="#%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90" title="安装完成"></a>安装完成</h2><p>现在打开浏览器访问 VPS 的 IP 地址来看看效果吧。<br><img src="/images/laravel.png" alt="larave"></p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a><a href="#%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3" title="参考文档"></a>参考文档</h2><p><a href="https://laravist.com/discuss/752">从零开始部署 Laravel 项目</a><br><a href="https://getcomposer.org/download/">Download Composer</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;h2 id=&quot;准备工作&quot;&gt;&lt;a href=&quot;#准备工作&quot; class=&quot;headerlink&quot; title=&quot;准备工作&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#%E5%87%86%E5
      
    
    </summary>
    
    
    
      <category term="Laravel" scheme="https://slw.im/tags/Laravel/"/>
    
      <category term="VPS" scheme="https://slw.im/tags/VPS/"/>
    
  </entry>
  
  <entry>
    <title>Hyper_ 主机性能</title>
    <link href="https://slw.im/2016/08/hyper-performance-test/"/>
    <id>https://slw.im/2016/08/hyper-performance-test/</id>
    <published>2016-08-16T06:26:46.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><p>Hyper_ 刚刚正式发布，Hyper_是世界上第一家 Container-native 的 Docker 云服务。它的核心是底层的<a href="http://hypercontainer.io/">HyperContainer</a>虚拟化容器技术，以及<a href="http://hypernetes.com/">Hypernetes</a>多租户的 Kubernetes 系统。抱着一颗好奇心就测试了一下性能,发现性能还是不错的。</p><figure class="highlight nix"><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><code class="hljs nix">----------------------------------------------------------------------<br>CPU <span class="hljs-params">model            :</span> Intel(R) Xeon(R) CPU E5-<span class="hljs-number">2630</span> v4 @ <span class="hljs-number">2.20</span>GHz<br>Number of <span class="hljs-params">cores      :</span> <span class="hljs-number">1</span><br>CPU <span class="hljs-params">frequency        :</span> <span class="hljs-number">2199.998</span> MHz<br>Total amount of <span class="hljs-params">ram  :</span> <span class="hljs-number">494</span> MB<br>Total amount of <span class="hljs-params">swap :</span> <span class="hljs-number">0</span> MB<br>System <span class="hljs-params">uptime        :</span> <span class="hljs-number">0</span>days, <span class="hljs-number">0</span>:<span class="hljs-number">2</span>:<span class="hljs-number">52</span><br>Load <span class="hljs-params">average         :</span> <span class="hljs-number">0.32</span>, <span class="hljs-number">0.14</span>, <span class="hljs-number">0.05</span><br><span class="hljs-params">OS                   :</span> CentOS <span class="hljs-number">7.2</span>.<span class="hljs-number">1511</span><br><span class="hljs-params">Arch                 :</span> x86_64 (<span class="hljs-number">64</span> Bit)<br><span class="hljs-params">Kernel               :</span> <span class="hljs-number">4.4</span>.<span class="hljs-number">1</span>2-hyper<br><span class="hljs-operator">-</span>---------------------------------------------------------------------<br>Node NameIPv4 addressDownload Speed<br>CacheFly<span class="hljs-number">205.234</span>.<span class="hljs-number">175.175</span><span class="hljs-number">80.0</span>MB<span class="hljs-symbol">/s</span><br>Linode, Tokyo, JP<span class="hljs-number">106.187</span>.<span class="hljs-number">96.148</span><span class="hljs-number">13.5</span>MB<span class="hljs-symbol">/s</span><br>Linode, Singapore, SG<span class="hljs-number">139.162</span>.<span class="hljs-number">23.4</span><span class="hljs-number">4.31</span>MB<span class="hljs-symbol">/s</span><br>Linode, London, UK<span class="hljs-number">176.58</span>.<span class="hljs-number">107.39</span><span class="hljs-number">4.73</span>MB<span class="hljs-symbol">/s</span><br>Linode, Frankfurt, DE<span class="hljs-number">139.162</span>.<span class="hljs-number">130.8</span><span class="hljs-number">4.11</span>MB<span class="hljs-symbol">/s</span><br>Linode, Fremont, CA<span class="hljs-number">50.116</span>.<span class="hljs-number">14.9</span><span class="hljs-number">24.4</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Dallas, TX<span class="hljs-number">173.192</span>.<span class="hljs-number">68.18</span><span class="hljs-number">36.7</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Seattle, WA<span class="hljs-number">67.228</span>.<span class="hljs-number">112.250</span><span class="hljs-number">47.8</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Frankfurt, DE<span class="hljs-number">159.122</span>.<span class="hljs-number">69.4</span><span class="hljs-number">5.54</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Singapore, SG<span class="hljs-number">119.81</span>.<span class="hljs-number">28.170</span><span class="hljs-number">6.97</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, HongKong, CN<span class="hljs-number">119.81</span>.<span class="hljs-number">130.170</span><span class="hljs-number">8.23</span>MB<span class="hljs-symbol">/s</span><br><span class="hljs-operator">-</span>---------------------------------------------------------------------<br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">1</span>st run) : <span class="hljs-number">429</span> MB<span class="hljs-symbol">/s</span><br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">2</span>nd run) : <span class="hljs-number">321</span> MB<span class="hljs-symbol">/s</span><br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">3</span>rd run) : <span class="hljs-number">283</span> MB<span class="hljs-symbol">/s</span><br>Average I<span class="hljs-symbol">/O</span> <span class="hljs-params">speed  :</span> <span class="hljs-number">344.333</span> MB<span class="hljs-operator">/</span>s<br></code></pre></td></tr></table></figure><p>下面的是 DaoCloud 的性能测试，摘自<a href="https://yux.io/2016/05/13/daocloud-benchmark/">DaoCloud主机性能初探</a></p><figure class="highlight nix"><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><code class="hljs nix">----------------------------------------------------------------------<br>CPU <span class="hljs-params">model            :</span> Common KVM CPU<br>Number of <span class="hljs-params">cores      :</span> <span class="hljs-number">4</span><br>CPU <span class="hljs-params">frequency        :</span> <span class="hljs-number">2593.748</span> MHz<br>Total amount of <span class="hljs-params">ram  :</span> <span class="hljs-number">12017</span> MB<br>Total amount of <span class="hljs-params">swap :</span> <span class="hljs-number">4607</span> MB<br>System <span class="hljs-params">uptime        :</span> <span class="hljs-number">1</span>days, <span class="hljs-number">0</span>:<span class="hljs-number">28</span>:<span class="hljs-number">27</span><br><span class="hljs-params">OS                   :</span> Debian GNU<span class="hljs-symbol">/Linux</span> <span class="hljs-number">8</span><br><span class="hljs-params">Arch                 :</span> x86_64 (<span class="hljs-number">64</span> Bit)<br><span class="hljs-params">Kernel               :</span> <span class="hljs-number">3.13</span>.<span class="hljs-number">0</span><span class="hljs-operator">-</span><span class="hljs-number">8</span>5-generic<br><span class="hljs-operator">-</span>---------------------------------------------------------------------<br>Node Name                       IPv4 address            Download Speed<br><span class="hljs-params">ping:</span> unknown host<br>CacheFly<br>Linode, Tokyo, JP               <span class="hljs-number">106.187</span>.<span class="hljs-number">96.148</span>          <span class="hljs-number">5.73</span>MB<span class="hljs-symbol">/s</span><br>Linode, Singapore, SG           <span class="hljs-number">139.162</span>.<span class="hljs-number">23.4</span>            <span class="hljs-number">5.67</span>MB<span class="hljs-symbol">/s</span><br>Linode, London, UK              <span class="hljs-number">176.58</span>.<span class="hljs-number">107.39</span>           <span class="hljs-number">4.41</span>MB<span class="hljs-symbol">/s</span><br>Linode, Frankfurt, DE           <span class="hljs-number">139.162</span>.<span class="hljs-number">130.8</span>           <span class="hljs-number">5.16</span>MB<span class="hljs-symbol">/s</span><br>Linode, Fremont, CA             <span class="hljs-number">50.116</span>.<span class="hljs-number">14.9</span>             <span class="hljs-number">5.52</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Dallas, TX           <span class="hljs-number">173.192</span>.<span class="hljs-number">68.18</span>           <span class="hljs-number">5.28</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Seattle, WA          <span class="hljs-number">67.228</span>.<span class="hljs-number">112.250</span>          <span class="hljs-number">5.33</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Frankfurt, DE        <span class="hljs-number">159.122</span>.<span class="hljs-number">69.4</span>            <span class="hljs-number">5.26</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, Singapore, SG        <span class="hljs-number">119.81</span>.<span class="hljs-number">28.170</span>           <span class="hljs-number">5.03</span>MB<span class="hljs-symbol">/s</span><br>Softlayer, HongKong, CN         <span class="hljs-number">119.81</span>.<span class="hljs-number">130.170</span>          <span class="hljs-number">4.88</span>MB<span class="hljs-symbol">/s</span><br><span class="hljs-operator">-</span>---------------------------------------------------------------------<br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">1</span>st run) : <span class="hljs-number">94.0</span> MB<span class="hljs-symbol">/s</span><br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">2</span>nd run) : <span class="hljs-number">68.8</span> MB<span class="hljs-symbol">/s</span><br>I<span class="hljs-symbol">/O</span> speed(<span class="hljs-number">3</span>rd run) : <span class="hljs-number">62.2</span> MB<span class="hljs-symbol">/s</span><br>Average I<span class="hljs-operator">/</span><span class="hljs-params">O:</span> <span class="hljs-number">75</span> MB<span class="hljs-operator">/</span>s<br></code></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Hyper_ 刚刚正式发布，Hyper_是世界上第一家 Container-native 的 Docker 云服务。它的核心是底层的&lt;a href=&quot;http://hyp
      
    
    </summary>
    
    
    
      <category term="hyper docker" scheme="https://slw.im/tags/hyper-docker/"/>
    
  </entry>
  
  <entry>
    <title>从 0 开始在 VPS 上部署 Laravel (CentOS 7.2)</title>
    <link href="https://slw.im/2016/08/deploy-lavaral-on-centos/"/>
    <id>https://slw.im/2016/08/deploy-lavaral-on-centos/</id>
    <published>2016-08-13T12:11:10.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a><a href="#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C" title="准备工作"></a>准备工作</h2><p>之前写了一个 Ubuntu 系统的搭建教程，这次以 CentOS 7.2 为例，来说说怎么部署一个最简单的 Laravel 应用。我这里都是以 root 权限运行，如果不是 root 用户，请在命令前加上<code>sudo</code>。<br>先运行<code>yum update -y</code></p><h2 id="安装-lnmp-一键安装包"><a href="#安装-lnmp-一键安装包" class="headerlink" title="安装 lnmp 一键安装包"></a><a href="#%E5%AE%89%E8%A3%85-lnmp-%E4%B8%80%E9%94%AE%E5%AE%89%E8%A3%85%E5%8C%85" title="安装 lnmp 一键安装包"></a>安装 lnmp 一键安装包</h2><p>前期使用一键安装包可以有效防止莫名其妙出现的错误，简化安装步骤，这个安装过程预计需要1个小时左右的安装时间。<br>注意事项：<br>需要<strong>3GB</strong>以上硬盘剩余空间<br>需要<strong>128MB以上</strong>内存(如果为128MB的小内存VPS,Xen的需要有SWAP,OpenVZ的至少要有128MB以上的vSWAP或突发内存)，注意小内存请勿使用64位系统！<br>安装MySQL 5.6或5.7及MariaDB 10必须<strong>1G以上内存</strong>!</p><p><a id="more"></a></p><p>首先安装 screen：<code>yum install -y screen</code><br>然后运行<code>screen -S lnmp</code><br>如果网路出现中断，可以执行命令 <code>screen -r lnmp</code> 重新连接安装窗口<br>然后是安装 lnmp:<code>wget -c http://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz &amp;amp;&amp;amp; tar zxf lnmp1.3-full.tar.gz &amp;amp;&amp;amp; cd lnmp1.3-full &amp;amp;&amp;amp; ./install.sh lnmp</code><br>安装过程中需要输入 MySQL 的 root 密码，后面设置可以自己设置，或者参考我下面的设置。</p><figure class="highlight asciidoc"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs asciidoc"><span class="hljs-code">+------------------------------------------------------------------------+</span><br><span class="hljs-section">|          LNMP V1.3 for CentOS Linux Server, Written by Licess          |</span><br><span class="hljs-section">+------------------------------------------------------------------------+</span><br><span class="hljs-section">|        A tool to auto-compile &amp; install LNMP/LNMPA/LAMP on Linux       |</span><br><span class="hljs-section">+------------------------------------------------------------------------+</span><br><span class="hljs-section">|          For more information please visit http://www.lnmp.org         |</span><br><span class="hljs-section">+------------------------------------------------------------------------+</span><br>Please setup root password of MySQL.(Default password: root)<br>Please enter: root<br><span class="hljs-section">MySQL root password: root</span><br><span class="hljs-section">===========================</span><br>Do you want to enable or disable the InnoDB Storage Engine?<br>Default enable,Enter your choice [Y/n]: Y<br><span class="hljs-section">You will disable the InnoDB Storage Engine!</span><br><span class="hljs-section">===========================</span><br>You have 5 options for your DataBase install.<br>1: Install MySQL 5.1.73<br>2: Install MySQL 5.5.48 (Default)<br>3: Install MySQL 5.6.29<br>4: Install MariaDB 5.5.48<br>5: Install MariaDB 10.0.23<br>6: Install MySQL 5.7.11<br>Enter your choice (1, 2, 3, 4, 5 or 6): 2<br><span class="hljs-section">You will install MySQL 5.5.48</span><br><span class="hljs-section">===========================</span><br>You have 6 options for your PHP install.<br>1: Install PHP 5.2.17<br>2: Install PHP 5.3.29<br>3: Install PHP 5.4.45 (Default)<br>4: Install PHP 5.5.36<br>5: Install PHP 5.6.22<br>6: Install PHP 7.0.7<br>Enter your choice (1, 2, 3, 4, 5 or 6): 6<br><span class="hljs-section">You will install PHP 7.0.7</span><br><span class="hljs-section">===========================</span><br>You have 3 options for your Memory Allocator install.<br>1: Don&#x27;t install Memory Allocator. (Default)<br>2: Install Jemalloc<br>3: Install TCMalloc<br>Enter your choice (1, 2 or 3): 1<br>You will install not install Memory Allocator.<br>Press any key to install...or Press Ctrl+c to cancel<br></code></pre></td></tr></table></figure><h3 id="配置-nginx"><a href="#配置-nginx" class="headerlink" title="配置 nginx"></a><a href="#%E9%85%8D%E7%BD%AE-nginx" title="配置 nginx"></a>配置 nginx</h3><p><code>vi /usr/local/nginx/conf/nginx.conf</code><br>参考如下修改 nginx 的配置</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs nginx"><span class="hljs-attribute">listen</span> <span class="hljs-number">80</span> default_server;<br><span class="hljs-attribute">listen</span> [::]:<span class="hljs-number">80</span> default_server;<br><span class="hljs-attribute">root</span> /var/www/laravel/public;<br><span class="hljs-attribute">index</span> index.php index.html index.htm;<br><span class="hljs-comment"># Make site accessible from http://localhost/</span><br><span class="hljs-attribute">server_name</span> localhost;<br><span class="hljs-section">location</span> / &#123;<br>        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> <span class="hljs-variable">$uri</span>/ /index.php?<span class="hljs-variable">$query_string</span>;<br>&#125;<br><span class="hljs-section">location</span> <span class="hljs-regexp">~ \.php$</span> &#123;<br>        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> /index.php =<span class="hljs-number">404</span>;<br>        <span class="hljs-attribute">fastcgi_split_path_info</span><span class="hljs-regexp"> ^(.+\.php)(/.+)$</span>;<br>        <span class="hljs-attribute">fastcgi_pass</span> unix:/var/run/php-fpm.sock;<br>        <span class="hljs-attribute">fastcgi_index</span> index.php;<br>        <span class="hljs-attribute">fastcgi_param</span> SCRIPT_FILENAME <span class="hljs-variable">$document_root</span><span class="hljs-variable">$fastcgi_script_name</span>;<br>        <span class="hljs-attribute">include</span> fastcgi_params;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="部署-Laravel"><a href="#部署-Laravel" class="headerlink" title="部署 Laravel"></a><a href="#%E9%83%A8%E7%BD%B2-Laravel" title="部署 Laravel"></a>部署 Laravel</h2><h3 id="安装-composer"><a href="#安装-composer" class="headerlink" title="安装 composer"></a><a href="#%E5%AE%89%E8%A3%85-composer" title="安装 composer"></a>安装 composer</h3><figure class="highlight scilab"><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><code class="hljs scilab">php -r <span class="hljs-string">&quot;copy(&#x27;</span>https:<span class="hljs-comment">//getcomposer.org/installer&#x27;, &#x27;composer-setup.php&#x27;);&quot;</span><br>php -r <span class="hljs-string">&quot;if (hash_file(&#x27;</span>SHA384&#x27;, <span class="hljs-string">&#x27;composer-setup.php&#x27;</span>) === <span class="hljs-string">&#x27;e115a8dc7871f15d853148a7fbac7da27d6c0030b848d9b3dc09e2a0388afed865e6a3d6b3c0fad45c48e2b5fc1196ae&#x27;</span>) &#123; echo <span class="hljs-string">&#x27;Installer verified&#x27;</span>; &#125; <span class="hljs-keyword">else</span> &#123; echo <span class="hljs-string">&#x27;Installer corrupt&#x27;</span>; unlink(<span class="hljs-string">&#x27;composer-setup.php&#x27;</span>); &#125; echo PHP_EOL;<span class="hljs-string">&quot;</span><br><span class="hljs-string">php composer-setup.php</span><br><span class="hljs-string">php -r &quot;</span>unlink(<span class="hljs-string">&#x27;composer-setup.php&#x27;</span>);<span class="hljs-string">&quot;</span><br><span class="hljs-string">mv composer.phar /usr/local/bin/composer</span><br></code></pre></td></tr></table></figure><h2 id="配置-Laravel"><a href="#配置-Laravel" class="headerlink" title="配置 Laravel"></a><a href="#%E9%85%8D%E7%BD%AE-Laravel" title="配置 Laravel"></a>配置 Laravel</h2><p>把文件<a href="/images/laravel.zip">larave</a>上传至<code>/home/wwwroot/</code>目录下<br>修改<code>storage</code>文件夹权限<code>chmod -R 775 /home/wwwroot/laravel/storage/</code><br><code>chown www:www -R /home/wwwroot/laravel/</code><br>编辑<code>env</code>将<code>DB_PASSWORD=root</code>中的<code>root</code>改为之前设置的密码<br>之后运行命令<code>mv env .env</code><br>运行<code>composer install</code>，在国内的话，安装时间会比较长</p><h2 id="安装完成"><a href="#安装完成" class="headerlink" title="安装完成"></a><a href="#%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90" title="安装完成"></a>安装完成</h2><p>现在打开浏览器访问 VPS 的 IP 地址来看看效果吧。<br><img src="/images/laravel.png" alt="larave"></p><h2 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a><a href="#%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3" title="参考文档"></a>参考文档</h2><p><a href="https://webtatic.com/packages/php70/">PHP 7 on CentOS/RHEL 6.8 and 7.2 via Yum</a><br><a href="http://www.ahlinux.com/centos/23340.html">阿里云CentOS 7.1使用yum安装MySql5.6.24</a><br><a href="https://laravist.com/discuss/752">从零开始部署 Laravel 项目</a><br><a href="https://getcomposer.org/download/">Download Composer</a><br><a href="https://www.slinvent.com/2016/deploy-laravel-on-vps/">从 0 开始在 VPS 上部署 Laravel (Ubuntu 14.04)</a></p>]]></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;a href=&quot;#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot; title=&quot;准备工作&quot;&gt;&lt;/a&gt;准备工作&lt;/h2&gt;
      
    
    </summary>
    
    
    
      <category term="Laravel" scheme="https://slw.im/tags/Laravel/"/>
    
      <category term="VPS" scheme="https://slw.im/tags/VPS/"/>
    
  </entry>
  
  <entry>
    <title>用 Let’s Encrypt 使你的网站用上 https</title>
    <link href="https://slw.im/2016/08/lets-encrypt-https/"/>
    <id>https://slw.im/2016/08/lets-encrypt-https/</id>
    <published>2016-08-02T07:46:14.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><p><img src="/images/006tNbRwgw1f5tq6hq9rnj309a02774g.jpg" alt="006tNbRwgw1f5tq6hq9rnj309a02774g">￼</p><p>在网上查找了不少资料之后终于弄好了 Let’s Encrypt 的 https 证书。</p><h2 id="Let’s-Encrypt"><a href="#Let’s-Encrypt" class="headerlink" title="Let’s Encrypt"></a><a href="#Let%E2%80%99s-Encrypt" title="Let’s Encrypt"></a>Let’s Encrypt</h2><p><a href="https://letsencrypt.org/">Let’s Encrypt</a>是由EFF、Mozilla、Cisco、Akamai、IdenTrust与密西根大学研究人员共同创立的免费的凭证中心，目的在于推动全球所有的网站都使用HTTPS加密传输，并由非营利的网际网路安全研究组织Internet Security Research Group(ISRG)负责营运。<br>我选择 Let’s Encrypt 的原因之一就是因为证书是免费的。</p><p><a id="more"></a></p><h2 id="首次生成证书"><a href="#首次生成证书" class="headerlink" title="首次生成证书"></a><a href="#%E9%A6%96%E6%AC%A1%E7%94%9F%E6%88%90%E8%AF%81%E4%B9%A6" title="首次生成证书"></a>首次生成证书</h2><h3 id="从Github签出Let’s-Encrypt的源代码"><a href="#从Github签出Let’s-Encrypt的源代码" class="headerlink" title="从Github签出Let’s Encrypt的源代码"></a><a href="#%E4%BB%8EGithub%E7%AD%BE%E5%87%BALet%E2%80%99s-Encrypt%E7%9A%84%E6%BA%90%E4%BB%A3%E7%A0%81" title="从Github签出Let’s Encrypt的源代码"></a>从Github签出Let’s Encrypt的源代码</h3><p><code>git clone https://github.com/letsencrypt/letsencrypt</code></p><h3 id="进入本地源代码目录"><a href="#进入本地源代码目录" class="headerlink" title="进入本地源代码目录"></a><a href="#%E8%BF%9B%E5%85%A5%E6%9C%AC%E5%9C%B0%E6%BA%90%E4%BB%A3%E7%A0%81%E7%9B%AE%E5%BD%95" title="进入本地源代码目录"></a>进入本地源代码目录</h3><p><code>cd letsencrypt</code><br>Let’s Encrypt提供多种认证方式，因为之前在VPS上有了HTTP的网站，所以这里采用了webroot的方式，其他方式请参考官方文档</p><h4 id="主域名的认证"><a href="#主域名的认证" class="headerlink" title="主域名的认证"></a><a href="#%E4%B8%BB%E5%9F%9F%E5%90%8D%E7%9A%84%E8%AE%A4%E8%AF%81" title="主域名的认证"></a>主域名的认证</h4><p><code>./letsencrypt-auto --debug certonly --webroot --email name@your_main_domain.com -d your_main_domain.com -d www.your_main_domain.com -w /var/www/your_main_domain.com</code></p><h4 id="子域名的认证"><a href="#子域名的认证" class="headerlink" title="子域名的认证"></a><a href="#%E5%AD%90%E5%9F%9F%E5%90%8D%E7%9A%84%E8%AE%A4%E8%AF%81" title="子域名的认证"></a>子域名的认证</h4><p><code>./letsencrypt-auto --debug certonly --webroot --email name@your_main_domain.com -d subdomain.your_main_domain.com -w /var/www/your_main_domain.com/subdomain</code><br>然后在弹出的蓝底白字提示框中一路点击”OK”</p><h3 id="注意如下问题"><a href="#注意如下问题" class="headerlink" title="注意如下问题"></a><a href="#%E6%B3%A8%E6%84%8F%E5%A6%82%E4%B8%8B%E9%97%AE%E9%A2%98" title="注意如下问题"></a>注意如下问题</h3><pre><code class="hljs">*   请将命令中的name, your_main_domain.com, subdomain替换成你自己的名字，域名以及子域名 *   因为Gentoo目前是在试验阶段，所以命令行加上--debug参数*   参数--email如果没有在命令行加上，会在随后弹出的对话框里提示你填写*   -w指定Web服务器网址内容放置的目录，请指定自己放置的目录</code></pre><p>生成的证书放在<code>/etc/letsencrypt/live/[网站域名]</code>下</p><table><thead><tr><th>文件名</th><th>内容</th></tr></thead><tbody><tr><td>cert.pem</td><td>服务端证书</td></tr><tr><td>chain.pem</td><td>浏览器需要的所有证书但不包括服务端证书，比如根证书和中间证书</td></tr><tr><td>fullchain.pem</td><td>包括了cert.pem和chain.pem的内容</td></tr><tr><td>privkey.pem</td><td>证书的私钥</td></tr></tbody></table><p>一般情况下 <code>fullchain.pem</code> 和 <code>privkey.pem</code> 就够用了</p><h2 id="Nginx配置"><a href="#Nginx配置" class="headerlink" title="Nginx配置"></a><a href="#Nginx%E9%85%8D%E7%BD%AE" title="Nginx配置"></a>Nginx配置</h2><p>我使用的是 lnmp 的一键安装包，打开 <code>/usr/local/nginx/conf/vhost/</code> 下 <code>域名.conf</code> 的文件，改成类似下面的设置。</p><figure class="highlight pgsql"><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><code class="hljs pgsql"><span class="hljs-keyword">server</span> &#123;<br>    <span class="hljs-keyword">listen</span>    <span class="hljs-number">80</span>;<br>    server_name    www.slinvent.com slinvent.com;<br>    <span class="hljs-keyword">return</span>   <span class="hljs-number">301</span> https://$server_name$<span class="language-pgsql">request_uri;</span><br><span class="language-pgsql">&#125;</span><br><span class="language-pgsql"><span class="hljs-keyword">server</span></span><br><span class="language-pgsql">    &#123;</span><br><span class="language-pgsql">        <span class="hljs-keyword">listen</span> <span class="hljs-number">443</span> ssl;</span><br><span class="language-pgsql">        #<span class="hljs-keyword">listen</span> [::]:<span class="hljs-number">80</span>;</span><br><span class="language-pgsql">        server_name www.slinvent.com slinvent.com;</span><br><span class="language-pgsql">        <span class="hljs-keyword">index</span> <span class="hljs-keyword">index</span>.html <span class="hljs-keyword">index</span>.htm <span class="hljs-keyword">index</span>.php <span class="hljs-keyword">default</span>.html <span class="hljs-keyword">default</span>.htm <span class="hljs-keyword">default</span>.php;</span><br><span class="language-pgsql">        root  /home/wwwroot/www.slinvent.com;</span><br><span class="language-pgsql">        ssl_certificate /etc/letsencrypt/live/slinvent.com/fullchain.pem;</span><br><span class="language-pgsql">        ssl_certificate_key /etc/letsencrypt/live/slinvent.com/privkey.pem;</span><br><span class="language-pgsql">        ssl_protocols TLSv1 TLSv1<span class="hljs-number">.1</span> TLSv1<span class="hljs-number">.2</span>;</span><br><span class="language-pgsql">        ssl_prefer_server_ciphers <span class="hljs-keyword">on</span>;</span><br><span class="language-pgsql">        ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;</span><br><span class="language-pgsql">        ……</span><br><span class="language-pgsql">    &#125;</span><br></code></pre></td></tr></table></figure><p>其中<code>return   301 https://$server_name$request_uri;</code>是用来实现80端口到443端口的流量跳转的。<br>最后再执行：<code>/etc/init.d/nginx reload</code> 重新载入配置使其生效。</p><h2 id="更新证书"><a href="#更新证书" class="headerlink" title="更新证书"></a><a href="#%E6%9B%B4%E6%96%B0%E8%AF%81%E4%B9%A6" title="更新证书"></a>更新证书</h2><p><code>./letsencrypt-auto renew</code></p><h2 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a><a href="#%E5%8F%82%E8%80%83%E6%96%87%E7%AB%A0" title="参考文章"></a>参考文章</h2><p><a href="http://www.jianshu.com/p/5575893df1ed">使用Let’s Encrypt轻松实现站点https</a><br><a href="http://www.jianshu.com/p/ba2a384e89ec">Let’s Encrypt给你的网站穿上HTTPS的铠甲，防止http劫持</a><br><a href="http://bbs.qcloud.com/thread-12059-1-1.html">如何在Nginx上部署 Let’s Encrypt 证书</a><br><a href="http://www.vpser.net/build/letsencrypt-free-ssl.html">免费SSL安全证书Let’s Encrypt安装使用教程(附Nginx/Apache配置)</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;img src=&quot;/images/006tNbRwgw1f5tq6hq9rnj309a02774g.jpg&quot; alt=&quot;006tNbRwgw1f5tq6hq9rnj30
      
    
    </summary>
    
    
    
      <category term="letsencrypt" scheme="https://slw.im/tags/letsencrypt/"/>
    
      <category term="https" scheme="https://slw.im/tags/https/"/>
    
  </entry>
  
  <entry>
    <title>Mingw32 gcc/g++ 在windows 8下的安装过程</title>
    <link href="https://slw.im/2016/08/mingw32-gcc-g-install-on-windows-8/"/>
    <id>https://slw.im/2016/08/mingw32-gcc-g-install-on-windows-8/</id>
    <published>2016-08-01T06:40:54.000Z</published>
    <updated>2026-06-09T06:04:57.748Z</updated>
    
    <content type="html"><![CDATA[<script src="/assets/js/APlayer.min.js"> </script><h4 id="下载地址"><a href="#下载地址" class="headerlink" title="下载地址"></a><a href="#%E4%B8%8B%E8%BD%BD%E5%9C%B0%E5%9D%80" title="下载地址"></a>下载地址</h4><p><a href="http://sourceforge.net/projects/mingw/files/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip/download">mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip</a></p><h4 id="解压"><a href="#解压" class="headerlink" title="解压"></a><a href="#%E8%A7%A3%E5%8E%8B" title="解压"></a>解压</h4><p>将其解压至 C:\mingw</p><p><a id="more"></a></p><h4 id="Win-R-打开运行-gt-输入cmd-gt-点击确定"><a href="#Win-R-打开运行-gt-输入cmd-gt-点击确定" class="headerlink" title="Win+R 打开运行 -&gt; 输入cmd -&gt; 点击确定"></a><a href="#Win-R-%E6%89%93%E5%BC%80%E8%BF%90%E8%A1%8C-gt-%E8%BE%93%E5%85%A5cmd-gt-%E7%82%B9%E5%87%BB%E7%A1%AE%E5%AE%9A" title="Win+R 打开运行 -&gt; 输入cmd -&gt; 点击确定"></a>Win+R 打开运行 -&gt; 输入cmd -&gt; 点击确定</h4><p><img src="/images/1.jpg" alt="1"></p><p>输入 cd c:\mingw\bin</p><p><img src="/images/2.jpg" alt="2"></p><h4 id="更新"><a href="#更新" class="headerlink" title="更新"></a><a href="#%E6%9B%B4%E6%96%B0" title="更新"></a>更新</h4><p>输入 mingw-get upgrade</p><p><img src="/images/3.jpg" alt="3"></p><h4 id="安装"><a href="#安装" class="headerlink" title="安装"></a><a href="#%E5%AE%89%E8%A3%85" title="安装"></a>安装</h4><p><img src="/images/4.jpg" alt="4"></p><h4 id="环境设置"><a href="#环境设置" class="headerlink" title="环境设置"></a><a href="#%E7%8E%AF%E5%A2%83%E8%AE%BE%E7%BD%AE" title="环境设置"></a>环境设置</h4><p>“计算机”右键-&gt;“属性”</p><p><img src="/images/5.jpg" alt="5"></p><p><img src="/images/6.jpg" alt="6"></p><p><img src="/images/7.jpg" alt="7"></p><p>“高级系统设置” -&gt; “环境变量” ，在”系统变量（S）”，在“Path”，里增加 gcc/g++的目录：</p><p>c:\mingw\bin</p><p>新建LIBRARY_PATH变量，如果有的话，在值中加入C:\MinGW\lib;</p><p>新建</p><p>C_INCLUDEDE_PATH变量，值设为C:\MinGW\include;</p><h4 id="重新启动计算机命令行"><a href="#重新启动计算机命令行" class="headerlink" title="重新启动计算机命令行"></a><a href="#%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%91%BD%E4%BB%A4%E8%A1%8C" title="重新启动计算机命令行"></a>重新启动<del>计算机</del>命令行</h4><h4 id="检验是否安装完成"><a href="#检验是否安装完成" class="headerlink" title="检验是否安装完成"></a><a href="#%E6%A3%80%E9%AA%8C%E6%98%AF%E5%90%A6%E5%AE%89%E8%A3%85%E5%AE%8C%E6%88%90" title="检验是否安装完成"></a>检验是否安装完成</h4><p>直接运行cmd命令行，输入g++ -v</p><p><img src="/images/8.jpg" alt="8"></p><h3 id="参考文档："><a href="#参考文档：" class="headerlink" title="参考文档："></a><a href="#%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3%EF%BC%9A" title="参考文档："></a>参考文档：</h3><p><a href="http://hi.baidu.com/lmstz/item/d9248feba18497cfbbf37d8b">Mingw32 gcc/g++ 的安装过程</a></p><p><a href="http://wenku.baidu.com/link?url=a1NsXuYLF_yHiCY6TZpvu7ly-LxJBLMcjAd0nsxZwSoKssHx7OS4NDgs4aTCZji0UGtFmrY5q3jROq87EJpcz6XyGt2qNmmUg3uDMwKJDLW">S​u​b​l​i​m​e​_​T​e​x​t​ ​3​搭​建​c​ ​c​+​+​ ​j​a​v​a​语​言​开​发​环​境​教​程</a></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;script src=&quot;/assets/js/APlayer.min.js&quot;&gt; &lt;/script&gt;

&lt;h4 id=&quot;下载地址&quot;&gt;&lt;a href=&quot;#下载地址&quot; class=&quot;headerlink&quot; title=&quot;下载地址&quot;&gt;&lt;/a&gt;&lt;a href=&quot;#%E4%B8%8B%E8
      
    
    </summary>
    
    
    
      <category term="调试" scheme="https://slw.im/tags/%E8%B0%83%E8%AF%95/"/>
    
  </entry>
  
</feed>
