<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Zcp&#39;s Zone</title>
    <link>https://chengpengzhao.com/</link>
    
    <image>
      <url>https://chengpengzhao.com/medias/logo.png</url>
      <title>Zcp&#39;s Zone</title>
      <link>https://chengpengzhao.com/</link>
    </image>
    
    <atom:link href="/rss2.xml" rel="self" type="application/rss+xml"/>
    
    <description>この、くそったれな世界に、精一杯愛をこめて</description>
    <pubDate>Sun, 19 Apr 2026 08:50:12 GMT</pubDate>
    <generator>http://hexo.io/</generator>
    
    <item>
      <title>gitlab跨多个版本更新</title>
      <link>https://chengpengzhao.com/2026-04-19-gitlab-kua-duo-ge-ban-ben-geng-xin/</link>
      <guid>https://chengpengzhao.com/2026-04-19-gitlab-kua-duo-ge-ban-ben-geng-xin/</guid>
      <pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;背景&quot;&gt;1&amp;emsp;背景&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;之前用
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="背景">1&emsp;背景</h1><ul><li><p>之前用的15.10.2版本，已经比较旧了：一方面是安全和兼容性风险越来越高，另一方面很多新功能、修复和维护工具都已经跟老版本脱节了  </p></li><li><p>gitlab更新比较麻烦，某些版本必须先停留，不能直接跨过去  </p></li></ul><h1 id="下载安装包">2&emsp;下载安装包</h1><p>按照<a href="https://gitlab-com.gitlab.io/support/toolbox/upgrade-path/?current=15.10.2" target="_blank" rel="noopener">官方升级路径查询</a>，先准备好这些安装包。由于我用的是<code>Ubuntu22.04</code>系统，直接用<code>deb</code>包来装了。  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#download.sh</span><span class="token comment" spellcheck="true">#!/usr/bin/env bash</span><span class="token keyword">set</span> -euo pipefailBASE_URL<span class="token operator">=</span><span class="token string">"https://packages.gitlab.com/gitlab/gitlab-ce/ubuntu/jammy/pool/main/g/gitlab-ce"</span>ARCH<span class="token operator">=</span><span class="token string">"amd64"</span>OUTDIR<span class="token operator">=</span><span class="token string">"<span class="token variable">${1:-gitlab-ce-upgrade-packages}</span>"</span>VERSIONS<span class="token operator">=</span><span class="token punctuation">(</span>  <span class="token string">"15.11.13-ce.0"</span>  <span class="token string">"16.3.9-ce.0"</span>  <span class="token string">"16.7.10-ce.0"</span>  <span class="token string">"16.11.10-ce.0"</span>  <span class="token string">"17.3.7-ce.0"</span>  <span class="token string">"17.5.5-ce.0"</span>  <span class="token string">"17.8.7-ce.0"</span>  <span class="token string">"17.11.7-ce.0"</span>  <span class="token string">"18.2.8-ce.0"</span>  <span class="token string">"18.5.5-ce.0"</span>  <span class="token string">"18.8.9-ce.0"</span>  <span class="token string">"18.11.0-ce.0"</span><span class="token punctuation">)</span><span class="token function">mkdir</span> -p <span class="token string">"<span class="token variable">$OUTDIR</span>"</span><span class="token function">cd</span> <span class="token string">"<span class="token variable">$OUTDIR</span>"</span><span class="token keyword">for</span> ver <span class="token keyword">in</span> <span class="token string">"<span class="token variable">${VERSIONS[@]}</span>"</span><span class="token punctuation">;</span> <span class="token keyword">do</span>  file<span class="token operator">=</span><span class="token string">"gitlab-ce_<span class="token variable">${ver}</span>_<span class="token variable">${ARCH}</span>.deb"</span>  url<span class="token operator">=</span><span class="token string">"<span class="token variable">${BASE_URL}</span>/<span class="token variable">${file}</span>"</span>  <span class="token keyword">echo</span> <span class="token string">"Downloading <span class="token variable">${file}</span> ..."</span>  <span class="token function">wget</span> -c <span class="token string">"<span class="token variable">$url</span>"</span><span class="token keyword">done</span><span class="token keyword">echo</span><span class="token keyword">echo</span> <span class="token string">"Done. Packages saved in: <span class="token variable"><span class="token variable">$(</span><span class="token function">pwd</span><span class="token variable">)</span></span>"</span><span class="token function">ls</span> -lh<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="漫长的升级过程">3&emsp;漫长的升级过程</h1><p>直接写了个脚本来一步步安装，<strong>安装前保证旧版本的gitlab正常运行，并且已经做好备份</strong>：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># install.sh</span><span class="token comment" spellcheck="true">#!/usr/bin/env bash</span><span class="token keyword">set</span> -euo pipefailPACKAGES<span class="token operator">=</span><span class="token punctuation">(</span>  <span class="token string">"gitlab-ce_15.11.13-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_16.3.9-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_16.7.10-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_16.11.10-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_17.3.7-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_17.5.5-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_17.8.7-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_17.11.7-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_18.2.8-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_18.5.5-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_18.8.9-ce.0_amd64.deb"</span>  <span class="token string">"gitlab-ce_18.11.0-ce.0_amd64.deb"</span><span class="token punctuation">)</span><span class="token keyword">for</span> pkg <span class="token keyword">in</span> <span class="token string">"<span class="token variable">${PACKAGES[@]}</span>"</span><span class="token punctuation">;</span> <span class="token keyword">do</span>  <span class="token keyword">echo</span> <span class="token string">"Installing <span class="token variable">$pkg</span> ..."</span>  <span class="token function">sudo</span> dpkg -i <span class="token string">"./<span class="token variable">$pkg</span>"</span>  <span class="token function">sudo</span> gitlab-ctl reconfigure  <span class="token function">sudo</span> gitlab-ctl restart  <span class="token keyword">echo</span> <span class="token string">"Check background migrations before continuing."</span>  <span class="token function">sudo</span> gitlab-rails runner <span class="token string">'puts Gitlab::BackgroundMigration.remaining'</span>  <span class="token function">read</span> -rp <span class="token string">"Press Enter to continue to the next version..."</span><span class="token keyword">done</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这个脚本好像执行到<code>18.5.5</code>左右版本时会报个小错误，可能是某个命令(<code>gitlab-rails</code>那行)太旧用法改变了，但不妨碍继续运行安装。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-04-19-gitlab-kua-duo-ge-ban-ben-geng-xin/#disqus_thread</comments>
    </item>
    
    <item>
      <title>部署nextcloud并实现文件上传审批功能</title>
      <link>https://chengpengzhao.com/2026-04-06-bu-shu-nextcloud-bing-shi-xian-wen-jian-shang-chuan-shen-pi-gong-neng/</link>
      <guid>https://chengpengzhao.com/2026-04-06-bu-shu-nextcloud-bing-shi-xian-wen-jian-shang-chuan-shen-pi-gong-neng/</guid>
      <pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;背景&quot;&gt;1&amp;emsp;背景&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;团队有
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="背景">1&emsp;背景</h1><ul><li><p>团队有内部研发环境，需要控制其文件导出能力，故对每次导出操作进行审批，避免关键代码泄漏</p></li><li><p>经过一番调研没有找到特别好用的开源文件导出系统（之前买过的付费的系统也难用的一匹）</p></li><li><p>nextcloud作为生态最完善的网盘之一，拥有庞大的社区和开发者/插件，可以支持各种功能</p></li><li><p>坑爹的Nextcloud All-in-One，<strong>部署难搞的一匹</strong>，各种卡住/某个服务起不起来，弄了几个晚上没解决，写的真是辣鸡</p></li></ul><h1 id="整体方案">2&emsp;整体方案</h1><ul><li><p>手写docker-compose 部署nextcloud</p></li><li><p>approval插件完成核心审批功能（基于标签）</p></li><li><p>files_accesscontrol插件用于文件可访问性的控制</p></li><li><p>files_automatedtagging用于给文件自动大标签</p></li></ul><h1 id="快速部署-Nextcloud">3&emsp;快速部署 Nextcloud</h1><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">nextcloud</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> nextcloud    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> nextcloud_web    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token datetime number">80:80</span>      <span class="token punctuation">-</span> 443<span class="token punctuation">:</span><span class="token number">443</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./nextcloud<span class="token punctuation">:</span>/var/www/html    <span class="token key atrule">links</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> db      <span class="token punctuation">-</span> redis  <span class="token key atrule">db</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> mariadb    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> nextcloud_mariadb    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 3306<span class="token punctuation">:</span><span class="token number">3306</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./mysql<span class="token punctuation">:</span>/var/lib/mysql    <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">-</span><span class="token punctuation">-</span>default<span class="token punctuation">-</span>authentication<span class="token punctuation">-</span>plugin=mysql_native_password <span class="token punctuation">-</span><span class="token punctuation">-</span>character<span class="token punctuation">-</span>set<span class="token punctuation">-</span>server=utf8mb4 <span class="token punctuation">-</span><span class="token punctuation">-</span>collation<span class="token punctuation">-</span>server=utf8mb4_unicode_ci <span class="token punctuation">-</span><span class="token punctuation">-</span>max<span class="token punctuation">-</span>allowed<span class="token punctuation">-</span>packet=10G    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token key atrule">TZ</span><span class="token punctuation">:</span> Asia/Taipei      <span class="token key atrule">MYSQL_ROOT_PASSWORD</span><span class="token punctuation">:</span> password1234      <span class="token key atrule">MYSQL_DATABASE</span><span class="token punctuation">:</span> nextcloud      <span class="token key atrule">MYSQL_USER</span><span class="token punctuation">:</span> nextcloud      <span class="token key atrule">MYSQL_PASSWORD</span><span class="token punctuation">:</span> password1234  <span class="token key atrule">phpmyadmin</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> phpmyadmin    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> nextcloud_phpmyadmin    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"8081:80"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> PMA_HOST=db      <span class="token punctuation">-</span> UPLOAD_LIMIT=10G  <span class="token key atrule">redis</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> redis<span class="token punctuation">:</span>alpine    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> nextcloud_redis    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">environment</span><span class="token punctuation">:</span>        <span class="token punctuation">-</span> TZ=Asia/Taipei    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>        <span class="token punctuation">-</span> ./redis<span class="token punctuation">:</span>/data    <span class="token key atrule">command</span><span class="token punctuation">:</span> /bin/sh <span class="token punctuation">-</span>c "redis<span class="token punctuation">-</span>server <span class="token punctuation">-</span><span class="token punctuation">-</span>requirepass $$REDIS_HOST_PASSWORD"    <span class="token key atrule">env_file</span><span class="token punctuation">:</span>        <span class="token punctuation">-</span> redis.env<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre><code># redis.env文件REDIS_HOST_PASSWORD=password1234</code></pre><p>只需要两个文件，pull一下就部署好了，再次提醒<strong>避雷Nextcloud AIO（个人部署体验极差）</strong></p><h1 id="安装插件、修改配置">4&emsp;安装插件、修改配置</h1><ol><li><p>官网下载插件，压缩包解压到<code>nextcloud/apps</code>文件中  </p></li><li><p>设置<code>trusted_domains</code>，路径为<code>config/config.php</code>  </p></li><li><p><code>sudo docker compose down &amp;&amp; sudo docker compose up -d</code>重启即可</p></li></ol><h1 id="定义（审批）流程">5&emsp;定义（审批）流程</h1><ul><li>核心是通过几个标签：如<code>通过</code>、<code>审批</code>、<code>拒绝</code>等来控制审批状态</li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260406114859465.png" alt></p><ul><li>然后通过插件完成配套的权限控制</li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260406114817114.png" alt></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-04-06-bu-shu-nextcloud-bing-shi-xian-wen-jian-shang-chuan-shen-pi-gong-neng/#disqus_thread</comments>
    </item>
    
    <item>
      <title>VMWare Horizon 8(2312) 团队配置与使用（下）</title>
      <link>https://chengpengzhao.com/2026-04-03-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-2/</link>
      <guid>https://chengpengzhao.com/2026-04-03-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-2/</guid>
      <pubDate>Fri, 03 Apr 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;场景需
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><ul><li><p>场景需求：团队共享桌面、远程办公、研发测试、统一环境管理</p></li><li><p><a href="https://chengpengzhao.com/2026-04-02-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-1/">上篇</a>覆盖范围：ESXi、域控、vCenter的安装与基础配置</p></li><li><p>下篇覆盖范围：Horizon的安装与配置</p></li><li><p>整体目标</p><ul><li>搭建一套可供团队使用的 VMware 虚拟化桌面环境</li><li>实现统一认证、集中管理、远程接入与桌面池分发</li><li>支持后续模板化批量交付和权限管理，以及安全控制（禁止文件拷出）</li></ul></li></ul><h1 id="Horizon-8-2312-安装与基础配置">2&emsp;Horizon 8 (2312) 安装与基础配置</h1><h2 id="Horizon-Client-Connection-Server-配置">2.1&emsp;Horizon Client(Connection Server)配置</h2><ul><li>虚拟机规格： 我给了 4CPU、10G内存、90存储</li><li>系统安装： windows server 2016安装</li><li>固定 IP 配置： 管理机，设置固定IP</li></ul><ul><li>步骤：</li></ul><ol><li>安装虚拟机，加入域中，比如我设定机器名为<code>horizon.simforge.work</code>（后续也通过这个域名访问）  </li><li>传入软件包<code>VMware-Horizon-Connection-Server-x86_64-xxx.exe</code>，开始安装  </li><li>一路默认下一步就行，中途可能需要设一个密码  </li><li>安装好就可以用<code>https://&lt;ConnectionServerDomainName&gt;/admin</code>访问了  </li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403100820808.png" alt></p><p><strong>登录账号密码</strong>即域管理员的账号密码，之前在域控服务器里设置过</p><h2 id="事件数据库配置">2.2&emsp;事件数据库配置</h2><p>事件数据库用于记录Horizon事件，不配置也不影响正常使用，只是没有审计日志和错误信息。(但安装起来还挺麻烦的，主要是安装包的获取)<br>我把数据库配置在了域控机器上。</p><ol><li>SQL Server安装，我选择的是：<code>cn_sql_server_2016_enterprise_x64_dvd_8699450</code>  </li><li>SQL Server Management Studio安装，下载<code>SSMS-Setup-CHS.exe</code>安装包  </li><li>新建一个数据库，如<code>horizon_log</code>  (可以专门建一个数据库用户，记得开启SQL Server验证方式)<br><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403101907323.png" alt></li><li>在Horizon里链接到数据库即可（使用刚创建的用户）<br><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403102025247.png" alt></li></ol><h1 id="桌面模板与桌面池配置">3&emsp;桌面模板与桌面池配置</h1><h2 id="制作桌面模板机">3.1&emsp;制作桌面模板机</h2><ol><li>vCenter中创建 Windows/Ubuntu 虚拟机（根据之前下载的镜像）  </li><li>将虚拟机加入域  </li><li>安装 VMware Tools: Windows直接通过vCenter安装，Ubuntu安装<code>open-vm-tools</code>  </li><li>安装 Horizon Agent： <code>VMware-Horizon-Agent-x86_64-2312-xxxx.exe</code>，还有一个<code>VMware-Horizon-Agent-Direct-Connection-x86_64-2312-xxx.exe</code>不知道具体有啥用，想装就装吧（一路默认安装即可）  </li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403103837475.png" alt></p><ol start="5"><li>系统优化与基础配置：<ul><li>网络配置（通过交换机设置好DHCP服务器，这里不用手动配置，自动获得ip即可，记得DNS要指向域控服务器）</li><li>安装必要的软件、卸载无用的组件</li></ul></li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403104007946.png" alt></p><h2 id="创建桌面池">3.2&emsp;创建桌面池</h2><ul><li>测试阶段建议选择<strong>手动池</strong>  </li><li>当模板机配置好了建议选择<strong>自动桌面池中的完整虚拟机</strong>（即时克隆适合临时使用，不适合团队长期使用）  </li><li>桌面池授权： 我这里直接授权<code>simforge_user</code>用户组  </li><li>计算机分配： 待虚拟机创建好后手动进行用户分配  </li><li>使用VMware Horizon Client进行连接测试  </li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403105241782.png" alt></p><h1 id="Horizon-自定义-amp-amp-安全配置">4&emsp;Horizon 自定义&amp;&amp;安全配置</h1><blockquote><p>这部分配置图文资料比较少，有些官方文档也感觉和实际对不太上，我试了挺久才弄好的</p></blockquote><h2 id="导入配置模板">4.1&emsp;导入配置模板</h2><ol><li><p>参考<a href="https://docs.omnissa.com/zh-CN/bundle/Horizon-Remote-Desktop-FeaturesVmulti/page/AddaHorizon8ADMXTemplateFiletoaGPO.html" target="_blank" rel="noopener">官方说明</a>，将<code>VMware-Horizon-Extras-Bundle-2312-xx.zip</code>导入到域控服务器里（这个文件在Horizon安装包里应该可以找到）  </p></li><li><p>解压缩文件，并将 ADMX 文件复制到 Active Directory 服务器。<br>a. 将<code>.admx</code> 文件复制到 Active Directory 服务器上的<code>%systemroot%\PolicyDefinitions</code> 文件夹。<br>b. 将语言资源 (<code>.adml</code>) 文件夹复制到 Active Directory 服务器上的 <code>%systemroot%\PolicyDefinitions</code>中。<br>c. 在 Active Directory 服务器上，打开组策略管理编辑器并在该编辑器中输入模板文件在安装后所在的路径。 </p></li><li><p>最好新建一个组策略，不要在默认的策略上改，如图：  </p></li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403110321654.png" alt></p><ol start="4"><li>为远程桌面启用<a href="https://docs.omnissa.com/zh-CN/bundle/Horizon-Remote-Desktop-FeaturesV2312/page/EnablingLoopbackProcessingforRemoteDesktops.html" target="_blank" rel="noopener">环回处理</a>：<br> a. 在 Active Directory 服务器上，打开组策略管理控制台。<br> b. 展开您的域，右键单击为组策略设置创建的 GPO 并选择编辑。<br> c. 在组策略管理编辑器中，导航到计算机配置 &gt; 策略 &gt; 管理模板: 策略定义 &gt; 系统 &gt; 组策略。<br> d. 在右侧窗格中，双击配置用户组策略环回处理模式。<br> e. 选择已启用，然后从模式下拉菜单中选择一个环回处理模式。<br> f. 我选择的是<strong>合并模式</strong>：即应用的<strong>用户策略设置结合了计算机 GPO 与用户 GPO 中包含的设置。如果发生冲突，则优先选用计算机 GPO。</strong> </li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403111957843.png" alt></p><ol start="5"><li>导入完成后应该可以看到各种各样的配置选项了，分计算机设置和用户设置两部分，其中有些重复的（如剪贴板设置在两个里面都有），有些是独有的（如<strong>水印</strong>设置在用户设置里面有）</li></ol><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403112127214.png" alt></p><h2 id="Horizon其他配置-针对Windows客户机">4.2&emsp;Horizon其他配置(针对Windows客户机)</h2><p>根据需求在组策略里修改配置即可，注意最好计算机和用户策略都改了，免得有时候不生效。  </p><ul><li>关闭USB、扫描仪重定向（处于安全性需求）  </li><li>设置各种超时时间，免得动不动退出登录了（一部分配置是在Horizon Web端的全局配置里修改的）  </li><li>开启用户水印、定义水印样式   </li></ul><h3 id="剪贴板重定向、拖放文件">4.2.1&emsp;剪贴板重定向、拖放文件</h3><ul><li>允许双向剪贴板共享  </li><li>控制剪贴板大小上限（如20KB）  </li><li>设置文件拖放方向（仅从客户端到代理）  </li></ul><p>不过好像拖放文件只对windows系统生效，linux只能通过驱动器重定向拷贝文件进去  </p><h3 id="设置驱动器重定向只读">4.2.2&emsp;设置驱动器重定向只读</h3><p>这个设置找的我好苦啊，<a href="https://docs.omnissa.com/zh-CN/bundle/Horizon-Remote-Desktop-FeaturesV2312/page/EnableStorageDriveRedirection.html" target="_blank" rel="noopener">官方文档</a>说的根本就是错的（针对2312版本）。最后还是在一篇远古<a href="https://arunpc.com/2016/06/24/readonly-usb-and-client-drive-redirection-in-horizon-7/" target="_blank" rel="noopener">博文</a>中找到了对应的设置方法。  </p><p><strong>这个需要在虚拟机上修改注册表，因此最好在模板机就调好，并且控制好用户权限，避免用户可以修改该选项</strong></p><p>(默认没有permissions这个项，手动加上并设置为<code>r</code>，默认应该是<code>rw</code>)<br><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260403115656440.png" alt></p><h2 id="Horizon其他配置-针对Ubuntu客户机">4.3&emsp;Horizon其他配置(针对Ubuntu客户机)</h2><p>参考<a href="https://docs.omnissa.com/zh-CN/bundle/Desktops-and-Applications-in-HorizonV2312/page/EditConfigurationFilesonaLinuxDesktop.html" target="_blank" rel="noopener">官方文档</a>，linux上的配置和Windows有较大区别。  </p><h3 id="配置文件修改">4.3.1&emsp;配置文件修改</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">cp</span> /etc/vmware/config.template /etc/vmware/config<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><strong>这个需要在虚拟机上修改文件，因此最好在模板机就调好，并且控制好用户权限，避免用户可以修改该文件</strong></p><p>(这就是为什么我在上篇中配置sudoer权限时写了一大串)</p><pre><code>ubuntu2204% cat /etc/vmware/config         #Enable/Disable the build to lossless mode. Default is FALSE#RemoteDisplay.buildToPNG=TRUE#Enable/Disable the left-handed mouse support on Ubuntu/SUSE platform and#the Mate Desktop of Redhat platform. Default is False.#For the other Desktop of Redhat and CentOS platform, user can select#left-handed mouse at system UI.#mksVNCServer.useUInputButtonMapping=TRUE#Enable/Disable the audio out. Default is TRUE.#RemoteDisplay.allowAudio=FALSE#Set clipboard redirection. Default is 2. 0 means disable; 1 means both directions; 2 means from client to agent only, 3 means from agent to client only.Clipboard.Direction=1#Set clipboard maximum size which should be specified in KBytes. Default is 1024 KBytes.mksvchan.clipboardSize=10#Enable/Disable the smartcard redirection. Default is TRUE#VVC.ScRedir.Enable=FALSE#Set the max of the reader contexts for the smartcard redirection. Default is 16#VVC.ScRedir.MaxReaderContexts=32#Loglevel for the smartcard redirection. Log level include [ info | debug]. Default is info.#VVC.ScRedir.logLevel=debug#Set the max reader contexts supported by pcscd. Default is determined by pcscd.#pcscd.maxReaderContext=32#Set parsing the message body or not. Default is determined by pcscd.#This option only takes effect if pcscd.maxReaderContext is set.#pcscd.readBody=TRUE#Loglevel for pcscd. Log level include [ info | debug]. Default is info.#pcscd.logLevel=debug#Enable/Disable audio in feature. Default is TRUE#VVC.RTAV.Enable=FALSE#Loglevel for rtav process. Log level include [error | info | debug | trace]. Default is info.#RTAV.logLevel=debug# Maximum rate at which frames can be captured from Webcam per second, Minimum = 1 Maximum = 30. No limit is set by default.#VVC.RTAV.WebcamMaxFrameRate=15# Maximum width in pixels of an image frame when capturing from Webcam. Available range of values: 32 - 4096, no limit is set by default.#VVC.RTAV.WebcamMaxResWidth=1920# Maximum height in pixels of an image frame when capturing from Webcam. Available range of values: 32 - 2160, no limit is set by default.#VVC.RTAV.WebcamMaxResHeight=1080# Sets the default image resolution width, this is used if no resolution value is defined by the user.# Available range of values: 32 - 4096, no value is set by default.#VVC.RTAV.WebcamDefaultResWidth=320# Sets the default image resolution height, this is used if no resolution value is defined by the user.# Available range of values: 32 - 2160, no value is set by default.#VVC.RTAV.WebcamDefaultResHeight=240#Loglevel for vmware-CDRServer.log. log level include [ error | warn | info | debug | trace | verbose]. Default is info.#cdrserver.logLevel=debug#To prevent the client from sharing additional folders (that is, folders that are not specified with cdrserver.shareFolders). Default is FALSE.#cdrserver.forcedByAdmin=TRUE#To specify the folders client can share and the permission for each folder.#cdrserver.sharedFolders=c:\Users\folder1,R;c:\Users\folder2,R;/home/user,R#To prevent write access to all folders that are shared with the remote desktop, default value is RW means all shared folders are readable and writable.cdrserver.permissions=R#To enable the write cache from agent towards the client side. Default is TRUE.#cdrserver.cacheEnable=FALSE#Setup customized shared folder path.#cdrserver.customizedSharedFolderPath=/mnt/#Loglevel for vmware-vvcProxy-Node log file. log level include [ fatal | error | warn | info | debug | trace | all ]. Default is info.#vvc.logLevel=debug#Loglevel for vmware-vdpService-Server log file. log level include [ error | warn | info | debug | trace | verbose]. Default is info.#vdpservice.log.logLevel=debug#To enable/disable VVC heartbeats. The value can be 0|1, means disable|enable VVC heartbeats, Default is enabled.#vvc.VVCHeartbeats=0#Specifies the maximum bandwidth, in kilobits per second (kbps), for a VMware Blast session. The bandwidth includes all imaging, audio, virtual channel, USB, and VMware Blast control traffic. The default value is 1 Gbps.#RemoteDisplay.maxBandwidthKbps=1000000#Specifies the minimum bandwidth, in kilobits per second (kbps), that is reserved for a VMware Blast session. The default value is 256 kbps.#RemoteDisplay.minBandwidthKbps=256#Specifies the maximum rate of screen updates. Use this setting to manage the average bandwidth that users consume. Valid value should be between 3 and 60. The default value is 30 updates per second.RemoteDisplay.maxFPS=60#Enable/Disable the Blast protocol statistics in mks log, such bandwidth, FPS, RTT, ... Default is FALSERemoteDisplay.enableStats=TRUE#Enable/Disable H.264 Encoding. Default is TRUE#RemoteDisplay.allowH264=FALSE#Max H264 Quantization Parameter (MINIMUM H264 QUALITY for the SW H264 encoder). Default is 36. Accept values from 0 to 51, but the value should be set larger than the value of RemoteDisplay.qpminH264.#RemoteDisplay.qpmaxH264=36#Min H264 Quantization Parameter (MAXIMUM H264 QUALITY for the SW H264 encoder). Default is 10. Accept values from 0 to 51, but the value should be set less than the value of RemoteDisplay.qpmaxH264.#RemoteDisplay.qpminH264=10#Specifies the image quality for the JPEG/PNG encoded desktop display. The low-quality settings are for areas of the screen that change often, for example, when scrolling occurs.#The high-quality settings are for areas of the screen that are more static, resulting in a better image quality. You can specify the following settings:#Available range of values: 1 - 100, default: 25#RemoteDisplay.minQualityJPEG=25#Available range of values: 1 - 100, default: 35#RemoteDisplay.midQualityJPEG=35#Available range of values: 1 - 100, default: 90#RemoteDisplay.maxQualityJPEG=90#Enable/Disable mouse cursor warping support. This enables the remoted desktop/application to change the mouse position without the user moving the mouse. Default is FALSE.#RemoteDisplay.enableCursorWarping=TRUE#Enable/Disable UDP protocol support, Default is TRUE#RemoteDisplay.enableUDP=FALSE#Enable/Disable Network Continuity, Default is TRUE#RemoteDisplay.enableNetworkContinuity=FALSE#Enable/Disable Network Intelligence, Default is TRUE#RemoteDisplay.enableNetworkIntelligence=FALSE#Loglevel for vmware-UsbRedirPlugin. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#UsbRedirPlugin.log.logLevel=debug#Loglevel for vmware-UsbRedirServer. Log level include [ error | warn | info | debug | trace | verbose]. Default is info. If log level is trace, it will dump all the binary data. If the log level of vmware-UsbRedirServer is debug or trace, &quot;UsbRedirServer.log.throttleBytesPerSec&quot; should be set to &quot;-1&quot;.#UsbRedirServer.log.logLevel=debug#UsbRedirServer.log.throttleBytesPerSec=-1#Enable the log file for TrueSSO feature. Log level include [error | warn | info | debug | trace | verbose]. The log file is disabled by default.#VMWPkcs11Plugin.log.enable=true#VMWPkcs11Plugin.log.logLevel=debug#PLZ refer to https://www.vmware.com/content/dam/digitalmarketing/vmware/en/pdf/techpaper/vmware-horizon-view-usb-device-redirection-white-paper.pdf for USB Configuration. The format of USB Config such as:#viewusb.IncludeVidPid=m:vid-xxxx_pid-xxxx#viewusb.AllowKeyboardMouse=o:true#Loglevel for collabui. Log level include [ error | info | debug]. Default is info. If log level is debug, it will dump every entrance of collabui functions and the collaborator list&#39;s content.#collaboration.logLevel=debug#Specifies the maximum collaborators. Use this setting to manage how many users can be added to one session. Valid value should not be greater than 20. The default is 5.#collaboration.maxCollabors=20#Enable/Disable the invitation via email, Default is TRUE#collaboration.enableEmail=FALSE#Enable/Disable passing input control to other collaborators, Default is TRUE#collaboration.enableControlPassing=FALSE#Customized server URL to include in the invitation message for Session Collaboration feature.#collaboration.serverUrl=&quot;&quot;#Loglevel for BlastServer process. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#BlastServer.log.logLevel=debug#Loglevel for BlastProxy process. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#BlastProxy.log.logLevel=debug#BlastProxy.log.throttleBytesPerSec should be set to &quot;-1&quot; if the log level is set to debug or trace, Default value is 1000.#BlastProxy.log.throttleBytesPerSec=-1#HTTP server thread pool size, default is 10.#BlastProxy.NumHttpThreads=10#Enable/Disable udp forwarding, default is TRUE.#BlastProxy.UdpEnabled=FALSE#Enable/Disable dump udp statistics, default is FALSE.#BlastProxy.enableDumpUdpStatistics=TRUE#Loglevel for desktopDaemon process. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#DesktopDaemon.log.logLevel=debug#Loglevel for desktopWorker process. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#DesktopWorker.log.logLevel=debug#TTY number for Xorg of Linux Agent, it is used in physical machine only. This value should greater than 0. Default is 7.#DesktopWorker.ttyNum=7#Loglevel for desktopController process. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#DesktopController.log.logLevel=debug#Loglevel for rdeSvc process. Log level include [error | warn | info | debug]. Default is info.#rdeSvc.logLevel=debug#Loglevel for appScanner process. Log level include [error | warn | info | debug]. Default is info.#appScanner.logLevel=debug#Semicolon separated application executable path list that could be blocked from launching and creating unity window.#rdeSvc.blockedWindows=/usr/libexec/gnome-terminal-server;#Enable/Disable optimized seamless window resize, default is TRUE.#rdeSvc.enableOptimizedResize=FALSE#Enable/Disable display scaling. This option only works if DPI sync feature is enabled.#Display scaling resizes the screen to auto fit the font size when the DPI is a mismatch between client#and agent, the default value is FALSE.#rdeSvc.allowDisplayScaling=TRUE#Configure app window&#39;s executable path and the app&#39;s desktopfile name in#a xml file, the xml file should be configured like the example below.#&lt;WINDOWEXECPATTERNCONFIG&gt;#        &lt;WINDOWEXECPATTERN&gt;#                &lt;EXECPATTERN&gt;gnome-terminal-server&lt;/EXECPATTERN&gt;#                &lt;TARGETPATTERN&gt;org.gnome.Terminal&lt;/TARGETPATTERN&gt;#        &lt;/WINDOWEXECPATTERN&gt;#&lt;/WINDOWEXECPATTERNCONFIG&gt;#The EXECPATTERN should be configured with the basename of the commandline to#launch the app and TARGETPATTERN should be configurd with the app&#39;s .desktop#file name(remove the suffix &quot;.desktop&quot;)#The configured xml file&#39;s path should be set in the line below.##rdeSvc.execPatternsConfig=path_to_execpattersiconfig_file#Enable/Disable printer redirection feature. The default value is TRUE.printSvc.enable=FALSE#Customized printer drivers(PPD) on Agent if user don&#39;t need NPD or UPD. In this option, the name is the client side printer name, PPD#path is the absolute ppd file path on Agent. Each item in option must be followed by a semicolon, the entire option must be enclosed#in quotation marks.#printSvc.customizedPpd=&quot;PinterName1=PPDPath1;PrinterName2=PPDPath2;&quot;#Update the virtual printer&#39;s ppd file to use PDF as the print format. This option only works for Linux/Mac client. Default is TRUE.#printSvc.usePdfFilter=FALSE#Set print job owner name as local user name or not. TRUE for local user name, otherwise the session logon user name will be used. Default is FALSE.#printSvc.jobOwnerAsLocal=TRUE#Enable/Disable printer watermark feature. Default is FALSE. It needs qpdf to be installed. Please refer to the chapter &quot;Configure VMware Integrated Printing for Linux Desktops&quot; in user guide.#printSvc.watermarkEnabled=TRUE#Loglevel for printSvc process. Log level include [error | warn | info | debug]. Default is info.#printSvc.logLevel=&quot;debug&quot;#Customized papers config file used to filter the papers, papers not listed in the config file will be ignored. The paper information#in the config file must follow specific rules, otherwise printSvc will fail to parse it. Each line in the config file follows format#&quot;keyword, name, widthMm, heightMm, widthPts, heightPts&quot;. Keyword is a unique string that represents the paper, only allow ASCII#characters within the range of decimal 33 to decimal 126 inclusive, name is the paper display name on the print UI, widthMm and heightMm#are the 10 times paper size in mm, widthPts and heightPts are paper size in points. This is a global config that will affect all virtual#printers. Please note that this option is only valid for Windows client.#Below is the content of a sample paper list file:#Letter, Letter, 2159, 2794, 612, 792#A3, A3, 2970, 4200, 842, 1191#A4, A4, 2100, 2970, 595, 842#printSvc.paperListFile=path_to_paper_list_file#This config item provides the ability to set the default print options when applications don&#39;t provide them. All the options are space#separated, their default value and range are listed as below(case sensitive):#printSvc.defaultPrintOptions=&quot;ColorMode=Color[Mono] Duplex=None[DuplexTumble|DuplexNoTumble] PageSize=9 number-up=1 number-up-layout=None[lrbt|lrbt|rltb|rlbt|tblr|tbrl|btlr|btrl] OutputOrder=Normal[Reverse] page-set=all[even|odd] noCollate[Collate]&quot;#Printer Filter can be configured to filter the virtual printers not to be added. Printers can be filtered based on the printer name, driver name or driver vendor name. The filter supports logical combination of multiple query conditions using AND, OR, NOT and Bracket. Each query condition in the filter supports Wildcard (asterisk and question mark) and Regular Expression (JavaScript Dialect and substring matching). The value on the right side of = or != should be enclosed with single quotation.#printSvc.printerFilter=&quot;(DriverName=&#39;DrName1&#39; OR DriverName=&#39;DrName2&#39;) AND PrinterName!= &#39;PrNa.?e&#39;&quot;#Enable/Disable watermark feature. The default value is FALSE.#rdeSvc.enableWatermark=TRUE#Opacity: the transparency level of the text. The range is 0-255. The default value is 50.#rdeSvc.watermark.opacity=50#Text Rotation, a specific angle for the watermark text. The default value is 45.#rdeSvc.watermark.rotation=45#Image Layout: the watermark layout on the screen, which is divided into nine squares:#0: Tile, watermark is positioned in all 9 squares. This layout is always used for application sessions.#1: Center, watermark is positioned in the center square.#2: Multiple, watermark is positioned in the center and four corner squares. If the watermark size exceeds the box size, it is scaled to maintain the aspect ratio.#The default value is 0.#rdeSvc.watermark.fit=0#The space around the watermark for the Tile layout. If the watermark is scaled, the margin will also be scaled. The default value is 50.#rdeSvc.watermark.margin=50#The watermark font size. The default value is 10.#rdeSvc.watermark.fontSize=10#The watermark font type. The default value is serif.#rdeSvc.watermark.font=&quot;serif&quot;#Enable this setting to configure a watermark to appear on your virtual desktop. Enter information you want to display as the watermark in Text.#Options are:#$BROKER_USER_NAME#$BROKER_DOMAIN_NAME#$USER_NAME#$USER_DOMAIN#$MACHINE_NAME#$REMOTE_CLIENT_IP#$CLIENT_CONNECT_TIME#The character limit is 1024 characters and 4096 characters after expansion. The text will be truncated if it exceeds the maximum length.#rdeSvc.watermark.template=&quot;$USER_DOMAIN\$USER_NAME\n$MACHINE_NAME On $CLIENT_CONNECT_TIME\n$REMOTE_CLIENT_IP&quot;#The minimum number used for X display allocation. Default is 100 and must not be negative.#Be careful to set the value in [0,9] which is very likely used by Display Manager.#This item should be little than 59535 to avoid XDMCP port being illegal.#For VDI mode, the counts from Desktop.displayNumberMin to Desktop.displayNumberMax must not greater than 60.#For multi-session, the counts from Desktop.displayNumberMin to Desktop.displayNumberMax must be 60.#Desktop.displayNumberMin=100#The maximum number used for X display allocation. Default is 159 and must not be negative.#Be careful to set the value in [0,9] which is very likely used by Display Manager.#This item should be little than 59535 to avoid XDMCP port being illegal.#For VDI mode, the counts from Desktop.displayNumberMin to Desktop.displayNumberMax must not greater than 60.#For multi-session, the counts from Desktop.displayNumberMin to Desktop.displayNumberMax must be 60.#Desktop.displayNumberMax=159#Loglevel for greeter. Log level include [warn | error | info | debug]. Default is info.#Greeter.logLevel=debug#Loglevel for Session Recording library. Log level include [ error | warn | info | debug | trace | verbose]. Default is info.#VMBlastRec.log.logLevel=debug</code></pre><h3 id="设置驱动器重定向只读-1">4.3.2&emsp;设置驱动器重定向只读</h3><p>修改上述配置文件中的： </p><pre><code>#To prevent write access to all folders that are shared with the remote desktop, default value is RW means all shared folders are readable and writable.cdrserver.permissions=R</code></pre><p>即可</p><h1 id="总结">5&emsp;总结</h1><p>本文分上下两篇，完整记录了一套基于 ESXi、Windows 域控、vCenter 和 Horizon 8(2312) 的团队虚拟桌面环境搭建过程：    </p><ul><li>上篇主要解决底层基础设施问题，包括 ESXi 宿主机安装、管理网络配置、域控与 DNS 部署、客户端加入域，以及 vCenter 的安装和纳管配置；  </li><li>下篇则进一步完成 Horizon Connection Server、事件数据库、桌面模板机、桌面池以及组策略和安全选项的配置。  </li></ul><p>从实际使用角度看，这套方案已经能够满足团队统一认证、集中管理、远程接入和标准化桌面交付的基本需求。通过 vCenter 统一管理底层虚拟化资源，再配合 Horizon 对桌面模板、桌面池和用户权限进行组织，可以较好地支撑团队研发、测试和日常办公场景。<br>同时，文章里也补充了不少实际踩坑后的经验，比如 Windows 和 Ubuntu 加入域的方法差异、Linux 桌面模板的 Agent 配置方式、组策略环回处理、驱动器重定向只读、剪贴板与拖放控制、水印显示等内容。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-04-03-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-2/#disqus_thread</comments>
    </item>
    
    <item>
      <title>VMWare Horizon 8(2312) 团队配置与使用（上）</title>
      <link>https://chengpengzhao.com/2026-04-02-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-1/</link>
      <guid>https://chengpengzhao.com/2026-04-02-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-1/</guid>
      <pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;场景需
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><ul><li><p>场景需求：团队共享桌面、远程办公、研发测试、统一环境管理</p></li><li><p>上篇覆盖范围：ESXi、域控、vCenter的安装与基础配置</p></li><li><p>下篇覆盖范围：Horizon的安装与配置</p></li><li><p>整体目标</p><ul><li>搭建一套可供团队使用的 VMware 虚拟化桌面环境</li><li>实现统一认证、集中管理、远程接入与桌面池分发</li><li>支持后续模板化批量交付和权限管理，以及安全控制（禁止文件拷出）</li></ul></li></ul><h1 id="总体架构">2&emsp;总体架构</h1><table><thead><tr><th>机器名称</th><th>主机名</th><th align="right">IP</th><th>系统/组件</th><th>主要作用</th></tr></thead><tbody><tr><td>交换机</td><td>xxx</td><td align="right">172.20.13.254</td><td>xxx, DHCP</td><td>分配IP，与上层网络以及其他机器相连接</td></tr><tr><td>ESXi宿主机1</td><td>esxi01</td><td align="right">172.20.13.42</td><td>VMware ESXi</td><td>承载所有虚拟机，提供虚拟化计算、存储、网络资源</td></tr><tr><td>ESXi宿主机2</td><td>esxi02</td><td align="right">172.20.13.43</td><td>VMware ESXi</td><td>承载所有虚拟机，提供虚拟化计算、存储、网络资源</td></tr><tr><td>域控服务器</td><td>dc</td><td align="right">172.20.13.100</td><td>Windows Server + AD DS + DNS</td><td>提供域控、用户认证、DNS 解析、组策略管理</td></tr><tr><td>vCenter 服务器</td><td>vc</td><td align="right">172.20.13.101</td><td>vCenter Server Appliance</td><td>统一管理 ESXi、集群、数据存储、模板和虚拟机</td></tr><tr><td>Horizon 连接服务器</td><td>horizon</td><td align="right">172.20.13.102</td><td>Horizon Connection Server</td><td>提供 Horizon 管理入口、用户认证对接、桌面分配与连接</td></tr><tr><td>win11桌面模板机</td><td>win11-template</td><td align="right">172.20.13.xx</td><td>Windows 11 + Horizon Agent</td><td>制作标准桌面模板，供后续克隆生成团队桌面</td></tr><tr><td>ubuntu2204桌面模板机</td><td>win11-template</td><td align="right">172.20.13.xx</td><td>Windows 11 + Horizon Agent</td><td>制作标准桌面模板，供后续克隆生成团队桌面</td></tr><tr><td>团队桌面xx</td><td>userxx</td><td align="right">172.20.13.xx</td><td>Horizon Agent</td><td>分配给团队成员使用的虚拟桌面</td></tr></tbody></table><ul><li><strong>实际物理机器只有两台服务器，其他都是在ESXi里装的。</strong></li></ul><ul><li>部署顺序说明：<ol><li>ESXi安装配置  </li><li>域控服务器安装配置  </li><li>vCenter安装配置  </li><li>Horizon安装配置  </li></ol></li></ul><h1 id="安装前准备">3&emsp;安装前准备</h1><p>先把这些镜像、安装包下载好（自行搜索）</p><ul><li>ESXi 镜像： 7.0 Update3 （这个看服务器型号，可能得去服务器官方下载镜像）</li><li>Windows Server 镜像：Microsoft Windows Server 2016 (64-bit)  （选2016准没错）</li><li>vCenter Server Appliance 镜像： vSphere Client 版本 7.0.3.02400 （公司之前买的这个版本的key）</li><li>Horizon 安装包： VMware Horizon 8.12.0  版本2312 （公司之前买的这个版本的key）</li><li>Win11 镜像： Windows 11 IoT Enterprise LTSC 2024 简体中文  （避坑网上各种所谓的“纯净版”，这才是真正的纯净版）</li><li>Ubuntu 镜像： ubuntu-22.04-desktop-amd64  （注意和horizon的兼容性，比如Horizon2312最多只支持Ubuntu 22.04版本）</li></ul><p><strong>注意Horizon 8和Horizon 7的安装配置过程差距挺大的，似乎是删了一些组件</strong></p><h1 id="ESXi-安装与基础配置">4&emsp;ESXi 安装与基础配置</h1><h2 id="ESXi-安装过程">4.1&emsp;ESXi 安装过程</h2><p>此部分没什么好说的，正常装系统呗</p><ul><li>安装介质制作</li><li>引导安装</li><li>磁盘选择</li><li>初始密码设置</li></ul><h2 id="管理网络配置">4.2&emsp;管理网络配置</h2><p>主要是在交换机上配置，然后在ESXi里改就行</p><ul><li>配置管理 IP</li><li>子网掩码、网关、DNS（DNS服务器可能要手动进入shell通过命令配置、记得打开shell）</li><li>测试网络连通性</li></ul><p>值得注意的是几个概念： <strong>物理网卡、VMkernel网卡、端口组、虚拟交换机</strong>， 后面改vCenter网络的时候可能会派上用场。<strong>设置不当也会导致你的机器直接失联!!</strong></p><p><strong>目标</strong>是看懂这样的拓扑图（我这个是配置后的分布式虚拟交换机，可能和一开始的vSwitch0还不太一样）<br><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402175025594.png" alt></p><p>所以如果是远程，请务必配置好服务器的<strong>带外管理</strong>页面IP，方便远程重启、进入BIOS等操作。</p><h2 id="ESXi-基础优化">4.3&emsp;ESXi 基础优化</h2><ul><li><p>主机名修改</p></li><li><p>NTP 配置，时区与时间同步(我用的ntp.aliyun.com)</p></li><li><p>存储与数据存储检查（新建数据存储，ESXi好像识别不太出来SSD，奇怪）</p></li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402180149846.png" alt></p><ul><li><p>上传 ISO 与安装文件（镜像要传到数据存储浏览器里，或者直接shell scp过去）</p></li><li><p>按需修改一些高级设置（比如我修改了最大失败登录尝试，之前被锁定登录不上还以为是密码被改了）</p></li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402181509403.png" alt></p><h1 id="域控（AD-DNS）安装与配置">5&emsp;域控（AD/DNS）安装与配置</h1><p>域控机的作用非常重要，没有它后续无法开展，安装好ESXi之后就可以创建一个虚拟机作为域控（当然有稳定的真实物理机做域控更好）。</p><h2 id="创建域控虚拟机">5.1&emsp;创建域控虚拟机</h2><ul><li>虚拟机规格： 我给了 2CPU、4G内存、90存储，感觉够用</li><li>系统安装： windows server 2016安装</li><li>固定 IP 配置： 这些管理机就不要用自动IP了，固定设置一下吧</li></ul><h2 id="安装-AD-DS-与-DNS">5.2&emsp;安装 AD DS 与 DNS</h2><p>主要包括 AD DS 与 DNS 的安装、域控制器提升以及新域创建，这类基础操作网上教程很多，按流程执行一般问题不大。<br>真正需要重点关注的是后续基础配置是否到位，包括正向解析区是否正常、主机名解析是否正确、时间同步是否一致，以及用户和用户组是否提前规划清楚（一般区分普通用户和管理员就够用了）。  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402223357102.png" alt></p><p>我还花时间折腾了一会AD CS证书服务，发现难用的一匹，于是放弃。  </p><ul><li><strong>DNS服务器</strong>比较重要，之后的用户机器DNS都要设成这台域控的IP，这样就能自动解析这里设置的各种域名了。</li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402223056424.png" alt></p><ul><li>顺便说下Windows Server的共享文件夹功能可以使用一下，方便在不同计算机之间传文件。以我这个例子进行说明，该计算机名为dc，文件夹share：<strong>Windows</strong>访问只需通过<code>\\dc\share</code>地址即可，<strong>Linux</strong>则是通过<code>smb://ip.xxx</code>来实现。（前提是机器加入了该域）</li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402223819427.png" alt></p><h2 id="将计算机加入域">5.3&emsp;将计算机加入域</h2><p>域存在的价值是有其他计算机加入进来，因此得明白各种系统的计算机怎么加进创建好的域。加入之后就可以统一用域账号、而不需要再用本地账号进行登录和使用了。</p><h3 id="windows">5.3.1&emsp;windows</h3><p>系统属性里面点击更改计算机名就行，会提示你加入域、输入域成员账号和密码。（我这里用域控为例，改不了是因为有证书在）</p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402224112831.png" alt></p><h3 id="linux（Ubuntu为例）">5.3.2&emsp;linux（Ubuntu为例）</h3><p>主要使用<code>realm</code>工具</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> apt <span class="token function">install</span> -y realmd libnss-sss libpam-sss sssd sssd-tools adcli samba-common-bin oddjob oddjob-mkhomedir packagekit<span class="token function">sudo</span> hostnamectl set-hostname xxx.simforge.work<span class="token comment" spellcheck="true"># 测试</span>realm discover simforge.worksimforge.work<span class="token comment" spellcheck="true"># 返回类似：</span><span class="token comment" spellcheck="true">#  type: kerberos</span><span class="token comment" spellcheck="true">#  realm-name: SIMFORGE.WORK</span><span class="token comment" spellcheck="true">#  domain-name: simforge.work</span><span class="token comment" spellcheck="true">#  configured: kerberos-member</span><span class="token comment" spellcheck="true">#  server-software: active-directory</span><span class="token comment" spellcheck="true">#  client-software: sssd</span><span class="token comment" spellcheck="true">#  required-package: sssd-tools</span><span class="token comment" spellcheck="true">#  required-package: sssd</span><span class="token comment" spellcheck="true">#  required-package: libnss-sss</span><span class="token comment" spellcheck="true">#  required-package: libpam-sss</span><span class="token comment" spellcheck="true">#  required-package: adcli</span><span class="token comment" spellcheck="true">#  required-package: samba-common-bin</span><span class="token comment" spellcheck="true">#  login-formats: %U</span><span class="token comment" spellcheck="true">#  login-policy: allow-realm-logins</span><span class="token comment" spellcheck="true"># 使用管理员账户加入域</span><span class="token function">sudo</span> realm <span class="token function">join</span> --user<span class="token operator">=</span>administrator dc.simforge.work<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>加入域后修改下配置<code>/etc/sssd/sssd.conf</code>，避免需要输入用户名时要把域带上，简化使用：  </p><pre><code>use_fully_qualified_names = Falsefallback_homedir = /home/%u</code></pre><p>再配置下sudoer的权限就好了，<code>sudo EDITOR=vi visudo</code></p><pre><code># 用户无法切换成管理员，但有一些sudo权限Cmnd_Alias SERVICE_OPS = /usr/bin/systemctl status *, /usr/bin/systemctl restart *, /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl reload *Cmnd_Alias LOG_OPS = /usr/bin/journalctl *, /usr/bin/tail *, /bin/cat /var/log/*Cmnd_Alias PKG_SAFE = /usr/bin/apt *, /usr/bin/apt-get *, /usr/bin/apt-cache *Cmnd_Alias NET_OPS = /usr/sbin/ip *, /usr/bin/ss *, /usr/bin/netstat *Cmnd_Alias SAFE_READ = /bin/ls *, /usr/bin/du *, /bin/df *Cmnd_Alias DATA_RW = \    /bin/ls *, /bin/cat *, /usr/bin/tail *, /usr/bin/head *, \    /usr/bin/vim *, /usr/bin/vi *, \    /bin/cp *, /bin/mv *, /bin/rm *, \    /bin/mkdir *, /bin/rmdir *, \    /usr/bin/touch *, /usr/bin/truncate *, \    /bin/chmod *, /bin/chown *, /bin/chgrp *, \    /usr/bin/tee *, /usr/bin/find *, \    /usr/bin/du *, /bin/df *%simforge_user ALL=(root) NOPASSWD:SERVICE_OPS, LOG_OPS, PKG_SAFE, NET_OPS, SAFE_READ, DATA_RW# 管理员的sudo权限%simforge_admin    ALL=(ALL:ALL) NOPASSWD:ALL</code></pre><h1 id="vCenter-Server-安装与配置">6&emsp;vCenter Server 安装与配置</h1><h2 id="部署-vCenter-Server-Appliance">6.1&emsp;部署 vCenter Server Appliance</h2><ul><li>安装程序启动： 安装程序在能连上ESXi的机器上运行就行</li><li>目标 ESXi 选择：填空就行，size我选的Small（但空间需求还是挺大的）</li><li>配置 IP、FQDN、DNS： 注意FQDN填写的域名需要在域控服务器里设置好正向查找解析</li><li>stage1部署完成后的stage2: SSO configuration部分设置登录账号密码（名字改不改无所谓，反正好像除了登录也用不到），该阶段会卡挺长时间的</li></ul><p>其实安装过程没有什么好说的，大部分按照默认选项即可，必须填的填一下就行了。</p><p><strong>注意登录的账号和密码写法：是在SSO 部分设置的，类似<code>administrator@vsphere.local</code> 这种用户名</strong></p><h2 id="登录与配置">6.2&emsp;登录与配置</h2><ul><li>Datacenter 创建</li><li>Cluster 创建</li><li>添加 ESXi 主机</li><li>许可证与基本参数设置</li></ul><p>这部分配置好后大概这样：</p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402232026053.png" alt></p><p>我还折腾了一段时间网络的配置，最后弄成了这种自己看起来比较舒服的样子：  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260402232641548.png" alt></p><p>用vCenter迁移/备份虚拟机数据还是很方便的，可以开机状态无感知完成迁移。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-04-02-vmware-horizon-tuan-dui-pei-zhi-yu-shi-yong-1/#disqus_thread</comments>
    </item>
    
    <item>
      <title>凌晨三点半的灯光映照着破碎的大理石桌</title>
      <link>https://chengpengzhao.com/2026-02-18-ling-chen-san-dian-ban-de-deng-guang-ying-zhao-zhao-po-sui-de-da-li-shi-zhuo/</link>
      <guid>https://chengpengzhao.com/2026-02-18-ling-chen-san-dian-ban-de-deng-guang-ying-zhao-zhao-po-sui-de-da-li-shi-zhuo/</guid>
      <pubDate>Wed, 18 Feb 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;吵架的结束和开始&quot;&gt;1&amp;emsp;吵架的结束和开始&lt;/h1&gt;&lt;p&gt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="吵架的结束和开始">1&emsp;吵架的结束和开始</h1><p>今天是大年初二凌晨2点半，我从睡梦中醒来，原因是听到了来自客厅的争吵：导火索大致是我爸因为爷爷大晚上不睡觉上个厕所就穿好了衣服坐在沙发上不时还跺脚叹气等行为影响了他的睡眠这件事。但这并不是没有预兆：昨天也发生了相似的剧情，只不过受影响睡眠的是我妈。而我爷爷自己却没有这方面的任何自觉，从我的角度来看他的思维/行为能力由于长期不使用已经退化了，再加上耳朵不好、接受外界的信息严重不足，与人的<strong>沟通不畅</strong>，与外界的障碍越来越大。  </p><p>不出意外，我的妈妈这次也被吵醒了，于是她起床开始调解：“大晚上的睡觉嘛，不要吵睡觉好吗？” 原以为这次事件已经告一段落了，可一个小时后<strong>第二波争吵</strong>再次开始，从语调和情绪的波动上来看似乎更加严重，我妈妈再次起来劝阻，然而似乎效果甚微，于是我也起床开始劝阻了，拉住看上去马上要打起来的我爸和我爷爷，两人还在激动地争论着，话语像一串串火星溅出来。然后，在某个瞬间，伴随着一声闷响——那张<strong>大理石</strong>台面的桌子终究没撑住。碎裂的声音并不尖锐，却格外沉，像砸在人的胸口上。石面裂开，边角崩掉，细小的<strong>碎屑</strong>散了一地。  </p><p>妈妈转身去拿来了扫帚，把碎块一点点扫拢，扫帚划过地面的声音沙沙作响，像是把这一夜的狼藉和疲惫也一并扫进了簸箕里。</p><h1 id="亲情与困局的思考">2&emsp;亲情与困局的思考</h1><h2 id="靠钱就能解决的问题">2.1&emsp;靠钱就能解决的问题</h2><p>爷爷在爸爸这儿住了十多年。其实更早些时候，爷爷去其他子女家，往往也是“到哪儿，吵到哪儿”。家里人都明白：这不是一场偶然的争执，而是一种长期的相处模式——脾气硬碰硬，谁也不肯先软下来。  </p><p>近几年，爷爷年纪更大了，记性似乎越来越差，情绪也更难捉摸。最棘手的，是晚上不睡觉。你说他是故意折腾吧，可他有时又像自己也不知道自己在干什么；你说他是清醒的吧，可他说的话、做的事又常常前后不搭。<br>我不敢轻易给爷爷贴诊断标签，但我知道，有一种现象常见于失智相关问题：傍晚到夜间更容易烦躁、混乱、睡不着，甚至像“能量突然增加”。医学上常把它叫作“日落综合征/黄昏症候群”，它并不罕见，也往往把照护者拖进深夜的疲惫里。  </p><p>问题是：我们家没有足够的空间和人手去消化这种“长期夜战”。房子不大、隔音也一般，能腾挪的余地太少。说得更直白一点——归根到底，很多家庭矛盾表面上是脾气，底层是<strong>资源</strong>：空间不够、照护不够，归根是钱不够。钱能解决99％的问题这句话的含金量仍在上升中。</p><h2 id="我国家庭养老的现状">2.2&emsp;我国家庭养老的现状</h2><p>我以前以为养老是“孝顺”两个字就能讲通的事。现在越来越觉得，家庭养老更像一套系统工程：它需要空间、时间、体力、专业知识和持续稳定的情绪供给。  </p><p>在中国，养老的现实结构也确实决定了大多数老人最终还是由家庭承担主要照护。常被提到的“<strong>9073</strong>”格局——约九成居家、少部分社区、少数机构——就是这种现实的缩影。  </p><p>国家也在补位，比如长期护理保险制度的试点与推进，目的就是给失能失智照护提供一定的制度支持，减轻家庭的压力。可制度从“有”到“能用”，中间还隔着供给、评估、服务质量等很多现实细节。对于把<strong>秩序与安全</strong>置于优先位置的统治机器来说，很难指望它在福利与医疗上同步实现显著提升，普通家庭的等待期太过漫长。  </p><h2 id="暴力沟通终究不可取">2.3&emsp;暴力沟通终究不可取</h2><p>把吵架当成一种“沟通方式”，其实更接近<strong>暴力沟通</strong>：它不重在讨论问题，只争输赢；不表达清需要，只释放情绪。摔东西、砸桌子、用更大的声音压住对方——这些动作看似在“讲理”，本质是在用力量逼对方退让，把家一点点推向战场。  </p><p>在这种领域里，老人只会更不安、更混乱；照护者会更疲惫、更易怒；而其他家庭成员表面上成了“无辜的旁观者”，实际上没有谁能全身而退——每个人都在被噪音、恐惧和无力感慢慢磨损。争吵不会让问题变小，只会让彼此的心变硬，让原本还能修补的关系裂得更深。  </p><p>两个人吵架，全家遭殃。昨晚从凌晨两点拖到五点。天亮的时候，仿佛并没有迎来早晨，只是熬过了黑夜。</p><h2 id="资源被消耗殆尽之后">2.4&emsp;资源被消耗殆尽之后</h2><p>又想到“久病床前无孝子，久贫家中无贤妻”这句话，它未必是在骂谁薄情，而是在描述一种极限：当苦难被拉得足够长，人的耐心、善意和体面都会被一点点兑付出去——再好的人，也可能在日复一日的消耗里变形。睡眠与生理能量、情绪余量、注意力与判断力、机会成本这些都是被不断消耗的资源。  </p><p>如果能有更大的居住空间，夜里的脚步声不至于磨进每个人的耳朵；如果能获得更专业的照护支持，很多冲突也许根本不必在家里以“互相伤害”的方式爆发。那些看起来最现实的条件，往往也是最有效的止痛药。</p><p>可现实偏偏是——我们家像许多普通家庭一样，最缺的正是这些“最管用”的东西。于是所有问题都被挤压进同一个狭窄的夜里，挤压进同一个客厅里，最后变成一句句火气、一声声摔砸。  </p><h1 id="未来的去向在何处">3&emsp;未来的去向在何处</h1><p>我并不想给谁判对错，但是越来越清楚的一点是，不能再靠硬扛了，而是要做更现实的事情：</p><ol><li><p>先把“是不是失智/阿尔兹海默症、睡眠相关问题”这件事弄清楚。哪怕只是去做一次系统评估。因为“夜里不睡”可能不仅是生物钟，也可能与日落综合征、疼痛、感染、药物副作用等因素有关。  </p></li><li><p>避免“情绪对抗”，优化“流程分工”。特殊情况（如家中位置不够用）时如何处理？是否考虑了可能发生冲突的点？是否有更好的方案可以实行？</p></li><li><p>认真看养老院/照护机构——它可能是首选，而不是“最后的羞耻”。说实话，如果夜间问题持续、房子空间有限、家里人已经被拖到崩溃边缘，那么养老院或专业机构不一定是“抛弃”，更像是把专业的事交给专业的人。我们需要的不是“面子上的孝顺”，而是“可持续的生活”。</p></li></ol><hr><p>希望下一次在深夜醒来的时候，不再是争吵和碎裂的声音，而是我们终于做出了一个更稳、更长久的选择——让所有人都能体面地活下去，也能好好睡一觉。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-02-18-ling-chen-san-dian-ban-de-deng-guang-ying-zhao-zhao-po-sui-de-da-li-shi-zhuo/#disqus_thread</comments>
    </item>
    
    <item>
      <title>2025年总结——得过且过</title>
      <link>https://chengpengzhao.com/2026-01-03-2025-nian-zong-jie-de-guo-qie-guo/</link>
      <guid>https://chengpengzhao.com/2026-01-03-2025-nian-zong-jie-de-guo-qie-guo/</guid>
      <pubDate>Sat, 03 Jan 2026 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;2025年总结&quot;&gt;1&amp;emsp;2025年总结&lt;/h1&gt;&lt;p&gt;依照
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="2025年总结">1&emsp;2025年总结</h1><p>依照惯例，看看2025年自己的时间都花在哪了吧：  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260103195547156.jpg" alt></p><p>回顾一下我的时间分类：</p><ul><li>睡眠，毕竟人类的一生有$\frac{1}{3}$的时间都在睡觉  </li><li>消费时间，指我们每天的日常工作（或学业），为了获取报酬所花的时间  </li><li>投资时间，有助于我们提高自身能力的，比如读书运动学习新技能等  </li><li>浪费时间，洗漱、通勤、用餐等硬性时间  </li><li>消磨时间，放空、打游戏看剧等娱乐活动  </li></ul><p>总的来说：  </p><ul><li>2025 全年理论总时长 8760 小时（非闰年），所以未记录大约 5 小时 09 分，覆盖率约 99.94% —— 这个完成度很舒服  </li><li>2025 的节奏很稳定——大头几乎都能归到明确的行为标签里（睡、工、玩、吃、通勤），波动空间反而集中在“娱乐”和“用餐”这种可伸缩项上  </li><li>娱乐时间减少、工作时间略增多、睡眠时间保持稳定，和体感基本一致  </li></ul><h1 id="2025发生的几件事">2&emsp;2025发生的几件事</h1><h2 id="家庭">2.1&emsp;家庭</h2><ul><li><p>年初相了两次亲，然后遇到了现在的女友  </p></li><li><p>国庆后去女友家见了父母，这个元旦她也到我家来见了父母  </p></li><li><p>没有能当成魔法师(今年正式满30岁了)</p></li></ul><h2 id="生活">2.2&emsp;生活</h2><ul><li><p>学了一段时间钢琴，后面因为事情多搁置了（感觉动力不够强）  </p></li><li><p>国庆去厦门旅游了一轮（人好多、好热）  </p></li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260103200707684.png" alt></p><ul><li>元旦去深圳/香港玩了一波（深圳好大、香港好多人、金价好贵）  </li></ul><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20260103200742818.png" alt></p><h2 id="工作">2.3&emsp;工作</h2><ul><li><p>多了几个头衔，该干的活还得加油干，在AI浪潮的冲击下保持不断学习</p></li><li><p>公司整体情况仍然不明朗，大环境仍就这个样子，确实不太好混</p></li></ul><h2 id="收支">2.4&emsp;收支</h2><ul><li><p>去年买房掏空了几乎所有积蓄，经过一年积累攒了一丢丢回来，但仍然远远不够看  </p></li><li><p>整体支出较往年有较大增多，主要是有女友之后要经常出去吃喝玩乐，开销必然增大  </p></li></ul><h2 id="技能">2.5&emsp;技能</h2><ul><li><p>每天敲代码、打击键盘熟练度up  </p></li><li><p>开始用AI编程工具，基本每天问AI问题，已确诊AI依赖症  </p></li></ul><h2 id="投资">2.6&emsp;投资</h2><ul><li><p>去年刚说”放弃股市投资这条路”，今年就被打脸了，又下载回那几个证券app了  </p></li><li><p>今年整体没亏（牛市）、但也没挣多少钱（毕竟没啥本金）  </p></li><li><p>开通了几张香港的银行卡  </p></li><li><p>开通了港股美股的证券账号，增加一些投资途径  </p></li></ul><h1 id="2026的期望">3&emsp;2026的期望</h1><ol><li>增加学习的时间，找到最适合自己的投资策略  </li><li>继续牛马生活，希望公司能稳步发展下去  </li><li>加强锻炼，希望自己和家人能够身体健康  </li><li>密切关注世界局势，愿世界和平  </li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2026-01-03-2025-nian-zong-jie-de-guo-qie-guo/#disqus_thread</comments>
    </item>
    
    <item>
      <title>时隔5年我又回到了安卓的怀抱</title>
      <link>https://chengpengzhao.com/2025-12-4-shi-ge-5-nian-wo-you-hui-dao-liao-an-zhuo-de-huai-bao/</link>
      <guid>https://chengpengzhao.com/2025-12-4-shi-ge-5-nian-wo-you-hui-dao-liao-an-zhuo-de-huai-bao/</guid>
      <pubDate>Thu, 04 Dec 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;从诺基亚5230开始的手机折腾史&quot;&gt;1&amp;emsp;从诺基亚5230
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="从诺基亚5230开始的手机折腾史">1&emsp;从诺基亚5230开始的手机折腾史</h1><p>手机这东西，对我来说一直不只是通讯工具，而是某种“随身电脑”，承载着那段时间的生活方式。</p><h2 id="高中：诺基亚-5230——第一次拥有“自己的设备”">1.1&emsp;高中：诺基亚 5230——第一次拥有“自己的设备”</h2><p>真正意义上的第一台手机，是高中的诺基亚 5230。<br>那时候智能机刚刚普及，市面上都是那种九宫格键盘的手机，滑盖或者是26字母键盘已经算是比较潮流了。塞班系统还是主流系统之一，屏幕是电阻触控，操作有点费劲，但耐用得可以砸核桃。</p><p>5230 留给我最大的印象就是两个字：自由。</p><ul><li>可以自己折腾主题，改各种菜单图标；</li><li>用数据线往里塞乱七八糟的 mp3、小游戏、电子书；</li><li>宿舍里偷偷看小说、在被窝里用着2G网冲浪，那种“我与世界相连”的感觉非常强。</li></ul><p>现在回头看，5230 大概就是我对“可玩性”和“可配置性”有了要求的起点。</p><h2 id="大学：小米-4c、小米-Max-2、红米-Note-5——安卓时代的主力工具">1.2&emsp;大学：小米 4c、小米 Max 2、红米 Note 5——安卓时代的主力工具</h2><p>上大学之后，正式进入安卓时代，主角依次是：小米 4c → 小米 Max 2 → 红米 Note 5，期间似乎还换过华为的平板。（更换太频繁不太记得了）</p><p>这么算来小米 4c 是我第一台真正意义上的安卓主力机。 那会儿的 MIUI 还处在一个很好玩的阶段：</p><ul><li>酷安还很纯粹，里面全是大佬，交流各种工具氛围很不错；  </li><li>随随便便root，刷第三方系统；  </li><li>接触到了小飞机，受到谷歌全家桶的热烈欢迎；  </li><li>各种第三方App、黑科技，只有你不会的没有你想不到的。  </li></ul><p>后来的 小米 Max 2屏幕大、电池大，拿在手里就有种“带着一块小平板走”的感觉，记得当初经常拿它来打炉石。  </p><p>红米 Note 5 则是一个很标准的“水桶机”：性能够用、信号不错、拍照够看，没有明显短板。那几年基本就是安卓的一套完整生活体系：日常社交、支付、出行都在这台机器上完成；折腾自动化、备份、各种效率工具，也是在这几代安卓机上慢慢练出来的，什么冰箱、绿色守护、幸运破解器都是手到拈来。文件系统怎么管理、后台怎么放权、哪些 App 需要特殊权限，这些都已经变成肌肉记忆。</p><h2 id="2020：iPhone-11——第一次“大幅换路”">1.3&emsp;2020：iPhone 11——第一次“大幅换路”</h2><p>2020 年换上 iPhone 11，算是一次比较彻底的“换路”。</p><p>一方面，是19年买了iPad（目前仍在役），感觉一些应用很不错只在苹果生态里有（没错就是Things和GoodNotes等笔记软件），有点想体验一下 iOS 的那种「不用管系统，只管用」的状态；另一方面，也确实是被大家说的稳定、省心、生态联动给种草了：</p><p>iOS 的动画和手势配合很顺滑，打开 App、在应用间切换的感觉确实很细腻；通知、权限、后台这些东西，都被系统管理得非常保守——省心，但也代表着另一种“被管着”。</p><p>在 iPhone 11 的这几年里，我慢慢适应了 iOS 的世界，习惯了那种“一切自动同步好、但你别管细节”的哲学。</p><h2 id="2022：红米-Note-11-作为备用机——安卓从未真正离开">1.4&emsp;2022：红米 Note 11 作为备用机——安卓从未真正离开</h2><p>不过安卓并没有完全从我的生活里消失。 2022 年入手的红米 Note 11，从一开始定位就是一台备用机，主要理由有几点：  </p><ul><li>手机号太多，一个手机不够（目前4张，绑定了一堆乱七八糟的账号也不敢注销）；</li><li>苹果没有通话录音功能，还得是安卓；  </li><li>需要折腾自动化、远程管理、文件传输时，也经常会用到它（比如<a href="https://github.com/pppscn/SmsForwarder" target="_blank" rel="noopener">短信自动转发</a>）；</li></ul><p>可以说，从诺基亚 5230 到大学那几代小米，再到现在的备用机红米 Note 11，安卓这条线一直都在，只是这几年 iPhone 11 一直当着“名义上的主力机”。</p><h1 id="为什么从iPhone回到了安卓">2&emsp;为什么从iPhone回到了安卓</h1><p>回想一下，这次从 iPhone 11 换回安卓，其实并不是一瞬间头脑发热，而是几个因素一路叠加，最后“啪”的一声把我推回了 Android 阵营。</p><h2 id="拆换电池的“事故现场”，给了最后一击">2.1&emsp;拆换电池的“事故现场”，给了最后一击</h2><p>直接导火索是——我自己动手换电池翻车了。</p><p>iPhone 11 用到后期，电池健康一路往下掉，其实早就不太抗用了。本着“勤俭持家 + 动手能力还行”的原则，我没去官方，也没去路边小店，选择了最危险的一条路：自己拆机换电池。</p><p>结果就是：</p><ul><li>拆的时候各种查视频、看教程，自以为步骤都对；</li><li>真上手的时候，排线、卡扣、胶条，处处都是坑；</li><li>重新装好那一刻，心里已经有点发虚：防水肯定是彻底告别了，细节上总觉得哪儿不太对。</li></ul><p>虽然手机最后还能开机，但屏幕直接废了没反应，解锁不了也不能备份数据。这件事也算是给了我一个心理上的明示——差不多可以考虑换主力机了。</p><h2 id="用了五年的老机：耗电快、有点卡、空间也不够">2.2&emsp;用了五年的老机：耗电快、有点卡、空间也不够</h2><p>即便不算拆机阴影，一台 2020 年的 iPhone 11 用到今天，也确实到了力不从心的时候。电池就不用说了，换之前基本就是出门久一点必带充电宝；日常刷刷社交、看看视频都还行，但一旦后台多开几个 App，明显感觉“有点卡”。<br>最直观的痛点其实是——空间不够用。 照片、视频、聊天文件、各种应用缓存，一点点把存储吃光；清理过几轮之后发现：这台机器已经不太适合当主力机了。</p><h2 id="被国内应用的广告喂了太多“屎”">2.3&emsp;被国内应用的广告喂了太多“屎”</h2><p>这条其实是 iOS 和 Android 共同的现实，但我确实有点被国内 app 的广告环境磨到心态爆炸。无论你用的是 iPhone 还是安卓，只要日常生活离不开那几款高频国产 app：</p><ul><li>打开就是横幅广告、信息流推荐、全屏弹窗；</li><li>有的应用甚至会用各种“伪通知”“伪系统弹窗”把广告包装得像系统提示；  </li><li>关闭按钮还贼难找，且升级后稍微摇一摇就跳转了；</li></ul><blockquote><p>“我在用一台很干净的系统，打开的却是一堆在疯狂给我喂屎的 app。”</p></blockquote><p>既然我用苹果避免不了骚扰，难道我的大安卓还治不了你区区广告？<br>这时候，安卓那一套“你可以自己掌管一切”的思路，又开始变得有吸引力了。</p><h2 id="听说国内-Root-环境日益严峻——想在还能折腾的时候再折腾一次">2.4&emsp;听说国内 Root 环境日益严峻——想在还能折腾的时候再折腾一次</h2><p>最后一个原因有点“技术宅自留地”的味道：听说这几年国内 Root 环境越来越严峻。</p><ul><li>各家厂商对 Bootloader 解锁和 Root 的限制越来越严格（参考小米）；</li><li>有的机型根本不开放解锁，有的需要各种申请流程，甚至后续系统更新也会对 Root 用户不太友好；</li><li>支付、安全类 app 对 Root 环境的检测也越来越敏感（据说装了Xposed框架后容易打不开各银行app）。</li></ul><p>这些变化让我有一种“窗口期正在关闭”的危机感—— 如果再不趁现在换一台相对好折腾的安卓机，以后可能就真的只能当一个“纯用户”，而不是一个“会在底层翻箱倒柜的人”了。 我并不是非要天天刷机、魔改系统，但我希望手里至少有一台设备：</p><ul><li>可以自己决定要不要解锁、要不要开 Root；</li><li>可以玩玩自动化、文件系统、NFC、网络工具这些更接近“随身电脑”的东西；</li><li>而不是永远被锁在一个“你只能在我规划好的范围里折腾”的小盒子里。</li></ul><hr><p>综合这四点：拆机阴影 + 老机力不从心 + 国内 app 广告环境 + 想趁还能折腾时再折腾一次，最后就自然走到了一个结论：</p><blockquote><p>是时候再给安卓一次“主力机”的机会了。</p></blockquote><h1 id="为什么选择了一加而不是小米">3&emsp;为什么选择了一加而不是小米</h1><p>从一开始，我筛手机的思路就很明确，不是“谁拍照好、谁充电快”这种大众评测维度，而是更偏“工具控”的几条：</p><ul><li>能不能解Bootloader，过程麻不麻烦，毕竟我立刻就要用起来的；</li><li>解锁之后 Root 环境是否稳定，有没有成熟教程和社区；</li><li>日常体验要够顺滑，不卡壳、不拖泥带水；</li><li>厂商别一上来就把各种权限锁死，让我连发挥空间都没有。</li></ul><p>在这几条的交集中，一加自然就浮上来了。</p><h2 id="选机标准：先看-Root，再看配置">3.1&emsp;选机标准：先看 Root，再看配置</h2><p>大致排了一圈：</p><ul><li>有的品牌干脆不开放 Bootloader 解锁，直接淘汰；</li><li>有的要各种“申请开发者资格”“审核通过”，流程又长又不透明；</li><li>还有一些机型是理论上能解锁，但 Root 后各种安全 App 直接不给你活路。</li></ul><p>相比之下，一加这边的口碑就简单直接得多——“还算比较友好”：</p><ul><li>官方还在提供 Bootloader 解锁通道（虽然步骤也变得比早年复杂了一点，要申请深度测试）；</li><li>国内外论坛、Telegram、酷安上都有一堆详细教程和踩坑记录；</li><li>各种 Magisk 模块、定制 ROM、内核调教都有人在维护。</li></ul><h2 id="一加的“气质”：系统够干净，折腾空间又大">3.2&emsp;一加的“气质”：系统够干净，折腾空间又大</h2><p>硬件层面其实现在大家都卷得差不多了，真正让我更倾向一加的是两点：</p><ol><li><p>系统不算太花哨</p><ul><li>虽然现在的一加也用上了 ColorOS 系列，但整体还是维持了一种“偏干净”的调性；</li><li>预装软件不至于多到离谱，大部分能关的都能关，通知和权限的调教也比较直观；</li><li>UI 动画、操作逻辑很接近“轻度定制的原生安卓”，没有那种层层套娃的感觉。</li></ul></li><li><p>可折腾的空间够大</p><ul><li>GitHub / 各种论坛上，你能找到一堆专门针对一加的脚本和工具；</li><li>从Root、系统精简、自动化到高级电源管理，都有人趟过坑；</li><li>这意味着我可以省掉很多“自己摸黑试错”的时间，直接站在前人的踩坑记录上往前走。</li></ul></li></ol><p>换句话说，一加在“普通用户体验”和“极客折腾空间”之间踩得比较平衡： 你可以当一台正常手机用，也可以在某个周末，把它当开发板玩一玩。</p><h2 id="一加的-Root-环境：目前还能“愉快玩耍”">3.3&emsp;一加的 Root 环境：目前还能“愉快玩耍”</h2><ul><li><p>解锁流程：</p><ul><li>安装<strong>深度测试</strong>app，填写申请</li><li>一到两天申请通过（我是第一天拿到手机立刻申请，第二天早上6点看已经通过了）</li></ul></li><li><p>Root过程：</p><ul><li>我是无脑选择了<a href="https://optool.daxiaamu.com/optool/" target="_blank" rel="noopener">一加全能工具箱</a>进行root</li><li>注意读使用说明，以及提前下载好驱动和对应系统版本的ROM包就行</li></ul></li><li><p>Root 后的生态：</p><ul><li>银行、支付类 App 虽然越来越敏感，但目前还有一套可用的绕行方案（我刷的SukiSU Ultra）；</li><li>日常使用中，不会出现“Root 之后变成一台不能干正事的玩具机”的尴尬局面；  </li><li>通过GKD/李跳跳，可以解决95%以上的应用广告骚扰问题。  </li></ul></li></ul><p>这些综合起来，让我有一种很微妙的安全感： 我不是为了 Root 而 Root，而是知道在我需要的时候，这条路是通的。</p><h1 id="核心配置">4&emsp;核心配置</h1><p>这次从一加开箱到解锁、获取 Root，再到装好常用模块、把系统调成我顺手的样子，整个流程其实挺长的：</p><ul><li>包括解锁 Bootloader、刷入第三方 recovery；</li><li>用 SukiSU Ultra 获取 Root 权限；</li><li>做一些基础安全配置和备份；</li><li>再根据自己的需求选装若干模块和工具。</li></ul><blockquote><p>👉 详细教程参考大佬文章：<a href="https://gledos.science/oneplus-ace-5-pro-superuser.html" target="_blank" rel="noopener">一加 Ace 5 Pro 获取超级用户权限（Root）与基础配置</a></p></blockquote><p>如果你对具体命令、刷写流程、配置细节感兴趣，直接去看上面那篇教程会更高效。</p><h1 id="个人常用APP列表记录">5&emsp;个人常用APP列表记录</h1><h2 id="衣食住行">5.1&emsp;衣食住行</h2><table><thead><tr><th>应用</th><th>应用</th><th>应用</th><th>应用</th><th>应用</th></tr></thead><tbody><tr><td>Google 日历</td><td>Chrome</td><td>微信</td><td>支付宝</td><td>微博</td></tr><tr><td>PayPal</td><td>淘宝</td><td>京东</td><td>闲鱼</td><td>猫眼</td></tr><tr><td>叮咚买菜</td><td>山姆</td><td>美团</td><td>大众点评</td><td>小红书</td></tr><tr><td>去哪儿</td><td>携程</td><td>航旅纵横</td><td>春秋航空</td><td>百度地图</td></tr><tr><td>12306</td><td>滴滴</td><td>酷安</td><td>12123</td><td>中国移动</td></tr><tr><td>中国电信</td><td>中国银行</td><td>建设银行</td><td>江苏银行</td><td>工商银行</td></tr><tr><td>住这儿</td><td>贝壳找房</td><td>米家</td><td>小米音箱</td><td>网易云音乐</td></tr><tr><td>播客</td><td>bilibili</td><td>贴吧</td><td>豆瓣</td><td>灵犀</td></tr><tr><td>彩云天气</td><td>Zepp</td><td>国家医保</td><td>个人所得税</td><td>惠泽保险</td></tr></tbody></table><h2 id="工作相关">5.2&emsp;工作相关</h2><table><thead><tr><th>应用</th><th>应用</th><th>应用</th></tr></thead><tbody><tr><td>微软 Lens</td><td>WPS 国际版</td><td>HiPER 计算器</td></tr><tr><td>OpenVPN</td><td>万能遥控</td><td>Windows App</td></tr><tr><td>码上行地铁</td><td>百度网盘</td><td>背单词</td></tr><tr><td>aTimeLogger</td><td>钉钉</td><td></td></tr></tbody></table><h2 id="其他工具">5.3&emsp;其他工具</h2><table><thead><tr><th>应用</th><th>应用</th><th>应用</th><th>应用</th><th>应用</th></tr></thead><tbody><tr><td>微信输入法</td><td>Simeji</td><td>MX 播放器</td><td>KMPlayer Plus</td><td>博客播放器</td></tr><tr><td>Lightroom</td><td>Solid 文件管理</td><td>EX 文件管理</td><td>倒数日</td><td>AutoXjs</td></tr><tr><td>LocalSend</td><td>NFCTool Pro</td><td>MacroDroid</td><td>MacroDroid 辅助应用</td><td>GKD</td></tr><tr><td>Fing</td><td>爱玩机工具箱</td><td>冰箱</td><td>SukiSU Ultra</td><td>东方财富</td></tr><tr><td>涨乐财富通</td><td>集思录</td><td>雪球</td><td>数码罗盘</td><td>Clash</td></tr><tr><td>飞牛</td><td>Windows 远程连接</td><td>Immich</td><td>Emby</td><td>Telegram</td></tr><tr><td>Google 全家桶</td><td>Voice</td><td>数据备份</td><td>NFC 卡模拟</td><td>幸运破解器</td></tr><tr><td>Bitwarden</td><td>谷歌Authenticator</td><td>Tailscale</td><td></td><td></td></tr></tbody></table><h1 id="两套系统的优缺点总结">6&emsp;两套系统的优缺点总结</h1><table><thead><tr><th>维度</th><th>安卓（以一加 + Root 视角）</th><th>iOS（以 iPhone 11 视角）</th></tr></thead><tbody><tr><td>系统稳定性</td><td>大版本偶尔有小 bug，更新前需要“等别人踩坑”；配置到位后总体稳定</td><td>整体非常稳，几乎不用管系统；升级心智负担小</td></tr><tr><td>个性化 &amp; 外观</td><td>桌面、图标、字体、主题、息屏、手势全都能改，想多花多花</td><td>图标和布局自由度有限，主题系统偏保守</td></tr><tr><td>文件系统 &amp; 传输</td><td>真·文件系统，本地/NAS/U 盘随便挂；LocalSend 等非常好用</td><td>文件抽象层比较重，各应用隔离，用户一般看不到</td></tr><tr><td>自动化</td><td>MacroDroid/Tasker + Root 能做到“手机级小服务器”</td><td>快捷指令在系统框架内很好用，但触发条件和权限边界更严格</td></tr><tr><td>权限 &amp; 后台</td><td>可以精细控制自启动、电池优化、后台保活；也更容易自己搞乱</td><td>系统一刀切，后台和推送很克制；省心但可控性弱</td></tr><tr><td>Root / 高级玩法</td><td>还能比较顺利解锁 + Root，有成熟社区和模块生态</td><td>等于没有 Root 这条路；安全一致，但完全不能往底层折腾</td></tr><tr><td>隐私与安全策略</td><td>看厂商，默认比 iOS 放得更开；Root 后需要自己做好风险管理</td><td>系统默认更保守，权限管得严；对“小白用户”更友好</td></tr><tr><td>电池与续航</td><td>电池大 + 快充爽，续航基本靠堆料和调教</td><td>优化不错，但老机型掉电明显；电池不可自己瞎折腾（我就翻车过）</td></tr><tr><td>与其他设备联动</td><td>主要靠第三方（NAS、远程桌面、云同步等）自己搭</td><td>和 Mac/iPad/Apple Watch 生态联动顺滑，开箱即用</td></tr><tr><td>折腾成本 vs 收益</td><td>前期要花时间配好；一旦搞顺手，会非常贴合自己的使用习惯</td><td>几乎不用折腾；但很多“小强迫症需求”永远满足不了</td></tr><tr><td>广告环境体感</td><td>系统层面可用工具压制一大部分</td><td>系统本身干净，但 App喂shi能力极强，很难压制</td></tr></tbody></table>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-12-4-shi-ge-5-nian-wo-you-hui-dao-liao-an-zhuo-de-huai-bao/#disqus_thread</comments>
    </item>
    
    <item>
      <title>CUDA程序编译的二进制兼容性问题</title>
      <link>https://chengpengzhao.com/2025-11-27-cuda-cheng-xu-bian-yi-de-er-jin-zhi-jian-rong-xing-wen-ti/</link>
      <guid>https://chengpengzhao.com/2025-11-27-cuda-cheng-xu-bian-yi-de-er-jin-zhi-jian-rong-xing-wen-ti/</guid>
      <pubDate>Thu, 27 Nov 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;问题场景&quot;&gt;1&amp;emsp;问题场景&lt;/h1&gt;&lt;p&gt;在高性能计算和 
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="问题场景">1&emsp;问题场景</h1><p>在高性能计算和 GPU 加速应用中，程序的可移植性和兼容性是一个关键问题。对于使用 NVIDIA GPU 和 CUDA 技术的应用，开发者通常需要面对不同 GPU 架构（Compute Capability）带来的二进制兼容性挑战，很可能在Nvidia RTX 5090上编译的程序放到Nvidia V100上运行就会出问题。因此有必要了解CUDA 编译器的一些编译细节。</p><h1 id="技术方案">2&emsp;技术方案</h1><h2 id="CUDA-编译器-nvcc-生成的两种形式GPU代码：">2.1&emsp;CUDA 编译器(nvcc)生成的两种形式GPU代码：</h2><ol><li>cubin（二进制代码）：针对特定 GPU 架构的编译结果。</li><li>PTX（中间代码）：可移植、可 JIT（即时编译）生成针对目标 GPU 的二进制代码。</li></ol><p>二进制兼容性问题主要表现为：如果一个 CUDA 程序编译出的二进制文件仅包含针对特定 GPU 架构的 cubin，那么它可能无法在较新或不同架构的 GPU 上运行。反之，如果程序包含 PTX 代码，则可以在不同 GPU 上通过 JIT 编译生成可执行的二进制，从而实现更高的兼容性。</p><p>例如，一个针对 <code>sm_86</code>（Compute Capability 8.6）编译的 cubin 文件，只能保证在 8.x 系列的 GPU 上运行，而不能直接在 7.x 或 9.x GPU 上运行。若应用中包含 PTX targeting compute_70，则该 PTX 可以 JIT 编译在 compute capability 7.0 及以上的 GPU 上，包括 8.x、9.x、10.x 等新架构，从而提供向前兼容性。</p><h2 id="CUDA的host与device部分编译流程">2.2&emsp;CUDA的host与device部分编译流程</h2><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20251127153918478.png" alt></p><p>上图展示了 CUDA 编译流程：NVCC 先把<code>example.cu</code>拆成 host 与 device 两部分，device 代码由 GPU 编译链生成 PTX 中间码，再经 ptxas 汇编为 CUBIN 目标文件；host 代码则交给系统 C/C++ 编译器生成 CPU 二进制；最终 NVCC 把两者打包进同一可执行文件，实现一次源码、双码并行的异构编译。</p><h2 id="编译选项解析">2.3&emsp;编译选项解析</h2><p>使用 <code>nvcc</code> 的 <code>--generate-code</code> 选项可以灵活控制生成 PTX 和/或 cubin。例如：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 仅生成 PTX</span>nvcc simple_add.cu -o simple_add --generate-code <span class="token string">"arch=compute_50,code=[compute_50]"</span><span class="token comment" spellcheck="true"># 同时生成 PTX 和 cubin，推荐✅</span>nvcc simple_add.cu -o simple_add --generate-code <span class="token string">"arch=compute_50,code=[compute_50,sm_50]"</span><span class="token comment" spellcheck="true"># 仅生成 cubin</span>nvcc simple_add.cu -o simple_add --generate-code <span class="token string">"arch=compute_50,code=[sm_50]"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><blockquote><p>注意<code>arch=compute_xx</code>选项在哪种情况都是必需的，用于指定虚拟架构版本</p></blockquote><h1 id="实现路径">3&emsp;实现路径</h1><h2 id="分析目标-GPU-架构">3.1&emsp;分析目标 GPU 架构</h2><p>确定程序需要支持的 GPU 架构范围（主要 Compute Capability 版本）。对于企业级部署，可覆盖当前主流架构及可能升级的 GPU。  </p><ul><li>命令<code>nvidia-smi --query-gpu=name,compute_cap --format=csv</code>可直接得到目标GPU的架构号</li></ul><h2 id="选择适当的生成策略">3.2&emsp;选择适当的生成策略</h2><ol><li><p>明确代码生产环境<br> 对于稳定的生产环境，且目标 GPU 架构固定，可生成针对 GPU 的 cubin 以获得最高性能。<br> 对于多架构或未来可能升级的环境，建议生成 PTX 或同时生成 PTX 与 cubin，以保证向前兼容性。</p></li><li><p>利用 PTX 的 JIT 功能<br>将 PTX 代码存储在应用或库中，在程序运行时根据实际 GPU 进行 JIT 编译。这样可以实现跨架构运行，保证新 GPU 可以执行旧版本 PTX 编译的程序。</p></li><li><p>混合生成 cubin 和 PTX<br>在编译阶段同时生成目标 GPU 的 cubin 和 PTX。cubin 可在编译时支持当前 GPU 架构的高性能运行，而 PTX 提供向前兼容性，保证程序在未来 GPU 上也能运行。</p></li></ol><h2 id="调整编译选项">3.3&emsp;调整编译选项</h2><ul><li><p><code>nvcc -arch-ls -code-ls</code>列出当前cuda编译环境支持的所有架构代号</p></li><li><p>根据前述分析结果，设置 <code>--generate-code</code> 参数，合理组合 PTX 与 cubin。例如，生成 PTX 提供跨 GPU 兼容性，生成 cubin 保证特定架构的性能优化。</p></li><li><p>若是使用Cmake的项目，只需在<code>CmakeLists.txt</code>中设置<code>set(CMAKE_CUDA_ARCHITECTURES &quot;61;70&quot;  CACHE STRING &quot;Set CUDA compute capability&quot;)</code>即可生成类似 <code>&quot;--generate-code=arch=compute_61,code=[compute_61,sm_61]&quot; &quot;--generate-code=arch=compute_70,code=[compute_70,sm_70]&quot;</code>的编译选项代码，免去了手动添加选项的过程</p></li></ul><h2 id="验证与测试">3.4&emsp;验证与测试</h2><p>   在不同架构的 GPU 上运行程序，验证 PTX JIT 编译是否正常，并检查性能表现。确保程序在主要目标 GPU 上性能最优，同时在新架构 GPU 上可正常执行。</p><hr><p>通过以上方法，CUDA 程序不仅能够在现有 GPU 上高效运行，也能在未来 GPU 架构上保持兼容，实现二进制和 PTX 的灵活组合，提高软件的可移植性和长期可维护性。</p><hr>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-11-27-cuda-cheng-xu-bian-yi-de-er-jin-zhi-jian-rong-xing-wen-ti/#disqus_thread</comments>
    </item>
    
    <item>
      <title>frp+OpenVPN实现内网访问实践</title>
      <link>https://chengpengzhao.com/2025-08-21-frp-openvpn-shi-xian-nei-wang-fang-wen-shi-jian/</link>
      <guid>https://chengpengzhao.com/2025-08-21-frp-openvpn-shi-xian-nei-wang-fang-wen-shi-jian/</guid>
      <pubDate>Thu, 21 Aug 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;问题场景&quot;&gt;1&amp;emsp;问题场景&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;&lt;p
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="问题场景">1&emsp;问题场景</h1><ol><li><p>电脑A需要访问电脑B上的某个服务，但是电脑A、B在两个不同的网络中，且不具备公网IP、不具备对路由器的修改权限；  </p></li><li><p>用户C在家想要访问公司内网上的一些资源/机器，但又不想通过RustDesk等远程桌面的形式。  </p></li></ol><h1 id="技术方案">2&emsp;技术方案</h1><h2 id="frp内网穿透的使用">2.1&emsp;frp内网穿透的使用</h2><h3 id="工具下载">2.1.1&emsp;工具下载</h3><p>在github相关页面直接下载编译好的可执行文件：  <a href="https://github.com/fatedier/frp/releases" target="_blank" rel="noopener">https://github.com/fatedier/frp/releases</a></p><h3 id="服务端配置">2.1.2&emsp;服务端配置</h3><p>这里只讲新版配置文件(.toml)的写法，旧版(.ini)差不多，只是一些变量名的区别</p><pre class="line-numbers language-toml"><code class="language-toml">bindPort = 7000 #{必选} 客户端与该端口建立连接kcpBindPort = 7000   # kcp 绑定的是 UDP 端口，可以和 bindPort 一样log.to = "console" #{可选} 日志配置， 通过打印的方式输出日志vhostHTTPPort = 7070 #{可选} http代理需要，当访问该端口时跳到对应本地frpc代理vhostHTTPSPort = 7443 #{可选} https代理需要，当访问该端口时跳到对应本地frpc代理transport.tcpMux = true #tcp流多路复用（优化传输，客户端与服务端同时配置才有效）#身份验证auth.method = "token" #{可选}身份验证方式auth.token = "abcdefgGHSDSAFDXFW324324321313U90809" #token设置密码，用于通过身份验证创建连接#frp服务仪表板配置webServer.port = 8888 #{自行修改端口}webServer.addr = "0.0.0.0" #公网ip或者0.0.0.0或者域名webServer.user = "admin" #登录用户名{自行修改}webServer.password = "admin" #登录密码{自行修改}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="客户端配置">2.1.3&emsp;客户端配置</h3><pre class="line-numbers language-toml"><code class="language-toml">serverAddr = "1.1.1.1" #[必选]服务器公网ip地址/域名serverPort = 7000 # [必选] 要连接的 frps 端口auth.token = "abcdefgGHSDSAFDXFW324324321313U90809" #与服务端校验的令牌（需一致）transport.tcpMux = true #tcp流多路复用（优化传输，客户端与服务端同时配置才有效）transport.protocol = "kcp"  #相比于 TCP，在弱网环境下传输效率提升明显，但是会有一些额外的流量消耗user = xxx[[proxies]]name = "web" # 代理名称(随便填)type = "tcp" # 代理类型localIP = "127.0.0.1" # 代理地址, 要转发的那个地址localPort = 3000 #  代理端口, 要转发的本地的那个端口remotePort = 8081 # 远程端口(通过公网IP+对应端口访问localPort服务)transport.useCompression = true  # 对传输内容进行压缩，可以有效减小 frpc 与 frps 之间的网络流量，加快流量转发速度，但是会额外消耗一些 CPU 资源[[proxies]]name = "filelink"type = "tcp"localIp = "127.0.0.1"localPort = 4888remotePort = 9002transport.useCompression = true [[proxies]]name = "vpn"type = "udp"localIp = "127.0.0.1"localPort = 1194remotePort =9003transport.useCompression = true<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="服务端的端口配置">2.1.4&emsp;服务端的端口配置</h3><p>需要放行的端口有：  </p><ul><li><code>webServer.port TCP</code>： 管理面板网页访问  </li><li><code>bindPort TCP</code>： 核心端口之一  </li><li><code>kcpBindPort UDP</code>： 核心端口之一  </li><li><code>remotePort TCP/UDP</code>： 根据实际用到的放行即可  </li></ul><h3 id="客户端的端口配置">2.1.5&emsp;客户端的端口配置</h3><ul><li>防火墙放行所有<code>localPort TCP/UDP</code>端口  </li></ul><h1 id="实现路径">3&emsp;实现路径</h1><ul><li><p>对于<strong>问题场景1</strong>，实际上通过上述<code>frp</code>的简单配置就能够满足需求  </p></li><li><p>对于<strong>问题场景2</strong>，则需要以下步骤来实现：  </p><ol><li>在内网机器上部署一个VPN，如OpenVPN；  </li><li>测试确保能通过<code>内网IP+端口</code>的形式连接上VPN；  </li><li>使用<code>frp</code>内网穿透，将VPN的端口暴露到公网，测试确保能通过<code>公网IP+端口</code>的形式连接上VPN；  </li><li>通过内网机器、VPN服务端的一些设置，确保连接上VPN后能够访问内网其他资源。  </li></ol></li></ul><h2 id="OpenVPN的服务端配置">3.1&emsp;OpenVPN的服务端配置</h2><h3 id="Windows系统">3.1.1&emsp;Windows系统</h3><p>该部分主要参考<a href="https://www.moralok.com/2023/06/07/how-to-setup-OpenVPN-server-on-windows-10/" target="_blank" rel="noopener">这篇博文</a>，按照步骤来基本不会有问题。  </p><ol><li>从 <a href="https://openvpn.net/community-downloads/" target="_blank" rel="noopener">OpenVPN 社区</a> 下载 <code>Windows 64-bit MSI installer</code>；  </li><li>在选择安装类型时，选择 Customize 而不要选择 Install Now；  <ul><li>勾选 <code>OpenVPN -&gt; OpenVPN Service -&gt; Entire feature will be installed on local hard drive</code>；  </li><li>勾选 <code>OpenSSL Utilities -&gt; EasyRSA 3 Certificate Management Scripts -&gt; Entire feature will be installed on local hard drive</code>；  </li><li>总之能装的全装上。  </li></ul></li><li>安装完毕后，会弹出一条消息提示未找到可读的连接配置文件，暂时忽略。此时在<code>控制面板\网络和 Internet\网络连接</code>中可以看到创建了两个新的网络适配器 OpenVPN TAP-Windows6 和 OpenVPN Wintun；  </li><li>进入 OpenVPN 默认安装目录中的 easy-rsa 目录<code>C:\Program Files\OpenVPN\easy-rsa</code>；  </li><li>执行CMD命令进入 Easy-RSA 3 Shell：  </li></ol><pre><code>.\EasyRSA-Start.bat</code></pre><ol start="6"><li>初始化公钥基础设施目录 pki：   </li></ol><pre><code>./easyrsa init-pki</code></pre><ol start="7"><li>构建证书颁发机构（CA）密钥，CA 根证书文件将在后续用于对其他证书和密钥进行签名。该命令要求输入 Common Name，输入主机名即可。创建的 ca.crt 保存在目录<code>C：\Program Files\OpenVPN\easy-rsa\pki</code>中，ca.key 保存在目录<code>C：\Program Files\OpenVPN\easy-rsa\pki\private</code>中：  </li></ol><pre><code>./easyrsa build-ca nopass</code></pre><ol start="8"><li>构建服务器证书和密钥。创建的 server.crt 保存在目录 <code>C：\Program Files\OpenVPN\easy-rsa\pki\issued</code> 中，server.key 保存在目录 <code>C：\Program Files\OpenVPN\easy-rsa\pki\private</code> 中：  </li></ol><pre><code>./easyrsa build-server-full server nopass</code></pre><ol start="9"><li>构建客户端证书和密钥。创建的 client.crt 保存在目录 <code>C：\Program Files\OpenVPN\easy-rsa\pki\issued</code> 中，client.key 保存在目录 <code>C：\Program Files\OpenVPN\easy-rsa\pki\private</code> 中：  </li></ol><pre><code>./easyrsa build-client-full client nopass</code></pre><ol start="10"><li>生成 Diffie-Hellman 参数：  </li></ol><pre><code>./easyrsa gen-dh</code></pre><ol start="11"><li>从目录 <code>C：\Program Files\OpenVPN\sample-config</code> 复制服务端配置文件模板 <code>server.ovpn</code> 到目录 <code>C：\Program Files\OpenVPN\config</code> 中，修改以下配置：端口号按需修改，默认为 1194，需要保证 OpenVPN 的网络流量可以通过防火墙，设置 <code>Windows 10 Defender</code> 允许 OpenVPN 通过即可。<code>dh2048.pem</code> 修改为生成的文件名 <code>dh.pem</code>。取消注释 <code>duplicate-cn</code>，让多个客户端使用同一个客户端证书。注释掉 <code>tls-auth ta.key 0</code>：  </li></ol><pre><code>port 1194dh dh.pemduplicate-cn;tls-auth ta.key 0</code></pre><ol start="12"><li>复制 <code>ca.crt</code>，<code>dh.pem</code>，<code>server.crt</code> 和 <code>server.key</code> 到目录 <code>C：\Program Files\OpenVPN\config</code> 中；  </li><li>启动 OpenVPN，点击连接，系统提示分配 IP 为 10.8.0.1。按配置，每次 OpenVPN server 都将为自己分配 10.8.0.1。</li></ol><h3 id="Linux系统">3.1.2&emsp;Linux系统</h3><p>以Ubuntu为例，用安装脚本比较简单：  </p><ol><li><code>wget https://git.io/vpn -O openvpn-ubuntu-install.sh</code>  </li><li><code>sudo bash openvpn-ubuntu-install.sh</code>，逐步设定后自动完成安装  </li><li>根据输出信息能找到服务端配置文件在<code>/etc/openvpn/server/server.conf</code>，客户端配置文件直接输出在脚本运行目录下  </li></ol><h2 id="OpenVPN客户端配置">3.2&emsp;OpenVPN客户端配置</h2><ul><li>Linux系统用脚本安装的一般已经配置好了，只需要修改<code>remote your-server-ip 1194</code>这行，<strong>改为公网IP和对应端口</strong>；  </li><li>Windows版本比较复杂，需要替换几个密钥的文本到客户端配置文件里：  <ol><li>从目录 <code>C：\Program Files\OpenVPN\sample-config</code> 复制客户端配置文件模板 <code>client.ovpn</code>，修改配置；  </li><li>将 <code>remote your-server 1194</code> 中的地址和端口替换成你的 OpenVPN 服务端对外的地址和端口；  </li><li>将 <code>ca ca.crt</code>，<code>cert client.crt</code>，<code>key client.key</code>，<code>tls-auth ta.key 1</code> 注释掉，再将各自文件中的内容以类 XML 的形式粘贴到 <code>client.ovpn</code> 中；  </li><li>将修改好的客户端配置文件导入到客户端中。  </li></ol></li></ul><pre><code>remote your-server 1194;ca ca.crt;cert client.crt;key client.key;tls-auth ta.key 1&lt;ca&gt;-----BEGIN CERTIFICATE-----paste contents of ca.crt-----END CERTIFICATE-----&lt;/ca&gt;&lt;cert&gt;-----BEGIN CERTIFICATE-----paste contents of client.crt-----END CERTIFICATE-----&lt;/cert&gt;&lt;key&gt;-----BEGIN PRIVATE KEY-----paste contents of client.key-----END PRIVATE KEY-----&lt;/key&gt;</code></pre><h2 id="内网穿透配置">3.3&emsp;内网穿透配置</h2><p>具体<code>frp</code>配置请参照前文  </p><pre><code>[[proxies]]name = &quot;vpn&quot;type = &quot;udp&quot;localIp = &quot;127.0.0.1&quot;localPort = 1194remotePort= 9003transport.useCompression = true</code></pre><h2 id="实现访问内网资源的配置">3.4&emsp;实现访问内网资源的配置</h2><p>按照上述配置完成后，应该能用<code>OpenVPN Connect</code>连接上VPN，但一般还无法访问内网资源。  </p><h3 id="Windows系统-1">3.4.1&emsp;Windows系统</h3><ol><li>确认 OpenVPN 配置是否正确下发路由：  </li></ol><ul><li>在服务端配置文件<code>server.conf</code>里增加：  </li></ul><pre><code>push &quot;route 192.168.x.0 255.255.255.0&quot;</code></pre><p>内网真实网段可通过<code>cmd</code>的<code>ipconfig</code>或<code>route print</code>命令打印，一般可以从局域网 IP 和子网掩码推断出来。  </p><ol start="2"><li>开启 Windows 的 IP 转发，Windows 默认不转发 VPN 网段到内网，需要手动开启：</li></ol><ul><li>打开注册表：</li></ul><pre><code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters</code></pre><ul><li>找到或新建 DWORD 值改为：</li></ul><pre><code>IPEnableRouter = 1</code></pre><ul><li><code>Win + R</code> → 输入 <code>services.msc</code> → 回车，服务里重启 <strong>Routing and Remote Access</strong> 服务。</li></ul><ol start="3"><li>设置防火墙允许转发，Windows 防火墙可能会阻止 VPN 网段访问内网。</li></ol><ul><li>打开 PowerShell 运行：</li></ul><pre class="line-numbers language-powershell"><code class="language-powershell">netsh advfirewall firewall add rule name=<span class="token string">"Allow OpenVPN"</span> <span class="token function">dir</span>=in action=allow protocol=any localport=1194netsh advfirewall firewall add rule name=<span class="token string">"Allow VPN Traffic"</span> <span class="token function">dir</span>=in action=allow protocol=any<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="4"><li>处理回程路由问题（只能访问VPN这台机器，无法访问其他内网资源）：  </li></ol><ul><li>管理员打开<code>powershell</code>；  </li><li>启用 NAT（假设 VPN 网段是 10.8.0.0/24），这样，Windows 会自动对来自 <code>10.8.0.0/24</code> 的流量做 NAT，让它们看起来像是从 <code>192.168.1.100</code>（假设VPN服务端机器IP） 发出的。</li></ul><pre><code>New-NetNat -Name &quot;OpenVPN-NAT&quot; -InternalIPInterfaceAddressPrefix 10.8.0.0/24</code></pre><ul><li>查看 NAT 状态： <code>Get-NetNat</code>；  </li><li>如需清理NAT： <code>Remove-NetNat -Name &quot;OpenVPN-NAT&quot;</code>  </li></ul><h3 id="Linux系统-1">3.4.2&emsp;Linux系统</h3><ol><li>确认 OpenVPN 配置是否正确下发路由：  </li></ol><ul><li>在服务端配置文件<code>server.conf</code>里增加：  </li></ul><pre><code>push &quot;route 192.168.x.0 255.255.255.0&quot;</code></pre><p>(我测试出来ubuntu系统只做完1后面的步骤没弄就已经可以正常访问内网其他资源了)</p><ol start="2"><li>确认服务端开启 IP 转发：  </li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">vi</span> /etc/sysctl.conf<span class="token comment" spellcheck="true">#确保 net.ipv4.ip_forward = 1</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="3"><li>确认 NAT/防火墙规则：<br>首先确保服务器1194端口打开。如果 VPN 网段（例如 10.8.0.0/24）要访问内网（比如 192.168.1.0/24），VPN 服务端必须做路由转发或 NAT。最常见做法是在 VPN 服务器上加 iptables：  </li></ol><pre class="line-numbers language-bash"><code class="language-bash">iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.1.0/24 -j MASQUERADE<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-08-21-frp-openvpn-shi-xian-nei-wang-fang-wen-shi-jian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>程序访存性能瓶颈分析</title>
      <link>https://chengpengzhao.com/2025-08-14-cheng-xu-fang-cun-xing-neng-ping-jing-fen-xi/</link>
      <guid>https://chengpengzhao.com/2025-08-14-cheng-xu-fang-cun-xing-neng-ping-jing-fen-xi/</guid>
      <pubDate>Thu, 14 Aug 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;问题场景&quot;&gt;1&amp;emsp;问题场景&lt;/h1&gt;&lt;p&gt;在测试程序的并行
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="问题场景">1&emsp;问题场景</h1><p>在测试程序的并行效率时，发现Release版本的并行效率很低，而Debug版测出来则符合预期，怀疑程序受内存带宽限制而无法发挥应有的性能。但需要用实际数据来验证这个合理的猜想。  </p><blockquote><p>想象内存带宽就是一根水管，数据是水，CPU就是在等水来做事。Debug版水的流速很慢、Release较快，当多进程时Debug版的速度明显翻倍（离水流量上限较远）、而Release版达到水流量上限后，进程越多则每个人的流速越慢（并行计算时，多个进程/核同时访问内存，争抢相同的带宽，导致单个进程速度下降）。  </p></blockquote><h1 id="背景知识">2&emsp;背景知识</h1><ul><li><p>算术强度（Arithmetic Intensity, AI） = 浮点运算数(Floating Point Operations, <strong>FLOPs</strong>) / 内存访问字节数  </p><p>  举例，稀疏矩阵-向量乘（SpMV）是迭代法的核心操作，假设用CSR存储， 每个非零元需要：  </p><ol><li>读数值（8字节，double）  </li><li>读列索引（4或8字节）  </li><li>读对应的向量元素（8字节）  </li><li>计算只涉及一个乘法 + 一个加法（2 FLOPs）<br>结果：每20~24 字节数据，只有2FLOPs → AI ≈ 0.1 FLOPs/Byte  </li></ol></li><li><p>最大内存带宽（Max Memory Bandwidth) : CPU可以从内存读取数据或将数据存储到内存中的最大速率 (以GB/s为单位)<br>  如<code>Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz</code>的官方标注最大内存带宽为<code>76.8 GB/s</code></p></li><li><p><strong>FLOPS</strong>，即每秒浮点运算次数, 是每秒所执行的浮点运算次数（Floating-point operations per second, <strong>FLOPS</strong>）</p><ol><li><p>估算方式，FLOPS = <code>核数*单核主频*CPU单个周期浮点计算次数</code>，其中前两个参数CPU都会标，后面一个参数看<code>Instruction Set Extensions</code></p><table><thead><tr><th>名称</th><th>指令集</th><th>每时钟周期的64 bits运算次数</th></tr></thead><tbody><tr><td>Nehalem</td><td>SSE（128-bits）</td><td>2</td></tr><tr><td>Sandy Bridge</td><td>AVX（256-bits）</td><td>4</td></tr><tr><td>Haswell</td><td>AVX2（256-bits）</td><td>4</td></tr><tr><td>Pueley</td><td>AVX512（512-bits）</td><td>16（融合乘加FMA=2） 8（FMA=1）</td></tr></tbody></table></li><li><p>举例，<code>Intel® Xeon® Processor E5-2650 v4</code>,  <code>Processor Base Frequency</code> <code>2.20 GHz</code>，<code>Total Cores</code> <code>12</code>， <code>Instruction Set Extensions</code> <code>Intel® AVX2</code>， FLOPS= <code>2.2*12*8</code> = <code>211.2GFLOPS</code></p></li></ol></li><li><p>Roofline Model，计算量为A且访存量为B的模型在算力为C且带宽为D的计算平台所能达到的理论性能上限E是多少  </p><ul><li>计算瓶颈区域 Compute-Bound，算法强度很高时，受峰值FLOPS（横线）限制  </li><li>带宽瓶颈区域 Memory-Bound，带宽（斜率）决定FLOPS上限</li><li><code>FLOPS ≤ min(峰值FLOPS, 内存带宽×算法强度)</code> </li><li>算法强度很低时： <code>FLOPS≈实际内存带宽×算法强度</code></li></ul></li></ul><h1 id="验证测试">3&emsp;验证测试</h1><h2 id="内存带宽上限测试-cs-roofline-toolkit">3.1&emsp;内存带宽上限测试(cs-roofline-toolkit)</h2><ol><li><code>git clone https://bitbucket.org/berkeleylab/cs-roofline-toolkit.git</code>  </li><li>输入：  </li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> cs-roofline-toolkit/Empirical_Roofline_Tool-1.1.0<span class="token function">cp</span> Config/config.madonna.lbl.gov.01 Config/myPCTest<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="3"><li>编辑<code>Config/myPCTest</code>，主要是将编译器从intel改为gnu  </li></ol><pre class="line-numbers language-bash"><code class="language-bash">ERT_RESULTS Results.myPCtestERT_DRIVER  driver1ERT_KERNEL  kernel1ERT_MPI         TrueERT_MPI_CFLAGSERT_MPI_LDFLAGSERT_OPENMP         TrueERT_OPENMP_CFLAGS  -fopenmpERT_OPENMP_LDFLAGS -fopenmpERT_FLOPS   1,2,4,8,16ERT_ALIGN   32ERT_CC      mpic++ERT_CFLAGS  -O3 -march<span class="token operator">=</span>native -msse3ERT_LD      mpic++ERT_LDFLAGSERT_LDLIBSERT_PRECISION FP64ERT_RUN     <span class="token function">export</span> OMP_NUM_THREADS<span class="token operator">=</span>ERT_OPENMP_THREADS<span class="token punctuation">;</span> mpirun -np ERT_MPI_PROCSERT_CODEERT_PROCS_THREADS  1-8ERT_MPI_PROCS      1,2,4,8ERT_OPENMP_THREADS 1,2,4,8ERT_NUM_EXPERIMENTS 3ERT_MEMORY_MAX 1073741824ERT_WORKING_SET_MIN 1ERT_TRIALS_MIN 1ERT_GNUPLOT gnuplot<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="4"><li><p>绘图若使用较高版本gnuplot，需要修改<code>Plot</code>文件夹中所有文件的其中一行：  </p><pre class="line-numbers language-gnuplot"><code class="language-gnuplot"># 原命令set clabel '%8.3g'# 替换后：set cntrlabel format '%8.3g'<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>运行测试: <code>./ert Config/myPCtest</code></p></li><li><p>查看<code>Results.myPCtest/Run.001/roofline.ps</code> 文件</p></li></ol><h2 id="实际内存带宽测试-likwid">3.2&emsp;实际内存带宽测试(likwid)</h2><ol><li><p>源码安装<code>likwid</code></p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> clone https://github.com/RRZE-HPC/likwid.git<span class="token function">cd</span> likwid<span class="token function">vi</span> config.mk<span class="token function">make</span> -j8<span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>启动MSR： <code>sudo modprobe msr</code></p></li><li><p>运行程序：  </p><ul><li>串行： <code>likwid-perfctr  -g MEM_DP ./xxx |tee log.perf.np1</code></li><li>并行： <code>likwid-mpirun -np $1 -mpi openmpi  -g MEM_DP  ./xxx |tee log.perf.np$1</code></li></ul></li><li><p>结果示例：</p></li></ol><pre><code># Debug版本## 1进程+----------------------------------------+--------------+--------------+-----------------+--------------+|                 Metric                 |      Sum     |      Min     |       Max       |      Avg     |+----------------------------------------+--------------+--------------+-----------------+--------------+|        Runtime (RDTSC) [s] STAT        |    1479.7008 |      30.8271 |         30.8271 |      30.8271 ||        Runtime unhalted [s] STAT       |      31.1694 | 2.426207e-05 |         27.6407 |       0.6494 ||            Clock [MHz] STAT            |   72421.4641 |    1199.9661 |       2497.0138 |    1508.7805 ||                CPI STAT                |      66.3224 |       0.4918 |          5.3376 |       1.3817 ||             Energy [J] STAT            |    2597.8198 |            0 |       1348.1428 |      54.1212 ||             Power [W] STAT             |      84.2708 |            0 |         43.7325 |       1.7556 ||          Energy DRAM [J] STAT          |     183.7499 |            0 |        107.3479 |       3.8281 ||           Power DRAM [W] STAT          |       5.9607 |            0 |          3.4823 |       0.1242 ||              MFLOP/s STAT              |      95.8335 | 1.427318e-06 |         90.9389 |       1.9965 ||           AVX [MFLOP/s] STAT           |            0 |            0 |               0 |            0 ||          Packed [MUOPS/s] STAT         | 6.487808e-08 |            0 |    6.487808e-08 | 1.351627e-09 ||          Scalar [MUOPS/s] STAT         |      95.8335 | 1.427318e-06 |         90.9389 |       1.9965 ||  Memory read bandwidth [MBytes/s] STAT |     820.1712 |            0 |        820.1712 |      17.0869 ||  Memory read data volume [GBytes] STAT | 2.361183e+12 |            0 |   2361183000000 | 4.919131e+10 || Memory write bandwidth [MBytes/s] STAT |     231.5628 |            0 |        231.5628 |       4.8242 || Memory write data volume [GBytes] STAT | 2.361183e+12 |            0 |   2361183000000 | 4.919131e+10 ||    Memory bandwidth [MBytes/s] STAT    | 1.531890e+14 |            0 | 153189000000000 | 3.191438e+12 ||    Memory data volume [GBytes] STAT    | 4.722366e+12 |            0 |   4722366000000 | 9.838263e+10 || Operational intensity [FLOP/Byte] STAT |       0.0912 | 1.000000e-20 |          0.0865 |       0.0019 ||      Vectorization ratio [%] STAT      |       0.1795 |            0 |          0.1795 |       0.0037 |+----------------------------------------+--------------+--------------+-----------------+--------------+## 2进程+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|                 Metric                 |    Sum    |    Min    |    Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |   35.5453 |   17.7625 |   17.7828 |   17.7726 |   17.7625 |   17.7625 |   17.7828 ||        Runtime unhalted [s] STAT       |   37.1324 |   18.5648 |   18.5676 |   18.5662 |   18.5648 |   18.5648 |   18.5676 ||            Clock [MHz] STAT            | 4994.1269 | 2497.0395 | 2497.0874 | 2497.0634 | 2497.0395 | 2497.0395 | 2497.0874 ||                CPI STAT                |    0.9934 |    0.4885 |    0.5049 |    0.4967 |    0.4885 |    0.4885 |    0.5049 ||             Energy [J] STAT            |  922.7993 |         0 |  922.7993 |  461.3997 |         0 |         0 |  922.7993 ||             Power [W] STAT             |   51.9522 |         0 |   51.9522 |   25.9761 |         0 |         0 |   51.9522 ||          Energy DRAM [J] STAT          |   79.1592 |         0 |   79.1592 |   39.5796 |         0 |         0 |   79.1592 ||           Power DRAM [W] STAT          |    4.4565 |         0 |    4.4565 |    2.2283 |         0 |         0 |    4.4565 ||              MFLOP/s STAT              |  190.9296 |   94.4443 |   96.4853 |   95.4648 |   94.4443 |   94.4443 |   96.4853 ||           AVX [MFLOP/s] STAT           |         0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |         0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Scalar [MUOPS/s] STAT         |  190.9296 |   94.4443 |   96.4853 |   95.4648 |   94.4443 |   94.4443 |   96.4853 ||  Memory read bandwidth [MBytes/s] STAT | 1562.0553 |         0 | 1562.0553 |  781.0276 |         0 |         0 | 1562.0553 ||  Memory read data volume [GBytes] STAT |   27.7459 |         0 |   27.7459 |   13.8729 |         0 |         0 |   27.7459 || Memory write bandwidth [MBytes/s] STAT |  413.7612 |         0 |  413.7612 |  206.8806 |         0 |         0 |  413.7612 || Memory write data volume [GBytes] STAT |    7.3494 |         0 |    7.3494 |    3.6747 |         0 |         0 |    7.3494 ||    Memory bandwidth [MBytes/s] STAT    | 1975.8165 |         0 | 1975.8165 |  987.9082 |         0 |         0 | 1975.8165 ||    Memory data volume [GBytes] STAT    |   35.0954 |         0 |   35.0954 |   17.5477 |         0 |         0 |   35.0954 || Operational intensity [FLOP/Byte] STAT |    0.0488 |         0 |    0.0488 |    0.0244 |         0 |         0 |    0.0488 ||      Vectorization ratio [%] STAT      |         0 |         0 |         0 |         0 |         0 |         0 |         0 |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+## 4进程+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|                 Metric                 |    Sum    |    Min    |    Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |   36.0001 |    8.9877 |    9.0053 |    9.0000 |    8.9877 |    9.0029 |    9.0042 ||        Runtime unhalted [s] STAT       |   37.8236 |    9.4377 |    9.4879 |    9.4559 |    9.4377 |    9.4459 |    9.4521 ||            Clock [MHz] STAT            | 9988.1020 | 2497.0171 | 2497.0344 | 2497.0255 | 2497.0171 | 2497.0228 | 2497.0277 ||                CPI STAT                |    1.9578 |    0.4859 |    0.4919 |    0.4894 |    0.4859 |    0.4893 |    0.4907 ||             Energy [J] STAT            |  549.6915 |         0 |  549.6915 |  137.4229 |         0 |         0 |         0 ||             Power [W] STAT             |   61.1607 |         0 |   61.1607 |   15.2902 |         0 |         0 |         0 ||          Energy DRAM [J] STAT          |   46.4047 |         0 |   46.4047 |   11.6012 |         0 |         0 |         0 ||           Power DRAM [W] STAT          |    5.1632 |         0 |    5.1632 |    1.2908 |         0 |         0 |         0 ||              MFLOP/s STAT              |  375.9728 |   92.8303 |   96.2008 |   93.9932 |   92.8303 |   93.1243 |   93.8174 ||           AVX [MFLOP/s] STAT           |         0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |         0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Scalar [MUOPS/s] STAT         |  375.9728 |   92.8303 |   96.2008 |   93.9932 |   92.8303 |   93.1243 |   93.8174 ||  Memory read bandwidth [MBytes/s] STAT | 3151.1117 |         0 | 3151.1117 |  787.7779 |         0 |         0 |         0 ||  Memory read data volume [GBytes] STAT |   28.3211 |         0 |   28.3211 |    7.0803 |         0 |         0 |         0 || Memory write bandwidth [MBytes/s] STAT |  837.0949 |         0 |  837.0949 |  209.2737 |         0 |         0 |         0 || Memory write data volume [GBytes] STAT |    7.5235 |         0 |    7.5235 |    1.8809 |         0 |         0 |         0 ||    Memory bandwidth [MBytes/s] STAT    | 3988.2066 |         0 | 3988.2066 |  997.0516 |         0 |         0 |         0 ||    Memory data volume [GBytes] STAT    |   35.8447 |         0 |   35.8447 |    8.9612 |         0 |         0 |         0 || Operational intensity [FLOP/Byte] STAT |    0.0241 |         0 |    0.0241 |    0.0060 |         0 |         0 |         0 ||      Vectorization ratio [%] STAT      |         0 |         0 |         0 |         0 |         0 |         0 |         0 |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+## 8进程+----------------------------------------+------------+-----------+-----------+-----------+-----------+-----------+-----------+|                 Metric                 |     Sum    |    Min    |    Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+------------+-----------+-----------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |    37.2697 |    4.6400 |    4.6783 |    4.6587 |    4.6538 |    4.6568 |    4.6605 ||        Runtime unhalted [s] STAT       |    38.8445 |    4.8415 |    4.8793 |    4.8556 |    4.8419 |    4.8510 |    4.8547 ||            Clock [MHz] STAT            | 19975.2132 | 2496.5400 | 2497.0420 | 2496.9017 | 2496.8017 | 2496.9713 | 2496.9762 ||                CPI STAT                |     3.9348 |    0.4852 |    0.4938 |    0.4919 |    0.4900 |    0.4926 |    0.4937 ||             Energy [J] STAT            |   337.8464 |         0 |  337.8464 |   42.2308 |         0 |         0 |         0 ||             Power [W] STAT             |    72.8114 |         0 |   72.8114 |    9.1014 |         0 |         0 |         0 ||          Energy DRAM [J] STAT          |    29.4452 |         0 |   29.4452 |    3.6806 |         0 |         0 |         0 ||           Power DRAM [W] STAT          |     6.3459 |         0 |    6.3459 |    0.7932 |         0 |         0 |         0 ||              MFLOP/s STAT              |   722.5548 |   88.2318 |   93.2152 |   90.3194 |   89.0568 |   89.3543 |   91.0526 ||           AVX [MFLOP/s] STAT           |          0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |          0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Scalar [MUOPS/s] STAT         |   722.5548 |   88.2318 |   93.2152 |   90.3194 |   89.0568 |   89.3543 |   91.0526 ||  Memory read bandwidth [MBytes/s] STAT |  6235.6248 |         0 | 6235.6248 |  779.4531 |         0 |         0 |         0 ||  Memory read data volume [GBytes] STAT |    28.9334 |         0 |   28.9334 |    3.6167 |         0 |         0 |         0 || Memory write bandwidth [MBytes/s] STAT |  1648.2151 |         0 | 1648.2151 |  206.0269 |         0 |         0 |         0 || Memory write data volume [GBytes] STAT |     7.6478 |         0 |    7.6478 |    0.9560 |         0 |         0 |         0 ||    Memory bandwidth [MBytes/s] STAT    |  7883.8399 |         0 | 7883.8399 |  985.4800 |         0 |         0 |         0 ||    Memory data volume [GBytes] STAT    |    36.5812 |         0 |   36.5812 |    4.5727 |         0 |         0 |         0 || Operational intensity [FLOP/Byte] STAT |     0.0118 |         0 |    0.0118 |    0.0015 |         0 |         0 |         0 ||      Vectorization ratio [%] STAT      |          0 |         0 |         0 |         0 |         0 |         0 |         0 |+----------------------------------------+------------+-----------+-----------+-----------+-----------+-----------+-----------+# Release版本## 1进程+-----------------------------------+--------------+|               Metric              | simforge:0:0 |+-----------------------------------+--------------+|        Runtime (RDTSC) [s]        |       6.3306 ||        Runtime unhalted [s]       |       5.0403 ||            Clock [MHz]            |    2497.0459 ||                CPI                |       0.7337 ||             Energy [J]            |     314.7977 ||             Power [W]             |      49.7263 ||          Energy DRAM [J]          |      32.3864 ||           Power DRAM [W]          |       5.1158 ||              MFLOP/s              |     467.1491 ||           AVX [MFLOP/s]           |            0 ||          Packed [MUOPS/s]         |      64.0155 ||          Scalar [MUOPS/s]         |     339.1181 ||  Memory read bandwidth [MBytes/s] |    3835.0151 ||  Memory read data volume [GBytes] |      24.2780 || Memory write bandwidth [MBytes/s] |    1000.8994 || Memory write data volume [GBytes] |       6.3363 ||    Memory bandwidth [MBytes/s]    |    4835.9145 ||    Memory data volume [GBytes]    |      30.6143 || Operational intensity [FLOP/Byte] |       0.0966 ||      Vectorization ratio [%]      |      15.8795 |+-----------------------------------+--------------+## 2进程+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|                 Metric                 |    Sum    |    Min    |    Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |    7.3827 |    3.6819 |    3.7008 |    3.6913 |    3.6819 |    3.6819 |    3.7008 ||        Runtime unhalted [s] STAT       |    5.9300 |    2.9573 |    2.9727 |    2.9650 |    2.9573 |    2.9573 |    2.9727 ||            Clock [MHz] STAT            | 4993.3202 | 2496.5943 | 2496.7259 | 2496.6601 | 2496.5943 | 2496.5943 | 2496.7259 ||                CPI STAT                |    1.3248 |    0.6557 |    0.6691 |    0.6624 |    0.6557 |    0.6557 |    0.6691 ||             Energy [J] STAT            |  203.2261 |         0 |  203.2261 |  101.6131 |         0 |         0 |  203.2261 ||             Power [W] STAT             |   55.1963 |         0 |   55.1963 |   27.5982 |         0 |         0 |   55.1963 ||          Energy DRAM [J] STAT          |   23.0437 |         0 |   23.0437 |   11.5219 |         0 |         0 |   23.0437 ||           Power DRAM [W] STAT          |    6.2587 |         0 |    6.2587 |    3.1294 |         0 |         0 |    6.2587 ||              MFLOP/s STAT              |  919.2860 |  453.8133 |  465.4727 |  459.6430 |  453.8133 |  453.8133 |  465.4727 ||           AVX [MFLOP/s] STAT           |         0 |         0 |         0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |  120.4004 |   59.2092 |   61.1912 |   60.2002 |   59.2092 |   59.2092 |   61.1912 ||          Scalar [MUOPS/s] STAT         |  678.4853 |  335.3949 |  343.0904 |  339.2427 |  335.3949 |  335.3949 |  343.0904 ||  Memory read bandwidth [MBytes/s] STAT | 7451.4953 |         0 | 7451.4953 | 3725.7476 |         0 |         0 | 7451.4953 ||  Memory read data volume [GBytes] STAT |   27.4355 |         0 |   27.4355 |   13.7178 |         0 |         0 |   27.4355 || Memory write bandwidth [MBytes/s] STAT | 1951.3573 |         0 | 1951.3573 |  975.6786 |         0 |         0 | 1951.3573 || Memory write data volume [GBytes] STAT |    7.1847 |         0 |    7.1847 |    3.5924 |         0 |         0 |    7.1847 ||    Memory bandwidth [MBytes/s] STAT    | 9402.8526 |         0 | 9402.8526 | 4701.4263 |         0 |         0 | 9402.8526 ||    Memory data volume [GBytes] STAT    |   34.6202 |         0 |   34.6202 |   17.3101 |         0 |         0 |   34.6202 || Operational intensity [FLOP/Byte] STAT |    0.0495 |         0 |    0.0495 |    0.0248 |         0 |         0 |    0.0495 ||      Vectorization ratio [%] STAT      |   30.1405 |   15.0047 |   15.1358 |   15.0702 |   15.0047 |   15.0047 |   15.1358 |+----------------------------------------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+## 4进程+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+|                 Metric                 |     Sum    |    Min    |     Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |     8.2769 |    2.0532 |     2.0822 |    2.0692 |    2.0532 |    2.0701 |    2.0714 ||        Runtime unhalted [s] STAT       |     6.8580 |    1.7066 |     1.7271 |    1.7145 |    1.7066 |    1.7098 |    1.7145 ||            Clock [MHz] STAT            |  9987.9943 | 2496.8601 |  2497.1454 | 2496.9986 | 2496.8601 | 2496.9319 | 2497.0569 ||                CPI STAT                |     2.9292 |    0.7068 |     0.7549 |    0.7323 |    0.7068 |    0.7220 |    0.7455 ||             Energy [J] STAT            |   126.1763 |         0 |   126.1763 |   31.5441 |         0 |         0 |         0 ||             Power [W] STAT             |    61.4538 |         0 |    61.4538 |   15.3635 |         0 |         0 |         0 ||          Energy DRAM [J] STAT          |    16.3530 |         0 |    16.3530 |    4.0883 |         0 |         0 |         0 ||           Power DRAM [W] STAT          |     7.9647 |         0 |     7.9647 |    1.9912 |         0 |         0 |         0 ||              MFLOP/s STAT              |  1635.4090 |  401.4841 |   421.1108 |  408.8523 |  401.4841 |  404.7493 |  408.0648 ||           AVX [MFLOP/s] STAT           |          0 |         0 |          0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |   214.6206 |   52.6419 |    55.4525 |   53.6552 |   52.6419 |   52.7975 |   53.7287 ||          Scalar [MUOPS/s] STAT         |  1206.1680 |  296.2004 |   310.2059 |  301.5420 |  296.2004 |  299.1543 |  300.6074 ||  Memory read bandwidth [MBytes/s] STAT | 13624.7225 |         0 | 13624.7225 | 3406.1806 |         0 |         0 |         0 ||  Memory read data volume [GBytes] STAT |    27.9741 |         0 |    27.9741 |    6.9935 |         0 |         0 |         0 || Memory write bandwidth [MBytes/s] STAT |  3568.9472 |         0 |  3568.9472 |  892.2368 |         0 |         0 |         0 || Memory write data volume [GBytes] STAT |     7.3277 |         0 |     7.3277 |    1.8319 |         0 |         0 |         0 ||    Memory bandwidth [MBytes/s] STAT    | 17193.6696 |         0 | 17193.6696 | 4298.4174 |         0 |         0 |         0 ||    Memory data volume [GBytes] STAT    |    35.3019 |         0 |    35.3019 |    8.8255 |         0 |         0 |         0 || Operational intensity [FLOP/Byte] STAT |     0.0245 |         0 |     0.0245 |    0.0061 |         0 |         0 |         0 ||      Vectorization ratio [%] STAT      |    60.4202 |   15.0014 |    15.1651 |   15.1050 |   15.0014 |   15.0905 |   15.1632 |+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+## 8进程+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+|                 Metric                 |     Sum    |    Min    |     Max    |    Avg    |  %ile 25  |  %ile 50  |  %ile 75  |+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+|        Runtime (RDTSC) [s] STAT        |    11.9013 |    1.4603 |     1.4996 |    1.4877 |    1.4830 |    1.4848 |    1.4990 ||        Runtime unhalted [s] STAT       |    10.1243 |    1.2500 |     1.3127 |    1.2655 |    1.2549 |    1.2599 |    1.2614 ||            Clock [MHz] STAT            | 19973.1141 | 2496.3416 |  2497.0836 | 2496.6393 | 2496.6011 | 2496.6143 | 2496.6251 ||                CPI STAT                |     8.7761 |    0.9795 |     1.1799 |    1.0970 |    0.9848 |    1.1228 |    1.1395 ||             Energy [J] STAT            |   105.2261 |         0 |   105.2261 |   13.1533 |         0 |         0 |         0 ||             Power [W] STAT             |    72.0554 |         0 |    72.0554 |    9.0069 |         0 |         0 |         0 ||          Energy DRAM [J] STAT          |    13.8533 |         0 |    13.8533 |    1.7317 |         0 |         0 |         0 ||           Power DRAM [W] STAT          |     9.4863 |         0 |     9.4863 |    1.1858 |         0 |         0 |         0 ||              MFLOP/s STAT              |  2263.1222 |  274.1682 |   296.1761 |  282.8903 |  277.2784 |  279.2491 |  285.9232 ||           AVX [MFLOP/s] STAT           |          0 |         0 |          0 |         0 |         0 |         0 |         0 ||          Packed [MUOPS/s] STAT         |   298.0918 |   36.0281 |    39.0467 |   37.2615 |   36.5567 |   36.7915 |   37.5327 ||          Scalar [MUOPS/s] STAT         |  1666.9384 |  202.1119 |   218.0828 |  208.3673 |  203.9546 |  205.6660 |  211.3595 ||  Memory read bandwidth [MBytes/s] STAT | 19786.0005 |         0 | 19786.0005 | 2473.2501 |         0 |         0 |         0 ||  Memory read data volume [GBytes] STAT |    28.8945 |         0 |    28.8945 |    3.6118 |         0 |         0 |         0 || Memory write bandwidth [MBytes/s] STAT |  5186.3296 |         0 |  5186.3296 |  648.2912 |         0 |         0 |         0 || Memory write data volume [GBytes] STAT |     7.5739 |         0 |     7.5739 |    0.9467 |         0 |         0 |         0 ||    Memory bandwidth [MBytes/s] STAT    | 24972.3301 |         0 | 24972.3301 | 3121.5413 |         0 |         0 |         0 ||    Memory data volume [GBytes] STAT    |    36.4683 |         0 |    36.4683 |    4.5585 |         0 |         0 |         0 || Operational intensity [FLOP/Byte] STAT |     0.0119 |         0 |     0.0119 |    0.0015 |         0 |         0 |         0 ||      Vectorization ratio [%] STAT      |   121.3594 |   14.9942 |    15.2373 |   15.1699 |   15.1290 |   15.1848 |   15.2175 |+----------------------------------------+------------+-----------+------------+-----------+-----------+-----------+-----------+</code></pre><ol start="5"><li>示例结果分析： Debug版这浮点计算量，8进程带宽都没吃满，并行效率正常。Release版本，4进程到8进程发现浮点计算效率明显降低，带宽提升不够，显然发生了竞争，总带宽已经接近该机器的上限了。 </li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-08-14-cheng-xu-fang-cun-xing-neng-ping-jing-fen-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Ubuntu上安装NVIDIA GPU开发环境</title>
      <link>https://chengpengzhao.com/2025-05-28-ubuntu-shang-an-zhuang-nvidia-gpu-kai-fa-huan-jing/</link>
      <guid>https://chengpengzhao.com/2025-05-28-ubuntu-shang-an-zhuang-nvidia-gpu-kai-fa-huan-jing/</guid>
      <pubDate>Wed, 28 May 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;问题场景&quot;&gt;1&amp;emsp;问题场景&lt;/h1&gt;&lt;p&gt;在 Linux 
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="问题场景">1&emsp;问题场景</h1><p>在 Linux 系统上进行深度学习相关项目开发时，需要安装 PyTorch(libTorch) 、 CUDA套件 来充分利用 NVIDIA GPU 的计算能力，加速模型训练和推理过程。然而，我在实际安装过程中遇到找不到显卡、系统依赖项不满足、CUDA 版本与显卡驱动不兼容、PyTorch运行失败等各种问题，因此需要一个详细的安装指南来确保顺利安装和配置。</p><h1 id="技术方案">2&emsp;技术方案</h1><h2 id="前置条件">2.1&emsp;前置条件</h2><ul><li>英伟达显卡  </li><li>尽可能高版本的python3及pip  </li><li>版本不是很低的gcc编译器（支持c++17往上）  </li><li>其他编译相关基础环境，如cmake等</li></ul><h2 id="版本兼容性问题">2.2&emsp;版本兼容性问题</h2><h3 id="显卡与驱动版本的兼容性问题">2.2.1&emsp;显卡与驱动版本的兼容性问题</h3><p>首先要注意驱动的安装版本，为了避免兼容性问题通常用以下几种方式：  </p><ol><li><p>文件安装，通过<a href="https://www.nvidia.com/en-us/drivers/results/" target="_blank" rel="noopener">英伟达驱动官网</a>，搜索对应显卡型号，找到对应的<code>xxx.run</code>驱动安装文件下载安装；  </p></li><li><p>系统安装，以<code>Ubuntu</code>系统为例，当系统检测到显卡时，通过下面的命令可以列出或安装驱动程序。  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> ubuntu-drivers list --gpgpu<span class="token function">sudo</span> ubuntu-drivers <span class="token function">install</span> --gpgpu<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ol><p>个人比较推荐通过文件安装的方式。  </p><h3 id="显卡架构与版本号">2.2.2&emsp;显卡架构与版本号</h3><p>NVIDIA的架构代号有很多，以sm_xx类型为例，各架构兼容性如下表：  </p><table><thead><tr><th>架构名称</th><th>版本号</th><th>特点</th></tr></thead><tbody><tr><td>费米 Fermi</td><td>sm_20</td><td>不支持CUDA 10及以后版本</td></tr><tr><td>开普勒 Kepler</td><td>sm_30、sm_35、sm_37</td><td>支持统一内存模型编程，支持动态并行化，增加了一些寄存器，不支持CUDA 11及以后版本</td></tr><tr><td>麦克斯韦 Maxwell</td><td>sm_50、sm_52、sm_53</td><td>不支持CUDA 11及以后版本</td></tr><tr><td>帕斯卡 Pascal</td><td>sm_60、sm_61、sm_62</td><td>支持CUDA 8及以后版本</td></tr><tr><td>伏特 Volta</td><td>sm_70、sm_72</td><td>支持CUDA 9及以后版本</td></tr><tr><td>图灵 Turing</td><td>sm_75</td><td>支持CUDA 10及以后版本</td></tr><tr><td>安培 Ampere</td><td>sm_80、sm_86</td><td>支持CUDA 11及以后版本，从8.0上编译出的二进制文件可以也在8.6上运行，但推荐在fp32类型上使用8.6的编译选项</td></tr><tr><td>哈珀 Hopper</td><td>sm_90</td><td>支持CUDA 12及以后版本（计划中）</td></tr></tbody></table><p>关于如何查找所用显卡对应的<code>sm_xx</code>代号，大概有以下两种方式：  </p><ol><li>通过网址查询：<a href="https://developer.nvidia.com/cuda-gpus" target="_blank" rel="noopener">https://developer.nvidia.com/cuda-gpus</a>  </li><li>安装cuda编译器后，通过<code>__nvcc_device_query</code>命令查询  </li></ol><h3 id="torch版本与显卡架构兼容性">2.2.3&emsp;torch版本与显卡架构兼容性</h3><p>选择安装pytorch/libtorch时也要注意与显卡架构兼容性的问题，可在<a href="https://github.com/moi90/pytorch_compute_capabilities" target="_blank" rel="noopener">pytorch_compute_capabilities</a>仓库中查询，摘录结果如下：  </p><table><thead><tr><th>package</th><th>architectures</th></tr></thead><tbody><tr><td>pytorch-2.5.1-py3.12_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.12_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.12_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.1-py3.11_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.11_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.11_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.1-py3.10_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.10_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.10_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.1-py3.9_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.9_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.1-py3.9_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.0-py3.12_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.12_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.12_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.0-py3.11_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.11_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.11_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.0-py3.10_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.10_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.10_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.5.0-py3.9_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.9_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90, sm_90a</td></tr><tr><td>pytorch-2.5.0-py3.9_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.12_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.12_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.12_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.11_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.11_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.11_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.10_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.10_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.10_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.9_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.9_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.1-py3.9_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.12_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.12_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.12_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.11_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.11_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.11_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.10_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.10_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.10_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.9_cuda12.4_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.9_cuda12.1_cudnn9.1.0_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.4.0-py3.9_cuda11.8_cudnn9.1.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.12_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.12_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.1-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.12_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.12_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.11_cuda11.8_cudnn8.7.0_0</td><td></td></tr><tr><td>pytorch-2.3.0-py3.10_cuda12.1_cudnn8.9.2_0</td><td></td></tr><tr><td>pytorch-2.3.0-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.3.0-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.12_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.12_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.2-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.12_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.12_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.1-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.12_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.12_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_70, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_70, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_70, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.2.0-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.2-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.1-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.11_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.10_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.9_cuda12.1_cudnn8.9.2_0</td><td>sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.1.0-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.1-py3.11_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.1-py3.11_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-2.0.1-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.1-py3.10_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-2.0.1-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.1-py3.9_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-2.0.0-py3.10_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.0-py3.10_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-2.0.0-py3.9_cuda11.8_cudnn8.7.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86, sm_90</td></tr><tr><td>pytorch-2.0.0-py3.9_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.1-py3.10_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.1-py3.10_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.1-py3.9_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.1-py3.9_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.0-py3.10_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.0-py3.10_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.0-py3.9_cuda11.7_cudnn8.5.0_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.13.0-py3.9_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.1-py3.10_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.1-py3.10_cuda11.3_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.1-py3.10_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.12.1-py3.9_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.1-py3.9_cuda11.3_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.1-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.12.0-py3.10_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.0-py3.10_cuda11.3_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.0-py3.10_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.12.0-py3.9_cuda11.6_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.0-py3.9_cuda11.3_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.12.0-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.11.0-py3.10_cuda11.5_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.10_cuda11.3_cudnn8.2.0_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.10_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.10_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.11.0-py3.9_cuda11.5_cudnn8.3.2_0</td><td>sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.9_cuda11.3_cudnn8.2.0_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.11.0-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.10.2-py3.9_cuda11.3_cudnn8.2.0_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.2-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.2-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.10.1-py3.9_cuda11.3_cudnn8.2.0_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.1-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.1-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.10.0-py3.9_cuda11.3_cudnn8.2.0_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.0-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.10.0-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.9.1-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.9.1-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.9.0-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.9.0-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.8.1-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.8.1-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.8.1-py3.9_cuda10.1_cudnn7.6.3_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.8.0-py3.9_cuda11.1_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80, sm_86</td></tr><tr><td>pytorch-1.8.0-py3.9_cuda10.2_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.8.0-py3.9_cuda10.1_cudnn7.6.3_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.7.1-py3.9_cuda11.0.221_cudnn8.0.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75, sm_80</td></tr><tr><td>pytorch-1.7.1-py3.9_cuda10.2.89_cudnn7.6.5_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.7.1-py3.9_cuda10.1.243_cudnn7.6.3_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70, sm_75</td></tr><tr><td>pytorch-1.7.1-py3.9_cuda9.2.148_cudnn7.6.3_0</td><td>sm_35, sm_37, sm_50, sm_60, sm_61, sm_70</td></tr></tbody></table><h1 id="实现路径">3&emsp;实现路径</h1><h2 id="显卡检查">3.1&emsp;显卡检查</h2><ol><li><p>显卡连接主板后，查询系统是否能找到显卡：  </p><pre class="line-numbers language-bash"><code class="language-bash">lspci <span class="token operator">|</span> <span class="token function">grep</span> -i nvidia<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li><p>显卡似乎未正常工作时（如<code>nvidia-smi</code>命令返回为空），可用以下命令查询出错信息：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">dmesg</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li></ol><p>如显卡供电线未工作时输出如下：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token punctuation">[</span>  301.584104<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: GPU does not have the necessary power cables connected.<span class="token punctuation">[</span>  301.584597<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: RmInitAdapter failed<span class="token operator">!</span> <span class="token punctuation">(</span>0x24:0x1c:1512<span class="token punctuation">)</span><span class="token punctuation">[</span>  301.584642<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: rm_init_adapter failed, device minor number 0<span class="token punctuation">[</span>  304.095280<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: GPU does not have the necessary power cables connected.<span class="token punctuation">[</span>  304.095722<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: RmInitAdapter failed<span class="token operator">!</span> <span class="token punctuation">(</span>0x24:0x1c:1512<span class="token punctuation">)</span><span class="token punctuation">[</span>  304.095765<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: rm_init_adapter failed, device minor number 0<span class="token punctuation">[</span>  342.790660<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: GPU does not have the necessary power cables connected.<span class="token punctuation">[</span>  342.791129<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: RmInitAdapter failed<span class="token operator">!</span> <span class="token punctuation">(</span>0x24:0x1c:1512<span class="token punctuation">)</span><span class="token punctuation">[</span>  342.791182<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: rm_init_adapter failed, device minor number 0<span class="token punctuation">[</span>  343.163675<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: GPU does not have the necessary power cables connected.<span class="token punctuation">[</span>  343.164110<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: RmInitAdapter failed<span class="token operator">!</span> <span class="token punctuation">(</span>0x24:0x1c:1512<span class="token punctuation">)</span><span class="token punctuation">[</span>  343.164151<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: rm_init_adapter failed, device minor number 0<span class="token punctuation">[</span>  349.650912<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: GPU does not have the necessary power cables connected.<span class="token punctuation">[</span>  349.651390<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: RmInitAdapter failed<span class="token operator">!</span> <span class="token punctuation">(</span>0x24:0x1c:1512<span class="token punctuation">)</span><span class="token punctuation">[</span>  349.651445<span class="token punctuation">]</span> NVRM: GPU 0000:02:00.0: rm_init_adapter failed, device minor number 0<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="显卡驱动安装">3.2&emsp;显卡驱动安装</h2><ol><li>下载正确的<code>.run</code>文件；  </li><li>运行该文件，按提示完成安装；  </li><li>运行<code>nvidia-smi</code>测试安装结果。  </li></ol><p>详见《显卡与驱动版本的兼容性问题》</p><h2 id="cuda套件安装">3.3&emsp;cuda套件安装</h2><p>安装 CUDA Toolkit ：</p><ol><li>安装<a href="https://developer.nvidia.com/cuda-downloads" target="_blank" rel="noopener">官网</a>的步骤进行下载安装；  </li><li>将<code>cuda</code>安装路径加入PATH：  <pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">export</span> PATH<span class="token operator">=</span>/usr/local/cuda/bin:<span class="token variable">$PATH</span>  <span class="token function">export</span> LD_LIBRARY_PATH<span class="token operator">=</span>/usr/local/cuda/lib:<span class="token variable">$LD_LIBRARY_PATH</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><code>nvcc -v</code>测试安装结果。  </li></ol><h2 id="pytorch安装">3.4&emsp;pytorch安装</h2><ol><li>确定与显卡架构兼容的pytorch版本（见技术方案部分），如我们的显卡<code>sm_61</code>支持的最新torch版本为<code>pytorch-2.5.1-py3.12_cuda12.4_cudnn9.1.0_0</code>；  </li><li>前往PyTorch官网<a href="https://pytorch.org/get-started/previous-versions" target="_blank" rel="noopener">https://pytorch.org/get-started/previous-versions</a>，找到对应版本的安装命令：  </li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># cpu version</span>pip <span class="token function">install</span> torch<span class="token operator">==</span>2.5.1 torchvision<span class="token operator">==</span>0.20.1 torchaudio<span class="token operator">==</span>2.5.1；  <span class="token comment" spellcheck="true"># gpu support</span>pip <span class="token function">install</span> torch<span class="token operator">==</span>2.5.1 torchvision<span class="token operator">==</span>0.20.1 torchaudio<span class="token operator">==</span>2.5.1 --index-url https://download.pytorch.org/whl/cu124<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><ol start="3"><li>通过pip安装。  </li></ol><p>需要注意的是，如果系统提示需要创建一个python虚拟环境（如Ubuntu24.04），则前置步骤如下：  </p><ol><li>选定合适的目录，运行<code>python3 -m venv torch_env</code>;  </li><li>将<code>source /path/to/torch_env/bin/activate</code>加入到<code>~/.bashrc</code>中；  </li><li><code>source ~/.bashrc</code>，自动导入虚拟环境，接下来所有python包都会安装在该<code>torch_env</code>目录中。  </li></ol><p>可通过以下小程序测试安装结果：  </p><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">import</span> torch<span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"PyTorch 版本:"</span><span class="token punctuation">,</span> torch<span class="token punctuation">.</span>__version__<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"CUDA 是否可用:"</span><span class="token punctuation">,</span> torch<span class="token punctuation">.</span>cuda<span class="token punctuation">.</span>is_available<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"CUDA 版本:"</span><span class="token punctuation">,</span> torch<span class="token punctuation">.</span>version<span class="token punctuation">.</span>cuda<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"GPU 数量:"</span><span class="token punctuation">,</span> torch<span class="token punctuation">.</span>cuda<span class="token punctuation">.</span>device_count<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"当前 GPU 名称:"</span><span class="token punctuation">,</span> torch<span class="token punctuation">.</span>cuda<span class="token punctuation">.</span>get_device_name<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>若<code>torch.cuda.is_available()</code>返回<code>True</code>，则说明 PyTorch 已成功配置 GPU 支持。</p><h2 id="pytorch扩展安装">3.5&emsp;pytorch扩展安装</h2><p>安装扩展时，要注意与torch版本的一致性，如torch2.5.1版本扩展安装命令如下：  </p><pre class="line-numbers language-bash"><code class="language-bash">pip <span class="token function">install</span> torch-cluster -f https://data.pyg.org/whl/torch-2.5.1+cu124.htmlpip <span class="token function">install</span> pyg-lib -f https://data.pyg.org/whl/torch-2.5.1+cu124.htmlpip <span class="token function">install</span> torch-sparse -f https://data.pyg.org/whl/torch-2.5.1+cu124.htmlpip <span class="token function">install</span> torch-cluster -f https://data.pyg.org/whl/torch-2.5.1+cu124.htmlpip <span class="token function">install</span> torch-spline-conv -f https://data.pyg.org/whl/torch-2.5.1+cu124.htmlpip <span class="token function">install</span> torchmetrics -f https://data.pyg.org/whl/torch-2.5.1+cu124.html<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="libtorch安装">3.6&emsp;libtorch安装</h2><p>如果要在C++环境中使用torch，则需下载libtorch库，<strong>注意torch版本和cuda版本</strong>的兼容性选择，如之前安装了pytorch2.5.1和cuda12.8，则下载命令如下：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">wget</span> https://download.pytorch.org/libtorch/cu128/libtorch-cxx11-abi-shared-with-deps-2.5.1%2Bcu128.zip<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>解压后设置环境变量即可使用：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">export</span> Torch_ROOT<span class="token operator">=</span>/path/to/libtorch<span class="token function">export</span> LD_LIBRARY_PATH<span class="token operator">=</span>/path/to/libtorch/lib:<span class="token variable">$LD_LIBRARY_PATH</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h2 id="libtorch扩展安装">3.7&emsp;libtorch扩展安装</h2><p>扩展组件一般都需要编译安装，过程如下（以torch-scatter为例）：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> clone https://github.com/rusty1s/pytorch_scatter.git<span class="token function">cd</span> pytorch_scatter<span class="token function">mkdir</span> build <span class="token operator">&amp;&amp;</span> <span class="token function">cd</span> buildcmake <span class="token punctuation">..</span>ccmake <span class="token punctuation">..</span> <span class="token comment" spellcheck="true">#修改安装路径等选项</span><span class="token function">make</span> -j8<span class="token function">make</span> <span class="token function">install</span><span class="token comment" spellcheck="true">#加入到环境变量~/.bashrc</span><span class="token function">export</span> TorchScatter_DIR<span class="token operator">=</span>/path/to/pytorch_scatter/install<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-05-28-ubuntu-shang-an-zhuang-nvidia-gpu-kai-fa-huan-jing/#disqus_thread</comments>
    </item>
    
    <item>
      <title>flex/bison使用</title>
      <link>https://chengpengzhao.com/2025-02-27-flex-bison-shi-yong/</link>
      <guid>https://chengpengzhao.com/2025-02-27-flex-bison-shi-yong/</guid>
      <pubDate>Thu, 27 Feb 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;基本介绍&quot;&gt;1&amp;emsp;基本介绍&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="基本介绍">1&emsp;基本介绍</h1><ul><li><p><strong>Flex</strong>（词法分析器）<br>像“文本拆分器”，负责将原始文本拆解成有意义的单词（称为 <strong>Token</strong>）。<br>例如：从代码 <code>price = 100+20</code> 中识别出 <code>price</code>、<code>=</code>、<code>100</code>、<code>+</code>、<code>20</code>。  </p></li><li><p><strong>Bison</strong>（语法分析器）<br>像“语法检查器”，负责验证这些单词是否符合预定规则，并构建结构。<br>例如：检查 <code>100+20</code> 是否符合数学表达式规则，并解释其计算逻辑。  </p></li></ul><p><strong>典型应用场景</strong></p><ul><li>写编程语言的编译器/解释器（比如实现一个简易的 Python 或 JSON 解析器）  </li><li>读取配置文件（比如解析 Nginx 的配置规则）  </li><li>开发专用小语言（比如一些脚本指令）  </li></ul><h1 id="安装配置">2&emsp;安装配置</h1><ul><li><p>Linux (Ubuntu)</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> flex bison<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li><p>macOS</p><pre class="line-numbers language-bash"><code class="language-bash">brew <span class="token function">install</span> flex bison<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li><p>Windows</p></li></ul><ol><li>使用Cygwin或WSL环境</li><li>或使用预编译包：<a href="https://winflexbison.sourceforge.net/" target="_blank" rel="noopener">https://winflexbison.sourceforge.net/</a></li></ol><p>验证安装：</p><pre class="line-numbers language-bash"><code class="language-bash">flex --versionbison --version<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h1 id="编写flex文件">3&emsp;编写flex文件</h1><blockquote><p>以下代码均用C++编写，第一种使用方式为flex/bsion在C语言中的使用风格（在这两节中介绍），第二种为在C++中面向对象的使用风格（在后文中介绍）。</p></blockquote><p>flex文件一般在C语言中后缀用<code>.l</code>，在C++中用<code>.ll</code>。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// 禁用旧式yyloop，其他option查手册</span><span class="token operator">%</span>option noyywrap yylineno<span class="token operator">%</span><span class="token punctuation">{</span><span class="token comment" spellcheck="true">// C头文件和声明（会直接复制到输出）</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"parser_tab.h"</span> </span><span class="token comment" spellcheck="true">// Bison生成的头文件，名称可自定义</span><span class="token comment" spellcheck="true">// 可定义函数/变量</span><span class="token keyword">void</span> yyerror（<span class="token keyword">char</span> <span class="token operator">*</span>s，<span class="token punctuation">.</span><span class="token punctuation">.</span>）｛     va_list ap；    va_start（ap<span class="token punctuation">,</span>s）；    fprintf（<span class="token constant">stderr</span>，<span class="token string">"Error： "</span>）；    vfprintf（<span class="token constant">stderr</span><span class="token punctuation">,</span>s<span class="token punctuation">,</span>ap）；    fprintf（<span class="token constant">stderr</span>，<span class="token string">"\n"</span>）；｝<span class="token keyword">int</span> brace_count <span class="token operator">=</span> <span class="token number">0</span>； <span class="token comment" spellcheck="true">// 记录大括号的嵌套层级</span><span class="token operator">%</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 状态声明，默认状态为INITIAL，用户可定义不同状态，以及特定状态下的规则</span><span class="token operator">%</span>× COMMENT<span class="token operator">%</span><span class="token operator">%</span><span class="token comment" spellcheck="true">/* 规则段，注意规则会从前往后查找 */</span><span class="token string">"VALUE"</span>                       <span class="token punctuation">{</span> <span class="token keyword">return</span> VALUE<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"ARRAY"</span>                       <span class="token punctuation">{</span> <span class="token keyword">return</span> ARRAY<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"SIZE"</span>                        <span class="token punctuation">{</span> <span class="token keyword">return</span> SIZE<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">">"</span>  <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token string">"&lt;"</span>  <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token string">">="</span> <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token string">"&lt;="</span> <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">4</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token string">"!="</span> <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token string">"=="</span> <span class="token punctuation">{</span> yylval<span class="token punctuation">.</span>comptok <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span> <span class="token keyword">return</span> COMPARISON<span class="token punctuation">;</span> <span class="token punctuation">}</span>\<span class="token string">"([^"</span>\\<span class="token punctuation">]</span><span class="token operator">|</span>\\<span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token operator">*</span>\"                  <span class="token punctuation">{</span>                                    yylval<span class="token punctuation">.</span>str <span class="token operator">=</span> <span class="token function">strdup</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> STRING<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>                        <span class="token punctuation">{</span>                                    yylval<span class="token punctuation">.</span>num <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> NUMBER<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span>a<span class="token operator">-</span>zA<span class="token operator">-</span>Z0<span class="token operator">-</span>9_<span class="token operator">/</span><span class="token operator">!</span><span class="token punctuation">]</span><span class="token punctuation">[</span>a<span class="token operator">-</span>zA<span class="token operator">-</span>Z0<span class="token operator">-</span>9_<span class="token operator">/</span>\<span class="token operator">-+</span>\<span class="token punctuation">.</span><span class="token punctuation">]</span><span class="token operator">*</span>     <span class="token punctuation">{</span>                                    yylval<span class="token punctuation">.</span>id <span class="token operator">=</span> <span class="token function">strdup</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> IDENTIFIER<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>      <span class="token punctuation">{</span>                                    yylval<span class="token punctuation">.</span>floatval <span class="token operator">=</span> <span class="token function">atof</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span> <span class="token punctuation">;</span>                                    <span class="token keyword">return</span> FLOAT<span class="token punctuation">;</span>                                 <span class="token punctuation">}</span><span class="token punctuation">[</span> \t\r\n<span class="token punctuation">]</span><span class="token operator">+</span>                      <span class="token comment" spellcheck="true">/* 忽略空白字符 */</span><span class="token string">"//"</span><span class="token punctuation">.</span><span class="token operator">*</span>\n                        <span class="token comment" spellcheck="true">/* 忽略 C/C++ 风格注释 */</span><span class="token string">"/*"</span>           <span class="token punctuation">{</span> <span class="token function">BEGIN</span><span class="token punctuation">(</span>COMMENT<span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">&lt;</span>COMMENT<span class="token operator">></span><span class="token string">"*/"</span>  <span class="token punctuation">{</span> <span class="token function">BEGIN</span><span class="token punctuation">(</span>INITIAL<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">&lt;</span>COMMENT<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">^</span><span class="token operator">*</span><span class="token punctuation">]</span><span class="token operator">|</span>\n<span class="token punctuation">)</span><span class="token operator">+</span><span class="token operator">|</span><span class="token punctuation">.</span><span class="token punctuation">.</span>               <span class="token punctuation">{</span> <span class="token function">yyerror</span><span class="token punctuation">(</span><span class="token string">"未知字符 '%c'"</span><span class="token punctuation">,</span> <span class="token operator">*</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">%</span><span class="token operator">%</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li><code>%%</code>分割符号</li><li><code>yytext</code>包含匹配的文本</li><li><code>yylval</code>向Bison传递token值</li><li>返回值对应Bison的token类型</li></ul><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 生成命令，根据.l生成.c</span>flex -o xxx_lex.c  xxx_flex.l <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h1 id="编写bison文件">4&emsp;编写bison文件</h1><p>bison文件一般在C语言中后缀用<code>.y</code>，在C++中用<code>.yy</code>。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token operator">%</span><span class="token punctuation">{</span><span class="token comment" spellcheck="true">//头文件及全局变量声明段</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;string.h></span></span><span class="token macro property">#<span class="token directive keyword">define</span> xxx 1000</span><span class="token keyword">extern</span> <span class="token keyword">void</span> <span class="token function">yyerror</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>s<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">int</span> hier_stack_top <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">xxxfunc</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token operator">%</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">/*! * * * * * * * * * * * * * * *  * * * * * * * * * * * * * */</span><span class="token comment" spellcheck="true">/* 定义令牌，必须在flex中定义过，这里列出的不需要通过yylval传参 */</span><span class="token operator">%</span>token VALUE ARRAY SIZE<span class="token comment" spellcheck="true">/* 定义类型(yylval) */</span><span class="token operator">%</span><span class="token keyword">union</span> <span class="token punctuation">{</span>    <span class="token keyword">char</span> <span class="token operator">*</span>id<span class="token punctuation">;</span>    <span class="token keyword">char</span> <span class="token operator">*</span>str<span class="token punctuation">;</span>    <span class="token keyword">int</span> num<span class="token punctuation">;</span>    <span class="token keyword">double</span> floatval<span class="token punctuation">;</span>    <span class="token keyword">int</span> comptok<span class="token punctuation">;</span>    Expr<span class="token operator">*</span> expr<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// 用户定义结构体</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">/* 为非终结符指定类型 */</span><span class="token operator">%</span>type <span class="token operator">&lt;</span>expr<span class="token operator">></span> expression<span class="token punctuation">;</span><span class="token operator">%</span>type <span class="token operator">&lt;</span>expr<span class="token operator">></span> expressions<span class="token punctuation">;</span><span class="token comment" spellcheck="true">/* 为令牌指定类型 */</span><span class="token operator">%</span>token <span class="token operator">&lt;</span>id<span class="token operator">></span> IDENTIFIER<span class="token operator">%</span>token <span class="token operator">&lt;</span>str<span class="token operator">></span> STRING<span class="token operator">%</span>token <span class="token operator">&lt;</span>num<span class="token operator">></span> NUMBER<span class="token operator">%</span>token <span class="token operator">&lt;</span>floatval<span class="token operator">></span> FLOAT<span class="token operator">%</span>token <span class="token operator">&lt;</span>comptok<span class="token operator">></span> COMPARISON<span class="token comment" spellcheck="true">/* 定义优先级和结合性（根据需要调整） */</span><span class="token operator">%</span>left  <span class="token string">','</span><span class="token operator">%</span><span class="token operator">%</span><span class="token comment" spellcheck="true">/*! * * * * * * * * * * * * * * * * * * * * * * * * */</span><span class="token comment" spellcheck="true">/* 语法规则段 */</span>cfg_file<span class="token operator">:</span>    <span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">/* 刚读入，可进行一些初始化操作 */</span>    <span class="token punctuation">}</span>    <span class="token operator">|</span> cfg_file check_block    <span class="token punctuation">;</span>check_block<span class="token operator">:</span>    CHECK <span class="token string">'{'</span> expressions <span class="token string">'}'</span>        <span class="token punctuation">{</span>        <span class="token comment" spellcheck="true">//...</span>        <span class="token punctuation">}</span>    <span class="token operator">|</span> CHECK <span class="token string">'('</span> IDENTIFIER <span class="token string">')'</span> <span class="token string">'{'</span> expressions <span class="token string">'}'</span>        <span class="token punctuation">{</span>        <span class="token comment" spellcheck="true">//...</span>        <span class="token function">free</span><span class="token punctuation">(</span>$<span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">}</span>    <span class="token punctuation">;</span>expressions<span class="token operator">:</span>    <span class="token comment" spellcheck="true">/* 没有键值对 */</span>    <span class="token punctuation">{</span> $$ <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>    <span class="token operator">|</span> expressions expression    <span class="token punctuation">{</span>        $<span class="token number">2</span><span class="token operator">-</span><span class="token operator">></span>next <span class="token operator">=</span> $<span class="token number">1</span><span class="token punctuation">;</span>        $$ <span class="token operator">=</span> $<span class="token number">2</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span>    <span class="token punctuation">;</span>expression<span class="token operator">:</span>    IDENTIFIER  COMPARISON  value <span class="token string">';'</span>    <span class="token punctuation">{</span>        <span class="token comment" spellcheck="true">//用户在其他地方定义了create_expr函数</span>        $$<span class="token operator">=</span><span class="token function">create_expr</span><span class="token punctuation">(</span>$<span class="token number">1</span><span class="token punctuation">,</span> $<span class="token number">2</span><span class="token punctuation">,</span> $<span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">free</span><span class="token punctuation">(</span>$<span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span>    <span class="token operator">|</span>    IDENTIFIER  COMPARISON  value    <span class="token punctuation">{</span>        $$<span class="token operator">=</span><span class="token function">create_expr</span><span class="token punctuation">(</span>$<span class="token number">1</span><span class="token punctuation">,</span> $<span class="token number">2</span><span class="token punctuation">,</span> $<span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">free</span><span class="token punctuation">(</span>$<span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token operator">%</span><span class="token operator">%</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li><code>%token</code>定义终结符</li><li><code>%left/%right</code>定义运算符结合性</li><li><code>$$</code>表示当前规则的结果</li><li><code>$1, $2...</code>访问子项的值</li></ul><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 生成命令，根据.y生成.c和.h</span>bison --debug xxx_parser.y -o parser_tab.c<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h1 id="编写主函数执行解析">5&emsp;编写主函数执行解析</h1><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// main.c，如果是C++则使用extern "C"</span><span class="token comment" spellcheck="true">// debug only</span>yydebug <span class="token operator">=</span> <span class="token number">1</span>；<span class="token comment" spellcheck="true">//外部声明</span><span class="token keyword">extern</span> <span class="token keyword">int</span> <span class="token function">yyparse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">extern</span> FILE <span class="token operator">*</span>yyin；<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span><span class="token operator">*</span>argv<span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>argc <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">/* 从文件读取输入 */</span>    FILE <span class="token operator">*</span>file <span class="token operator">=</span> <span class="token function">fopen</span><span class="token punctuation">(</span>argv<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">"r"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>file<span class="token punctuation">)</span> <span class="token punctuation">{</span>      <span class="token function">perror</span><span class="token punctuation">(</span><span class="token string">"无法打开文件"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>      <span class="token keyword">return</span> <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span>    yyin <span class="token operator">=</span> file<span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token comment" spellcheck="true">/* 解析 CFG 文件 */</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">yyparse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">// ...</span>  <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"解析失败\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="面向对象的使用方式">6&emsp;面向对象的使用方式</h1><p>前文介绍的传统flex/bison使用风格较为常见，但在处理一些复杂问题上功能稍弱，尤其是参数传递以及调用的灵活性方面。本部分介绍面向对象的flex/bison使用方式，并给出基本框架。  </p><h2 id="xxx-driver">6.1&emsp;xxx_driver</h2><p>驱动器部分，负责调用分析器进行解析，同时也是传递参数的重要枢纽。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// xxx_driver.hpp，展示的均为通用函数</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;string></span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;iostream></span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;fstream></span></span><span class="token comment" spellcheck="true">/*! 可有多个Driver，命名空间不同，其他不变 */</span><span class="token keyword">namespace</span> xxx_parse <span class="token punctuation">{</span><span class="token comment" spellcheck="true">/// Forward declarations of classes</span><span class="token keyword">class</span> <span class="token class-name">Parser</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">Scanner</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">location</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">Driver</span> <span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">// 可定义用于参数传递的变量/成员函数</span> <span class="token keyword">public</span><span class="token operator">:</span>  <span class="token comment" spellcheck="true">/// enable debug output in the flex scanner</span>  <span class="token keyword">bool</span> trace_scanning<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/// enable debug output in the bison parser</span>  <span class="token keyword">bool</span> trace_parsing<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/// stream name (file or input stream) used for error messages.</span>  std<span class="token operator">::</span>string streamname<span class="token punctuation">;</span>  <span class="token function">Driver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token operator">~</span><span class="token function">Driver</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/** Invoke the scanner and parser for a stream.   * @param in  input stream   * @param sname  stream name for error messages   * @return    true if successfully parsed   */</span>  <span class="token keyword">bool</span> <span class="token function">parse_stream</span><span class="token punctuation">(</span>std<span class="token operator">::</span>istream<span class="token operator">&amp;</span> in<span class="token punctuation">,</span>                    <span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> sname <span class="token operator">=</span> <span class="token string">"stream input"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/** Invoke the scanner and parser on an input string.   * @param input  input string   * @param sname  stream name for error messages   * @return    true if successfully parsed   */</span>  <span class="token keyword">bool</span> <span class="token function">parse_string</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> input<span class="token punctuation">,</span>                    <span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> sname <span class="token operator">=</span> <span class="token string">"string stream"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/** Invoke the scanner and parser on a file. Use parse_stream with a   * std::ifstream if detection of file reading errors is required.   * @param filename  input file name   * @return    true if successfully parsed   */</span>  <span class="token keyword">bool</span> <span class="token function">parse_file</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> filename<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// To demonstrate pure handling of parse errors, instead of</span>  <span class="token comment" spellcheck="true">// simply dumping them on the standard error output, we will pass</span>  <span class="token comment" spellcheck="true">// them to the driver using the following two member functions.</span>  <span class="token comment" spellcheck="true">/** Error handling with associated line number. This can be modified to   * output the error e.g. to a dialog box. */</span>  <span class="token keyword">void</span> <span class="token function">error</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">class</span> <span class="token class-name">location</span><span class="token operator">&amp;</span> l<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> m<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/** General error handling. This can be modified to output the error   * e.g. to a dialog box. */</span>  <span class="token keyword">void</span> <span class="token function">error</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> m<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">private</span><span class="token operator">:</span>  Scanner<span class="token operator">*</span> scanner_<span class="token punctuation">;</span>  Parser<span class="token operator">*</span> parser_<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/// Allows Parser and Scanner to access private attributes</span>  <span class="token comment" spellcheck="true">/// of the Driver class</span>  <span class="token keyword">friend</span> <span class="token keyword">class</span> <span class="token class-name">Parser</span><span class="token punctuation">;</span>  <span class="token keyword">friend</span> <span class="token keyword">class</span> <span class="token class-name">Scanner</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span>  <span class="token comment" spellcheck="true">// namespace xxx_parse</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// xxx_driver.cpp，展示的均为通用函数</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_driver.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_scanner.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_parser.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;sstream></span></span><span class="token keyword">namespace</span> xxx_parse <span class="token punctuation">{</span>Driver<span class="token operator">::</span><span class="token function">Driver</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">scanner_</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Scanner</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">parser_</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token function">Parser</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  trace_scanning <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>  trace_parsing <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><span class="token punctuation">}</span>Driver<span class="token operator">::</span><span class="token operator">~</span><span class="token function">Driver</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token keyword">delete</span> parser_<span class="token punctuation">;</span>  <span class="token keyword">delete</span> scanner_<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">bool</span> Driver<span class="token operator">::</span><span class="token function">parse_stream</span><span class="token punctuation">(</span>std<span class="token operator">::</span>istream<span class="token operator">&amp;</span> in<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> sname<span class="token punctuation">)</span> <span class="token punctuation">{</span>  streamname <span class="token operator">=</span> sname<span class="token punctuation">;</span>  scanner_<span class="token operator">-</span><span class="token operator">></span><span class="token function">switch_streams</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>in<span class="token punctuation">,</span> <span class="token operator">&amp;</span>std<span class="token operator">::</span>cerr<span class="token punctuation">)</span><span class="token punctuation">;</span>  scanner_<span class="token operator">-</span><span class="token operator">></span><span class="token function">set_debug</span><span class="token punctuation">(</span>trace_scanning<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token macro property">#<span class="token directive keyword">if</span> YYDEBUG</span>  parser_<span class="token operator">-</span><span class="token operator">></span><span class="token function">set_debug_level</span><span class="token punctuation">(</span>trace_parsing<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token macro property">#<span class="token directive keyword">endif</span></span>  <span class="token keyword">return</span> <span class="token punctuation">(</span>parser_<span class="token operator">-</span><span class="token operator">></span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">bool</span> Driver<span class="token operator">::</span><span class="token function">parse_file</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> filename<span class="token punctuation">)</span> <span class="token punctuation">{</span>  std<span class="token operator">::</span>ifstream <span class="token function">in</span><span class="token punctuation">(</span>filename<span class="token punctuation">.</span><span class="token function">c_str</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>in<span class="token punctuation">.</span><span class="token function">good</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token function">parse_stream</span><span class="token punctuation">(</span>in<span class="token punctuation">,</span> filename<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">bool</span> Driver<span class="token operator">::</span><span class="token function">parse_string</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> input<span class="token punctuation">,</span> <span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> sname<span class="token punctuation">)</span> <span class="token punctuation">{</span>  std<span class="token operator">::</span>istringstream <span class="token function">iss</span><span class="token punctuation">(</span>input<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token function">parse_stream</span><span class="token punctuation">(</span>iss<span class="token punctuation">,</span> sname<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">void</span> Driver<span class="token operator">::</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> m<span class="token punctuation">)</span> <span class="token punctuation">{</span> std<span class="token operator">::</span>cerr <span class="token operator">&lt;&lt;</span> m <span class="token operator">&lt;&lt;</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span>  <span class="token comment" spellcheck="true">// namespace xxx_parse</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="xxx-scanner">6.2&emsp;xxx_scanner</h2><p>扫描器部分，主要负责词法分析。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// xxx_scanner.hpp，展示的均为通用函数，注意命名空间的对应（包括继承的父类名称前缀）</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_parser.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">ifndef</span> YY_DECL</span><span class="token macro property">#<span class="token directive keyword">define</span> YY_DECL                                              \  xxx_parse::Parser::token_type xxx_parse::Scanner::yylex( \      xxx_parse::Parser::semantic_type* yylval, xxx_parse::Driver&amp; driver)</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span class="token macro property">#<span class="token directive keyword">ifndef</span> __FLEX_LEXER_H</span><span class="token macro property">#<span class="token directive keyword">define</span> yyFlexLexer xxx_parseFlexLexer</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;FlexLexer.h></span></span><span class="token macro property">#<span class="token directive keyword">undef</span> yyFlexLexer</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span class="token keyword">namespace</span> xxx_parse <span class="token punctuation">{</span><span class="token keyword">class</span> <span class="token class-name">Scanner</span> <span class="token operator">:</span> <span class="token keyword">public</span> xxx_parseFlexLexer <span class="token punctuation">{</span> <span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">Scanner</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">Scanner</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">virtual</span> Parser<span class="token operator">::</span>token_type <span class="token function">yylex</span><span class="token punctuation">(</span>Parser<span class="token operator">::</span>semantic_type<span class="token operator">*</span> yylval<span class="token punctuation">,</span>                                   Driver<span class="token operator">&amp;</span> driver<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">void</span> <span class="token function">set_debug</span><span class="token punctuation">(</span><span class="token keyword">bool</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">}</span>  <span class="token comment" spellcheck="true">// namespace xxx_parse</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// xxx_scanner.ll，展示了一个比较丰富的例子，除了规则和状态定义，其他均为通用函数</span><span class="token operator">%</span>option noyywrap<span class="token operator">%</span>option debug<span class="token operator">%</span>option c<span class="token operator">++</span><span class="token comment" spellcheck="true">/* the manual says "somewhat more optimized"，加上后速度快很多 */</span><span class="token operator">%</span>option batch<span class="token operator">%</span>option prefix<span class="token operator">=</span><span class="token string">"xxx_parse"</span><span class="token comment" spellcheck="true">/* enables the use of start condition stacks */</span><span class="token operator">%</span>option stack<span class="token operator">%</span><span class="token punctuation">{</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_parser.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_scanner.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_driver.hpp"</span></span><span class="token keyword">typedef</span> xxx_parse<span class="token operator">::</span>Parser<span class="token operator">::</span>token token<span class="token punctuation">;</span><span class="token keyword">typedef</span> xxx_parse<span class="token operator">::</span>Parser<span class="token operator">::</span>token_type token_type<span class="token punctuation">;</span><span class="token macro property">#<span class="token directive keyword">define</span> yyterminate() return token::TOK_EOF</span><span class="token operator">%</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//状态定义区</span><span class="token operator">%</span>x COMMENT<span class="token operator">%</span>x RIGHTSIDE<span class="token operator">%</span><span class="token operator">%</span><span class="token comment" spellcheck="true">//规则定义区</span><span class="token string">"{"</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>L_BRACE<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"}"</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>R_BRACE<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"["</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>L_BRACKETS<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"]"</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>R_BRACKETS<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"="</span>   <span class="token punctuation">{</span> <span class="token function">yy_push_state</span><span class="token punctuation">(</span>RIGHTSIDE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span> token<span class="token operator">::</span>EQUAL<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">";"</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>SEMICOLON<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">"("</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>L_PARENTHESES<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">")"</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>R_PARENTHESES<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token string">","</span>   <span class="token punctuation">{</span> <span class="token keyword">return</span> token<span class="token operator">::</span>COMMA<span class="token punctuation">;</span><span class="token punctuation">}</span>\<span class="token string">"([^"</span>\\<span class="token punctuation">]</span><span class="token operator">|</span>\\<span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token operator">*</span>\"                  <span class="token punctuation">{</span>                                    <span class="token keyword">char</span> <span class="token operator">*</span> temp <span class="token operator">=</span> <span class="token function">strdup</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>str <span class="token operator">=</span> <span class="token function">unquote</span><span class="token punctuation">(</span>temp<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token function">free</span><span class="token punctuation">(</span>temp<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>STRING<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>                        <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>num <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>INT<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span>a<span class="token operator">-</span>zA<span class="token operator">-</span>Z_<span class="token punctuation">]</span><span class="token operator">*</span>                         <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>id <span class="token operator">=</span> <span class="token function">strdup</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>IDENTIFIER<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>      <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>floatval <span class="token operator">=</span> <span class="token function">atof</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span> <span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>FLOAT<span class="token punctuation">;</span>                                 <span class="token punctuation">}</span><span class="token string">"/*"</span>           <span class="token punctuation">{</span> <span class="token function">yy_push_state</span><span class="token punctuation">(</span>COMMENT<span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">[</span> \t\r\n<span class="token punctuation">]</span><span class="token operator">+</span>                      <span class="token operator">/</span><span class="token operator">*</span> 忽略空白字符 <span class="token operator">*</span><span class="token operator">/</span><span class="token operator">&lt;</span>RIGHTSIDE<span class="token operator">></span><span class="token punctuation">{</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>                        <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>num <span class="token operator">=</span> <span class="token function">atoi</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token function">yy_pop_state</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>INT<span class="token punctuation">;</span>                                <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span> <span class="token operator">|</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token string">"."</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">*</span><span class="token punctuation">[</span>eE<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token operator">-+</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation">]</span><span class="token operator">+</span>      <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>floatval <span class="token operator">=</span> <span class="token function">atof</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span> <span class="token punctuation">;</span>                                    <span class="token function">yy_pop_state</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>FLOAT<span class="token punctuation">;</span>                                 <span class="token punctuation">}</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token operator">-</span>9a<span class="token operator">-</span>zA<span class="token operator">-</span>Z_<span class="token operator">+</span>\<span class="token operator">-</span><span class="token operator">*</span><span class="token operator">/</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\t<span class="token punctuation">]</span><span class="token operator">+</span>               <span class="token punctuation">{</span>                                    yylval<span class="token operator">-</span><span class="token operator">></span>expr <span class="token operator">=</span> <span class="token function">strdup</span><span class="token punctuation">(</span>yytext<span class="token punctuation">)</span> <span class="token punctuation">;</span>                                    <span class="token function">yy_pop_state</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>                                    <span class="token comment" spellcheck="true">/* 表达式中不能有空格 */</span>                                    <span class="token keyword">return</span> token<span class="token operator">::</span>EXPR<span class="token punctuation">;</span>                                 <span class="token punctuation">}</span><span class="token punctuation">[</span> \t\r\n<span class="token punctuation">]</span><span class="token operator">+</span>                      <span class="token comment" spellcheck="true">/* 忽略空白字符 */</span><span class="token punctuation">}</span><span class="token string">"//"</span><span class="token punctuation">.</span><span class="token operator">*</span>\n                        <span class="token comment" spellcheck="true">/* 忽略 C/C++ 风格注释 */</span><span class="token operator">&lt;</span>COMMENT<span class="token operator">></span><span class="token string">"*/"</span>  <span class="token punctuation">{</span> <span class="token function">yy_pop_state</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">&lt;</span>COMMENT<span class="token operator">></span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">^</span><span class="token operator">*</span><span class="token punctuation">]</span><span class="token operator">|</span>\n<span class="token punctuation">)</span><span class="token operator">+</span><span class="token operator">|</span><span class="token punctuation">.</span><span class="token punctuation">.</span>               <span class="token punctuation">{</span> <span class="token function">yyerror</span><span class="token punctuation">(</span><span class="token string">"未知字符 '%c'"</span><span class="token punctuation">,</span> <span class="token operator">*</span>yytext<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">%</span><span class="token operator">%</span><span class="token comment" spellcheck="true">/*   CUSTOM C++ CODE*/</span><span class="token keyword">namespace</span> xxx_parse<span class="token punctuation">{</span>    Scanner<span class="token operator">::</span><span class="token function">Scanner</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token operator">:</span> <span class="token function">xxx_parseFlexLexer</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token punctuation">{</span>    <span class="token punctuation">}</span>    Scanner<span class="token operator">::</span><span class="token operator">~</span><span class="token function">Scanner</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token punctuation">{</span>    <span class="token punctuation">}</span>    <span class="token keyword">void</span> Scanner<span class="token operator">::</span><span class="token function">set_debug</span><span class="token punctuation">(</span><span class="token keyword">bool</span> b<span class="token punctuation">)</span>    <span class="token punctuation">{</span>        yy_flex_debug <span class="token operator">=</span> b<span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token macro property">#<span class="token directive keyword">ifdef</span> yylex</span><span class="token macro property"># <span class="token directive keyword">undef</span> yylex</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span class="token keyword">int</span> xxx_parseFlexLexer<span class="token operator">::</span><span class="token function">yylex</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>  std<span class="token operator">::</span>cerr <span class="token operator">&lt;&lt;</span> <span class="token string">"call parsepitFlexLexer::yylex()!"</span> <span class="token operator">&lt;&lt;</span> std<span class="token operator">::</span>endl<span class="token punctuation">;</span>  <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="xxx-parser">6.3&emsp;xxx_parser</h2><p>解析器，主要负责语法分析。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">// xxx_parser.yy，展示的均为通用函数，注意前缀名称的对应</span><span class="token operator">%</span><span class="token punctuation">{</span><span class="token comment" spellcheck="true">// 其他头文件</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token comment" spellcheck="true">// 必备头文件</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_parser.hpp"</span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_scanner.hpp"</span></span><span class="token comment" spellcheck="true">/*! 全局变量定义区 */</span><span class="token macro property">#<span class="token directive keyword">define</span> yylex driver.scanner_->yylex</span><span class="token operator">%</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">/*! * * * * * * * * * * * * * * *  * * * * * * * * * * * * * */</span><span class="token operator">%</span>code requires<span class="token punctuation">{</span>  <span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;string></span></span>  <span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"xxx_driver.hpp"</span></span>  <span class="token keyword">using</span> <span class="token keyword">namespace</span> xxx<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token operator">%</span>code provides<span class="token punctuation">{</span>  <span class="token keyword">namespace</span> xxx_parse  <span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">// Forward declaration of the Driver class</span>    <span class="token keyword">class</span> <span class="token class-name">Driver</span><span class="token punctuation">;</span>    <span class="token keyword">inline</span> <span class="token keyword">void</span> <span class="token function">yyerror</span><span class="token punctuation">(</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>s<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    va_list ap<span class="token punctuation">;</span>    <span class="token function">va_start</span><span class="token punctuation">(</span>ap<span class="token punctuation">,</span> s<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"Error: "</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">vfprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> s<span class="token punctuation">,</span> ap<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span> <span class="token string">"\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span>  <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">// 传递参数driver</span><span class="token operator">%</span>require <span class="token string">"3.2"</span><span class="token operator">%</span>language <span class="token string">"C++"</span><span class="token comment" spellcheck="true">/* use newer C++ skeleton file */</span><span class="token operator">%</span>skeleton <span class="token string">"lalr1.cc"</span><span class="token operator">%</span>define api<span class="token punctuation">.</span><span class="token keyword">namespace</span> <span class="token punctuation">{</span>xxx_parse<span class="token punctuation">}</span><span class="token operator">%</span>define api<span class="token punctuation">.</span>parser<span class="token punctuation">.</span><span class="token keyword">class</span> <span class="token punctuation">{</span>Parser<span class="token punctuation">}</span><span class="token operator">%</span>parse<span class="token operator">-</span>param <span class="token punctuation">{</span>Driver <span class="token operator">&amp;</span>driver<span class="token punctuation">}</span><span class="token operator">%</span>lex<span class="token operator">-</span>param <span class="token punctuation">{</span>Driver <span class="token operator">&amp;</span>driver<span class="token punctuation">}</span><span class="token comment" spellcheck="true">/* verbose error messages */</span><span class="token operator">%</span>define parse<span class="token punctuation">.</span>error verbose<span class="token operator">%</span>debug<span class="token comment" spellcheck="true">/* 定义令牌 */</span><span class="token operator">%</span>token TOK_EOF <span class="token number">0</span><span class="token operator">%</span>token L_BRACE R_BRACE L_BRACKETS R_BRACKETS EQUAL SEMICOLON L_PARENTHESES R_PARENTHESES COMMA<span class="token comment" spellcheck="true">/* 定义类型 */</span><span class="token operator">%</span><span class="token keyword">union</span> <span class="token punctuation">{</span>    <span class="token keyword">char</span> <span class="token operator">*</span>id<span class="token punctuation">;</span>    <span class="token keyword">char</span> <span class="token operator">*</span>str<span class="token punctuation">;</span>    <span class="token keyword">double</span> floatval<span class="token punctuation">;</span>    <span class="token keyword">int</span> num<span class="token punctuation">;</span>    <span class="token keyword">char</span> <span class="token operator">*</span> expr<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">/* 为令牌指定类型 */</span><span class="token operator">%</span>token <span class="token operator">&lt;</span>id<span class="token operator">></span> IDENTIFIER<span class="token operator">%</span>token <span class="token operator">&lt;</span>str<span class="token operator">></span> STRING<span class="token operator">%</span>token <span class="token operator">&lt;</span>num<span class="token operator">></span> INT<span class="token operator">%</span>token <span class="token operator">&lt;</span>floatval<span class="token operator">></span> FLOAT<span class="token comment" spellcheck="true">/* 为非终结符指定类型 */</span><span class="token comment" spellcheck="true">/* 定义优先级和结合性（根据需要调整） */</span><span class="token operator">%</span>start xxx_file<span class="token operator">%</span><span class="token operator">%</span><span class="token comment" spellcheck="true">/*! * * * * * * * * * * * * * * * * * * * * * * * * */</span><span class="token comment" spellcheck="true">/* 语法规则定义区 */</span>xxx_file<span class="token operator">:</span>    <span class="token operator">|</span> xxx_file quantity_block    <span class="token punctuation">{</span> <span class="token punctuation">}</span>    <span class="token punctuation">;</span><span class="token operator">%</span><span class="token operator">%</span><span class="token keyword">namespace</span> xxx_parse<span class="token punctuation">{</span>    <span class="token keyword">void</span> Parser<span class="token operator">::</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token keyword">const</span> std<span class="token operator">::</span>string<span class="token operator">&amp;</span> m<span class="token punctuation">)</span>    <span class="token punctuation">{</span>        driver<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="生成命令">6.4&emsp;生成命令</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/sh</span><span class="token function">cd</span> <span class="token variable">${0%/*}</span> <span class="token operator">||</span> <span class="token keyword">exit</span> 1<span class="token comment" spellcheck="true"># -d --debug </span><span class="token function">rm</span> -f xxx_scanner.c* xxx_parser.c* xxx_parser.h* location.hhflex -o xxx_scanner.cpp xxx_scanner.llbison --debug -d xxx_parser.yy -o xxx_parser.cpp<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="调用方式">6.5&emsp;调用方式</h2><p>通过driver来调用解析。</p><pre class="line-numbers language-cpp"><code class="language-cpp">std<span class="token operator">::</span>string full_path<span class="token operator">=</span><span class="token string">"xxx"</span><span class="token punctuation">;</span>xxx_parse<span class="token operator">::</span>Driver driver<span class="token punctuation">;</span><span class="token comment" spellcheck="true">// driver.trace_scanning = true; </span><span class="token comment" spellcheck="true">/*!&lt; debug */</span>driver<span class="token punctuation">.</span><span class="token function">parse_file</span><span class="token punctuation">(</span>full_path<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><h1 id="高级使用（AST）">7&emsp;高级使用（AST）</h1><blockquote><p>什么是抽象语法树</p></blockquote><p>抽象语法树（AST）是源代码语法结构的一种树形表示。它将源代码分解为树形结构，其中每个节点代表源代码中的一个语法结构，如表达式、语句或声明。与具体的语法树相比，抽象语法树省略了语法上的一些次要信息，如括号和运算符的优先级等，保留主要的语义内容，以一种更简洁、更抽象的形式展示代码的结构。  </p><blockquote><p>为什么要使用抽象语法树</p></blockquote><p>在一些比较复杂的使用场景中，对bison解析的时机（顺序）要求较高，而一般写法是<code>识别-&gt;解析-&gt;执行</code>的流程，解析后立即会执行规则段中的代码，用户无法控制执行的时机。而使用AST的流程则为<code>识别-&gt;解析-&gt;生成AST-&gt;调用AST执行接口-&gt;执行</code>，能够适用更多的场景。</p><blockquote><p>AST示例（基于上面的框架）</p></blockquote><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token keyword">namespace</span> xxx_parse <span class="token punctuation">{</span><span class="token comment" spellcheck="true">// 用来处理各种类型的数（整数、浮点等）</span><span class="token keyword">class</span> <span class="token class-name">ParsedData</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">/*! \class ASTNode *  \brief Abstract syntax tree.  ASTNode is abstract base class for all other * nodes. */</span><span class="token keyword">class</span> <span class="token class-name">ASTNode</span> <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  Driver <span class="token operator">*</span>driver_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">ASTNode</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">ASTNode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">/*! pure abstract */</span>  <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">eval</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">push_back</span><span class="token punctuation">(</span>ASTNode <span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">/*! * * * * * * * * * * * * * * *  * * * * * * * * * * * * * */</span><span class="token comment" spellcheck="true">/*! 数学表达式基类 */</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression</span> <span class="token operator">:</span> <span class="token keyword">public</span> ASTNode <span class="token punctuation">{</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">ASTNode</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">eval</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">push_back</span><span class="token punctuation">(</span>ASTNode <span class="token operator">*</span>n<span class="token punctuation">)</span> override <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">/*! 变量类型 */</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression</span> <span class="token operator">:</span> <span class="token keyword">public</span> ASTNode <span class="token punctuation">{</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_Var</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  std<span class="token operator">::</span>string var_name_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_Var</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> std<span class="token operator">::</span>string name<span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">var_name_</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_Var</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>std<span class="token operator">::</span>string name<span class="token punctuation">)</span> <span class="token punctuation">{</span> var_name_ <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_Int</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  <span class="token keyword">int</span> value_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_Int</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> <span class="token keyword">int</span> i<span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">value_</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_Int</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">void</span> <span class="token function">setValue</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> value_ <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_Float</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  <span class="token keyword">double</span> value_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_Float</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> <span class="token keyword">double</span> i<span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">value_</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_Float</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">void</span> <span class="token function">setValue</span><span class="token punctuation">(</span><span class="token keyword">double</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> value_ <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_Bool</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  <span class="token keyword">bool</span> value_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_Bool</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> <span class="token keyword">bool</span> i<span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">value_</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_Bool</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">void</span> <span class="token function">setValue</span><span class="token punctuation">(</span><span class="token keyword">bool</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span> value_ <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_ADD</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  AST_Expression <span class="token operator">*</span>left_<span class="token punctuation">;</span>  AST_Expression <span class="token operator">*</span>right_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_ADD</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> AST_Expression <span class="token operator">*</span>left <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">,</span>                     AST_Expression <span class="token operator">*</span>right <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">left_</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">right_</span><span class="token punctuation">(</span>right<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_ADD</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token keyword">delete</span> left_<span class="token punctuation">;</span>    <span class="token keyword">delete</span> right_<span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_SUB</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  AST_Expression <span class="token operator">*</span>left_<span class="token punctuation">;</span>  AST_Expression <span class="token operator">*</span>right_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_SUB</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> AST_Expression <span class="token operator">*</span>left <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">,</span>                     AST_Expression <span class="token operator">*</span>right <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">left_</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">right_</span><span class="token punctuation">(</span>right<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_SUB</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token keyword">delete</span> left_<span class="token punctuation">;</span>    <span class="token keyword">delete</span> right_<span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_MUL</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  AST_Expression <span class="token operator">*</span>left_<span class="token punctuation">;</span>  AST_Expression <span class="token operator">*</span>right_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_MUL</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> AST_Expression <span class="token operator">*</span>left <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">,</span>                     AST_Expression <span class="token operator">*</span>right <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">left_</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">right_</span><span class="token punctuation">(</span>right<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_MUL</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token keyword">delete</span> left_<span class="token punctuation">;</span>    <span class="token keyword">delete</span> right_<span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">class</span> <span class="token class-name">AST_Expression_DIV</span> <span class="token operator">:</span> <span class="token keyword">public</span> AST_Expression <span class="token punctuation">{</span><span class="token keyword">protected</span><span class="token operator">:</span>  AST_Expression <span class="token operator">*</span>left_<span class="token punctuation">;</span>  AST_Expression <span class="token operator">*</span>right_<span class="token punctuation">;</span><span class="token keyword">public</span><span class="token operator">:</span>  <span class="token function">AST_Expression_DIV</span><span class="token punctuation">(</span>Driver <span class="token operator">*</span>driver<span class="token punctuation">,</span> AST_Expression <span class="token operator">*</span>left <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">,</span>                     AST_Expression <span class="token operator">*</span>right <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">)</span>      <span class="token operator">:</span> <span class="token function">AST_Expression</span><span class="token punctuation">(</span>driver<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">left_</span><span class="token punctuation">(</span>left<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token function">right_</span><span class="token punctuation">(</span>right<span class="token punctuation">)</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>  <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">AST_Expression_DIV</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token keyword">delete</span> left_<span class="token punctuation">;</span>    <span class="token keyword">delete</span> right_<span class="token punctuation">;</span>  <span class="token punctuation">}</span>  <span class="token keyword">virtual</span> ParsedData <span class="token operator">*</span><span class="token function">eval_expr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> override<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>在<code>xxx_parse.yy</code>中，则需要在<code>union</code>中增加各AST类型，并在解析语句中构造AST类的实例。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-02-27-flex-bison-shi-yong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>关于团队知识库的选择</title>
      <link>https://chengpengzhao.com/2025-02-08-guan-yu-tuan-dui-zhi-shi-ku-de-xuan-ze/</link>
      <guid>https://chengpengzhao.com/2025-02-08-guan-yu-tuan-dui-zhi-shi-ku-de-xuan-ze/</guid>
      <pubDate>Sat, 08 Feb 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;背景与目标&quot;&gt;1&amp;emsp;背景与目标&lt;/h1&gt;&lt;p&gt;随着高性能计
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="背景与目标">1&emsp;背景与目标</h1><p>随着高性能计算技术在工业仿真领域的快速发展，团队成员面临着日益复杂的技术挑战。为了提高工作效率、促进知识共享、减少重复劳动和提升技术水平，建立一个高效、易用、全面的团队知识库显得尤为重要。该知识库将成为团队知识积累、经验共享和技术创新的核心平台，确保团队在不断变化的技术环境中保持竞争力。</p><p>团队知识库的目标如下：</p><ul><li><strong>知识存储与管理</strong>：高效存储和管理团队成员在项目中积累的技术知识、经验、解决方案、文档和工具。  </li><li><strong>信息共享与传递</strong>：促进团队成员之间的知识共享，避免信息孤岛，提升团队的整体技术水平。  </li><li><strong>技术支持与问题解决</strong>：提供对常见问题、挑战和技术难题的解决方案和最佳实践。  </li><li><strong>培训与成长</strong>：为新成员提供系统的技术入门资料和学习资源，帮助团队成员快速提升专业能力。  </li><li><strong>文档化工作流程</strong>：记录和规范团队的工作流程、项目管理规范和技术决策，为后续工作提供指导和参考。  </li></ul><h1 id="需求分析">2&emsp;需求分析</h1><p>为满足团队的实际工作需求，知识库应具备以下功能：</p><h2 id="核心功能">2.1&emsp;核心功能</h2><ul><li><strong>技术文档管理</strong>  <ul><li>版本控制、文档更新日志和权限管理。  </li><li>确保知识库中的文档和资料及时更新，并且成员可以方便地查看文档的历史版本。  </li></ul></li></ul><ul><li><p><strong>文档搜索与分类</strong>  </p><ul><li>强大的全文搜索功能，能够快速定位到需要的技术文档和解决方案。  </li><li>分类清晰的目录结构，支持按主题、领域、项目等多维度进行浏览。  </li></ul></li><li><p><strong>权限管理</strong>  </p><ul><li>根据团队成员的角色和权限设置不同的访问权限，保证敏感信息的安全性。  </li><li>支持不同级别的编辑和评论权限，以便团队成员能够参与到文档的完善和更新中。  </li></ul></li><li><p><strong>集成与兼容性</strong>  </p><ul><li>支持多种格式的文档，如文本(Markdown)、图像、PDF、代码文件等，确保资料的多样性和可读性。  </li></ul></li><li><p><strong>数据备份与恢复</strong></p><ul><li>设置定期的数据备份方案，防止数据丢失。  </li><li>提供应急数据恢复机制，确保系统故障时能够快速恢复。  </li></ul></li><li><p><strong>安全性与隐私保护</strong></p><ul><li>数据本地储存</li><li>公司内网访问  </li></ul></li></ul><h2 id="可选功能">2.2&emsp;可选功能</h2><ul><li><p><strong>成员间交互</strong>  </p><ul><li>支持评论、反馈和讨论功能，促进成员间的知识交流。  </li><li>提供书签、收藏夹等功能，帮助成员保存常用文档和知识点。  </li></ul></li><li><p><strong>数据库与存储</strong></p><ul><li>使用高性能的数据库管理系统（如MySQL、PostgreSQL）来管理知识库中的文档数据。</li></ul></li><li><p><strong>自动化更新与提醒</strong>  </p><ul><li>系统可以自动提醒团队成员参与文档的更新和审阅工作，确保知识库内容的及时更新。  </li><li>定期发布知识库更新报告，向团队成员推送重要文档和技术内容。  </li></ul></li></ul><h1 id="几款知名知识库">3&emsp;几款知名知识库</h1><h2 id="Wiki-js">3.1&emsp;Wiki.js</h2><ul><li><strong>功能特点</strong>：<ul><li>支持Markdown和富文本编辑器。</li><li>提供多用户实时协作功能。</li><li>支持多种备份存储方式和用户验证方式。</li><li>提供灵活的权限管理。</li><li>支持国际化和自定义主题。</li></ul></li><li><strong>优点</strong>：<ul><li>开源免费，可自由部署和定制。</li><li>界面简洁美观，易于使用。</li><li>支持多种编辑器和插件扩展。</li></ul></li><li><strong>缺点</strong>：<ul><li>部署和配置需要一定的技术基础。</li></ul></li></ul><h2 id="Confluence">3.2&emsp;Confluence</h2><ul><li><strong>功能特点</strong>：<ul><li>提供强大的文档管理和团队协作功能。</li><li>支持丰富的插件和自定义功能。</li><li>支持文档版本控制和搜索功能。</li></ul></li><li><strong>优点</strong>：<ul><li>界面简洁直观，易于上手。</li><li>与Jira等Atlassian产品无缝集成。</li><li>功能强大，适合大型企业和复杂项目。</li></ul></li><li><strong>缺点</strong>：<ul><li>价格较高，尤其是用户数量增加时。</li><li>不支持私有部署。</li></ul></li></ul><h2 id="Outline">3.3&emsp;Outline</h2><ul><li><strong>功能特点</strong>：<ul><li>支持Markdown语法和富文本编辑。</li><li>支持团队协作和内容分享。</li><li>提供即时搜索功能。</li></ul></li><li><strong>优点</strong>：<ul><li>开源免费，可私有化部署。</li><li>界面简洁，学习成本低。</li></ul></li><li><strong>缺点</strong>：<ul><li>功能相对简单，部分高级功能有待完善。</li></ul></li></ul><h2 id="DocMost">3.4&emsp;DocMost</h2><ul><li><strong>功能特点</strong>：<ul><li>支持实时协作的富文本编辑器。</li><li>支持表格、数学公式和注释。</li><li>提供完善的权限管理系统。</li></ul></li><li><strong>优点</strong>：<ul><li>开源免费，可自托管。</li><li>界面简洁，类似Notion。</li><li>支持Docker部署，便于安装。</li></ul></li><li><strong>缺点</strong>：<ul><li>功能相对有限，不如其他软件丰富。</li><li>层级目录管理功能缺失。</li></ul></li></ul><h2 id="PingCode">3.5&emsp;PingCode</h2><ul><li><strong>功能特点</strong>：<ul><li>支持多人实时在线协同编辑，信息实时保存同步。</li><li>支持富文本编辑，支持插入图片、表格、思维导图等。</li><li>支持页面级权限管控和安全能力。</li><li>支持AI智能助手。</li></ul></li><li><strong>优点</strong>：<ul><li>产品开箱即用，简单易上手。</li><li>支持私有部署和定制化。</li><li>国际信息安全体系认证，安全有保障。</li></ul></li><li><strong>缺点</strong>：<ul><li>商软，且功能比较杂。</li><li>用户没有数据的掌控权。</li></ul></li></ul><h2 id="对比">3.6&emsp;对比</h2><table><thead><tr><th>功能/工具</th><th>Wiki.js</th><th>Confluence</th><th>Outline</th><th>DocMost</th><th>PingCode</th></tr></thead><tbody><tr><td><strong>开源性</strong></td><td>开源免费</td><td>非开源，需付费</td><td>开源免费</td><td>开源免费</td><td>非开源，需付费</td></tr><tr><td><strong>编辑器</strong></td><td>Markdown、富文本</td><td>富文本编辑器</td><td>Markdown、富文本</td><td>富文本、Markdown</td><td>富文本、Markdown等</td></tr><tr><td><strong>协作功能</strong></td><td>多用户实时协作</td><td>多人协作编辑和审核</td><td>多人协作</td><td>多人实时协作</td><td>多人实时在线协同编辑</td></tr><tr><td><strong>版本控制</strong></td><td>支持</td><td>支持</td><td>不支持</td><td>不支持</td><td>支持</td></tr><tr><td><strong>权限管理</strong></td><td>灵活</td><td>强大</td><td>简单</td><td>完善</td><td>页面级权限管控</td></tr><tr><td><strong>多语言支持</strong></td><td>支持多种语言</td><td>支持多种语言</td><td>支持多种语言</td><td>支持多种语言</td><td>不支持多语言</td></tr><tr><td><strong>集成能力</strong></td><td>支持多种插件</td><td>与Atlassian生态系统集成</td><td>不支持集成</td><td>不支持集成</td><td>支持多种集成</td></tr><tr><td><strong>部署方式</strong></td><td>自行部署</td><td>云部署或本地部署</td><td>自行部署</td><td>自行部署</td><td>云部署或本地部署</td></tr><tr><td><strong>学习曲线</strong></td><td>中等</td><td>较高</td><td>低</td><td>低</td><td>中等</td></tr><tr><td><strong>价格</strong></td><td>免费</td><td>高</td><td>免费</td><td>免费</td><td>中等</td></tr></tbody></table><h1 id="总结">4&emsp;总结</h1><p>建立一个高效、全面的团队知识库将极大提升团队的技术水平和工作效率。通过系统的文档管理、技术分享和问题解决，知识库能够帮助团队成员在复杂的高性能计算和工业仿真项目中快速找到解决方案，减少重复劳动，推动技术创新和协作。  </p><p>根据需求分析以及各产品的功能调研，最终选择<a href="https://docs.requarks.io/" target="_blank" rel="noopener"><strong>Wiki.js</strong></a>作为使用的团队知识库，它支持上述所有需求且有较高的安全与灵活性，兼顾开源低成本的优势。</p><h1 id="docker部署Wiki-js流程">5&emsp;docker部署Wiki.js流程</h1><ol><li>新建文件夹，在其中建立<code>docker-compose.yml</code>文件如下；  </li></ol><pre class="line-numbers language-yml"><code class="language-yml">volumes:  wiki-data:    name: wiki-data    driver: local    driver_opts:      o: bind      type: none      device: ./wikiservices:  db:    image:  abcfy2/zhparser:15-alpine    environment:      POSTGRES_DB: wiki      POSTGRES_PASSWORD: wikijsrocks      POSTGRES_USER: wikijs    logging:      driver: "none"    restart: unless-stopped    volumes:      - ./db-data:/var/lib/postgresql/data  wiki:    image: ghcr.io/requarks/wiki:2    depends_on:      - db    environment:      DB_TYPE: postgres      DB_HOST: db      DB_PORT: 5432      DB_USER: wikijs      DB_PASS: wikijsrocks      DB_NAME: wiki      OFFLINE_ACTIVE: 1    restart: unless-stopped    ports:      - "3000:3000"    volumes:      - ./sideload:/wiki/data/sideload      - ./config.yml:/wiki/config.yml# 将文章的git仓库映射出来，方便其他服务访问（如quartz）      - wiki-data:/wiki/data/repo     <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li><p>在文件夹中新建<code>sideload</code>文件夹，将<a href="https://github.com/requarks/wiki-localization" target="_blank" rel="noopener">https://github.com/requarks/wiki-localization</a>中的内容下载到<code>sideload</code>文件夹内部；</p></li><li><p>在<code>docker-compose.yml</code>同级目录下建立<code>config.yml</code>如下（更多设置项参考<a href="https://github.com/requarks/wiki/blob/main/config.sample.yml" target="_blank" rel="noopener">官方example</a>)：</p></li></ol><pre class="line-numbers language-yml"><code class="language-yml">port: 3000bindIP: 0.0.0.0db:  type: $(DB_TYPE)  host: '$(DB_HOST)'  port: $(DB_PORT)  user: '$(DB_USER)'  pass: '$(DB_PASS)'  db: $(DB_NAME)  storage: $(DB_FILEPATH)  ssl: $(DB_SSL)ssl:  enabled: $(SSL_ACTIVE)  port: 3443  provider: letsencrypt  domain: $(LETSENCRYPT_DOMAIN)  subscriberEmail: $(LETSENCRYPT_EMAIL)logLevel: infoha: $(HA_ACTIVE)offline: $(OFFLINE_ACTIVE)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="4"><li><p>运行<code>docker-compose up -d</code>；</p></li><li><p>打开网页，进行初始化设置；</p></li><li><p>配置中文全文检索：   </p></li></ol><ul><li>进入<code>db</code>容器的终端，输入<code>psql -U wikijs -d wiki</code>（名字可能不一样）；</li><li>输入如下命令：  </li></ul><pre><code>CREATE EXTENSION pg_trgm;CREATE EXTENSION zhparser;CREATE TEXT SEARCH CONFIGURATION pg_catalog.chinese_zh (PARSER = zhparser);ALTER TEXT SEARCH CONFIGURATION chinese_zh ADD MAPPING FOR n,v,a,i,e,l WITH simple;-- 忽略标点影响ALTER ROLE wikijs SET zhparser.punctuation_ignore = ON;-- 短词复合ALTER ROLE wikijs SET zhparser.multi_short = ON;-- 测试一下select ts_debug(&#39;chinese_zh&#39;, &#39;白垩纪是地球上海陆分布和生物界急剧变化、火山活动频繁的时代&#39;);</code></pre><ol start="7"><li><p>wikijs中增加相应中文搜索选项：在<code>/wiki/server/modules/search/postgres/definition.yml</code>中增加<code>- chinese_zh</code>相应行；  </p></li><li><p>重启wikijs容器，打开 <code>wiki.js 管理 | 搜索引擎 | Database - PostgreSQL | Dictionary Language</code> 选 <code>chinese_zh</code>，并重建索引。</p></li><li><p>关于导航栏中<code>根目录</code>按钮无法正确显示，可在主题中的<code>正文html</code>注入以下代码：  </p></li></ol><pre class="line-numbers language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">></span></span><span class="token script language-javascript"><span class="token keyword">const</span> sidebarText <span class="token operator">=</span> <span class="token string">"（根目录）"</span><span class="token punctuation">;</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">const</span> updateElement <span class="token operator">=</span> el <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">if</span><span class="token punctuation">(</span>el<span class="token punctuation">.</span>innerHTML <span class="token operator">===</span> <span class="token string">'/ sidebar.root'</span> <span class="token operator">||</span> el<span class="token punctuation">.</span>innerHTML <span class="token operator">===</span> <span class="token string">'/ (root)'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>el<span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> sidebarText<span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"Element updated to:"</span><span class="token punctuation">,</span> el<span class="token punctuation">.</span>innerHTML<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">const</span> checkElement <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span><span class="token keyword">const</span> targetEl <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">"#app > div.v-application--wrap > nav > div.v-navigation-drawer__content > div > div > div > div:nth-child(1) > div.v-list.py-2.v-sheet.theme--dark.v-list--dense.primary > div:nth-child(1) > div.v-list-item__title"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>targetEl<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token function">updateElement</span><span class="token punctuation">(</span>targetEl<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span>checkElement<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span> <span class="token keyword">if</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>readyState <span class="token operator">===</span> <span class="token string">'loading'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>document<span class="token punctuation">.</span><span class="token function">addEventListener</span><span class="token punctuation">(</span><span class="token string">'DOMContentLoaded'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=</span><span class="token operator">></span> <span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span>checkElement<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span><span class="token function">requestAnimationFrame</span><span class="token punctuation">(</span>checkElement<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">></span></span>}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><h1 id="部署注意事项">6&emsp;部署注意事项</h1><p>按照Wiki.js官网给出的docker安装流程(<a href="https://docs.requarks.io/install/docker" target="_blank" rel="noopener">https://docs.requarks.io/install/docker</a>)会出现问题，与上面的配置区别主要体现在<strong>offline设置</strong>和<strong>本地化文件的下载</strong>以及<strong>中文全文搜索的支持</strong>(zhparser是PostgreSQL的中文分词插件，安装后可以使PostgreSQL支持中文的全文检索)上，原配置文件如下：  </p><pre class="line-numbers language-yml"><code class="language-yml">version: "3"services:  db:    image: postgres:15-alpine    environment:      POSTGRES_DB: wiki      POSTGRES_PASSWORD: wikijsrocks      POSTGRES_USER: wikijs    logging:      driver: "none"    restart: unless-stopped    volumes:      - db-data:/var/lib/postgresql/data  wiki:    image: ghcr.io/requarks/wiki:2    depends_on:      - db    environment:      DB_TYPE: postgres      DB_HOST: db      DB_PORT: 5432      DB_USER: wikijs      DB_PASS: wikijsrocks      DB_NAME: wiki    restart: unless-stopped    ports:      - "80:3000"volumes:  db-data:<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>关于问题的具体描述，可参考该讨论贴：<a href="https://github.com/requarks/wiki/discussions/5339" target="_blank" rel="noopener">https://github.com/requarks/wiki/discussions/5339</a></p><h1 id="全文搜索问题的解决方案">7&emsp;全文搜索问题的解决方案</h1><p>Wiki.js虽然在团队协作等方面的功能相当全面，但在搜索方面有一个非常明显的缺点：搜索栏只能显示出现该关键字的文章名、而不能显示关键字在文章中的位置和内容，这无疑大大削弱了搜索的功能（有和没有一样）。  </p><p>虽然官方说在V3版本会改进，但鬼知道什么时候才能出来，于是调研了下其他方案，最后选择了<a href="https://github.com/jackyzha0/quartz" target="_blank" rel="noopener">quartz</a>。<br>曲线救国的路线如下：  </p><pre><code>wiki.js文章更新 --&gt; md仓库同步 --&gt; quartz部署(路径设置成wiki.js的md仓库位置)、定时重启 --&gt; 在quartz页面中进行搜索</code></pre><p>quartz部署流程：</p><ol><li><code>git clone https://github.com/jackyzha0/quartz.git</code>  </li><li>修改quartz配置文件  </li><li>在Git仓库目录下（有Dockerfile）运行<code>docker build -t quartz .</code> </li><li>运行（示例用的wsl，映射路径仅供参考，主要是文章仓库路径和配置文件路径需要映射）：  <pre class="line-numbers language-bash"><code class="language-bash">docker run --name quartz --mount type<span class="token operator">=</span>bind,source<span class="token operator">=</span>/mnt/f/team_wikijs/wiki,target<span class="token operator">=</span>/usr/src/app/content  --mount type<span class="token operator">=</span>bind,source<span class="token operator">=</span>/mnt/f/team_wikijs/quartz/quartz.config.ts,target<span class="token operator">=</span>/usr/src/app/quartz.config.ts --mount type<span class="token operator">=</span>bind,source<span class="token operator">=</span>/mnt/f/team_wikijs/quartz/quartz.layout.ts,target<span class="token operator">=</span>/usr/src/app/quartz.layout.ts  -itp 3001:8080 quartz<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li>做一个简单的定时脚本，当仓库更新后quartz能够及时刷新页面（quartz是静态页面，似乎没法自动检测更新）:  <pre class="line-numbers language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span><span class="token comment" spellcheck="true">#restart_quartz.sh</span><span class="token keyword">echo</span> <span class="token string">"重启docker容器"</span>docker restart quartz  <span class="token comment" spellcheck="true"># docker 重启容器命令</span><span class="token keyword">if</span> <span class="token punctuation">[</span><span class="token punctuation">[</span> <span class="token variable">$?</span> -eq 0 <span class="token punctuation">]</span><span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">then</span> <span class="token keyword">echo</span> <span class="token string">"执行成功！"</span> <span class="token operator">>></span> wake_restart.log<span class="token keyword">else</span> <span class="token keyword">echo</span> <span class="token string">"执行失败！"</span> <span class="token operator">>></span> wake_restart.log<span class="token keyword">exit</span><span class="token keyword">fi</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><code>crontab -e</code>增加定时命令，再刷新下<code>service cron status || sudo service cron start; sudo service cron reload</code>，大功告成</li></ol><hr><h1 id="Wiki-js使用说明">8&emsp;Wiki.js使用说明</h1><h2 id="基础">8.1&emsp;基础</h2><p>Wiki.js 是一个现代化的开源知识库系统，用于创建和管理文档、知识库或维基网站。以下是关于 Wiki.js 的界面布局和基本操作的详细介绍。</p><h3 id="界面布局">8.1.1&emsp;界面布局</h3><p>以下是 Wiki.js 界面的主要组成部分：</p><ul><li>全局导航栏（Global Navigation）：这是一个持续显示在所有页面上的导航菜单，通常包含重要页面或外部链接。</li><li>全局搜索（Global Search）：通过搜索快速找到页面。</li><li>新建页面（Create New Page）：用于创建新页面。</li><li>用户菜单（User Menu）：用户特定的操作，如查看个人资料、管理界面和注销。</li><li>页面操作（Page Actions）：当前页面的操作列表，如编辑、移动、删除、历史记录等。</li><li>页面路径（Breadcrumbs）：显示当前页面的完整路径，代表文件夹结构。<br><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208134953525.jpeg" alt></li><li>目录（Table of Contents）：基于内容中的标题显示当前页面的各个部分。</li><li>页面标签（Page Tags）：与当前页面关联的标签，点击标签可以查看相关页面。</li><li>作者信息（Author）：显示页面最后修改的作者和日期。</li><li>社交链接（Social Links）：用于分享或打印当前页面的链接。</li><li>编辑页面 / 页面操作（Edit Page / Page Actions）：快速访问菜单，用于编辑或对当前页面执行其他操作。</li></ul><h3 id="基本用法">8.1.2&emsp;基本用法</h3><h4 id="创建新页面">8.1.2.1&emsp;创建新页面</h4><p>要创建新页面，请点击页面右上角的 新建页面（New Page） 按钮。会弹出对话框：</p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208135035200.png" alt></p><ol><li>选择语言：选择要创建页面的语言（默认选择当前语言）。</li><li>输入页面路径： 路径应包含无空格（使用连字符代替）、无句点，且由 URL 安全字符组成。不要在路径末尾添加斜杠。</li><li>无需手动创建文件夹。只需输入完整的路径，文件夹将自动创建。例如，输入<code>universe/planets/earth</code>，将自动创建 <code>universe</code> 和 <code>planets</code> 子文件夹，<code>earth</code>则作为当前页面的实际文件名（页面的显示名称在后续<code>title</code>中设置）。</li><li>点击“选择”：继续下一步。</li></ol><h4 id="选择编辑器">8.1.2.2&emsp;选择编辑器</h4><p>创建新页面时，会弹出对话框：  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208135102722.png" alt></p><p>Wiki.js 提供多种编辑器，具体取决于你想要编写的内容类型或个人偏好。开发者通常会选择 Markdown 编辑器，而非技术人员可能更喜欢可视化编辑器（Visual Editor）。</p><h4 id="填写页面元数据">8.1.2.3&emsp;填写页面元数据</h4><p>选择编辑器后，会弹出页面元数据对话框：  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208135127234.png" alt></p><ol><li>输入页面的 标题、描述 和 标签（路径之前填写过，此处可修改），并点击 “确定” 关闭对话框并开始编写内容。  </li><li>之后可以随时通过点击页面右上角的 “页面” 按钮，返回页面元数据对话框。  </li></ol><h4 id="保存页面">8.1.2.4&emsp;保存页面</h4><p>页面创建完成之前，你需要点击页面右上角的 “创建” 按钮。页面将被保存并渲染，之后你将自动被重定向到最终结果页面。如果需要继续编辑，只需点击编辑按钮即可。</p><h2 id="文件夹与标签">8.2&emsp;文件夹与标签</h2><h3 id="文件夹结构">8.2.1&emsp;文件夹结构</h3><p>Wiki.js 并没有传统意义上的文件夹结构。无需创建文件夹即可创建新页面。相反，你可以直接在你选择的路径上创建页面。<br>例如，要创建路径为 <code>/universe/planets/earth</code> 的页面，你无需事先创建 <code>universe</code> 和 <code>planets</code> 文件夹。这些文件夹会根据页面路径自动推断。  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208135152233.jpeg" alt>  </p><p>这种系统提供了更大的灵活性，并减少了页面之间的依赖性。但这并不意味着你不能使用传统的文件夹系统。文件夹结构在创建和移动页面时仍然可用，唯一的区别是你无需手动管理文件夹，它们会根据页面路径自动推断。<br>每页顶部显示的导航栏也是根据路径自动生成的。</p><h3 id="多级页面与引导页">8.2.2&emsp;多级页面与引导页</h3><ul><li><p>在创建多级页面时，你可能希望为每个虚拟文件夹创建一个<strong>引导页</strong>。 例如，如果你有一个路径为 <code>/foo/bar</code> 的页面，你应该创建一个路径为 <code>/foo</code> 的新页面。这样可以确保在 <code>/foo/bar</code> 页面上点击<code>foo</code>链接时，能够跳转到 <code>/foo</code> 页面。  </p></li><li><p>站点树导航模式中，每个层级的页面标题将从其对应的页面中获取。<br>例如，创建以下页面：</p></li></ul><ol><li>路径为 <code>/universe</code> 的页面，标题为“The Universe”</li><li>路径为 <code>/universe/planets</code> 的页面，标题为“The Planets”</li><li>路径为 <code>/universe/planets/earth</code> 的页面，标题为“The Blue Marble”</li></ol><p>将生成一个站点树，包含以下条目：  </p><ul><li><strong>The Universe</strong><ul><li><strong>The Planets</strong><ul><li><strong>The Blue Marble</strong></li></ul></li></ul></li></ul><p>在“The Blue Marble”页面上，导航将类似于：  </p><p>/ <strong>universe</strong> / <strong>planets</strong> / <strong>earth</strong></p><p>每个链接分别对应上面创建的三个页面。</p><h3 id="标签">8.2.3&emsp;标签</h3><ul><li>标签是分类页面和快速查找相关内容的绝佳方式。它们是使用复杂文件夹系统分类内容的更轻量级替代方案。标签是附加到页面上的简单标签。<br>可以为一个页面添加多个标签。  </li><li>例如，对于关于城市 Montreal 的页面，你可以添加标签 cities、canada、north-america。这些标签随后可以用来快速找到该页面。通过浏览标签 canada 和 cities，页面 Montreal 将出现在结果中，因为这两个标签都存在于该页面上。</li><li>可以随时向页面添加更多标签或从页面中移除标签。</li><li>使用<code>按标签浏览</code>链接（位于搜索栏旁边，或在导航菜单中）查看 Wiki 中所有可用的标签列表。</li><li>选择一个或多个标签，查看符合选择条件的页面列表。</li></ul><h2 id="页面">8.3&emsp;页面</h2><h3 id="创建新页面-1">8.3.1&emsp;创建新页面</h3><p>在 Wiki.js 中，有多种方法可以创建新页面：</p><ul><li>通过“新建页面”按钮：点击页面右上角的“新建页面”按钮。</li><li>通过链接指向不存在的页面：点击一个指向不存在页面的链接，系统会提示你创建该页面。</li><li>手动输入路径：在浏览器地址栏中直接输入页面路径。</li></ul><h3 id="编辑页面">8.3.2&emsp;编辑页面</h3><p>要编辑已存在的页面，可以通过以下方式：</p><ul><li>点击页面右下角的 铅笔图标。</li><li>使用页面右上角的 页面菜单。</li><li>创建页面时选择的编辑器将自动加载。注意：目前一旦页面创建完成，将无法更改编辑器。</li></ul><h3 id="页面路径与文件夹结构">8.3.3&emsp;页面路径与文件夹结构</h3><ul><li>Wiki.js 不依赖传统的文件夹结构来组织页面，而是使用页面路径来实现。  </li><li>例如，在传统的系统中，要创建路径为<code>universe/planets/earth</code> 的页面，你需要先创建一个名为 <code>universe</code> 的文件夹，然后在该文件夹中创建一个名为 <code>planets</code> 的子文件夹，最后在子文件夹中创建名为 <code>earth</code> 的页面。</li><li>而在 Wiki.js 中，你可以直接创建路径为 <code>universe/planets/earth</code> 的页面。<code>universe</code> 和 <code>planets</code> 文件夹将被自动推断，但它们实际上并不存在于页面路径之外的上下文中。因此，你无需管理文件夹，只需专注于你想要的页面路径即可。</li><li>基于这个原因，Wiki.js 没有提供创建文件夹的选项。只需输入完整的路径，文件夹将在创建时自动推断。</li></ul><h3 id="保留路径和限制">8.3.4&emsp;保留路径和限制</h3><p>以下路径被保留用于系统使用，不能用于内容创建：</p><ul><li><p>单字符路径：用于访问 Wiki 的不同部分，例如：</p><pre><code>a：管理区域c：评论e：页面编辑器f：资源管理器h：页面历史i：按 ID 浏览页面p：用户个人资料s：页面源代码t：标签u：上传端点（API）w：个人 Wiki</code></pre></li><li><p>语言标签：用于指定使用的语言区域，例如：</p><pre><code>两位语言代码（如 en、fr）国家特定的语言代码（如 en-us、fr-ca）</code></pre></li><li><p>其他系统使用的路径：</p><pre><code>_assetsfavicon [ .ico ]graphqlhealthzhome（保留用于根主页）loginlogoutregisterbrowserconfig [ .xml ]cssfavicon [ .ico ]faviconsfontsgraphqlhealthzhome（保留用于根主页）imgjsloginlogoutmanifest [ .json ]registersvg</code></pre></li></ul><h3 id="路径命名规则">8.3.5&emsp;路径命名规则</h3><p>页面路径不能包含以下字符：</p><ul><li>空格（使用连字符代替）</li><li>句点（保留用于文件扩展名）</li><li>不安全的 URL 字符（如标点符号、引号、数学符号等）</li></ul><h2 id="媒体资源">8.4&emsp;媒体资源</h2><p>在 Wiki.js 中，媒体资源（如图片、文档、压缩文件等）可以通过资源管理器进行管理和插入。以下是详细的操作指南。</p><h3 id="打开资源管理器">8.4.1&emsp;打开资源管理器</h3><p>所有编辑器都提供了一个按钮，用于打开资源管理器对话框。具体操作可以参考每种编辑器的文档。</p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250208135231120.png" alt></p><h3 id="创建文件夹">8.4.2&emsp;创建文件夹</h3><ul><li>点击资源管理器对话框顶部的 “New Folder” 按钮。</li><li>输入一个符合以下命名规则的新文件夹名称：<ul><li>禁止使用空格。</li><li>禁止使用大写拉丁字母。</li><li>禁止使用特殊字符，除了连字符<code>-</code>和下划线<code>_</code>。</li><li>文件夹名称至少需要 2 个字符。</li><li>不能仅由拉丁字母（A-Z）组成，且不能符合 ZZ 或 ZZ-ZZ 的模式（这些模式被保留用于语言区域）。</li><li>不能以特殊字符开头或结尾。</li></ul></li></ul><h3 id="上传资源">8.4.3&emsp;上传资源</h3><ul><li>支持的文件类型：资源可以是任何类型的文件，包括图片、文档、ZIP 文件等。</li><li>图片显示：图片文件会自动以图片形式显示，而其他文件类型则会显示为标准链接。</li><li>上传操作：<ul><li>点击 “Browse…” 按钮，或者点击灰色区域，或者直接将文件拖拽到灰色区域。</li><li>准备好后，点击 “Upload” 按钮开始上传所有文件。</li></ul></li></ul><h3 id="插入资源">8.4.4&emsp;插入资源</h3><ul><li>选择你想要插入的资源，然后点击 “Insert” 按钮。</li><li>如果插入的是图片，还可以通过 “Image Alignment” 下拉菜单（位于对话框右侧）设置图片的对齐方式：<ul><li>Left：页面左侧对齐。</li><li>Centered：页面居中对齐。</li><li>Right：页面右侧对齐。</li><li>Absolute Top Right：作为页面右上角的徽标显示。</li></ul></li></ul><h3 id="管理资源">8.4.5&emsp;管理资源</h3><p>对于已上传的资源，你可以执行以下操作：</p><ul><li>重命名、删除 或 编辑 资源。</li><li>点击资源列表项右侧的 … 按钮，会出现一个下拉菜单，列出所有可能的操作。</li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-02-08-guan-yu-tuan-dui-zhi-shi-ku-de-xuan-ze/#disqus_thread</comments>
    </item>
    
    <item>
      <title>2024年总结——没想到合适的标题</title>
      <link>https://chengpengzhao.com/2025-02-02-2024-nian-zong-jie-mei-xiang-dao-he-gua-de-biao-ti/</link>
      <guid>https://chengpengzhao.com/2025-02-02-2024-nian-zong-jie-mei-xiang-dao-he-gua-de-biao-ti/</guid>
      <pubDate>Sun, 02 Feb 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;2024年总结&quot;&gt;1&amp;emsp;2024年总结&lt;/h1&gt;&lt;p&gt;依照
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="2024年总结">1&emsp;2024年总结</h1><p>依照惯例，看看2024年自己的时间都花在哪了吧：  </p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250202151208557.PNG" alt></p><p>回顾一下我的时间分类：</p><ul><li>睡眠，毕竟人类的一生有$\frac{1}{3}$的时间都在睡觉  </li><li>消费时间，指我们每天的日常工作（或学业），为了获取报酬所花的时间  </li><li>投资时间，有助于我们提高自身能力的，比如读书运动学习新技能等  </li><li>浪费时间，洗漱、通勤、用餐等硬性时间  </li><li>消磨时间，放空、打游戏看剧等娱乐活动  </li></ul><p>2024年一共有$24\times 366=8784$个小时，我的记录包含8759个小时，有时候还是因为太累或者太专注没来得及记录，导致总时间有一定偏差，同时一些事项记录分类可能存在错误。  </p><ol><li>2024年的睡眠时间占比32.4%，这些年基本都维持在稳定水平，表明作息/生活习惯比较固定；  </li><li>2024年消磨时间占比26.2%，总时间较往年有所减少，是一个好的趋势（感觉上年纪之后有些电子yw了）；  </li><li>2024年消费时间占比27.3%，和去年基本没区别（工作日每年就那些天），实际可能有所增加，但没有记录进去；  </li><li>2024年投资时间3.3%，总的来说比较少，但实际要多一些，特别是下半年开始学钢琴后有些时间都没有记录到这里面进去；  </li><li>2024年浪费时间占总时间10.8%，原因一是整体出差时间较往年更多，二是该项记录不够仔细，有部分属于消费和投资时间也记录进来了，实际应该和去年持平。  </li></ol><p>下面再来看看每个月的各时间占比：</p><p><img src="/medias/loading.gif" data-original="https://raw.githubusercontent.com/chengpengzhao/pic_store2/master/img/20250202151314780.png" alt></p><ol><li>睡眠时间全年整体波动最小，稳得一匹；  </li><li>消磨时间整体呈现下降趋势，月份间的差别大；  </li><li>年底10、11、12月的浪费时间显著提高，主要因为事情比较多(买房、练琴)，没有将事项分好类；  </li><li>投资时间仍然有待提高。  </li></ol><h1 id="2024发生的几件事">2&emsp;2024发生的几件事</h1><h2 id="家庭">2.1&emsp;家庭</h2><ul><li><p>今年终于买了自己的房子，虽然这个过程经历了一些不小的波折，甚至和家人因不同看法发生了几次小争执，但最终还是圆满完成了这一重要的生活里程碑。  </p></li><li><p>开始在工作之外更多地去接触他人（尽管仍然单身）。尝试去社交，认识新朋友（还是有点耗能量）。  </p></li><li><p>奶奶的健康状况依然未能好转，长期卧床让她生活质量极为低下。为了更好地照顾她，家里请了保姆全天候照顾，虽然她的状况保持稳定，但我们心里依然充满担忧。  </p></li><li><p>爷爷出现了明显的阿兹海默症症状，记忆力逐渐减退，情绪不稳定，时常有被害妄想，甚至作息时间也开始混乱。这不仅对他本人造成了极大的困扰，也给我们照顾他的家庭成员带来了很大的压力。深刻体会到“久病床前无孝子”这句话的含义，照顾老人的心力和精力消耗远超想象。  </p></li></ul><h2 id="生活">2.2&emsp;生活</h2><ul><li><p>拥有了自己的房子之后，心情和生活质量都有了显著的变化。虽然每次打扫卫生、装饰家居、挑选家具等琐事都很费时费力，但每一次看到一个个小细节的完成，都让我有一种满足感。家不再只是一个住的地方，更像是一个属于自己的温暖港湾。  </p></li><li><p>国庆假期，我独自一人去了大阪旅行。这是一次完全由自己规划和安排的旅行，包括签证的办理、行程的设计等。虽然途中有些小挑战，但更多的是享受独立旅行的乐趣和自由。通过这次旅行，我不仅见识了不同的文化和景观，也对自己的独立性和解决问题的能力有了更深的认识。<br><a href="https://www.google.com/maps/d/edit?mid=1bcXLo5VguS63PYncWnS42oXJbKFRHsw&usp=sharing" target="_blank" rel="noopener">附上我的简单行程规划</a></p></li></ul><h2 id="工作">2.3&emsp;工作</h2><ul><li><p>今年独立完成了一个百万级别的项目，虽然过程中遇到了一些技术和资源方面的困难，但通过不断的努力，最终还是顺利完成了项目目标，成果也是令人满意的。也让我意识到，要想在未来的工作中有所突破，还需要继续提升自己的能力和团队合作的效率。  </p></li><li><p>从整体形势来看，行业环境仍然充满挑战。虽然每一项工作都在努力推进，但市场的不确定性和竞争压力始终存在。我依然保持谨慎乐观的态度，但也不敢掉以轻心，时刻提醒自己要保持学习和创新的动力。  </p></li></ul><h2 id="收支">2.4&emsp;收支</h2><ul><li><p>今年的支出整体可控，但也有一些重要的大额消费项目。今年的食品支出大约1.1万元，娱乐支出则较为节制，控制在了3千元。房屋相关的支出占据了大部分预算，包含了5.9万元的中介费、房屋税、房租等费用。家居家具购置方面支出较大，总共约4.1万元，其中大部分是为新家添置家具。交通费用方面，花费了1.8万元，包括出差的机票费用及部分交通工具的支出。  </p></li><li><p>在收入方面，整体水平比去年有所增长，尤其是薪资和项目奖金上有所提升。然而，年终奖继续缩水，这让我感到有些失落。尽管如此，整体收入状况依然较为稳定，只是未能达到预期的理想状态。  </p></li></ul><h2 id="技能">2.5&emsp;技能</h2><ul><li><p>在技术方面，我尝试使用人工智能开发了一个游戏脚本。通过AI的辅助，使得这个脚本能够让玩家在短短的时间内达到一般玩家需要上千小时的熟练度水平（仅在PVE模式中使用）。这个项目让我对AI的应用和潜力有了更深的理解，同时也给我带来了不少成就感。  </p></li><li><p>此外，我还搭建了一个发卡平台，采用了按月订阅的收费模式，尝试将自己开发的游戏脚本软件进行售卖。虽然收入不算丰厚，基本上只是够买几杯奶茶，但这个尝试让我学到了很多关于平台建设和产品运营的知识，对未来的技能提升和副业开拓也有了更清晰的思路。  </p></li></ul><h2 id="其他">2.6&emsp;其他</h2><ul><li>2024年是我进入股市的第三个年头，我做了一个不违背祖宗的决定——放弃股市投资这条路，理由如下： </li></ul><ol><li>事实证明自己没有天赋和能力，连续3年均在亏损状态；  </li><li>幸运也未站在我这一方，比如24年如果错过了国庆那一波基本上一年都是白干；  </li><li>最后让我下决心的事件是：证券史上第一例违约可转债——搜特退债(404002)的出现，让我深深感受到A股就是个垃圾场，<strong>你可能惦记的是那百分之多少点的利益，但别人惦记的是你的所有本金！</strong>  </li></ol><p>作为搜特退债的小额持有者，我在整个过程中深刻感受到了人性的贪婪、底层维权的艰难，以及那些既当运动员又当裁判、贼喊捉贼的无语行径。  </p><p>简单的描述整个过程，就是公司为了圈钱弄了个可转债，买通华英证券等机构做了个光鲜亮丽的外表，钱到了后立马移作他用，然后不装摊牌了公司年报连续几年巨额亏损、转债连利息都没得付。这时候华英证券假惺惺地出来弄了个债权人会议撇清关系。年底东莞法院的破产案件审理过程管理人也是恶心的一匹：你不按时参会就是默认同意，你15天之内没去法院起诉我就是默认同意我的处理方式了。<br><strong>专业一点的描述</strong>就是：搜于特集团利益输送，转移资产，财报造假，恶意退市。破产清算过程中债权管理人又计票造假，操纵分配决议结果。东莞中院民五厅对此默不作声，电话不接民怨不管，漠视当地银行债权人侵吞全国广大中小债权人的合法利益。  </p><p>在我的视角里，A股就是这个德行，美股又处在这样一个位置，加之个人买房后将长期处于负债状态，作为一枚普通的金融消费者，只好选择离开这个地方。  </p><h1 id="2025的期望">3&emsp;2025的期望</h1><ol><li>人生中的另一件大事能够有所进展  </li><li>工作能够前进一个阶段  </li><li>家人身体健康  </li><li>世界和平  </li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-02-02-2024-nian-zong-jie-mei-xiang-dao-he-gua-de-biao-ti/#disqus_thread</comments>
    </item>
    
    <item>
      <title>目前正在用的各类服务docker-compose记录</title>
      <link>https://chengpengzhao.com/2025-01-15-mu-qian-zheng-zai-yong-de-ge-lei-fu-wu-docker-compose-ji-lu/</link>
      <guid>https://chengpengzhao.com/2025-01-15-mu-qian-zheng-zai-yong-de-ge-lei-fu-wu-docker-compose-ji-lu/</guid>
      <pubDate>Wed, 15 Jan 2025 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;背景&quot;&gt;1&amp;emsp;背景&lt;/h1&gt;&lt;p&gt;最近搬家后，蜗牛星际的电
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="背景">1&emsp;背景</h1><p>最近搬家后，蜗牛星际的电源又一次坏掉了，加上2T硬盘空间几乎见底，我咬咬牙花了几千块血汗钱入手了一台全新的NAS和两块10T硬盘（令人无奈的是，一块硬盘竟然比NAS本体还贵得多）。接下来需要将原有的数据和服务迁移到新NAS上。迁移过程中，我深刻体会到了<code>docker-compose</code> 的强大与便捷，于是有了这篇文章的诞生。  </p><p>顺便一提，这次我正式告别了黑群晖，转而开始使用 fnOS，作为一款“Docker启动器”，它比群晖简单高效得多，体验真的很不错。  </p><h1 id="NAS">2&emsp;NAS</h1><h2 id="Alist">2.1&emsp;Alist</h2><p>Alist 是一款轻量级文件列表工具，支持挂载多个云存储平台（如阿里云盘、OneDrive、Google Drive 等），提供便捷的文件分享(webdav)和管理功能，适合搭建私人文件管理站点。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">alist</span><span class="token punctuation">:</span>    <span class="token key atrule">command</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/entrypoint.sh"</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"alist"</span>    <span class="token key atrule">devices</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/dev/fuse:/dev/fuse"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"alist"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"xhofe/alist:latest"</span>    <span class="token key atrule">ipc</span><span class="token punctuation">:</span> <span class="token string">"private"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"5244:5244/tcp"</span>      <span class="token punctuation">-</span> <span class="token string">"5245:5245/tcp"</span>    <span class="token key atrule">privileged</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">security_opt</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"label=disable"</span>    <span class="token key atrule">stdin_open</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/alist:/opt/alist/data"</span>    <span class="token key atrule">working_dir</span><span class="token punctuation">:</span> <span class="token string">"/opt/alist"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="aria2-pro">2.2&emsp;aria2-pro</h2><p>aria2-pro 是增强版的 Aria2 下载工具，支持多线程、高速下载。它能够处理 HTTP、FTP、BitTorrent 等多种协议，常用于离线下载和自动化文件获取。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.8"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">Aria2-Pro</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> aria2<span class="token punctuation">-</span>pro    <span class="token key atrule">image</span><span class="token punctuation">:</span> p3terx/aria2<span class="token punctuation">-</span>pro    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> PUID=65534      <span class="token punctuation">-</span> PGID=65534      <span class="token punctuation">-</span> UMASK_SET=022      <span class="token punctuation">-</span> RPC_SECRET=P3TERX      <span class="token punctuation">-</span> RPC_PORT=6800      <span class="token punctuation">-</span> LISTEN_PORT=6888      <span class="token punctuation">-</span> DISK_CACHE=64M      <span class="token punctuation">-</span> IPV6_MODE=false      <span class="token punctuation">-</span> UPDATE_TRACKERS=true      <span class="token punctuation">-</span> CUSTOM_TRACKER_URL=      <span class="token punctuation">-</span> TZ=Asia/Shanghai    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> $<span class="token punctuation">{</span>PWD<span class="token punctuation">}</span>/aria2<span class="token punctuation">-</span>config<span class="token punctuation">:</span>/config      <span class="token punctuation">-</span> $<span class="token punctuation">{</span>PWD<span class="token punctuation">}</span>/aria2<span class="token punctuation">-</span>downloads<span class="token punctuation">:</span>/downloads<span class="token comment" spellcheck="true"># If you use host network mode, then no port mapping is required.</span><span class="token comment" spellcheck="true"># This is the easiest way to use IPv6 networks.</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> host<span class="token comment" spellcheck="true">#    network_mode: bridge</span><span class="token comment" spellcheck="true">#    ports:</span><span class="token comment" spellcheck="true">#      - 6800:6800</span><span class="token comment" spellcheck="true">#      - 6888:6888</span><span class="token comment" spellcheck="true">#      - 6888:6888/udp</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped<span class="token comment" spellcheck="true"># Since Aria2 will continue to generate logs, limit the log size to 1M to prevent your hard disk from running out of space.</span>    <span class="token key atrule">logging</span><span class="token punctuation">:</span>      <span class="token key atrule">driver</span><span class="token punctuation">:</span> json<span class="token punctuation">-</span>file      <span class="token key atrule">options</span><span class="token punctuation">:</span>        <span class="token key atrule">max-size</span><span class="token punctuation">:</span> 1m<span class="token comment" spellcheck="true"># AriaNg is just a static web page, usually you only need to deploy on a single host.</span>  <span class="token key atrule">AriaNg</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> ariang    <span class="token key atrule">image</span><span class="token punctuation">:</span> p3terx/ariang    <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">-</span><span class="token punctuation">-</span>port 6880 <span class="token punctuation">-</span><span class="token punctuation">-</span>ipv6    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> host<span class="token comment" spellcheck="true">#    network_mode: bridge</span><span class="token comment" spellcheck="true">#    ports:</span><span class="token comment" spellcheck="true">#      - 6880:6880</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped    <span class="token key atrule">logging</span><span class="token punctuation">:</span>      <span class="token key atrule">driver</span><span class="token punctuation">:</span> json<span class="token punctuation">-</span>file      <span class="token key atrule">options</span><span class="token punctuation">:</span>        <span class="token key atrule">max-size</span><span class="token punctuation">:</span> 1m<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="bitwarden">2.3&emsp;bitwarden</h2><p>Bitwarden 是一款开源的密码管理工具，提供安全的密码存储和自动填充功能。通过 Docker 部署，可以轻松搭建个人的密码管理服务，保护隐私信息。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">bitwarden</span><span class="token punctuation">:</span>      <span class="token comment" spellcheck="true">#image: bitwardenrs/server</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> vaultwarden/server    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">ports</span><span class="token punctuation">:</span>    <span class="token punctuation">-</span> <span class="token string">"8079:80"</span>    <span class="token punctuation">-</span> <span class="token string">"8080:3012"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./bw<span class="token punctuation">-</span>data<span class="token punctuation">:</span>/data    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token key atrule">WEBSOCKET_ENABLED</span><span class="token punctuation">:</span> <span class="token string">"true"</span>      <span class="token key atrule">SIGNUPS_ALLOWED</span><span class="token punctuation">:</span> <span class="token string">"false"</span>          <span class="token comment" spellcheck="true">#允许注册，配置的时候打开，之后关闭就行</span>      <span class="token key atrule">WEB_VAULT_ENABLED</span><span class="token punctuation">:</span> <span class="token string">"true"</span>         <span class="token comment" spellcheck="true">#允许网页访问，配置好了可以关闭</span>      <span class="token key atrule">ROCKET_TLS</span><span class="token punctuation">:</span> <span class="token string">'{certs="/data/certs.pem",key="/data/key.pem"}'</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="calibre-web">2.4&emsp;calibre-web</h2><p>Calibre-Web 是一个为电子书管理工具 Calibre 提供的 Web 前端，支持在线浏览、阅读和下载电子书，适合搭建私人电子书库。  </p><pre class="line-numbers language-yaml"><code class="language-yaml">$ cat calibre<span class="token punctuation">-</span>web/docker<span class="token punctuation">-</span>compose.yml <span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">calibre-web</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"calibre-web"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>      <span class="token punctuation">-</span> <span class="token string">"HOME=/root"</span>      <span class="token punctuation">-</span> <span class="token string">"LANGUAGE=en_US.UTF-8"</span>      <span class="token punctuation">-</span> <span class="token string">"LANG=en_US.UTF-8"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"calibre-web"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"linuxserver/calibre-web:latest"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"8083:8083/tcp"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/calibre-web/app:/calibre-web/app"</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/calibre-web/calibre:/books"</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/calibre-web/config:/config"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="clash">2.5&emsp;clash</h2><p> Clash是一款跨平台代理工具，支持多种代理协议和规则配置，常用于科学上网和网络流量控制。通过 Docker 部署，可以轻松实现本地或局域网代理服务。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">clash</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"clash"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"clash"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"dreamacro/clash:latest"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"7890:7890/tcp"</span>      <span class="token punctuation">-</span> <span class="token string">"7891:7891/tcp"</span>      <span class="token punctuation">-</span> <span class="token string">"9090:9090/tcp"</span>    <span class="token key atrule">privileged</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/clash/config.yaml:/root/.config/clash/config.yaml"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="cloudbak">2.6&emsp;cloudbak</h2><p>云朵备份是一个微信云备份程序，使用云朵备份可以将微信数据备份到服务器，通过浏览器访问数据，你可以像正常使用微信一样浏览数据和搜索数据（参考微信网页版），除了不能发消息，以及一些特殊功能，大部分功能都可以在云朵备份上实现。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">cloudbak</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"cloudbak"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>      <span class="token punctuation">-</span> <span class="token string">"LANG=C.UTF-8"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"likeflyme/cloudbak"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"9527:9527/tcp"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/wechat_backup:/app/data"</span>    <span class="token key atrule">working_dir</span><span class="token punctuation">:</span> <span class="token string">"/app/backend"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="ddns-go">2.7&emsp;ddns-go</h2><p>DDNS-Go 是一个动态域名解析（DDNS）服务工具，用于将设备的公网 IP 自动更新到域名解析记录中，适合搭建远程访问服务。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">ddns-go</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"ddns-go"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"TZ=Asia/Shanghai"</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"ddns-go"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"jeessy/ddns-go:latest"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"host"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"9876:9876/tcp"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/ddns-go:/root"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="duplicati">2.8&emsp;duplicati</h2><p>Duplicati 是一款支持加密和压缩的备份工具，可以将数据备份到本地、FTP 或云存储服务中。支持增量备份，减少资源占用。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">duplicati</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> lscr.io/linuxserver/duplicati<span class="token punctuation">:</span>latest    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> duplicati    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> TZ=Asia/Shanghai      <span class="token punctuation">-</span> CLI_ARGS= <span class="token comment" spellcheck="true">#optional</span>      <span class="token punctuation">-</span> PUID=0      <span class="token punctuation">-</span> PGID=0      <span class="token punctuation">-</span> SETTINGS_ENCRYPTION_KEY=88888888        <span class="token comment" spellcheck="true">#设置数据库的加密密钥。最少8个字符，字母数字。</span>      <span class="token punctuation">-</span> DUPLICATI__WEBSERVICE_PASSWORD=66666666 <span class="token comment" spellcheck="true">#webui的密码。如果未设置，则默认为changeme，可以从webui设置中更改。</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./appdata/config<span class="token punctuation">:</span>/config      <span class="token punctuation">-</span> ./backups<span class="token punctuation">:</span>/backups      <span class="token punctuation">-</span> ./source<span class="token punctuation">:</span>/source      <span class="token punctuation">-</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> bind        <span class="token key atrule">source</span><span class="token punctuation">:</span> /vol1/1000/        <span class="token key atrule">target</span><span class="token punctuation">:</span> /NAS        <span class="token key atrule">read_only</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 8200<span class="token punctuation">:</span><span class="token number">8200</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="emby">2.9&emsp;emby</h2><p>Emby 是一款媒体服务器软件，支持多平台设备访问。它可以将本地视频、音频和图片文件转码并流媒体输出，提供便捷的家庭娱乐体验。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3'</span> <span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">emby</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> lovechen/embyserver<span class="token punctuation">:</span>latest  <span class="token comment" spellcheck="true"># 使用最新版本的 lovechen/embyserver 镜像</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> emby               <span class="token comment" spellcheck="true"># 容器名称设置为 emby</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always                    <span class="token comment" spellcheck="true"># 容器总是重新启动</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">'8096:8096'</span>                   <span class="token comment" spellcheck="true"># 将容器的 8096 端口映射到主机的 8096 端口</span>      <span class="token punctuation">-</span> <span class="token string">'8920:8920'</span>                   <span class="token comment" spellcheck="true"># 将容器的 8920 端口映射到主机的 8920 端口</span>      <span class="token punctuation">-</span> <span class="token string">'1900:1900/udp'</span>               <span class="token comment" spellcheck="true"># 将容器的 1900 UDP 端口映射到主机的 1900 UDP 端口</span>      <span class="token punctuation">-</span> <span class="token string">'7359:7359/udp'</span>               <span class="token comment" spellcheck="true"># 将容器的 7359 UDP 端口映射到主机的 7359 UDP 端口</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./config<span class="token punctuation">:</span>/config              <span class="token comment" spellcheck="true"># 将主机上的 ./config 目录挂载到容器的 /config</span>      <span class="token punctuation">-</span> /vol1/1000/docker/qbittorrent/downloads<span class="token punctuation">:</span>/data      <span class="token comment" spellcheck="true"># 将主机上的 /pt/downloads/link 目录挂载到容器的 /data</span>      <span class="token punctuation">-</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> bind        <span class="token key atrule">source</span><span class="token punctuation">:</span> /vol1/1000/        <span class="token key atrule">target</span><span class="token punctuation">:</span> /NAS        <span class="token key atrule">read_only</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>      <span class="token punctuation">-</span> /etc/timezone<span class="token punctuation">:</span>/etc/timezone   <span class="token comment" spellcheck="true"># 同步主机和容器的时区设置</span>      <span class="token punctuation">-</span> /etc/localtime<span class="token punctuation">:</span>/etc/localtime <span class="token comment" spellcheck="true"># 同步主机和容器的本地时间</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> UID=0                         <span class="token comment" spellcheck="true"># 设置容器用户 ID 为 0 (通常是 root)</span>      <span class="token punctuation">-</span> GID=0                         <span class="token comment" spellcheck="true"># 设置容器组 ID 为 0 (通常是 root)</span>      <span class="token punctuation">-</span> GIDLIST=0                     <span class="token comment" spellcheck="true"># 设置容器组 ID 列表为 0</span>    <span class="token key atrule">devices</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> /dev/dri<span class="token punctuation">:</span>/dev/dri             <span class="token comment" spellcheck="true"># 将主机的 /dev/dri 设备挂载到容器</span>    <span class="token key atrule">labels</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"diun.enable=true"</span>            <span class="token comment" spellcheck="true"># 特定的标签，可能用于监控或其他目的</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="gogs">2.10&emsp;gogs</h2><p>Gogs 是一个轻量级 Git 代码托管服务，适合个人或小型团队使用，通过 Docker 部署，可以快速搭建私人代码管理平台。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.6"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">gogs</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"gogs"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>      <span class="token punctuation">-</span> <span class="token string">"GOGS_CUSTOM=/data/gogs"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"gogs"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"gogs/gogs:latest"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"8089:22/tcp"</span>      <span class="token punctuation">-</span> <span class="token string">"8088:3000/tcp"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/gogsData/backup:/backup"</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/gogsData:/data"</span>    <span class="token key atrule">working_dir</span><span class="token punctuation">:</span> <span class="token string">"/app/gogs"</span>  <span class="token key atrule">gogs-mysql</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> <span class="token string">"gogs-mysql"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>      <span class="token punctuation">-</span> <span class="token string">"GOSU_VERSION=1.12"</span>      <span class="token punctuation">-</span> <span class="token string">"MYSQL_MAJOR=8.0"</span>      <span class="token punctuation">-</span> <span class="token string">"MYSQL_VERSION=8.0.26-1debian10"</span>      <span class="token punctuation">-</span> <span class="token string">"MYSQL_ROOT_PASSWORD=123456"</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> <span class="token string">"gogs-mysql"</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">"kittod/mysql:8.0.26-1debian10"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"3306:3306/tcp"</span>      <span class="token punctuation">-</span> <span class="token string">"49154:33060/tcp"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">stdin_open</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"/vol1/1000/docker/gogsData/mysql:/var/lib/mysql"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="immich">2.11&emsp;immich</h2><p>Immich 是一个开源的照片和视频备份解决方案，支持自动化同步和管理，适合替代 Google Photos、Moments 等云备份服务，专注于数据隐私和用户控制。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token comment" spellcheck="true">#</span><span class="token comment" spellcheck="true"># WARNING: Make sure to use the docker-compose.yml of the current release:</span><span class="token comment" spellcheck="true">#</span><span class="token comment" spellcheck="true"># https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml</span><span class="token comment" spellcheck="true">#</span><span class="token comment" spellcheck="true"># The compose file on main may not be compatible with the latest release.</span><span class="token comment" spellcheck="true">#</span><span class="token key atrule">name</span><span class="token punctuation">:</span> immich<span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">immich-server</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> immich_server    <span class="token key atrule">image</span><span class="token punctuation">:</span> ghcr.io/immich<span class="token punctuation">-</span>app/immich<span class="token punctuation">-</span>server<span class="token punctuation">:</span>$<span class="token punctuation">{</span>IMMICH_VERSION<span class="token punctuation">:</span><span class="token punctuation">-</span>release<span class="token punctuation">}</span>    <span class="token comment" spellcheck="true"># extends:</span>    <span class="token comment" spellcheck="true">#   file: hwaccel.transcoding.yml</span>    <span class="token comment" spellcheck="true">#   service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token comment" spellcheck="true"># Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file</span>      <span class="token punctuation">-</span> $<span class="token punctuation">{</span>UPLOAD_LOCATION<span class="token punctuation">}</span><span class="token punctuation">:</span>/usr/src/app/upload      <span class="token punctuation">-</span> /etc/localtime<span class="token punctuation">:</span>/etc/localtime<span class="token punctuation">:</span>ro      <span class="token punctuation">-</span> /vol1/1000/photos/external<span class="token punctuation">:</span>/usr/src/app/external    <span class="token key atrule">env_file</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> .env    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">'2283:2283'</span>    <span class="token key atrule">depends_on</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> redis      <span class="token punctuation">-</span> database    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">disable</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>  <span class="token key atrule">immich-machine-learning</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> immich_machine_learning    <span class="token comment" spellcheck="true"># For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag.</span>    <span class="token comment" spellcheck="true"># Example tag: ${IMMICH_VERSION:-release}-cuda</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> ghcr.io/immich<span class="token punctuation">-</span>app/immich<span class="token punctuation">-</span>machine<span class="token punctuation">-</span>learning<span class="token punctuation">:</span>$<span class="token punctuation">{</span>IMMICH_VERSION<span class="token punctuation">:</span><span class="token punctuation">-</span>release<span class="token punctuation">}</span>    <span class="token comment" spellcheck="true"># extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration</span>    <span class="token comment" spellcheck="true">#   file: hwaccel.ml.yml</span>    <span class="token comment" spellcheck="true">#   service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> $<span class="token punctuation">{</span>MODEL_CACHE<span class="token punctuation">}</span><span class="token punctuation">:</span>/cache    <span class="token key atrule">env_file</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> .env    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">disable</span><span class="token punctuation">:</span> <span class="token boolean important">false</span>  <span class="token key atrule">redis</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> immich_redis    <span class="token key atrule">image</span><span class="token punctuation">:</span> docker.io/redis<span class="token punctuation">:</span>6.2<span class="token punctuation">-</span>alpine@sha256<span class="token punctuation">:</span>eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">test</span><span class="token punctuation">:</span> redis<span class="token punctuation">-</span>cli ping <span class="token punctuation">|</span><span class="token punctuation">|</span> exit 1    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always  <span class="token key atrule">database</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> immich_postgres    <span class="token key atrule">image</span><span class="token punctuation">:</span> docker.io/tensorchord/pgvecto<span class="token punctuation">-</span>rs<span class="token punctuation">:</span>pg14<span class="token punctuation">-</span>v0.2.0@sha256<span class="token punctuation">:</span>90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token key atrule">POSTGRES_PASSWORD</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span>DB_PASSWORD<span class="token punctuation">}</span>      <span class="token key atrule">POSTGRES_USER</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span>DB_USERNAME<span class="token punctuation">}</span>      <span class="token key atrule">POSTGRES_DB</span><span class="token punctuation">:</span> $<span class="token punctuation">{</span>DB_DATABASE_NAME<span class="token punctuation">}</span>      <span class="token key atrule">POSTGRES_INITDB_ARGS</span><span class="token punctuation">:</span> <span class="token string">'--data-checksums'</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token comment" spellcheck="true"># Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file</span>      <span class="token punctuation">-</span> $<span class="token punctuation">{</span>DB_DATA_LOCATION<span class="token punctuation">}</span><span class="token punctuation">:</span>/var/lib/postgresql/data    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">></span><span class="token punctuation">-</span>        pg_isready <span class="token punctuation">-</span><span class="token punctuation">-</span>dbname="$$<span class="token punctuation">{</span>POSTGRES_DB<span class="token punctuation">}</span>" <span class="token punctuation">-</span><span class="token punctuation">-</span>username="$$<span class="token punctuation">{</span>POSTGRES_USER<span class="token punctuation">}</span>" <span class="token punctuation">|</span><span class="token punctuation">|</span> exit 1;        Chksum="$$(psql <span class="token punctuation">-</span><span class="token punctuation">-</span>dbname="$$<span class="token punctuation">{</span>POSTGRES_DB<span class="token punctuation">}</span>" <span class="token punctuation">-</span><span class="token punctuation">-</span>username="$$<span class="token punctuation">{</span>POSTGRES_USER<span class="token punctuation">}</span>" <span class="token punctuation">-</span><span class="token punctuation">-</span>tuples<span class="token punctuation">-</span>only <span class="token punctuation">-</span><span class="token punctuation">-</span>no<span class="token punctuation">-</span>align        <span class="token punctuation">-</span><span class="token punctuation">-</span>command='SELECT COALESCE(SUM(checksum_failures)<span class="token punctuation">,</span> 0) FROM pg_stat_database')";        echo "checksum failure count is $$Chksum";        <span class="token punctuation">[</span> "$$Chksum" = '0' <span class="token punctuation">]</span> <span class="token punctuation">|</span><span class="token punctuation">|</span> exit 1      <span class="token key atrule">interval</span><span class="token punctuation">:</span> 5m      <span class="token key atrule">start_interval</span><span class="token punctuation">:</span> 30s      <span class="token key atrule">start_period</span><span class="token punctuation">:</span> 5m    <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">></span><span class="token punctuation">-</span>      postgres      <span class="token punctuation">-</span>c shared_preload_libraries=vectors.so      <span class="token punctuation">-</span>c 'search_path="$$user"<span class="token punctuation">,</span> public<span class="token punctuation">,</span> vectors'      <span class="token punctuation">-</span>c logging_collector=on      <span class="token punctuation">-</span>c max_wal_size=2GB      <span class="token punctuation">-</span>c shared_buffers=512MB      <span class="token punctuation">-</span>c wal_compression=on    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always<span class="token key atrule">volumes</span><span class="token punctuation">:</span>  model<span class="token punctuation">-</span>cache<span class="token punctuation">:</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>.env文件：</p><pre class="line-numbers language-sh"><code class="language-sh"># You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables# The location where your uploaded files are storedUPLOAD_LOCATION=/vol1/1000/photos# The location where your database files are storedDB_DATA_LOCATION=/vol1/1000/docker/immich/dbMODEL_CACHE=/vol1/1000/docker/immich/model_cache# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#ListTZ=Asia/Shanghai# The Immich version to use. You can pin this to a specific version like "v1.71.0"IMMICH_VERSION=release# Connection secret for postgres. You should change it to a random password# Please use only the characters `A-Za-z0-9`, without special characters or spacesDB_PASSWORD=postgres# The values below this line do not need to be changed###################################################################################DB_USERNAME=postgresDB_DATABASE_NAME=immich<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="iptv">2.12&emsp;iptv</h2><p>IPTV是一种通过互联网协议提供电视内容的服务，该镜像是个直播源代理程序。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">allinone</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> youshandefeiyang/allinone    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> allinone    <span class="token key atrule">privileged</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"35455:35455"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> bridge    <span class="token key atrule">command</span><span class="token punctuation">:</span> <span class="token punctuation">-</span>tv=true <span class="token punctuation">-</span>aesKey= <span class="token comment" spellcheck="true">#具体用法自行搜索，完整command总不能告诉你把</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="komga">2.13&emsp;komga</h2><p>Komga 是一款开源的漫画和图书管理服务，支持多种格式文件（如 CBZ、EPUB 等）的在线阅读和分类管理，适合搭建私人漫画库。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3.3'</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">komga</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> gotson/komga    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> komga    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> bind        <span class="token key atrule">source</span><span class="token punctuation">:</span> ./config        <span class="token key atrule">target</span><span class="token punctuation">:</span> /config      <span class="token punctuation">-</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> bind        <span class="token key atrule">source</span><span class="token punctuation">:</span> ./data        <span class="token key atrule">target</span><span class="token punctuation">:</span> /data      <span class="token punctuation">-</span> <span class="token key atrule">type</span><span class="token punctuation">:</span> bind        <span class="token key atrule">source</span><span class="token punctuation">:</span> /etc/timezone <span class="token comment" spellcheck="true">#alternatively you can use a TZ environment variable, like TZ=Europe/London</span>        <span class="token key atrule">target</span><span class="token punctuation">:</span> /etc/timezone        <span class="token key atrule">read_only</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 25600<span class="token punctuation">:</span><span class="token number">25600</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="minecraft-server">2.14&emsp;minecraft-server</h2><p>Minecraft-Server 是运行 Minecraft 游戏服务器的容器，支持多人联机游戏，适合玩家搭建私人游戏服务器或社群服务器。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">mc</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> itzg/minecraft<span class="token punctuation">-</span>server    <span class="token key atrule">tty</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">stdin_open</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"25565:25565"</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token key atrule">EULA</span><span class="token punctuation">:</span> <span class="token string">"TRUE"</span>      <span class="token key atrule">PUID</span><span class="token punctuation">:</span> <span class="token number">0</span>      <span class="token key atrule">PGID</span><span class="token punctuation">:</span> <span class="token number">0</span>      <span class="token key atrule">UMASK</span><span class="token punctuation">:</span> <span class="token number">022</span>      <span class="token key atrule">TYPE</span><span class="token punctuation">:</span> <span class="token string">"FABRIC"</span>      <span class="token comment" spellcheck="true">#OPS: "8a2ee9a2-dc33-4e83-ba80-5670cd636b47"</span>      <span class="token key atrule">OPS</span><span class="token punctuation">:</span> <span class="token string">"JiyoTomare"</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> <span class="token string">"bridge"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> <span class="token string">"always"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token comment" spellcheck="true"># attach the relative directory 'data' to the container's /data path</span>      <span class="token punctuation">-</span> ./data<span class="token punctuation">:</span>/data<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="moviepilot">2.15&emsp;moviepilot</h2><p>NAS媒体库自动化管理工具，自动化观影平台，pt站玩家必备。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3.3'</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">moviepilot</span><span class="token punctuation">:</span>    <span class="token key atrule">stdin_open</span><span class="token punctuation">:</span> <span class="token boolean important">true  </span><span class="token comment" spellcheck="true"># 是否打开标准输入流（交互模式），为 true 时容器可以保持运行并与用户交互</span>    <span class="token key atrule">tty</span><span class="token punctuation">:</span> <span class="token boolean important">true  </span><span class="token comment" spellcheck="true"># 是否分配伪终端，使容器的终端行为更像一个真实的终端</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> moviepilot<span class="token punctuation">-</span>v2  <span class="token comment" spellcheck="true"># 容器的名称</span>    <span class="token key atrule">hostname</span><span class="token punctuation">:</span> moviepilot<span class="token punctuation">-</span>v2  <span class="token comment" spellcheck="true"># 容器主机名</span>    <span class="token comment" spellcheck="true"># 网关设置</span>    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> host  <span class="token comment" spellcheck="true"># 内置的网关</span>    <span class="token comment" spellcheck="true"># networks:  # 自定义网关</span>    <span class="token comment" spellcheck="true">#  - moviepilot</span>    <span class="token comment" spellcheck="true"># 端口映射，当network_mode的值为 host 时，将失效</span>    <span class="token comment" spellcheck="true"># ports:</span>      <span class="token comment" spellcheck="true"># 前端 UI 显示</span>      <span class="token comment" spellcheck="true"># - target: 3000  # 容器内部端口设置为 3000</span>      <span class="token comment" spellcheck="true">#   published: 3000  # 映射到宿主机的 3000 端口，允许外部访问</span>      <span class="token comment" spellcheck="true">#   protocol: tcp  # TCP 协议，可选udp</span>      <span class="token comment" spellcheck="true"># API 接口</span>      <span class="token comment" spellcheck="true"># - target: 3001  # 容器内部端口设置为 3001</span>      <span class="token comment" spellcheck="true">#   published: 3001  # 映射到宿主机的 3001 端口，允许外部访问</span>      <span class="token comment" spellcheck="true">#   protocol: tcp  # TCP 协议，可选udp</span>    <span class="token comment" spellcheck="true"># 目录映射：宿主机目录:容器内目录</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">'/vol1/1000/video:/media'</span>  <span class="token comment" spellcheck="true"># 媒体库或下载库路径</span>      <span class="token punctuation">-</span> <span class="token string">'./moviepilot-v2/config:/config'</span>  <span class="token comment" spellcheck="true"># moviepilot 的配置文件存放路径</span>      <span class="token punctuation">-</span> <span class="token string">'./moviepilot-v2/core:/moviepilot/.cache/ms-playwright'</span>  <span class="token comment" spellcheck="true"># 浏览器内核存放路径</span>      <span class="token punctuation">-</span> <span class="token string">'/var/run/docker.sock:/var/run/docker.sock:ro'</span>  <span class="token comment" spellcheck="true"># 用于获取宿主机的docker管理权，一般用于UI页面重启或自动更新</span>    <span class="token comment" spellcheck="true"># 环境变量：- '变量名=值‘</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">'NGINX_PORT=3000'</span>  <span class="token comment" spellcheck="true"># UI页面的内部监听端口</span>      <span class="token punctuation">-</span> <span class="token string">'PORT=3001'</span>  <span class="token comment" spellcheck="true"># API接口的内部监听端口</span>      <span class="token punctuation">-</span> <span class="token string">'PUID=0'</span>  <span class="token comment" spellcheck="true"># 设置应用运行时的用户 ID 为 0（root 用户）</span>      <span class="token punctuation">-</span> <span class="token string">'PGID=0'</span>  <span class="token comment" spellcheck="true"># 设置应用运行时的组 ID 为 0（root 组）</span>      <span class="token punctuation">-</span> <span class="token string">'UMASK=000'</span>  <span class="token comment" spellcheck="true"># 文件创建时的默认权限掩码，000 表示不限制权限</span>      <span class="token punctuation">-</span> <span class="token string">'TZ=Asia/Shanghai'</span>  <span class="token comment" spellcheck="true"># 设置时区为上海（Asia/Shanghai）</span>      <span class="token punctuation">-</span> <span class="token string">'PROXY_HOST=http://192.168.100.45:7890'</span>      <span class="token comment" spellcheck="true"># - 'AUTH_SITE=iyuu'  # 设置认证站点，v2.0.7+版本以后可不设置，直接通过 UI 配置</span>      <span class="token comment" spellcheck="true"># - 'IYUU_SIGN=xxxx'  # 单个站点密钥，配合 AUTH_SITE 使用</span>      <span class="token punctuation">-</span> <span class="token string">'SUPERUSER=admin'</span>  <span class="token comment" spellcheck="true"># 设置超级用户为 admin</span>      <span class="token comment" spellcheck="true"># - 'API_TOKEN=无需手动配置，系统会自动生成。如果需要自定义配置，必须为16位以上的复杂字符串'</span>    <span class="token comment" spellcheck="true"># 重启模式:</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always  <span class="token comment" spellcheck="true"># 始终重启</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> jxxghp/moviepilot<span class="token punctuation">-</span>v2<span class="token punctuation">:</span>latest<span class="token comment" spellcheck="true"># 当使用内置网关时，可不启用</span><span class="token comment" spellcheck="true"># networks:</span><span class="token comment" spellcheck="true">#   moviepilot:  # 定义一个名为 moviepilot 的自定义网络</span><span class="token comment" spellcheck="true">#     name: moviepilot  # 网络的名称</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="openspeedtest">2.16&emsp;openspeedtest</h2><p>OpenSpeedTest 是一个网络测速工具，通过简单的 Web 界面，可以测试设备与服务器之间的上传和下载速度。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3.3'</span><span class="token key atrule">services</span><span class="token punctuation">:</span>    <span class="token key atrule">speedtest</span><span class="token punctuation">:</span>        <span class="token key atrule">restart</span><span class="token punctuation">:</span> always        <span class="token key atrule">container_name</span><span class="token punctuation">:</span> openspeedtest        <span class="token key atrule">ports</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> <span class="token string">'3003:3000'</span>            <span class="token punctuation">-</span> <span class="token string">'3004:3001'</span>        <span class="token key atrule">image</span><span class="token punctuation">:</span> openspeedtest/latest<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="qbittorrent">2.17&emsp;qbittorrent</h2><p>qBittorrent 是一个 BitTorrent 客户端，支持跨平台文件共享和下载，提供 Web 界面管理功能，适合离线下载和资源分发。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">qbittorrent</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> binswm/qbittorrent<span class="token punctuation">:</span>4.3.9    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> qbittorrent    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> bridge    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> PUID=0      <span class="token punctuation">-</span> PGID=0      <span class="token punctuation">-</span> UMASK_SET=022      <span class="token punctuation">-</span> TZ=Asia/Shanghai <span class="token comment" spellcheck="true"># 你的时区</span>      <span class="token punctuation">-</span> WEBUI_PORT=8081 <span class="token comment" spellcheck="true"># 将此处修改成你欲使用的 WEB 管理平台端口 </span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./config<span class="token punctuation">:</span>/config <span class="token comment" spellcheck="true"># 绝对路径请修改为自己的config文件夹</span>      <span class="token punctuation">-</span> ./downloads<span class="token punctuation">:</span>/downloads <span class="token comment" spellcheck="true"># 绝对路径请修改为自己的downloads文件夹</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token comment" spellcheck="true"># 要使用的映射下载端口与内部下载端口，可保持默认，安装完成后在管理页面仍然可以改成其他端口。</span>      <span class="token punctuation">-</span> 12812<span class="token punctuation">:</span><span class="token number">6881 </span>      <span class="token punctuation">-</span> 12812<span class="token punctuation">:</span>6881/udp      <span class="token comment" spellcheck="true"># 此处WEB UI 目标端口与内部端口务必保证相同，见问题1</span>      <span class="token punctuation">-</span> 8081<span class="token punctuation">:</span><span class="token number">8081</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="sun-panel">2.18&emsp;sun-panel</h2><p>一个服务器、NAS导航面板、Homepage、浏览器首页。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">"3.2"</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">sun-panel</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> <span class="token string">'hslr/sun-panel:latest'</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> sun<span class="token punctuation">-</span>panel    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"PUID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"PGID=0"</span>      <span class="token punctuation">-</span> <span class="token string">"UMASK=022"</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>    <span class="token punctuation">-</span> ./conf<span class="token punctuation">:</span>/app/conf    <span class="token punctuation">-</span> ./database<span class="token punctuation">:</span>/app/database    <span class="token punctuation">-</span> /var/run/docker.sock<span class="token punctuation">:</span>/var/run/docker.sock    <span class="token comment" spellcheck="true"># - ./runtime:/app/runtime</span>    <span class="token key atrule">ports</span><span class="token punctuation">:</span>    <span class="token punctuation">-</span> 3002<span class="token punctuation">:</span><span class="token number">3002</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="tailscale">2.19&emsp;tailscale</h2><p>tailscale 是一种基于 WireGuard 的零配置 VPN 工具，支持快速建立安全的点对点连接，适用于远程访问、内网穿透和多设备协作。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">version</span><span class="token punctuation">:</span> <span class="token string">'3.7'</span><span class="token key atrule">services</span><span class="token punctuation">:</span>    <span class="token key atrule">tailscale</span><span class="token punctuation">:</span>        <span class="token key atrule">container_name</span><span class="token punctuation">:</span> tailscale        <span class="token key atrule">volumes</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> /vol1/1000/docker/tailscale/var/lib<span class="token punctuation">:</span>/var/lib            <span class="token punctuation">-</span> /vol1/1000/docker/tailscale/dev/net/tun<span class="token punctuation">:</span>/dev/net/tun        <span class="token key atrule">network_mode</span><span class="token punctuation">:</span> host        <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped        <span class="token key atrule">environment</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> TS_AUTHKEY=xxxxxxxxxxxxxxxx            <span class="token punctuation">-</span> TS_EXTRA_ARGS=<span class="token punctuation">-</span><span class="token punctuation">-</span>advertise<span class="token punctuation">-</span>exit<span class="token punctuation">-</span>node            <span class="token punctuation">-</span> TS_ROUTES=192.168.100.0/24   <span class="token comment" spellcheck="true">#把xx替换成自己网关的网段</span>            <span class="token punctuation">-</span> TS_HOSTNAME=fnOS    <span class="token comment" spellcheck="true">#把xx替换成自己喜欢的名字，比如 fnOS</span>            <span class="token punctuation">-</span> TS_STATE_DIR=./state/        <span class="token key atrule">image</span><span class="token punctuation">:</span> tailscale/tailscale<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="VPS">3&emsp;VPS</h1><h2 id="rss">3.1&emsp;rss</h2><p>Tiny Tiny RSS 是一款基于 PHP 的免费开源 RSS 聚合阅读器。🐋 Awesome TTRSS 旨在提供一个 「一站式容器化」 的 Tiny Tiny RSS 解决方案，通过提供简易的部署方式以及一些额外插件，以提升用户体验。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">service.ttrss</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> wangqiru/ttrss<span class="token punctuation">:</span>latest    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> ttrss    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 181<span class="token punctuation">:</span><span class="token number">80</span>    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> SELF_URL_PATH=http<span class="token punctuation">:</span>//yourdomain.com<span class="token punctuation">:</span><span class="token number">181 </span><span class="token comment" spellcheck="true"># please change to your own domain</span>      <span class="token punctuation">-</span> DB_PASS=6666666666 <span class="token comment" spellcheck="true"># use the same password defined in `database.postgres`</span>      <span class="token punctuation">-</span> ALLOW_PORTS=3000      <span class="token punctuation">-</span> PUID=1000      <span class="token punctuation">-</span> PGID=1000    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> feed<span class="token punctuation">-</span>icons<span class="token punctuation">:</span>/var/www/feed<span class="token punctuation">-</span>icons/    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> public_access      <span class="token punctuation">-</span> service_only      <span class="token punctuation">-</span> database_only    <span class="token key atrule">stdin_open</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">tty</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>    <span class="token key atrule">depends_on</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> database.postgres    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"CMD-SHELL"</span><span class="token punctuation">,</span> <span class="token string">"curl -f http://localhost:80 || exit 1"</span><span class="token punctuation">]</span>      <span class="token key atrule">start_period</span><span class="token punctuation">:</span> 30s      <span class="token key atrule">interval</span><span class="token punctuation">:</span> 30s      <span class="token key atrule">timeout</span><span class="token punctuation">:</span> 10s      <span class="token key atrule">retries</span><span class="token punctuation">:</span> <span class="token number">5</span>  <span class="token key atrule">service.mercury</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># set Mercury Parser API endpoint to `service.mercury:3000` on TTRSS plugin setting page</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> wangqiru/mercury<span class="token punctuation">-</span>parser<span class="token punctuation">-</span>api<span class="token punctuation">:</span>latest    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> mercury    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> public_access      <span class="token punctuation">-</span> service_only    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always  <span class="token key atrule">service.opencc</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># set OpenCC API endpoint to `service.opencc:3000` on TTRSS plugin setting page</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> wangqiru/opencc<span class="token punctuation">-</span>api<span class="token punctuation">-</span>server<span class="token punctuation">:</span>latest    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> opencc    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> NODE_ENV=production    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> service_only    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always  <span class="token key atrule">database.postgres</span><span class="token punctuation">:</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> postgres<span class="token punctuation">:</span>16<span class="token punctuation">-</span>alpine    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> POSTGRES_PASSWORD=6666666666 <span class="token comment" spellcheck="true"># feel free to change the password</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./postgres/data/<span class="token punctuation">:</span>/var/lib/postgresql/data <span class="token comment" spellcheck="true"># persist postgres data to ~/postgres/data/ on the host</span>    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> database_only    <span class="token key atrule">restart</span><span class="token punctuation">:</span> always    <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>      <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"CMD-SHELL"</span><span class="token punctuation">,</span> <span class="token string">"pg_isready -U postgres"</span><span class="token punctuation">]</span>      <span class="token key atrule">start_period</span><span class="token punctuation">:</span> 30s      <span class="token key atrule">interval</span><span class="token punctuation">:</span> 30s      <span class="token key atrule">timeout</span><span class="token punctuation">:</span> 10s      <span class="token key atrule">retries</span><span class="token punctuation">:</span> <span class="token number">5</span>  <span class="token comment" spellcheck="true"># utility.watchtower:</span>  <span class="token comment" spellcheck="true">#   container_name: watchtower</span>  <span class="token comment" spellcheck="true">#   image: containrrr/watchtower:latest</span>  <span class="token comment" spellcheck="true">#   volumes:</span>  <span class="token comment" spellcheck="true">#     - /var/run/docker.sock:/var/run/docker.sock</span>  <span class="token comment" spellcheck="true">#   environment:</span>  <span class="token comment" spellcheck="true">#     - WATCHTOWER_CLEANUP=true</span>  <span class="token comment" spellcheck="true">#     - WATCHTOWER_POLL_INTERVAL=86400</span>  <span class="token comment" spellcheck="true">#   restart: always</span>  <span class="token comment" spellcheck="true"># service.rsshub:</span>  <span class="token comment" spellcheck="true">#   container_name: rsshub</span>  <span class="token comment" spellcheck="true">#   image: diygod/rsshub:latest</span>  <span class="token comment" spellcheck="true">#   environment:</span>  <span class="token comment" spellcheck="true">#     NODE_ENV: production</span>  <span class="token comment" spellcheck="true">#     DEBUG_INFO: false</span>  <span class="token comment" spellcheck="true">#     LOGGER_LEVEL: error</span>  <span class="token comment" spellcheck="true">#     NO_LOGFILES: true</span>  <span class="token comment" spellcheck="true">#   networks:</span>  <span class="token comment" spellcheck="true">#     - service_only</span>  <span class="token comment" spellcheck="true">#   expose:</span>  <span class="token comment" spellcheck="true">#     - 3000</span>  <span class="token comment" spellcheck="true">#   restart: unless-stopped</span><span class="token key atrule">volumes</span><span class="token punctuation">:</span>  <span class="token key atrule">feed-icons</span><span class="token punctuation">:</span><span class="token key atrule">networks</span><span class="token punctuation">:</span>  <span class="token key atrule">public_access</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># Provide the access for ttrss UI</span>  <span class="token key atrule">service_only</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># Provide the communication network between services only</span>    <span class="token key atrule">internal</span><span class="token punctuation">:</span> <span class="token boolean important">true</span>  <span class="token key atrule">database_only</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># Provide the communication between ttrss and database only</span>    <span class="token key atrule">internal</span><span class="token punctuation">:</span> <span class="token boolean important">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="rsshub">3.2&emsp;rsshub</h2><p>RSSHub 是一个开源的 RSS 生成工具，它的主要作用是将许多无法直接提供 RSS 源的网站内容（如新闻、博客、社交媒体更新等）转化为标准化的 RSS 订阅源，从而让用户通过 RSS 阅读器统一订阅和管理不同来源的信息。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">services</span><span class="token punctuation">:</span>    <span class="token key atrule">rsshub</span><span class="token punctuation">:</span>        <span class="token comment" spellcheck="true"># two ways to enable puppeteer:</span>        <span class="token comment" spellcheck="true"># * comment out marked lines, then use this image instead: diygod/rsshub:chromium-bundled</span>        <span class="token comment" spellcheck="true"># * (consumes more disk space and memory) leave everything unchanged</span>        <span class="token key atrule">image</span><span class="token punctuation">:</span> diygod/rsshub        <span class="token key atrule">restart</span><span class="token punctuation">:</span> always        <span class="token key atrule">ports</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> <span class="token string">"1200:1200"</span>        <span class="token key atrule">environment</span><span class="token punctuation">:</span>            <span class="token key atrule">NODE_ENV</span><span class="token punctuation">:</span> production            <span class="token key atrule">CACHE_TYPE</span><span class="token punctuation">:</span> redis            <span class="token key atrule">REDIS_URL</span><span class="token punctuation">:</span> <span class="token string">"redis://redis:6379/"</span>            <span class="token key atrule">PUPPETEER_WS_ENDPOINT</span><span class="token punctuation">:</span> <span class="token string">"ws://browserless:3000"</span> <span class="token comment" spellcheck="true"># marked</span>            <span class="token comment" spellcheck="true">#ACCESS_KEY: 6666666666</span>        <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>            <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"CMD"</span><span class="token punctuation">,</span> <span class="token string">"curl"</span><span class="token punctuation">,</span> <span class="token string">"-f"</span><span class="token punctuation">,</span> <span class="token string">"http://localhost:1200/healthz"</span><span class="token punctuation">]</span>            <span class="token key atrule">interval</span><span class="token punctuation">:</span> 30s            <span class="token key atrule">timeout</span><span class="token punctuation">:</span> 10s            <span class="token key atrule">retries</span><span class="token punctuation">:</span> <span class="token number">3</span>        <span class="token key atrule">depends_on</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> redis            <span class="token punctuation">-</span> browserless <span class="token comment" spellcheck="true"># marked</span>    <span class="token key atrule">browserless</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># marked</span>        <span class="token key atrule">image</span><span class="token punctuation">:</span> browserless/chrome <span class="token comment" spellcheck="true"># marked</span>        <span class="token key atrule">restart</span><span class="token punctuation">:</span> always <span class="token comment" spellcheck="true"># marked</span>        <span class="token key atrule">ulimits</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># marked</span>            <span class="token key atrule">core</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true"># marked</span>                <span class="token key atrule">hard</span><span class="token punctuation">:</span> <span class="token number">0 </span><span class="token comment" spellcheck="true"># marked</span>                <span class="token key atrule">soft</span><span class="token punctuation">:</span> <span class="token number">0 </span><span class="token comment" spellcheck="true"># marked</span>        <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>            <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"CMD"</span><span class="token punctuation">,</span> <span class="token string">"curl"</span><span class="token punctuation">,</span> <span class="token string">"-f"</span><span class="token punctuation">,</span> <span class="token string">"http://localhost:3000/pressure"</span><span class="token punctuation">]</span>            <span class="token key atrule">interval</span><span class="token punctuation">:</span> 30s            <span class="token key atrule">timeout</span><span class="token punctuation">:</span> 10s            <span class="token key atrule">retries</span><span class="token punctuation">:</span> <span class="token number">3</span>    <span class="token key atrule">redis</span><span class="token punctuation">:</span>        <span class="token key atrule">image</span><span class="token punctuation">:</span> redis<span class="token punctuation">:</span>alpine        <span class="token key atrule">restart</span><span class="token punctuation">:</span> always        <span class="token key atrule">volumes</span><span class="token punctuation">:</span>            <span class="token punctuation">-</span> redis<span class="token punctuation">-</span>data<span class="token punctuation">:</span>/data        <span class="token key atrule">healthcheck</span><span class="token punctuation">:</span>            <span class="token key atrule">test</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">"CMD"</span><span class="token punctuation">,</span> <span class="token string">"redis-cli"</span><span class="token punctuation">,</span> <span class="token string">"ping"</span><span class="token punctuation">]</span>            <span class="token key atrule">interval</span><span class="token punctuation">:</span> 30s            <span class="token key atrule">timeout</span><span class="token punctuation">:</span> 10s            <span class="token key atrule">retries</span><span class="token punctuation">:</span> <span class="token number">5</span>            <span class="token key atrule">start_period</span><span class="token punctuation">:</span> 5s<span class="token key atrule">volumes</span><span class="token punctuation">:</span>    redis<span class="token punctuation">-</span>data<span class="token punctuation">:</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="rustdesk">3.3&emsp;rustdesk</h2><p>RustDesk 是一款开源的远程桌面软件，类似于 TeamViewer 和 AnyDesk，但更加注重隐私与自主可控。它允许用户通过互联网远程访问和控制其他设备，支持跨平台使用（如 Windows、macOS、Linux、iOS 和 Android）。  </p><pre class="line-numbers language-yaml"><code class="language-yaml"><span class="token key atrule">networks</span><span class="token punctuation">:</span>  <span class="token key atrule">rustdesk-net</span><span class="token punctuation">:</span>    <span class="token key atrule">external</span><span class="token punctuation">:</span> <span class="token boolean important">false</span><span class="token comment" spellcheck="true"># 21114~21119端口记得开放</span><span class="token key atrule">services</span><span class="token punctuation">:</span>  <span class="token key atrule">hbbs</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> hbbs    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 21115<span class="token punctuation">:</span><span class="token number">21115</span>      <span class="token punctuation">-</span> 21116<span class="token punctuation">:</span><span class="token number">21116 </span><span class="token comment" spellcheck="true"># 自定义 hbbs 映射端口</span>      <span class="token punctuation">-</span> 21116<span class="token punctuation">:</span>21116/udp <span class="token comment" spellcheck="true"># 自定义 hbbs 映射端口</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> rustdesk/rustdesk<span class="token punctuation">-</span>server    <span class="token key atrule">command</span><span class="token punctuation">:</span> hbbs <span class="token punctuation">-</span>r xxx.xxx.xxx.xxx<span class="token punctuation">:</span>21117 <span class="token punctuation">-</span>k 66666666666666    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./data<span class="token punctuation">:</span>/root <span class="token comment" spellcheck="true"># 自定义挂载目录</span>    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> rustdesk<span class="token punctuation">-</span>net    <span class="token key atrule">depends_on</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> hbbr    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped    <span class="token key atrule">deploy</span><span class="token punctuation">:</span>      <span class="token key atrule">resources</span><span class="token punctuation">:</span>        <span class="token key atrule">limits</span><span class="token punctuation">:</span>          <span class="token key atrule">memory</span><span class="token punctuation">:</span> 64M  <span class="token key atrule">hbbr</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> hbbr    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> 21117<span class="token punctuation">:</span><span class="token number">21117 </span><span class="token comment" spellcheck="true"># 自定义 hbbr 映射端口</span>    <span class="token key atrule">image</span><span class="token punctuation">:</span> rustdesk/rustdesk<span class="token punctuation">-</span>server    <span class="token key atrule">command</span><span class="token punctuation">:</span> hbbr <span class="token punctuation">-</span>k 66666666666666    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./data<span class="token punctuation">:</span>/root <span class="token comment" spellcheck="true"># 自定义挂载目录</span>    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> rustdesk<span class="token punctuation">-</span>net    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped    <span class="token key atrule">deploy</span><span class="token punctuation">:</span>      <span class="token key atrule">resources</span><span class="token punctuation">:</span>        <span class="token key atrule">limits</span><span class="token punctuation">:</span>          <span class="token key atrule">memory</span><span class="token punctuation">:</span> 64M  <span class="token key atrule">rustdesk-api-server</span><span class="token punctuation">:</span>    <span class="token key atrule">container_name</span><span class="token punctuation">:</span> rustdesk<span class="token punctuation">-</span>api<span class="token punctuation">-</span>server    <span class="token key atrule">image</span><span class="token punctuation">:</span> kingmo888/rustdesk<span class="token punctuation">-</span>api<span class="token punctuation">-</span>server<span class="token punctuation">:</span>latest    <span class="token key atrule">environment</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> CSRF_TRUSTED_ORIGINS=http<span class="token punctuation">:</span>//xxx.xxx.xxx.xxx<span class="token punctuation">:</span><span class="token number">21114 </span><span class="token comment" spellcheck="true">#防跨域信任来源，可选</span>      <span class="token punctuation">-</span> ID_SERVER=xxx.xxx.xxx.xxx<span class="token punctuation">:</span><span class="token number">21114 </span><span class="token comment" spellcheck="true">#Web控制端使用的ID服务器</span>    <span class="token key atrule">volumes</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> ./db<span class="token punctuation">:</span>/rustdesk<span class="token punctuation">-</span>api<span class="token punctuation">-</span>server/db <span class="token comment" spellcheck="true">#修改为你宿主机数据库挂载目录</span>      <span class="token punctuation">-</span> /etc/timezone<span class="token punctuation">:</span>/etc/timezone<span class="token punctuation">:</span>ro      <span class="token punctuation">-</span> /etc/localtime<span class="token punctuation">:</span>/etc/localtime<span class="token punctuation">:</span>ro    <span class="token comment" spellcheck="true">#network_mode: bridge</span>    <span class="token key atrule">networks</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> rustdesk<span class="token punctuation">-</span>net    <span class="token key atrule">ports</span><span class="token punctuation">:</span>      <span class="token punctuation">-</span> <span class="token string">"21114:21114"</span>    <span class="token key atrule">restart</span><span class="token punctuation">:</span> unless<span class="token punctuation">-</span>stopped<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="tailscale-derp">3.4&emsp;tailscale-derp</h2><p>建DERP组建私有局域网的简单步骤，该方案为了保持极简未配置域名，直接填IP访问，但要注意不要被别人白嫖了（别人知道地址ip也能用）。</p><pre class="line-numbers language-yml"><code class="language-yml"># 记得开放对应端口防火墙version: "3.8"services:services:  derper:    image: ghcr.io/yangchuansheng/ip_derper:latest    container_name: derper    restart: always    volumes:      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro      - ./data/tailscale/tmp:/var/run/tailscale    ports:      - "xxxx1:443"           #和后面tailscale admin网页里填的port对应      - "xxxx2:3478/udp"#    environment:#      - DERP_VERIFY_CLIENTS: "true" #使用tailscale客户端鉴权    depends_on:      - tailscale  tailscale:    image: tailscale/tailscale:latest    container_name: tailscale    restart: always    network_mode: host  #注释本行可使VPS主机不可通过tailscale网络访问    environment:      TS_STATE_DIR: /var/lib/tailscale      TS_USERSPACE: "false"    volumes:      - /dev/net/tun:/dev/net/tun      - ./data/tailscale/state:/var/lib/tailscale      - ./data/tailscale/tmp:/tmp      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro    cap_add:      - net_admin      - sys_module#"derpMap": {#        "OmitDefaultRegions": false, // 设置为 true不下发官方derp节点#        "Regions": {#            "901": {#                "RegionID":   901, #                "RegionCode": "derp_self",#                "RegionName": "derp_self", #                "Nodes": [#                    {#                        "Name":             "derp_self",#                        "RegionID":         901,#                        "HostName":         "0.0.0.0", // 你的公网IP地址#                        "IPv4":             "0.0.0.0", // 你的公网IP地址#                        "DERPPort":         xxxx1, #                        "InsecureForTests": true, // 客户端不做校验#                        "STUNPort":         xxxx2,#                    },#                ],#            },#        },#    },<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2025-01-15-mu-qian-zheng-zai-yong-de-ge-lei-fu-wu-docker-compose-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>无Ipv4折腾NAS外网访问</title>
      <link>https://chengpengzhao.com/2024-12-30-wu-ipv4-zhe-teng-nas-wai-wang-fang-wen/</link>
      <guid>https://chengpengzhao.com/2024-12-30-wu-ipv4-zhe-teng-nas-wai-wang-fang-wen/</guid>
      <pubDate>Mon, 30 Dec 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;背景&quot;&gt;1&amp;emsp;背景&lt;/h1&gt;&lt;p&gt;自从之前我的出租屋联通宽
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="背景">1&emsp;背景</h1><p>自从之前我的出租屋联通宽带这套方案实施后（<a href="/2021-08-29-nas-ke-yi-wai-wang-fang-wen-ge/" title="NAS可以外网访问咯">NAS可以外网访问咯</a>），NAS已经稳定运行了有3年多，期间基本没有出现过任何问题（访问不了的情况等），这400块的蜗牛星际当时买来还是挺有性价比的。<br>然而现在不是买房了嘛，联通宽带迁移还得多付100多块，我思考索性重新办个宽带。不知道是看了小区电梯的小广告还是脑袋抽风怎么的，我竟然云里雾里地办了<strong>中国移动</strong>的宽带，还是太年轻了，这里我重点强调一下：  </p><blockquote><p>有NAS除非迫不得已千万不要选择中国移动宽带！<br>有NAS除非迫不得已千万不要选择中国移动宽带！<br>有NAS除非迫不得已千万不要选择中国移动宽带！  </p></blockquote><p>主要基于如下几点理由：  </p><ol><li>中国移动（我们这）的光猫用的动态密码，业务注册后会自动改密，装光猫的师傅不查也是不知道密码的；  </li><li>中国移动不给桥接，光猫师傅是不可能搞定的（说是明令禁止、帮我查了密码会有记录）；  </li><li>改了后如果被移动后台检测到，会自动改密、或者光猫拉黑名单；  </li><li>中国移动是大内网，<strong>没有动态的公网IP！没有动态的公网IP！没有动态的公网IP！</strong>；  </li></ol><h1 id="光猫改桥接">2&emsp;光猫改桥接</h1><p>在知道了上述坑后，后悔已经来不及了，现在违约移动还得赔一笔钱不划算，于是只能想有没有什么曲线救国方案，最后我发现了一线曙光：  </p><p><strong>没有公网IPv4地址，但是我有公网IPv6啊！</strong>  </p><p>当然首先第一步是光猫改桥接，脱离万恶的中国移动的魔爪是必须的。下面是我尝试过的一些方法。  </p><h2 id="安装师傅">2.1&emsp;安装师傅</h2><p>如果能搞定人那肯定是最好的，然而不论我怎么晓之以情动之以理，师傅都不为所动，估计是公司特别向他们强调了这种情况，没办法只能放弃该方法（不过最后师傅还是给出了一点提示，虽然他自己没办法帮我查，但是如果我通过别的途径查到了他也不会管）。  </p><h2 id="网上各类方法">2.2&emsp;网上各类方法</h2><p>接着就是根据光猫的型号（我的是中兴ZXHN F663NV9）查网上的各类方法，包括：  </p><ol><li>改html大法（通过修改网页执行隐藏命令）；  </li><li>恢复默认设置大法（注意记录原有信息）；  </li><li>基于factorymode_crack.exe等工具的Telnet方法…  </li></ol><p>然而不幸的是，以上方法全部阵亡，虽然光猫是个老型号但我怀疑移动在内部动了手脚，一个最显著的特点就是无论我怎么按reset按钮想要重置系统，它都毫无反应。  </p><h2 id="淘宝-闲鱼大法">2.3&emsp;淘宝/闲鱼大法</h2><p>迫不得已，只能使用从内部攻破的方法，去闲鱼找了一个支持查我们市光猫密码的，小小破费了10来块，不到1分钟便将密码发了过来，是<code>CMCCAdmin+一串随机字符串</code>的形式。  </p><h2 id="光猫改设置并除后患">2.4&emsp;光猫改设置并除后患</h2><p>管理员权限到手，这不立马就可以光纤一拔、开始改设置了么：  </p><ol><li>原设置每一页拍照留存；  </li><li><code>X_INTERNET_R_VID_xx</code>，光猫拨号设置，删掉；  </li><li><code>X_TR069_R_VID_xxxx</code>，万恶的TR069，删掉；  </li><li><code>QoS</code>，关掉；  </li><li>乱七八糟的使能设置，去掉勾；  </li><li>远程管理服务器，URL改掉；  </li><li>新建<code>X_INTERNET_B_VID_XXX</code>，桥接模式设定！  </li></ol><p>多确认以下这些设置，确保没有问题之后再插上光纤。不出意外的话，路由器接上光猫、在路由器拨号里账号密码一填就能够正常上网了。  </p><h1 id="NAS与路由器配置">3&emsp;NAS与路由器配置</h1><p>我的<strong>最终目的</strong>是要实现NAS在外网的安全访问，虽然通过ipv6地址是可以直接访问的，但总感觉有点不安全，还是希望能有层VPN保护一下，尽可能减少端口的暴露，于是尝试了很多方案：  </p><ol><li><p>老方法配置OpenVPN服务端，但遇到了阻碍，那就是不知道纯ipv6环境下该如何设置，复杂的网络配置我也不懂，只好放弃；  </p></li><li><p>尝试使用<strong>softetherVPN</strong>，配置过程是很简单，但巨坑的是很容易<strong>CPU占用原地螺旋上升</strong>，根本不懂怎么进阶配置才能既能快速访问又不占用资源；  </p></li><li><p>自己配置VPN的路行不通，那就使用P2P穿透技术代替吧！于是用<strong>ZeroTier</strong>试了下，发现还可以，但连接上花的时间多了点，且和内网ip相同时好像有点问题（可能是我不会设置）；  </p></li><li><p>用<strong>tailscale</strong>代替ZeroTier，配置起来也很简单，而且不用改变IP，确实很不错，最后就选择了它。  </p><p>最后再用<strong>ddns-go</strong>配置一番，动态解析下可能会变动的ipv6地址（仅暴露一个端口以防tailscale连不上的时候有操作空间），路由器再检查下防火墙是否全部打开着（用tailscale就不用暴露其他端口啦），一切准备就绪！  </p></li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-12-30-wu-ipv4-zhe-teng-nas-wai-wang-fang-wen/#disqus_thread</comments>
    </item>
    
    <item>
      <title>二手房交易流程记录</title>
      <link>https://chengpengzhao.com/2024-12-21-er-shou-fang-jiao-yi-liu-cheng-ji-lu/</link>
      <guid>https://chengpengzhao.com/2024-12-21-er-shou-fang-jiao-yi-liu-cheng-ji-lu/</guid>
      <pubDate>Sat, 21 Dec 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;最近一个月完成了人生中的
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>最近一个月完成了人生中的一件大事——买房，现在的我正坐在新家享受着冬日下午的阳光吹着空调写着这篇博客。<br>梳理整个流程，还是相当的复杂的，而且涉及到很多大大小小的坑，在准备出手之前必须要做足功课，毕竟对于这笔普通人一辈子可能就一两次的巨额消费，怎么小心谨慎都不为过。  </p><h1 id="明需求">2&emsp;明需求</h1><p>在开始打开各类app之前，请务必明确自己的预算和需求，要优先舍弃哪些，就像<a href="https://sspai.com/post/88238" target="_blank" rel="noopener">这篇少数派文章</a>里描绘的“不可能三角”所展示的，鱼和熊掌不可兼得。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20241221225432229.png" alt="房子里的不可能三角"></p><blockquote><p>这里顺带让我想到了以前看到的VPS的不可能三角，也一并放在这儿了~<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20241221225821919.png" alt="VPS的不可能三角"></p></blockquote><h1 id="找房源">3&emsp;找房源</h1><p>明确了自身需求之后，就可以开始找房子了，推荐这个阶段先自己在靠谱的app和靠谱的中介的帮助下进行第一轮筛选，我是找的我爱我家（我所在的城市好像就我爱我家和链家两家独大、其他鱼龙混杂），大品牌口碑有一定保证，但也得遇到个靠谱的中介，可以少操心很多事。<br>找房源时首先要注意真实性，这里不得不提一下<em>某居客</em>平台，请注意远离。  </p><p>这个阶段其实非常重要，主要从位置、配套、户型、小区、物业、楼层、交通、教育、经济承受范围等方面考虑，需要注意的点就很多，最好能线上确认的点都确认完没问题之后再考虑线下实地看房。<br>这里随便列一些当时做的笔记吧，如果想系统性梳理的话推荐先分好角度（如上文所述）再逐渐完善。  </p><ul><li>一手房：契税+物业维修基金； 二手房： 契税+土地增值税(满2免)+个税(满五唯一免)+中介费+土地出让金(安置房)；  </li><li>土地出让金的费用是很吓人的，买安置房的话一定要确认，当然也可以谈让卖家缴；  </li><li>建筑面积=公摊面积+套内建筑面积； 得房率=套内建筑面积÷建筑面积； 套内建筑面积=套内使用面积+套内墙体面积+阳台面积；  </li><li>公摊面积＝建筑面积×公摊系数；（7层以下的住宅的公摊率是7%—12%、7层—11层的住宅的公摊率是10%—20%、12层—33层的住宅公摊率为14%—24%）；  </li><li>售后公房（售后公房是机关单位建造的分配给职工居住使用的住房，职工没有权只有使用权）</li><li>容积率低：一个良好的居住小区，高层住宅容积率应不超过5，多层住宅应不超过3 （地面以上各类建筑的建筑面积总和与基地面积的比值）；  </li><li>绿化率高：小区的绿化率应该在30%以上才达标；  </li><li>物业靠谱：从小区环境观察、物业公司的资质和背景（很多安置房没物业）；  </li><li>尽量避免高层或底层：楼层总数的1/3到2/3处为宜；  </li><li>避免腰线层：影响采光、容易藏污纳垢；  </li><li>避免反水层（1、2、3…）、避难层（超33层时）、槽钢层、设备层；  </li><li>开间、进深：习惯上，我们把房间的主采光面成为开间（面宽），与其垂直的称为进深。也可根据房间门的朝向来确定开间和进深，房门进入的方向的距离为进深，左右两边距离为开间。根据《住宅建筑模数协调标准》（GBJ100-87）规定：住宅建筑的开间常采用下列参数：2.1米、2.4米、2.7米、3.0米、3.3米、3.6米、3.9米、 4.2米。（卧室以床顺着摆放的方向为开间，床头依靠的墙宽度为“进深”，卧室内布置床时，床头一般不靠窗台摆放）；  </li></ul><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20241221232604190.png" alt="开间和进深"></p><ul><li>动区：客厅、餐厅、厨房、次卫等。 静区：卧室、书房、主卫等。 动区是人们活动较为频繁的区域，应该靠近入户门设置，尤其是厨房；而静区主要供居住者休息，相对比较安静，应当尽量布置在户型内侧。两者分离，一方面使会客、娱乐或者进行家务的人能够放心活动，另一方面也不会过多打扰休息、学习的人，减少相互之间的干扰。详见以下范例：  </li></ul><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20241221232649599.png" alt="动区和静区"></p><ul><li>小区的梯户比、车位比等指标需要留意；  </li></ul><h1 id="约看房">4&emsp;约看房</h1><p>一般找房源的时间都很长，我算短的也差不多前后隔了几个月，在找到一些心仪的房源后，就可以联系中介约时间线下带看了。有时候确实你得实地看几套房之后才能知道自己的一些潜在需求（当然我线下看的不多、正巧没看几套就找到合适的了）。<br>线下看，自然得重点关注房子的实际情况，推荐去的时候带卷尺，也可再适当添加其他工具。需要关注的面也很多：  </p><ul><li>房屋结构与质量： 检查房屋的主体结构是否稳固，有无裂缝、渗水、漏水等现象； 检查墙面、地面、天花板是否平整，有无裂缝或脱落； 检查门窗是否完好，能否正常开启和关闭…  </li><li>户型与朝向： 观察房屋的户型是否合理，是否符合居住需求；检查房屋的朝向，是否有足够的自然光照和良好的通风…  </li><li>室内设施： 检查室内的水电、暖气、燃气等设施是否齐全且正常工作；  检查卫生间和厨房的排水系统是否畅通无阻…  </li><li>装修与维护：评估房屋的装修质量，是否需要重新装修或部分翻新。检查房屋的维护状况，是否有定期的保养和维修…  </li><li>了解周边的噪音、污染、绿化等情况，尤其是有没有垃圾处理站、加油站、殡仪馆、火葬场、较大噪音声源等，当然，这些并不是必须没有，主要根据自己的可接受程度。</li><li>物业：向物业或其他小区的人了解小区情况（对于社恐来说可能难度大点）…  </li></ul><h1 id="走流程">5&emsp;走流程</h1><p>如果不是急着买房，可以在找房源和约看房两个流程里停留久一点，现在是买方市场，就算看到很合适的也可以先放一放，说不定房东比你更着急卖。  </p><h2 id="谈价格">5.1&emsp;谈价格</h2><p>一般跟中介说觉得这房子不错之后就可以让中介联系房东见面谈谈了。我的情况是中介直接把我带到了我爱我家在我们市的总部，然后一开始买方和卖方分别单独和中介聊，说你的预期价位然后他帮你争取巴拉巴拉的，这时候一般会来回折腾几轮（说什么对方不接受啊、我再帮你砍一刀啊什么的，都是套路），最后才把你带去三方聊，进行新一轮的砍价。  </p><p>最后谈成什么样的价格，主要取决于以下几个因素：  </p><ol><li>你在看房中获得的筹码（如楼层不行啊、墙面有缺陷啊、阳台窗户质量差啊巴拉巴拉），也就是一些扣分项，扣分当然要减钱了对吧（当然也不能一味往坏处说）；  </li><li>你对市场的了解程度，同小区该户型过去一年成交价如何？成交价变化趋势？该小区的热门程度？房源上架时间？带看次数？调价次数及幅度？… 需要前期在各平台多搜集些数据，有的数据可能还不是公开透明的，需要找点关系或者花点💰；  </li><li>你的谈判方（卖家）的特点：卖方出售动机（可能会获取你意想不到的信息）？年纪及性格（初步推断）？经济状况如何，是否急需钱了？…<br>我觉得其中2和3是重点，2决定了至少你在这次交易中不会大亏，3可以为你在接下来的流程中少一些折腾，而1的作用则是进一步地帮你争得一些优惠。<br>我碰到的卖家是个带娃妈，年纪不大，因为去了旁边的城市发展而卖房，总的来说也比较好说话，不会为了鸡毛蒜皮的事争个你死我活。  </li></ol><h2 id="签合同">5.2&emsp;签合同</h2><p>价格谈好了，当场一般会签一个《居间服务合同》，这是买家、卖家和中介的三方合同，里面的细节一定要好好看一看，有想法就提出来让他们改！！！这一步直接决定了后面你的交易是否能顺心地进行下去，而不用总是提心吊胆生怕哪里有坑。<br>签合同一定要谨慎，一字一句都要过一遍（靠谱的中介会详细给你讲解），需要弄清楚的点包括但不限于：  </p><ul><li>先核对卖房证件信息（身份证、房产证、车位合同、户口本），确认产权清晰无纠纷， 查看房屋的规划用途，是否符合购买目的，能拍照最好（因为待会是要付定金的，卖方肯定愿意给你看，除非里面有鬼）；   </li><li>卖方是个人还是单位（单位不动产出售的税费要高于个人的）；  </li><li>房屋是否有共有产权人，夫妻的情况双方是否都同意卖房（共有产权人没签字，合同无效）；  </li><li>卖方持有房屋年限和是否唯一住宅（满二免收增值税，满五唯一的个人住宅免收个人所得税）；  </li><li>是普通商品房还是经济适用房等，土地性质是出让地还是划拨地（划拨地的房屋，在过户的时候需要额外补交土地收益金）；  </li><li>是否凶宅（屋内发生自杀或他杀的房屋定义为凶宅，看自己是否忌讳）；  </li><li>是否串串房（ABC单，炒房客操作方式，一般来说，产权持有人和与你签订合同的人不一致，房屋为刚装修好没有入住过的精装房）；  </li><li>如果是学位房 ，落实清楚学位是否还能使用（去派出所查户口、去学校查学位）；  </li><li>上一手交易是买卖、继承还是赠与（上一手交易是继承或赠与的，这次交易的税费会比较高）；  </li><li>合同中房屋描述是否和房产证一致；  </li><li>是否注明车位，包括车位号、车位有无产权等，车位是否有租赁、租期多长、有无合同，车位过户的具体流程及需要的材料；  </li><li>是否说明价格是否包含家具家电（家具家电如何处理需要和卖方协商）；  </li><li><strong>是否有抵押、查封、设立居住权</strong>等情况（中介一般会帮你查，但最好自己再去查一下，网上一般各市都有途径线上查的）（如果有，推荐远离。也可以毫不留情再砍一刀并了解详情，并在后面做出风险规避措施）；  </li><li>是否带有租赁合同（买卖不破租赁，如果有个20年的租赁合同，可就麻烦了）；  </li><li>物业（包含车位管理费、滞纳金等）、水电燃气欠费情况；  </li><li>卖方是否还有贷款未偿清，如有具体金额是多少；  </li><li><strong>确认支付方式，若贷款，请提前保证贷款资格没问题</strong>（尤其要注意公积金，是否有非正常缴纳的情况）；  </li><li>确认房屋户口情况，以及户口何时迁出（这个还好，我们市有强制迁出政策）；  </li><li>定金、首付、贷款、尾款、中介费的支付时间，尤其是中介费尽量别开始就全交了；  </li><li><strong>违约责任</strong>，重中之重，最起码得对等，也可以就上面一些你需要确认但无法当场确认的事项进行协商，加入违约责任；  </li><li>是否写明走<strong>资金监管</strong>流程（推荐、比较省心）；  </li><li><strong>最好注明</strong>： 如网签合同与本合同有冲突，双方均认同以本合同为主（因为网签合同一般都不会很详细，但很多地方都主要看网签合同，这里可能会产生风险）；  </li></ul><h2 id="备资料">5.3&emsp;备资料</h2><p>合同签了、定金交了，等首付款齐了就可以约时间准备网签了。中介一般都会提前把需要准备的材料发你，大概有（单身人士版）：  </p><ul><li>一年银行流水（APP下载）；  </li><li>收入证明（公司开）；  </li><li>详版征信报告（找网点打印，注意必须是详细版）；  </li><li>身份证户口本；  </li><li>银行卡（我网签时就忘记带了）；  </li></ul><p>这个阶段可以跟中介说偏向去找哪个银行贷款，让中介联系银行相关负责人（利率我们这现在各大行都比较统一）；  </p><h2 id="网-面签">5.4&emsp;网/面签</h2><p>材料备齐，跟公司请个半天假，再次来到了我爱我家总部，卖方和银行工作人员都也到了，中午12点多便有许多人在办手续了。<br>这个流程就是需要签字的材料特别多，一不小心就陷入了闷头签字的状态，这里还是也想几点注意事项吧：  </p><ol><li>首先明确网签和面签的概念，网签指的马上要签的《存量房买卖合同》（二手房情况），它是要上房管所备案的（防一房多卖），主要起公示作用；而面签指的是指买卖双方当面签署网签合同这样一个过程；  </li><li>网签合同金额可能和前面签的合同总金额不一致（如尾款未算进去、或者故意做低网签价），需留意一下；  </li><li>网签合同可能没有注明三方合同里的一些信息（如车位等），问可不可以加（有可能不行，所以最好在签三方合同时就规避掉该处风险、因为网签合同签完不代表三方合同就失效了，仅有互相冲突的地方可能产生风险）；  </li><li>银行贷款要签的材料特别特别多，包括借款抵押担保合同、征信信息查询、使用授权书、个人贷款凭证、贷款合同等，主要关注的是能选择的地方：如<strong>贷款金额、贷款偿还方式、是否浮动利率、利率调整期限、利率调整时间</strong>；  </li></ol><h2 id="等贷款">5.5&emsp;等贷款</h2><p>公积金贷款大概要2周，商贷1周左右，总体来说还是比较速度的。<br>等贷款的过程中可以要求再去房子里看下（并录视频），同时解决所有还仍未能确认的遗留事项，在这个期间如果需要签署补充协议也可以尽快提出一起讨论。  </p><h2 id="缴欠费">5.6&emsp;缴欠费</h2><p>缴欠的物业、水电燃气费用，这个可能在有的交易中是在过户后进行的，但还是比较推荐过户之前（当天）解决，免得遇上中介收了尾款跑路、房东过完户失联等奇葩情况。  </p><h2 id="再验房">5.7&emsp;再验房</h2><p>推荐过户之前（当天）再去验下房，重点看家电家具是否完整，有无偷天换日（当然对于本身就是垃圾家电的情况就不需要在意了，反正要换的）。  </p><h2 id="补协议">5.8&emsp;补协议</h2><p>有什么需要补充的协议一定要在过户前签好，不然还指望着过完户对方再低声下气地和你签？  </p><p>我是在过户那天上午和卖家签了<strong>车位的使用权转让协议</strong>，因为我们市车位很多都是无产权的人防车位，物业一般认开发商和业主签的车位使用权合同。当权属发生变化时再签个协议按理说是十分自然的，不过很多地方都并没有强制要求，为了保险和规范起见还是签一个为好。  </p><h2 id="办过户">5.9&emsp;办过户</h2><p>贷款审批通过并放款到监管账户之后，就可以约时间去办理过户手续了，就是去房管所登记拿房产证（我们市一般等1个小时就出证）。  </p><p><strong>推荐在过户前办完所有对方可能收钱之后翻脸不认人的事项</strong>，如前面说到的<strong>缴欠费、再验房、补协议</strong>等。  </p><p>过完户会自动触发监管，然后账户里的钱过几天会自动划转到卖方账户里，标志着房屋在法律上的权属正式发生了变更。过完户如果钱都已经交了却还有没有办完的事，那就比较尴尬，只能祈祷中介和卖家人品在线了。</p><h2 id="房交付">5.10&emsp;房交付</h2><ul><li><p>验：核验水表、电表、燃气表等读数，确保数据准确。  </p></li><li><p>交：交接钥匙、物业手续、原房主的材料（如合同、发票、维修基金缴费凭据）等，完成交付流程。  </p></li></ul><h1 id="搬新家，成房奴">6&emsp;搬新家，成房奴</h1><p>经过近一个月的流程，我终于拥有了人生中的第一套房子，并且成功地背上了几十年的负债（笑），接下来便是系统性地清洁和必要的装修（又是个大工程），然后根据需要调整家具布局或购置必要的家居用品，使新家更加舒适（陆陆续续花了我两周才彻底弄好），最后便是搬家整理物品，享受今后的新生活~  </p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-12-21-er-shou-fang-jiao-yi-liu-cheng-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>关于个人博客未来方向的一点思考</title>
      <link>https://chengpengzhao.com/2024-12-20-guan-yu-ge-ren-bo-ke-wei-lai-fang-xiang-de-yi-dian-si-kao/</link>
      <guid>https://chengpengzhao.com/2024-12-20-guan-yu-ge-ren-bo-ke-wei-lai-fang-xiang-de-yi-dian-si-kao/</guid>
      <pubDate>Fri, 20 Dec 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;过去：博客的发展历程&quot;&gt;1&amp;emsp;过去：博客的发展历程&lt;/h1
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="过去：博客的发展历程">1&emsp;过去：博客的发展历程</h1><h2 id="初衷">1.1&emsp;初衷</h2><p>最近在整理很久没有更新的博客（最近几年都是一年更新一两篇，还都是春节的时候才想起来），忽然发现竟然已经过了这么长的时间，自己也从一个无忧无虑的青年变成了一个无忧无虑的大叔🧔。<br>回想起当时创建博客的初衷：那是2019年的春天，世界还没有经历新冠疫情，我还在读硕士，某天晚上学习遇到一个专业方面的问题书本上找不到答案，于是打开万能的谷歌浏览器开始网上冲浪，最后在一个大佬的个人博客（记不清是哪个了）中找到了答案，顺便把他的博客翻了个遍，顿时觉得好炫酷啊！就像小朋友看到别人的玩具时自己也想要的心情一样，我也顿时产生了创建自己的个人博客的想法。然后就把这个想法化为了这个网页。<br>当时完全没有仔细考虑过该写什么样的内容（先来一篇hello world再说），整天想着页面还有哪些地方不合我的意、怎么把这里那里修改一下，就好像在装饰我的新房，觉得这里要有个这个家具、那里应该有个xx风的装饰之类的。<br>不过不得不说一个人的喜好（品味？）确实很难改变，我这几天想过换个风格于是把hexo所有高star的主题都逛了个遍，但最后还是觉得原来的才是最好的。整体的思路是既要在一定程度上保证简洁（少放大图、动态等效果），但也要保证有点酷酷的感觉（主页风格）以及较完善的功能（<em>归档目录标签关于</em>各种页面都得有），于是最后只是在导航栏排版上稍作了调整（删除了书影音这些感觉有点多余且构建麻烦的东西）。</p><h2 id="成长与收获">1.2&emsp;成长与收获</h2><p>如果问我写博客的过程中有没有什么成长与收获？我的回答肯定是有的，任何事情都会让人成长和收获一些东西，虽然这个事情可能有时并不是什么好事。<br>但写博客这件事肯定是件好事，对我现在工作的帮助作用也是挺大的。因为hexo这些大多在linux系统中弄比较合适，而当时的我是个纯萌新，花了好一段时间学习各种基本知识，当时积累的一些常见命令或是vim的用法现在每天都会用到，无形中让我的工作效率可以保持一个好的水准。<br>此外，写博客本质是一种写作行为，写作是一项不仅能提高表达能力，还能锻炼逻辑思维的重要技能。通过写作，思维得以组织和整理，帮助我们更加清晰地表达复杂的思想。有很多人上了大学之后就再也没有写过作文，往往是因为没有推动力，而建立个人博客这个行为恰好提供了这样一种表达和创作的通道、提供了一种让你去思考、去推敲、去自我审视的理由，而且你也可以通过留言来建立和其他博客的关联、收到他人的反馈。  </p><h2 id="挑战与不足">1.3&emsp;挑战与不足</h2><p>回顾自己以前写的博客，发现最明显的缺点有两个：  </p><ol><li>半途而废，很多博客在写的时候就没有构思好完整内容是什么样的，或者说当成了每日任务的形式，就自己那点自律很容易最后烂尾（事实也确实如此= =）；  </li><li>时效性，这点可能是很多技术类文章最头疼的地方：技术是不断向前发展的，有可能过了一两年你现在写的技术就已经淘汰了或者明显有更好的方案。作为作者当然还是希望自己的文章能够产生价值的时间更长一点，所以今后这一点可能得多注意以下。  </li></ol><h1 id="现在与未来：反思与调整">2&emsp;现在与未来：反思与调整</h1><h2 id="当前的定位">2.1&emsp;当前的定位</h2><ul><li>内容领域的聚焦</li></ul><p>当前本博客的内容还是主要以个人技术、经验、思考的分享和记录为主（将来也是）</p><ul><li>读者群体特征与偏好  </li></ul><p>读者？没几个人看的博客还关心这个？至少对我来说，博客的本质有些类似于小朋友的玩具，首先是为了自我满足，其次才是与他人分享，而最后则可能带有一些炫耀的成分。就像孩子们通过玩具来获得乐趣与成就感，博客的创作也是一种个人表达和情感寄托的方式，更多时候是为了实现自我价值的展示，而与他人互动或引发关注则是次要的附加目的。  </p><h2 id="现阶段问题">2.2&emsp;现阶段问题</h2><p>现在的问题就是太久不更新，处在休眠状态。（懒）</p><h2 id="反思与调整">2.3&emsp;反思与调整</h2><ol><li>太久没更新除了懒还和写博客环境有关，还和工作流没有设置得足够简单和完善脱不了干系。之前一直用的电脑坏了，部署博客还遇到一些报错，要是早点把GitHub Actions啥的用上、早点去掉那些乱七八糟的插件，也不至于休眠这么久；  </li><li>针对信息的时效性问题，一是要在写博客是注意尽量讲通用技术而非聚焦于某种特定方法，二是要增加文章的时效性提醒。  </li></ol><h1 id="总结">3&emsp;总结</h1><p>总的来说就是博客还是要写的，内容不一定要多细节有用即可，然后就是怎么方便省事怎么来。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-12-20-guan-yu-ge-ren-bo-ke-wei-lai-fang-xiang-de-yi-dian-si-kao/#disqus_thread</comments>
    </item>
    
    <item>
      <title>不老缺席的长生</title>
      <link>https://chengpengzhao.com/2024-02-11-bu-lao-que-xi-de-chang-sheng/</link>
      <guid>https://chengpengzhao.com/2024-02-11-bu-lao-que-xi-de-chang-sheng/</guid>
      <pubDate>Sun, 11 Feb 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;时间自由与不朽之躯&quot;&gt;1&amp;emsp;时间自由与不朽之躯&lt;/h1&gt;&lt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="时间自由与不朽之躯">1&emsp;时间自由与不朽之躯</h1><p>长生不老一直是人类追寻的一个目标，提到这个词语，我的脑中首先联想到的是佛神、仙药、炼丹、蓬莱岛、徐福……这些关键词大多带有些许宗教信仰色彩，作为中国人自然就是道教和佛教。反观西方，基督教旧约圣经中有生命树使人不死，古希腊宗教中有肉体的不朽和与灵魂的永久结合等，还有就是吸血鬼这一由人类创造的非常接近长生不老概念的存在等。  总之，正因为人类个体的存在如此渺小与短暂，大家才一直追逐着“永远”，“永久的生命”、“永葆青春的肉体”、“永恒的情感”……<br>不同语言可能表达方式略有不同，下面我想从中文的角度简单理解一下长生不老这个词。<br><code>长生</code>，<strong>长</strong>为带有主观意识的时间尺度概念，隐含的比较基准应该为当前时代人类寿命的极限吧。毕竟人类文明的历史按照最长来算大概几百万年，而相对的地球的历史如果浓缩成一小时，陆生动物则是在倒数6分钟时才出现。人类的历史相对于人类的文明史而言无比漫长，但和地球的历史比起来则无比短暂。因此，我认为“长”这个字是非常暧昧不清的、阐述主观评论而非客观描述观察结果的一个词，相较而言“永”则对时间的描述更为清晰。也许是第一次提出”长生“这个词的人并没有想活得那么长，亦或是随着时代变迁一些词语的含义发生了细微的变动罢。<br><strong>生</strong>，生命的状态，按照当前科学水平来说，生是指有机体存在和活动的状态，涉及从分子和细胞水平到整个有机体水平的复杂现象，与之相对的”死“则为生命的终结或停止、器官的衰竭和生物体的分解。当然我相信未来“生”的概念会发生改变，生命的形式可能会更加多样、生命和有机体的关系可能会减弱。<br><code>不老</code>，更多地描述有机体的良好状态，更具体的描述如青春永驻、健康强壮、长寿不衰…表现为一个人能够不受岁月的侵蚀，拥有强健体魄和强大免疫力，不受疾病侵扰，皮肤容颜保持年轻，不会有衰老痕迹…也有观点认为“不老”还包含心理和精神层面，个体的心智和情感状态可能保持年轻、充满活力，不受精神衰老的影响。<br><br><br>总而言之，长生不老反映了人们对于超越生命周期限制的愿望，长生强调的是生命的延续，不老侧重肉体的健康状态，虽强调的方面略有不同，但都是文化、宗教和哲学传统中经常涉及的主题，代表了人类对生命意义和超越死亡的思考。</p><h1 id="日积月累的微小绝望">2&emsp;日积月累的微小绝望</h1><p>在人类对自身的奥秘解析还未透彻的当下，长生仍未能摆脱肉体的限制，因此长生通常还需不老相伴。<br>试想一下“长生缺席的不老”，与其说是理论设想不如认为是实际追求，是现实中人们对于健康、活力和生活质量的实际追求。通过基因疗法、抗衰老药物、细胞修复、健康的生活方式等手段人类已经能够做到防止老化、维持生理和心理的健康状态，即使寿命不会因此得到延续。<br>而”不老缺席的长生“，在我看来是一种更为另类的状态，是一个充满绝望感的短语。我想只有那些拥有强烈执念的人才会不考虑衰老而仅追求寿命的延长吧。如果把”长生“的概念放宽些，那么”不老缺席的长生“则是那些长寿老人在生命接近末期阶段的真实写照了吧。<br>    我爷爷奶奶应该算长寿了，小时候记得周围总有人说到”哎呀，你们已经七/八十岁了啊！完全看不出来，身体真健朗啊！“之类的话。然而，时间是残酷无情的，当初就算身体再怎么好，随时光流逝和微小病痛的积累摧残，也都会不复当日。我大一暑假回家时，他们仍能独立乘火车出远行；我大三暑假时，他们仍能在家周围散步购物；我读研时，他们仍能在小区内缓步；直到我工作后过年回家时，忽然发现他们的活动范围已经只剩下了家中的几个房间。<br>    我有时候也会想，会不会下一次就只剩下了他们的痕迹？我是比较抗拒离别的类型，记得小学5、6年级的时候放假哥哥过来带我玩，当他走后我总是有很长一段时间常常在教室外的走廊上望着远处的风景怔怔出神，仿佛心里缺了点什么。  因此，我变得开始有点害怕回家过年。<br>    2023年春节的时候，我担心的事还是发生了，那天奶奶正在阳台，我做在屋里的沙发上忙着配置MacBook的nvim环境，忽然听到一声不妙的闷响，抬头一看发现并没有捕捉到她的身影，顿时心里咯噔一下，起身赶去发现奶奶已倒在地上，头部伴有出血。喊家人一起扶起并处理后准备打车去医院检查，期间我一直在为头部止血，虽流血不严重但难以完全止住，也许是年龄大止血系统也退化了。由于是春节期间，到医院做检查流程较顺利，但根据奶奶身上的疼痛情况可认为出现了骨折，我能做的只有期望内伤不要严重，毕竟老人家骨质疏松、康复周期很长。首要任务是处理头部外伤流血，于是让外科医生缝了几针，并套上了弹力网帽，每隔几天需要换药，10天左右后再来拆线。由于我的假期很快结束了，后面几乎都是爸妈两人来处理的。<br>    2023年秋，我听闻奶奶又摔跤了，而且比较严重（毕竟之前的伤肯定都没有痊愈），需要住院治疗、还得做手术，我当时就愣住了，心想年纪这么大了还能承受住手术么。不过最后手术还是顺利成功了，中途还有个因肺部感染导致手术延期的插曲。但是对于骨折，手术能做的很有限，最后还得靠身体慢慢恢复。秋去冬来，当今年春节我回到家时，奶奶虽已出院几月，但仍然处于无法走路的状态，生活不能自理。由于爸妈平日要上班家里也请了护工照料，不过过年期间还是得自己来照顾。我也首次近距离体会到了照顾瘫痪病人的挑战性和瘫痪在床的人的无助和绝望，以及自己的无能。<br>    我想，奶奶一定不止一次、反反复复的想着“要是自己死了就好了”之类的话，我也确实亲口听她说过几次，虽然我们每次都会立马反驳她，但其实说不定在心里也会觉得与其痛苦的延续不如轻松的逝去吧。如果我变成这个状态的话应该会想方设法追求安乐死吧，如果实在不行就选择一种只有一瞬间痛苦的死法。言归正传，不分昼夜地躺在床上，失去了唯一消磨时间的手段——电视，想必每一天都十分难熬吧。逐渐地，语言功能退化，四肢功能退化，人的尊严被疾病践踏，每每将自己代入这样的场景便感到十分悲哀。我心中忽然浮现炼狱这个词，但细想又不太符合，毕竟并没有人犯下什么罪过，而且就算是神曲中的炼狱也能够看见山顶升入天国的道路。<br>    照顾瘫痪在床的人，包含身体护理、床上护理、饮食和喂养、医疗管理、心理支持等方面，实在不像是一个素昧平生非亲非故的护工能做得好的。擦拭身体、更衣、处理排泄物、床单衣被清洁、预防褥疮、沟通互动、备餐喂食、突发状况处理……在这方面我感觉到很无力，认为自己做不好这些，会不由自主地将眼移到别处。然而父母却丝毫没有逃避，将这些都做得近乎完美，让我感到十分敬佩，不得不对他们说句辛苦了。<br>    或许有一天，我的父母也会变成这样的状况，到那时，我真的能像这样照顾好他们么？还是说我会不等绝望的积累而去追寻各种方法来让他们安详解脱？现在的我似乎还回答不了这个问题。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-02-11-bu-lao-que-xi-de-chang-sheng/#disqus_thread</comments>
    </item>
    
    <item>
      <title>爷爷的重要记载</title>
      <link>https://chengpengzhao.com/2024-02-09-ye-ye-de-chong-yao-ji-zai/</link>
      <guid>https://chengpengzhao.com/2024-02-09-ye-ye-de-chong-yao-ji-zai/</guid>
      <pubDate>Fri, 09 Feb 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;重要记载，注意保存&lt;br&gt;此本所载于2014年8月
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p>重要记载，注意保存<br>此本所载于2014年8月收集整理，以后逐步补充，充实内容</p></blockquote><p>注：</p><ul><li>历史是由无数个看似微不足道的个体行为组成的</li><li>未看懂的字用<code>？</code>代替  </li><li>记载中尽量省去了姓名  </li><li>由于本人字迹辨认能力有限，部分地方可能有错误</li></ul><h1 id="老照片">1&emsp;老照片</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402081337810.jpg" alt></p><h1 id="记载汇总（杂）">2&emsp;记载汇总（杂）</h1><ul><li><p>两位老人墓地： 于2006年11月11日定岳阳市长山永久陵园墓地，？华豪型，位于上团山区C9排，双穴墓。修建编号即墓地证书号为1701（07.4.15验收）  </p></li><li><p>生庚八字： 爷爷<code>辛未腊月初九亥时 35钱</code>、奶奶<code>丙子七月廿午时 50钱</code></p></li><li><p>旅行记录：</p><ul><li>首次去上海：2006年7月3日，我们三人从岳阳起程，武汉住宿，次日乘火车，5号上午达上海，在xx家21天与7.26离开上海乘火车，7.27往长沙，回家。  </li><li>首次去海口：1987年4月13日，起程到岳阳，14到武汉，4.16乘火车次日深夜到长江，随乘汽车到海安已时达凌晨1点。4.18乘海轮，下午2点到达海口市。187医院xx家居住一个月。5.17上午乘飞机到广州，5.20下午乘火车到岳阳，中午12时到家（华容三中）。</li><li>二次去海口：1992年3月3日去4月20日返回，住一个多月，其他不详。</li><li>三次去海口：2009年1月13日（腊月十八日）下午8点乘火车到广州，1.16上午乘飞机到海口，于2.5号（正月十一）乘飞机回岳阳。其中在三亚玩了3天。</li><li>四次去海口：2014年9月13日从岳阳起程到深圳，22号上午xx接我们同机到海口。居住半年之久。于2015年3月21号乘飞机到深圳xx家。具体时间为2014年9月22日——2015年3.21日整6个月。此时间内我们到了文昌市（1日）、儋州市（4晚）。此时间内我们两人在解放军187医院（10.10号）进行了全套体格检查（结果见体检报告书）。</li><li>迁居武汉：1989年10月27日，我们带有xx三人，从三中专车送往武汉，准备靠长子安度晚年，因意气不和于1990年5月又专车送回华容三中（只居住了八个月，扫兴而归）。</li><li>二次去广州过年：2012年1月18日（腊月廿六日）从岳阳乘火车到广州，xx一家同去。我们于1.31号即正月初九返回岳阳（28号——正月初六去深圳xx家）</li><li>去北京游览：由xx带领我们两老于2010年10月13日晚乘火车，14号下午2点到达北京。参观了天安门广场、登上了天安门城楼，瞻仰了毛主席遗容，观看了大礼堂、故宫，到达了八达岭长城、十三陵、香山红叶、鸟巢水立方、国家体育馆、圆明园、颐和园等几十个名胜古迹。于10.21号下午3:45乘火车22号早上6:00到岳阳回家。</li><li>补记：<strong>首次在广州过春节</strong>，2005年2月2日（腊月廿四日），住了15天于2.17（正月初九）返回岳阳；<strong>三次去广州过年</strong>，2017年1月21号（腊月廿四日）从深圳去广州。于2.6（正月初十日）三人同返深圳；<strong>去香港</strong>，2016.10.4四人同去香港。  </li></ul></li></ul><ul><li>胞兄xxx遗作（写于一九七七年五月）</li></ul><blockquote><p>抒怀（仿五言古体诗）并序<br>父病床褥，度日如年，回忆往事，泣涕涟涟。叹旧社会，<br>遗恨未消，感新社会，恩愤未报。有亲不能奉养，有妻不能<br>白首，已矣呼！岁月虚度，一事无成，恨何x也。又不联篇，<br>笔墨生疏，聊仿古意，以抒我怀。<br>未曾提笔写，热泪洒胸膛。行年五十五，病痨三十三。<br>回想旧社会，遗恨万年长。阶级剥削重，霸王黑心肠。<br>感谢毛主席，恩情重如山，解放全人类，穷苦得身翻。<br>终身犹有恨，亲恩未能忘。夫妻恩爱重，手足性谊长。<br>世人为我叹，我为们道伤。犹子满膝下，愧我教无方。<br>社会主义景，光彩耀人寰，推陈又出新，越来越好看。<br>总是人要死，难过百岁关。既无x生笔，又无不老方。<br>打破痴梦想，看透人生观。我死如鸿毛，遗恨在人间，<br>取尽南北竹，恩怨写不完。骨骸x所置，荒草满山岗。</p></blockquote><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402081502258.png" alt></p><h1 id="寿诞纪庆活动">3&emsp;寿诞纪庆活动</h1><ul><li><p><strong>爷爷七十大寿</strong>： 2000年提前在6.10（农历五月初九日）居住花容三中，酒宴设在东山镇信用社酒楼，亲朋十五桌。华容县政委贺送寿匾：“寿”；  </p></li><li><p><strong>奶奶七十大寿</strong>： 2006年提前在4月14日（农历三月二十日）居住岳阳制药一厂，酒宴设在岳阳市九华山路北源酒店，亲朋十来桌；  </p></li><li><p><strong>爷爷八十大寿</strong>： 2010年提前在10月2日（农历八月二十五日）居住岳阳制药厂，酒宴设在岳阳市站前路红日大酒楼，亲朋二十余桌。庆典较为隆重，祝寿、敬酒、摄影等活动。县教育局送贺寿匾：“领班授业，誉满华容”，华容三中送贺寿匾：“师德承高远，桃李艳神州”，自作寿联一幅，贴在门前：“人生八旬，修身严谨，子女器成，可欣可慰；执教四十，爱岗敬业，桃李芬芳，无愧无憾。” 横批：”耄耋年华“。</p></li><li><p><strong>奶奶八十大寿</strong>： 提前在2016年春节（正月初三）全家人聚在岳阳时祝寿，在岳阳市九华山洞庭湖鲜楼举办庆典。  </p></li><li><p>爷爷八十寿诞庆典会上的讲话稿</p><blockquote><p>来宾、亲朋、女士们、先生们，大家好！<br>在这改革开放的年代，在这举国上下欢庆之时，在这秋高气爽金秋之际，迎来了本人80岁的生日。<br>今天承蒙各位前来祝贺，特别是有制药厂的领导、有华容县教育局的领导、华容县第三中学的领导亲临祝贺，我x蓬荜生辉、三生有幸、感到十分喜悦。在此，我及其全家对各位的到来表示热烈的欢迎、并致以诚挚的谢意。<br>我是经历了两个朝代，跨越了两个世纪的耄耋年华的80岁老人。昔日人云：人到七十古来稀，而今朝活到80更是稀奇。80啊，在这个漫长的岁月，生活得不平常。回首往事，记忆犹新，所见所闻，历历在目。我的一生是不平凡的一生，是艰苦奋斗的一生，是先苦后甜的一生。我的童年是苦难的、少年时期是艰难的、青壮年时期是幸运的、老年时期是幸福的。<br>由于我老两口自身严谨、艰苦奋斗、勤俭治家，在工作之余，辛勤地培育五个子女，成人成才，个个大学文化，人人事业有成。分别在大城市工作。我有六个孙子，已有三人大学毕业，分别在上海、广州、海口工作。唯有的独生孙女，大学毕业后考研，又读了硕士研究生，现已毕业几年，品学兼优。在学校入了党，年轻的共产党员，德才双馨，被中央国营企业招聘录用。还有几个孙子，在初中、高中攻读，成绩优秀，xx可佳，成才在望。<br>由于子女的器成，孙孙们的掘壮成长，我感到十分高兴和无比的欣慰。我是干教育工作的，忠诚党的教育事业一辈子。工作43个寒暑，学生数以万计，桃李满神州，无愧于党的教育事业。<br>为此，我80寿辰之际，我拟了一幅对联，以抒情怀，以活人生。<br>上联： 人生八旬，修身严谨，子女器成，可欣可慰<br>下联： 执教四十，爱岗敬业，桃李芬芳，无愧无憾&gt; 横批： 耄耋年华<br>最后祝各位：事业有成，合家安康。<br>2010年10月2日于岳阳</p></blockquote></li></ul><h1 id="家庭情况">4&emsp;家庭情况</h1><ul><li><p>祖籍地点：华容县塔市乡桂竹村第七队（赵家坊）  </p></li><li><p>家庭经济状况：</p><ol><li>解放前1942年（我十岁开始懂事时）家有瓦房一栋，明三暗六，水田6石（42亩），洲田40亩，分别与自姓人合庄，三？口，我家应有水田4石（28亩）；</li><li>解放前1948年，瓦屋六间，水田4石，旱地3亩，疏于耕种；</li><li>土地改革时，1952年成为中农身份，合作化时，土地全部入社。</li></ol></li><li><p>房屋变动情况：祖x两层两厢，房一大栋10间瓦房，于1939年洪水淹没倒塌。1942年母亲新做瓦房一栋，明三暗六，居住多年。1972年正月，我个人自做新房一栋，明三暗六加？？共计九间土砖瓦房，供母亲、哥嫂居住。后因全家都转入城镇居民，吃国家补，家里无人居住，将此房于1985年八月十六写字出售给自家人xxx。</p></li></ul><h1 id="个人简历">5&emsp;个人简历</h1><p><strong>首先是爷爷的部分</strong></p><blockquote><p>我生于1931年腊月初九日亥时。出生时父亲已去世了三个月。我这个遗腹子由母亲一人抚养。<br>兄弟姐妹四人全靠母亲一人抚养，多么艰难，多么辛苦。<br>我8岁时，入蒙学，上私塾，从师xxx。从那时起，断断续续，从师xx、xxx、xxx、xxx，在私塾、小学读了三年。空隙时间在家放牛做杂事度日。<br>1947-1948年在塔市完小读国民小学（高级小学）一年半，校长xxx，教导xxx，班主任xxx老师。<br>1948年下期-1949年上期在华容黄湖山中学（现在的华容一中）初中读书一年，校长xxx，班主任xx。<br>1949年我地解放了，下半年落家种田到次年7月。<br>1950年8月，由xxx老师介绍，参加教育工作，先后在洪仙庙、新堤、老x、x泥等地教小学五年。1955年被评为全县优秀教师，于当年8月调到塔市完小教书。<br>1956年前往常德师范学习培养提高，当年8月回塔市完小教五、六年级语、数主课。同年九月廿八日加入共产党。<br>1958年我任塔市完小校长，教导主任xxx。<br>1958年下期，我县建立人民公社，我被县组织部任命为东山人民公社联校校长，管辖七个校的教育工作，当年教育局建立党的基层组织，任命我为东山联校党支部书记。<br>1962年调任胜丰公社联校长、党支部书记。<br>1963年-1966年7月任？桥联校长党支部书记。<br>1966年8月-1974年10月回任胜丰联校长、党支部书记。<br>1974年11月-1979年8月，任塔市联校长、党支部书记。<br>1979年8月-1982年，调任华容县第三中学校长、党支部书记。<br>1983年-1984年8月，任华容三中党支部书记。<br>1984年9月退居二线。<br>1993年元月退休。<br>于2000年12月3日即冬月初八搬迁岳阳靠次子xx，居住岳阳市岳阳楼区九华山南路31号。</p></blockquote><ul><li>工作时的经济待遇</li></ul><blockquote><p>由参加工作时的每月大米80斤-100斤，由工分制的100-130分（10元-13元），由人民币27元-37元-45.5元-53元-59元-66元-74元-137元-148元-184元（88年）-205元（90年）-252元（92年），到93年退休时267.3元。<br>退休工资，从93年1月294元-同年4元374.3元。<br>从94年8月514.7元-97年10月545.7元。<br>从99年7月665.1元-2001年10元910元。<br>从2006年1000.1元-同年7月1236.3元。<br>从2009年1月1942.3元-2011年1月2081.3元。<br>从2012年1月2211.3元-2014年1月2361元。<br>从2014年1月起2611元。<br>从2014年10月起3051元。<br>从2016年1月起3286元。<br>从2017年元月起3430元。<br>从2018年元月起3924元。<br>从2019年1月4294元。<br>2021年7月4676.5元。  </p></blockquote><ul><li>政治待遇</li></ul><blockquote><p>1955年被评为华容县优秀教师后，1957年、1962年、1964年、1969年、1974年、1978年、1982年先后多次被评为县级先进工作和优秀共产党员。<br>1959年、1965年、1972年、1978年选为县党代会代表。<br>1958年、1962年、1963年、1965年、1972年当选为县人大代表。<br>在教育工作时，离单位外出搞中心工作：1961年10月-1962年1月在县委？传调出搞调研，在胜丰公社石伏山大队同xxx两人与群众同吃同住，搞调查研究工作三个月。<br>1964年上半年同xxx在东山公社红莲大队搞社教工作四个月。<br>1964年9月-1965年8月随华容总分团在湘阴县白马镇姑嫂公社清河大队搞社教工作一整年。象搞土改一样，访贫问苦，扎根串连与群众同吃同住同劳动。所谓“三公”：办事是包公、劳动是长工，吃饭是斋公。<br>2021年7月1日建党100周年时，中共中央授与“光荣在党50年纪念章”1枚，最高荣誉。</p></blockquote><ul><li>个人疾病情况</li></ul><blockquote><p>一、肾绞痛：（确症为肾结石）</p><p>第一次发痛：1974年4.15早5:40（在胜丰联校）突然发痛整天。4.16上午用救护车到县人民医院确症为肾结石，住院12天，于4.27上午出院。</p><p>第二次发痛：1978年8.30早饭后（塔市教育组）突然剧痛，乡卫生院治疗三天无效于9.22到县人民医院住院治疗9.7出院，继续在乡卫生院诊治月余。</p><p>第三次发痛：1984年（在华容三中）9.3晚10时剧痛厉害,凌晨1点到东山医院，4号服药打针，9.14去县医院照片（?，显形）以后又反复痛了几次，于10.10去武汉治疗（同济医院、协和医院）效果不明显。又在1987年5月到海南187医院，做B超造形，仍不明显。以后坚持服排石药物，长时期的不断排出结石，没有发痛无感觉，但肾内还有结石。</p><p>从94年开始排石—2000年共排出结石110多粒。</p><p>二.心脏血压</p><p>1992年2.5（正月初二）早睡在床上，觉得心跳过速（约140），一个小时后自然恢复复正常。<br>1992年12.9上午心跳过速，并无规则的时快时慢，血压（90—140），心电图正常。在此期间，<br>服用丹参痛？？药物。<br>从2001年3月初，心脏用药：地安心血康.丹参滴丸。<br>以后多次在岳阳阳市二医院诊治做心电图、动态心电图，结论是心脏有？？冠心病、不严重。<br>2005年服用的药物：卡托普利、倍他乐克、消心痛、丹参滴丸等。<br>以后在武汉在广州均做过动态心电图。<br>血压：长时期的自我检查：作了几年的记裁。一般：<br>上午血压：60-130，下午60—140，结果血压偏高。<br>从2012年底一现在（2014.8）服用药物：xxx，有时急性发作时加服速效救心丸。</p><p>重患肾结石：2015年8月底血尿几次后到10.21，左肾剧痛约4个小时以上，于11.2号中午排出结石1粒（约豆子大）<br>患胆结石、尿路结石、前列腺肥大，还有血压心脏病一起于2017.7月初在岳阳初患胆结石，市一医院治愈，8月初在岳阳发肾结石带病返回深圳，多次去深圳市北大医院泌尿外科知心血管内科就诊，历时40多天花钱万余元，基本治好，但又有反复。</p><p>2017.12.20洗澡后出现头晕、站不稳，次日去深州北京大学医院就诊脑出血，医生建议住院治疗，当时无条件，只好门诊治，吃药四个月效果果不佳。<br>肾功能不全，肾结石复发住院：2019.5.18号入院—光明人民医院肾内科住院部312房41床位，5.31号出院共花两个星期。共花21704元，国家报销63％，计10104元。个人开支11600元。后又住了二周。此次住院，医生给故疾：心脏、高血压作了结论正常。从此未服此病药物了。</p><p>三、手臂痛颈椎病：手臂痛疼多年多地求医，海南军医院上海广州岳阳等地医治无效。<br>后到深圳南山人民医院诊治，检验确诊为”尺神经炎”，吃药诊治也效。<br>后到2020年9.26号深圳光明人民医院神经内科求治，检查确诊结论为“劲椎病”，现在正在治疗中，目前效果不佳。现在除手臂症状以外，还增加右腿疼痛造成行走困难。</p></blockquote><p><strong>接下来是奶奶的部分</strong></p><ul><li>家庭情况</li></ul><blockquote><p>xxx，生于1936丙子年古历七月二十日午时，出于地 址塔市驿清泥湾。<br>祖籍：华容县塔市乡清泥村五组。<br>父亲xx解放前病故，是传泥湾的大地主之一，家有洲田百多亩，另有田庄毛港水田五石（35亩）、瓦房一栋两层两厢房，加二？层计16间，庄屋一栋六间。出租收稞和传长工工耕种，土改时划为地主，因主动将财物金银交给政府，定为开明地主，未戴？？帽子，只是地主成份。<br>母亲.xx生于1906丙午年，冬月八日，家庭妇女。自溢死于1983年古三月十七日。父母均葬在老xx王xx汉姐后山。</p></blockquote><ul><li>简历</li></ul><blockquote><p>七岁时开始读书（私塾、小学）<br>1946年在塔市完小（高小）读书<br>1947年全家迁住岳阳，因病闲住<br>1998年在岳阳西门某高小读书<br>1949-1950年在监利中学（初中）读书<br>1951年在传泥小学教书（代课）<br>1952年在塔市供销社工作（临时工）<br>1953年古七月二十二日结婚，随工作人地点闲住<br>1955年.住塔市场，参加文艺宣传队<br>1956—1957年在东山卫生院学医、工作<br>1958-1961年在塔市卫生工作<br>1962年.在胜丰卫生院、后到？？？工作<br>1963—1969年先在卫生院、？？医疗所、？家诊所工作<br>1990-1972年响应召下放回家.在桂竹大队任赤脚医生<br>1972.8-1976年在？？卫生院工作<br>1976.10-1979.9在塔市卫生院工作<br>1979.10东山？？医院工作<br>1982年12.31退休（病退）</p></blockquote><ul><li>工作时的经济待遇</li></ul><blockquote><p>参加工作时由：<br>9元－18元－28元－34元－39元－44.5元－49元 —59元（退休前）<br>88年退休工资为93.4元<br>1990年130元4角<br>1992年168.3元－189.3元<br>1995年230.11-334元<br>1997年357元<br>2002年420元<br>2006年792元－918元<br>2011年1763元<br>2012年1892元<br>2014年2292元<br>2014年10月起2612元<br>2016年元月2786元<br>2017年元月2967元<br>2018年元月起3224元<br>2018.1 3374元<br>2019.1 3557元<br>2021.7 3927.58元</p></blockquote><ul><li>疾病情况</li></ul><blockquote><p>12岁时即1948年在岳阳居住时，患病严重已死，木框子已做，准备入棺出葬时，慢慢甦醒复活，后经过路郎中医治脱险无恙。</p><p>1976年3月去长少第二附属医院，检查疾病发现子宫一级病变（癌症初期）。<br>老兄xx决定：3.15号入院——？附医院三病房（妇科）观察，准备于3.30上午（历时4个小时）做手术，子宫全切，4月12日出院回家，休假两个月后会塔市卫生院上班。<br>1978年古五月，在塔市卫生院工作时因用青霉素过敏中毒，当时昏倒休克。本院医生无法抢救，人民医院来救护车并随来医4人，经抢救后，随即运往县人民医院急救室，继续抢救。从塔市？东山医理再到县，死达十个小时，于当天下午8时才甦醒复活，住院三日恢复回家。<br>患有多年的胆结石，痛疼难忍，于1995年10.2上午入院（东山地区医院）作体格检查，下午入院，3号上午9点一11点做切除胆手术。从胆囊中取出似绿豆大小般的结石63粒。手术成功，9号拆线，10号出院。<br>21年2.15在深圳骨科医院住院。一月前，在深圳街上走路时不小心摔倒两次，损伤尾骨。住院8天（12.15-12.23）以后在家床上休息。住院期间用钱1万3000多元，国家报销1.2万多元。请保姆于21年12月27号来家。  </p></blockquote><h1 id="五个子女与孙子们的简要情况">6&emsp;五个子女与孙子们的简要情况</h1><p>略</p><h1 id="爷爷的自传">7&emsp;爷爷的自传</h1><blockquote><p> 我是经历了两个朝代和跨越了两个世纪的人，当今耄耋年华、八十高龄之际，我提笔忆往事，历历在目，顺时记下，供后人览之。<br> 我出生于一九三一年（民国二十年间，辛未年）古腊月初九日亥时。苦命的我，未见过父亲，我出世时父亲已死了三个月。我这个不幸的苦命的遗腹子，全靠母亲一人抚养，她人家含着眼泪，把我拉扯大的。可见我当时的生活多么凄惨、多么可怜。我的兄弟姐妹四人靠家产几十亩田地出租收稞。维持艰苦？？的生活。一九三八年老兄结婚，以后金姐、银姐先后出嫁，家里人口减少了，但我母子俩和哥嫂四人同居一家，过着贫寒的生活。当时腐败的国民党政府欺压人民，苛捐杂税多如牛毛。按田亩征收，我家收的租谷，只能交给乡、保、甲，所剩无几，还有亲？统治，教侄欺压孤儿寡母。迫使家里贫困，雪上加霜。后来老兄年青时，换上了肺结核，此病当时是不治之症，治病要钱，家里人生活窘迫，无办法只好年年出卖田地，于是祖宗留下的产业一年比一年减少，直到解放时，所剩无几。所以土改时，家里只划到个中农成份。<br> <br><br> 一九三九年，我八岁时，开始入私塾读书，依启蒙老师xxx在xxx祠堂里，一年半后就停学了，因当时日军侵华已经蔓延全国，我家曾经也驻扎过日本军队。这个时局不稳定、兵荒马乱的年代，哪有安定的绿洲，哪有读书求学的机会。从此以后，只好断断续续的半耕半读。在附近的xxx、xxx、xxx等老师的学堂上了几个半年。这个时候家里生活依然困难，迫使我只能从小就在家里搞些劳动：砍柴、挖？子、看牛喂马、捕鱼捞虾、挑柴叫卖、卖米卖小菜、换回油钱，以补贴家里不足。从那时起，我就从小养成勤俭朴实、热爱劳动的良好习惯。这个时候，不仅家境贫寒，缺衣少食，更有甚者，是世界不太平、局时混乱，日军侵华，烧杀掳掠，皇伪军时常？？抢劫民财，搞得民不聊生，老百姓出境逃难。我家四人，哥嫂外逃华容西乡，我同母亲就近躲藏，以便给家里打点照面。敌来我跑，敌差我回。我母子俩曾在沉塌湖边的？家桥、杂草丛生的树林中躲藏生活。这一个时候，以后附近难躲藏就跑远点。先后分别到？？？的？？庙里，和？？？的黄鹤？等地避难数月之久。那时候不仅生活过的极困难，而且很不安定，度日如度年。我的童年生活基本上就是在这样的环境中度过的。<br> <br><br> 一九四七年，我已经十六岁，重新走上了学生生活。那年的春天哥哥送我到塔市驿小上，校长xxx先生，收进我到塔市完小（国民小学高？部）读书。编入五年级就读。此年级只有六个同学，只好与六年级并班，一个教室里学习上课。由于只上了几个半年的私塾，只识了几个字，数学完全不会，“1+1=2”这个算式根本不会写。进校水平这么低劣，怎么办？由于我有知？？，在艰苦的环境锻炼了自己的我，下决心非常发奋，十分用功，加班加点，在老师的教导下，学业成绩不断提高。半个学期的时间，就赶上去了，数学、作文、自然知识等学科进步很大进步很快，仅花了一年半的时间，学完了四个学期五、六年级的全部课程，提前小学毕业了。<br> 同年六月，高小毕业会全体到县城会考，既是毕业考试也是升学考试。这时，我第一次步入县城，第一次看到了电？，感到十分荣幸，多么高兴啊！同年七月，会考成绩揭晓，我毕业合格，被黄湖山中学（即现华容一中）录取。<br> <br><br> 一九四八年九月初，家里给我凑齐了五十块光洋，作为一个学期的生活费和学杂费，xxx担任？？护送我，两人步行当天到达县城黄湖山中学报到。<br> 该校设有师范、初中两部，我是考入的初中部，编入中五班就读，该班学生90名，一个大教室上课，第二个学期淘汰到只有50名了。我连续读了两个学期，到了一九四九年五月，我县解放了。因时局变化，学校也就提前放假了。回到家里闲着无事。从此再次失学了，这就是结束我的学生生活。回忆起我学生生涯，认真地说就是连续读一年半高小、一年初中，这两年的时间学了点东西。<br> 失学了，怎么办？生活在农村，有业？？，那就是种田维持生活，养家糊口。从此，我就安心的开始做好种田打土块的种种准备，如添置农具、？？备耕工作，砍田坡、挖田角、？？？？、种涤肥、收野粪、耕田耙地，播种各农作物，小麦、大麦、蚕豆豌豆、油菜花，拜xxx为师，靠自己动手，行行先学后做。就这样边学边做，如耕田、犁地、播种、下秧、？？？？、排沟理水，？？？？？<br> 一九四九年冬，我结婚成家，春节后，与哥哥分家立产，各立其业，我分到田地两石多（约20亩），母亲？？水田四斗（三亩）作地和耕田，同我一起吃住。从此我就成家立业，自立门户，自力更生，兄弟俩分家后，仍住在同栋屋，两口灶开火，各自为家。<br> 我是才下学的青年，身体变弱，力量单薄，要担起种植两石田耕耘全部农活，加上农具不全，耕牛缺乏，确实困难不小。各种农活如耕田？？、泡种下秧、中耕除草、插秧收割、拖鞋、扬？样样都要学，门门都是？？干。就这样边学边干，先学后干，逐步掌握了技巧，基本上学会了全部农活。从此，以一个全劳动力的身份撑起了这个家。<br> 功夫不负有心人，辛苦讨了快活吃。当年的气候好，可算还是风调雨顺获得了比较好的收成。收获了20余石，还有小麦、蚕豆、豌豆、芝麻、？籽、？？？、油料作物，当年的生活有了保障。<br> 自一九四九年五月至一九五零年八月，这是我下学后的一年多的时间。这时，我刚从十八进入十九岁的时候，由一个生气十足的青年学生进入了学农务农的农民行列。这是我人生的大转折，由一个拿笔杆、书本的我，上年地搬起犁头、拿起锄头镰刀，天天早起干农活，这是多么困难、多么辛劳，但是为了生活、为了生存、为了养家糊口，不得不坚持下去。坚持就是胜利，从此，我由一个消费者，变成了一个艰苦奋斗、学农务农的生产劳动者，走上了自力更生、自食其力的道路。<br> <br><br> 一九五零年九月初的一天，我在塔市驿上偶然遇上了xxx老师，他推荐我到乡下教书，我应认了，于是他随即给一个课铃、一个闹钟、一盒粉笔，安排我到xxx教书。那里哪是个学校，只有两间屋子，是一个破庙？，什么也没有，要白手起家，办成一所学校该是多么困难啊！于是我就在当地村里，借了一块门板当黑板，找了几张短抽屉做课桌，走访动员了两天，却只来了八个学生，程度不一，四个年级进行复式教学，这算是洪山小学办起来了。以后一边教学，一边下去家访动员、说服劝学，学生逐步增多，可是劝来的学生多数没有钱出学费，只好自己掏腰包，救急贫困学生。当时我的报酬每月大米80斤（价值六元四角钱）？？到村里去收。当时热的不是？？只觉得自己有个？？，又？？自己，还可以提高自己的文化水平。于是我就这样坚持下去，接着先后陆续的分别在xx、xx、xx等地教书思念。由于我教育敬业、工作积极、教学认真，收到了当地的干部群众和家长的好评，评上了县级优秀教师，收到了村、乡、县的嘉奖和表扬。<br> <br><br>一九五五年春，县教育科调我到县第十完小（塔市完小）教课未满一年，即五六年调我轮洲，去常德师范学习深造，提高文化素质以充实自己。领到中师毕业证书后，回原单位任教。接五年级语数教学兼任班主任。同年，我县教育系统开始成立党组，发展新党员。我是第一批入党对象，于一九五六年九月二十八日光荣的加入中国共产党成为光荣的共产党员。<br>一九五七年，反右派斗争后，有不少领导干部批成右派，各级学校领导班子？？？？。此时，我被县任命塔市光全小学校长。<br>一九五八年，我县建立人民公社，我地将东山、塔市、桃花、xx、xx、xx等地共七个分社合并成为东山人民公社，以公社为单位建立联校，管理全社的中、小学校。我被县组织部任命东山人民公社联校校长和党支部书记。<br>以后随着？政体制的改变，公社范围减小，我县后到xx、塔市、xx等分社联校任校长和党支部书记。<br>一九七九年八月，我被县组织调任华容县第三中学当校长、党支部书记，一九八四年下期退居二线，一九九二年底正式退休，也就是我正式告别工作了四十三年的教育战线工作岗位。<br><br><br>                   此件，于2010年10月拟稿<br>                           2016年元旦抄录</p></blockquote><p><strong>附稿</strong></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091451804.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091452516.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091452830.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091453249.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091453632.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091453722.png" alt></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402091454582.png" alt></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-02-09-ye-ye-de-chong-yao-ji-zai/#disqus_thread</comments>
    </item>
    
    <item>
      <title>2023年总结——继续躺的一年</title>
      <link>https://chengpengzhao.com/2024-02-08-2023-nian-zong-jie-ji-xu-tang-de-yi-nian/</link>
      <guid>https://chengpengzhao.com/2024-02-08-2023-nian-zong-jie-ji-xu-tang-de-yi-nian/</guid>
      <pubDate>Thu, 08 Feb 2024 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;小目标回顾&quot;&gt;1&amp;emsp;小目标回顾&lt;/h1&gt;&lt;p&gt;小目标是什么
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="小目标回顾">1&emsp;小目标回顾</h1><p>小目标是什么？只怕早就忘了吧，这里就不回顾了，都躺着了还定什么目标呢~</p><h1 id="2023年总结">2&emsp;2023年总结</h1><p>首先看着2023年的时间都去哪了吧：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402080947784.png" alt></p><p>回顾一下我的时间分类：</p><ul><li>睡眠，毕竟人类的一生有$\frac{1}{3}$的时间都在睡觉  </li><li>消费时间，指我们每天的日常工作（或学业），为了获取报酬所花的时间  </li><li>投资时间，有助于我们提高自身能力的，比如读书运动学习新技能等  </li><li>浪费时间，洗漱、通勤、用餐等硬性时间  </li><li>消磨时间，放空、打游戏看剧等娱乐活动  </li></ul><p>2023年一共有$24\times 365=8760$个小时，我的记录包含8746个小时，今年的时间记录比较马虎，出现了较多多项分类时间重叠的情况，且未记录时间较去年有所增加。  </p><ol><li>2023年的睡眠时间占比33.7%，同比下降0.5%；    <code>睡眠时间下降不及预期，说明还是太懒了点，也许并不需要那么多睡眠</code>  </li><li>2023年消磨时间占比27.5%，同比下降0.8%；  <code>这么看来下班后就不想学习的惯性是很难变了，最好的方法还是找一个学习的环境，避免受到各种娱乐消遣方式的影响</code></li><li>2023年消费时间占比27.6%，同比上升0.5%；  <code>增加了一丢丢，说明工作强度较去年没多少变化，也说明自己还存在很多余力，2024年可以在这一方面多发一些力，真正用心做出点东西来</code></li><li>2023年投资时间2.8%，同比减少3.2%！   <code>这项着实没想到会继续减少，今后下班后的时间可能需要专门制定计划进行个人提升</code></li><li>2023年浪费时间占总时间8.4%，同比增加4%；  <code>这一项的增加存在一定记录误差，但主要原因还是由于今年工作上出差等事项增多，实际上这些时间中有一些也可以归结到投资时间中，只是懒得进行过细粒度的记录</code></li></ol><p>下面再来看看每个月的各时间占比：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202402081036482.png" alt></p><ol><li>消费时间有一半以上的月份大于消磨时间，且总时间首次超过消磨时间，表明工作较去年更上心了；</li><li>下半年的睡眠时间较为稳定，上半年尝试养成早上磨咖啡喝的习惯，但结果证明个人对咖啡因还是太敏感了，怎么都会影响正常休息，无奈放弃；</li><li>各月的消磨时间反复横跳，反映了在自甘堕落和不想堕落间不断切换的纠结心理；</li><li>投资时间始终处于底端，2024必须有所改变，差不多也该开始多建立起和社会的联系了。</li></ol><h1 id="2023发生的几件事">3&emsp;2023发生的几件事</h1><ul><li>工作上成了小组长（虽然组里还没人），责任变重了，工资涨了那么一丢丢；</li><li>之前买的1手搜特转债成为了A股历史上第一支退市可转债，算是见证历史了；</li><li>配了台新的台式机，娱乐消遣体验上升了一个台阶；</li><li>macbook严重进水，差点废了，还好淘宝上的师傅技术不错，硬是给修好了；</li><li>家里奶奶又摔跤了，严重到住院做手术，生活逐渐无法自理了，辛苦父母照顾了，我自己非常难受却也无能为力；</li><li>A股xxxx点保卫战的口号开始在身边不断响起了，似乎大家对未来普遍没什么信心了。</li></ul><h1 id="2024的期望">4&emsp;2024的期望</h1><p>不提什么小目标了，许几个愿望吧：</p><ul><li>希望国内经济能够有所好转，不要再让大家重复“今年是有史以来最差的一年，但是从今往后最好的一年”这句话了；  </li><li>希望世界和平，战争冲突完美解决；  </li><li>希望家人平安，没有病痛，老人可以安详度过最后的时间；  </li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2024-02-08-2023-nian-zong-jie-ji-xu-tang-de-yi-nian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>latex-cheatsheet</title>
      <link>https://chengpengzhao.com/2023-03-31-latex-cheatsheet/</link>
      <guid>https://chengpengzhao.com/2023-03-31-latex-cheatsheet/</guid>
      <pubDate>Fri, 31 Mar 2023 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;最近需要和一堆公式打交道
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>最近需要和一堆公式打交道，用mathpix的公式识别还是太贵了（API也连涨几次价），还是自己记住这些语法手打公式比较快。<br>下文全部从别的地方收集而来，仅供自己备用。</p><h1 id="cheatsheet-分类">2&emsp;cheatsheet(分类)</h1><h2 id="常见公式">2.1&emsp;常见公式</h2><table><thead><tr><th align="center">名称</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center">上下标</td><td align="center"><code>_1^2X_3^4</code></td><td align="center">$$_1^2X_3^4$$</td></tr><tr><td align="center">组合数</td><td align="center"><code>\mathrm{C}_n^r</code></td><td align="center">$$\mathrm{C}_n^r$$</td></tr><tr><td align="center">排列数</td><td align="center"><code>\mathrm{P}_n^r</code></td><td align="center">$$\mathrm{P}_n^r$$</td></tr><tr><td align="center">上划线</td><td align="center"><code>\overline{abc}</code></td><td align="center">$$\overline{abc}$$</td></tr><tr><td align="center">下划线</td><td align="center"><code>\underline{abc}</code></td><td align="center">$$\underline{abc}$$</td></tr><tr><td align="center">求和</td><td align="center"><code>\sum_{k=1}^N k^2</code></td><td align="center">$$\sum\limits_{k=1}^N k^2$$</td></tr><tr><td align="center">求积</td><td align="center"><code>\prod_{i=1}^N x_i</code></td><td align="center">$$\prod\limits_{i=1}^N x_i$$</td></tr><tr><td align="center">极限</td><td align="center"><code>\lim_{n \to \infty}n</code></td><td align="center">$$\lim\limits_{n \to \infty}n$$</td></tr><tr><td align="center">根号</td><td align="center"><code>\sqrt[n]{x}</code></td><td align="center">$$\sqrt[n]{x}$$</td></tr><tr><td align="center">上括号</td><td align="center"><code>\overbrace{a+b+\cdots+z}^26</code></td><td align="center">$$\overbrace{a+b+\cdots+z}^{26}$$</td></tr><tr><td align="center">下括号</td><td align="center"><code>\underbrace{a+b+\cdots+z}_26</code></td><td align="center">$$\underbrace{a+b+\cdots+z}_{26}$$</td></tr><tr><td align="center">向量</td><td align="center"><code>\overrightarrow{AB}</code></td><td align="center">$$\overrightarrow{AB}$$</td></tr></tbody></table><h2 id="分数">2.2&emsp;分数</h2><p>分数最普通的形式为<code>\frac{x}{y}</code>，也可以用<code>\tfrac{x}{y}</code>来得到较小的分数。</p><p>$$\frac{x}{y}\ \ \tfrac{x}{y}$$</p><p>用<code>\frac{x}{1+\frac{y}}</code>可以得到连分数，但是使用<code>\cfrac</code>代替可以得到更大的分数。</p><p>$$\frac{2}{c + \frac{2}{d + \frac{2}{4}}} \ \  \cfrac{2}{c + \cfrac{2}{d + \cfrac{2}{4}}}$$</p><h2 id="矩阵">2.3&emsp;矩阵</h2><p>矩阵首尾以<code>\begin{matrix}</code>和<code>\end{matrix}</code>标记，各元素以<code>&amp;</code>分隔，以<code>\\</code>换行。</p><pre class="line-numbers language-LaTeX"><code class="language-LaTeX">\begin{matrix}a_{11} & \cdots & a_{1n}  \\\vdots & \ddots & \vdots  \\a_{n1} & \cdots & a_{nn} \\\end{matrix}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>如上则是一个矩阵的代码，可以得到如下的效果。</p><p>$$ \begin{matrix} a_{11}      &amp; \cdots &amp; a_{1n}      \\ \vdots &amp; \ddots &amp; \vdots \\ a_{n1}      &amp; \cdots &amp; a_{nn} \end{matrix} $$</p><p>此外对于<code>{matrix}</code>中 matrix 可以替换成如下内容，以得到不同的边框。</p><table><thead><tr><th align="center">替换内容</th><th align="center">效果</th><th align="center">替换内容</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center">vmatrix</td><td align="center">$$\begin{vmatrix}a &amp; b \\c &amp; d\end{vmatrix}$$</td><td align="center">Vmatrix</td><td align="center">$$\begin{Vmatrix}a &amp; b \\c &amp; d\end{Vmatrix}$$</td></tr><tr><td align="center">bmatrix</td><td align="center">$$\begin{bmatrix}a &amp; b \\c &amp; d\end{bmatrix}$$</td><td align="center">Bmatrix</td><td align="center">$$\begin{Bmatrix}a &amp; b \\c &amp; d\end{Bmatrix}$$</td></tr><tr><td align="center">pmatrix</td><td align="center">$$\begin{pmatrix}a &amp; b \\c &amp; d\end{pmatrix}$$</td><td align="center">smallmatrix</td><td align="center">$$\begin{smallmatrix}a &amp; b \\c &amp; d\end{smallmatrix}$$</td></tr></tbody></table><h2 id="分段函数-amp-方程组">2.4&emsp;分段函数 &amp; 方程组</h2><p>首尾以<code>\begin{cases}</code>和<code>\end{cases}</code>标记，各元素以<code>&amp;</code>分隔，以<code>\\</code>换行。</p><pre class="line-numbers language-LaTeX"><code class="language-LaTeX">f(x) =\begin{cases}x,  & x\ge0 \\-x, & x<0\end{cases}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以得到如下效果。</p><p>$$ f(x) = \begin{cases} x,  &amp; x\ge0 \\ -x, &amp; x&lt;0 \end{cases} $$</p><p>如下所示，可以对上面的稍加修改，</p><pre class="line-numbers language-LaTeX"><code class="language-LaTeX">\begin{cases}x+y=1 \\3x+4y=5 \\\end{cases}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>便可以得到方程组的形式。</p><p>$$ \begin{cases} x+y=1 \\ 3x+4y=5 \\ \end{cases} $$</p><h2 id="多行等式">2.5&emsp;多行等式</h2><p>首尾以<code>\begin{align}</code>和<code>\end{align}</code>标记，各元素以<code>&amp;</code>分隔，以<code>\\</code>换行。</p><pre class="line-numbers language-LaTeX"><code class="language-LaTeX">\begin{align}(x+y)^3 & = (x+y)^2(x+y)& = (x+y)(x+y)(x+y)\end{align}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>实际效果如下。</p><p>$$ \begin{align} (x+y)^3 &amp; = (x+y)^2(x+y)\\ &amp; = (x+y)(x+y)(x+y)\\ \end{align} $$</p><h2 id="空格">2.6&emsp;空格</h2><table><thead><tr><th align="center">功能</th><th align="center">代码</th><th align="center">效果</th><th align="center">宽度</th></tr></thead><tbody><tr><td align="center">2个quad空格</td><td align="center"><code>\qquad</code></td><td align="center">$$A\qquad B$$</td><td align="center">$$2m$$</td></tr><tr><td align="center">quad空格</td><td align="center"><code>\quad</code></td><td align="center">$$A\quad B$$</td><td align="center">$$m$$</td></tr><tr><td align="center">大空格</td><td align="center"><code>\</code></td><td align="center">$$A\ B$$</td><td align="center">$$\frac{m}{3}$$</td></tr><tr><td align="center">中等空格</td><td align="center"><code>\;</code></td><td align="center">$$A;B$$</td><td align="center">$$\frac{2m}{7}$$</td></tr><tr><td align="center">小空格</td><td align="center"><code>\,</code></td><td align="center">$$A,B$$</td><td align="center">$$\frac{m}{6}$$</td></tr><tr><td align="center">没有空格</td><td align="center"><code></code></td><td align="center">$$AB$$</td><td align="center">$$0$$</td></tr><tr><td align="center">紧贴</td><td align="center"><code>\!</code></td><td align="center">$$A!B$$</td><td align="center">$$-\frac{m}{6}$$</td></tr></tbody></table><h2 id="括号">2.7&emsp;括号</h2><p>用<code>\left</code>和<code>\right</code>来控制左右括号。</p><table><thead><tr><th align="center">功能</th><th align="center">语法</th><th align="center">显示</th></tr></thead><tbody><tr><td align="center">小括号</td><td align="center"><code>\left( \frac{a}{b} \right)</code></td><td align="center">$$\left( \frac{a}{b} \right)$$</td></tr><tr><td align="center">中括号</td><td align="center"><code>\left[ \frac{a}{b} \right]</code></td><td align="center">$$ \left[ \frac{a}{b} \right]$$</td></tr><tr><td align="center">大括号</td><td align="center"><code>\left\{ \frac{a}{b} \right\}</code></td><td align="center">$$ \left\{ \frac{a}{b} \right\} $$</td></tr><tr><td align="center">角括号</td><td align="center"><code>\left \langle \frac{a}{b} \right \rangle</code></td><td align="center">$$ \left\langle \frac{a}{b} \right \rangle$$</td></tr><tr><td align="center">双竖线</td><td align="center"><code>\left\Vert \frac{a}{b} \right\Vert</code></td><td align="center">$$\left\Vert \frac{a}{b} \right\Vert$$</td></tr><tr><td align="center">绝对值</td><td align="center"><code>\left| \frac{a}{b} \right |</code></td><td align="center">$$ \left| \frac{a}{b} \right |$$</td></tr><tr><td align="center">向下取整</td><td align="center"><code>\left \lfloor \frac{a}{b} \right \rfloor</code></td><td align="center">$$ \left \lfloor \frac{a}{b} \right \rfloor$$</td></tr><tr><td align="center">向上取整</td><td align="center"><code>\left \lceil \frac{c}{d} \right \rceil</code></td><td align="center">$$ \left \lceil \frac{c}{d} \right \rceil$$</td></tr><tr><td align="center">斜线与反斜线</td><td align="center"><code>\left / \frac{a}{b} \right \backslash</code></td><td align="center">$$ \left / \frac{a}{b} \right \backslash$$</td></tr><tr><td align="center">上下箭头</td><td align="center"><code>\left \uparrow \frac{a}{b} \right \downarrow</code></td><td align="center">$$\left \uparrow \frac{a}{b} \right \downarrow$$</td></tr><tr><td align="center">上下箭头</td><td align="center"><code>\left \Uparrow \frac{a}{b} \right \Downarrow</code></td><td align="center">$$\left \Uparrow \frac{a}{b} \right \Downarrow$$</td></tr></tbody></table><p>括号同时可以用<code>\big \Big \bigg \Bigg</code>修饰。</p><pre class="line-numbers language-LaTeX"><code class="language-LaTeX">\Bigg( \bigg[ \Big\{ \big\langle\left| \frac{a}{b} \right| \big\rangle \Big\} \bigg] \Bigg)<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>如上代码可以得到如下效果。</p><p>$$ \Bigg( \bigg[ \Big\{ \big\langle\left| \frac{a}{b} \right| \big\rangle \Big\} \bigg] \Bigg) $$</p><h2 id="微积分">2.8&emsp;微积分</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\nabla</code></td><td align="center">$$\nabla$$</td><td align="center"><code>\partial{x}</code></td><td align="center">$$\partial{x}$$</td><td align="center"><code>\mathrm{d}x</code></td><td align="center">$$\mathrm{d}x$$</td></tr><tr><td align="center"><code>\dot{x}</code></td><td align="center">$$\dot{x}$$</td><td align="center"><code>\ddot{y}</code></td><td align="center">$$\ddot{y}$$</td><td align="center"><code>\frac{\mathrm{d}y}{\mathrm{d}x}</code></td><td align="center">$$\frac{\mathrm{d}y}{\mathrm{d}x}$$</td></tr><tr><td align="center"><code>f\prime(x)</code></td><td align="center">$$f\prime(x)$$</td><td align="center"><code>\int_{-N}^{N}</code></td><td align="center">$$\int_{-N}^{N}$$</td><td align="center"><code>\iint_{-N}^{N}</code></td><td align="center">$$\iint_{-N}^{N}$$</td></tr><tr><td align="center"><code>\iiint_{-N}^{N}</code></td><td align="center">$$\iiint_{-N}^{N}$$</td><td align="center"><code>\iiiint_{-N}^{N}</code></td><td align="center">$$\iiint_{-N}^{N}$$</td><td align="center"><code>\oint_{C}</code></td><td align="center">$$\oint_{C}$$</td></tr></tbody></table><h2 id="特殊字体">2.9&emsp;特殊字体</h2><table><thead><tr><th align="center">名称</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center">黑板粗体</td><td align="center"><code>\mathbb{ONLY\ UPPERCASE}</code></td><td align="center">$$\mathbb{ONLY\ UPPERCASE}$$</td></tr><tr><td align="center">正粗体</td><td align="center"><code>\mathbf{abcDEFGHI012}</code></td><td align="center">$$\mathbf{abcDEFGHI012}$$</td></tr><tr><td align="center">斜粗体</td><td align="center"><code>\boldsymbol{abcDEFGHI012}</code></td><td align="center">$$\boldsymbol{abcDEFGHI012}$$</td></tr><tr><td align="center">斜体数字</td><td align="center"><code>\mathit{0123456789}</code></td><td align="center">$$\mathit{0123456789}$$</td></tr><tr><td align="center">罗马体</td><td align="center"><code>\mathrm{012} \mbox{abc} \operatorname{ABC}</code></td><td align="center">$$\mathrm{012} \mbox{abc} \operatorname{ABC}$$</td></tr><tr><td align="center">哥特体</td><td align="center"><code>\mathfrak{abcDEFGHI012}</code></td><td align="center">$$\mathfrak{abcDEFGHI012}$$</td></tr><tr><td align="center">手写体</td><td align="center"><code>\mathcal{abcDEFGHI012}</code></td><td align="center">$$\mathcal{abcDEFGHI012}$$</td></tr><tr><td align="center">希伯来字母</td><td align="center"><code>\aleph\beth\gimel\daleth</code></td><td align="center">$$\aleph\beth\gimel\daleth$$</td></tr></tbody></table><h2 id="字符标记">2.10&emsp;字符标记</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\acute{a}</code></td><td align="center">$$\acute{a}$$</td><td align="center"><code>\grave{a}</code></td><td align="center">$$\grave{a}$$</td><td align="center"><code>\hat{a}</code></td><td align="center">$$\hat{a}$$</td></tr><tr><td align="center"><code>\tilde{a}</code></td><td align="center">$$\tilde{a}$$</td><td align="center"><code>\breve{a}</code></td><td align="center">$$\breve{a}$$</td><td align="center"><code>\check{a}</code></td><td align="center">$$\check{a}$$</td></tr><tr><td align="center"><code>\bar{a}</code></td><td align="center">$$\bar{a}$$</td><td align="center"><code>\ddot{a}</code></td><td align="center">$$\ddot{a}$$</td><td align="center"><code>\dot{a}</code></td><td align="center">$$\dot{a}$$</td></tr></tbody></table><h2 id="常见函数">2.11&emsp;常见函数</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\sin</code></td><td align="center">$$\sin$$</td><td align="center"><code>\cos</code></td><td align="center">$$\cos$$</td><td align="center"><code>\tan</code></td><td align="center">$$\tan$$</td></tr><tr><td align="center"><code>\sec</code></td><td align="center">$$\sec$$</td><td align="center"><code>\csc</code></td><td align="center">$$\csc$$</td><td align="center"><code>\cot</code></td><td align="center">$$\cot$$</td></tr><tr><td align="center"><code>\arcsin</code></td><td align="center">$$\arcsin$$</td><td align="center"><code>\arccos</code></td><td align="center">$$\arccos$$</td><td align="center"><code>\arctan</code></td><td align="center">$$\arctan$$</td></tr><tr><td align="center"><code>\sinh</code></td><td align="center">$$\sinh$$</td><td align="center"><code>\cosh</code></td><td align="center">$$\cosh$$</td><td align="center"><code>\tanh</code></td><td align="center">$$\tanh$$</td></tr><tr><td align="center"><code>\coth</code></td><td align="center">$$\coth$$</td><td align="center"><code>\lim</code></td><td align="center">$$\lim$$</td><td align="center"><code>\limsup</code></td><td align="center">$$\limsup$$</td></tr><tr><td align="center"><code>\liminf</code></td><td align="center">$$\liminf$$</td><td align="center"><code>\min</code></td><td align="center">$$\min$$</td><td align="center"><code>\max</code></td><td align="center">$$\max$$</td></tr><tr><td align="center"><code>\inf</code></td><td align="center">$$\inf$$</td><td align="center"><code>\sup</code></td><td align="center">$$\sup$$</td><td align="center"><code>\exp</code></td><td align="center">$$\exp$$</td></tr><tr><td align="center"><code>\ln</code></td><td align="center">$$\ln$$</td><td align="center"><code>\lg</code></td><td align="center">$$\lg$$</td><td align="center"><code>\log</code></td><td align="center">$$\log$$</td></tr><tr><td align="center"><code>\log_{10}</code></td><td align="center">$$\log_{10}$$</td><td align="center"><code>\ker</code></td><td align="center">$$\ker$$</td><td align="center"><code>\deg</code></td><td align="center">$$\deg$$</td></tr><tr><td align="center"><code>\gcd</code></td><td align="center">$$\gcd$$</td><td align="center"><code>\Pr</code></td><td align="center">$$\Pr$$</td><td align="center"><code>\det</code></td><td align="center">$$\det$$</td></tr><tr><td align="center"><code>\hom</code></td><td align="center">$$\hom$$</td><td align="center"><code>\arg</code></td><td align="center">$$\arg$$</td><td align="center"><code>\dim</code></td><td align="center">$$\dim$$</td></tr><tr><td align="center"><code>\bmod</code></td><td align="center">$$\bmod$$</td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td></tr></tbody></table><h2 id="二元运算符">2.12&emsp;二元运算符</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>+</code></td><td align="center">$$+$$</td><td align="center"><code>-</code></td><td align="center">$$-$$</td><td align="center"><code>\pm</code></td><td align="center">$$\pm$$</td></tr><tr><td align="center"><code>\mp</code></td><td align="center">$$\mp$$</td><td align="center"><code>\dotplus</code></td><td align="center">$$\dotplus$$</td><td align="center"><code>\times</code></td><td align="center">$$\times$$</td></tr><tr><td align="center"><code>\div</code></td><td align="center">$$\div$$</td><td align="center"><code>\divideontimes</code></td><td align="center">$$\divideontimes$$</td><td align="center"><code>\backslash</code></td><td align="center">$$\backslash$$</td></tr><tr><td align="center"><code>\cdot</code></td><td align="center">$$\cdot$$</td><td align="center"><code>\ast</code></td><td align="center">$$\ast$$</td><td align="center"><code>\star</code></td><td align="center">$$\star$$</td></tr><tr><td align="center"><code>\circ</code></td><td align="center">$$\circ$$</td><td align="center"><code>\bullet</code></td><td align="center">$$\bullet$$</td><td align="center"><code>\boxplus</code></td><td align="center">$$\boxplus$$</td></tr><tr><td align="center"><code>\boxminus</code></td><td align="center">$$\boxminus$$</td><td align="center"><code>\boxtimes</code></td><td align="center">$$\boxtimes$$</td><td align="center"><code>\boxdot</code></td><td align="center">$$\boxdot$$</td></tr><tr><td align="center"><code>\oplus</code></td><td align="center">$$\oplus$$</td><td align="center"><code>\ominus</code></td><td align="center">$$\ominus$$</td><td align="center"><code>\otimes</code></td><td align="center">$$\otimes$$</td></tr><tr><td align="center"><code>\oslash</code></td><td align="center">$$\oslash$$</td><td align="center"><code>\odot</code></td><td align="center">$$\odot$$</td><td align="center"><code>\circleddash</code></td><td align="center">$$\circleddash$$</td></tr><tr><td align="center"><code>\circledcirc</code></td><td align="center">$$\circledcirc$$</td><td align="center"><code>\circledast</code></td><td align="center">$$\circledast$$</td><td align="center"><code>\bigoplus</code></td><td align="center">$$\bigoplus$$</td></tr><tr><td align="center"><code>\bigotimes</code></td><td align="center">$$\bigotimes$$</td><td align="center"><code>\bigodot</code></td><td align="center">$$\bigodot$$</td><td align="center"><code>\equiv</code></td><td align="center">$$\equiv$$</td></tr></tbody></table><h2 id="集合">2.13&emsp;集合</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\forall</code></td><td align="center">$$\forall$$</td><td align="center"><code>\exists</code></td><td align="center">$$\exists$$</td><td align="center"><code>\emptyset</code></td><td align="center">$$\emptyset$$</td></tr><tr><td align="center"><code>\in</code></td><td align="center">$$\in$$</td><td align="center"><code>\ni</code></td><td align="center">$$\ni$$</td><td align="center"><code>\notin</code></td><td align="center">$$\notin$$</td></tr><tr><td align="center"><code>\subset</code></td><td align="center">$$\subset$$</td><td align="center"><code>\subseteq</code></td><td align="center">$$\subseteq$$</td><td align="center"><code>\supset</code></td><td align="center">$$\supset$$</td></tr><tr><td align="center"><code>\supseteq</code></td><td align="center">$$\supseteq$$</td><td align="center"><code>\bigcap</code></td><td align="center">$$\bigcap$$</td><td align="center"><code>\cup</code></td><td align="center">$$\cup$$</td></tr><tr><td align="center"><code>\bigcup</code></td><td align="center">$$\bigcup$$</td><td align="center"><code>\biguplus</code></td><td align="center">$$\biguplus$$</td><td align="center"><code>\setminus</code></td><td align="center">$$\setminus$$</td></tr><tr><td align="center"><code>\smallsetminus</code></td><td align="center">$$\smallsetminus$$</td><td align="center"><code>\sqsubset</code></td><td align="center">$$\sqsubset$$</td><td align="center"><code>\sqsubseteq</code></td><td align="center">$$\sqsubseteq$$</td></tr><tr><td align="center"><code>\sqsupset</code></td><td align="center">$$\sqsupset$$</td><td align="center"><code>\sqsupseteq</code></td><td align="center">$$\sqsupseteq$$</td><td align="center"><code>\sqcap</code></td><td align="center">$$\sqcap$$</td></tr><tr><td align="center"><code>\sqcup</code></td><td align="center">$$\sqcup$$</td><td align="center"><code>\bigsqcup</code></td><td align="center">$$\bigsqcup$$</td><td align="center"><code>\sqcap</code></td><td align="center">$$\sqcap$$</td></tr><tr><td align="center"><code>\varnothing</code></td><td align="center">$$\varnothing$$</td><td align="center"><code>\cap</code></td><td align="center">$$\cap$$</td><td align="center"><code>\supseteqq</code></td><td align="center">$$\sqsubseteq$$</td></tr><tr><td align="center"><code>\nsubseteq</code></td><td align="center">$$\nsubseteq$$</td><td align="center"><code>\nsupseteq</code></td><td align="center">$$\nsupseteq$$</td><td align="center"><code>\nsubseteqq</code></td><td align="center">$$\nsubseteqq$$</td></tr><tr><td align="center"><code>\nsupseteqq</code></td><td align="center">$$\nsupseteqq$$</td><td align="center"><code>\subseteqq</code></td><td align="center">$$\sqsubset$$</td><td align="center"></td><td align="center"></td></tr><tr><td align="center"><code>\sqsupset</code></td><td align="center">$$\sqsupset$$</td><td align="center"><code>\sqsupseteq</code></td><td align="center">$$\sqsupseteq$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><h2 id="逻辑运算符">2.14&emsp;逻辑运算符</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\land</code></td><td align="center">$$\land$$</td><td align="center"><code>\wedge</code></td><td align="center">$$\wedge$$</td><td align="center"><code>\bigwedge</code></td><td align="center">$$\bigwedge$$</td></tr><tr><td align="center"><code>\bar{q}</code></td><td align="center">$$\bar{A}$$</td><td align="center"><code>\to</code></td><td align="center">$$\to$$</td><td align="center"><code>\lor</code></td><td align="center">$$\lor$$</td></tr><tr><td align="center"><code>\vee</code></td><td align="center">$$\vee$$</td><td align="center"><code>\bigvee</code></td><td align="center">$$\bigvee$$</td><td align="center"><code>\lnot</code></td><td align="center">$$\lnot$$</td></tr><tr><td align="center"><code>\neg</code></td><td align="center">$$\neg$$</td><td align="center"><code>\And</code></td><td align="center">$$\And$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><h2 id="关系运算符">2.15&emsp;关系运算符</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\sim</code></td><td align="center">$$\sim$$</td><td align="center"><code>\approx</code></td><td align="center">$$\approx$$</td><td align="center"><code>\simeq</code></td><td align="center">$$\simeq$$</td></tr><tr><td align="center"><code>\cong</code></td><td align="center">$$\cong$$</td><td align="center"><code>\dot=</code></td><td align="center">$$\dot=$$</td><td align="center"><code>\gtrapprox</code></td><td align="center">$$\gtrapprox$$</td></tr><tr><td align="center"><code>&lt;</code></td><td align="center">$$&lt;$$</td><td align="center"><code>\le</code></td><td align="center">$$\le$$</td><td align="center"><code>\ll</code></td><td align="center">$$\ll$$</td></tr><tr><td align="center"><code>\gg</code></td><td align="center">$$\gg$$</td><td align="center"><code>\ge</code></td><td align="center">$$\ge$$</td><td align="center"><code>&gt;</code></td><td align="center">$$&gt;$$</td></tr><tr><td align="center"><code>\equiv</code></td><td align="center">$$\equiv$$</td><td align="center"><code>\not\equiv</code></td><td align="center">$$\not\equiv$$</td><td align="center"><code>\ne</code></td><td align="center">$$\ne$$</td></tr><tr><td align="center"><code>\mbox{or}</code></td><td align="center">$$\mbox{or}$$</td><td align="center"><code>\neq</code></td><td align="center">$$\neq$$</td><td align="center"><code>\propto</code></td><td align="center">$$\propto$$</td></tr><tr><td align="center"><code>\lessapprox</code></td><td align="center">$$\lessapprox$$</td><td align="center"><code>\lesssim</code></td><td align="center">$$\lesssim$$</td><td align="center"><code>\eqslantless</code></td><td align="center">$$\eqslantless$$</td></tr><tr><td align="center"><code>\leqslant</code></td><td align="center">$$\leqslant$$</td><td align="center"><code>\leqq</code></td><td align="center">$$\leqq$$</td><td align="center"><code>\geqq</code></td><td align="center">$$\geqq$$</td></tr><tr><td align="center"><code>\geqslant</code></td><td align="center">$$\geqslant$$</td><td align="center"><code>\eqslantgtr</code></td><td align="center">$$\eqslantgtr$$</td><td align="center"><code>\gtrsim</code></td><td align="center">$$\gtrsim$$</td></tr></tbody></table><h2 id="几何符号">2.16&emsp;几何符号</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\Diamond</code></td><td align="center">$$\Diamond$$</td><td align="center"><code>\Box</code></td><td align="center">$$\Box$$</td><td align="center"><code>\triangle</code></td><td align="center">$$\triangle$$</td></tr><tr><td align="center"><code>\angle</code></td><td align="center">$$\angle$$</td><td align="center"><code>\perp</code></td><td align="center">$$\perp$$</td><td align="center"><code>\mid</code></td><td align="center">$$\mid$$</td></tr><tr><td align="center"><code>\nmid</code></td><td align="center">$$\nmid$$</td><td align="center"><code>|</code></td><td align="center">$$|$$</td><td align="center"><code>45^\circ</code></td><td align="center">$$45^\circ$$</td></tr><tr><td align="center"><code>\sphericalangle</code></td><td align="center">$$\sphericalangle$$</td><td align="center"><code>\bigtriangledown</code></td><td align="center">$$\bigtriangledown$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><h2 id="希腊字母">2.17&emsp;希腊字母</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\alpha</code></td><td align="center">$$\alpha$$</td><td align="center"><code>\theta</code></td><td align="center">$$\theta$$</td><td align="center"><code>o</code></td><td align="center">$$o$$</td><td align="center"><code>\tau</code></td><td align="center">$$\tau$$</td></tr><tr><td align="center"><code>\beta</code></td><td align="center">$$\beta$$</td><td align="center"><code>\vartheta</code></td><td align="center">$$\vartheta$$</td><td align="center"><code>\pi</code></td><td align="center">$$\pi$$</td><td align="center"><code>\upsilon</code></td><td align="center">$$\upsilon$$</td></tr><tr><td align="center"><code>\gamma</code></td><td align="center">$$\gamma$$</td><td align="center"><code>\iota</code></td><td align="center">$$\iota$$</td><td align="center"><code>\varpi</code></td><td align="center">$$\varpi$$</td><td align="center"><code>\phi</code></td><td align="center">$$\phi$$</td></tr><tr><td align="center"><code>\delta</code></td><td align="center">$$\delta$$</td><td align="center"><code>\kappa</code></td><td align="center">$$\kappa$$</td><td align="center"><code>\rho</code></td><td align="center">$$\rho$$</td><td align="center"><code>\varphi</code></td><td align="center">$$\varphi$$</td></tr><tr><td align="center"><code>\epsilon</code></td><td align="center">$$\epsilon$$</td><td align="center"><code>\lambda</code></td><td align="center">$$\lambda$$</td><td align="center"><code>\varrho</code></td><td align="center">$$\varrho$$</td><td align="center"><code>\chi</code></td><td align="center">$$\chi$$</td></tr><tr><td align="center"><code>\varepsilon</code></td><td align="center">$$\varepsilon$$</td><td align="center"><code>\mu</code></td><td align="center">$$\mu$$</td><td align="center"><code>\sigma</code></td><td align="center">$$\sigma$$</td><td align="center"><code>\psi</code></td><td align="center">$$\psi$$</td></tr><tr><td align="center"><code>\zeta</code></td><td align="center">$$\zeta$$</td><td align="center"><code>\nu</code></td><td align="center">$$\nu$$</td><td align="center"><code>\varsigma</code></td><td align="center">$$\varsigma$$</td><td align="center"><code>\omega</code></td><td align="center">$$\omega$$</td></tr><tr><td align="center"><code>\eta</code></td><td align="center">$$\eta$$</td><td align="center"><code>\xi</code></td><td align="center">$$\xi$$</td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td></tr><tr><td align="center"><code>\Gamma</code></td><td align="center">$$\Gamma$$</td><td align="center"><code>\Lambda</code></td><td align="center">$$\Lambda$$</td><td align="center"><code>\Sigma</code></td><td align="center">$$\Sigma$$</td><td align="center"><code>\Psi</code></td><td align="center">$$\Psi$$</td></tr><tr><td align="center"><code>\Delta</code></td><td align="center">$$\Delta$$</td><td align="center"><code>\Xi</code></td><td align="center">$$\Xi$$</td><td align="center"><code>\Upsilon</code></td><td align="center">$$\Upsilon$$</td><td align="center"><code>\Omega</code></td><td align="center">$$\Omega$$</td></tr><tr><td align="center"><code>\Theta</code></td><td align="center">$$\Theta$$</td><td align="center"><code>\Pi</code></td><td align="center">$$\Pi$$</td><td align="center"><code>\Phi</code></td><td align="center">$$\Phi$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><h2 id="箭头">2.18&emsp;箭头</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\leftarrow</code></td><td align="center">$$\leftarrow$$</td><td align="center"><code>\rightarrow</code></td><td align="center">$$\rightarrow$$</td><td align="center"><code>\nleftarrow</code></td><td align="center">$$\nleftarrow$$</td></tr><tr><td align="center"><code>\nrightarrow</code></td><td align="center">$$\nrightarrow$$</td><td align="center"><code>\leftrightarrow</code></td><td align="center">$$\leftrightarrow$$</td><td align="center"><code>\nleftrightarrow</code></td><td align="center">$$\nleftrightarrow$$</td></tr><tr><td align="center"><code>\longleftarrow</code></td><td align="center">$$\longleftarrow$$</td><td align="center"><code>\longrightarrow</code></td><td align="center">$$\longrightarrow$$</td><td align="center"><code>\longleftrightarrow</code></td><td align="center">$$\longleftrightarrow$$</td></tr><tr><td align="center"><code>\leftarrow</code></td><td align="center">$$\leftarrow$$</td><td align="center"><code>\rightarrow</code></td><td align="center">$$\rightarrow$$</td><td align="center"><code>\nleftarrow</code></td><td align="center">$$\nleftarrow$$</td></tr><tr><td align="center"><code>\nrightarrow</code></td><td align="center">$$\nrightarrow$$</td><td align="center"><code>\leftrightarrow</code></td><td align="center">$$\leftrightarrow$$</td><td align="center"><code>\nleftrightarrow</code></td><td align="center">$$\nleftrightarrow$$</td></tr><tr><td align="center"><code>\longleftarrow</code></td><td align="center">$$\longleftarrow$$</td><td align="center"><code>\longrightarrow</code></td><td align="center">$$\longrightarrow$$</td><td align="center"><code>\longleftrightarrow</code></td><td align="center">$$\longleftrightarrow$$</td></tr><tr><td align="center"><code>\Leftarrow</code></td><td align="center">$$\Leftarrow$$</td><td align="center"><code>\Rightarrow</code></td><td align="center">$$\Rightarrow$$</td><td align="center"><code>\nLeftarrow</code></td><td align="center">$$\nLeftarrow$$</td></tr><tr><td align="center"><code>\nRightarrow</code></td><td align="center">$$\nRightarrow$$</td><td align="center"><code>\Leftrightarrow</code></td><td align="center">$$\Leftrightarrow$$</td><td align="center"><code>\nLeftrightarrow</code></td><td align="center">$$\nLeftrightarrow$$</td></tr><tr><td align="center"><code>\Longleftarrow</code></td><td align="center">$$\Longleftarrow$$</td><td align="center"><code>\Longrightarrow</code></td><td align="center">$$\Longrightarrow$$</td><td align="center"><code>\Longleftrightarrow</code></td><td align="center">$$\Longleftrightarrow$$</td></tr><tr><td align="center"><code>\Leftarrow</code></td><td align="center">$$\Leftarrow$$</td><td align="center"><code>\Rightarrow</code></td><td align="center">$$\Rightarrow$$</td><td align="center"><code>\nLeftarrow</code></td><td align="center">$$\nLeftarrow$$</td></tr><tr><td align="center"><code>\nRightarrow</code></td><td align="center">$$\nRightarrow$$</td><td align="center"><code>\Leftrightarrow</code></td><td align="center">$$\Leftrightarrow$$</td><td align="center"><code>\nLeftrightarrow</code></td><td align="center">$$\nLeftrightarrow$$</td></tr><tr><td align="center"><code>\Longleftarrow</code></td><td align="center">$$\Longleftarrow$$</td><td align="center"><code>\Longrightarrow</code></td><td align="center">$$\Longrightarrow$$</td><td align="center"><code>\Longleftrightarrow</code></td><td align="center">$$\Longleftrightarrow$$</td></tr><tr><td align="center"><code>\uparrow</code></td><td align="center">$$\uparrow$$</td><td align="center"><code>\downarrow</code></td><td align="center">$$\downarrow$$</td><td align="center"><code>\updownarrow</code></td><td align="center">$$\updownarrow$$</td></tr><tr><td align="center"><code>\Uparrow</code></td><td align="center">$$\Uparrow$$</td><td align="center"><code>\Downarrow</code></td><td align="center">$$\Downarrow$$</td><td align="center"><code>\Updownarrow</code></td><td align="center">$$\Updownarrow$$</td></tr><tr><td align="center"><code>\nearrow</code></td><td align="center">$$\nearrow$$</td><td align="center"><code>\searrow</code></td><td align="center">$$\searrow$$</td><td align="center"><code>\swarrow</code></td><td align="center">$$\swarrow$$</td></tr><tr><td align="center"><code>\nwarrow</code></td><td align="center">$$\nwarrow$$</td><td align="center"><code>\uparrow</code></td><td align="center">$$\uparrow$$</td><td align="center"><code>\downarrow</code></td><td align="center">$$\downarrow$$</td></tr><tr><td align="center"><code>\updownarrow</code></td><td align="center">$$\updownarrow$$</td><td align="center"><code>\Uparrow</code></td><td align="center">$$\Uparrow$$</td><td align="center"><code>\Downarrow</code></td><td align="center">$$\Downarrow$$</td></tr><tr><td align="center"><code>\Updownarrow</code></td><td align="center">$$\Updownarrow$$</td><td align="center"><code>\nearrow</code></td><td align="center">$$\nearrow$$</td><td align="center"><code>\searrow</code></td><td align="center">$$\searrow$$</td></tr><tr><td align="center"><code>\swarrow</code></td><td align="center">$$\swarrow$$</td><td align="center"><code>\nwarrow</code></td><td align="center">$$\nwarrow$$</td><td align="center"><code>\rightharpoonup</code></td><td align="center">$$\rightharpoonup$$</td></tr><tr><td align="center"><code>\rightharpoondown</code></td><td align="center">$$\rightharpoondown$$</td><td align="center"><code>\leftharpoonup</code></td><td align="center">$$\leftharpoonup$$</td><td align="center"><code>\leftharpoondown</code></td><td align="center">$$\leftharpoondown$$</td></tr><tr><td align="center"><code>\upharpoonleft</code></td><td align="center">$$\upharpoonleft$$</td><td align="center"><code>\upharpoonright</code></td><td align="center">$$\upharpoonright$$</td><td align="center"><code>\downharpoonleft</code></td><td align="center">$$\downharpoonleft$$</td></tr><tr><td align="center"><code>\downharpoonright</code></td><td align="center">$$\downharpoonright$$</td><td align="center"><code>\rightleftharpoons</code></td><td align="center">$$\rightleftharpoons$$</td><td align="center"><code>\leftrightharpoons</code></td><td align="center">$$\leftrightharpoons$$</td></tr><tr><td align="center"><code>\rightharpoonup</code></td><td align="center">$$\rightharpoonup$$</td><td align="center"><code>\rightharpoondown</code></td><td align="center">$$\rightharpoondown$$</td><td align="center"><code>\leftharpoonup</code></td><td align="center">$$\leftharpoonup$$</td></tr><tr><td align="center"><code>\leftharpoondown</code></td><td align="center">$$\leftharpoondown$$</td><td align="center"><code>\upharpoonleft</code></td><td align="center">$$\upharpoonleft$$</td><td align="center"><code>\upharpoonright</code></td><td align="center">$$\upharpoonright$$</td></tr><tr><td align="center"><code>\downharpoonleft</code></td><td align="center">$$\downharpoonleft$$</td><td align="center"><code>\downharpoonright</code></td><td align="center">$$\downharpoonright$$</td><td align="center"><code>\rightleftharpoons</code></td><td align="center">$$\rightleftharpoons$$</td></tr><tr><td align="center"><code>\leftrightharpoons</code></td><td align="center">$$\leftrightharpoons$$</td><td align="center"><code>\curvearrowleft</code></td><td align="center">$$\curvearrowleft$$</td><td align="center"><code>\circlearrowleft</code></td><td align="center">$$\circlearrowleft$$</td></tr><tr><td align="center"><code>\Lsh</code></td><td align="center">$$\Lsh$$</td><td align="center"><code>\upuparrows</code></td><td align="center">$$\upuparrows$$</td><td align="center"><code>\rightrightarrows</code></td><td align="center">$$\rightrightarrows$$</td></tr><tr><td align="center"><code>\rightleftarrows</code></td><td align="center">$$\rightleftarrows$$</td><td align="center"><code>\Rrightarrow</code></td><td align="center">$$\Rrightarrow$$</td><td align="center"><code>\rightarrowtail</code></td><td align="center">$$\rightarrowtail$$</td></tr><tr><td align="center"><code>\looparrowright</code></td><td align="center">$$\looparrowright$$</td><td align="center"><code>\curvearrowleft</code></td><td align="center">$$\curvearrowleft$$</td><td align="center"><code>\circlearrowleft</code></td><td align="center">$$\circlearrowleft$$</td></tr><tr><td align="center"><code>\Lsh</code></td><td align="center">$$\Lsh$$</td><td align="center"><code>\upuparrows</code></td><td align="center">$$\upuparrows$$</td><td align="center"><code>\rightrightarrows</code></td><td align="center">$$\rightrightarrows$$</td></tr><tr><td align="center"><code>\rightleftarrows</code></td><td align="center">$$\rightleftarrows$$</td><td align="center"><code>\Rrightarrow</code></td><td align="center">$$\Rrightarrow$$</td><td align="center"><code>\rightarrowtail</code></td><td align="center">$$\rightarrowtail$$</td></tr><tr><td align="center"><code>\looparrowright</code></td><td align="center">$$\looparrowright$$</td><td align="center"><code>\curvearrowright</code></td><td align="center">$$\curvearrowright$$</td><td align="center"><code>\circlearrowright</code></td><td align="center">$$\circlearrowright$$</td></tr><tr><td align="center"><code>\Rsh</code></td><td align="center">$$\Rsh$$</td><td align="center"><code>\downdownarrows</code></td><td align="center">$$\downdownarrows$$</td><td align="center"><code>\leftleftarrows</code></td><td align="center">$$\leftleftarrows$$</td></tr><tr><td align="center"><code>\leftrightarrows</code></td><td align="center">$$\leftrightarrows$$</td><td align="center"><code>\Lleftarrow</code></td><td align="center">$$\Lleftarrow$$</td><td align="center"><code>\leftarrowtail</code></td><td align="center">$$\leftarrowtail$$</td></tr><tr><td align="center"><code>\looparrowleft</code></td><td align="center">$$\looparrowleft$$</td><td align="center"><code>\curvearrowright</code></td><td align="center">$$\curvearrowright$$</td><td align="center"><code>\circlearrowright</code></td><td align="center">$$\circlearrowright$$</td></tr><tr><td align="center"><code>\Rsh</code></td><td align="center">$$\Rsh$$</td><td align="center"><code>\downdownarrows</code></td><td align="center">$$\downdownarrows$$</td><td align="center"><code>\leftleftarrows</code></td><td align="center">$$\leftleftarrows$$</td></tr><tr><td align="center"><code>\leftrightarrows</code></td><td align="center">$$\leftrightarrows$$</td><td align="center"><code>\Lleftarrow</code></td><td align="center">$$\Lleftarrow$$</td><td align="center"><code>\leftarrowtail</code></td><td align="center">$$\leftarrowtail$$</td></tr><tr><td align="center"><code>\looparrowleft</code></td><td align="center">$$\looparrowleft$$</td><td align="center"><code>\mapsto</code></td><td align="center">$$\mapsto$$</td><td align="center"><code>\longmapsto</code></td><td align="center">$$\longmapsto$$</td></tr><tr><td align="center"><code>\hookrightarrow</code></td><td align="center">$$\hookrightarrow$$</td><td align="center"><code>\hookleftarrow</code></td><td align="center">$$\hookleftarrow$$</td><td align="center"><code>\multimap</code></td><td align="center">$$\multimap$$</td></tr><tr><td align="center"><code>\leftrightsquigarrow</code></td><td align="center">$$\leftrightsquigarrow$$</td><td align="center"><code>\rightsquigarrow</code></td><td align="center">$$\rightsquigarrow$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><p>此外还有几个可以在箭头上下方写字的箭头。</p><table><thead><tr><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\xleftarrow[下方公式]{上方公式}</code></td><td align="center">$$A\xleftarrow[下方公式]{上方公式}B$$</td></tr><tr><td align="center"><code>\xrightarrow[下方公式]{上方公式}</code></td><td align="center">$$A\xrightarrow[下方公式]{上方公式}B$$</td></tr><tr><td align="center"><code>\underrightarrow{演示}</code></td><td align="center">$$A\underrightarrow{演示}B$$</td></tr><tr><td align="center"><code>\underleftarrow{演示}</code></td><td align="center">$$A\underleftarrow{演示}B$$</td></tr><tr><td align="center"><code>\underleftrightarrow{演示}</code></td><td align="center">$$A\underleftrightarrow{演示}B$$</td></tr></tbody></table><h2 id="其他各类符号">2.19&emsp;其他各类符号</h2><table><thead><tr><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th><th align="center">代码</th><th align="center">效果</th></tr></thead><tbody><tr><td align="center"><code>\ldots</code></td><td align="center">$$\ldots$$</td><td align="center"><code>\cdots</code></td><td align="center">$$\cdots$$</td><td align="center"><code>\vdots</code></td><td align="center">$$\vdots$$</td></tr><tr><td align="center"><code>\ddots</code></td><td align="center">$$\ddots$$</td><td align="center"><code>\aleph</code></td><td align="center">$$\aleph$$</td><td align="center"><code>\prime</code></td><td align="center">$$\prime$$</td></tr><tr><td align="center"><code>\infty</code></td><td align="center">$$\infty$$</td><td align="center"><code>\hbar</code></td><td align="center">$$\hbar$$</td><td align="center"><code>\Box$</code></td><td align="center">$$\Box$$</td></tr><tr><td align="center"><code>\imath</code></td><td align="center">$$\imath$$</td><td align="center"><code>\jmath</code></td><td align="center">$$\jmath$$</td><td align="center"><code>\surd</code></td><td align="center">$$\surd$$</td></tr><tr><td align="center"><code>\flat</code></td><td align="center">$$\flat$$</td><td align="center"><code>\triangle</code></td><td align="center">$$\triangle$$</td><td align="center"><code>\ell</code></td><td align="center">$$\ell$$</td></tr><tr><td align="center"><code>\top</code></td><td align="center">$$\top$$</td><td align="center"><code>\natural</code></td><td align="center">$$\natural$$</td><td align="center"><code>\clubsuit</code></td><td align="center">$$\clubsuit$$</td></tr><tr><td align="center"><code>\wp</code></td><td align="center">$$\wp$$</td><td align="center"><code>\bot</code></td><td align="center">$$\bot$$</td><td align="center"><code>\sharp</code></td><td align="center">$$\sharp$$</td></tr><tr><td align="center"><code>\diamondsuit</code></td><td align="center">$$\diamondsuit$$</td><td align="center"><code>\Re</code></td><td align="center">$$\Re$$</td><td align="center"><code>|</code></td><td align="center">$$|$$</td></tr><tr><td align="center"><code>\backslash</code></td><td align="center">$$\backslash$$</td><td align="center"><code>\heartsuit</code></td><td align="center">$$\heartsuit$$</td><td align="center"><code>\Im</code></td><td align="center">$$\Im$$</td></tr><tr><td align="center"><code>\spadesuit</code></td><td align="center">$$\spadesuit$$</td><td align="center"><code>\mho</code></td><td align="center">$$\mho$$</td><td align="center"></td><td align="center"></td></tr></tbody></table><h1 id="cheatsheet-PDF">3&emsp;cheatsheet(PDF)</h1><center><embed src="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/latex-cheatsheet.pdf#toolbar=0" width="750" height="900"></center>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2023-03-31-latex-cheatsheet/#disqus_thread</comments>
    </item>
    
    <item>
      <title>neovim一些插件的快捷键备忘录</title>
      <link>https://chengpengzhao.com/2023-01-26-neovim-yi-xie-cha-jian-kuai-jie-jian-bei-wang-lu/</link>
      <guid>https://chengpengzhao.com/2023-01-26-neovim-yi-xie-cha-jian-kuai-jie-jian-bei-wang-lu/</guid>
      <pubDate>Thu, 26 Jan 2023 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt; 本来SpaceVim用
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p> 本来SpaceVim用的好好的，在无意中一次更新Nvim和插件后，一切都改变了：各种乱七八糟的插件报错，怎么也解决不了，看来别人配好的东西还是有点局限性，真要稳定使用还得自己DIY，于是毅然删除了SpaceVim，从头开始配置我的Neovim（结合之前自己的vim配置）。这里记录一下几个常用插件的常用功能，作为备忘录使用，刚开始用的不熟时可以方便自己迅速找到参考处。  </p><p> nvim查看某快捷键详细信息： <code>:verbose map xxx&lt;cr&gt;</code></p><p>(各插件不分先后顺序)</p><h1 id="nvim-tree">2&emsp;nvim-tree</h1><p>侧边栏，呼出的命令分<code>NvimTreeToggle</code>与<code>NvimTreeFindFile</code>两个，用<code>which-key</code>插件统一管理快捷键，开关的快捷键我设为了<code>&lt;Space&gt;ft</code>或<code>&lt;leader&gt;n</code>，定位到文件的快捷键我设为了<code>&lt;Space&gt;fo或&lt;space&gt;n</code>。前面的快捷键与原SpaceVim保持一致，后面的是我根据习惯设置的。其他快捷键配置见<code>nvim-tree</code>配置文件：</p><pre class="line-numbers language-lua"><code class="language-lua"><span class="token keyword">local</span> keymap_list <span class="token operator">=</span> <span class="token punctuation">{</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"&lt;CR>"</span><span class="token punctuation">,</span> <span class="token string">"o"</span><span class="token punctuation">,</span> <span class="token string">"l"</span><span class="token punctuation">,</span> <span class="token string">"&lt;2-LeftMouse>"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"edit"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"h"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"close_node"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"p"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"preview"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"&lt;C-r>"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"refresh"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"yn"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"copy_name"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"yp"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"copy_path"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"yy"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"copy_absolute_path"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"a"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"create"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"d"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"remove"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"r"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"rename"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"I"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"toggle_git_ignored"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"R"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"collapse_all"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">{</span> key <span class="token operator">=</span> <span class="token string">"?"</span><span class="token punctuation">,</span> action <span class="token operator">=</span> <span class="token string">"toggle_help"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="buffer-line">3&emsp;buffer-line</h1><p>自己设置的快捷键如下：（依赖close-buffers插件）</p><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>&lt;leader&gt;j</td><td>next buffer</td></tr><tr><td>&lt;leader&gt;k</td><td>previous buffer</td></tr><tr><td>&lt;leader&gt;[number]</td><td>to buffer [number]</td></tr><tr><td>&lt;space&gt;bc</td><td>close invisible buffers</td></tr><tr><td>&lt;space&gt;bd</td><td>close current buffer</td></tr><tr><td>&lt;space&gt;bt</td><td>close other buffers</td></tr></tbody></table><h1 id="nvim-treesitter">4&emsp;nvim-treesitter</h1><ol><li>增量选择，可视模式下<code>&lt;CR&gt;</code>与<code>&lt;BS&gt;</code>进行选择；  </li></ol><pre class="line-numbers language-lua"><code class="language-lua">  incremental_selection <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">-- 启用增量选择</span>    enable <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>    keymaps <span class="token operator">=</span> <span class="token punctuation">{</span>      init_selection <span class="token operator">=</span> <span class="token string">'&lt;CR>'</span><span class="token punctuation">,</span>      node_incremental <span class="token operator">=</span> <span class="token string">'&lt;CR>'</span><span class="token punctuation">,</span>      node_decremental <span class="token operator">=</span> <span class="token string">'&lt;BS>'</span><span class="token punctuation">,</span>      scope_incremental <span class="token operator">=</span> <span class="token string">'&lt;TAB>'</span><span class="token punctuation">,</span>    <span class="token punctuation">}</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li>智能选择，<code>v.</code>、<code>v;</code>、<code>vi;</code>分别对应smart、outer、inner三种模式；</li></ol><pre class="line-numbers language-lua"><code class="language-lua">textsubjects <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">-- 智能选择</span>    enable <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>    prev_selection <span class="token operator">=</span> <span class="token string">','</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">-- (Optional) keymap to select the previous selection</span>    keymaps <span class="token operator">=</span> <span class="token punctuation">{</span>      <span class="token punctuation">[</span><span class="token string">'.'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'textsubjects-smart'</span><span class="token punctuation">,</span>      <span class="token punctuation">[</span><span class="token string">';'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'textsubjects-container-outer'</span><span class="token punctuation">,</span>      <span class="token punctuation">[</span><span class="token string">'i;'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'textsubjects-container-inner'</span><span class="token punctuation">,</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="3"><li>文本对象的选择、跳转、交换等，新文本对象f(function)、c(class)；移动快捷键h为start、l为end、j为next、k为previous、小写为function、大写为class；</li></ol><pre class="line-numbers language-lua"><code class="language-lua">  textobjects <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">-- 智能跳转</span>    select <span class="token operator">=</span> <span class="token punctuation">{</span>      enable <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>      <span class="token comment" spellcheck="true">-- Automatically jump forward to textobj, similar to targets.vim</span>      lookahead <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>      keymaps <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token comment" spellcheck="true">-- You can use the capture groups defined in textobjects.scm</span>        <span class="token punctuation">[</span><span class="token string">"af"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.outer"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"if"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.inner"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"ac"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@class.outer"</span><span class="token punctuation">,</span>        <span class="token comment" spellcheck="true">-- you can optionally set descriptions to the mappings (used in the desc parameter of nvim_buf_set_keymap</span>        <span class="token punctuation">[</span><span class="token string">"ic"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">{</span> query <span class="token operator">=</span> <span class="token string">"@class.inner"</span><span class="token punctuation">,</span> desc <span class="token operator">=</span> <span class="token string">"Select inner part of a class region"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>      <span class="token comment" spellcheck="true">-- You can choose the select mode (default is charwise 'v')</span>      selection_modes <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token punctuation">[</span><span class="token string">'@parameter.outer'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'v'</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">-- charwise</span>        <span class="token punctuation">[</span><span class="token string">'@function.outer'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'V'</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">-- linewise</span>        <span class="token punctuation">[</span><span class="token string">'@class.outer'</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">'&lt;c-v>'</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">-- blockwise</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>      <span class="token comment" spellcheck="true">-- If you set this to `true` (default is `false`) then any textobject is</span>      <span class="token comment" spellcheck="true">-- extended to include preceding xor succeeding whitespace. Succeeding</span>      <span class="token comment" spellcheck="true">-- whitespace has priority in order to act similarly to eg the built-in</span>      <span class="token comment" spellcheck="true">-- `ap`.</span>      include_surrounding_whitespace <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    move <span class="token operator">=</span> <span class="token punctuation">{</span>      enable <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span>      set_jumps <span class="token operator">=</span> <span class="token keyword">true</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">-- whether to set jumps in the jumplist</span>      goto_next_start <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token punctuation">[</span><span class="token string">"xl"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.outer"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"xL"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@class.outer"</span><span class="token punctuation">,</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>      goto_previous_start <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token punctuation">[</span><span class="token string">"xh"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.outer"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"xH"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@class.outer"</span><span class="token punctuation">,</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>      goto_next_end <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token punctuation">[</span><span class="token string">"xj"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.outer"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"xJ"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@class.outer"</span><span class="token punctuation">,</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>      goto_previous_end <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token punctuation">[</span><span class="token string">"xk"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@function.outer"</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token string">"xK"</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token string">"@class.outer"</span><span class="token punctuation">,</span>      <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="telescope">5&emsp;telescope</h1><p>模糊搜索神器，有很多扩展，我装了<code>fzf</code>（模糊匹配）、<code>bookmarks</code>（书签,基于vim-bookmarks？）、<code>heading</code>、<code>emoji</code>、<code>neoclip</code>，此外还有个`telescope-coc，下面是我设置的快捷键位：  </p><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>&lt;leader&gt;f</td><td>find files(当前buffer所在文件层级开始)</td></tr><tr><td>&lt;leader&gt;F</td><td>搜寻当前git项目中的文件(应用gitignore)</td></tr><tr><td>&lt;leader&gt;b</td><td>search buffers</td></tr><tr><td>&lt;leader&gt;o</td><td>search symbols in current file</td></tr><tr><td>&lt;leader&gt;s</td><td>search symbols in project</td></tr><tr><td>&lt;leader&gt;g</td><td>live grep, 内容搜索</td></tr><tr><td>&lt;leader&gt;G</td><td>live grep cursor word, 内容搜索所选单词</td></tr><tr><td>&lt;leader&gt;m/<space>ma</space></td><td>search bookmarks</td></tr><tr><td>&lt;leader&gt;d</td><td>search coc diagnostic</td></tr><tr><td>&lt;leader&gt;h</td><td>jump between headings(md、beancount…)</td></tr></tbody></table><p>模糊匹配平时感觉用的挺多，这里先说下书签相关快捷键：</p><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>mm</td><td>当前行做标记</td></tr><tr><td>mi</td><td>当前行做标记,并写上相应的注释</td></tr><tr><td>mn</td><td>跳到下一个标记</td></tr><tr><td>mp</td><td>跳到上一个标记</td></tr><tr><td>ma</td><td>show all bookmarks</td></tr><tr><td>mc</td><td>删除当前buffer的标记</td></tr><tr><td>mx</td><td>删除所有buffer的标记</td></tr></tbody></table><h1 id="nvim-surround">6&emsp;nvim-surround</h1><p>Add/delete/change surrounding pairs</p><table><thead><tr><th>快捷键</th><th>示例</th><th>功能</th></tr></thead><tbody><tr><td>ys</td><td>ysiw(</td><td>在当前文本对象周围增加surround</td></tr><tr><td>ds</td><td>ds[</td><td>删除一个[]</td></tr><tr><td>cs</td><td>cs’”</td><td>将一对’改为一对”</td></tr></tbody></table><h1 id="vista">7&emsp;vista</h1><p>显示symbols和tags导航栏，快捷键<code>cn</code></p><h1 id="vim-floaterm">8&emsp;vim-floaterm</h1><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>&lt;C-t&gt;</td><td>显示/关闭悬浮窗</td></tr><tr><td>&lt;C-n&gt;</td><td>新建悬浮窗</td></tr><tr><td>&lt;C-p&gt;</td><td>上一个悬浮窗</td></tr></tbody></table><h1 id="vim-commentary">9&emsp;vim-commentary</h1><p><code>:Commentary</code>注释代码，设定快捷键为<code>&lt;space&gt;lc</code>，默认快捷键如下：</p><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>gcc</td><td>comment out a line</td></tr><tr><td>gcaw</td><td>comment out a textobject</td></tr><tr><td>gc</td><td>comment out selected(visual mode)</td></tr></tbody></table><h1 id="undotree">10&emsp;undotree</h1><p>显示编辑历史记录，<code>:UndotreeToggle</code>，设定快捷键<code>&lt;space&gt;cu</code>，打开后按<code>?</code>可查看更具体的帮助。</p><h1 id="nvim-spectre">11&emsp;nvim-spectre</h1><p>文件名替换，同时对多个文件进行替换。</p><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>&lt;space&gt;sp</td><td>在当前项目中搜索</td></tr><tr><td>&lt;space&gt;sP</td><td>搜索当前光标</td></tr></tbody></table><h1 id="code-runner">12&emsp;code_runner</h1><p>只用该插件的<code>:RunCode</code>命令，忽略其他功能，快捷键我设为<code>&lt;Space&gt;rc</code></p><h1 id="vim-table-mode">13&emsp;vim-table-mode</h1><p><code>&lt;space&gt;tm</code>进入/退出表格编辑模式</p><h1 id="coc-nvim">14&emsp;coc-nvim</h1><table><thead><tr><th>快捷键</th><th>功能</th></tr></thead><tbody><tr><td>gd</td><td>跳转到定义处</td></tr><tr><td>gr</td><td>跳转到references-used</td></tr><tr><td>K</td><td>可以查询函数，变量，宏等，注释将会显示在悬浮窗口上</td></tr><tr><td>gy</td><td>跳转到type-definition处</td></tr><tr><td>gi</td><td>跳转到implementation</td></tr><tr><td>[g, ]g</td><td>跳转到coc各个诊断处</td></tr><tr><td>&lt;leader&gt;ln</td><td>重命名变量（别用算了，直接用nvim-spectre重命名）</td></tr><tr><td>&lt;leader&gt;d</td><td>打开诊断窗口（前面讲过了）</td></tr></tbody></table>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2023-01-26-neovim-yi-xie-cha-jian-kuai-jie-jian-bei-wang-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>2022年总结——躺平的一年</title>
      <link>https://chengpengzhao.com/2023-01-25-2022-nian-zong-jie-tang-ping-de-yi-nian/</link>
      <guid>https://chengpengzhao.com/2023-01-25-2022-nian-zong-jie-tang-ping-de-yi-nian/</guid>
      <pubDate>Wed, 25 Jan 2023 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;小目标回顾&quot;&gt;1&amp;emsp;小目标回顾&lt;/h1&gt;&lt;ol&gt;
&lt;li&gt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="小目标回顾">1&emsp;小目标回顾</h1><ol><li><del>通过5月28日的软考（高级系统架构设计师）</del>      <code>因疫情取消了，下半年懒没有考。话说上半年只有系分下半年才有架构考，这个当初都没调研清楚= =</code></li><li><del>7月的JLPT N1拿到满分（扣5分之内能够接受）</del>        <code>低估了出国党的人数和实力，根本抢不到考试名额啊有没有，开放报名没多少分钟考场座位全空</code></li><li>资产达到15w（穷啊）      <code>勉强达到目标，明年再接再厉</code></li></ol><h1 id="2022年总结">2&emsp;2022年总结</h1><p>首先看着2022年的时间都去哪了吧：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202301251123581.jpg" alt></p><p>回顾一下我的时间分类：</p><ul><li>睡眠，毕竟人类的一生有$\frac{1}{3}$的时间都在睡觉  </li><li>消费时间，指我们每天的日常工作（或学业），为了获取报酬所花的时间  </li><li>投资时间，有助于我们提高自身能力的，比如读书运动学习新技能等  </li><li>浪费时间，洗漱、通勤、用餐等硬性时间  </li><li>消磨时间，放空、打游戏看剧等娱乐活动  </li></ul><p>2022年一共有$24\times 365=8760$个小时，我的记录包含8758个小时，还剩0.1%左右的时间因为忘记了等因素没有记录，且有小段时间记录重叠了。从饼图可以得出：  </p><ol><li>2022年的睡眠时间占比34.2%，同比上升1.1%；    <code>睡眠状态健康，但入睡时间太晚，2023年需要注意在23:30左右强制进入睡眠模式，并适当减少睡眠时间来做更多有意义的事。睡眠计划占比30%</code>  </li><li>2022年消磨时间占比28.3%，同比上升3.4%；  <code>不得不又重复一遍这句：zcp啊zcp你怎么可以如此堕落。2023一定要减少这部分时间至20%以下，准备重新拿起琴玩玩，总比游戏更有意义</code></li><li>2022年消费时间占比27.1%，同比上升6.8%；  <code>工作时间甚至比不上消磨的时间，可见2022年有多“躺平”，今年部门OKR已经出来了，承担的责任与任务开始增多，在工作上肯定是要稍微加把劲的，计划在30%左右</code></li><li>2022年投资时间6.0%，同比减少9.3%！   <code>减少的时间都用来打游戏了吧这是！这个趋势值得引起警惕，不投资自己等同于逐渐向淘汰的边缘前行。2023年该占比必须在15%以上！</code></li><li>2022年浪费时间占总时间4.4%，同比减少1.9%；  <code>2022年开始点外卖了，同时大幅减少了自己做饭的次数，这不是个好兆头。2023年需要适当增加，对自己的健康负责</code></li></ol><p>下面再来看看每个月的各时间占比：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202301251234932.png" alt></p><ol><li>睡眠时间春夏较少，秋冬被窝太暖和了所以相对更长。12月得了新冠那段时间从早休息到晚，花了几周才差不多完全恢复；</li><li>消费时间和消磨时间基本上是完全相反的走势，工作少了说明玩游戏的时间多了，反之亦然。但两者之和占比应该是比较固定的；消磨时间的几个高点：2月份春节期间、6月份沉迷玩SCUM、10月份国庆；</li><li>浪费时间在5月份后明显下跌，正好是疫情管控与开始点外卖的时间段；</li><li>投资时间与消费时间的趋势相近，体现了自己在不想工作的时候也完全不想学些其他的东西，这个得改。</li></ol><h1 id="2023的小目标">3&emsp;2023的小目标</h1><p>去年对定下的目标重视不够，导致有两个没有完成，今年吸取教训，端正态度，定下如下小目标：</p><ol><li>通过软考，100天复习计划，每天至少2h，最后30天每天至少3h（系统分析师）</li><li>减脂，一季度体重减至72kg左右并维持。每周运动时间不少于4h</li><li>论文、专利至少都得有1个，不能总只写代码吧</li><li>资产达到30w（攒钱攒钱）</li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2023-01-25-2022-nian-zong-jie-tang-ping-de-yi-nian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>NAS使用状态记录</title>
      <link>https://chengpengzhao.com/2022-07-31-nas-shi-yong-zhuang-tai-ji-lu/</link>
      <guid>https://chengpengzhao.com/2022-07-31-nas-shi-yong-zhuang-tai-ji-lu/</guid>
      <pubDate>Sun, 31 Jul 2022 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;硬件配置&quot;&gt;1&amp;emsp;硬件配置&lt;/h1&gt;&lt;p&gt;2020年8月在
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="硬件配置">1&emsp;硬件配置</h1><p>2020年8月在淘宝买的，蜗牛星际，INTEL Xeon D-1527 CPU、4G内存、16G固态当做启动盘，当时价格398，前几天去看的时候已经变成了999，配置基本没啥变化，可能就黑群晖系统更新了下吧，说不定还是放了好几年或者继续挖了一段时间矿的机器。当然也可能是单纯的没货了，其他店铺的价格还是比较正常的。  </p><p>自己买了两块2T的希捷酷狼NAS用机械硬盘，560一块。采用的是RAID 1，也就是两块硬盘的内容是完全相同的，来降低数据损坏的风险。  </p><p>用了一年多的时候电源坏了，里面的风扇咔咔地响，吵的睡不着觉，又去淘宝买了个129的1Uflex电源（和原装同款）。  </p><p>硬件上一共花了2000多块，在承受范围之内。花钱不心疼的话建议直接上正版，我记得四盘位的好像要4500左右（好贵啊）。  </p><p>还有一种方案，那就是拿多余的笔记本电脑当NAS，虚拟机里装个黑群晖系统，一样能用。  </p><h1 id="软件与服务">2&emsp;软件与服务</h1><p>NAS主要用来保存重要数据的话，自带的一些软件如Drive、Moments就挺好用了，如果要部署一些服务的话，那就离不开Docker了。<br>有些<a href="https://wp.gxnas.com/category/nas" target="_blank" rel="noopener">大佬的博客</a>专门介绍了NAS使用的各种姿势，我一开始也是从这里学起的。最好的话先学一些linux的知识，包括linux里docker怎么使用，群晖上操作无非就是做了个界面，有时候还是通过ssh登录到终端在里面用命令行配置比较快。  </p><p>下面记录一下我一直在用的一些服务吧，如果你有其他NAS上好用的服务或软件，欢迎留言补充。  </p><h2 id="moments">2.1&emsp;moments</h2><p>Moments是群晖应用商店里的一款照片管理软件，可以自动对照片进行分类，什么人脸识别、场景识别，该有的都有。不过我平时不怎么拍照，用到其实不怎么多，更深入的用法可以参考<a href="https://post.smzdm.com/p/av7zn43p/" target="_blank" rel="noopener">其他用户分享的使用方法</a>。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311200903.png" alt="自动识别主题"></p><h2 id="emby">2.2&emsp;emby</h2><p>多媒体文件，除了图片还剩下音频和视频，我用的是emby管理（付费了，想免费可用Jellyfin代替）。emby是为数不多的私人多媒体服务器软件，它有最强大的影片搜刮能力，并且可以非常便捷远程维护其媒体库,提供全平台客户端和web端支持。  </p><p>作为曾经的网易云Lv10用户，在网易云音乐这个app上见证了这几年言论和意识形态管控的不断升级，随着一些歌曲的下架和评论的大量删除，我把网易云歌单里的20000多首音乐下载后转移到了NAS，emby的刮削功能确实很强大，但使用了一段时间后发现它的音频播放有个致命的缺点：没办法显示歌词（即使MP3文件中自带）。所以有时我也会选择NAS自带的Audio Station来听歌。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311217783.png" alt="刮削得到的专辑页面"></p><h2 id="gogs">2.3&emsp;gogs</h2><p>日常用的最多的服务了，工作、学习里的一些git仓库都用它来管理，毕竟有些数据（比如beancount记账信息）就算放在github的私人仓库还是感觉不够安全。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311222067.png" alt></p><h2 id="mango">2.4&emsp;mango</h2><p>死宅必备漫画管理软件，我没有将看过的电影、动漫都存起来的习惯（因为文件太大），但漫画的话一是文件本身不大，二是一些在线浏览网站广告一大堆阅读体验差，三是下载的漫画有多种格式不方便管理。我选择用mango这款工具来整理、浏览漫画。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311229571.png" alt="漫画架"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311233787.png" alt="分卷显示">  </p><h2 id="aria2">2.5&emsp;aria2</h2><p>Aria2大家都知道，BT和磁力链接下载器，用来代替迅雷。我最近很少用。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311234639.png" alt></p><h2 id="calibre-web">2.6&emsp;calibre-web</h2><p><a href="https://github.com/janeczku/calibre-web" target="_blank" rel="noopener">github相关页面</a></p><p>图书管理利器！用来搭建个人图书馆，配合豆瓣获取元数据（需要额外插件，豆瓣原来开放的API被禁用了）十分舒适。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311241832.png" alt="我曾经的读书计划"></p><h2 id="wiznote">2.7&emsp;wiznote</h2><p><a href="https://www.wiz.cn/zh-cn" target="_blank" rel="noopener">为知笔记</a>作为一款支持本地部署的笔记工具，我还是比较看好的，也用了很长一段时间。主要格式采用Markdown，导入导出也方便，缺点的话一是编辑笔记不方便、我希望用自己熟悉的工具（如nvim）直接编辑md文件，二是多端同步经常出些问题，明明显示同步完成结果还是没把最新的变动同步出来。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207311247349.png" alt="支持web访问"></p><p>前些日子开始转用Obsidian了。</p><h2 id="nextcloud">2.8&emsp;nextcloud</h2><p><a href="https://nextcloud.com/" target="_blank" rel="noopener">官方主页</a></p><blockquote><p>Nextcloud是一款开源免费的私有云存储网盘项目，可以让你快速便捷地搭建一套属于自己或团队的云同步网盘，从而实现跨平台跨设备文件同步、共享、版本控制、团队协作等功能。它的客户端覆盖了Windows、Mac、Android、iOS、Linux 等各种平台，也提供了网页端以及 WebDAV接口，所以你几乎可以在各种设备上方便地访问你的云盘。</p></blockquote><p>私有云这方面的服务有太多，nextcloud的特点是功能比较全，包括插件也很丰富，同时也比较占资源。我主要的使用场景主要有两个：  </p><ol><li>需要从一个设备发送文件（不大）到另一个设备(跨平台)，直接打开网页先把文件传到nextcloud上，另一个设备再下载。不需要额外的软件，相对比较便利；  </li><li>webDAV功能，用来配合Zotero存文献与多设备的文献同步。</li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2022-07-31-nas-shi-yong-zhuang-tai-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>聊聊这两年沉迷的开放世界生存游戏</title>
      <link>https://chengpengzhao.com/2022-07-26-liao-liao-zhe-liang-nian-chen-mi-de-kai-fang-shi-jie-sheng-cun-you-xi/</link>
      <guid>https://chengpengzhao.com/2022-07-26-liao-liao-zhe-liang-nian-chen-mi-de-kai-fang-shi-jie-sheng-cun-you-xi/</guid>
      <pubDate>Tue, 26 Jul 2022 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;strong&gt;多图警告！！！&lt;/strong&gt;&lt;/p&gt;
&lt;h1 id=&quot;我
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><strong>多图警告！！！</strong></p><h1 id="我心目中的开放世界生存游戏">1&emsp;我心目中的开放世界生存游戏</h1><ul><li>开放世界：</li></ul><p>首先看看Wiki百科的解释： </p><blockquote><p>開放世界（英語：Open world）是電子遊戲關卡設計的一種，玩家可以自由地在虛擬世界漫遊，並可自由選擇完成遊戲任務的時間點和方式。這類型的遊戲也常被稱為「漫遊式遊戲」（free roam），或被不嚴謹地稱呼為「沙盒式遊戲」（sandbox）。<br>「開放世界」和「漫遊」代表了遊戲中不存在版圖的阻礙，與之相對的是線性關卡設計中常見隱形牆和讀取畫面（英語：loading screen）。開放世界遊戲並不一定是沙盒式遊戲，在真正的沙盒式遊戲中，玩者可自由對遊戲世界進行修改，並創造自己的遊玩方式。</p></blockquote><p>也就是说，这类游戏首先要有一个大的<strong>地图</strong>，并且地图在技术上没有限制新玩家的可到达范围，刚进入游戏的萌新也可以自由地逛街。当然在实际情况中某些区域可能需要特殊手段才能到达，或者是特别危险、需要满足一定条件之后才能去，这都并不影响<strong>开放</strong>的判定。</p><ul><li>生存：</li></ul><blockquote><p>生きてこの世にいること[生存（せいぞん）の意味 - goo国語辞書]</p></blockquote><p>即这类游戏的首要目的十分明确，那就是活下去。通常刚开始时玩家只有极少的装备，需要收集资源、工具、武器和建造住所，以尽可能长时间地在恶劣的环境中存活。这种生存游戏有很多都是开放世界类型的。  </p><p>除了上述特征之外，我心目中的开放世界生存游戏还有如下特点：  </p><ol><li>多人服务器，这么大的世界只有自己一个人、其他都是NPC的话也太无聊了；  </li><li>存在PVP模式，不仅要提防自然，更要防人；  </li><li>有交通工具，没有的话说明地图不够大；  </li><li>完善的建造系统，没一时半会搞不清怎么玩的那种。  </li></ol><p>一些开放世界游戏如GTA5、塞尔达传说旷野之息、艾尔登法环显然不符合生存这一标签。<br>我玩过的一些开放世界生存游戏：英灵神殿（还行但只支持局域网）、饥荒（感受不到乐趣、弃）、7DaysToDie（这什么画质、都2022年了）、中世纪王朝（单机）以及接下来要重点介绍的两个。<br>我没时间玩但也很有名的几个开放世界生存游戏：ARK（方舟生存进化）、DayZ、Rust和最近很火的V Rising（吸血鬼崛起）。  </p><h1 id="Conan-Exiles">2&emsp;Conan Exiles</h1><h2 id="介绍">2.1&emsp;介绍</h2><blockquote><p>流放者柯南是一款開放世界生存類遊戲，以《蠻王柯南》中的荒野之地為背景。你是數以千計的流放者中的一員，被驅逐到一塊被沙暴席捲的蠻荒之地，在這片大地上，四面八方都是會攻擊你的敵人。在這裡你必須生存、建造並進行統治。<br>飢餓、口渴、孤獨，你的第一場戰鬥是面對殘酷的環境。種植莊稼或者狩獵動物來獲得食物。採集資源來製作武器和工具。 建造一個避難所來生存下去。在廣闊的世界中獨自旅行、探索，或者是聯合其他玩家來建立一整個居住地和要塞以抵禦外敵入侵。<br>足夠強大時，你該為了統治這塊流放之地掀起戰鬥、挑起戰爭攻擊你的敵人們。在神明們的祭壇上獻祭敵對玩家並以你自己的想法改變力量的平衡。在野蠻的快節奏的戰鬥中釋放你的怒火，處決敵人和肢解攻擊會讓腦袋落地、四肢橫飛。</p></blockquote><p>2020年正在准备硕士毕设那会开始玩的，刚进游戏瞬间就被吸引住了，大喊“这不就是我理想中的开放世界生存游戏应有的样子么！”，沉迷到毕设答辩的前一天晚上还上线迎接了一波扫荡（游戏特色，一段时间后大批怪来拆家）。工作之后逐渐不再有时间上线，建的豪华别墅与大量资源也腐朽（消失）了，自此退坑。<br>最近官方又在搞事，游戏即将迎来一次超大的更新，看了下好像是魔法时代，增加了许多可玩内容，搞得我都想回归了。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207252122766.png" alt="秀一秀我的游戏时长"></p><h2 id="特点">2.2&emsp;特点</h2><h3 id="庞大的世界观">2.2.1&emsp;庞大的世界观</h3><p>《流放者柯南》这款游戏的世界以美国作家、“剑与魔法派”奇幻文学创始人罗伯特·E·霍华德的小说《野蛮人柯南》里的蛮荒之地为背景，如果有看过小说的大佬，再玩游戏不知道会不会有更多的共鸣。<br>在游戏里，你不是故事中的主人公，而是一个普通的路人。游戏其实是有完整的主线剧情的，那就是找到<strong>解除手环</strong>（限制你在流放之地活动的工具、移除相当于自杀）、<strong>逃离流放之地</strong>。但游戏里是不会告诉你具体方法的，需要不断探索世界、收集关键物品。详细的流程可以参考steam上这篇<a href="https://steamcommunity.com/sharedfiles/filedetails/?id=1445861423" target="_blank" rel="noopener">【剧情向】解除手环的方法</a>文章。<br>在这个相当漫长的过程中（解除手环相当于删除角色、跟游戏说88了），你会收集到许多关于流放之地历史残留的碎片信息与特殊物品，逐渐拼凑起一个庞大的世界。你会体会到个人在游戏里是多么渺小，我在玩了500小时后看到一位贴吧大佬的<a href="https://tieba.baidu.com/p/7390045126?pn=1" target="_blank" rel="noopener">剧情分析文章</a>后仍感觉有大量自己觉得新鲜的地方，自己掌握的知识不过是这个世界拼图的一小块。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262001339.jpg" alt="看上去就很强的生物之一——红龙"></p><h3 id="广阔的地图">2.2.2&emsp;广阔的地图</h3><p>作为一款开放世界游戏，不得不说的就是它的地图了，从沙漠到雨林、再从雪地到火山，《流放者柯南》的地图可以说是足够广阔了。人物的旅途起始于最南边的沙漠，随着装备的积累逐渐向东发展或是北上，雪山地区必须要一定的防寒措施才能进入，火山类似，这两个地区的敌人也是最强的。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207261929778.png" alt="流放之地"></p><p>不得不说流放之地的风景还是很不错的，可惜当时没怎么截图。官方还有一个西普塔岛的地图，放在了一个DLC里，这里就不展开介绍了。  </p><h3 id="丰富的模组">2.2.3&emsp;丰富的模组</h3><p>这个游戏的mod现在已经有接近3000个了，可以说是非常丰富，有些大型mod（比如天灾系列）加上之后可以说完全又是另外一款游戏了。游戏里有很多启用了这些mod的服务器，可以和朋友愉快地玩耍，不过我主要玩的是PVE官服，模组方面其实是没怎么体验的。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262006613.png" alt="mod列表"></p><h3 id="耐玩的内容">2.2.4&emsp;耐玩的内容</h3><p>像Far Cry这类游戏，可能刚开始玩的时候比较新鲜，但玩着玩着发现其实每个任务都差不多，无非是换换场景，这种重复度会不断消磨玩家的游戏体验直到卸载。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262010892.png" alt="游戏内容划分"></p><p>与之相对的，《流放者柯南》在可玩性上就有很大的自由度，首先光是熟悉这些东西就得花个几十个小时。游戏的一大特点是可以抓奴隶（后期主力、自己就是一跟班）、抓宠物（幼崽、蛋），还可以骑马爬山耕作，pvp还有各种拆家打架（新手远离pvp），装备有各种套装、属性搭配等，建筑系统更不用说。总之就是很耐玩吧，不会让人很快感到失去乐趣。<br>好在服务器上还有很多其他玩家，不懂的地方可以直接公屏问他们，我在萌新期时就受到了一些大佬的关照，还送了我一些开荒装备。偶尔还会碰到一些外国人，比如新加坡的、日本的、韩国的，感觉还是蛮有意思的。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262015801.jpg" alt="和其他玩家沟通"></p><h3 id="特色的建筑">2.2.5&emsp;特色的建筑</h3><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262120099.webp" alt="丰富的建筑模块"></p><p>说到《流放者柯南》，不得不提的就是它的建筑系统，它有多个风格的建筑（需购买DLC）如契泰、阿奎洛尼亚、野蛮边境、邪马台、图兰、西伯莱、得喀托、西普塔岛等，只可惜好像没有中国风的特色建筑。家里可以摆各式各样的家具、工具台、储存箱、装饰物，可以说是满足了建筑党的大部分需求吧。<br>下图是从官方举办的建筑比赛中随便翻到的一个获奖作品，这设计水平显然不是我等只会建火柴盒的低端玩家可以触及的。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262130356.jpeg" alt="Temple of Ymir by Deaso"></p><h2 id="杂感">2.3&emsp;杂感</h2><p>这个游戏很大一部分活跃度是由PVP玩家贡献的，但由于PVP想想就觉得累，对于像我这样的休闲玩家是不会沾的。PVE的话几百个小时其实也差不多毕业了，也就是各种传奇奴隶不缺、资源装备都有、世界各处都逛了个遍这样的状态。接下来还能坚持玩多久主要靠自己的想象力，自己定一个有意思的目标（比如建20层兽栏养100只金石鼻兽），然后去达成它，其他玩家来自家参观有时会不禁发出一些了不起的感叹，这种时刻的成就感我想也是游戏的乐趣所在。  </p><p>最后放几张玩的时候随手截的图作为这部分的完结吧，可惜没有把自己建的家记录下来，有几栋高楼（掉下去要自由落体好几秒）的那种，感觉还挺壮观的hhh  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262142110.jpg" alt="无聊修山路玩，爬支撑柱"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262143420.jpg" alt="修路途中俯览宫殿风景"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262144038.jpg" alt="雪山偶遇流星雨"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207262145015.jpg" alt="海景房独自赏月"></p><h1 id="SCUM">3&emsp;SCUM</h1><h2 id="介绍-1">3.1&emsp;介绍</h2><blockquote><p>《SCUM》作为娱乐巨头TEC1公司推出真人秀节目数字游戏版，本季中，比赛场地由原来的破烂、封闭的室内竞技场转移到了TEC1公司旗下的SCUM岛上沼泽密布的树林、平整辽阔的草地、以及其他崎岖不平的山地。上一季最受观众喜爱的选手以及新参赛的囚犯们将在岛上展开残忍的生死搏杀，只为争取观众、制作人以及赞助商的青睐，获得声望、赢得奖励，在九死一生中求得一线生机。<br>在这里，唯有知识与技能才是助你长久存活的终极武器。融合了硬核生存游戏中各种规划和管理等元素，角色拥有营养、代谢率、武器能力、战斗类型、破坏安全系统等设定，玩家需要平衡自身的各项属性、技能。同时加入了玩家随时可参与的支线PvP“线上活动”，SCUM在复杂的生存模拟和激烈的动作元素中取得了微妙的平衡，为玩家献上一款新世代生存游戏。这里有丧尸、野兽、人渣(SCUM)甚至是极端天气</p></blockquote><p><a href="https://forum.gamer.com.tw/C.php?bsn=30860&snA=73" target="_blank" rel="noopener">SCUM游戏背景故事介绍</a></p><p>游戏刚出来的时候就买了，当时玩了一段时间后因太过硬核、以及很多地方不够完善而退坑。2022年51假期又回归了，游戏经过相当长的发展后已经比原来好很多，虽然目前还是0.7版本，离正式版还有很长的路要走…  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207252141412.png" alt="秀一秀我的游戏时长"></p><h2 id="特点-1">3.2&emsp;特点</h2><h3 id="硬核与拟真">3.2.1&emsp;硬核与拟真</h3><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207271959278.jpg" alt="军事地堡中随地大便"></p><p>硬核与拟真在scum不仅体现在可以拉屎这个有点搞笑的设定上，而是表现在游戏的方方面面，如：  </p><ol><li>每种枪都是根据现实来进行设计的，光有把枪还不够，还需要对应的弹夹，对应的子弹。scum里子弹的种类就有7.62x39mm、7.62x54mm、5.45x39mm、.30-06mm、9mm、.22mm、.50AE、.357等近几十种；  </li><li>给弹夹上子弹时是一颗一颗往里塞的；  </li><li>枪耐久低了会故障，卡膛什么的还需要诊断是哪个部位出了问题；  </li><li>所有食物的营养成分都是以现实为参照设定的，不同食物的消化速度也不一样；  </li><li>下雨了衣服会淋湿，衣服重量会增加；  </li><li>捡到的东西都是放在衣服或背包里的，衣服脱了或损坏了里面的东西也就没了；  </li><li>人物的属性（力量、体质、敏捷）需要长时间的锻炼才能提高，反之如果暴饮暴食相应属性也会降低；  </li><li>人类无法和高达抗衡（物资点看门机器人），被发现只有跑或者死两个选择；  </li><li>驾驶技能不高，车是会经常熄火的。<br>…</li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272001047.jpg" alt="人物属性面板图，看着就觉得硬核"></p><h3 id="优美的景色">3.2.2&emsp;优美的景色</h3><p>scum里很多地方风景都挺好的，特别是黄昏时分。虽然地图个人感觉不如流放者柯南那么有特色（很多城市、乡村的建筑模型都一个样，利用率比较高），但还是可以接受的。下面直观来感受一下游戏画面吧~  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272011222.jpg" alt="雪地里的拖拉机"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272012946.jpg" alt="黄昏时的机场"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272013289.jpg" alt="夜色中飞行"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272014359.jpg" alt="甚至可以在游戏里开烟花大会"></p><h3 id="锻炼心态">3.2.3&emsp;锻炼心态</h3><p>从游戏的背景可以看出，scum是一款不折不扣的pvp游戏，刚开始官方服务器也都是pvp的，直到后来才出了很少几个面向pve玩家的官服。<br>在pvp中，你可能辛辛苦苦搜了一天的物资，结果碰到一个蹲点的有缘人，把你一身家当全劫掠走了；你可能建了个自以为固若金汤的家，结果直接被有开锁大佬的小队拆家；你可能以为把箱子埋起来别人就找不到了，结果大佬直接拿个金属探测器地毯式搜索… 当然这些其实都是能够接受的，毕竟pvp的一部分乐趣也来自于这种胆战心惊、苟且偷生的感觉，最搞人心态的还是非那些开挂的玩家莫属了，这里就不展开讲了。<br>在pve里，虽然没那么勾心斗角，但各种游戏bug也会搞得你没法安安心心过日子：车开着开车就掉进了虚空或者爆炸了（因为模型没加载出来），一车家当瞬间清空；正开着飞机结果服务器掉线了，重进后发现机毁人亡；背包里的物品、枪里的弹夹不知怎么的就被bug给吞了；明明把所有材料都放进去了，建筑还是显示未完成状态，只好拆了重来…</p><p>所以说这个游戏真的很锻炼心态，也有不少玩家因为这些bug而退坑的。但我觉得和游戏的可玩性相比，这些都是可以接受的。毕竟这个游戏还是处于开发阶段，虽然马上就要到0.8大版本更新了，但离正式发布还有很长一段时间，只能期待开发团队越做越好了。  </p><h2 id="杂感-1">3.3&emsp;杂感</h2><p>这个游戏还有一个不得不提的地方，就是它的服务器。scum是不支持局域网联机的，只有单人或者服务器在线两种选项，国内scum的服务器状态只能用鱼龙混杂来形容，各种氪金商城权限服接踵而至，如果是想要获得一个比较好的游戏体验，还是推荐先去官方的服务器玩一玩。虽然难度大，但起码是这个游戏最原生的环境，可以体验到生存是多么的不易hh，还可以和众多老外进行一番“友好交流”。<br>玩了一段时间后，可以根据自己的偏好来挑选一些特色服务器，比如说丧尸数量很多、爆率相对高一点的服务器，或者是既支持pve又支持pvp的服务器等等。比如我就嫌官服丧尸太少，找了个能玩“求生之路”的服务器，开车在路上大概是这样的感觉：  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202207272044026.jpg" alt="你不要过来啊"></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2022-07-26-liao-liao-zhe-liang-nian-chen-mi-de-kai-fang-shi-jie-sheng-cun-you-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>迟到的2021年总结——时间都去哪了</title>
      <link>https://chengpengzhao.com/2022-03-08-chi-dao-de-2021-nian-zong-jie-shi-jian-du-qu-na-liao/</link>
      <guid>https://chengpengzhao.com/2022-03-08-chi-dao-de-2021-nian-zong-jie-shi-jian-du-qu-na-liao/</guid>
      <pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;目前的状态&quot;&gt;1&amp;emsp;目前的状态&lt;/h1&gt;&lt;p&gt;说到最近的状
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="目前的状态">1&emsp;目前的状态</h1><p>说到最近的状态，从3个多月博客没有更新、个人年终总结拖到2022年过了快$\frac{1}{4}$才想起来写就可以看出来：慵懒、浑浑噩噩、行尸走肉…<br>具体表现在： 近2个月没去健身房、下班后只想打游戏丝毫不想学习、找游戏玩追剧找漫画看的无限循环、周末出门的话一定是去超市、一觉睡到8点不想起床、周末学习一整天的计划从未实现过…<br>当然工作的时候还是没空摸鱼，毕竟事情一堆怎么做都不会完。<br>最近pc游戏也几乎玩腻了，switch的话海拉鲁大陆也探索的差不多了，忽然良心发现是不是应该开始学习、投资自己了。以此为契机，顺便整理下去年都在干嘛吧。</p><h1 id="2021年总结">2&emsp;2021年总结</h1><p>首先看着2021年的时间都去哪了吧：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202203082222184.PNG" alt></p><p>我把时间分成了4类：</p><ul><li>睡眠，毕竟人类的一生有$\frac{1}{3}$的时间都在睡觉  </li><li>消费时间，指我们每天的日常工作（或学业），为了获取报酬所花的时间  </li><li>投资时间，有助于我们提高自身能力的，比如读书运动学习新技能等  </li><li>浪费时间，洗漱、通勤、用餐等硬性时间  </li><li>消磨时间，放空、打游戏看剧等娱乐活动  </li></ul><p>2021年一共有$24\times 365=8760$个小时，我的记录包含8754个小时，还剩0.1%左右的时间因为忘记了等因素没有记录，从饼图可以得出：  </p><ol><li>2021年的睡眠时间总共2898h，平均每天睡7.94h，占总时间的33.1%；<code>睡眠状态十分健康，继续保持，甚至可以适当减少睡眠时间</code>  </li><li>2021年消磨时间2182h，平均每天5.98h，占总时间24.9% ！  <code>zcp啊zcp你怎么可以如此堕落，在娱乐上竟然花了这么多时间，自己都吓了一跳，2022争取减少到1800h</code></li><li>2021年消费时间1772h，平均每天4.85h，占总时间20.2%；  <code>按天算的话工作日一般占比35%以上，非工作日为0，这部分时间每年的占比应该相对固定（由于2021上半年还没毕业，具体比例今年才能得出）</code></li><li>2021年投资时间1338h，平均每天3.67h，占总时间15.3%； <code>感觉这部分有点虚高，可能和投资时间的定义偏主观有关，是否算得上投资、自己获得了什么，有时候也很难回答清楚</code></li><li>2021年浪费时间551h，平均每天1.5h，占总时间6.4%；  <code>虽然工作日的中餐时间没算到这里面来，但平均下来时间感觉还是比较合理</code></li></ol><h1 id="2022的小目标">3&emsp;2022的小目标</h1><p>2021年的读书目标是没有完成的，究其原因很大程度上是制定的目标不够具体化，比如平摊到每个月要读多少本，这本书一共多少页、平摊到每天需要读多少页，今天忘记读书了、这个月的目标还剩多少页、会不会影响完成等等 （当然这里主要针对外文书，中文的话只要还算有点意思刷刷刷地就能看完）  </p><p>2022我给自己的目标相对就很简单、很具体了：</p><ol><li>通过5月28日的软考（高级系统架构设计师）  </li><li>7月的JLPT N1拿到满分（扣5分之内能够接受）  </li><li>资产达到15w（穷啊）</li></ol><p>看今年年终总结的时候会不会被啪啪啪打脸吧</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2022-03-08-chi-dao-de-2021-nian-zong-jie-shi-jian-du-qu-na-liao/#disqus_thread</comments>
    </item>
    
    <item>
      <title>markdown转离线单文件html</title>
      <link>https://chengpengzhao.com/2021-12-27-markdown-zhuan-chi-xian-html-dan-wen-jian/</link>
      <guid>https://chengpengzhao.com/2021-12-27-markdown-zhuan-chi-xian-html-dan-wen-jian/</guid>
      <pubDate>Mon, 27 Dec 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;经常需要写一些markd
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>经常需要写一些markdown文档，用vscode或者vim的<code>MarkdownPreview</code>插件都能实现比较好的实时渲染与编辑，但导出给别人看时发现存在一个问题：<strong>没有目录栏</strong>，文档很长时翻起来十分费劲。（vscode的导出功能我没怎么用，好像挺鸡肋就放弃了；vim的话我是直接用谷歌浏览器的SingleFile插件保存渲染的html）<br>查了一下发现有位叫i5ting的大佬很早开发过一个叫<a href="https://github.com/i5ting/tocmd.npm" target="_blank" rel="noopener">i5ting_ztree_toc</a>的工具，能够为markdown转html后生成目录并且自动编号，正好是我想要的东西。用了一会发现还不够满足自己的需求，主要有以下几点不足：  </p><p>1) 生成的html需要和一堆样式文件(<code>.css</code>、<code>.js</code>)所在的文件夹放一起；<br>2）目录栏随滚动高亮功能不错，但有图片、uml等元素时正在浏览区域与高亮条目明显对应不起来；<br>3）不支持LaTeX公式；<br>4）不支持各种图（mermaid、plantuml…）；<br>5）默认marked渲染器配置不全，高亮没有；  </p><p>综上所述，还是自己动动手修改吧。于是有了<a href="https://github.com/chengpengzhao/md2html" target="_blank" rel="noopener">md2html</a>这个工具：</p><h1 id="md2html">2&emsp;md2html</h1><p>首先几个足够展示markdown与LaTeX几乎所有常用语法的demo：  </p><p><a href="https://chengpengzhao.com/md2html/test/commTest.html">basicTest</a><br><a href="https://chengpengzhao.com/md2html/test/katexSupportTest.html">katexSupportTest</a><br><a href="https://chengpengzhao.com/md2html/test/latexTest.html">latexTest1</a><br><a href="https://chengpengzhao.com/md2html/test/tensorTest.html">latexTest2</a>  </p><p>这个工具的<strong>设计原则</strong>有如下两点：  </p><ul><li>完全<strong>本地化</strong>，所有内容不需要联网便可舒适阅览  </li><li>只能有<strong>一个</strong>html文件，所有样式文件必须内嵌进去，不能通过联网或本地其他文件的方式获取  </li></ul><p><strong>主要特性</strong>:</p><p>1）目录侧边栏与自动编号，以及定位高亮；<br>2）markdown中本地图片路径(如<code>![](img/a.png)</code>)可转为base64内嵌入html，不再需要<code>img</code>文件夹；（可禁用该转换）<br>3）plantuml支持，可选择使用<code>plantuml.jar</code>生成<code>.svg</code>到本地再转为base64嵌入html；<br>4）mermaid支持，这个比较容易实现；<br>5）flowchart.js支持(一种画流程图的)，我没怎么用过，不过也比较容易实现；<br>6）本地化KaTeX支持（一开始用Mathjax但感觉最新版很难弄进一个html里就放弃了），所有字体手动转为base64嵌入了html中；</p><h1 id="使用建议">3&emsp;使用建议</h1><p>1）默认不使用本地<code>plantuml.jar</code>（生成速度慢一些），默认转换图片为base64；<br>2）使用<code>mdhtml -h</code>查看帮助：</p><pre class="line-numbers language-bash"><code class="language-bash">$ md2html -hUsage: md2html can convert markdown<span class="token punctuation">(</span>.md<span class="token punctuation">)</span> <span class="token function">file</span> to single html file<span class="token punctuation">(</span>offline<span class="token punctuation">)</span>, <span class="token function">which</span> is a modified tocmd.npm<span class="token punctuation">(</span>a <span class="token function">npm</span> wrapper of i5ting_ztree_toc<span class="token punctuation">)</span> toolOptions:  -V, --version                output the version number  -i, --intputfile <span class="token operator">&lt;</span>filename<span class="token operator">></span>  .md <span class="token function">file</span> location, default is README.md  <span class="token punctuation">(</span>default:                               <span class="token string">"README.md"</span><span class="token punctuation">)</span>  -o, --output-path <span class="token operator">&lt;</span>path<span class="token operator">></span>     output .html PATH, default PATH is the same with .md <span class="token function">file</span>  -d, --debug                  print detailed information<span class="token punctuation">(</span>for debug<span class="token punctuation">)</span>  -n, --no-convert-img         don't convert local images to base64 when generating .html                               <span class="token function">file</span>  -u, --uml-path <span class="token punctuation">[</span>path<span class="token punctuation">]</span>        plantuml.jar PATH to generate offilne UML images<span class="token punctuation">(</span>require                               java<span class="token operator">!</span><span class="token punctuation">)</span>, default PATH is ./pantuml.jar  -h, --help                   display <span class="token function">help</span> <span class="token keyword">for</span> <span class="token function">command</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>3）推荐Linux系统，或者WSL也行。Windows下用cmd也太难受了<br>4）目前pkg打包后的windows版本用本地<code>plantuml.jar</code>会图片出现乱码，且无法正确生成html，请使用默认选项（解析为网址）</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-12-27-markdown-zhuan-chi-xian-html-dan-wen-jian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《死月妖花～四月八日～》游玩思考记录1</title>
      <link>https://chengpengzhao.com/2021-12-18-si-yue-yao-hua-you-wan-si-kao-ji-lu-1/</link>
      <guid>https://chengpengzhao.com/2021-12-18-si-yue-yao-hua-you-wan-si-kao-ji-lu-1/</guid>
      <pubDate>Sat, 18 Dec 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;上班之后基本上很少有时间
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>上班之后基本上很少有时间玩这类游戏，之前也偶尔有粗略找过一些，没发现什么好的作品。直到上周翻<a href="https://bangumi.tv/game/browser?sort=rank" target="_blank" rel="noopener">番組</a>的榜单时，一个叫做《<ruby>死月妖花<rp> (</rp><rt>しがつようか</rt><rp>) </rp></ruby>～四月八日～》的同人作品映入我的眼中。给我的第一印象是：看起来像是我喜欢的类型，并且这个<strong>双关名</strong>有点意思（四月八日和死月妖花都读作しがつようか），再加上这游戏本身<strong>免费</strong>！迫不及待的我立马下载安装玩了起来，不知不觉难得的一个周末就过去了…  </p><blockquote><p>2021-12-18 10:37<br>游戏版本号： Ver1.16.19.17<br>目前进度： <ruby>呪殺編<rp> (</rp><rt>じゅさつへん</rt><rp>) </rp></ruby> 35/46<br>目前个人评分：★★★★☆  （有点寒蝉的感觉）</p></blockquote><h1 id="呪殺編">2&emsp;呪殺編</h1><h2 id="人物关系">2.1&emsp;人物关系</h2><img src="http://www.plantuml.com/plantuml/svg/ROxBIiD058RtynIpr4M49hkXv5s2Q97UGWDkH6Y8bcfw4xmjBDgI657JQ4jBIT4-J3AJz2sSIJ8b1M4s_pV_-SvHbSEoKZg2k6zjZD4PG87-7kXMeAyHL3HOEoq057UUUAZITEMHwOg3Ot0ErCn1xh_8y8OwoACTNtzd5H6WwBU7MvyyKmTvkGYNpOtHuool2VrRF5jGJJIVa_4RjjjPIwA38mEx0vurEeMmvOH-9t4LYx7xYhrdMMO5jG80KqD1aE5Uw9laxfAugtt0pavXFFuW4nElksJOn9DPyWK5TX144Di_k6-cY34fpyH_M26H9dO4e_OYzATvMgMKUDsKYXaLTxfRkjELCYffR9ipe0yaleDjzS69lHPGAxn9MQFUE2dNQty0"><h2 id="剧情线">2.2&emsp;剧情线</h2><p>(右击图片在新标签页中打开)</p><blockquote><p>常識はずれの要素が入った時点で、 あらゆることを常識はずれで考えなくてはならない</p></blockquote><img src="http://www.plantuml.com/plantuml/svg/bLdBSYB95Ttp5KJqPden4p4FUo65lV5ilFF6tZWSYdPOqwDmXpmnqzuNGa3n1Wa44Y24cfSUl8I4e03nBwFAhAnL_uBFhIog2gHMZnKTQedAohoFSyyzD-NxvVsRdz_xDXu3bu-1-cDWOPpiirA9brMZ4DB7ANxUtFJj_kVzjl_ddRS_llSPrzVwMD77btZ0qabUFDErCEkdUM74b6CZVwoFuzZYLwNC5a4Z4sPgIP_LVrKglZ_WooUYFNuprQT9NZZZ8vK7UXzd2P4eytW8wrb4qxMuRtltNtuwqhV1Ear-LkEv1nQ8V857-dJ4qbaZLtsDrtYn8M83rXqPvVZtV_j-nKo_hYLqJJEL31zdOA5eVM1gN-u0y_HnmumakTAohKgKyLHqccoWy5Y3rrJNXbz-UhUp5X-A0RQtOl1nfhBam3o-CC_tZMhZuwpwSHRTb6_vtxnzixFh-_Blh_xvxh_R__ZoZxvNVzdP_VS6gr_mQ98rXiOyguzZeX_arSRc-aE6xm-AaUgpihPSujcA39IsxVpW_u8rvgmHGGZDYu4-No0wCW16R286L_guyzh__iVjNIoCQ6QX_ThdzsyWkwubfR4PYD1huoZ5hPvXgP2krKLVtSHQAxBljdz0OFrVV-MNaJTFCiRfWQ6ETEs6fQRw-0YxiD0GQxvPhk6PQoI8PLBwMDFdUPPMMUcKLnfOy-rNVYUeyga-Jihr22elfl2FfGkyFQ0ipmViC8dGuiNlll8xTlDq1Xw9o2Mx7x3UHDTIJevvgitlubZlfDBlfr0vXwxcBS5Y5RCuTNPU1Wn6CJLi1WvvzDhC3oboLkmeJ395xeRTqQRrs1ikln_rOWodJ2qOqx28xV6JWb7NU6Sgb10lzbnWMO6qtd1tJ5yAxKeU8-5fFVTu97roGNDWbuKtWqxkAoSy4P1OadvOlhWlfwRo45F90JBY_8fNb4rduQfNz8MuYrf2p9jYtXN15E_du93e1r2mI035D3BYqRW-KL4NpbjkyZfreetx6sEQnc56gOTgGB5YCG5YgbWl9ioJ1mg_vHR5idJBocrhVLQqmYixMyVHK-d6yRvOP8rEb3s4u0dh3ft04kiiYh1MRYZkgs9ywGPYSUNmWUM8UyHAwEdhrKzltcs__NbxUtS3pxxUabQz6BK5IF8IYtTstnBRPfAiKw023gPH74OdHumQJPgLSukf55qh6KTPiz1rTh18Q_cBuvFCb_EvJOy72HOQyLwIrGTmyTD-u0E9hNU_R0Cg8GGXw6pz75giHd7A5XvVLw38emy8ehH2OXkboVCXSRVFZuwNcCGg6x25BX-7UEF4SvRD8OCz5hjmA4sVdI0q12whBDoaBQjFcbbf6iTpGnlZ3T4BiOC32gOMVoanFAg8_g5SlGHTpxQXboG7nWhmnG-JXdQtXWl9OA8P4DqB-vLuWvUZIBRHIehRgZ6_vFlL5w6q8HryoYhaBDeUMa68oeK7ssQW8n7z8j3wgkXLKCaitTEd3RH9SANJDIMoq3MuSacncPpfYyBp45kDWKNLaoeOJDOgzWMZKpcLezXKxDLORC5Yq12NPla6kNeALVG1OWehDjY73_FKp_7wFC_tq_eakaOPJqCbJG818GmKdYKAY99kFxoOPP1Ju8eN7upzaKK0q1nXQ17pkCwh6KfMBy2JRh6ny34iSwf9Ha4MBMa12s6IzbZWvFzZYs-tIDhCWfjFgj2jH7rMP25LNrHuhFviFIv9cw9maF2qL8Lb4bIXthfOFV-RBK2ILmzV39TwQrGK4PnBFh8PVTemAwUaBmPJV6WgLQOrIME5XnB3p-C8qi6cw6fSdwL1r6mH0ldhaxYuxta31m514d8fHA4VrmhIbXsbC-JFGc9DdvqPqsElJlDk2BLXxdtWtJiIdiCy4MsPX2e_YY2H-g86AMf6qko-pUgjpxEa_VFE3pxlJpPtEemKJehkmXOabewprGFoH3dh5gNiak7Va2sRPRBo6OyUiimr3uQWI9-J5J8EZh-cKXAr0ehTjz9Z7Usx4hRv8PlSIa848_jM4kMMKhUEu7fvo2hm9B1WDATifh1goin7A8XMtK3j6xd1sXujDD-2NJmFjbH-NiCu1_5Km-s-kJjGc5UBBU7-j4tSt-kJ0LL19kiQRRM1b_3j0gOq9XXOUn4R1OTWSzQDyb2VDIQVP-rAXeoTDqqb2FFP05gbyzB168B0G4Y_DPY4POLX8veeGYg9X8dA8bcMKL5_B7t5CYsfVvSggiMRUqOgWf8mAsTs3D2ToXhhdkXpY6KLYc1DNeAYn2A2PMB_nBlR9mds_0ekyODJIp2L_lodl_BOESzdFwDlp4W2i71SuZSrG8SDybG54OtL8RLEl0I2bMWOPF6Y262HeeILbORNH4a0D2CKgPk1zwswjoJ1M3DANLdnBDDawZ5u3T0Z3WHCMt4aK9zUi_xWxLk4shKKsLgrb3QsXMOIz8IDqOqnP202i0ZWS-PEz2bMFu8tv5CwAPG4KoVOKFR4zTQvE82n68Ey8S6yuk8qraPIl2zATwNX-kB2CaOHT_Uac4DetXrx3BUwC3IHd8jHOyQmQWppihW_8pTc1L97WHCYuiJKF3xtTbBCGvYBqK_Dvj6B3UA9E20LP3TcrIXNgJbQlrfDFUgr2GT0zyaaSYM51VpidloPn14ig0GyDHvIB7pjF2KWzcvfDcnCCBWXHcvCYpsv-Dbfmu6b70mj54cJgjQyQVVtbOkGq12JcnU4nlIGzMt5Ifrn2Hqvr3aR_bO1yDsMFQRdga3-vgV4-3ES9nxQu6TPr6QWeCyzJTokNV2WTowKNMMT43UasfIzXsABLRqgLSqWpsE7F9ddjrEWSmq1zYtBIiNJBBxQPoY449gJcaWU6Bc-MGgBpDnzop98TXd2zk9K7zyuuxijDAnozqBCvSzvU9tSF9GeWG33AU7H-DgXigr0COY71sUmH3N9yS9fLFOWEiy3QrobUoJG33-BU3Fy_2nc-vy_XYG1oALGv9KQRHqQchdknzc9wyb3_37GXTjUJBBGDHi72M2zYaiJo_7ULZ7bjb5_WCLK-PsYronRb2-74HbbcaVSMKW37qeLpYAGKU3a5ldluKSa3tb53cIXuI1I0CkvNDJQA4Ef-ucIfaTIzvDLJqRpf-m3RB9q7oGeRbz6bqobJ0HFLEaAGzxt0DRxq3r1STTVeTp6pAoDnFrG7yUfT1P5QY-J8VNomfd5YWcwYBBQ4NNUKOXeq6f1QuTI--i7pCl26gj_fgn_joMo9L6elrmqW8K6oNe8kYHL1R5XfPoQbXfvXh_0UcM5DUO4fkaXForBOWKzMyEJmYffVF99CnsHQlrl3nVeSkw5e37FYjiEZrs93AbWS08vi84n4dKj4MsZBmZLVkaAhcJUY5_BZPpRmgMpVDX6gvGCGMM4lZTkIftYynGC1ag6H7NxpbC9H8yBIrgJaxtdsl7fcVBM4IgiCNpS6_2RSpRUSsUzcocYADc4Y6OHn8HXNNtce6ibLV7IhLXaVSlkXkJmmPu-ZI4R-ZZb7RACqgripAAM0DrGEAnQ84Zr0t2BSjiAoFsbUfP3cS_X3lkCtgt4jHJNhXosIXqiBE5i7p3ka0393fsCUmF5Zgv4OiIq0jrzBV6pwNFlBP7Ekpj-tcODrRe9w3mDuP8LCSIm6Lr0UvmciDeZ09emAAeLDhI5I0HPwHRluaEcvKIl8Md3s9iiEOF8JzTIZgfPwx5U7sGZul4oHYZokHiL7qB6PH0p4JksOBR1UWkMXcZl6lC2Lq5_gZp7l9vPb_3FtbRHNXxXHUqXVwtFBoJK7Ia1xZn_6XNF1KQ1UXqqNMhgz3gUYB1PVjqFZpf1oJ_PKenYT1Y-PqwfsqNs9F2nTdahdhARShRD2t48JIcdnMBkcBDwvYeP_NvBvdBBxEGGY2qORJHEFv5mFb9PdMOu-uyj6I_May023buRpDV-0a8AljoM-VJUPtabWBo2faF1MfaK4ThYp2ZFf51v3CHOA_eOg3tk1H_t3kNTogg7f8zi7iDF_mC0"><h2 id="Reference">2.3&emsp;Reference</h2><p>根据游戏中与玩家互动的能面人的说法，reference中有很多提示，能够帮助推导故事的“裏側”，但有些是很主观的看法。<br>带一个*代表个人觉得比较重要的Ref，两个*为古书，三个*为生物兵器相关报告</p><p>1) 転居届  *<br>なつみ家搬到隔壁？？？搬家的深层原因？（也许是我想多了）</p><p>2) 桜祭ポスター<br>底下说的就是春花父亲当年的事故</p><p>3) 幼儿园毕业照<br>显示出なつみ对当时记忆模糊</p><p>4) おはようjapan  *<br>受访教授的观点：a. 樱花中含有麻黄碱（可能是谣言），是制造冰毒的重要化学成分；b. 樱花都是一样的，都是嫁接（克隆）出来的；c. 介绍染井吉野樱，无法自然繁殖，自交不亲和性，需要利用其他品种；</p><p>5) 手机介绍  *<br>Real-time Maintenance功能：定期外部通信<br>Friend GPS：近距离可被定位<br>Copyright不是なつみ父亲的公司<br>end4中春花手机中发现有一金属板，这里能找到什么线索么？</p><p>6) 电影评价网页： 似乎没有什么有用信息  </p><p>7) なつみ学生证： 似乎没有什么有用信息  </p><p>8) 春花学生证： 证实2020年5月春花家和なつみ家交换了位置</p><p>9) 絵梨奈的过去：塑造人物形象</p><p>10) 新闻现场连线：塑造事件氛围</p><p>11) 絵梨奈的笔记①  *<br>和女ケ沢市事件<strong>很不同</strong>（案发现场≠发现现场），不像是模仿犯<br>犯人为何要让尸体被发现？<br>其他推测后面基本被证实</p><p>12) 灵异现象之妖花：忽然出现的巨大樱花树（1954年）</p><p>13) 灵异现象之心灵感应：心灵感应现象的一些历史实验（大概是真实存在的研究）</p><p>14) 天才女与春花讨论  *<br>关于事件死者的死法：<code>犠牲者がすぐに死なないようになっている</code><br>推测犯人不是真想连续杀人<del>（也许是给下一个目标的警告）</del></p><p>15) 17) 絵梨奈的笔记②  ：关于なつみ梦的解析</p><p>16) 塾の案内：侧面表现絵梨奈的聪明</p><p>18) 大二郎的兴趣介绍：塑造人物形象</p><p>19) 元木日報：end1结局描述</p><p>20) 翠眼の娘　　**<br>第一封古书（先这么叫吧），时间1180年7月1日（日本平安时代后期），历史背景是平清盛刚迫使高仓天皇退位不久，拥立自己的外孙，平德子之子即位，是为安德天皇。这是平氏一族的全盛时期。日记的意思是平清盛在派人找一个皇居没落家系的女儿，当时10岁左右，特征是单眼翠绿。这里提到的<code>帝の三男坊</code>应该是源赖朝了。</p><p>21) 桃子的简历：塑造人物形象</p><p>22) 同学会通知：解释天才女母亲没出场</p><p>23) 汽车失窃情报：应该就是用来运尸体的</p><p>24) 元木町犯罪情况：反映当地治安较好</p><p>25) 电话对方： 塑造桃子的人物形象</p><p>26) 絵梨奈的笔记③<br>重点区别这次事件和之前的不同，对犯人来说这次是紧急情况？</p><p>27) 女ケ沢报纸： 第一女ケ沢市事件</p><p>28) 女ケ沢报纸： 第二女ケ沢市事件</p><p>29) 诊断录音记录： end3的补充，天才女放弃后产生自杀倾向</p><p>30) 供养  *<br>2001年，第一人称带能面的人是谁？<br>开头的玻璃瓶和火焰是什么？制作药物？还是单纯什么仪式？<br>开头的对话Google一下发现竟然是葡萄牙语（最后的オブリガーダObrigada意思即ありがとう）<br>美冬说的優しい友達就是茜吧，还在迷茫，迷茫什么？</p><p>31) 高贵者的首领  **<br>1190年4月1日，讲的是这个人未得到平清盛信任，在其迁都后被降职到元木这个地方，远离政治纷争，但仍崇拜平清盛。文中的<code>法皇</code>即后白河天皇（信赖平清盛）</p><p>32) 42) 周四休诊日  *<br>2018年10月，春花因某种原因去医院，且瞒着なつみ</p><p>33) なつみ的调查：侧面反映警官的认真负责</p><p>34) 春花父亲的死亡诊断书  *<br>有某种药物中毒的迹象？</p><p>35) 目击者采访  *<br>2017年，第三女ケ沢市事件<br>可以看出春花一家刚从老家回来，其母亲不应该是犯人</p><p>36) 食人集团  **<br>1180年11月，当时的背景应该是：平治之乱中被打败的源义平（源赖朝的哥哥）逃到飛騨这个地方苟延残喘<br>由于缺少食物出现了吃同伴尸体的情况</p><p>37) 姐姐在哪里：反映絵梨奈小时候很依赖姐姐</p><p>38) 大二郎的警官证：塑造人物形象</p><p>39) 不審者情報：完善故事情节</p><p>40) 宅急送通话记录 *<br>春花把地址写错了(306写成603)，有什么特殊含义么？<br>该住宅只有5层所以配送员发现了错误</p><p>41) 元木站时刻表</p><p>43) 絵梨奈的笔记④  *<br>为何春花要隐瞒父亲的死？<br>为何なつみ父母也要隐瞒这点？<br>为何なつみ一家不搬走？</p><p>44) 絵梨奈的笔记⑤  *<br>这部分是关于end4的一些推理<br>春花母亲自杀一是为了隐瞒证据（自身）、二是为了向某人传达某种信息<br>春花母亲“追杀”二人但中途发觉目的已无法达成，所以决定不再下杀手？</p><p>45) 春花手机的调查报告  *<br>被做的一些手脚，但仍不太清楚一些部件是干嘛的</p><p>46) 鬼神の群れ  **<br>1560年8月，背景是日本战国时代，朝比奈元長是确实存在的人物，原为今川义元的部下，1560年桶狭间之战中今川义元亲自率军攻入尾张国境内（在今爱知县名古屋市一带），遭织田信长领军奇袭本阵阵亡，在此文中被描述为织田家一方有着鬼神之力。今川家还让同盟武田信玄注意织田家的动向。</p><p>47)　なつみ父亲的死亡诊断书 *<br>医师名这里有个细节，原来的医师是现医师的父亲，曾说要调查春花父亲药物中毒，现在是引退了还是被失踪了？</p><p>48) 担心①: 2018年10月，茜也不知道春花为何去医院</p><p>49) 学生时代的信： 塑造警官的人物形象</p><p>50)　抓捕行动： ホシ代表美冬，マルタイ代表春花</p><p>51) 紧急联络： 塑造桃子的人物形象</p><p>52) なつみ父亲的信  *<br>含有非常关键的信息<br>果然春花和なつみ两人在一起时不会被杀？</p><p>53) “妖魔的声音”  **<br>1561年4月，还是朝比奈元長的记录，说是桶狭间之战后军队中有些人（杀了“鬼神般”的织田军的人）能听到妖魔的声音，从而预知并回避危险</p><p>54) 教えて新村さん： 描述春花对地理的兴趣</p><p>55) I’m a bird: …这是来搞笑的吧</p><p>56) 犯行現場  *<br>end6这条线中警察发现作案现场，确定为失窃的货车，为何犯人将其遗弃至此？</p><p>57) お気を付けて: 警官和茜的通话，茜坚持回家（想当诱饵）</p><p>58) 担心②: 2018年10月，なつみ担心春花最近的状况询问美冬</p><p>59) 桜寿司: 看上去很贵的店…</p><p>60) 不能靠近: 天才女和姐姐的对话</p><p>61) 火事場の馬鹿力  *<br>火事場の馬鹿力（ことわざ）：火事のときに、自分にはあると思えない大きな力を出して重い物を持ち出したりすることから。切迫した状況に置かれると、普段は想像できないような力を無意識に出すことのたとえ。<br>天才女关于兴奋剂（ドーピング）的调查，提到了麻黄碱（エフェドリン）</p><p>62) 63) 排球教练的评价、体育大会: 天才女和なつみ过去的故事</p><p>64) 絵梨奈的笔记⑥  *<br>讲述天才女协助警方保护なつみ</p><p>65) 音信不通 *<br>突然刮起的大风是人为么？<br>信号不通的原因和大风有关么？</p><p>66) 灵异现象之终焉喇叭声 *<br>圣经新约中相应章节科普<br>学者对于宗教的认识</p><p>67) 春花父亲的死亡诊断书2 *<br>类似麻黄碱的药物<br>调查被上层中止（案件上升到国家层面）<br>药物和微生物混合</p><p>68) 儀之助の日記　**<br>点数不够解锁</p><p>69) 強き女　**<br>点数不够解锁</p><hr><ol><li><p>生物兵器企划书 ***<br>1935年3月，军队得知荒田集落中存在某种药，能让人拥有“鬼神之力”，派人前去调查</p></li><li><p>荒田集落调查结果 ***<br>1953年4月，荒田集落积极提供帮助（文献资料、样品等），并告知药已没再使用，原料之一为当地樱花<br>对于近乎异样的热情协助，军队怀疑他们有别的目的</p></li><li><p>药物的使用方法相关对比 ***<br>点数不足暂时无法解锁…</p></li></ol><h2 id="事典">2.4&emsp;事典</h2><p>这一部分基本上都是客观的描述，如人物和事件的概述、故事背景地点的介绍，帮助玩家了解故事发生的这座城镇</p><h1 id="目前的推测">3&emsp;目前的推测</h1><p>在<code>end2_感染</code>中，最后有段文字是无法暂停下来回放的，描述了天才女在“得到”なつみ的能力后听到的东西：  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202112181530648.PNG" alt="1"><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202112181530982.PNG" alt="2"></p><ul><li>春花父亲作为荒田集落的一员，有着某种秘密（药物，鬼神之力）</li><li>なつみ在春花父亲的事故中近距离目睹了他的死亡，获得了“危险预知能力”（参考Ref53，妖魔的声音）</li><li>太多事件的目的不明确，要首先从なつみ父亲的那封信开始理解才行</li><li>犯下女ケ沢市事件的犯人另有其人，<del>他利用了美冬，使其杀害了なつみ父亲</del>(美冬确实被利用了，也确实最可能杀害了なつみ父亲，但幕后黑手应该不会轻易亲自动手杀人)</li><li><del>春花和なつみ在一起时，因为某种考量犯人不会动杀手</del>(也许只是巧合，也许只是不想当春花面杀なつみ)</li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-12-18-si-yue-yao-hua-you-wan-si-kao-ji-lu-1/#disqus_thread</comments>
    </item>
    
    <item>
      <title>关于并行程序调试</title>
      <link>https://chengpengzhao.com/2021-11-28-guan-yu-bing-xing-cheng-xu-diao-shi/</link>
      <guid>https://chengpengzhao.com/2021-11-28-guan-yu-bing-xing-cheng-xu-diao-shi/</guid>
      <pubDate>Sun, 28 Nov 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://indico.i
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p><a href="https://indico.ihep.ac.cn/event/3040/contribution/2/material/slides/0.pdf" target="_blank" rel="noopener">大规模并行程序调试及优化</a></p></blockquote><h1 id="前言">1&emsp;前言</h1><p>从串行到并行，需要多考虑很多东西（并行体系结构、通信、负载均衡），有些事也变得更困难了，最典型的一个例子就是程序的调试<br>想象如下场景，我刚用MPI写了个程序，运行发现有问题，可能出现的错误种类有：1) 只有某个进程出现了错误； 2) 并行规模变大了才出现的错误； 3) 用Intel的MPI跑有问题但用MPICH又不出错； 4) 单进程没问题但多进程就不行了，可能与通信有关…<br>以上错误都是串行程序所没有的。那么，要如何定位并解决问题呢，天才的话可能扫一遍代码就能发现错在哪里，而身为庸才的我，当然是要进行并行程序的调试了~  </p><p>于是开始用各种手段对付MPI：</p><h1 id="有效且常见的方法">2&emsp;有效且常见的方法</h1><p>最容易想到的方法当然就是<strong>变量输出</strong>了，判断哪个变量可能有错误，<code>cout</code>、<code>printf</code>、<code>write</code>使用一通，总能发现一些问题吧<br>缺点当然也很明显：  </p><ol><li>低效率，需要改变源代码并重新编译，大型项目可能很费时</li><li>存在许多不同类型的变量需要打印时，需要花费精力在输出格式控制上</li><li>调试目的不是为了找出错误、而是为了看懂别人的代码细节时，往往存在大量变量去理解，一个个打印出来实在太慢</li></ol><h1 id="gdb工具">3&emsp;gdb工具</h1><p>说到linux下的调试怎么都离不开gdb，毕竟开源、功能也还齐全，对于并行程序来说，也不是不能用，只需要运行以下命令：</p><pre class="line-numbers language-sh"><code class="language-sh">mpirun -np N xterm -e cgdb ./a.out<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>（我一般用cgdb作为GUI）这里xterm系统默认的字体主题实在没法看，可以自行做一些<a href="https://www.markjour.com/article/20190620-my-xterm.html" target="_blank" rel="noopener">调整</a>如下：</p><pre><code>! 使用方式! vim ~/.Xresources! xrdb -merge ~/.Xresources! xrdb -query! xtermxterm*faceName:             DejaVu Sans Mono:style=Book:antialias=truexterm*faceNameDoublesize: WenQuanYi Micro Hei!xterm*faceNameDoublesize:   Noto Sans CJK SCxterm*faceSize: 11xterm*renderFont:           truexterm*cjk_width:            truexterm*geometry:             80x25xterm*dynamicColors:        truexterm*utf8:                 2xterm*eightBitInput:        truexterm*saveLines:            2048xterm*scrollKey:            truexterm*scrollTtyOutput:      falsexterm*scrollBar:            truexterm*rightScrollBar:       truexterm*jumpScroll:           truexterm*multiScroll:          truexterm*toolBar:              falsexterm*Scrollbar*thickness:  10xterm*Scrollbar*background: blackxterm*Scrollbar*foreground: gray90xterm*termName:             xterm-256colorxterm*decTerminalID:        vt340! https://askubuntu.com/questions/237942/how-does-copy-paste-work-with-xtermxterm*selectToClipboard:    true! https://futurile.net/2016/06/15/xterm-256color-themes-molokai-terminal-theme/xterm*background:   rgb:1a/1a/1axterm*foreground:   rgb:d6/d6/d6xterm*cursorColor:  rgb:d6/d6/d6xterm*color0:       rgb:00/00/00xterm*color1:       rgb:9e/18/28xterm*color2:       rgb:00/88/00xterm*color3:       rgb:96/8a/38xterm*color4:       rgb:41/41/71xterm*color5:       rgb:96/3c/59xterm*color6:       rgb:41/81/79xterm*color7:       rgb:be/be/bexterm*color8:       rgb:66/66/66xterm*color9:       rgb:cf/61/71xterm*color10:      rgb:7c/bc/8cxterm*color11:      rgb:ff/f7/96xterm*color12:      rgb:41/86/bexterm*color13:      rgb:cf/9e/bexterm*color14:      rgb:71/be/bexterm*color15:      rgb:ff/ff/ff</code></pre><p>我之前用gdb对并行程序调试了一段时间，感觉还是很不方便，最多只能到3个进程，不然窗口切换来切换去，进程间的同步就已经够折腾了，再加上还要一个命令一个命令的输出各进程的变量，实在是很低效。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202111282302752.png" alt="感受一下gdb调试mpi的恐惧吧"></p><h1 id="专业并行调试软件">4&emsp;专业并行调试软件</h1><p>之前也搜过有没有开源的并行调试工具，结果没有找到一个满足我的使用需求的。听说<code>eclipse</code>也能调试MPI程序，但我没有具体操作过，毕竟不用这个IDE  </p><p>现在国际上的商用并行程序调试软件基本上就2家：</p><ol><li><a href="https://totalview.io/" target="_blank" rel="noopener">TotalView</a>  </li><li><a href="https://developer.arm.com/tools-and-software/server-and-hpc/debug-and-profile/arm-forge/arm-ddt" target="_blank" rel="noopener">Arm DDT</a>  </li></ol><p>文章开头的PPT对<code>Arm DDT</code>有简要的介绍，中科院软件研究所好像买过，不过自从贸易战之后不知道现在还接不接受国内客户。<code>TotalView</code>我去官网逛了几圈竟然发现购买价格它都不直接告诉你，还需要发邮件咨询；请求试用版后邮件还要我告知各种信息，我嫌麻烦就懒得回了。<code>Arm DDT</code>倒是很有效率，请求试用后5分钟之内<code>license</code>就已经发到邮箱了，经过几天的使用，唯一的感受就是：<br>太好用了吧！！！<br>直接在软件里打开可执行文件、设定进程数，就可以开始debug了，不同进程的数据点一下就能切换，在右边窗口直观地显示出来；设置的断点可以保存成文件下次直接导入…</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store3/img/202111282306101.png" alt="强大的Arm DDT"></p><p>正式版还是挺贵的，光DDT这一个模块就220美元一年，但我竟然还有点忍不住想买，因为用过之后再和用gdb的调试方法一对比，差距还是太悬殊了…  </p><p>可惜国内也没有发现在做这种并行调试工具的，毕竟这么多超算中心，还是很缺这种工具的吧。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-11-28-guan-yu-bing-xing-cheng-xu-diao-shi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>稀疏线性方程组直接求解库学习</title>
      <link>https://chengpengzhao.com/2021-10-31-xi-shu-ju-zhen-zhi-jie-qiu-jie-ku-xue-xi/</link>
      <guid>https://chengpengzhao.com/2021-10-31-xi-shu-ju-zhen-zhi-jie-qiu-jie-ku-xue-xi/</guid>
      <pubDate>Sun, 31 Oct 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;最近正在入门代数求解相关
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>最近正在入门代数求解相关领域，简单来说就是研究$Ax=b$如何求解，只不过这里的$A$是一个<strong>大型</strong>（上亿阶）<strong>稀疏</strong>（大量0元素）<strong>矩阵</strong>。虽然工程实际中用得最多的是迭代法，这里还是先介绍直接求解的相关库  </p><p>首先，推荐<code>Xiaoye(Sherry) Li</code>(在美国<code>Lawrence Berkeley National Laboratory</code>担任<code>Senior Scientist &amp; Group Lead</code>)在<a href="https://archive.siam.org/students/g2s3/2013/lecturers/XSLi/Lecture-Notes/sherry.pdf" target="_blank" rel="noopener">Summer School的PPT</a>，过一遍就大概知道了稀疏矩阵直接求解有哪些要注意的问题。接着就是找文献继续深入了~</p><h1 id="汇总表">2&emsp;汇总表</h1><p>前人做的比较全面的对比：<a href="https://portal.nersc.gov/project/sparse/superlu/SparseDirectSurvey.pdf" target="_blank" rel="noopener">Direct Solvers for Sparse Matrices</a>  </p><p>这里补充了一些自己找的，稍微整理了一下：</p><table><thead><tr><th>名称</th><th>名称含义</th><th>机构</th><th>求解方法</th><th>对应矩阵类型</th><th>网址</th><th>程序语言</th><th>个人评分</th></tr></thead><tbody><tr><td>HSL</td><td>Harwell Subroutine Library</td><td>STFC’s Rutherford Appleton Laboratory, UK</td><td>Multifrontal</td><td>Sym、Sym-pat、Unsym</td><td><a href="http://www.hsl.rl.ac.uk/" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍</td></tr><tr><td>BCSLIB-EXT</td><td>Unknown</td><td>Boeing Computer Services, USA</td><td>Multifrontal</td><td>Sym、Unsym</td><td><a href="http://www.aanalytics.com/products.htm" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍</td></tr><tr><td>PSPASES</td><td>Parallel SPArse Symmetric dirEct Solver</td><td>IBM Corporation and  University of Minnesota，USA</td><td>Multifrontal</td><td>SPD</td><td><a href="https://www.lrz.de/services/software/mathematik/pspases/" target="_blank" rel="noopener">link</a></td><td>C/FORTRAN</td><td>👍</td></tr><tr><td>WSMP</td><td>Watson Sparse Matrix Package</td><td>IBM Corporation，USA</td><td>Multifrontal</td><td>SPD、Unsym</td><td><a href="https://researcher.watson.ibm.com/researcher/view_group_subpage.php?id=7624" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍👍👍👍👍</td></tr><tr><td>TAUCS</td><td>Unknown</td><td>Tel-Aviv University，Israel</td><td>Left/Multifr.</td><td>Sym、Unsym</td><td><a href="https://www.tau.ac.il/~stoledo/taucs/" target="_blank" rel="noopener">link</a></td><td>C</td><td>👍👍</td></tr><tr><td>PARDISO</td><td>Parallel Sparse Direct Solver</td><td>USI, Lugano，Switzerland</td><td>Left-Right looking</td><td>Sym-pat</td><td><a href="https://www.pardiso-project.org/" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍👍👍</td></tr><tr><td>PaStiX</td><td>Parallel Sparse direct Solver</td><td>BORDEAUX I UNIVERSITY，France</td><td>Left-Right looking</td><td>Sym-pat</td><td><a href="http://pastix.gforge.inria.fr/files/README-txt.html" target="_blank" rel="noopener">link</a></td><td>C</td><td>👍👍👍👍</td></tr><tr><td>UMFPACK</td><td>Unknown（Now as a part of <a href="https://people.engr.tamu.edu/davis/suitesparse.html" target="_blank" rel="noopener">SuiteSparse</a></td><td>Texas A&amp;M university，USA</td><td>Multifrontal</td><td>Unsym</td><td><a href="https://people.sc.fsu.edu/~jburkardt/f77_src/umfpack/umfpack.html" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍👍</td></tr><tr><td>SuperLU</td><td>Supernodal Low Upper Decomposition</td><td>Lawrence Berkeley National Laboratory，USA</td><td>Left/Right-looking</td><td>Unsym</td><td><a href="https://portal.nersc.gov/project/sparse/superlu/" target="_blank" rel="noopener">link</a></td><td>C</td><td>👍👍👍👍👍</td></tr><tr><td>MUMPS</td><td>Multifrontal Massively Parallel Sparse Direct Solver</td><td>University of Bordeaux，France</td><td>Multifrontal</td><td>SPD、Sym-pat、Unsym</td><td><a href="http://mumps.enseeiht.fr/" target="_blank" rel="noopener">link</a></td><td>FORTRAN</td><td>👍👍👍👍</td></tr><tr><td>STRUMPACK</td><td>STRUctured Matrix PACKage</td><td>Lawrence Berkeley National Laboratory，USA</td><td>Multifrontal</td><td>Sym-pat、Unsym</td><td><a href="https://portal.nersc.gov/project/sparse/strumpack/index.html" target="_blank" rel="noopener">link</a></td><td>C++</td><td>👍👍👍👍👍</td></tr></tbody></table><h1 id="一些说明">3&emsp;一些说明</h1><ul><li><p>个人评分根据求解库对个人的<strong>参考价值</strong>来判断，判断标准有：是否开源、性能、可扩展性、代码可读性、相关文档丰富度、程序版本号等</p></li><li><p>PARDISO（上次更新：2020.11），网页做的很好，<code>Intel MKL</code>库中的直接求解模块就用到了它；文献量不多，值得关注</p></li><li><p>PaStiX（上次更新：2021.07），文献较新，测试最大问题规模达10M？，文献值得跟进</p></li><li><p>MUMPS（上次更新：2021.08），算例最大问题规模10M，推荐（因为是用FORTRAN写的、个人评分减一）</p></li><li><p>STRUMPACK（上次更新：几天前），很有潜力，采用的是面向对象的C++编程，用到了大量C++11特性，为稀疏及稠密矩阵提供了一系列线性代数操作以及方程求解方法，不仅仅是直接求解库</p></li><li><p>PSPASES貌似是WSMP的前身，同一个团队开发的，前几年PSPASES把官网的下载渠道给关了，可能是为了保护自己的一些成果吧</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-10-31-xi-shu-ju-zhen-zhi-jie-qiu-jie-ku-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>可转债入门笔记</title>
      <link>https://chengpengzhao.com/2021-10-15-ke-zhuan-zhai-ru-men-bi-ji/</link>
      <guid>https://chengpengzhao.com/2021-10-15-ke-zhuan-zhai-ru-men-bi-ji/</guid>
      <pubDate>Fri, 15 Oct 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;相关网站： &lt;a href=&quot;https://ww
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p>相关网站： <a href="https://www.jisilu.cn/data/cbnew/#cb" target="_blank" rel="noopener">集思录</a></p></blockquote><h1 id="入门篇">1&emsp;入门篇</h1><ul><li><p>可转债，全称为“可转换公司债券”，是可以转换成公司股票的债券，债权+期权。其持有人可以选择持有债券到期，获取公司还本付息；也可以选择在约定的时间内转换成股票，享受股利分配或资本增值。</p></li><li><p>法律规定、合同约定、资质认定外加发行公司的利益决定，可转债到期保本，是肯定的，换言之是100%的（中国市场还未出现过违约）</p></li><li><p>有了下调转股价这个武器，可转债变得更另类，也更有吸引力。不怕股票跌，反正转股价可以如影随形地跟着跌；而且，跌得越狠，反弹的可能性越大，上涨幅度也往往更大</p></li><li><p>国内可转债都设有到期回售条款，到期回售的价格通常在面值的105%-110%，如果再加上利息，按面值购买的可转债持有到期的债券收益率会高达2.5%-3%</p></li><li><p>可转债的面值是每张100元，以10张为一个最低交易单位，称为“一手”，一手等于1000元</p></li></ul><h1 id="升级篇">2&emsp;升级篇</h1><ul><li><p>可转债<strong>四大要素</strong>：转股价、强制赎回条款、下调转股价条款、回售条款  </p></li><li><p>转股价：对投资者、越低越好；<strong>转股期</strong>是转股价的附属品，它规定了可转债发行上市以后，必须过了一定的时间才能进行转换股票的行为  </p></li><li><p>当转股价低于股票市场价的时候，等于可以低价买入股票，所以可转债的价格就会上涨并维持在面值100元以上；当转股价高于股票市场价时，等于高价买入股票，不值得，所以可转债价格下跌，向面值靠拢甚至跌破100元</p></li><li><p>如果能让借款人变成公司的股东，就等于把借到手里的钱变成了公司自己的钱，不仅不用还了，还可以直接投入在企业经营上（甚至其他任意用途），这在资本严重紧缺的中国市场，是何等的美事啊</p></li><li><p>下调转股价条款：股价长期低于一阈值，<strong>公司有权</strong>在一定的条件下下调转股价；  </p></li><li><p>强制赎回条款：股价在一定时期高于一阈值，<strong>公司有权</strong>按照略高于可转债面值的一个约定赎回价格（一般是103元）赎回全部或部分未转股的可转债。（这种情况还不赶紧转股并卖出立赚30%以上）  </p></li><li><p>回售条款：如果公司股票收盘价在N个交易日低于当期转股价格的一个阈值（一般要低于向下修正转股价）时，<strong>可转债持有人有权</strong>将其持有的可转债全部或部分按面值的103%或面值100元+当期计息年度利息回售给本公司（当公司迟迟不下调转股价时）  </p></li><li><p>回售保护是有期限的，有的可转债甚至没有回售保护条款</p></li><li><p>只要做到股价在转股价的130%以上保持一段时间，上市公司就完全可以在法律允许的前提下，合理合法地把借来的钱装到自己的钱包里，世上还有比这更美好的事情吗</p></li><li><p>可转债的底部确定，而且100%保底；顶部上不封顶，貌似不确定，但是30%~40%的上涨却是大概率事件，等于保险收益区间是确定的；甚至时间也确定，五六年之内（实际99%都是不到期即可提前获利）。</p></li><li><p>凡是在网上遇到说可转债不好、投资可转债亏钱的人，仔细一问，几乎100%都不是在面值附近买入并坚持在收盘价以上卖出的</p></li></ul><h1 id="策略篇">3&emsp;策略篇</h1><ul><li><p>傻瓜策略：<br>100元以下，越跌越买；100元~130元之间，不动如山；130元以上，安全就继续持有，赚多了就变现，收放自如</p></li><li><p>简单策略：<br>1) 在面值附近买入可转债，越低越好；<br>2) 不断记录可转债价格的最高点，持有可转债不动；<br>3) 一旦可转债价格跌破当前最高点的90%，或从最高价跌掉10元，立即卖出；<br>4) 重复步骤1的过程，不到面值附近绝对不买。  </p></li><li><p>三个安全价格：<strong>到期安全价</strong>（到期还本付息，持有人所能拿到的价值等于所有中间利息之和+到期赎回价；如果算上利息扣税还要扣掉20%）、<strong>回售安全价</strong>  、<strong>面值</strong>（100元）  </p><p>假设某转债6年的利息分别为0.5%、0.5%、1%、1%、2%、2%，到期赎回价是106元（含最后一年利息2%）。那么其理论上持有到期的价值为： 106元+(0.5+0.5+1+1+2)×80%=110元。</p></li><li><p>挑选原则（参考）：<br>1) 120（或110）元以上的排除<br>2) 无回售的大转债尽量不买（下调转股价动力不足、波动性小、股性弱）<br>3) 去掉存量太少的转债（低于5000万）<br>4) 未到转股期的，除非特别看好，否则不买<br>5) 溢价率高的离谱、转股价高的离谱，不买<br>6) 在剩余的到期时间内，无论是3年还是5年的，期间正股上涨30%概率不大的，都可以排除</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-10-15-ke-zhuan-zhai-ru-men-bi-ji/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Vim升级NeoVim，再到SpaceVim</title>
      <link>https://chengpengzhao.com/2021-10-06-vim-sheng-ji-neovim/</link>
      <guid>https://chengpengzhao.com/2021-10-06-vim-sheng-ji-neovim/</guid>
      <pubDate>Wed, 06 Oct 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;Vim的麻烦之处&quot;&gt;1&amp;emsp;Vim的麻烦之处&lt;/h1&gt;&lt;p&gt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="Vim的麻烦之处">1&emsp;Vim的麻烦之处</h1><p>Vim用了很长一段时间，搭配各种插件、学习VimScript等也逐步<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener">积累</a>了一些配置。但随着使用场景重心转移到C/C++项目上，感觉YCM(YouCompleteMe)、ctags(vim-gutentags)等插件有点力不从心，有时跳转不到正确的位置、有时没法提供想要的补全…<br>网上冲浪搜寻解决方案时看到Martins的<a href="https://martins3.github.io/My-Linux-Config/nvim.html" target="_blank" rel="noopener">这篇文章</a>，顿时觉得豁然开朗，于是又花了一阵子折腾，结果还算比较满意。</p><h1 id="NeoVim、SpaceVim">2&emsp;NeoVim、SpaceVim</h1><p>让我们一步一步进行升级，首先对于最基本的Vim，配置文件常用位置为<code>~/.vimrc</code>，当然也可以通过如下方式自定义路径：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 个人vimrc文件配置路径</span><span class="token function">export</span> VIMINIT<span class="token operator">=</span><span class="token string">'source <span class="token variable">$MYVIMRC</span>'</span><span class="token function">export</span> MYVIMRC<span class="token operator">=</span><span class="token variable">$mypath</span>/.vimrc<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><a href="https://neovim.io/charter/" target="_blank" rel="noopener">Neovim</a>是在Vim的基础上派生出的编辑器，兼容大部分Vim配置，据说在性能等方面和Vim有差异（我是没啥感觉），配置文件通常在<code>~/.config/nvim/init.vim</code>。如果使用SpaceVim的话，这个文件会有一行内容，我们不需要修改它：</p><pre class="line-numbers language-bash"><code class="language-bash">execute <span class="token string">'source'</span> fnamemodify<span class="token punctuation">(</span>expand<span class="token punctuation">(</span><span class="token string">'&lt;sfile>'</span><span class="token punctuation">)</span>, <span class="token string">':h'</span><span class="token punctuation">)</span>.<span class="token string">'/main.vim'</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>如果称Vim和NeoVim为编辑器，那么<a href="https://spacevim.org/cn/quick-start-guide/" target="_blank" rel="noopener">SpaceVim</a>则更像是<strong>IDE</strong>，也就是说它默认就捆绑了各种插件、快捷键配置、显示外观等，不用自己再去一个个配置。就像官网描述的：</p><blockquote><p>SpaceVim 是一个社区驱动的模块化的 Vim IDE，以模块的方式组织管理插件以及相关配置， 为不同的语言开发量身定制了相关的开发模块，该模块提供代码自动补全， 语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱即用的 Vim IDE。  </p></blockquote><p>SpaceVim的配置在<code>~/.SpaceVim.d</code>文件夹中，比较方便建一个git仓库，我的相关文件树如下：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token keyword">.</span>├── autoload│   └── myspacevim.vim├── init.toml├── LICENSE├── plugin│   ├── coc.vim│   └── defx.vim├── Readme.md└── UltiSnips    ├── beancount.snippets    ├── cmake.snippets    ├── cpp.snippets    ├── c.snippets    ├── fortran.snippets    ├── html.snippets    ├── javascript.snippets    └── markdown.snippets<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="ccls、LSP">3&emsp;ccls、LSP</h1><p>LSP(Language Server Protocol)即语言服务器协议，微软提出的一个<a href="https://microsoft.github.io/language-server-protocol/" target="_blank" rel="noopener">主意</a>，意在让 editor 和 IDE 以后能够使用一个通用的组件来做代码分析。具体可以参考<a href="https://microsoft.github.io/language-server-protocol/overviews/lsp/overview/" target="_blank" rel="noopener">这里</a>，用过Vscode的应该都知道吧，我前一阵子才听说这个词语，真是孤陋寡闻了- -<br>ccls则是<code>C/C++/ObjC language server</code>，针对这几个语言提供了相应的自动补全、 查找定义、交叉引用、调用树/成员树/继承树、自动格式化、符号重命名等功能，在NeoVim中的实现为<a href="https://github.com/Maxattax97/coc-ccls" target="_blank" rel="noopener">coc-ccls</a>。</p><h1 id="相关配置">4&emsp;相关配置</h1><p>快速了解了相关概念后，重要的是如何根据自己的使用偏好调整配置。首先，需要详细学习<a href="https://spacevim.org/cn/quick-start-guide/" target="_blank" rel="noopener">SpaceVim使用文档</a>，搞清楚和<code>&lt;Space&gt;</code>有关的快捷键以及常用插件的使用。如果是一个老Vim用户的话，还需要重点关注如何把之前的好用配置移到SpaceVim中，通常是编辑<code>~/.SpaceVim.d/autoload/myspacevim.vim</code>文件，利用<code>myspacevim#before()</code>和<code>myspacevim#after()</code>函数直接将原配置复制粘贴过来（需要注意两个函数的区别）。  </p><p>用NAS之后习惯把所有东西只放在局域网中，git仓库也是用自建的Gogs服务而不是GitHub托管，下面还是贴一下自己现在的配置吧（凑凑字数）。</p><h2 id="myspacevim-vim">4.1&emsp;myspacevim.vim</h2><p>大部分是我原来的Vim配置，小部分是沿用了Martins3大佬的配置，这里特别强调下<code>airline</code>部分是我自己调整后的SpaceVim状态栏设置，删去了原版不少自认为多余之处，自己用起来还挺舒服的。</p><pre class="line-numbers language-vim"><code class="language-vim">func<span class="token operator">!</span> myspacevim#<span class="token function">before</span><span class="token punctuation">(</span><span class="token punctuation">)</span> abort    <span class="token comment" spellcheck="true">"有时候在windows下编写的python脚本在linux下不能运行，因为^M的原因,设置格式为unix能够自动清除多余的^M</span>    <span class="token keyword">set</span> <span class="token builtin">fileformat</span><span class="token operator">=</span>unix    <span class="token keyword">set</span> <span class="token builtin">showmatch</span>       <span class="token comment" spellcheck="true">" 高亮显示匹配的括号</span>    <span class="token comment" spellcheck="true">"设置标记，三个{定义为标记，可用za折叠展开</span>    <span class="token keyword">set</span> <span class="token builtin">foldenable</span>    <span class="token keyword">set</span> <span class="token builtin">foldmethod</span><span class="token operator">=</span>marker    <span class="token builtin">autocmd</span> FileType <span class="token keyword">c</span><span class="token punctuation">,</span>cpp<span class="token punctuation">,</span><span class="token keyword">python</span> <span class="token keyword">set</span> <span class="token builtin">foldmethod</span><span class="token operator">=</span>indent <span class="token builtin">nofoldenable</span>    <span class="token comment" spellcheck="true">"解决乱码问题</span>    <span class="token keyword">set</span> <span class="token builtin">encoding</span><span class="token operator">=</span>utf<span class="token operator">-</span><span class="token number">8</span>    <span class="token keyword">set</span> <span class="token builtin">termencoding</span><span class="token operator">=</span>utf<span class="token operator">-</span><span class="token number">8</span>    <span class="token keyword">set</span> <span class="token builtin">fileencodings</span><span class="token operator">=</span>utf<span class="token operator">-</span><span class="token number">8</span><span class="token punctuation">,</span>gbk<span class="token punctuation">,</span>latin1    <span class="token keyword">set</span> <span class="token builtin">langmenu</span><span class="token operator">=</span>zh_CN<span class="token operator">.</span>UTF<span class="token operator">-</span><span class="token number">8</span>    <span class="token keyword">set</span> <span class="token builtin">helplang</span><span class="token operator">=</span><span class="token keyword">cn</span>    <span class="token keyword">set</span> <span class="token builtin">ttyfast</span>        <span class="token comment" spellcheck="true">"a fast terminal connection.</span>    <span class="token comment" spellcheck="true">"设置数字为十进制，防止&lt;C-a>&lt;C-x>修改时出现不希望的结果</span>    <span class="token keyword">set</span> <span class="token builtin">nrformats</span><span class="token operator">=</span>    <span class="token comment" spellcheck="true">"依文件类型设置自动缩进</span>    <span class="token keyword">filetype</span> plugin <span class="token keyword">on</span>    <span class="token keyword">filetype</span> indent <span class="token keyword">on</span>    <span class="token comment" spellcheck="true">"显示当前的行号(普通模式为相对)：</span>    <span class="token keyword">set</span> <span class="token builtin">ruler</span>    <span class="token keyword">set</span> <span class="token keyword">number</span>    <span class="token keyword">set</span> relativenumber    augroup relative_numbser        <span class="token builtin">autocmd</span><span class="token operator">!</span>        <span class="token builtin">autocmd</span> InsertEnter <span class="token operator">*</span> <span class="token punctuation">:</span><span class="token keyword">set</span> norelativenumber        <span class="token builtin">autocmd</span> InsertLeave <span class="token operator">*</span> <span class="token punctuation">:</span><span class="token keyword">set</span> relativenumber    augroup END    <span class="token comment" spellcheck="true">"显示行尾多余空格与tab符号</span>    <span class="token keyword">set</span> <span class="token builtin">listchars</span><span class="token operator">=</span><span class="token keyword">tab</span><span class="token punctuation">:</span>»<span class="token operator">-</span><span class="token punctuation">,</span>trail<span class="token punctuation">:</span>■    <span class="token keyword">set</span> <span class="token keyword">list</span>    <span class="token comment" spellcheck="true">"将制表符扩展为空格</span>    <span class="token keyword">set</span> <span class="token builtin">expandtab</span>    <span class="token comment" spellcheck="true">"设置编辑时制表符占用空格数</span>    <span class="token keyword">set</span> <span class="token builtin">tabstop</span><span class="token operator">=</span><span class="token number">4</span>    <span class="token comment" spellcheck="true">"设置格式化时制表符占用空格数</span>    <span class="token keyword">set</span> <span class="token builtin">shiftwidth</span><span class="token operator">=</span><span class="token number">4</span>    <span class="token comment" spellcheck="true">" 关闭softtabstop 永远不要将空格和tab混合输入</span>    <span class="token keyword">set</span> <span class="token builtin">softtabstop</span><span class="token operator">=</span><span class="token number">0</span>    <span class="token comment" spellcheck="true">"开启自动缩进</span>    <span class="token keyword">set</span> <span class="token builtin">autoindent</span>   <span class="token comment" spellcheck="true">" Indent at the same level of the previous line</span>    <span class="token comment" spellcheck="true">"开启智能对齐</span>    <span class="token keyword">set</span> <span class="token builtin">smartindent</span>    <span class="token comment" spellcheck="true">"设置使用 C/C++ 语言的自动缩进方式</span>    <span class="token keyword">set</span> <span class="token builtin">cindent</span>    <span class="token comment" spellcheck="true">"设置命令行的高度</span>    <span class="token keyword">set</span> <span class="token builtin">cmdheight</span><span class="token operator">=</span><span class="token number">1</span>    <span class="token comment" spellcheck="true">"设置大小写不敏感/当前为大写字母时调整为敏感/自动改动字母大小写</span>    <span class="token keyword">set</span> <span class="token builtin">ignorecase</span>    <span class="token keyword">set</span> <span class="token builtin">smartcase</span>    <span class="token keyword">set</span> <span class="token builtin">infercase</span>    <span class="token keyword">set</span> <span class="token builtin">smarttab</span>        <span class="token comment" spellcheck="true">" insert tabs on the start of a line according to context</span>    <span class="token keyword">set</span> <span class="token builtin">magic</span>    <span class="token comment" spellcheck="true">"单词自动补全功能,写博客时用,自定义词典可参考网上教程</span>    <span class="token string">""</span><span class="token keyword">set</span> <span class="token builtin">dictionary</span><span class="token operator">+=</span><span class="token operator">/</span>usr<span class="token operator">/</span>share<span class="token operator">/</span><span class="token builtin">dict</span><span class="token operator">/</span>american<span class="token operator">-</span>english    <span class="token keyword">set</span> <span class="token builtin">dictionary</span><span class="token operator">+=</span><span class="token operator">/</span>usr<span class="token operator">/</span>share<span class="token operator">/</span><span class="token builtin">dict</span><span class="token operator">/</span>engspchk<span class="token operator">-</span><span class="token builtin">dict</span>    <span class="token keyword">set</span> <span class="token builtin">completeopt</span><span class="token operator">+=</span>noinsert    <span class="token comment" spellcheck="true">".Md文件也能被识别为markdown</span>    <span class="token builtin">autocmd</span> BufNewFile<span class="token punctuation">,</span>BufRead <span class="token operator">*</span><span class="token operator">.</span>Md <span class="token keyword">set</span> <span class="token keyword">filetype</span><span class="token operator">=</span>markdown    <span class="token comment" spellcheck="true">"ejs识别为html</span>    <span class="token builtin">autocmd</span> BufNewFile<span class="token punctuation">,</span>BufRead <span class="token operator">*</span><span class="token operator">.</span>ejs <span class="token keyword">set</span> <span class="token keyword">filetype</span><span class="token operator">=</span>html    <span class="token comment" spellcheck="true">"Scons相关脚本识别为python</span>    <span class="token builtin">autocmd</span> BufNewFile<span class="token punctuation">,</span>BufRead SConstruct <span class="token keyword">set</span> <span class="token keyword">filetype</span><span class="token operator">=</span><span class="token keyword">python</span>    <span class="token builtin">autocmd</span> BufNewFile<span class="token punctuation">,</span>BufRead SConscript <span class="token keyword">set</span> <span class="token keyword">filetype</span><span class="token operator">=</span><span class="token keyword">python</span>    <span class="token comment" spellcheck="true">" 焦点消失的时候自动保存</span>    au FocusLost <span class="token operator">*</span> <span class="token punctuation">:</span><span class="token keyword">wa</span>    au FocusGained<span class="token punctuation">,</span>BufEnter <span class="token operator">*</span> <span class="token punctuation">:</span><span class="token keyword">checktime</span>    <span class="token comment" spellcheck="true">" 当文件被其他编辑器修改时，自动加载</span>    <span class="token keyword">set</span> <span class="token builtin">autowrite</span>    <span class="token keyword">set</span> <span class="token builtin">autoread</span>    <span class="token comment" spellcheck="true">" 重新映射 leader 键</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>mapleader <span class="token operator">=</span> <span class="token string">','</span>    <span class="token comment" spellcheck="true">" 让 leaderf 可以搜索 git 的 submodule，否则 submodule 的文件会被自动忽略</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>Lf_RecurseSubmodules <span class="token operator">=</span> <span class="token number">1</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>table_mode_corner<span class="token operator">=</span><span class="token string">'|'</span>    <span class="token comment" spellcheck="true">" 调节 window 大小</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>winresizer_start_key <span class="token operator">=</span> <span class="token string">'&lt;space>wa'</span>    <span class="token comment" spellcheck="true">" If you cancel and quit window resize mode by `q` (keycode 113)</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>winresizer_keycode_cancel <span class="token operator">=</span> <span class="token number">113</span>    <span class="token comment" spellcheck="true">" 让file tree 显示文件图标，需要 terminal 安装 nerd font</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>spacevim_enable_vimfiler_filetypeicon <span class="token operator">=</span> <span class="token number">1</span>    <span class="token comment" spellcheck="true">" 让 filetree 显示 git 的状态</span>    <span class="token comment" spellcheck="true">" let g:spacevim_enable_vimfiler_gitstatus = 1</span>    <span class="token comment" spellcheck="true">" 默认 markdown preview 在切换到其他的 buffer 或者 vim</span>    <span class="token comment" spellcheck="true">" 失去焦点的时候会自动关闭 preview</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>mkdp_auto_close <span class="token operator">=</span> <span class="token number">0</span>    <span class="token comment" spellcheck="true">" 书签选中之后自动关闭 quickfix window</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>bookmark_auto_close <span class="token operator">=</span> <span class="token number">1</span>    <span class="token comment" spellcheck="true">" vim-lsp-cxx-highlight 和这个选项存在冲突</span>    <span class="token comment" spellcheck="true">" let g:rainbow_active = 1</span>    <span class="token comment" spellcheck="true">" 让光标自动进入到popup window 中间</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>git_messenger_always_into_popup <span class="token operator">=</span> v<span class="token punctuation">:</span>true    <span class="token comment" spellcheck="true">" 设置映射规则，和 spacevim 保持一致</span>    <span class="token keyword">call</span> SpaceVim#custom#<span class="token function">SPC</span><span class="token punctuation">(</span><span class="token string">'nnoremap'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'g'</span><span class="token punctuation">,</span> <span class="token string">'m'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'GitMessenger'</span><span class="token punctuation">,</span> <span class="token string">'show commit message in popup window'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>    <span class="token keyword">call</span> SpaceVim#custom#<span class="token function">SPC</span><span class="token punctuation">(</span><span class="token string">'nnoremap'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'g'</span><span class="token punctuation">,</span> <span class="token string">'l'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'FloatermNew lazygit'</span><span class="token punctuation">,</span> <span class="token string">'open lazygit in floaterm'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">" 和 sourcetrail 配合使用</span>    <span class="token comment" spellcheck="true">"call SpaceVim#custom#SPC(</span><span class="token string">'nnoremap'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'SourcetrailStartServer'</span><span class="token punctuation">,</span> <span class="token string">'start sourcetrail server'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">"call SpaceVim#custom#SPC(</span><span class="token string">'nnoremap'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token string">'b'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'SourcetrailActivateToken'</span><span class="token punctuation">,</span> <span class="token string">'sync sourcetrail with neovim'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">"call SpaceVim#custom#SPC(</span><span class="token string">'nnoremap'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token string">'f'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token string">'SourcetrailRefresh'</span><span class="token punctuation">,</span> <span class="token string">'sourcetrail server'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">" 设置默认的pdf阅览工具</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>vimtex_view_method <span class="token operator">=</span> <span class="token string">'zathura'</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>vimtex_syntax_conceal_default <span class="token operator">=</span> <span class="token number">0</span>    <span class="token comment" spellcheck="true">" 关闭所有隐藏设置</span>        <span class="token keyword">let</span> g<span class="token punctuation">:</span>tex_conceal <span class="token operator">=</span> <span class="token string">""</span>    <span class="token comment" spellcheck="true">" 实现一键运行各种文件，适合非交互式的，少量的代码，比如 leetcode {{{</span>    func<span class="token operator">!</span> <span class="token function">QuickRun</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        exec <span class="token string">"w"</span>        <span class="token keyword">let</span> ext <span class="token operator">=</span> <span class="token function">expand</span><span class="token punctuation">(</span><span class="token string">"%:e"</span><span class="token punctuation">)</span>        <span class="token keyword">let</span> <span class="token keyword">file</span> <span class="token operator">=</span> <span class="token function">expand</span><span class="token punctuation">(</span><span class="token string">"%"</span><span class="token punctuation">)</span>        <span class="token keyword">if</span> ext <span class="token operator">==#</span> <span class="token string">"sh"</span>            exec <span class="token string">"!bash %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"cpp"</span>            exec <span class="token string">"!clang++ % -Wall -g -std=c++17 -o %&lt;.out &amp;&amp; ./%&lt;.out"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"c"</span>            exec <span class="token string">"!clang % -Wall -g -std=c11 -o %&lt;.out &amp;&amp; ./%&lt;.out"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"java"</span>            <span class="token keyword">let</span> classPath <span class="token operator">=</span> <span class="token function">expand</span><span class="token punctuation">(</span><span class="token string">'%:h'</span><span class="token punctuation">)</span>            <span class="token keyword">let</span> className <span class="token operator">=</span> <span class="token function">expand</span><span class="token punctuation">(</span><span class="token string">'%:p:t:r'</span><span class="token punctuation">)</span>            <span class="token comment" spellcheck="true">" echo classPath</span>            <span class="token comment" spellcheck="true">" echo className</span>            exec <span class="token string">"!javac %"</span>            exec <span class="token string">"!java -classpath "</span> <span class="token operator">.</span> classPath <span class="token operator">.</span> <span class="token string">" "</span> <span class="token operator">.</span> className        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"go"</span>            exec <span class="token string">"!go run %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"js"</span>            exec <span class="token string">"!node %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"bin"</span>            exec <span class="token string">"!readelf -h %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"py"</span>            exec <span class="token string">"!python3 %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"vim"</span>            exec <span class="token string">"so %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"html"</span>            exec <span class="token string">"!microsoft-edge %"</span>        <span class="token keyword">elseif</span> ext <span class="token operator">==#</span> <span class="token string">"rs"</span>            <span class="token keyword">call</span> <span class="token function">CargoRun</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token keyword">else</span>            echo <span class="token string">"Check file type !"</span>        <span class="token keyword">endif</span>        echo <span class="token string">'done'</span>    <span class="token keyword">endf</span>    <span class="token string">"===============================插件配置======================================"</span>    <span class="token comment" spellcheck="true">" floaterm - 浮动终端窗口</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>floaterm_keymap_prev   <span class="token operator">=</span> <span class="token string">'&lt;C-p>'</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>floaterm_keymap_new    <span class="token operator">=</span> <span class="token string">'&lt;C-n>'</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>floaterm_keymap_toggle <span class="token operator">=</span> <span class="token string">'&lt;F5>'</span>    <span class="token comment" spellcheck="true">"gutentags配置，由于依靠compile_command.json总是跳转到安装目录，不方便编辑源文件，还是用ctags吧</span>    <span class="token comment" spellcheck="true">" gutentags 搜索工程目录的标志，碰到这些文件/目录名就停止向上一级目录递归</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_modules <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'ctags'</span><span class="token punctuation">]</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_project_root <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'.root'</span><span class="token punctuation">,</span> <span class="token string">'.svn'</span><span class="token punctuation">,</span> <span class="token string">'.git'</span><span class="token punctuation">,</span> <span class="token string">'.hg'</span><span class="token punctuation">,</span> <span class="token string">'.project'</span><span class="token punctuation">]</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_ctags_exclude<span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">'.ccls-cache'</span><span class="token punctuation">,</span><span class="token string">'build'</span><span class="token punctuation">,</span><span class="token string">'install'</span><span class="token punctuation">]</span>    <span class="token comment" spellcheck="true">" 所生成的数据文件的名称</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_ctags_tagfile <span class="token operator">=</span> <span class="token string">'.tags'</span>    <span class="token comment" spellcheck="true">" 将自动生成的 tags 文件全部放入 ~/.cache/tags 目录中，避免污染工程目录</span>    <span class="token keyword">let</span> s<span class="token punctuation">:</span>vim_tags <span class="token operator">=</span> <span class="token function">expand</span><span class="token punctuation">(</span><span class="token string">'~/.cache/tags'</span><span class="token punctuation">)</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_cache_dir <span class="token operator">=</span> s<span class="token punctuation">:</span>vim_tags    <span class="token string">" 检测 ~/.cache/tags 不存在就新建 "</span>    <span class="token keyword">if</span> <span class="token operator">!</span><span class="token function">isdirectory</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span>vim_tags<span class="token punctuation">)</span>       <span class="token keyword">silent</span><span class="token operator">!</span> <span class="token keyword">call</span> <span class="token function">mkdir</span><span class="token punctuation">(</span>s<span class="token punctuation">:</span>vim_tags<span class="token punctuation">,</span> <span class="token string">'p'</span><span class="token punctuation">)</span>    <span class="token keyword">endif</span>    <span class="token comment" spellcheck="true">" 配置 ctags 的参数</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_ctags_extra_args <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">'--fields=+niazS'</span><span class="token punctuation">,</span> <span class="token string">'--extra=+q'</span><span class="token punctuation">]</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_ctags_extra_args <span class="token operator">+=</span> <span class="token punctuation">[</span><span class="token string">'--c++-kinds=+px'</span><span class="token punctuation">]</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>gutentags_ctags_extra_args <span class="token operator">+=</span> <span class="token punctuation">[</span><span class="token string">'--c-kinds=+px'</span><span class="token punctuation">]</span>    <span class="token comment" spellcheck="true">" airline代替statusline，部分配置在bootsrap_after</span>    <span class="token keyword">call</span> SpaceVim#layers#<span class="token function">disable</span><span class="token punctuation">(</span><span class="token string">'core#statusline'</span><span class="token punctuation">)</span>    <span class="token keyword">call</span> SpaceVim#layers#<span class="token function">disable</span><span class="token punctuation">(</span><span class="token string">'core#tabline'</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">" 关闭最右边栏</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>airline#extensions#whitespace#enabled <span class="token operator">=</span> <span class="token number">0</span>    <span class="token comment" spellcheck="true">" 不显示git分支</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>airline#extensions#branch#enabled <span class="token operator">=</span> <span class="token number">0</span>    <span class="token comment" spellcheck="true">" 去掉section B和X</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>airline_section_b <span class="token operator">=</span> <span class="token string">''</span>    <span class="token comment" spellcheck="true">"let g:airline_section_x = </span><span class="token string">''</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>airline_section_x <span class="token operator">=</span> <span class="token string">'%-0.25{getcwd()}'</span><span class="token keyword">endf</span>func<span class="token operator">!</span> myspacevim#<span class="token function">after</span><span class="token punctuation">(</span><span class="token punctuation">)</span> abort    <span class="token comment" spellcheck="true">"一般关闭paste模式，该模式下有的map会出问题</span>    <span class="token keyword">set</span> <span class="token builtin">nopaste</span>    <span class="token comment" spellcheck="true">"不自动分行(但可以分行显示）</span>    <span class="token keyword">set</span> <span class="token builtin">wrap</span>    <span class="token keyword">set</span> <span class="token builtin">textwidth</span><span class="token operator">=</span><span class="token number">0</span>    <span class="token comment" spellcheck="true">" Search mappings: These will make it so that going to the next one in a</span>    <span class="token comment" spellcheck="true">" search will center on the line it's found in.</span>    nnoremap <span class="token keyword">n</span> nzzzv    nnoremap <span class="token keyword">N</span> Nzzzv    <span class="token string">"Ctrl+Space单词补全"</span>    <span class="token comment" spellcheck="true">"WSL系统中此快捷键不管用，故换成下面一条</span>    <span class="token comment" spellcheck="true">"inoremap &lt;C-@> &lt;C-x>&lt;C-k></span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">f</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">x</span><span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">k</span><span class="token operator">></span>    <span class="token comment" spellcheck="true">"保存文件</span>    nnoremap <span class="token operator">&lt;</span>Leader<span class="token operator">></span><span class="token keyword">w</span>  <span class="token punctuation">:</span><span class="token keyword">w</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token comment" spellcheck="true">"选择全文</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>M<span class="token operator">-</span>a<span class="token operator">></span> <span class="token operator">&lt;</span>Esc<span class="token operator">></span>ggVG<span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token comment" spellcheck="true">"退出</span>    nnoremap  qw    <span class="token punctuation">:</span><span class="token keyword">wq</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    nnoremap  qq    <span class="token punctuation">:</span><span class="token keyword">q</span><span class="token operator">!</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token comment" spellcheck="true">"插入模式下移动光标</span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">k</span><span class="token operator">></span> <span class="token operator">&lt;</span>Up<span class="token operator">></span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">h</span><span class="token operator">></span> <span class="token operator">&lt;</span>Left<span class="token operator">></span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">l</span><span class="token operator">></span> <span class="token operator">&lt;</span>Right<span class="token operator">></span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">j</span><span class="token operator">></span> <span class="token operator">&lt;</span>Down<span class="token operator">></span>    <span class="token comment" spellcheck="true">"向后删除 *为向前删除，shell通用</span>    inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">d</span><span class="token operator">></span> <span class="token operator">&lt;</span>Delete<span class="token operator">></span>    <span class="token comment" spellcheck="true">"超级用户权限编辑，出现权限不够无法保存时命令模式输入sw即可</span>    cnoremap <span class="token builtin">sw</span> <span class="token keyword">w</span> <span class="token operator">!</span>sudo tee <span class="token operator">></span><span class="token operator">/</span>dev<span class="token operator">/</span>null <span class="token operator">%</span>    <span class="token comment" spellcheck="true">"可视模式下用*和#查找选中文本</span>    <span class="token keyword">xnoremap</span> <span class="token operator">*</span> <span class="token punctuation">:</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">u</span><span class="token operator">></span><span class="token keyword">call</span> <span class="token operator">&lt;</span>SID<span class="token operator">></span><span class="token function">VsetSearch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">&lt;</span>CR<span class="token operator">></span><span class="token operator">/</span><span class="token operator">&lt;</span>C<span class="token operator">-</span>R<span class="token operator">>=</span>@<span class="token operator">/</span><span class="token operator">&lt;</span>CR<span class="token operator">></span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token keyword">xnoremap</span> # <span class="token punctuation">:</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">u</span><span class="token operator">></span><span class="token keyword">call</span> <span class="token operator">&lt;</span>SID<span class="token operator">></span><span class="token function">VsetSearch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">&lt;</span>CR<span class="token operator">>?</span><span class="token operator">&lt;</span>C<span class="token operator">-</span>R<span class="token operator">>=</span>@<span class="token operator">/</span><span class="token operator">&lt;</span>CR<span class="token operator">></span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token keyword">function</span><span class="token operator">!</span> s<span class="token punctuation">:</span><span class="token function">VsetSearch</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token keyword">let</span> temp<span class="token operator">=</span>@s        norm<span class="token operator">!</span> gv<span class="token comment" spellcheck="true">"sy</span>        <span class="token keyword">let</span> @<span class="token operator">/</span> <span class="token operator">=</span> <span class="token string">'\V'</span> <span class="token operator">.</span> <span class="token function">substitute</span><span class="token punctuation">(</span><span class="token function">escape</span><span class="token punctuation">(</span>@s<span class="token punctuation">,</span> <span class="token string">'/\'</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'\n'</span><span class="token punctuation">,</span> <span class="token string">'\\n'</span><span class="token punctuation">,</span><span class="token string">'g'</span><span class="token punctuation">)</span>        <span class="token keyword">let</span> @s<span class="token operator">=</span> temp    <span class="token keyword">endfunction</span>    <span class="token string">""</span> Switching windows    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">j</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">j</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">k</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">k</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">l</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">l</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">h</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">h</span>    <span class="token string">""</span> Move <span class="token keyword">visual</span> block    vnoremap K <span class="token punctuation">:</span><span class="token keyword">m</span> '<span class="token operator">&lt;</span><span class="token operator">-</span><span class="token number">2</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>gv<span class="token operator">=</span>gv    vnoremap J <span class="token punctuation">:</span><span class="token keyword">m</span> '<span class="token operator">></span><span class="token operator">+</span><span class="token number">1</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>gv<span class="token operator">=</span>gv    <span class="token comment" spellcheck="true">"关闭高亮直到下一次查找</span>    cnoremap <span class="token builtin">hl</span>  <span class="token keyword">nohlsearch</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token comment" spellcheck="true">" &lt;F3> 打开文件树</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>vista_sidebar_position <span class="token operator">=</span> <span class="token string">"vertical topleft"</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>vista_default_executive <span class="token operator">=</span> <span class="token string">'coc'</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>vista_finder_alternative_executives <span class="token operator">=</span> <span class="token string">'ctags'</span>    nnoremap  <span class="token operator">&lt;</span>F2<span class="token operator">></span>  <span class="token punctuation">:</span>Vista<span class="token operator">!</span><span class="token operator">!</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    nnoremap  <span class="token operator">&lt;</span>F4<span class="token operator">></span>  <span class="token punctuation">:</span><span class="token keyword">call</span> <span class="token function">QuickRun</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token comment" spellcheck="true">" &lt;F5> floaterm toggle</span>    <span class="token comment" spellcheck="true">" &lt;F7> 打开历史记录</span>    tnoremap  <span class="token operator">&lt;</span>Esc<span class="token operator">></span>  <span class="token operator">&lt;</span>C<span class="token operator">-</span>\<span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">n</span><span class="token operator">></span>    <span class="token comment" spellcheck="true">" 窗口间切换</span>    <span class="token comment" spellcheck="true">"map &lt;Tab> :wincmd w&lt;CR></span>    <span class="token comment" spellcheck="true">" coc-smartf配置，press &lt;esc> to cancel.</span>    nmap <span class="token keyword">f</span> <span class="token operator">&lt;</span>Plug<span class="token operator">></span><span class="token punctuation">(</span>coc<span class="token operator">-</span>smartf<span class="token operator">-</span>forward<span class="token punctuation">)</span>    nmap F <span class="token operator">&lt;</span>Plug<span class="token operator">></span><span class="token punctuation">(</span>coc<span class="token operator">-</span>smartf<span class="token operator">-</span>backward<span class="token punctuation">)</span>    nmap <span class="token punctuation">;</span> <span class="token operator">&lt;</span>Plug<span class="token operator">></span><span class="token punctuation">(</span>coc<span class="token operator">-</span>smartf<span class="token operator">-</span>repeat<span class="token punctuation">)</span>    nmap <span class="token punctuation">,</span> <span class="token operator">&lt;</span>Plug<span class="token operator">></span><span class="token punctuation">(</span>coc<span class="token operator">-</span>smartf<span class="token operator">-</span>repeat<span class="token operator">-</span>opposite<span class="token punctuation">)</span>    augroup Smartf      <span class="token builtin">autocmd</span> User SmartfEnter <span class="token punctuation">:</span><span class="token builtin">hi</span> Conceal ctermfg<span class="token operator">=</span><span class="token number">220</span> guifg<span class="token operator">=</span>pink      <span class="token builtin">autocmd</span> User SmartfLeave <span class="token punctuation">:</span><span class="token builtin">hi</span> Conceal ctermfg<span class="token operator">=</span><span class="token number">239</span> guifg<span class="token operator">=</span>#<span class="token number">504945</span>    augroup end    <span class="token comment" spellcheck="true">"目录栏设置相对行号</span>    <span class="token builtin">autocmd</span> FileType defx <span class="token keyword">setlocal</span> relativenumber    <span class="token comment" spellcheck="true">"同时显示git信息和line number</span>    <span class="token keyword">set</span> signcolumn<span class="token operator">=</span>yes    <span class="token string">"===============================插件配置======================================"</span>    <span class="token comment" spellcheck="true">" vim-beanCount</span>    <span class="token comment" spellcheck="true">"path to your root beancount file</span>    <span class="token keyword">let</span> <span class="token keyword">b</span><span class="token punctuation">:</span>beancount_root<span class="token operator">=</span> <span class="token string">'~/Desktop/repositories/beanCount_zcp/zcp.bean'</span>    <span class="token comment" spellcheck="true">" default or chunks</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>beancount_account_completion<span class="token operator">=</span> <span class="token string">'default'</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>beancount_separator_col<span class="token operator">=</span> <span class="token number">10</span>    <span class="token comment" spellcheck="true">" If non-zero, accounts higher down the hierarchy will be listed first as completions.</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>beancount_detailed_first <span class="token operator">=</span> <span class="token number">1</span>    <span class="token builtin">autocmd</span> Filetype beancount inoremap <span class="token operator">.</span> <span class="token operator">.</span><span class="token operator">&lt;</span>C<span class="token operator">-</span>\<span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span>O<span class="token operator">></span><span class="token punctuation">:</span>AlignCommodity<span class="token operator">&lt;</span>CR<span class="token operator">></span>    <span class="token builtin">autocmd</span> Filetype beancount inoremap <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">o</span><span class="token operator">></span> <span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">x</span><span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span>O<span class="token operator">></span>    <span class="token comment" spellcheck="true">" vim-airline</span>    <span class="token comment" spellcheck="true">" 去掉LN显示</span>    <span class="token keyword">let</span> g<span class="token punctuation">:</span>airline_symbols<span class="token operator">.</span>linenr<span class="token operator">=</span> <span class="token string">''</span>    <span class="token comment" spellcheck="true">" 加入Window编号</span>    <span class="token keyword">function</span><span class="token operator">!</span> <span class="token function">WindowNumber</span><span class="token punctuation">(</span><span class="token operator">.</span><span class="token operator">.</span><span class="token operator">.</span><span class="token punctuation">)</span>        <span class="token keyword">let</span> builder <span class="token operator">=</span> a<span class="token punctuation">:</span><span class="token number">1</span>        <span class="token keyword">let</span> context <span class="token operator">=</span> a<span class="token punctuation">:</span><span class="token number">2</span>        <span class="token keyword">call</span> builder<span class="token operator">.</span><span class="token function">add_section</span><span class="token punctuation">(</span><span class="token string">'airline_b'</span><span class="token punctuation">,</span> <span class="token string">'%{tabpagewinnr(tabpagenr())}'</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> <span class="token number">0</span>    <span class="token keyword">endfunction</span>    <span class="token keyword">call</span> airline#<span class="token function">add_statusline_func</span><span class="token punctuation">(</span><span class="token string">'WindowNumber'</span><span class="token punctuation">)</span>    <span class="token keyword">call</span> airline#<span class="token function">add_inactive_statusline_func</span><span class="token punctuation">(</span><span class="token string">'WindowNumber'</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">" 用airline时`SPC num`跳转窗口失效，重新映射</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token number">1</span> <span class="token number">1</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">w</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token number">2</span> <span class="token number">2</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">w</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token number">3</span> <span class="token number">3</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">w</span>    <span class="token builtin">noremap</span> <span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token number">4</span> <span class="token number">4</span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">w</span><span class="token operator">></span><span class="token keyword">w</span><span class="token keyword">endf</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="init-toml">4.2&emsp;init.toml</h2><p>SpaceVim的默认配置文件，文法和<code>.vimrc</code>不一样。这里禁用了<code>statusline</code>改为使用<code>airline</code>，同时增加了以前Vim中经常用的插件</p><pre class="line-numbers language-toml"><code class="language-toml">#=============================================================================# Copyright (c) 2021-20xx# Author:  zcp# License: GPLv3#=============================================================================# All SpaceVim option below [option] section[options]    # 设置 SpaceVim 主题及背景，默认的主题是 gruvbox，如果你需要使用更    # 多的主题，你可以载入 colorscheme 模块    colorscheme = "gruvbox"    # colorscheme = "OceaniwcNext"    colorscheme_bg = "dark"    # colorscheme = "NeoSolarized"    # colorscheme_bg = "light"    # 背景可以取值 "dark" 和 "light"    # 启用/禁用终端真色，在目前大多数终端下都是支持真色的，当然也有    # 一小部分终端不支持真色，如果你的 SpaceVim 颜色看上去比较怪异    # 可以禁用终端真色，将下面的值设为 false    enable_guicolors = true    # statusline设置，启用时才有效    # 设置状态栏上分割符号形状，如果字体安装失败，可以将值设为 "nil" 以    # 禁用分割符号，默认为箭头 "arrow"    statusline_separator = "nil"    # statusline_separator = "bar"    # 设置顶部标签列表序号类型，有以下五种类型，分别是 0 - 4    buffer_index_type = 4    # 0: 1 ➛ ➊    # 1: 1 ➛ ➀    # 2: 1 ➛ ⓵    # 3: 1 ➛ ¹    # 4: 1 ➛    # 显示/隐藏顶部标签栏上文件类型图标，这一图标需要安装 nerd fonts，    # 如果未能成功安装这一字体，可以隐藏图标    enable_tabline_filetype_icon = true    # 是否在状态栏上显示当前模式，默认情况下，不显示 Normal/Insert 等    # 字样，只以颜色区分当前模式    enable_statusline_display_mode = false    statusline_left_sections = [       'winnr',       'filename',       'major mode',       'fileformat',       'minor mode lighters',       'version control info',    ]    statusline_right_sections = [       'cursorpos',       'percentage',       'date',       'time',    ]    #######################################################################    # MY OWN OPTIONS    filemanager = "defx"    autocomplete_method = "coc"    #snippet_engine = "ultisnips"    # 启动函数名称，该函数中可以使用Vim Script    # 启动函数文件位置：~/.SpaceVim.d/autoload/myspacevim.vim    # 函数 bootstrap_before 将在读取用户配置后执行，而函数 bootstrap_after 将在 VimEnter autocmd 之后执行。    bootstrap_before = "myspacevim#before"    bootstrap_after = "myspacevim#after"    # Vim兼容    # vimcompatible = true    # Vim兼容：Normal模式窗口快捷键的前缀改为X，s作为删除字符    windows_leader = 'X'    # Vim兼容：语言专用的前缀键，f、F、t、T改为搜索    enable_language_specific_leader = false    # Vim兼容：智能关闭窗口q改为录制宏    windows_smartclose = ''# ----------------- SpaceVim 添加的各种 layers ---------------------------------# 强化`/`搜索显示[[layers]]    name = "incsearch"# 计算器, 日历, 书签等小工具[[layers]]    name = 'tools'# 禁用 SpaceVim 的 checkers layer, 让 coc.nvim 来管理[[layers]]    name = "checkers"    enable = false# 版本控制[[layers]]    name = "VersionControl"    enable-gtm-status = false[[layers]]    name = "git"    git-plugin = "fugitive"[[layers]]    name = "fzf"[[layers]]    name = "lang#markdown"[[layers]]    name = "lang#latex"[[layers]]    name = "lang#c"    enable_clang_syntax_highlight = true[[layers]]    name = "lang#python"[[layers]]    name = "lang#toml"[[layers]]    name = "lang#vim"[[layers]]    name = "lang#sh"[[layers]]    name = "format"# ----------------- 添加的插件 -------------------------------------------------# oceanic-next 主题，采用其他的主题可以删除[[custom_plugins]]    name = "mhartington/oceanic-next"    merged = 0# coc.nvim 核心配置，不要删除# ~/.cache/vimfiles/repos/github.com/neoclide/coc.nvim[[custom_plugins]]    name = 'neoclide/coc.nvim'    merge = 0# 优化 coc 的搜索界面[[custom_plugins]]    name = 'antoinemadec/coc-fzf'    branch = 'release'[[custom_plugins]]    name = 'junegunn/fzf.vim'# 快速搜索文件和 buffer[[custom_plugins]]    name = "Yggdroot/LeaderF"    build = "./install.sh"# 快速编辑 markdown 的表格[[custom_plugins]]    name = 'dhruvasagar/vim-table-mode'# 更加美观的 tagbar[[custom_plugins]]    name = 'liuchengxu/vista.vim'# 更加方便的调节窗口的大小[[custom_plugins]]    name = 'simeji/winresizer'# 为 c/cpp 提供基于 lsp 的高亮[[custom_plugins]]    name = 'jackguo380/vim-lsp-cxx-highlight'# 从 http://cplusplus.com/ 和 http://cppreference.com/ 获取文档[[custom_plugins]]    name = 'skywind3000/vim-cppman'# 利用 git blame 显示当前行的 commit message[[custom_plugins]]    name = 'rhysd/git-messenger.vim'    lazy =  1    on_cmd = 'GitMessenger'# 以悬浮窗口的形式打开终端[[custom_plugins]]    name = 'voldikss/vim-floaterm'# 显示搜索的标号[[custom_plugins]]    name = 'google/vim-searchindex.git'# 记账[[custom_plugins]]    name = 'jonsmithers/vim-beancount'# 常用snippets[[custom_plugins]]    name = 'honza/vim-snippets'# 用于高效操作与括号、引号或html、xml标签相关的配对符号(surrounding)[[custom_plugins]]    name = 'tpope/vim-surround'[[custom_plugins]]    name = 'tpope/vim-repeat'# 文本对象[[custom_plugins]]    name = 'kana/vim-textobj-user'[[custom_plugins]]    name = 'kana/vim-textobj-indent'[[custom_plugins]]    name = 'kana/vim-textobj-syntax'[[custom_plugins]]    name = 'kana/vim-textobj-function'[[custom_plugins]]    name = 'sgur/vim-textobj-parameter'# ctags[[custom_plugins]]    name = 'ludovicchabant/vim-gutentags'<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="总结">5&emsp;总结</h1><p>文中未提相关安装方式，是因为<a href="https://martins3.github.io/My-Linux-Config/nvim.html" target="_blank" rel="noopener">这篇文章</a>已经很详细了，我就是照着它入门的；而SpaceVim、NeoVim具体的使用方式官方文档也已经说的很清楚了，下面就简单写下我自己的使用备忘录吧：  </p><ul><li><p>几个需要知道的概念：  </p><pre class="line-numbers language-markdown"><code class="language-markdown">| --------- | ------------------------------------------------- || Window    | A window can split into more windows              || Buffer    | A buffer is a file loaded into memory for editing || Tab/Frame | A tab could contain different file                || Tagbar    | Display tags of current file                      || Filetree  | File browser                                      |<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>卸载并回滚到原vim：<code>curl -sLf https://spacevim.org/install.sh | bash -s -- --uninstall</code></p></li><li><p>同时使用原有的vim和spacevim <a href="https://spacevim.org/faq/#have-a-try-with-spacevim-without-overwrite-vimrc" target="_blank" rel="noopener">FAQ:Have a try with SpaceVim without overwrite vimrc?</a></p></li><li><p>探索快捷键的最好方式是在spacevim中按下空格键等待一秒，它会弹出有用的提示框， 亲自尝试其中的快捷键才能更加准确知道它的效果。</p></li><li><p><code>[SPC]</code>：表示空格键； <code>[WIN]</code>，窗口操作，默认s（我改为了X）</p></li><li><p><code>spc f t</code>：open filetree</p></li><li><p><code>spc b b</code>：打开缓冲区管理页面,<code>spc b d</code>关闭当前缓冲区</p></li><li><p><code>g</code>     | go to       | <code>g 0</code>     | 跳到第一个tab                 | <a href="https://spacevim.org/documentation/#commands-starting-with-g" target="_blank" rel="noopener">link</a> </p></li><li><p><code>z</code>     | fold        | <code>z a</code>     | 触发代码折叠 | <a href="https://spacevim.org/documentation/#commands-starting-with-z" target="_blank" rel="noopener">link</a> </p></li><li><p>按一下空格键，等待1秒，可以看到有用的提示信息</p></li><li><p><code>F2</code>             | Open tagbar                                                     </p></li><li><p><code>spc p /</code>    | 模糊查找</p></li><li><p><code>spc f o</code>        | open file tree and locate to current directory                  </p></li><li><p><code>win g</code>(<code>spc w /</code>)            | open file and split window horizontally                         </p></li><li><p><code>win v</code>(<code>spc w -</code>)            | open file split window vertically                               </p></li><li><p>注释代码（取消注释重复即可） | <a href="https://spacevim.org/documentation/#commenting" target="_blank" rel="noopener">Link</a><br>| <code>spc c l</code>        | comment/uncomment current line<br>| <code>spc c p/P</code>      | comment/uncomment current paragraph<br>| <code>spc ; [num] j</code>  | comment <em>num</em> lines                                             </p></li><li><p>页面Tab管理器 | <a href="https://spacevim.org/documentation/#tabline" target="_blank" rel="noopener">Link</a><br>| <code>spc t t</code>        | open tab manager<br>| <code>spc w F</code>        | open a new tab, equal to <code>spc t t + n</code><br>| <code>spc w o</code>        | switch tab<br>| <code>spc s c</code>        | clear search highlight                                          </p></li><li><p>搜索 | <a href="https://spacevim.org/documentation/#searching" target="_blank" rel="noopener">Link</a><br>| <code>spc s s</code>        | Searching in current file<br>| <code>spc s d</code>        | Searching in current directory<br>| <code>spc s b</code>        | Searching in all loaded buffers<br>| <code>spc s p</code>        | Searching in current proj, equal to <code>spc /</code>                     </p></li><li><p>编程相关<br>| <code>g d</code>       | Go to function definition<br>| <code>spc b f</code>   | format code according to pep8 standard<br>| <code>spc l g d</code> | generate docstring                     </p></li><li><p>git使用<br>| <code>spc g s</code>       | 查看git状态<br>| <code>spc g A</code>   | 添加所有文件<br>| <code>spc g c</code> | commit messages，保存即提交<br>| <code>spc g p</code> | push</p></li><li><p><code>spc t w</code> | 行尾空格检查</p></li><li><p><code>&lt;Leader&gt;</code> y    | 复制文本至系统剪切板</p></li><li><p><code>spc s c</code> 或者运行命令 <code>:nohlsearch</code> 来取消搜索结果的高亮表示</p></li><li><p>书签跳转（需要启用tools）<br>| <code>m a</code> | 显示书签列表<br>| <code>m c</code> | 清除所有书签<br>| <code>m m</code> | 切换当前行标签状态<br>| <code>m n</code> | 跳至下一个书签<br>| <code>m p</code> | 跳至前一个书签<br>| <code>m i</code> | 给当前行标签添加说明</p></li><li><p>UltiSnips插件配置,<code>&lt;C-l&gt;</code>展开，<code>&lt;C-j&gt;</code>下一个，<code>&lt;C-k&gt;</code>上一个</p></li><li><p>coc.nvim学习<br>| <code>[g</code>, <code>]g</code> |  跳转到coc各个诊断处<br>| <code>gd</code> |  跳转到定义处<br>| <code>gy</code> |  跳转到type-definition<br>| <code>gi</code> |  跳转到implementation<br>| <code>gr</code> |  跳转到references-used<br>| <code>&lt;Leader&gt;rn</code> |  重命名变量<br>| <code>&lt;Leader&gt;d</code> |  打开诊断窗口<br>| <code>&lt;Leader&gt;o</code> |  查看文件outline</p></li><li><p>vim-table-mode使用：<code>&lt;Leader&gt;tm</code>开启table模式，输入<code>|</code>开始制表，文字与<code>|</code>要有空格，回车后<code>||</code>会自动插入行，第一行作为标题</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-10-06-vim-sheng-ji-neovim/#disqus_thread</comments>
    </item>
    
    <item>
      <title>NAS可以外网访问咯</title>
      <link>https://chengpengzhao.com/2021-08-29-nas-ke-yi-wai-wang-fang-wen-ge/</link>
      <guid>https://chengpengzhao.com/2021-08-29-nas-ke-yi-wai-wang-fang-wen-ge/</guid>
      <pubDate>Sun, 29 Aug 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;虽然这篇post的主题是
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>虽然这篇post的主题是<strong>NAS(Network Attached Storage)</strong>，但因为懒还是放在了<strong>VPS(virtual private server)</strong>目录里。上班后发现家里的黑群晖处于长期闲置状态，虽然一直开着机但在公司里也用不了（只能局域网访问）。这周末终于狠下心来整改一番，实现了外网访问，以后<del>摸鱼</del>工作起来更加便利了。</p><h1 id="准备阶段">2&emsp;准备阶段</h1><p>首先进行需求分析：能够从外网访问NAS的文件以及各种服务，实现方式经过<del>百度</del>Google可知有<strong>内网穿透</strong>与<strong>端口映射</strong>两类，其中<code>内网穿透</code>我很早之前试过但死活不成功，有点恶心到我了所以这次直接pass。<code>端口映射</code>的话需要以下条件：  </p><ol><li>光猫改桥接，通过<strong>路由器拨号</strong>，这样路由器页面里设置的端口映射才有效，不然在光猫的下级网络里。（什么？你没有路由器直接拿光猫上网？并且还在用光猫的WIFI？不会吧不会吧？）  </li><li>最好得有个域名，配置下DDNS，因为外部IP地址隔一段时间就会变，配置之后NAS检测到IP变化后会自动修改服务器提供商的解析设置，用户每次只需用域名访问即可。  </li></ol><p>下面回顾下具体需要准备的东西。</p><h2 id="光猫改桥接">2.1&emsp;光猫改桥接</h2><ol><li>首先得获取光猫的管理员账号密码，这个一般搜一下就能搜到，实在不行问装机小哥，再不行万能的淘宝解决；</li><li>宽带拨号用的用户名（连接名称<code>INTERNET_R_VID_XXX</code>里面可以看到）及密码，办宽带的时候一般都会告诉你密码，没说的话自己在网上营业厅里应该也都能查到，我是自己在网上重置了拨号密码（顺便吐槽下中国联通，重置几次都失败，最后忍无可忍提交宽带故障保修后又立马重置成功了）。</li><li>修改成桥接模式很简单，但还是保守一点比较好，留条后路，不要随便把连接直接删了。只需要先把原来PPP(或者PPPOE？)模式的连接勾选的绑定端口给取消，然后再新建一个桥接模式的连接并勾选这个端口（千兆）就完事了。</li><li>路由器里面改成拨号输入账号密码就行，不出意外的话现在路由器就能够上网了，但光猫的管理页面大概率没办法再登上去。要用的话可以直接拿网线连，一般也不会再去动它。</li><li>记得根据群晖的MAC地址给它分配一个静态IP。</li><li>随便设置一个端口映射，用<code>WAN IP:端口</code>的形式可以访问就表示大功告成了。</li></ol><h2 id="DDNS设置">2.2&emsp;DDNS设置</h2><blockquote><p>DDNS(Dynamic Domain Name Server)，是将用户的动态IP地址映射到一个固定的域名解析服务上，用户每次连接网络的时候客户端程序就会通过信息传递把该主机的动态IP地址传送给位于服务商主机上的服务器程序，服务器程序负责提供DNS服务并实现动态域名解析。</p></blockquote><p>我的域名放在Cloudflare上，但在群晖上一看支持DDNS的默认服务商竟然没有它，好在有<a href="https://github.com/joshuaavalon/SynologyCloudflareDDNS" target="_blank" rel="noopener">SynologyCloudflareDDNS</a>这个工具可以添加，配置起来也很简单，我按照步骤来没出现任何问题。</p><h1 id="其他设置">3&emsp;其他设置</h1><p>沉浸在成功实现外网访问的喜悦中，我一顿操作下来添加了接近10个端口映射。正准备再加个ssh端口时，我忽然想到，当初用NAS是因为它的安全性，文件都放在本地，在自己的掌控中；而将这些东西暴露在外网，甚至想直接用ssh登录，这样和VPS有什么区别，人家毕竟还是是专业托管机器的，反而比我这个小白弄的裸奔群晖安全吧。  </p><p>那么相对安全地暴露到公网的方式是什么呢，第一个想到的是<strong>VPN</strong>，只需要开放VPN相关的端口，通过它进入内网，之后就可以愉快地在工作时访问啦~  </p><p>下面具体说下我的设置:</p><ol><li>群晖安装<code>VPN Server</code>应用(国内被下架了，需要到官网去下载安装包手动安装)</li><li>开启之前先看一看群晖的证书设置，也以自己导入SSL证书，但最好<strong>不要</strong>把默认的给删了</li><li>我用的是<code>openvpn</code>，它的配置可以非常复杂，但我现在以能用为首要目标，就直接在页面上设置完事。只需要改一下动态IP地址（和局域网不同网段）以及勾选 <em>允许客户端访问服务器的LAN</em> 选项，导出配置里在修改下域名端口就行</li><li>我暂且只设置了账号密码登录，后续配合秘钥登录可能更好，但感觉安全性已经差不多了，毕竟是毫无规律性的<strong>几十位的数字字母字符混合密码</strong>加上群晖的<strong>自动封锁</strong>和<strong>账户保护</strong>功能</li><li>关闭除VPN以外的所有端口，保证直接从外网是打开不了网页的，防止被攻击以及被运营商找茬</li><li>更多安全设置可以参考<a href="https://blog.csdn.net/hilaryfrank/article/details/106127871" target="_blank" rel="noopener">这位大佬</a>的文章（垃圾充斥的CSDN里还是有点好东西的）</li></ol><blockquote><p>最后补充一点：<br>千万不要买个辣鸡路由器，主板配置low的一匹、就没几个选项。我用的是华硕性价比最高的一款（穷），除了需要定时重启（不然运行几十天后会不太稳定）其他都感觉不错。</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-08-29-nas-ke-yi-wai-wang-fang-wen-ge/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Makefile学习</title>
      <link>https://chengpengzhao.com/2021-07-28-makefile-xue-xi/</link>
      <guid>https://chengpengzhao.com/2021-07-28-makefile-xue-xi/</guid>
      <pubDate>Wed, 28 Jul 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;在Linux（unix）环境下使用GNU的make
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p>在Linux（unix）环境下使用GNU的make工具能够比较容易的构建一个属于你自己的工程，整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。  </p></blockquote><blockquote><p>make是一个命令工具，它解释Makefile中的指令（应该说是规则）。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile有自己的书写格式、关键字、函数。像C语言有自己的格式、关键字和函数一样。而且在Makefile中可以使用系统shell所提供的任何命令来完成想要的工作。  </p></blockquote><blockquote><p>Makefile（在其它的系统上可能是另外的文件名）在绝大多数的IDE开发环境中都在使用，已经成为一种工程的编译方法。</p></blockquote><h1 id="基础">1&emsp;基础</h1><ul><li><p>首先需要了解常见的编译器选项：以<code>gcc</code>编译器为例：</p><ul><li><p><code>-c</code>，仅编译不链接； <code>-I</code>，指定头文件路径(include)；<code>-L</code>，指定依赖库路径；<code>-l</code>，指定链接库的名字，如<code>libc.a</code>这一名称的库可用<code>-lc</code>来引用；</p></li><li><p><code>-o</code>，指定输出；<code>-O</code>，优化的4级别(0,1,2,3，常用<code>-O2</code>)；<code>-g</code>，产生调试信息；<code>-static</code>，禁用动态库；<code>-share</code>，生成一个共享目标文件,他可以和其他目标文件连接产生可执行文件.只有部分系统支持该选项；</p></li><li><p><code>-D</code>，定义比较重要的宏，如<code>-DDEBUG=1</code>，可配合程序中类似<code>#if DEBUG</code>语句使用；<code>-w</code>，关闭编译时警告；<code>-Wall</code>，编译后显示所有警告；</p></li></ul></li></ul><ul><li>简单规则： <pre class="line-numbers language-Makefile"><code class="language-Makefile">target ... : prerequisites ...#recipe前面一定要是一个Tab，不是空格  recipeclean:  recipe<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ul><li><p>简单例子：<code>main.c</code> 、<code>defs.h</code>、<code>func.c</code>，其中两个<code>.c</code>文件都依赖<code>defs.h</code></p><pre class="line-numbers language-Makefile"><code class="language-Makefile">#反斜线（用于换行）后不要加空格Name: main.o \  func.o      #这里用空格就行  gcc -o main.o func.o # 命令前是Tabmain.o: main.c defs.h  gcc -c main.cfunc.o: func.c defs.h  gcc -c func.cclean:          #这个target没有依赖  rm Name main.o func.o<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>变量的使用</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">objects= main.o func.oName: $(objects)  gcc -o ${objects}   #小括号和花括号都行，但必须要加<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>一条默认规则： 一个<code>N.o</code>文件默认依赖<code>N.c</code>，可以不用写出，故上面例子简化成：</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">Name: main.o \  func.o      #这里用空格就行  gcc -o main.o func.o # 命令前是Tab#书写建议：单目标、多依赖main.o: defs.hfunc.o: defs.h.PHONY:clean        #将clean声明为伪目标，避免存在名为clean的文件clean:  -rm Name main.o func.o# '-'：表示忽略rm的执行错误<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="进阶">2&emsp;进阶</h1><ul><li><p><code>include FILENAME</code>: 暂停当前Makefile读取，完成指定文件读取后再继续</p><pre class="line-numbers language-Makefile"><code class="language-Makefile"># VPATH, 指定依赖文件的搜索路径VPATH=../src:../headers# 使用空格或冒号可将多个目录分开include ../src/Makefile<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>通配符（如<code>*.c</code>）的使用，限于规则的<strong>目标</strong>、<strong>依赖</strong>和<strong>命令</strong>中</p></li><li><p><strong>变量</strong>定义中应使用<code>wildcard</code>展开通配符</p><pre class="line-numbers language-Makefile"><code class="language-Makefile"># :=表示不能使用后面定义的变量OBJS:=$(wildcard *.o)# 高级用法，先获取所有.c文件，再将变量中的.c后缀替换为.oOBJS:=$(patsubst %.c,%.o,$(wildcard *.c))<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>?=</code>操作符，表示只有在之前没有赋值的情况下才会对此变量进行赋值</p></li><li><p>定义变量时注释和定义要<strong>分行写</strong>，否则注释前的空格会被作为变量值的一部分</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">dir := /foo/bar    # directory to ...# 变量dir的值是"/foo/bar    "(后面有四个空格)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>变量的替换引用</p><pre class="line-numbers language-Makefile"><code class="language-Makefile"># 表示替换foo中所有以.o结尾的字为.c结尾bar:=$(foo:.o=.c)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p><code>$^</code> 代表所有通过目录搜索得到的依赖文件的完整路径名（目录 + 一般文件名）列表；<code>$@</code> 代表规则的目标名；<code>$&lt;</code> 代表规则中通过目录搜索得到的依赖文件列表的第一个依赖文件</p></li><li><p>链接静态库、共享库</p><pre class="line-numbers language-Makefile"><code class="language-Makefile"># 表示生成目标时需要链接libcurses.a或libcurses.so文件foo : foo.c -lcurses  cc $^ -o $@<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>命令回显：make执行命令时会默认将其输出到shell</p><pre class="line-numbers language-Makefile"><code class="language-Makefile"># 用@字符后不会回显命令，但仍会输出命令运行结果@echo 开始编译...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>命令的执行：每一行的命令执行<strong>相互独立</strong>，除非用<code>\</code>将一行分两行写</p></li><li><p>命令前加<code>-</code>字符，表示即使命令执行失败，make仍<strong>继续执行</strong></p></li><li><p>make中的<strong>条件</strong>语句</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">ifeq ($(CC),gcc)libs=$(libs_for_gcc)elselibs=$(normal_libs)endiffoo: $(objects)  $(CC) -o foo $(objects) $(libs)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>make中的<strong>循环</strong>语句</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">dirs:=a b c dfiles := $(foreach dir, $(dirs) , $(wildcard $(dir)/*))#等价于：files := $(wildcard a/* b/* c/* d/*)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>shell函数的使用</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">files:=$(shell echo *.c)# 变量“ files”赋值为当前目录下所有.c文件的列表（文件名之间使用空格分割），等效于$(wildcard *.c)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ul><h1 id="深入">3&emsp;深入</h1><ul><li><p>自动找寻源文件中包含的头文件，并生成文件的依赖关系</p><pre class="line-numbers language-bash"><code class="language-bash">gcc -M main.c<span class="token comment" spellcheck="true"># 不考虑标准库头文件时，用-MM参数</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>自动生成每一个<code>.c</code>文件对应的<code>.d</code>文件（包含相应依赖文件描述）</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">%.d: %.cpp# 1. 使用编译器自自动生成依赖文件（$<）的头文件的依赖关系，并输出成为一个临时文件# 2. 使用sed处理第二行已产生的那个临时文件并生成此规则的目标文件。（将.d加入到规则的目标中）# 3. 删除临时文件  $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \  sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \  rm -f $@.$$$$<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>.d</code>文件的处理（接着上面一条）</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">SRCS = $(wildcard ./*.cpp)dependence:=$(SRCS:.cpp=.d)sinclude $(dependence)# sinclude相当于 -include，(和其它版本make兼容)，表示无论include过程中出现什么错误，都不要报错继续执行。<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ul><li><p>order-only依赖使用</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">LIBS=libtest.afoo: foo.c|$(LIB)  $(CC) $(CFLAGS) $< -o $@ $(LIBS)# 如果foo已存在（前提），若libtest.a被修改，将不会重建foo<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>filter</code>分类函数使用</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">files = foo.elc bar.o lose.o$(filter %.o,$(files)): %.o: %.c  $(CC) -c $(CFLAGS) $< -o $@$(filter %.elc,$(files)): %.elc: %.el  emacs -f batch-byte-compile $<<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>没卵用的小技巧</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">var := one$\     word# 上面的内容等价于：var := one$ word# '$ '($后面有一个空格): a variable named ' '# 又等价于：var := oneword<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>一个例子</p><pre class="line-numbers language-Makefile"><code class="language-Makefile">#一个实用的makefile，能自动编译当前目录下所有.c/.cpp源文件，支持二者混合编译#并且当某个.c/.cpp、.h或依赖的源文件被修改后，仅重编涉及到的源文件，未涉及的不编译#详解文档：http://blog.csdn.net/huyansoft/article/details/8924624#author：胡彦 2013-5-21#----------------------------------------------------------#编译工具用g++，以同时支持C和C++程序，以及二者的混合编译CC=g++#使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表#sources:=main.cpp command.c#变量sources得到当前目录下待编译的.c/.cpp文件的列表，两次调用winldcard、结果连在一起即可sources:=$(wildcard *.c) $(wildcard *.cpp)#变量objects得到待生成的.o文件的列表，把sources中每个文件的扩展名换成.o即可。这里两次调用patsubst函数，第1次把sources中所有.cpp换成.o，第2次把第1次结果里所有.c换成.oobjects:=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(sources)))#变量dependence得到待生成的.d文件的列表，把objects中每个扩展名.o换成.d。也可写成$(patsubst %.o,%.d,$(objects))dependence:=$(objects:.o=.d)#----------------------------------------------------------#当$(objects)列表里所有文件都生成后，便可调用这里的 $(CC) $^ -o $@ 命令生成最终目标all了#把all定义成第1个规则，使得可以把make all命令简写成makeall: $(objects)  $(CC) $(CPPFLAGS) $^ -o $@  @./$@    #编译后立即执行#这段使用make的模式规则，指示如何由.c文件生成.o，即对每个.c文件，调用gcc -c XX.c -o XX.o命令生成对应的.o文件#如果不写这段也可以，因为make的隐含规则可以起到同样的效果%.o: %.c  $(CC) $(CPPFLAGS) -c $< -o $@#同上，指示如何由.cpp生成.o，可省略%.o: %.cpp  $(CC) $(CPPFLAGS) -c $< -o $@#----------------------------------------------------------include $(dependence)    #注意该句要放在终极目标all的规则之后，否则.d文件里的规则会被误当作终极规则了#因为这4行命令要多次凋用，定义成命令包以简化书写define gen_depset -e; rm -f $@; \$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$endef#指示如何由.c生成其依赖规则文件.d#这段使用make的模式规则，指示对每个.c文件，如何生成其依赖规则文件.d，调用上面的命令包即可%.d: %.c  $(gen_dep)#同上，指示对每个.cpp，如何生成其依赖规则文件.d%.d: %.cpp  $(gen_dep)#----------------------------------------------------------#清除所有临时文件（所有.o和.d）。之所以把clean定义成伪目标，是因为这个目标并不对应实际的文件.PHONY: cleanclean:    #.$$已在每次使用后立即删除。-f参数表示被删文件不存在时不报错  rm -f all $(objects) $(dependence)echo:    #调试时显示一些变量的值  @echo sources=$(sources)  @echo objects=$(objects)  @echo dependence=$(dependence)  @echo CPPFLAGS=$(CPPFLAGS)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-07-28-makefile-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>新的开始</title>
      <link>https://chengpengzhao.com/2021-07-18-xin-de-kai-shi/</link>
      <guid>https://chengpengzhao.com/2021-07-18-xin-de-kai-shi/</guid>
      <pubDate>Sun, 18 Jul 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;好久没更新点东西了，4月份一直在写论文，5-6月在改论文、准备答辩（顺便沉迷
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>好久没更新点东西了，4月份一直在写论文，5-6月在改论文、准备答辩（顺便沉迷了下<a href="https://store.steampowered.com/app/440900/Conan_Exiles/" target="_blank" rel="noopener">流放者柯南</a>这个游戏），6月底毕业收拾行李准备工作的时候才忽然发现、自己的学生时代似乎已经结束了（虽然N年后可能考虑去读个博）</p><p>前些日子称体重发现这3个月自己胖了6斤，虽然和室友动不动就点KFC拖不了干系但毕竟是自己没控制饮食（好像从来就没怎么控制过），工作之后准备重新开始被遗忘在角落的减脂计划，打算下周就去办个卡。</p><p>数一数自己在北京呆了快7年去过哪些地方玩……还是算了吧太low了，宅着不香嘛。而且大脑容量有限，就算是之前去过的地方也都忘记了好多，懒得仔细去回想。</p><p>双证还没发就跑来工作了，等要到迁户口等办手续的时候估计还得回北京折腾一趟，好麻烦。</p><p>租房还是找正规中介比较效率，像是我爱我家、链家啥的，签起合同来比较方便。这边很多房东也怕麻烦，直接把房源甩给中介处理了（谁叫中介费全部由租客承担呢）。一居室的便宜好房还是少啊，如果找不到的话二室一厅合租也挺好，除开室友这一不确定因素。</p><p>昨天刚从酒店搬进房间，有个家还是爽啊（虽然是暂时的），55平米一个人住也够宽敞了，可以在里面锻炼甚至反复横跳。这两天光买生活用品就花了我1000多，加上房租押一付三+中介费，加起来也有一万多了，真是花钱如流水。</p><p>既然工作了，游戏时间要开始严格控制（虽说上学时也基本玩腻了）。自律还是要自律的，近半年的主要目标是先把体重和体脂降下来，把工作给做好。</p><p>博客也准备增加点更新频率，算是逼迫自己去学习的一种手段吧。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-07-18-xin-de-kai-shi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《人人都看得懂的财报书》读书笔记</title>
      <link>https://chengpengzhao.com/2021-04-01-ren-ren-du-kan-de-dong-de-cai-bao-shu-du-shu-bi-ji/</link>
      <guid>https://chengpengzhao.com/2021-04-01-ren-ren-du-kan-de-dong-de-cai-bao-shu-du-shu-bi-ji/</guid>
      <pubDate>Thu, 01 Apr 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;财务报表相关书籍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>财务报表相关书籍：</p><blockquote><p><a href="https://book.douban.com/subject/25790961/" target="_blank" rel="noopener">《人人都看得懂的财报书》</a><br><a href="https://book.douban.com/subject/34810876/" target="_blank" rel="noopener">《一本书读懂财报(全新修订版)》</a><br><a href="https://book.douban.com/subject/35299355/" target="_blank" rel="noopener">《手把手教你读财报》</a><br><a href="https://book.douban.com/subject/33423395/" target="_blank" rel="noopener">《财报就像一本故事书》</a><br>……</p></blockquote><h1 id="为什么看财报">1&emsp;为什么看财报</h1><ul><li><p>财报：评判企业好坏的首要标准。</p></li><li><p>30％以上的毛利率是衡量一般企业的最低标准，如果毛利率达不到这一标准，基本上就可以确定它是没有竞争能力的企业了(当然要先判断企业的类型，再量化分析）。</p></li><li><p>格雷厄姆：“把投资股票当成生意来做的人，是聪明的投资者。”</p></li><li><p>为什么你投资企业和大家一起合伙做生意时，却要每天关注企业股票的报价呢？</p></li><li><p>估价一定要做到保守，安全边际一定要设得足够安全。</p></li></ul><h1 id="利润表1">2&emsp;利润表1</h1><ul><li><p><strong>营业收入</strong>：主营业务收入，一般财报都会说清楚主营业务有哪些分类。</p></li><li><p><strong>营业成本</strong>： 直接参与主营业务经营的成本。</p></li><li><p><strong>营业税金及附加</strong>：消费税（以特定消费品为对象征收的价内税）、资源税（矿产，盐）、教育费附加（为发展教育事业的附加税）、城市维护建设税（为加强城市建设的附加税）。同一行业各企业基本大同小异。</p></li><li><p><strong>销售费用</strong>：一般也会注明详细分类，如广告宣传、运输、促销、打假费。</p></li><li><p><strong>管理费用</strong>：企业用来管理自身所花费的费用，如固定资产折旧费、无形资产摊。占毛利润比率最好在10%以内。</p></li><li><p><strong>财务费用</strong>：大部分企业都是负债经营的。为了满足扩展业务规模的需要，企业可能会向银行借钱，也可能通过发行企业债券来融资。向银行借钱，要给银行利息。发行企业债券，除了要付给购买者利息以外，还必须首先把债券印出来。而印债券的钱也算是财务费用。有外汇储备时汇率变动导致的盈亏也算入其中。</p></li><li><p><strong>资产减值损失</strong>：如应收账款变坏账、固定资产的减值、商誉资产减值…只有正视资产减值损失，才能为企业的赢利能力增砖添。</p></li><li><p><strong>公允价值变动收益</strong>：1. 交易性金融资产，近期内售出股票债券的行为；2. 交易性金融负债，通过发行短期债券等为企业融资；3. 股票及现金选择权，持有的股票或现金增值或贬值。</p></li><li><p>数字加括号=负号=损失</p></li><li><p><strong>联营企业</strong>是指两个及两个以上相同或不同所有制性质的企业法人或事业单位法人，按自愿、平等、互利的原则，共同投资组成的经济组织。而<strong>合营企业</strong>是指按合同约定对某项经济活动所共有的控制，是指由两个或多个企业或个人共同投资建立的企业，该被投资企业的财务和经营政策必须由投资双方或若干方共同决定。</p></li><li><p><strong>投资收益</strong>：通过证券获得的收益、对联营企业和合营企业业的投资收益等。</p></li><li><p><strong>营业外收入</strong>：如固定资产处置利得、政府补助、罚款及赔款利得…</p></li><li><p><strong>营业外支出</strong>：如因不可抗力遭受的损失，固定资产盘亏、报废、毁损、出售的净损失、非季节性和非修理性期间的停工损失、职工子弟学校经费和技工学校经费、非常损失、公益救济性的捐赠、赔偿金、违约金…</p></li><li><p><strong>利润总额</strong>=营业利润+营业外收入-营业外支出</p></li><li><p><strong>所得税</strong>：企业所得税（固定比例税率），国家针对企业法人在一定时期内的收入所征收的税种。它所征收的基础是建立在利润总额基础上的。用利润总额乘以相关的税率，得出企业所得税。</p></li><li><p><strong>每股收益</strong>=净利润/总股本；  <strong>基本每股收益</strong>：归属于普通股东的当期净利润／当期发行在外普通股的加权平均数； <strong>摊薄每股收益</strong>：不管新股是哪个月发行的，只按期末有多少来计算； <strong>稀释每股收益</strong>：债转股以后，增加的每股收益并没有原来的每股收益多，把新股加进来以后，会稀释原有的每股收益。所以叫作稀释每股收益。</p></li></ul><h1 id="利润表2">3&emsp;利润表2</h1><ul><li><p><strong>净利润</strong>：稳定持续才是真。要把营业外收入中产生的营业外利润剔除掉。</p></li><li><p><strong>主营业务收入与成本</strong>： 需要对比分析，观察收入增长率是否超过成本增长率。</p></li><li><p><strong>毛利率</strong>=(主营业务收入-主营业务成本)/主营业务收入</p></li><li><p><strong>财务费用</strong>为负：表示公司在收取利息收入。</p></li><li><p><strong>权责发生制</strong>：资产当年的损耗就计在当年，不把未来的损耗也算在今年中。固定资产折旧方法有很多种…</p></li><li><p>总结：<br>  a. 看主营业务收入曲线增长。<br>  b. 对比主营业务收入与主营业务成本曲线。<br>  c. 对比主营业务收入与销售费用曲线。<br>  d. 看财务费用变化情况。<br>  e. 看固定资产折旧占毛利润百分比。<br>  f. 看管理费用占毛利润百分比。<br>  g. 看净利润增长；净利润占总收入的20％以上，都可以看成是有竞争力的企业。而净利润占总收入在10％以下的企业，则是严重溃乏竞争力的企业。净利润在10％至20％之间的企业，则是介于两者之间，有待于投资者去发现的那些被低估的公司。<br>  h. 看行业的特殊性，如零售业的薄利多销、金融银行业的风险控制。<br>  i. ……</p></li></ul><h1 id="资产负债表1">4&emsp;资产负债表1</h1><ul><li><p><strong>货币现金</strong>：通过融资、出售业务或资产、运营所得到的现金。</p></li><li><p>现金通过回购股票可以间接提升股东手中所持股票的含金量。</p></li><li><p><strong>存货</strong>： 计算方法有多种，如先进先出法、后进先出法、加权平均法。存货减少，企业资金的周转速度才能加快，才能不断提升自身的赚钱能力。</p></li><li><p><strong>应收科目</strong>： 应收票据和应收账款。对于小公司，应收科目过多意味着现金的不足，需要承担更大的风险。</p></li><li><p><strong>固定资产</strong>： 需要长期摊销的成本，太多了不太好。越是可以长久使用的，可以长期摊销的，更新换代慢的，就越有竞争力。</p></li><li><p><strong>无形资产</strong>： 企业真正的竞争力所在。</p></li><li><p><strong>长期投资</strong>：指时间在一年以上的投资，包括股票、债券、房地产等。</p></li><li><p><strong>借款科目</strong>：首先看短期贷款（比较危险），再看长期贷款需要用多少年的利润才能还清。巨额银行债务和即将到期的长期贷款，基本上都是企业倒闭的导火索。</p></li><li><p><strong>少数股东权益</strong>：母公司并不占有子公司100％的股份，但账面上属于母公司，最后划分产权的时候，划出不属于母公司的那部分。属于“别人的资产”。</p></li><li><p><strong>流动比率</strong>=流动资产/流动负债；  大于1表明还债不存在问题。对于经营状况良好、有竞争力的企业而言，流动比率不一定都要小于1；而流动比率小于1的企业，除非极个别特例，绝大部分竞争力都不强。</p></li><li><p><strong>总资产回报率</strong>＝净利润／总资产，体现了赚钱的速度。</p></li><li><p><strong>优先股与普通股</strong>：每次赚钱以后都要先分给投资者，并且每次分多少都是事先确定好了的。从这个角度来看，它更像是一种负债，虽然永远不用归还本金，但却一直都要付给他利息，并且这利息似乎要高于银行贷款的利息。在企业发展到一定规模以后，若还没有赎回优先股，它就变成了一种负担。</p></li><li><p>购买优先股属于债券投资，购买普通股属于股权投资。</p></li><li><p><strong>账面价值（清算价值）</strong> ＝普通股价值+盈余项目－无形资产价值；  ＝有形资产－所有优先级别高于普通股的负债。</p></li><li><p><strong>每股账面价值（每股净资产）</strong> ＝（股东权益总额－优先股权益）／发行在外的普通股股数</p></li><li><p>当市场价格低于清算价值（约等于流动资产价值）时，决定是清算还是继续经营时，不能指望高管或是其他人做出相对正确的决定，而是要谨慎行事，不可贸然买入。如果某家企业的市场价格低于清算价值，也同时意味着可以以极低的价格买进这些资产。但是，这里面有一个问题：如果真的被低估了，趁机买进当然是一笔相当划算的交易；可要是确实没有任何赢利能力了，买进的就是垃圾股了。</p></li><li><p><strong>所有者权益变动表</strong>：将资产负债表中的所有者权益项放大，变得更加详细而已。</p></li><li><p><strong>资本公积</strong>： 股票价格比票面价值多出来部分的总额。</p></li><li><p><strong>盈余公积</strong>：净利润中提取一部分钱出来，用处有三条：1. 如果以后亏损了，亏损的部分可以用盈余公积来填补； 2. 可以转化为企业的资本，但是剩余的盈余公积的数额不得少于注册资本的四分之一。 3. 如果企业在亏损的年份还要发放股利的话，可以用盈余公积来发放股利。</p></li></ul><h1 id="资产负债表2">5&emsp;资产负债表2</h1><ul><li><p>看总资产与负债增长、所有者权益增长情况。</p></li><li><p>资产和负债的流动性与非流动性的界定是和<strong>资金周转快慢</strong>联系在一起的。越是可以快速周转流动的，在编制资产负债表时就越靠前；周转流动性越差的，排的位置就越靠后。由于资金只有周转起来、流动起来，才能运营起来。所以，编制越靠前的，可以说是越重要。</p></li><li><p><strong>闲置资金</strong>的用途： 金融资产（黄金、有价证券）、金融负债（短期融资）。</p></li><li><p><strong>交易性金融资产</strong>： 短期获利为目的的投机，属于当年或当期的投资行为，无论是赚了，还是亏了，都需要计算到利润表中去。企业这部分资产不宜过多。</p></li><li><p><strong>可供出售金融资产</strong>：什么时候出售，是长期还是短期，都不确定，全看企业的战略意图；购买可供出售交易金融资产所花的钱，由于不一定是在当期就平仓了结，所以这些钱常会被当作一种投资成本。</p></li><li><p><strong>交易性金融负债</strong>：通过发行企业债券等方式进行的主动地融资。</p></li><li><p><strong>应收票据</strong>： 如银行承兑汇票与商业承兑汇票（风险更大）。</p></li><li><p><strong>应收账款</strong>： 风险更大，很多没有利息；而应收票据有期限，一般有利息。</p></li><li><p>应收票据相对于应收账款来说，风险更小一些。应收票据主要是银行汇票、商业汇票等。银行汇票几乎没有风险，商业汇票是拿企业的信誉为担保的，所以大部分企业都会履约，如果不能履约，也会转入“应收账款”中。几乎无风险的为应收票据，有风险的都归为应收账款。</p></li><li><p><strong>应付账款</strong>： 到期收款，属于负债； <strong>预付账款</strong>： 到期收货，属于资产。</p></li><li><p><strong>应收股利</strong>： 如现金股利、股票股利。现金股利，是指以现金形式分派给股东的股利，是股利分派最常见的方式。 … 现金股利侧重于反映近期利益，对于看重近期利益的股东很有吸引力。 股票股利，是指公司用无偿增发新股的方式支付股利，因其既可以不减少公司的现金，又可使股东分享利润，还可以免交个人所得税，因而对长期投资者更为有利。</p></li><li><p><strong>递延</strong>：包含递延所得税资产、递延所得税负债、长期待摊费用等，确认时间不同导致递延的项目。</p></li><li><p><strong>长期股权投资</strong>：不仅能用现金来投资，也可以用专利权、设备等进行股权投资，属于持有至到期投资，不是金融衍生品。</p></li><li><p><strong>固定资产</strong>：生产时所用的固定资产，比如设备、流水生产线；非生产时使用的固定资产，比如办公用品；租出的固定资产，比如出租给其他企业的房屋或店面；未使用的固定资产；不需用固定资产；融资租赁固定资产；接受捐赠固定资产。</p></li><li><p><strong>固定资产折旧</strong>：与陈旧过时的风险相比，长期折旧因素根本就无关紧要； 固定资产清理：过渡性的科目，产生收益了，就记成正的，产生支出了，就记成负的。</p></li><li><p><strong>正在成型的资产</strong>： 在建工程（半成品、完成后变为固定资产）、工程物资（能够变现）、生产性生物资产（林木、畜类）及油气资源等。</p></li><li><p><strong>净资产</strong>：所有者权益，包含实收资本（股本、代表了股东在企业中的权益，既有优先股，也有普通股）、资本公积（股本溢价、他人的捐赠、法定资产重新估值）、库存股（被减掉、它会抵消掉一部分资本公积，回购股票产生）、盈余公积和未分配利润。</p></li></ul><h1 id="现金流量表1">6&emsp;现金流量表1</h1><ul><li><p><strong>现金</strong>：普通意义上的现金、银行存款、银行汇票、三个月内可以变现的有价证券等。</p></li><li><p>现金流量表<strong>六大项</strong>：经营活动产生的现金流量、投资活动产生的现金流量、筹资活动产生的现金流量、汇率变动对现金的影响、现金及现金等价物净增加额、期末现金及现金等价物余额。</p></li><li><p><strong>经营活动产生的现金流量</strong>：企业最重要的现金流入项目，其他项目都是附属。</p></li><li><p>企业赢利利润表中的净利润增长，但钱未必能收得回来，可能是欠钱的这家企业倒闭了，分文皆无，也可能明年再还钱。每种可能都能让企业的盈利只停留在账面上，而收不到真金白银。</p></li><li><p><strong>投资活动产生的现金流量</strong>： 资本性投资（不能直接卖钱），而不是收益性投资（加工、卖钱变现）。</p></li><li><p>企业资产分类： 经营性资产和金融性资产。</p></li><li><p><strong>期末现金及现金等价物余额</strong>：如果这一余额逐年增加，说明这家企业创造的现金流逐年增加，其财务能力极强。</p></li></ul><h1 id="现金流量表2">7&emsp;现金流量表2</h1><ul><li><p><strong>自由现金流</strong>：实实在在进入了企业的银行账户的钱，并且只要股东大会同意，这些钱除了还给银行或其他债权人以外，可以任意进行分配。    自由现金流（经营活动产生的现金流和投资活动产生的现金流加总）＝向股东发放的净股利＋对债权人的净支付</p></li><li><p><strong>自由现金流（偿债能力）</strong>　不仅是股东判断企业是否值得投资的重要标准，也是企业经营者判断企业财务是否健康的重要依据。分析自由现金流不能只看当期的数值，而要全面分析企业正处于哪个阶段。</p></li><li><p>在现金流量表中，购置固定资产只列在了投资活动产生的现金流出项内，并且是一次性列支（“一次性巨额资本性支出”），而在剩余的会计年度内提取的折旧准备金中，并没有产生现金的流出。当所有的资本性支出都摊销结束时，资本性支出所带来的现金回流才相应结束，那时自由现金流会趋于正值。</p></li><li><p>净利润和自由现金流永远只能在理论上长期趋同。</p></li><li><p>重资本输出型企业的市盈率很低：这类企业的固定资产在严重损耗的情况下，最后只能折旧或报废，因此它的净利润是打了折扣的，自由现金流也相应地打了折扣。 而轻资本输出型企业每年的净利润基本上等于自由现金流。</p></li><li><p><strong>经营负债杠杆</strong>＝经营负债／净经营资产， 国际上通用的经营负债杠杆测量标准不能超过40%。</p></li></ul><h1 id="持续盈利的能力（利润表）">8&emsp;持续盈利的能力（利润表）</h1><ul><li><p><strong>毛利润</strong>＝主营业务收入－主营业务成本（营业收入－营业成本）  ；  <strong>毛利率</strong>＝毛利润／主营业务收入</p></li><li><p>不必强求毛利率非要有70％或80％那么高；不能单方面去看企业的毛利率。它可能有很高的毛利率，但长期投资却也是高的，在一段时间内需要大规模更换固定资产。</p></li><li><p>看企业有没有核心竞争力就要看毛利率。毛利率越高，说明产品或企业在成本之外的附加价值就越高。</p></li><li><p><strong>销售净利率</strong>，反映了到底赚了多少钱，附加了无形资产的价值。</p></li><li><p><strong>资产周转率</strong>= 营业收入/总资产，不能只看结果，还要看总资产的大小。分母越大，达到同一水平的资产周转率难度就越大。</p></li><li><p>资产周转率的问题关系到企业的定位，如果像沃尔玛一样的零售企业，多数情况下是毛利率特别低，但周转得特别快。而高端企业则是毛利润高，资产周转的速度相对较慢。</p></li><li><p><strong>流动资产周转率</strong>＝营业收入／流动资产 ， 固定资产周转率＝营业收入／固定资产 ； 流动资产周转率越高，说明企业将资金分配得越合理，现金的利用率越高。固定资产周转率越高，说明利用固定资产赚取的利润越多，可以反映企业管理水平。</p></li><li><p><strong>净资产收益率</strong>＝净利润／所有者权益，随着净资产的不断增加，净资产收益率还能升高或保持不变，那这家企业就相当有竞争力了。 净资产收益率一定要高于银行利率与长期国债利率（如5.32%）。</p></li></ul><h1 id="资产管理">9&emsp;资产管理</h1><ul><li><p>净资产（所有者权益）/总资产=<strong>股东权益比率</strong>；  负债总额/总资产=<strong>负债比率</strong>；  负债总额/净资产=<strong>产权比率</strong></p></li><li><p>不可只看总资产增加得有多快，一定要把本质的东西找出来，看净资产的增幅到底有多快。如果总资产不断增加，而净资产却不断减少，那企业一定是借了很多钱，并且越借越多，风险也就越来越高。</p></li><li><p>当负债的总额接近企业所有者权益1.2倍的时候，我们就应该警惕负债过高了。</p></li><li><p><strong>长期负债比率</strong>＝长期负债／总资产； <strong>资本总额比率</strong>＝长期负债／（长期负债+股东权益总额）； <strong>流动负债率</strong>＝流动负债／负债总额</p></li><li><p>资本总额比率越低，说明他人在自己的长期投资中所占的比率很小，还债的压力就越小，反之压力就越大。通常认为35％是一个临界点。大于35％，长期负债的还款压力就大；小于35％，基本上处于可以接受的限度之内。</p></li><li><p><strong>有息负债率</strong>＝（短期贷款＋一年内到期的长期负债＋长期借款＋应付债券＋长期应付款）／股东权益总额×100％    ；    有息负债则会在不动声色中增加企业的负债。当有息负债比率达到1时，警戒线就到了。</p></li><li><p><strong>资本周转率</strong>＝（货币资金＋短期投资＋应收票据）／长期负债合计×100％  ；   衡量企业长期负债的偿债能力。</p></li><li><p>长期负债，不能只看当期的数据，还要看长期的数据。</p></li><li><p><strong>有形资产净值债务率</strong>＝负债总额／（股东权益－无形资产净值）×100％    ；    衡量偿还债务的能力时，不能把无形资产看得太重。也正因为如此，我们需要重视有形资产的变现能力。当有形资产净值债务率为1时，警戒线就来临了。</p></li><li><p><strong>固定资产与股东权益比率</strong>＝固定资产总额／股东权益总额   ；     在理论上来说，股东的投资是不能直接变现的。如果想要变现，只能转让股份。所以，这部分钱对于企业来说就是本金，所以叫作股本，主要用来购买固定资产。</p></li><li><p>如果固定资产与股东权益比率过高，高于100％，股东投的钱买固定资产都不够，那就得举债购买。这样，企业的资本结构就会变得不稳定。一旦出现了突发性问题，需要现金却没有，企业就只能卖固定资产了，这样财务风险非常大。最常用的为66％的股东权益用来购置固定资产，34％用来作流动资产。</p></li><li><p><strong>存货周转率（存货周转次数）</strong> ＝销售成本（一年）／平均存货余额（每天） ；   存货周转率越高，说明变现能力越强，也说明投在存货上的资金周转得越快。</p></li><li><p><strong>存货周转天数</strong>=360天（默认每年360天）/存货周转率</p></li><li><p><strong>应收账款周转率</strong>＝当期销售净收入／平均应收账款余额   ；   应收账款周转率越高越好，这表明别人还我们钱的速度越快。</p></li><li><p><strong>市盈率</strong>：每股售价/每股收益， 反映了多少年能回本；市盈率是20倍，如果企业每年收益不变的情况下，需要20年能赚回所支付的现金。</p></li><li><p>长期国债的利率为5％，那么赚回本金，需要20年，以此推算，正常的市盈率乘以国债利率为1，也可以说，正常的市盈率为长期国债利率的倒数。</p></li><li><p>资产负债表相对于其他报表来说是最规范的报表，因为它是存量表，是平衡表，并且由于项目众多，很难出现虚假情况。所以，资产负债表完全可以成为企业收益质量的试金石。</p></li></ul><h1 id="利润与资产，都以现金作为终点">10&emsp;利润与资产，都以现金作为终点</h1><ul><li><p><strong>速动比率</strong>= 速动资产（货币现金+短期投资+应收票据+应收账款+其他应收款）/流动负债     ；  衡量企业流动资产中可以立即变现用于偿还流动负债的能力。比例在1~1.5为宜。</p></li><li><p>流动资产中也有一些变现能力很差的，如存货和不能变现的待摊费用。</p></li><li><p>速动比率与流动比率类似，但去掉了变现能力差的部分。</p></li><li><p><strong>现金到期债务比</strong>=营业现金净流量（自由现金流）/本期到期债务   警戒线1.5   ；    <strong>现金流动负债比率</strong>=年经营活动现金净流量/年末流动负债   ；  <strong>现金债务总额比</strong>=经营活动现金净流量/期末债务总额</p></li><li><p>利润表和资产负债表：权责发生制；  现金流量表：收付实现制。</p></li><li><p>营业收入的含金量：     <strong>销售现金比率</strong>=经营活动现金净流量/营业收入；     <strong>净利润含金量</strong>=自由现金流/净利润。  越大说明销售回款能力越强、财务压力越小。</p></li><li><p>自由现金流可自由支配，是用来偿还债务和发放股利的最大限度额。          <strong>每股营业现金净流量</strong>=经营现金流量净额/普通股股数。    每股营业现金净流量越大，说明股东所拥有的权益就越多。</p></li><li><p><strong>全部资产现金回收率</strong>=自由现金流/平均资产总额 ；  考量企业全部资产产出现金的能力，越大说明企业自由支配的现金越多，企业的运营情况就越好。</p></li><li><p><strong>现金满足投资比率</strong>= 近五年累计经营活动现金净流量/（同期内的资本支出+存货增加+现金股利） ；  衡量企业赚来的钱够不够花。      <strong>现金股利保障倍数</strong>=自由现金流/现金股利 ；  按照更简单的发放股利的标准来衡量。</p></li><li><p><strong>现金运营指数</strong>=（经营所得现金-经营性资产净增加）/经营所得现金   ；      <strong>经营性资产净增加</strong>：流动资产、固定资产、无形资产的增加。      现金运营指数越高，说明赚的钱多以现金形式存在，否则说明大多为实物或债权方式存在。但计算过程比较复杂。</p></li></ul><h1 id="财报分析">11&emsp;财报分析</h1><ul><li><p><strong>企业价值</strong>=账面价值（企业净资产）+溢价（预期增加的部分）    ；      </p></li><li><p><strong>市净率</strong>=市场价格/账面价格      ；      越大说明溢价越多。若小于1则说明溢价为负，该企业不容乐观。</p></li><li><p><strong>折现</strong>：钱越来越不值钱， 如按照年利率5.32%来说，明年的5万相当于今天的4.51万。</p></li><li><p>溢价是未来实现的，而我们需要现在对它埋单，但现在的钱比未来的钱值钱，所以需要将未来的溢价进行折现。</p></li><li><p>如何给企业估价？   收益递增型、收益平稳型（不预估、采用当前价位）、收益递减型企业（离场）<br>a. 至少进行10年（书中推荐30年）的预估，估值时一定要保守；<br>b. 企业增长率的估计，预期每股收益增长率；<br>c. 折现率的确定，至少为2倍长期国债收益率；<br>d. 给出多个档次的价位。</p></li><li><p>分散投资： 必须要将筹码分散开，因为对于收益是预估的。</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-04-01-ren-ren-du-kan-de-dong-de-cai-bao-shu-du-shu-bi-ji/#disqus_thread</comments>
    </item>
    
    <item>
      <title>股票价格指数学习</title>
      <link>https://chengpengzhao.com/2021-02-26-gu-piao-jie-ge-zhi-shu-xue-xi/</link>
      <guid>https://chengpengzhao.com/2021-02-26-gu-piao-jie-ge-zhi-shu-xue-xi/</guid>
      <pubDate>Fri, 26 Feb 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;摘录来源：&lt;br&gt;1.&lt;a href=&quot;https
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p>摘录来源：<br>1.<a href="https://www.zhihu.com/question/21337780" target="_blank" rel="noopener">中国股票指数为什么会有上证、深证、沪深300等各种指数，它们之间的区别和联系是什么？</a><br>2. <a href="https://www.zhihu.com/question/63750947" target="_blank" rel="noopener">到底什么是股票指数？什么是上证指数？</a><br>3. <a href="https://www.zhihu.com/question/36687104" target="_blank" rel="noopener">什么是股票指数,有哪些种类?</a><br>4. <a href="http://caifuhao.eastmoney.com/news/20200805164853383223230" target="_blank" rel="noopener">关于主板、中小板、创业板、新三板，再也不会傻傻分不清楚啦！</a><br>5. <a href="https://www.zhihu.com/question/20747036" target="_blank" rel="noopener">主板、中小板、创业板、新三板的区别是什么？企业选择上市板块时的参考依据是什么？</a></p></blockquote><h1 id="Tips">1&emsp;Tips</h1><ul><li><p>股票价格指数：一揽子股票通过某种方式计算出来的综合价格指数，可以看做便利投资者的晴雨表。</p></li><li><p>股票分类：<br>A股：指境内的公司发行，供境内机构、组织或个人(不含台、港、澳投资者)以人民币认购和交易的普通股股票。<br>B股：指那些在中国大陆注册、在中国大陆上市的特种股票。B股以美元港元计价，面向境外投资者发行，但在中国境内上市。<br>H股：指国有企业在香港上市的股票。<br>S股：指那生产或者经营在中国大陆，注册地在新加坡或者其他国家和地区，但是在新加坡交易所上市挂牌的企业股票。<br>N股：在中国大陆注册、在纽约上市的外资股票。  </p></li><li><p>通常按照板块划分、规模划分。有两种分类方式，一种是全部包含的，叫综合指数，简称综指或全指；另一种是部分包含，选取一些代表性的，叫做成分指数，简称成指。</p></li><li><p>搞清楚自己的股票的所属分类，就会理解我们手中的股票的涨跌不一定和大盘同步，因为大盘的分类颗粒度太粗了。想要找线索和相关性，用更细颗粒度的分类方式就可以找到你想要的答案。</p></li><li><p>指数基金：为投资者提供最接近指数的投资回报。投资者最后拿到手的指数基金回报，应该是指数回报，扣除基金费用，加上租出股票得到的租金，以及调整了跟踪误差之后的投资回报。</p></li><li><p>没有基金跟踪的指数，基本都是被市场抛弃的无用指数。 所以，好的指数，除了要求权威、客观、有效，还有更重要的一条就是：必须要有跟踪这些指数的ETF（指数基金），或者分级基金的母基金。</p></li><li><p>上交所（上海证券交易所）有1566家上市公司（截止到2020年6月），深交所（深圳证券交易所）有2231家上市公司（截止到2020年6月）</p></li><li><p>上证和深证的区别：<br>证券交易所的地点：沪市是上海;深市是深圳<br>板块不同：沪市只有主板与B股;深市有主板、中小板、创业板和B股<br>B股标价不同：沪市是以美元竞价;深市是以港币竞价<br>交易制度不同：基本的交易规则是一致的，差别在于收市最后3分钟(14:57~15:00)，具体在于沪市的交易规则是连续竞价;深市的交易规则是集合竞价<br>过户费不同，上海股票过户费每一千股收取1元，深圳股票过户费0元。</p></li></ul><ul><li><p>标普全球行业分类标准，10个行业部门：<br>基础材料(Materials)——化学品、金属采矿、纸产品和林产品；<br>消费者非必需品(Unnecessary Consume)——汽车、服装、休闲和媒体；<br>消费者常用品(Necessary Consume)——日用产品、食品和药品零售；<br>能源(Energy)——能源设施、冶炼、石油和天然气的开采；<br>金融(Finance)——银行、金融服务和所有保险；<br>医疗保健(Medical &amp; Health)——经营型医疗保健服务、医疗产品、药品和生物技术；<br>工业(Industry)——资本货物、交通、建筑、航空和国防；<br>信息技术(Information technology)——硬件、软件和通讯设备；<br>电信服务(Telecom)——电信服务和无线通讯；<br>公用事业(Utilities)——电力设备和天然气设备  </p></li><li><p>无论是什么，只要价格脱离价值产生背离，迟早价格都会回到价值附近，这就产生了涨和跌，要想抓住市场脉搏，首先要了解投资产品的价值所在，然后参考基本面消息作为辅助，主要运用技术策略判断走势，等待市场给出的信号，一旦确定满足交易条件，毫不犹豫入场交易。</p></li></ul><h1 id="板块分类">2&emsp;板块分类</h1><p>（主板、 创业板、 中小板、 科创板、新三板、四板…）</p><p>资本市场有不同的层次，主要分为场内市场和场外市场。 <strong>场内市场</strong>即交易所市场，包括上海证券交易所和深圳证券交易所。主板、中小板、创业板都是场内交易所市场，对应的企业均为上市公司。 <strong>场外市场</strong>即交易所之外的市场（OTC），包括新三板（全称叫全国中小企业股份转让系统）、区域性股权交易市场、双创板、券商OTC市场，对应的企业均为非上市公司。<br>主板、中小板、创业板、新三板，风险依次加大，所以一般股票开户时创业板和科创板需要另外开通，且开户条件依次升高。</p><ul><li>主板</li></ul><p>沪深主板，一板市场，在上交所上市的主板企业股票代码以600开头，在深交所上市的主板企业股票代码以000开头；<br>多为国有大型企业。</p><ul><li>中小板</li></ul><p>属于主板市场的一部分，是深交所主板市场中单独设立的一个板块，发行规模相对主板较小，企业均在深交所上市，也是一板市场；股票代码以002开头。<br>中小板实际上是民营企业比较多，民营企业中间又是各个行业的领头。<br>多为中型稳定发展企业。</p><ul><li>创业板</li></ul><p>二板市场，是深交所专属的板块，相较主板和中小板更看重企业的成长性，股票代码以300开头。<br>创业板是为无法在主板上市的创业型企业、中小企业和高科技产业企业等需要进行融资和发展的企业，提供融资途径和成长空间的证券交易市场，具有规模较小，高成长性、高科技性的特点，是对主板市场的重要补充。相对于主板和中小板，创业板上市门槛较也相对较低。<br>多为科技成长性企业。</p><ul><li>科创板</li></ul><p>是上交所专属的板块，2018年底成立，交易代码多以95开头。<br>多为科技创新性企业。</p><ul><li>新三板</li></ul><p>独立于沪深交易所之外，全名是叫做股份转让系统，是场外交易市场（OTC）。指全国性中小企业股份转让市场，为那些还未上市的中小微企业提供股权交易的场所，准入门槛低，企业质量层次不齐。股票代码开头为830或430。</p><h1 id="国内常见指数">3&emsp;国内常见指数</h1><h2 id="按照板块命名">3.1&emsp;按照板块命名:</h2><h3 id="上证指数">3.1.1&emsp;上证指数</h3><p>上海证券交易所<strong>综合</strong>股价指数，上证指数的样本为所有在上海证券交易所挂牌上市的股票，可以代表上海证券市场上所有的股票的整体涨跌情况</p><h3 id="深证成指">3.1.2&emsp;深证成指</h3><p>深证成份指数（价格），是深圳证券交易所最重要的指数。它是按一定标准选出500家有代表性的上市公司作为成份股，用成份股的自由流通股数作为权数，采用实际可交易市值加权的计算方法编制而成的股价指标。虽然只选择了部分股票，但深证指数仍然可以代表整个深圳证券市场上的股票价格走势。</p><h3 id="深成指R">3.1.3&emsp;深成指R</h3><p>深证成份指数（收益），全收益指数考虑了上市公司分红的影响，这类指数除了反映股价波动外，还假定篮子内所有股票的现金分红都用于再投资产生收益。 因此，从定义上，我们也可以大致判断出全收益指数的走势要好于价格指数。尤其是股息率比较高的指数更是如此。</p><h3 id="深证综指">3.1.4&emsp;深证综指</h3><p>深证综指是综合指数，包含了所有在深圳上市的股票，即包括了A股和B股，目前数量已超过2000只。深证综指对股票不作筛选，样本股数量不固定且不实施定期调整同时采用总市值来计算，可投资性较弱。</p><h3 id="创业板指">3.1.5&emsp;创业板指</h3><p>由创业板中市值大、流动性好的100只股票组成，反映创业板市场层次的运行情况。  </p><h3 id="中小板指">3.1.6&emsp;中小板指</h3><p>中小板指遴选了中小板市场中市值大、流动性好的100只A股作为样本，反映中小板市场的运行情况。</p><h3 id="恒生指数">3.1.7&emsp;恒生指数</h3><p>是以香港股票市场中的50家有代表性的上市股票为成份股样本，以其发行量为权数的加权平均股价指数，是反映香港股市价幅动趋势最有影响的一种股价指数。</p><h3 id="其他">3.1.8&emsp;其他</h3><ul><li>国企指数</li></ul><p>国企指数，又称H股指数，全称是恒生中国企业指数，由香港恒生指数服务有限公司编制和发布的。<br>是要为投资者提供一个反映在香港上市的中国H股企业的股价表现的指标。</p><ul><li>深次新股</li></ul><p>次新股被定义为上市一个月且不满一年的股票，更严谨的说法是新股开板之后但上市未满一年的股票。另外也有将条件放宽的情况，上市不满3年都算次新股。<br>深次新股指数选择深交所上市时间超过45天且不满一年的A股，调整样本股的频率为每日调整。</p><ul><li>新指数</li></ul><p>深证新指数由深圳证券交易所委托深圳证券信息有限公司编制、维护和管理，是反映未来多层次市场指数体系的基准指数，目的是为了配合股权分置改革的推进，适应当前的市场需求，建立和健全有特色的、有深度的、覆盖面广的指数体系，反映深市全流通股票的总体走势。</p><ul><li>B股指数</li></ul><p>上证B股指数，其样本股是全部上市B股。</p><ul><li>成份B指</li></ul><p>深证成份B股指数。</p><ul><li>创新成指</li></ul><p>选取了全国股转系统（新三板）创新层中具有代表性的公司股票作为成份股，指数样本覆盖创新层85%左右的市值，以反映创新层的整体表现。</p><ul><li>三板龙头、三板制造、三板服务、三板医药</li></ul><p>与创新成指共称新三板5只引领指数。<br>这四大指数和传统的二级市场指数相比创新点主要有：采取营收规模+研发费用率的指标来进行龙头公司遴选囊括了优质但无交易或交易不活跃的公司，扩大优质标的范围；不采用市值进行度量，规避了新三板公司市值失真以及交易间隔长的问题；样本股审核周期每半年一次，一定程度上保证了样本股的稳定性；设置了备选名单，考虑了新三板公司摘牌频繁的市场特有问题，用备选名单保证了指数能够快速调整，加强指数的连续性。</p><ul><li>台湾加权</li></ul><p>发行量加权股价指数，是由台湾证券交易所所编制的股价指数。</p><ul><li>富时：台湾50指数</li></ul><p>是台湾证券交易所与富时指数（FTSE）于2002年10月29日共同合作编制的一个指数，该指数涵盖台湾证券市场中市值前五十大的上市公司，统称台湾50指数成分股。</p><ul><li>富时：大中华指数</li></ul><p>The FTSE Greater China Index is derived from the FTSE Global Equity Index Series (GEIS) and<br>comprises Large and Mid Cap stocks from 3 markets: China, Hong Kong and Taiwan. The index<br>combines constituents of the FTSE China Index, the FTSE Hong Kong Index and the FTSE<br>Taiwan Index. An All Cap version is also available.</p><ul><li>中国A50、A200</li></ul><p>富时中国A50、A200指数，是中国内地A股市场的一个指数，是富时中国指数系列的旗舰指数。包含了在上海或深圳证券交易所上市的股票中市值最大的50/200家A股公司。</p><ul><li>中国A-H50</li></ul><p>富时中国A-H50指数是富时罗素首个囊括中国内地和香港上市公司股票的指数，其最大特色在于采用A/H价差策略，对于在A股与港股同时挂牌交易的股票，指数选择买相对价格更低的股票，捕捉A/H股间的相对价格优势。  </p><h2 id="按规模命名：">3.2&emsp;按规模命名：</h2><h3 id="中证">3.2.1&emsp;中证</h3><ul><li>沪深300</li></ul><p>排名1-300公司，成立的比较早，所以它的命名很独特叫沪深300， 而没有叫中证300。<br>涵盖了沪深两个证券市场上最具有代表性的300只股票，可以反应整个内地证券市场的价格走势。</p><ul><li>中证500</li></ul><p>沪深两市排名从301开始到800的这500只股票。</p><ul><li>中证800</li></ul><p>沪深300和中证500的成分股之和。</p><ul><li>中证1000</li></ul><p>排名从801到1800这1000只股票，而不是排名从1到1000，规模比较小的股票。</p><h3 id="上证">3.2.2&emsp;上证</h3><ul><li>上证50</li></ul><p>上交所前50，规模最大、流动性更强，<strong>大盘股</strong>。</p><ul><li>上证180</li></ul><p>上证180是对原上证30指数进行了调整并更名而成的，其样本股是在所有A股股票中抽取最具市场代表性的180种样本股票。上证180成分股市值占据了总市值的80%左右，分红总额的90%以上，充分反映了上海证券市场的概貌和运行状况。</p><ul><li>上证380</li></ul><p>由380家规模适中、成长性好、盈利能力强公司组成，与上证180指数、上证50指数不同，上证380指数定位于中盘股指数，面向的是<strong>中等规模市值</strong>的股票，由交易活跃、有增长潜力的股票构成，能够代表市场中中等规模股票的整体表现。</p><ul><li>科创50</li></ul><p>上证科创板50成份指数,由上海证券交易所科创板中市值大、流动性好的50只证券组成，反映最具市场代表性的一批科创企业的整体表现。</p><h3 id="深证">3.2.3&emsp;深证</h3><ul><li>深证100R、深圳100</li></ul><p>在深交所全部股票中挑选出规模最大、流动性最好的，排名前100位的股票，它们组成了一个篮子，叫深证100指数，<strong>大盘股</strong>。<br>带<code>R</code>字母的为全收益指数。</p><ul><li>深证300</li></ul><p>深圳证券交易所300股价指数，是深圳证券交易所主要的成分指数之一，由300只规模大、市场份额高、交易活跃的股票组成，指数反映了深圳市场具备代表性的上市公司股价的变动走势。</p><ul><li>创业板50</li></ul><p>选取创业板排名靠前的50只股票组成指数样本股。</p><ul><li>中小300</li></ul><p>选取市值排名靠前的300只非ST（非ST股票就是正常的股票，没有被退市风险警示提醒的股票）中小板上市股票构成，体现了深市中小板市场特征。</p><h3 id="央视50">3.2.4&emsp;央视50</h3><p>央视财经50指数，选出50家符合中国社会发展价值观且体质稳健的公司。<br>以“成长、创新、回报、公司治理、社会责任”五个维度为基础，筛选出各个维度最优样本公司进行投资。由于它众智、多维的选股特点，也被称为“聪明50”。</p><h1 id="国外常见指数">4&emsp;国外常见指数</h1><h2 id="日经指数">4.1&emsp;日经指数</h2><p>日经平均指数又名日经225，是由日本经济新闻社推出的东京证券交易所的225品种的股价指数，是基于日元的价格加权指数。</p><h2 id="道琼斯工业平均指数">4.2&emsp;道琼斯工业平均指数</h2><p>价格加权指数，指数的鼻祖，美国的查尔斯·亨利·道在1896年创造了华尔街第一支指数，道琼斯指数，由12个上市公司的股票构成，时光荏苒，当时的12个上市公司，如今只剩下通用电器一家，道琼斯指数也分化为现在主要的四个分支：<br>1、工业股票价格平均指数。它由30种有代表性的大工商业公司的股票组成，且随经济发展而变大，大致可以反映美国整个工商业股票的价格水平，这也就是人们通常所引用的道琼斯工业平均指数。人们通常所说的道琼斯指数是指道琼斯指数四组中的第一组，即：道琼斯工业股票价格平均指数。<br>2、运输业股票价格平均指数。它包括着20种有代表性的运输业公司的股票，即8家铁路运输公司、8家航空公司和4家公路货运公司。<br>3、公用事业股票价格平均指数。是由代表着美国公用事业的15家煤气公司和电力公司的股票所组成。<br>4、平均价格综合指数。它是综合前三组股票价格平均指数65种股票而得出的综合指数，这组综合指数显然为优等股票提供了直接的股票市场状况。  </p><p>现在最广为人知的，就是第一种，道琼斯工业平均指数。</p><h2 id="纳斯达克综合指数">4.3&emsp;纳斯达克综合指数</h2><p>在纳斯达克股票市场上市的所有公司，总共有3300多只股票。因此，它的基础要比道琼斯指数广泛得多。然而，纳斯达克(NASDAQ)科技股高度集中，因此综合指数对该行业的敏感度高于其它行业。综合指数不应该与纳斯达克100指数混淆，后者是纳斯达克市场上100家最大公司的指数。</p><h2 id="标准普尔500">4.4&emsp;标准普尔500</h2><p>市值加权指数，记录了美国500家上市公司的一个股票指数。它们来自经济的各个领域，股票在纽约证券交易所或纳斯达克上市。标普500指数成份股公司的总市值约占美国股市总市值的75%。<br>具有采样面广、代表性强、精确度高、连续性好等特点。</p><h2 id="英国富时">4.5&emsp;英国富时</h2><p>富时100指数（FTSE 100 Index），全称伦敦股市《金融时报》100种股票平均价格指数（Financial Times Stock Exchange 100 Index），又称伦敦金融时报100指数，涵盖在伦敦证券交易所交易的上市的市值最大的100支股票。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-02-26-gu-piao-jie-ge-zhi-shu-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《富爸爸，穷爸爸》摘录</title>
      <link>https://chengpengzhao.com/2021-02-21-fu-ba-ba-qiong-ba-ba-zhai-lu/</link>
      <guid>https://chengpengzhao.com/2021-02-21-fu-ba-ba-qiong-ba-ba-zhai-lu/</guid>
      <pubDate>Sun, 21 Feb 2021 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言——20年后的今天&quot;&gt;1&amp;emsp;前言——20年后的今天&lt;/
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言——20年后的今天">1&emsp;前言——20年后的今天</h1><ul><li>变革的十字路口，悲观主义情绪，不确定性</li><li>富人不会为钱工作 ，储蓄是失败者所为</li><li>你的房子并非资产，更多的时候房子是负债</li><li>高收入者≠真正的富人</li><li>财商教育的重要性</li></ul><h1 id="富人不为钱工作">2&emsp;富人不为钱工作</h1><ul><li>富人让钱为他工作，穷人和中产为钱而工作</li><li>出于恐惧的心理，人们才想找一份安稳的工作</li><li>恐惧和贪婪：给他们更多的钱，他们就会以更高的开支重复这种循环，正所谓“老鼠赛跑”</li><li>他们的感情代替了他们的思想</li><li>欲望： 希望拥有更好更漂亮更有趣更令人激动的东西</li><li>工作只是试图用暂时的办法来解决长期的问题</li><li>价格上涨的原因是由无知引起的贪婪和恐惧</li></ul><h1 id="为什么要教授财务知识">3&emsp;为什么要教授财务知识</h1><ul><li>只有知识才能解决问题并创造财富，那些不是靠财务知识挣来的钱也不会长久</li><li>从长远看，重要的不是你挣了多少钱，而是能留下多少、及能够留住多久</li><li>明白资产和负债的区别、并购买资产： 资产是能把钱放进我口袋里的东西、负债是把钱从我口袋里取走的东西</li><li>真正的问题在于他们选择的消费方式，只有运用财务知识才能解决这些问题</li><li>决定买昂贵房子对生活的冲击：1. 失去了用其他资产增值的时机；2. 本可以用来投资的资本用于房子各项费用；3. 失去受教育的机会：因为没钱投资，就不会去投资，无法获得经验，永远不会成为“成熟投资者”</li><li>财富：如果我今天停止工作、我还能活多久？</li></ul><h1 id="关注自己的事业">4&emsp;关注自己的事业</h1><ul><li>你的事业重心是你的资产项，而不是你的收入项</li><li>某人实际的净资产通常比认为的要少得多，因为通过缴税、每获得一次收益政府就会拿走一份</li><li>不要购买负债或是一旦被带回家就没有价值的个人用品</li><li>资产有哪些：  股票、债券、产生收入的房地产、票据（借据）、 版税（音乐手稿专利）、其他</li><li>财务知识的重要性，要懂会计和现金管理</li><li>先构筑资产项，再才能用增加的现金流消费</li></ul><h1 id="税收的历史和公司的力量">5&emsp;税收的历史和公司的力量</h1><ul><li>富人并未被征税，是中产尤其是受过良好教育的高收入中产在为穷人支付税金</li><li>政府花的钱和雇的人越多，他的机构就会越大，就需要征收更多的税以维持运营</li><li>无论“劫富”的呼声有多高、富人总有办法从中脱身</li><li>你在为谁工作？你使谁更富了？</li><li>财商由4各方面的专业知识构成： 1. 会计     2. 投资     3. 了解市场     4. 法律</li><li>富人利用公司的优势来避税</li></ul><h1 id="富人的投资">6&emsp;富人的投资</h1><ul><li>自我怀疑与缺乏自信通常会阻碍前进的步伐</li><li>人们往往依靠勇气而不是智慧去取得领先位置</li><li>陈旧的思想是最大的债务</li><li>金钱不是真实的资产、它是我们大家都认可的东西，我们唯一的最重要的资产是我们的头脑</li><li>会计： 理解数字的能力 ； 投资： 以钱生钱的科学；  了解市场： 供给与需求的科学；  法律： 按规则来“游戏”</li><li>能使富者更富的最好交易总是为那些精通游戏规则的人准备的</li><li>如果你清楚自己在做什么，就不是在赌博；如果你把钱投进一笔交易然后只是祈祷，才是在赌博</li><li>如何成为自己创造投资机会的投资者： 寻找其他人都忽视的机会、增加资金、把精明的人组织起来</li><li>风险无处不在，要学会驾驭风险而不是回避</li></ul><h1 id="学会不为钱工作">7&emsp;学会不为钱工作</h1><ul><li>他们只有一项技能，所以挣不到大钱</li><li>对于许多知识，你只需要知道一点就够了</li><li>工作一词就是比破产强一点儿</li><li>工人付出最大努力以免于被解雇、而雇主提供最低工资以防止工人辞职</li><li>如果我被这一行业抛弃，我的技能对其他行业便毫无用处</li><li>许多才华横溢之人之所以贫穷，是因为他们只是专心于做好产品，而对商业体系却知之甚少</li><li>他们只将注意力集中在提高做汉堡包的技能上，却不注意提高销售和配送汉堡包的技能</li><li>成功必备的3种管理技能有： 对现金流的管理；对系统的管理（个人时间管理）；对人员的管理（人事管理）</li><li>最重要的专门技能是销售和对市场营销的理解</li><li>精通专业技能既是优势也是弱点</li><li>要想真正富有，我们既要不吝付出也要学会索取</li><li>想要得到金钱，必须先付出金钱</li><li>罗伯特寻求的是不断学习新技能，而不像许多人那样寻求专业化</li></ul><h1 id="克服困难">8&emsp;克服困难</h1><ul><li>富人与穷人主要差别在于他们处理恐惧心理的方式不同</li><li>五个需要克服的障碍： 1. 恐惧      2. 愤世嫉俗     3. 懒惰     4. 不良习惯     5. 自负</li><li>对于失败者，失败则会击垮他们。大多数人来说，财务上不成功是因为亏钱造成的痛苦远大于致富带来的乐趣</li><li>成功的投资者在最初肯定不是追求平衡的，而是必须首先集中于一点</li><li>不要让谣言和杞人忧天的怀疑加剧我们的恐惧和疑虑</li><li>未经证实的怀疑和恐惧会使人们成为愤世嫉俗者。愤世嫉俗者抱怨现实，而成功者分析现实</li><li>他们把忙碌作为逃避问题的借口。这是懒惰最普遍的表现形式，一种通过忙碌掩饰下的懒惰</li><li>负罪感比欲望要糟，因为负罪感抢走了灵魂</li><li>学会先支付给自己，让支付的压力成为动力</li><li>我知道的东西给我带来金钱，我不知道的东西使我失去金钱</li><li>许多人试图用傲慢来掩饰无知</li></ul><h1 id="开始行动">9&emsp;开始行动</h1><ul><li>金矿到处都是，但大部分人没有经过相应的培训，所以发现不了他们</li><li>唤醒理财天赋的十个步骤：<br>  1.找一个现实的理由，利用精神的力量；如内心深处“想要”和“不想要”的结合体： 不想一生耗在工作上，不想做一个打工仔，想要以自己喜欢的方式生活，想要金钱为自己工作……促使自己前进的动力必须足够强大<br>  2.每天做出选择（时间、金钱、知识）；首先投资于教育，谦虚地阅读或倾听大佬们说过的话。骄傲自大或吹毛求疵的人往往是缺乏自信而不敢冒险的人<br>  3.慎重地选择朋友；不要听贫穷的或是胆小的人的话，保持开放的心态，不盲目从众；人们总是匆匆忙忙去赶那已经过去的浪头，往往又会被新的浪头淘汰出局<br>  4.快速学习，掌握一种模式、然后再去学习一种新的模式<br>  5.首先支付自己，能否自律是将富人穷人与中产阶级区分开的首要因素；不要背负数额过大的债务包袱，要保持低支出。资金短缺时，让压力去发挥作用，而不要动用储蓄或资本。不鼓励自我牺牲与理财紧缩<br>  6.给经纪人以优厚的报酬——好建议的力量；学会管理比自己更聪明的人<br>  7.不但要看到投资回报率，还要能够学会及时收回投资以得到额外资产（回本）<br>  8.用消费的欲望来激发并利用理财天赋去投资；要成为金钱的主人，首先要比它更精明<br>  9.对英雄的崇拜；向英雄人物学习(沃伦·巴菲特、乔治·索罗斯、特朗普…)<br>  10.先予后取；要勇于付出，你教给别人的越多、你学到的也越多；享受给予的快乐，而不是为了得到而给予</li></ul><h1 id="具体要做的事情">10&emsp;具体要做的事情</h1><ul><li>停下手头的活儿并评估；不要做那些无效的事，找一些有效的事去做</li><li>寻找新的思想： 投资的灵感、与众不同的主张…学习之后运用到实际</li><li>找一些做过你想做的事情的人；向他们请教诀窍和技巧</li><li>上辅导班、读书、参加研讨会</li><li>提出多份报价（购买房产时）；除非有另一处同样的交易作参照，否则很难知道什么价格才是“合适”的；必须到市场上去和许多人谈，做许多报价、还价、谈判、拒绝或接受；学会用“免责条款”</li><li>每月在某一地区慢跑、散步（为了发现好房产）；一桩交易要赢利，必须具备的两个条件：廉价、有变化</li><li>购买特价商品；利润是买来的，而不是卖出来的；利润在购买时就已确定，而不是在出售时获得的</li><li>先寻找想买进的人，再去找想卖出的人；买下馅饼并把它切成小块</li><li>考虑大生意</li><li>学习前人经验</li><li>行动的人总会击败不行动的人</li></ul><h1 id="最后">11&emsp;最后</h1><ul><li>三种收入： 劳动性收入、投资组合收入（如股票债券）、被动收入（如房产投资）</li><li>实现财务自由的关键取决于一个人将劳动性收入转化成被动收入或投资组合收入的能力</li><li>风险来自于你不知道自己在做什么</li><li>每一天，面对每一美元，你都在做出自己是成为一个富人、穷人还是中产阶级的抉择</li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2021-02-21-fu-ba-ba-qiong-ba-ba-zhai-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>东方时尚驾校学车记录</title>
      <link>https://chengpengzhao.com/2020-11-14-dong-fang-shi-shang-jia-xiao-xue-che-ji-lu/</link>
      <guid>https://chengpengzhao.com/2020-11-14-dong-fang-shi-shang-jia-xiao-xue-che-ji-lu/</guid>
      <pubDate>Sat, 14 Nov 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;更新于20
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><br><br></p><blockquote><p><em>更新于2020-12-22 22:02:03</em></p></blockquote><h1 id="前言">1&emsp;前言</h1><p>我从小对车并没有太大兴趣，刚上大学那会寒暑假闲得很也不想去学车，看到朋友们都拿到了驾照也没觉得羡慕啥的。也许就是因为懒吧，当时想做的事太多了，认为考了驾照也基本上不会去开车（家里没车），就把学车这件事一直放着了。 前一段时间忽然想到，明年就要工作了、是不是该趁这毕业前最后几个月考一波驾照，万一工作用得到呢。  </p><p>因为是在帝都，稍微了解了一下后选择了评价还行的<strong>东方时尚驾校</strong>，虽然有点贵但还是挺规范的。然后就是<strong>报名</strong>了，常见的有预约计时班、速成班、假日班： </p><ul><li><strong>预约计时班</strong>最便宜也比较灵活，首选这个；</li><li><strong>速成班</strong>需要工作日有时间，适合假期时报；</li><li><strong>假日班</strong>在周末，需要连续练几个周末，对方安排时间所以不用预约（第一次好像还是要自己预约）。  </li></ul><p>我报的是假日班，但总感觉有点坑，当初报预约计时班就好了。  </p><p>然后是<strong>驾照类型</strong>的选择，无脑手动挡(<strong>C1</strong>)就行，就算自动挡(C2)便宜1000块我也不会报、何况价钱还一样，选覆盖车型更多的C1不香嘛。  </p><p>还有就是<strong>车型</strong>选择，有伊兰特和宝来两种，推荐那种车多选哪种，我选的<strong>伊兰特</strong>。</p><ul><li>报名流程</li></ul><p><strong>11月06日</strong>，前往离学校最近的东方时尚报名点，带上身份证、学生证（可优惠300元）、1寸照片（只用到了1张，我当时带了8张过去- -），交完钱签完字会给你一本教材和<strong>东方时尚APP</strong>的学员账号（学车过程这个APP用的挺多的），然后就可以回去看科目一的视频课程了。</p><h1 id="科目一">2&emsp;科目一</h1><h2 id="准备阶段">2.1&emsp;准备阶段</h2><ol><li>跟着APP的视频过一遍，第一遍一定要认真看书（只看书都行、但推荐还是听一下、有助于抓住重点），一般流程： 看完一课时视频——看一遍书对应章节——做课后题并更正——在书中找到错题知识点对应位置；  </li><li>看完视频了，立马下载<strong>交管12123</strong>APP注册并预约科目一考试（好像必须要看完才能报名科目一），不过太快了可能显示还没完成课程需要等待一段时间才能预约（系统刷新较慢）；  </li><li>东方时尚APP上的1500多道题<strong>分章节</strong>做一遍，一个章节一个章节做完——对答案——翻书，我觉得一味刷题不看书实在很低效：题目是会变的，而每道题的答案都能在书上找到，为何不看书记知识点呢；  </li><li>随便下个驾考APP，比如<strong>驾考宝典</strong>，所有题分章节做一遍，按照3.的步骤；</li><li>总结比较难记的考点，所有错题刷一遍，随缘刷几份模拟考。如果前面步骤做到位了模拟考真的是随便过，我一共只模拟考了4次，东方时尚APP得分99\98，驾考宝典97\97，如果得分在<strong>95</strong>以下，说明对书本不够熟悉，请把书从头到尾认认真真有重点地看一遍、记一遍（刷了那么多题总知道重点在哪了吧）；</li></ol><h2 id="个人用复习tips">2.2&emsp;个人用复习tips</h2><p>考前必须要看的是<strong>扣分</strong>和<strong>各种处罚</strong>两处，这是最难记的一部分了（哪种行为扣多少分、有哪些处罚、罚款多少元），还有就是各种<strong>数字</strong>相关的知识点，比如日期、速度、距离…</p><pre><code>- 不能一开始学的：大型客车A1、牵引车A2、中型客车B1- 小型车C1，可以开自动挡C2、低速载货C3、三轮汽车C4- 6、10、长期有效（驾驶证）、4.9视力- 未满几年不得申请驾驶证：    1. 醉酒 营运机动车、10年    2. 醉酒 机动车、5年    3. 毒品、3年    4. 驾驶许可依法撤销（不正当取得）、3年    5. 吊销驾驶证、2年    6. 虚假材料申领、1年## 罚款### 20~200元1. 未带学习驾驶证明2. 使用原驾驶证3. 未贴实习标志、保险标志4. 违法其他实习期规定（单独上高速）、交通法规5. 故意遮挡车牌号等6. 信息变更未申报（去驾照核发地）### 200~500元1. 证被扣、欺瞒领证2. 不参加审验3. 事故未自行撤离造成堵车（200元）4. 不适合驾驶强行开车### 1000~2000元1. 饮酒（扣6月证）、饮酒再犯（拘留）2. 伪造合格、保险标志（1000~3000）### 2000~5000元- 号牌、机动车登记证书、行驶证、驾驶证方面### 200~2000元1. 超速50%（吊销证）2. 非法报警器3. 无证驾驶、交给无证的人驾驶（并处吊销自己的证）4. 事故后逃逸（不犯罪）5. 开报废标准车（吊销证）6. 其他较严重违法（不构成犯罪）、可并处15日以下拘留## 日期- 驾驶证有效期满前90日内换证- 换证、30日内到核发地- 审验、计分周期结束30日内- 延期办理：不超3年- 学习驾驶证明、3年有效- 1年无累积记分、可延长审验期- 扣12分后、15日内参加学习教育- 两次扣12分，考完科目一还要在10日内考科目三- 大、中货客车每1年体检审查一次## 扣分- 12分： 车型不符、饮酒、车号牌驾驶证伪造变造、高速路倒车、超速50%- 6分： 证暂扣驾车、信号灯、高速公路停车、占用应急道、欺瞒领证、疲劳驾驶、不避让校车（三条车道时最左侧可超越、其他等待）- 3分： 高速路过低速、不该驶入高速路、不按车道人行道标志标线（如逆行、禁停处停车）、停车未设警告和灯光、车未年检- 2分：交叉路口（无禁停标志）、电话、安全带（高速、一般道路罚款50）、堵车时穿插超车- 1分： 灯光、会车、长宽高、未放安检保险标志、未带证（行驶、驾驶）## 距离、速度（km/h）等数字- 车后50~100m设警告标志（高速150m）- 夜间、150m改用近光灯- 城市30公路40（无中心线）、城市50公路70（有）- 软牵引：4~10m- 高速路2车道（最低从左至右100、60），3车道（最低110、90、60）- 车速&gt;100、100m，其他不得小于50m- 能见度200m，60车速 100m距离，能见度100m，40 50m，能见度50m， 20- 不得停车：汽车站等 30m、交叉路口等 50m- &gt;20mg/100mL 饮酒、 &gt;80mg/100mL 醉酒- 连续开4h、休息20min- 白色菱形，预告前方30-50m有人行横道。</code></pre><h2 id="考试阶段">2.3&emsp;考试阶段</h2><p><strong>11月13日</strong>，去东方时尚主校区考科目一，我报的是下午考试，上午搭免费班车大概11点半到驾校。  </p><ol><li>首先排队<strong>体检</strong>，带个身份证就行、要交20元（体检下视力、有无色盲、拍个照）；</li><li>体检完请马上去考场<strong>取号、录指纹</strong>，取号越晚考试的排队时间越长，录指纹是考试验证要用，办完这两项再去吃饭！（我是100多号，还算比较靠前）；</li><li>吃完饭可以在驾校逛一逛，东方时尚环境还算可以的，而且有很多动物、甚至有种在动物园的错觉；</li><li>13:00之前回到考场，之后会讲考试流程相关内容和注意事项注意听，前面可能还有考前复习看心情听一听；</li><li>排队、13:30开始考试，一般10来分钟可以做完，我是<strong><em>98分</em></strong>（错了两道判断）。</li><li>考完试不要想着马上回去，立马<strong>打开东方时尚APP</strong>并<strong>预约VR基础训练</strong>，一共8课时，如果下午考科目一可以预约16:00-20:00（效率至上的话推荐<strong>上午考科目一</strong>，然后预约12:00-16:00和16:00-20:00的VR训练，这样一次就可以完成8课时，下次就直接预约实车操作了）。</li></ol><h1 id="科目二训练">3&emsp;科目二训练</h1><h2 id="VR基础训练">3.1&emsp;VR基础训练</h2><p>不得不说这VR设备还是挺高端的，用的时候千万注意别弄坏了（虽然戴久了有点晕）</p><h3 id="驾驶基础（1-4课时）">3.1.1&emsp;驾驶基础（1-4课时）</h3><p>第一次课重点是<strong>控制速度</strong>和<strong>方向盘</strong>，这也是科目二的基础。</p><h4 id="起步前调整">3.1.1.1&emsp;起步前调整</h4><p>坐上驾驶座，首先调节座椅和头枕位置，重要的是选取<strong>标准</strong>（或者说确定调节时的变量与不变量），我们需要根据几条总的原则合理规划调节顺序：</p><ol><li>座椅高低调节，不妨碍仪表盘（若方向盘上下不可调）及前方视野前提下<strong>尽量低</strong>，眼睛大概在侧窗中央；</li><li>座椅靠背角度调节，110度左右，舒适为准，并注意坐好时脑袋离靠背是有一定距离的；</li><li>头枕高度调节，后脑袋中央靠在头枕上正好也是中间位置；</li><li>座椅前后调节，油门踩到底时膝盖有弯曲（有余力去踩）前提下<strong>尽量靠后</strong>；</li><li>方向盘前后调节，手伸直搭在方向盘上（12点方向）正好是手腕部分（戴手表处），若方向盘前后不可调，结合3.调节座椅前后；</li><li>方向盘上下调节，不妨碍仪表盘视野为准，方向盘主轴延长线大概在脸部，若方向盘上下不可调，结合1.调节；</li><li>安全带高低调节，卡主肩胛骨、胸部，横向在肚脐一下</li></ol><h4 id="方向盘使用">3.1.1.2&emsp;方向盘使用</h4><ul><li>左右最多可转一圈半；</li><li>两只手对称的握在方向盘两侧，9点和3点钟位置，拇指自然搭放在方向盘内圈壁上；</li><li>打多少回多少，该迅速打方向时时不要犹豫；</li></ul><ol><li>左90度、180度，右手转、左手虚握位置不动；</li><li>左一圈，右手转半圈、左手松，并在快转到半圈时从上方越过右手握住9点方向，接着右手松、左手转半圈，完成后右手再握住9点方向；</li><li>向左打到底，结合2.和1.的操作；</li></ol><h4 id="踏板、变速杆等操纵装置的使用">3.1.1.3&emsp;踏板、变速杆等操纵装置的使用</h4><ul><li><p>离合踏板（手动挡）：左脚只踩离合用，踩下时要快速、一踏到底，不要没事把脚放在离合踏板上；推荐开始练的时候就<strong>悬空踩抬离合</strong>，可能书上、部分教练会说脚跟放地上，但标准动作是悬空，最多踩到底或半联动状态时脚跟才固定住（要点：踩下要狠，抬起要缓，抖动要稳）；</p></li><li><p>制动踏板：右脚默认虚放在刹车上，脚跟固定在刹车正下方、斜踩油门正踩刹；</p></li><li><p>变速操纵杆： 换挡前必须离合踩到底（自动挡踩刹车）！加档时必须逐级加！ 左右晃动确定是否在空挡，手掌轻握球头，随着推拉方向的变化，掌心贴球头的方向适当变化；</p></li><li><p>驻车制动器（手刹）：上抬时一步到位、下放时稍上提再按按钮、往下放<strong>到底</strong>；</p></li><li><p>灯光、刮水器等：手不离开方向盘的前提下用手指去拨动；</p></li></ul><h4 id="点火着车">3.1.1.4&emsp;点火着车</h4><ul><li>插钥匙点火前注意： 1. 先踩离合再点火；2. 手刹没松；3. 空挡状态</li><li>步骤：踩离合——点火——挂一档——放手刹——松离合、慢慢给油（先调档位再操作手刹）；</li></ul><h4 id="停车熄火">3.1.1.5&emsp;停车熄火</h4><ul><li>步骤：踩刹车——踩离合（速度很低时）——挂空挡——拉手刹——松刹车离合——钥匙关火；</li></ul><h4 id="控速度">3.1.1.6&emsp;控速度</h4><ul><li>一定要找到半联动状态的感觉；</li></ul><h4 id="曲线行驶">3.1.1.7&emsp;曲线行驶</h4><ul><li>1.以先左后右为例，靠右行驶，到弯道时，左车头碰到曲线右边线时，马上向左打一圈方向，然后控制角度使左车头始终贴着曲线的右边线行驶。2. 当行驶到左转弯向右转弯过渡段，左车头与曲线左边线相碰时，迅速回正方向，直到右车头碰到曲线左边线时，向右打一圈方向，然后控制方向驶右车头一直贴着左边线行驶。3. 当车头正对出口时，回正方向。切记：向左转弯时，要通过左后视镜观察车身与边线的距离，保持合适的距离;同理向右转弯时，观察右后视镜。右转弯时，车身尽量靠左;左转弯时，尽量靠右。</li></ul><h3 id="VR训练2（5-8课时）">3.1.2&emsp;VR训练2（5-8课时）</h3><p><strong>11月21日</strong>，今年冬天北京的第一场雪，早上骑车去食堂吃早餐忘带手套把我冻傻了，一想到还要去学车瞬间没动力了，还好下次课才是实车操作，希望下周有个好天气吧。</p><h4 id="后视镜调节">3.1.2.1&emsp;后视镜调节</h4><p>上车后第一步调好坐姿，然后就是三块后视镜的调节，<strong>非常重要</strong>的一步，后视镜没调好倒车入库简直没法进行下去。  </p><ul><li><p>车内后视镜：调整到一瞥（头不动）可以看到车后窗情况，保证镜子里的车后窗视野在中央且尽可能大就行；  </p></li><li><p>左后视镜：上下位置天空占<code>1/2</code>、地面占<code>1/2</code>（远处水平线在中央），横向车身占<code>1/4</code>、路面<code>3/4</code>，此时前门把手恰好在后视镜右下角边缘处。可以适当减少车身露出的比例以减少视野<strong>盲区</strong>（不要完全依赖后视镜、记得扭头！）；  </p></li><li><p>右后视镜：上下位置天空占<code>1/3</code>、地面占<code>2/3</code>，横向车身占<code>1/4</code>、路面<code>3/4</code>，可以适当减少车身露出的比例；</p></li><li><p>针对<strong>科目二</strong>的后视镜调节： 科目二中很多项目要看地面边线，后视镜中地面占比要更大。左右后视镜：车身占比<code>1/4</code>左右，前门把手出现在后视镜右（左）下角；</p></li></ul><h4 id="倒车入库">3.1.2.2&emsp;倒车入库</h4><ul><li><p>感受车轮位置：左前轮，在驾驶座放左脚处（不踩离合时），一般都会有个左脚休息位置；或者说是车A柱右侧20cm处（手掌伸开时中指到大拇指距离），3m宽车道若想靠中间行驶，一般A柱离路面白线10cm左右。  右前轮，引擎盖中间处。</p></li><li><p>回正： 哪边在变宽、方向盘往哪边打（变窄、反方向打）；</p></li><li><p>方向盘往一侧打时，可以无视另一侧相邻物体（不会碰到），只需要注意转弯一侧的车后轮（有转弯半径差）。</p></li><li><p>倒车入库时方向打满的时机过早或过晚如何补救？ 过早：发觉时立即回正方向、继续倒车到一定距离，再按原计划打满。 过晚：发觉时立即回正方向，之后前进一段距离，再按原计划打满。</p></li><li><p>倒车入库流程：</p><ol><li>驶入倒车入库区域，注意不要压线：车头右边缘碰到右侧黄虚线向右打一圈、正对停车位左尖点时回正方向、车头中部与黄实线重合时往左打一圈、车正回正、前轮过线停车（车窗中部位置）；</li><li>右倒库：注意看左后视与地面黄线判断右打满时机（如后视镜距黄虚线15cm左右）、观察右后视镜、停车位尖角距车15cm左右时回正、尖角消失时再打满、直至车边线与黄线平行、观察车后缘边线接触黄线底部时停车；</li><li>左出库： A柱右方20cm处与黄线相交时左打满、车正回正、前轮越线停车；</li><li>左倒库、右出库类似；</li><li>驶出：黄线在车窗中部时左打满、车前窗右下角与道路中央黄线相交时回正、再右转进入道路。</li></ol></li></ul><h2 id="科目二实车训练">3.2&emsp;科目二实车训练</h2><h3 id="9-12、13-16课时">3.2.1&emsp;9-12、13-16课时</h3><p><strong>11月28日、29日</strong>，上车之后感觉果然和VR完全不一样：首先是方向盘，左右打时会明显感觉阻力变化。离合也比想象中距离要长、半联动的感觉要重新体会，切记要<strong>慢抬离合</strong>、不然就熄火，尤其是在坡上。  第一天把侧方停车、直角转弯和坡道定点给教了，顺便练了下曲线行驶和8字路，第二天先练了n把倒车入库、之后直接进模拟考场走流程了，不得不说强度还是挺大的。<br>坐上驾驶座：<strong>调座椅前后和靠背、调节后视镜、系安全带</strong>。</p><h4 id="直角转弯">3.2.1.1&emsp;直角转弯</h4><p>考试时在坡道定点之后，这里以左转弯为例</p><ul><li><p>尽量靠右：人对地面白箭头直行（或者说发动机盖右侧1/3处压线、此时离右侧线大约30cm）；</p></li><li><p>打满时机：当前进到方向盘在直角一侧的直线延长线上时迅速打满方向（注意控制车速）；</p></li><li><p>打左转灯： 进入弯道前开转向灯（一般坡道走完到平地就开始打灯）、白箭头完全看不到之后关转向灯；</p></li></ul><h4 id="侧方停车">3.2.1.2&emsp;侧方停车</h4><p>倒车入库结束驶出区域、左转弯180度后进入侧方停车区域，（之后是坡道定点）</p><ul><li><p>驶入考试区域：和倒车入库那块相似，注意不要压到后面一个侧方停车位的实线就行；</p></li><li><p>靠右行驶：人对准箭头，和直角转弯一样，箭头消失时停车换倒挡开始倒车；</p></li><li><p>向右打满：当右后视镜中库角消失时迅速打方向盘；</p></li><li><p>回正方向：观察左后视镜，看到两条虚线（或者看到内库角）时回正；</p></li><li><p>向左打满： 前车门把手完全越过黄虚线后立即打满方向，待车正时停车（方向盘保持打满状态）；</p></li><li><p>驶出区域： 挂1档、开<strong>左转向灯</strong>，引擎盖右侧点碰到黄线时回正方向，引擎盖左侧1/3碰左边线时向右打一圈，车正回正；</p></li></ul><h4 id="坡道定点停车起步">3.2.1.3&emsp;坡道定点停车起步</h4><ul><li><p>靠右行驶： 标准和侧方停车一样，对好箭头后一档怠速（不踩离合）往上开；</p></li><li><p>找点停车：人、雨刷器中点、标杆三点一线时离合踩到底（提前一点，车会惯性滑行一小段）、轻踩刹车、拉手刹（拉到底！）；</p></li><li><p>起步： 慢抬离合、半联动状态时保持并用右脚踩油门，松手刹（松到底！），如果这时车有倒退趋势不要急，而要慢慢抬点离合（一急就容易熄火）；</p></li><li><p>下坡：离合踩到底，轻踩刹车保持匀速；</p></li></ul><h4 id="倒车入库-1">3.2.1.4&emsp;倒车入库</h4><p>特殊情况处理：</p><ul><li><p>打方向晚了点： 直接倒进去，太晚了直接gg；</p></li><li><p>尴尬的状况： 离库角一根手指时库角已经快消失在后视镜了，这时还是要先回正再打满；</p></li><li><p>早了点：按正常的步骤来，太早了直接gg、没救了；</p></li></ul><h3 id="17-20、21-24课时">3.2.2&emsp;17-20、21-24课时</h3><p><strong>12月5日、6日</strong>，主要是<strong>科目二</strong>考试模拟，我预约的下周一下午（不过据说上下午都能考）的考试，这两天争取用点心、做到考试时万无一失。东方时尚还发短信说周一早上有个<strong>考前测试</strong>可以参加，提前熟悉熟悉考试用车，看来又要早起了（6:30的班车）。</p><h4 id="考试流程相关注意事项">3.2.2.1&emsp;考试流程相关注意事项</h4><p>这一部分根据东方时尚APP的社区里大家的一些心得总结形成。  </p><ul><li><p>一共开<strong>2次</strong>转向灯，侧方停车出库一次（自动关）、直角转弯时一次（手动关）；</p></li><li><p>该快的时候快，防止项目超时： 侧方停车<strong>90s</strong>、坡起<strong>30s</strong>、倒车入库<strong>210s</strong>；</p></li><li><p>考试时上车先熟悉一下手感，离合器、油门、刹车都踩踩（记得拉上手刹），半联动状态看和练习车有没有太多区别（别熄火了）、踩油门时发动机转速怎样（主要怕坡起后溜）。觉得手感实在差可以申请换车；</p></li></ul><h4 id="考试内容相关注意事项">3.2.2.2&emsp;考试内容相关注意事项</h4><ol><li>侧方停车</li></ol><ul><li>注意与右侧道路边缘线距离控制好（方向盘对准箭头）；</li><li>停车挂倒挡开始计时，注意控制时间；</li><li>倒进去后可以车不正、只要不压线；</li><li>先打灯再挂一档；</li></ul><ol start="2"><li>坡停坡起</li></ol><ul><li>对准白箭头偏右一点的位置（有黑箭头的话对准两个箭头中间）；</li><li>一定要稳住离合、手刹一定收放到底；</li><li>拉手刹后开始计时，注意控制时间；</li><li>起步不要怂、直接油门踩到底；</li></ul><ol start="3"><li>直角转弯</li></ol><ul><li>坡道下来时记得放慢速度；</li><li>靠右点、记得打灯、及时迅速打满方向；</li></ul><ol start="4"><li>曲线行驶</li></ol><ul><li>入口处可以提前转向，第一个右转一定贴左（引擎盖右边缘贴线再转向）、回正不要太早、左转弯尽量靠右（引擎盖左边缘贴线再转向）；</li><li>曲线行驶打方向盘可以慢一点；</li></ul><ol start="5"><li>倒车入库</li></ol><ul><li>适当提前一些打轮，晚一点只能一把进、而早一点可以通过回正进行修正，容错范围更大；</li><li>不需要慢的地方尽量快一点、别拖拖拉拉的（练习的时候等别人倒库看到车半天不走几步就来气、差点按喇叭）；</li></ul><h1 id="科目二考试">4&emsp;科目二考试</h1><h3 id="考试流程">4.0.1&emsp;考试流程</h3><p><strong>12月7日</strong>，搭乘早上班车7点半到达驾校（早上6点半就堵车不愧是北京），直奔之前说的科目二第8、9道参加<strong>考前测试</strong>，人还不真少（60多个吧）。去那听教练指挥会有一次模拟考试的机会、还有注意事项的讲解，可以说东方时尚为了提高科目二通过率已经很用心了。我是从侧方开始的，结果坡起直接给熄火了、瞬间倍感压力，不过其他项目没太大问题，教练就让我再单独练了次坡停坡起（等于说是绕了两圈、有点赚到）。  </p><p>都通过了之后就可以离开场地去候考大厅取号<strong>等待考试</strong>了（东方时尚科目二考试是不分上下午的、我虽然在交管预约的下午考试但上午就能来考了，不过如果预约的上午结果下午来考试这种情况我不知道可不可以）。  </p><p>去了之后发现人比想象中更多，刚拿到号后前面还有140多人…经过2个半小时的煎熬等待（9:00-11:30）终于排到我了，期间把科目三理论的视频都快刷完了- -  </p><p>我是186号、当叫到160号时我就开始调整状态，首先去趟厕所，之后是自我随身检查（鞋带有没有系紧什么的），并把考试流程和每个项目要点在心里过了几遍、特别回顾了几个经常犯错误的点。为了不错过中午的班车我特地加快了点节奏、抢在我们那组第一个做（一般一次喊5个人去考试、车停在倒库外那条道上），所以是从侧方停车开始的。  </p><p><strong>进入考场</strong>，上车先刷一次身份证，然后调整座椅什么的、系上安全带，之后可以先试一试离合的感觉、踩一踩油门看看转速，一般车都不会有问题（每辆车教练都会自己上去以飞一般的速度过一遍考试、这熟练度看得我们目瞪口呆），再刷一遍身份证等待考试开始的语言播报。<br>组里第一个的好处是不会受到其他车的干扰、可以完全把注意力集中在项目上，加上自己当时也比较冷静，侧方停车——坡停坡起——直角转弯——曲线行驶——倒车入库  不知不觉就完成了、期间也没有提示扣分啥的，只记得最后的“成绩合格”，理所当然的一把 <strong><em>100分</em></strong> 过～</p><h3 id="总结">4.0.2&emsp;总结</h3><p>现在看来，东方时尚的假日班虽然贵点，但贵的合情合理： 首先科目二训练每次都是同一个教练，如果碰上一个好教练（我是1076车的孙虎老师、人挺亲切的、教的也很清楚）那么每次训练都能看见效果，而且假日班能保证一人一车、练习时间充足（虽然说每次等项目等半天、一个半小时也就跑了3次模拟考）。 考前测试是假日班才有的么这个我不太清楚，这个也是推荐能去尽量去的（练的次数越多越好）。  </p><p>科目二就是等待时间太长比较难受，推荐考前测试前先去科目二备考大厅看看人多不多，如果人已经很多的话可以先取号、再去考前测试、最后回来考试。当然如果没有把握能及时赶到考场还是老老实实先测试然后回来取号排队。</p><h1 id="科目三训练">5&emsp;科目三训练</h1><p>科目三内容：</p><ol><li>：上车准备、模拟夜间考试、起步、靠边停车</li><li>：会车、变更车道、加减档位、超车、直线行驶、掉头、夜间行驶</li><li>：通过人行横道、通过学校、通过公交车站、直行通过路口、路口右转、路口左转</li></ol><h2 id="25-28课时">5.1&emsp;25-28课时</h2><p><strong>12月12日</strong>，这节课按照驾校进度安排应该是科目二最后一次练习，由于我已经过了科目二所以直接要求教练教科目三，从而比别人有更多的练习时间。这次课主要是学习油门操作、加减挡、油离配合等，绕了训练场大概15圈左右，路上车也比较少开起来比较顺畅，不过感觉还是不够熟练所以没敢加到4档。<br>还有一个<strong>心得</strong>就是油门千万要踩<strong>稳</strong>了，不要不敢踩导致车一震一震的，油门的范围确实很窄还得慢慢适应它的感觉…</p><ul><li>起步前准备</li></ul><ol><li>车外检查：紧贴车身绕车一周半（这里应该是从副驾驶下车），上车调座椅、后视镜、系安全带。  考生听到“上车准备”语音指令后，贴近车辆以逆时针的方向绕圈，依次检查左后轮、车尾部是否有障碍物(车尾有感应探头)、右后轮、右前轮、车前部是否有障碍物(车头有感应探头)、左前轮。</li><li>上车：考生完成车外检查后，来到左车门前，观察前后交通情况，确认安全后，左手拉开车门，同时用右手扶着车门边角上车，最后关上车门。</li><li>车内检查：调整座椅及靠背位置，调整左中右后视镜，系好安全带，检查手刹，检查挡位是否置于空挡，并检查<strong>灯光把手是否复位</strong>（左手杆往后拨一下、别一打开就是远光考试直接挂）。检查完毕后，向考官示意准备完毕。</li><li>灯光使用：起步前先考灯光，抢拍操作会直接下车补考（一定要等语音说完再打灯！）。<br>起步： 近光； 无照明： 远光； 近距离跟车： 近光； 无交通信号灯：远近光交替三次（左手杆往后拨三下松开）； 路边临时停车：示廓灯、危险报警闪光灯；</li></ol><ul><li>起步</li></ul><ol><li>点火发动：车内检查结束后，系统发出指令“请准备完毕后立即起步”。听到指令后，考生启动发动机，然后系统继续发布指令“请起步”。</li><li>车辆起步：左脚踩离合到底，右手挂1挡，打开左转向灯，观察环境(左后视镜+扭头看下盲区)，确认安全后松手刹（踩刹车、两刹必有其一），慢抬离合，轻点油门（快到半联动之前、车有点抖了，两只脚反方向配合，达到<strong>快速起步</strong>效果），稍往左打方向起步。</li></ol><ul><li>直线行驶</li></ul><ol><li>观察交通情况：在行车道行驶过程中，要适时(每隔20秒左右)观察内外后视镜，视线不能离开行驶方向超过2秒，时刻观察前后车况、跟车距离、车道路况，时刻准备减速慢行和礼让。</li><li>控制挡位和车速：应根据交通实际状况，适时用换挡和制动控制车速。如遇前车制动、车距缩短、路面障碍时，要及时采取减速措施(轻点刹车或减挡);如遇前车提速、车距增大、路况较好时，应主动踩油门提速和升挡。</li><li>保持直线行驶：不论车速高低，都要保持直线行驶，控制车辆在行车道内行驶。在行驶过程中，考生要扶稳方向盘，适当修正行驶路线，尽量少转动方向盘，眼盯前方80至100米处。</li></ol><ul><li>加减挡位</li></ul><ol><li>原则：以发动机转速为准、记住踩油门到2000~2300转车发出时的声音，这时说明要升档了（发动机转速会下降）；当前方需要减速、高档位感觉车没力时则说明要减档了。</li><li>档位与速度匹配： 也可以根据速度判断加减档时机。<br>1) 一档： [ 0,20) km/h ， 15km/h加到二挡， 10km/h减到一档；<br>2) 二挡： [10,30) km/h ， 25km/h加到三挡， 20km/h减到二挡；<br>3) 三挡： [20,40) km/h ， 35km/h加到四挡， 30km/h减到三挡；<br>4) 四、五挡： [30,60) km/h ， 45km/h加到五档， 40km/h减到四挡；</li></ol><ul><li><p>升挡要求：升挡操作时，动作要轻快、柔和，选择挡位要准确，不能低头看挡位，不能空挡滑行。升挡前，看左右后视镜确保路况安全。右脚先松开油门、左脚踩下离合（同时完成），挂合适挡位。然后慢抬离合的同时缓踩油门提速。</p></li><li><p>降挡要求：降挡前，看左右后视镜确保路况安全；降档前最好适当减速。</p></li><li><p>变更车道</p></li></ul><ol><li>在考试过程中，考生根据实际路况选择向左或向右变更车道。</li><li>变更车道前，要观察左右后视镜，确保车外两侧安全之后，打开对应位置的转向灯(向左变道打左灯，向右变道打右灯)，打完灯之后<strong>等3秒再动方向盘</strong>，缓打方向（<strong>幅度一定要小！</strong>）变道。变道完毕后，关闭转向灯。</li><li>要记住上坡路段、高架桥、红绿灯、人行横道等地不能变道；</li></ol><ul><li><p>减速停车： 轻踩刹车减速，当减到很低速车有抖动若还不踩离合就会发生熄火，所以在低速时必踩离合！</p></li><li><p>调头</p></li></ul><p>1、调头前：向左变道进入左侧调头车道，踩离合带刹车减速，打开左转向灯，降至1挡，抬离合，到达调头位置时迅速向左打满方向盘，沿左侧路肩左转。<br>2、调头过程中：注意观察右侧来车方向，右脚放在刹车踏板上，随时准备减速避让。遇到直行来车时应减速或停车礼让。完成调头后适时回正方向，驶入快车道后根据实际路况提速升挡。</p><h2 id="29-32课时">5.2&emsp;29-32课时</h2><p><strong>12月14日</strong>，本来今天是科目三第一次课，跟教练说上节课学了点科三内容之后他二话不说直接把我带到实际道路上，我就这样瑟瑟发抖地开始上路了，中途印象最深的场景是左右两边两辆大货车呼啸而过，那叫一个刺激。  </p><h3 id="第一次上路总结">5.2.1&emsp;第一次上路总结</h3><ol><li>始终慢抬离合，抬快了既容易熄火也不方便控制车； 起步时一定给油，不要怕给多了（别太离谱就行，但少了的话动力不足或油门不稳容易车一震一震的），给油可以减少熄火的可能并快速起步。  </li></ol><p>我有几次起步熄火就是因为不敢给油或者给油后没稳住，我不敢踩油门是怕加速度太快车窜出去，但后面教练说只要<strong>离合稳住慢抬就不会窜车</strong>，之后体会好像确实是这样。起步的油离配合（两脚反向缓慢运动）是科目三非常基础和重要的部分，必须非常熟练，在路上跑遇到最多的情况也就是减速停车再起步；</p><ol start="2"><li>换挡时千万不要低头看，一点低头的动作都不要有！  </li></ol><p>发现我还是有时候不由自主地低头，但经常是看一眼仪表盘确认发动机转速和车速；各档位的位置和感觉一定要熟悉，别开一段之后忘记再哪一档或者挂错档了；</p><ol start="3"><li>换挡时左手千万要控制住方向！  </li></ol><p>刚开始走的时候发现我每次加档后的几秒内车就会向右偏，反映我换挡还不够熟练、注意力集中在正确换挡上而忽视了行驶路线控制；</p><ol start="4"><li>减档先减速，别速度还没降下来就减档！</li></ol><p>刚开始我碰到远处红灯就开始准备减档，后来教练说减档不是必须的、减速才是关键：前方车停下来后准备踩刹车减速，速度很低时踩下离合并松掉刹车（看距离）让车再滑一段，保持安全距离踩刹车停车挂空挡就行（或者直接挂一档随时准备起步）。</p><ol start="5"><li>转弯掉头前记得减到一档；</li></ol><p>这个更多是为了应付科目三考试，一档更保险一些减少熄火概率； 入弯前减速，减到<strong>车快要开始抖时</strong>离合踩到底（最好再提前一点）、换挡（这里有一个起步油离配合操作），怠速过弯、过弯后加速；</p><ol start="6"><li>开的别太慢了，免得被教练催；</li></ol><p>我是起步后如果前面道路状况好立马上2档然后3档，如果前面几乎没车继续上4档，但记得保持车速在60km/h以下（我是控制在最高50km/h左右）。其中3档行驶的路最长，很多时候都是直接3档降1档；</p><ol start="7"><li>靠边停车时和路边距离把握好；</li></ol><p>提前打灯，找到好位置后减速方向盘转90度切入（可以幅度再小点）、速度很低时离合器踩到底换一档，路边与发动机盖在1/2左右就往左打180度、最终和发动机盖距离1/3左右回正，和路边距离要是30cm以内，觉得距离没调好可以往前走一段慢慢调（选个好停车点的重要性）。</p><h2 id="综合训练（33-36课时）">5.3&emsp;综合训练（33-36课时）</h2><p><strong>12月18日</strong>，第二次在路上跑、一共熄火两次（和上次比有所进步），还是要时刻记住离合器<strong>慢松慢松慢松！</strong>，加减档基本没啥问题了，但还是有几点需要注意的：</p><ol><li><p>起步别弄熄火了；</p></li><li><p>转弯掉头<strong>提前</strong>减速（10km/h以下）、直接挂一档，速度没降下来的话直接减一档可能会感觉有阻力，别没挂上档就惨了；</p></li><li><p>靠边停车： 我是北线、掉头后升二挡直接听口令找地方停车了，踩刹车减速、注意力集中在别压线上（感觉要车停了就离合踩到底换一档半联动继续走），不要纠结于换挡而手忙脚乱；</p></li><li><p>几个踩刹车左右回头看的点位记住了，刹车稍微踩得深一点让考试系统感应到；</p></li></ol><h2 id="考前路训（37-40课时）">5.4&emsp;考前路训（37-40课时）</h2><p><strong>12月21日</strong>，最后一次课、两人一车跑考试路线，中午去考前测试三人一车每人跑一圈，明天就要考试了慌得不行。</p><ol><li><p>起步油离配合！！！拒绝熄火！！！</p></li><li><p>转弯前减好档！！！</p></li><li><p>灯灭了等3s再打灯！！</p></li><li><p>急刹车离合要同时踩到底防熄火！！</p></li></ol><h1 id="科目三道路考试">6&emsp;科目三道路考试</h1><p>东方时尚周一、三、五是南线，二、四北线。一般考试前一天约考前路训才能练考试路线，考试当天训练车是不得进入的。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222210109.jpeg" alt><br>上面图是东方时尚以前的灯光模拟考试部分，现在更简单些，记住几个容易犯错的点就行。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222205949.png" alt="考试线路图"></p><h2 id="复习（北线）">6.1&emsp;复习（北线）</h2><ol><li><p>问候考官，双手递上身份证，拿回后到车右后角等候，开始逆时针一圈半绕车检查（不要离车太远、快走）：车牌、轮胎、车门、障碍物…开门前要前后瞭望确认安全；</p></li><li><p>上车调座椅后视镜系安全带空挡灯光OFF复位，准备好了开始模拟灯光考试；</p></li><li><p>夜间起步前、近距离跟车、恢复照明、会车——近光灯， 无照明、照明不良——远光灯， 无信号灯路口、超车、山路拱桥、人行横道——三次交替远近光灯， 临时停车、发生故障——示廓灯、危险报警闪光灯；</p></li><li><p>报起步后立即打左灯、踩离合刹车挂一档松手刹、看左侧后视镜并左侧回头（幅度要大），满3s后油离配合起步左转；</p></li><li><p>左转后再打左灯3s以上、刹车减速左右观察，左转进入综合楼东侧路，路况良好直接上三档（限速40）；</p></li><li><p>听到右转口令后打灯刹车减速10km/h以下并挂一档，路口左右观察该停则停；</p></li><li><p>右转完马上加二档，过公交站减速并左右观察、 再往前注意左侧道路来车（减速观察），之后加油上三挡；</p></li><li><p>右转口令后打灯减速到一档，左右观察，进入芦东路最右侧公交车道；</p></li><li><p>车正后立即打左灯，踩油门加速到二档，左侧观察回头后向左变道；变道后再打左灯，加速到三挡，继续变道到最左；</p></li><li><p>十字路口提前减速左右观察，前进到掉头路段，听语音后打左灯减速到一档，掉头时（确认安全后）左右大幅度观察（看右边是否有左转车辆，不要跟着前车掉头）；</p></li><li><p>掉头后走中间车道，加二档保持直线行驶，加到三或四档；路口处减速左右观察；</p></li><li><p>通过学校区域：减速左右观察；继续直行至下一路口（会有语音播报），减速左右观察；</p></li><li><p>直行进入掉头车道，语音后减速挂一档左右观察完成掉头；掉头后迅速加至二挡；</p></li><li><p>听靠边停车语音后开右转向灯，观察后视镜并扭头后看；</p></li><li><p>完成后，开双闪、踩离合刹车摘空挡拉手刹，解安全带、车辆熄火，观察后方开门下车；</p></li></ol><p>下图是我趁教练抽烟翻车里的文件发现的一些资料，还蛮有用的：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222210928.jpg" alt="北线考试流程"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222211004.jpg" alt="南线考试流程"></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222211037.jpg" alt="科目三扣分点"></p><h2 id="我的考试过程">6.2&emsp;我的考试过程</h2><p><strong>12月22日</strong>，又是一大早坐满人的班车，到驾校直奔综合楼刷身份证领号，我比较幸运地领到了45号（挺靠前的了），差不多8点半就开始考试了，9点轮到我，11号考试车、是个高高瘦瘦戴墨镜的冷酷男考官。<br>我一开始在车后等他给我手势我好开始绕车检查，但他坐着半天一动不动，我有点懵但还是不管了直接开始，然后上车调整好说“准备好了”后开始考模拟灯光。当播报“请起步”后<strong>悲剧就开始了</strong>：<br>打左灯挂一档放手刹侧身看一套操作秀完后，正准备抬离合给油走时听见发动机“嗡..嗡嗡…嘭…”，接着就是机械的语言播报“因操作不当造成发动机熄火，扣十分”。没事只要接下来不扣分就行，稳住心态后我立马回空挡重新打火再起步…总算没再熄了！看到车动心中一阵欣喜，却忘记及时避让右边的考试车，只见考官一脚迅猛的刹车直接又把发动机给灭了（其实不是没准备让，而且车速当时非常慢，无奈考官反应太快了）。“倒车回去准备开始补考”，听到这句话我脑中一片空白，卧槽这还没走出去5m我就扣了110分直接一次机会没了？？<br>本以为今天是过不了了，结果在压力作用下最后一次机会反而能正常发挥了，从头到尾考官没抱怨过一点，最后的靠边停车也是异常完美，下车时为了节省考官回去的时间我还特地没把车熄火（其实是大舒一口气过于高兴而忘了），最后当然是<strong><em>95分</em></strong>（下车发动机未熄火扣5分）。</p><h1 id="科目三理论考试">7&emsp;科目三理论考试</h1><h2 id="复习">7.1&emsp;复习</h2><p>考试内容大致如下：</p><ol><li>违法行为综合判断与案例分析</li><li>安全行车常识</li><li>常见标志标线手势判别</li><li>文明驾驶常识</li><li>恶劣天气、复杂道路条件下驾驶常识</li><li>紧急情况避险常识</li><li>交通事故救护及危化品处置</li></ol><p>这里只列一些科目一背过、又经常出现在科目三中的知识点。没啥好说的，刷刷题总结下出题套路科三理论真的随便过…</p><pre><code>- 大型客车A1（20人以上）、牵引车A2、城市公交车A3、中型客车B1（10-19人）、大型货车B2、小型车C1，自动挡C2、低速载货C3、三轮汽车C4- 车后50~100m设警告标志（高速150m）- 夜间、150m以外改用近光灯- 限速：城市30公路40（无中心线）、城市50公路70（有）- 高速路2车道（最低从左至右100、60），3车道（最低110、90、60）- 能见度200m，60车速 100m距离，能见度100m，40 50m，能见度50m， 20 尽快驶离- 不得停车：汽车站等 30m、交叉路口窄桥陡坡隧道急弯等 50m- &gt;20mg/100mL 饮酒、 &gt;80mg/100mL 醉酒- 连续开4h、休息20min</code></pre><h2 id="考试流程-1">7.2&emsp;考试流程</h2><p>追求效率一般只推荐上午考科三道路下午考科三理论拿本，当然这样做给自己压力也很大，毕竟上午过不了下午也没法考。 我是<strong>周末两天</strong>准备科目三理论，周一开始到考完科目三道路之前就不再看理论了，专心把道路的细节记熟了。<br>上午考完会有一个安全警示教育，最好参加一下，之后赶紧去科目三备考点排队（上午考完最早也只能参加下午的理论考试，11:00开始取号），不要等到10:40左右再去（已经排了一百来号人了）。<br>考试注意事项同科一，科目三理论是50道题，前40道单选后10道多选，我最后一道多选因为赶时间点错了，只有<strong><em>98</em></strong>分。<br>下午两点考完，然后去规定的教室等发证就是了。我之前担心怕赶不上16:15的班车、不过后来事实证明是我想多了，东方时尚这边的效率还是挺高的，下午三点就拿到证了（一定记得提前在12123APP把<strong>考试费用</strong>一共160元全部交了，不然当天领不到证），学车时光也告一段落。</p><h1 id="最后">8&emsp;最后</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222215919.PNG" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222215938.PNG" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222215953.jpg" alt></p><p>感谢东方时尚的教练们，让我从11月06日报名到12月22日拿本期间学到很多驾驶技巧和防御性驾驶意识，附上几张东方时尚驾校的吉祥物们的图吧。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222220044.jpg" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222220106.jpg" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20201222220132.jpg" alt></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-11-14-dong-fang-shi-shang-jia-xiao-xue-che-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>C-Tips</title>
      <link>https://chengpengzhao.com/2020-11-13-c-tips/</link>
      <guid>https://chengpengzhao.com/2020-11-13-c-tips/</guid>
      <pubDate>Fri, 13 Nov 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;(欢迎纠错)&lt;/p&gt;
&lt;h1 id=&quot;基本概念&quot;&gt;1&amp;emsp;基本概念&lt;/
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>(欢迎纠错)</p><h1 id="基本概念">1&emsp;基本概念</h1><ul><li><p>CPU:运算器+控制器（向内储存器发送地址流数据）</p></li><li><p><code>1 Byte=8 Bit</code>，<code>1 K=1024 Byte</code>，每个Byte有一个唯一的地址，一个指针<code>4 Byte</code></p></li></ul><ul><li><p>预处理:<code>.c-&gt;.i</code> 编译:<code>.i/.c-&gt;.s</code> 汇编:<code>.s-&gt;.o</code> 链接:<code>.o-&gt;可执行程序</code>。通常预处理器与编译器集成在一起</p></li><li><p><strong>编译</strong>：转化成目标代码，但还需要<strong>标准启动代码</strong>和<strong>库代码</strong>合并起来（链接）才能形成<strong>可执行代码</strong></p></li><li><p>小端存储法： 高地址存高字节、低地址存低字节；(手机ARM、ipad、x86结构、intel/ARM和DSP…)(IBM大型机、网络字节序用大端存储法)</p></li><li><p>Gcc常用编译选项： <code>-Wall</code>   生成警告信息（配合<code>-O</code>使用），<code>-W</code>  额外的警告信息，<code>-pedantic</code>   根据C标准生成警告、避免使用非标准特性， <code>-ansi</code>   禁用非标准C特性，<code>-std=c99</code>   指定编译器版本</p></li><li><p>泛型编程（generic programming），指没有特定类型、但一旦指定一种类型就可以转换成指定类型的代码</p></li></ul><h1 id="格式化输入输出">2&emsp;格式化输入输出</h1><ul><li><p>printf的转换说明： <code>%(-)m.pX</code>   <code>m</code>为要显示字符最少数量（不够会自动扩充）、<code>p</code>为精度，有负号时左对齐（空格会放在右边、<code>+</code>表示始终加正负号）；常用转换说明符： <code>d</code> 十进制整数，<code>e</code>  指数，<code>f</code> 十进制浮点数，<code>g</code> 指数或浮点数、适合范围变化大或无法预知大小的数</p></li><li><p>读取<code>double</code>用<code>%lf</code>，显示用<code>%f</code></p></li></ul><h1 id="表达式与循环">3&emsp;表达式与循环</h1><ul><li><p>运算符优先级： 最高的是非正式意义运算符（数组下标、成员选择等）、其次是单目运算符（<code>括号</code>&gt;<code>++</code>&gt;<code>*</code>），双目运算符（<code>算术</code>&gt;<code>移位</code>&gt;<code>关系</code>&gt;<code>逻辑</code>&gt;<code>赋值</code>&gt;<code>条件(a?b:c)</code>），最后是逗号运算符</p></li><li><p>注意各种运算符的优先级、结合性，但没必要记</p></li><li><p><code>%</code>取余数只用于整数，其他的用<code>fmod</code>函数</p></li><li><p><code>x+=y</code>与<code>x=x+y</code>的区别： 后者对<code>x</code>进行了两次求值，可能引起的副作用也都会出现2次</p></li><li><p><code>while(i++ &lt; n)</code>    这种写法使程序更简洁</p></li><li><p>形式参数：<em>formal parameter<em>，实际参数：</em>actual argument</em> </p></li><li><p><code>switch</code>语句记得加<code>break</code>，否则会从匹配标签开始执行到<code>switch</code>末尾</p></li><li><p>可以接受的一种<code>goto</code>用法： 出现问题时想要从<strong>一组</strong>循环嵌套中跳出（用break只能跳出一个循环，比较麻烦）</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">goto</span> label<span class="token punctuation">;</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>label<span class="token punctuation">:</span> statement<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><ul><li>把常量放在判断相等的比较表达式左侧，减少出错：<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token string">'\t'</span><span class="token operator">==</span>c<span class="token operator">||</span><span class="token string">''</span><span class="token operator">==</span>c<span class="token operator">||</span><span class="token string">'\n'</span><span class="token operator">==</span>c<span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">;</span><span class="token punctuation">}</span>   <span class="token comment" spellcheck="true">//一旦出错会马上捕获</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li></ul><h1 id="基本类型">4&emsp;基本类型</h1><ul><li><p>C99的<code>&lt;stdbool.h&gt;</code>提供了bool宏：<code>bool flag=true;</code> 这样使用</p></li><li><p><code>typedef</code>可提高程序的可移植性</p></li><li><p><code>sizeof(short)</code> 函数返回<code>size_t</code>类型，是无符号整型<code>unsigned int</code>的别名。相比于<code>strlen()</code>、<code>sizeof</code>把字符串末尾不可见空字符也计算在内</p></li><li><p>指针的类型：决定指针移动一位时的距离（<code>sizeof(指针类型)</code>）</p></li><li><p><code>sizeof(a=b+1)</code>并没有向a赋值</p></li></ul><h1 id="数组">5&emsp;数组</h1><ul><li><p>获得数组长度：<code>sizeof(a)/sizeof(a[0])</code>， 注意返回的是一个无符号数</p></li><li><p>复制数组的一个方式： <code>memcpy(a,b,sizeof(a))</code>，来自<code>&lt;string.h&gt;</code>头的内存复制函数</p></li><li><p>复合字面量建立无名数组： <code>(int []){1,2,3,4,5};</code></p></li><li><p>一维数组中：<code>&amp;a[i]</code>等价于<code>a+i</code>，二维数组中：<code>&amp;a[i][j]</code>等价于<code>a[i]+j</code></p></li><li><p>一维数组<code>a[i]</code>中，<code>&amp;a+1</code>代表跨越整个数组的长度，不同于<code>a+1</code>（跨越数组一个元素的长度）</p></li><li><p>绝大多数情况下，数组名的值是指向数组第1个元素的指针，除了两个例外： <code>sizeof</code>返回整个数组占用的字节、<code>&amp;</code>返回一个指向数组的指针</p></li></ul><ul><li><p>多维数组作为函数参数：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span> mat<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token keyword">void</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token keyword">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>mat<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//指向数组的指针</span><span class="token comment" spellcheck="true">//也可以写成：  void func(int mat[][4]);</span><span class="token comment" spellcheck="true">//但不能写成：  void func(int **mat);</span><span class="token function">func</span><span class="token punctuation">(</span>mat<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>多维数组定义：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">//正确：</span><span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//报错：</span><span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">{</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//只有第一维能根据初始化列表缺省地提供，其余的必须显式写出</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="函数">6&emsp;函数</h1><ul><li><p><code>exit</code>导致程序退出，<code>return</code>导致函数退出</p></li><li><p><code>return 0;</code> 控制权交给上一级（直到最初一级、结束程序）; <code>exit(0);</code>   直接结束程序</p></li><li><p>函数名（不带括号）返回该类型函数的地址</p></li><li><p>递归的工作原理： 函数调用时、变量存在堆栈上，每一次递归、之前调用的变量仍留在堆栈上但不能被访问，直到函数返回前一次调用</p></li><li><p>递归往往是用简洁性弥补其运行开销（冗余计算增长极快），一些情况用迭代实现更好</p></li><li><p>调用在后面定义的函数，必须在调用之前声明其<strong>函数原型</strong>；函数定义时结尾可不加分号、但声明结束时必须加，推荐全都加</p></li><li><p>用<code>stdarg</code>实现可变参数：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdarg.h></span></span><span class="token keyword">double</span> <span class="token function">avg</span><span class="token punctuation">(</span><span class="token keyword">int</span> n<span class="token punctuation">,</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">// n为省略号中参数个数</span>va_list var_arg<span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">//定义一va_list类型</span><span class="token keyword">int</span> count<span class="token punctuation">;</span><span class="token keyword">double</span> sum <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token function">va_start</span><span class="token punctuation">(</span>var_arg<span class="token punctuation">,</span> n<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//初始化va_list</span><span class="token keyword">for</span> <span class="token punctuation">(</span>count <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> count <span class="token operator">&lt;</span> n<span class="token punctuation">;</span> count<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator">+</span><span class="token operator">=</span> <span class="token function">va_arg</span><span class="token punctuation">(</span>var_arg<span class="token punctuation">,</span> <span class="token keyword">double</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//按顺序读取va_list中的参数，注意类型一定要一致</span><span class="token punctuation">}</span><span class="token function">va_end</span><span class="token punctuation">(</span>var_arg<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//结尾要调用</span><span class="token keyword">return</span> sum <span class="token operator">/</span> n<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token function">avg</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">1.2</span><span class="token punctuation">,</span><span class="token number">2.3</span><span class="token punctuation">,</span><span class="token number">3.4</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//使用方式</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="指针">7&emsp;指针</h1><ul><li><p>二维数组中<code>a</code>和<code>a[0]</code>的区别： 类型不同，前者为（拿int举例）<code>int (*)[num_cols]</code>，后者为<code>int *</code></p></li><li><p><code>*p++</code> 等价于<code>*(p++)</code>；相当于<code>a[i++]</code>。<code>(*p)++</code>表示p所指元素值加1</p></li><li><p><code>*(a+i)</code>代表<code>a[i]</code>，<code>*(a[i]+j)</code>和<code>*(*(a+i)+j)</code>都代表<code>a[i][j]</code></p></li><li><p><code>*p[4]</code> 指针数组，元素全为指针的数组； <code>(*p)[4]</code> 是一个指针，指向一个4元素数组</p></li><li><p>字符指针：<code>char *s=&quot;Hello&quot;;</code>等价于：<code>char *s;   s=&quot;Hello&quot;;</code>而字符数组不可以分开这样做，并且字符数组间不能进行赋值(<code>s</code>输出的是<code>Hello</code>、而<code>*s</code>输出的是<code>H</code>)</p></li></ul><h1 id="字符串">8&emsp;字符串</h1><ul><li><p><strong>单引号</strong>：字符常量（代表一个整数）； <strong>双引号</strong>：字符串（指向无名数组起始字符的指针）</p></li><li><p>延续字符串到下一行： 前一行用<code>\</code>结尾</p></li><li><p>C语言把字符串字面量作为字符数组（结尾为<code>\0</code>）来处理，把字符常量（单引号）作为整数处理</p></li><li><p><code>getchar、putchar</code>  每次处理一个字符。<code>getchar</code>不会跳过空格、制表符和换行符，而<code>scanf</code>会</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span><span class="token string">&lt;stdio.h></span></span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token keyword">char</span> ch<span class="token punctuation">;</span><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ch<span class="token operator">=</span><span class="token function">getchar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">!=</span><span class="token constant">EOF</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment" spellcheck="true">//stdio.h中定义EOF</span> <span class="token function">putchar</span><span class="token punctuation">(</span>ch<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//该程序会每次按下`Enter`输出缓冲区字符、当遇到文件结尾模拟（`Ctrl+D`或`Ctrl+Z`）时停止</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>puts()</code>函数只输出字符串，会<strong>自动</strong>在末尾加上换行符（类似还有<code>fputs()</code>和<code>printf()</code>）；<code>gets()</code> 读取整行输入直到换行符（尽量别用、已淘汰、可以用<code>fgets()</code>、而<code>scanf()</code>适合读取单词）</p></li><li><p>字符串最后要有<code>\0</code>，否则为字符数组</p></li><li><p>常见创建字符串的方式：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// 数组形式中，数组名st1是地址常量，不能更改st1（不能++st1这样的操作）；数组元素是变量、但数组名是常量</span><span class="token keyword">char</span> st1<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token operator">=</span><span class="token string">"hello world."</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">// 指针形式，字符串字面量为const数据、不能修改st2指向的数据，但可以改变st2的值（可以++st2）</span><span class="token keyword">const</span> <span class="token keyword">char</span> <span class="token operator">*</span>st2<span class="token operator">=</span><span class="token string">"Hello world too."</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>atoi()</code>    <code>stdlib.h</code>中将字符串转成int，同理有<code>atof()</code>(double)、<code>atol()</code>(long)。另外<code>strtol()</code>也可以</p></li></ul><ul><li><p>所谓的文本文件不过是二进制文件按照一定规则解码得到的（如ASCII一字节一字节解读）？</p></li><li><p>字符只是<strong>小型整数</strong>，所以用一个整型变量容纳字符值不会引起任何问题</p></li><li><p>两个问号放一起的时候注意“三字母词（trigrph）”</p></li><li><p><code>signed</code>关键字多用于<code>char</code>类型，因为其他整形类型默认为有符号数，只有<code>char</code>因编译器而异</p></li><li><p>常用字符串函数：</p><pre class="line-numbers language-c"><code class="language-c">size_t <span class="token function">strlen</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>string<span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//返回字符串（末尾必须为\0）长度，size_t为无符号数</span><span class="token comment" spellcheck="true">//用strlen(x)>=strlen(y)而不是strlen(x)-strlen(y)>=0，无符号数必非负</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">strcpy</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span>dst<span class="token punctuation">,</span><span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>src<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//复制字符串并返回一份拷贝，注意内存不能重叠或空间不足</span><span class="token keyword">char</span> <span class="token operator">*</span><span class="token function">strcat</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token operator">*</span>dst<span class="token punctuation">,</span><span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>src<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//连接字符串到dst后面</span><span class="token keyword">int</span> <span class="token function">strcmp</span><span class="token punctuation">(</span><span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>s1<span class="token punctuation">,</span><span class="token keyword">char</span> <span class="token keyword">const</span> <span class="token operator">*</span>s2<span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//字符串比较、若相等返回0</span><span class="token comment" spellcheck="true">//长度受限的字符串函数：strncpy、strncat、strncmp，多了一个参数size_t len</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="预处理器">9&emsp;预处理器</h1><ul><li><p><code>#define PI 3.1415</code> 编译时替换、末尾不用加分号</p></li><li><p><code>#if 0  #endif</code>可以用来屏蔽含注释的代码</p></li><li><p>预处理中的<code>#</code>运算符和黏合剂<code>##</code>运算符：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">define</span> PSQR(x) printf("The square of " #x " is %d.\n",((x)*(x)))</span><span class="token macro property">#<span class="token directive keyword">define</span> XNAME(n) x ## n</span><span class="token keyword">int</span> y<span class="token operator">=</span><span class="token number">5</span><span class="token punctuation">,</span>x1<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">;</span><span class="token function">PSQR</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//输出为： "The square of y is 25"</span><span class="token function">printf</span><span class="token punctuation">(</span><span class="token function">XNAME</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//输出为2</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>带参数的宏：（若是表达式一定记得加括号，否则相邻操作符之间会产生不可预料的作用）</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">define</span> PRINT(FORMAT,VALUE) \ printf("The vaule of " #VALUE " is " FORMAT "\n",VALUE)</span><span class="token comment" spellcheck="true">//注意#argument的用法</span><span class="token macro property">#<span class="token directive keyword">define</span> ADD(num,value) \ sum##num+=value</span>x<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token function">PRINT</span><span class="token punctuation">(</span><span class="token string">"%d"</span><span class="token punctuation">,</span>x<span class="token operator">+</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">ADD</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//把sum5这个变量加25</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>#undef</code>移除一个宏定义</p></li><li><p>条件编译：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">if</span> constant-expression</span> statements<span class="token macro property">#<span class="token directive keyword">elif</span></span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span class="token comment" spellcheck="true">//是否被定义：</span><span class="token macro property">#<span class="token directive keyword">if</span> defined(symbol) </span><span class="token comment" spellcheck="true">//等价于#ifdef symbol</span><span class="token macro property">#<span class="token directive keyword">if</span> !defined(symbol2) </span><span class="token comment" spellcheck="true">//等价于#ifndef symbol2</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="大型程序编写要点">10&emsp;大型程序编写要点</h1><ul><li><p><code>include</code>中使用宏替换</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">if</span> defined(IA32)</span>  <span class="token macro property">#<span class="token directive keyword">define</span> CPU_FILE "ia32.h"</span><span class="token macro property">#<span class="token directive keyword">elif</span> defined(IA64)</span>  <span class="token macro property">#<span class="token directive keyword">define</span> CPU_FILE "ia64.h"</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span class="token macro property">#<span class="token directive keyword">include</span> CPU_FILE</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>#error</code>检查不该包含的头文件</p><pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">//避免把头文件用于旧的非标准编译器</span><span class="token macro property">#<span class="token directive keyword">ifndef</span> _STDC_</span><span class="token macro property">#<span class="token directive keyword">error</span> This header requires a Standard C compiler</span><span class="token macro property">#<span class="token directive keyword">endif</span></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>echo_eof &lt; words</code> ， <code>&lt;</code>为重定向运算符、使程序用文件而不是键盘输入，同样<code>&gt;</code>表示输出到文件（覆盖）、而<code>&gt;&gt;</code>表示附加到文件</p></li></ul><ul><li><p>宏可以完成一些函数做不到的事：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">define</span> MALLOC(n,type) \ ((type*)malloc((n)*sizeof(type)) )</span>pi<span class="token operator">=</span><span class="token function">MALLOC</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">,</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>模块的客户（main、使用者），模块的接口（头文件），模块的实现（.c文件）。模块的好处：抽象、可复用性、可维护性；模块的特点：高内聚性、低耦合性；模块的类型：数据池、库、抽象对象、抽象数据类型（ADT）</p></li></ul><h1 id="结构、联合和枚举">11&emsp;结构、联合和枚举</h1><ul><li><p>允许把一个结构<strong>赋值</strong>给另一个结构，也允许把一个结构<strong>初始化</strong>为相同类型的另一个结构</p></li><li><p>结构中比较特殊的一种初始化方式： <code>struct book a={.value=10.9};</code> 即只初始化部分成员（注意声明的结尾加分号）</p></li><li><p>结构内部不能包含该结构本身，但可以是指向该结构的指针（构造链表、树常用）</p></li><li><p>利用结构来复制数组： <code>struct {int a[10];} a1,a2; a1=a2;</code></p></li><li><p>复合字面量，创建一个临时的结构： <code>part1=((struct part){528,&quot;drive&quot;,10});</code></p></li><li><p>结构中储存字符串不要用字符指针而要用<strong>字符数组</strong>（字符指针将字符串储存在编译器储存常量的地方），如果要用请先用<code>malloc()</code>分配储存空间</p></li><li><p>结构名不是地址（不同于函数、数组），访问地址要加上<code>&amp;</code></p></li><li><p>两结构即使成员列表完全相同、也被编译器当做两种截然不同的类型</p></li><li><p><strong>联合</strong> 类型，混合数据类型：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">//该union可储存一个int或一个double或一个char</span><span class="token keyword">union</span> hold<span class="token punctuation">{</span> <span class="token keyword">int</span> digit<span class="token punctuation">;</span> <span class="token keyword">double</span> bigfl<span class="token punctuation">;</span> <span class="token keyword">char</span> letter<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><strong>枚举</strong>类型（enum）是整数类型，目的是为了提高程序的可读性和可维护性</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">enum</span> suit <span class="token punctuation">{</span>CLUBS<span class="token punctuation">,</span>DIAMONDS<span class="token punctuation">,</span>HEARTS<span class="token punctuation">,</span>SPADES<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">typedef</span> <span class="token keyword">enum</span> <span class="token punctuation">{</span>FALSE<span class="token punctuation">,</span>TRUE<span class="token punctuation">}</span> Bool<span class="token punctuation">;</span><span class="token keyword">enum</span> suit2 <span class="token punctuation">{</span>CLUBS<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span>DIAMONDS<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">}</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//也可以选择不同数字，推荐加尾逗号</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="动态储存分配和函数指针">12&emsp;动态储存分配和函数指针</h1><ul><li><p><code>Segmentation fault</code> 错误，说明程序试图访问未分配的内存</p></li><li><p><code>void *malloc( unsigned int size )</code>，size是申请字节的大小，常用示例：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span><span class="token operator">*</span> p<span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token operator">*</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token keyword">if</span><span class="token punctuation">(</span>p<span class="token operator">==</span><span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">"内存申请失败，退出"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">return</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>动态分配内存详解：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span>  </span><span class="token comment" spellcheck="true">//使用malloc、exit必加</span><span class="token keyword">double</span> <span class="token operator">*</span>ptd<span class="token punctuation">;</span><span class="token keyword">int</span> n <span class="token operator">=</span> <span class="token number">30</span><span class="token punctuation">;</span>ptd <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">double</span> <span class="token operator">*</span><span class="token punctuation">)</span><span class="token function">malloc</span><span class="token punctuation">(</span>  n <span class="token operator">*</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">double</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//创建一个数组（n可以用变量），分配了一块连续的内存</span><span class="token keyword">if</span> <span class="token punctuation">(</span>ptd <span class="token operator">==</span>  <span class="token constant">NULL</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">//分配失败时返回NULL指针，NULL在stdio.h、stdlib.h、string.h、time.h等中均有定义</span>  <span class="token function">exit</span><span class="token punctuation">(</span>      EXIT_FAILURE<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// EXIT_FAILURE表示程序异常终止、EXIT_SUCCESS表普通的程序结束（相当于0）</span>  <span class="token function">free</span><span class="token punctuation">(</span>ptd<span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token comment" spellcheck="true">//释放malloc分配了的内存</span>  <span class="token comment" spellcheck="true">// calloc和malloc类似，不过还会自动把指针初始化为0：</span>  <span class="token keyword">double</span> <span class="token operator">*</span>pt <span class="token operator">=</span> <span class="token function">calloc</span><span class="token punctuation">(</span>n<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">double</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">// realloc能修改分配的内存块大小</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>灵活数组成员</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">struct</span> vstring<span class="token punctuation">{</span>  <span class="token keyword">int</span> len<span class="token punctuation">;</span>  <span class="token keyword">char</span> chars<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//C99 only , flexible array member}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token keyword">struct</span> vstring <span class="token operator">*</span>str<span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">struct</span> vstring<span class="token punctuation">)</span><span class="token operator">+</span>n<span class="token punctuation">)</span><span class="token punctuation">;</span>str<span class="token operator">-></span>len<span class="token operator">=</span>n<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ul><li>函数指针的使用（常作为其他函数的参数）：<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token keyword">int</span> x<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//声明函数</span><span class="token keyword">int</span> <span class="token punctuation">(</span><span class="token operator">*</span>pf<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token operator">&amp;</span>f<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//创建并初始化函数指针pf，&amp;可以去掉、因为函数名总是被编译器转换为函数指针</span><span class="token comment" spellcheck="true">//函数的调用：</span><span class="token keyword">int</span> ans<span class="token operator">=</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">int</span> ans<span class="token operator">=</span><span class="token function">pf</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 直接这样调用也行，函数名就是个地址</span><span class="token keyword">int</span> ans<span class="token operator">=</span><span class="token punctuation">(</span><span class="token operator">*</span>pf<span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">// int *g() , ()优先级较高，故是个函数，返回类型是int *</span><span class="token comment" spellcheck="true">// int (*g)()  , 是个指针，指向一个返回int类型的函数</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="声明、存储类型、作用域、变量类型">13&emsp;声明、存储类型、作用域、变量类型</h1><ul><li>声明的语法：<pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">extern</span> <span class="token keyword">const</span> <span class="token keyword">unsigned</span> <span class="token keyword">int</span> a<span class="token punctuation">[</span><span class="token number">10</span><span class="token punctuation">]</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//1. extern、储存类型，有auto、static、extern、register四种</span><span class="token comment" spellcheck="true">//2. 类型限定符，const、volatile两种</span><span class="token comment" spellcheck="true">//3. 类型说明符，如int、char...</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ul><li><p>变量的3个性质：</p><ol><li>存储期限。自动存储期：块终止时释放，静态存储期：整个运行期间占有同一个单元</li><li>作用域。 块作用域、文件作用域</li><li>链接（不同部分共享此变量的范围）。 外部链接：可以被程序中几个（或全部）文件共享，内部链接：只能属于单独一个文件，无链接：属于单独一个函数，不能共享</li></ol></li><li><p>五种存储类别：</p><ol><li><p><strong>自动变量</strong>：自动存储期（函数自动分配的、运行时堆栈）、块作用域、无链接，声明在块或函数头（函数参数部分）中，最常见的类型</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span>voidl<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">auto</span> <span class="token keyword">int</span> plex<span class="token punctuation">;</span><span class="token comment" spellcheck="true">//显示声明成自动变量，注意auto的用法C和C++很不一样</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p><strong>寄存器变量</strong>：不储存在内存而是CPU寄存器（最快可用内存）中，无法获得变量地址，其他特性与自动变量相似（可以对指针用、这样就不必复制指针值、但必须被声明为局部变量？）</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">register</span> <span class="token keyword">int</span> quick<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//只是一个请求，可能被忽略而变成自动变量</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li><p><strong>块作用域的静态变量（静态无链接）</strong>：和自动变量的作用域相同、但离开后变量不消失（静态存储期，对其他函数隐藏、对当前函数保留），声明在块内</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">void</span> <span class="token function">trystat</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token comment" spellcheck="true">//不能在函数形参中用static</span> <span class="token keyword">static</span> <span class="token keyword">int</span> stay<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p><strong>外部链接的静态变量</strong>： 有文件作用域、外部链接，未初始化的外部变量会自动设为0，并且只能用常量表达式初始化</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">extern</span> <span class="token keyword">int</span> out<span class="token punctuation">;</span><span class="token comment" spellcheck="true">//在main之外声明外部变量，若变量定义在别的源文件中则需要加extern（不会分配存储空间，只提示定义在别处），否则不要加</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">void</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p><strong>内部链接的静态变量</strong>：只能用于同一个文件中的函数、声明在函数外、用<code>static</code>关键词</p></li></ol></li></ul><ul><li>内存的3个部分：<ol><li><strong>静态变量</strong>（外部链接、内部链接、无链接）、内存在编译时确定，程序开始时创建、结束时销毁</li><li><strong>自动变量</strong>：作为<strong>栈</strong>处理、进入定义变量的块时存在、离开块时消失；（按创建顺序加入、相反顺序销毁）</li><li><strong>动态分配的内存</strong>：“支离破碎”地分布在已用内存块之间（堆）、比栈内存要慢，malloc时分配free后释放</li></ol></li></ul><ul><li><p>标识符声明<code>static</code>或<code>external</code>只有<strong>第一次</strong>声明有效，多次声明无法更改其链接属性</p></li><li><p>如何理解复杂声明：从内往外读、<code>[]</code>和<code>()</code>还有<code>.</code>（于是有了<code>-&gt;</code>）优先<code>*</code></p><ol><li><p>从名字开始读取，按优先级顺序排序</p></li><li><p>优先级从高到低是： a. 声明中被括号括起来的部分  b. 后缀操作符、小括号表示函数、方括号表示数组  c. 前缀操作符：*表示指针</p></li><li><p>const后面若紧跟类型说明符(如int)、则作用与它，否则作用于它左边的星号</p><p>例子：<code>char * const *(*next)()</code><br>首先<code>*next</code>说明是个指针，看外面有个括号说明是函数指针，再有个<code>*</code>得出指针所指内容；再看函数返回类型，是个<code>char * const</code></p></li></ol></li><li><p>例子：<code>int *f()</code>， <code>()</code>优先级较高、说明是个函数、<code>*</code>表示返回值是个指针； <code>int (*f)()</code>:  是个指向函数的指针、函数返回值是int；<code>int *(*f)()</code>:    指向函数的指针、函数返回值为整形指针；<code>int *f[]</code>:   是个数组、元素是整形指针；<code>int (*f[])()</code>:  是个数组、数组元素为指针、指针类型为返回int的函数的指针；<code>int *(*f[])()</code>:  是个数组、数组元素为指针、指针类型为返回int*的函数的指针</p></li><li><p>复杂的类型转换符： 把声明中的变量名和末尾的分号去掉，剩余部分用括号“封装”即可</p></li></ul><ul><li>通过<code>-lname</code>选项告知编译器链接到<code>libname.so</code>函数库；始终将<code>-l</code>函数库选项放在命令行的最右端（首先需要让文件包含未解析的引用）</li></ul><h1 id="位运算符等">14&emsp;位运算符等</h1><ul><li><p>用处：编写系统程序（编译器、操作系统）、加密程序、图形程序、需要高执行速度或高效利用空间的程序</p></li><li><p>C语言中其他进制的表示方式：</p></li><li><p>移位运算符：<code>&lt;&lt; 左移</code>、<code>&gt;&gt; 右移</code>：（为了可移植性，最好只对无符号数移位运算）</p><pre class="line-numbers language-c"><code class="language-c"><span class="token keyword">unsigned</span> <span class="token keyword">int</span> i<span class="token operator">=</span><span class="token number">13</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//1101</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> j<span class="token operator">=</span>i<span class="token operator">&lt;&lt;</span><span class="token number">13</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//110100</span><span class="token keyword">unsigned</span> <span class="token keyword">int</span> j<span class="token operator">=</span>i<span class="token operator">>></span><span class="token number">13</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//11</span>i<span class="token operator">&lt;&lt;=</span><span class="token number">2</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//会改变操作数</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>~</code>按位取反、一元运算符（一定要弄清有多少位）</p></li><li><p><code>&amp;</code>按位与、<code>^</code>按位异或、<code>|</code>按位或</p></li></ul><h1 id="标准库">15&emsp;标准库</h1><ul><li><p>求余数和商：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span>  </span><span class="token comment" spellcheck="true">//定义了div函数</span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;iostream></span></span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">auto</span> result <span class="token operator">=</span> <span class="token function">div</span><span class="token punctuation">(</span><span class="token number">25</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//返回div_t类型的一个结构</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span>cout <span class="token operator">&lt;&lt;</span> <span class="token string">"quot(商): "</span> <span class="token operator">&lt;&lt;</span> result<span class="token punctuation">.</span>quot <span class="token operator">&lt;&lt;</span> <span class="token string">" , rem(余数): "</span> <span class="token operator">&lt;&lt;</span> result<span class="token punctuation">.</span>rem           <span class="token operator">&lt;&lt;</span> std<span class="token punctuation">:</span><span class="token punctuation">:</span>endl<span class="token punctuation">;</span> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>程序运行时间获取：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;time.h></span></span>clock_t t1<span class="token operator">=</span><span class="token function">clock</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">/</span>CLOCKS_PER_SEC<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//开始运行到这个位置处花的时间，并转换为s</span><span class="token comment" spellcheck="true">//只是近似值</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="输入输出（高级、stdio-h）">16&emsp;输入输出（高级、stdio.h）</h1><ul><li><p>文件指针：定义在<code>stdio.h</code>中的派生类型，C语言会自动打开<code>stdin</code>、<code>stdout</code>、<code>stderr</code>三个标准文件。</p><pre class="line-numbers language-c"><code class="language-c"><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdio.h></span></span><span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">&lt;stdlib.h></span></span>FILE <span class="token operator">*</span>fp<span class="token punctuation">;</span><span class="token comment" spellcheck="true">// 返回空指针则说明打开文件失败</span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token punctuation">(</span>fp<span class="token operator">=</span><span class="token function">fopen</span><span class="token punctuation">(</span><span class="token string">"filename"</span><span class="token punctuation">,</span><span class="token string">"r"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">==</span><span class="token constant">NULL</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stdout</span><span class="token punctuation">,</span><span class="token string">"Can't open file.\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">exit</span><span class="token punctuation">(</span>EXIT_FAILURE<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token punctuation">(</span>ch<span class="token operator">=</span><span class="token function">getc</span><span class="token punctuation">(</span>fp<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">!=</span><span class="token constant">EOF</span><span class="token punctuation">)</span><span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">//判断是否到了文件末尾</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">fclose</span><span class="token punctuation">(</span>fp<span class="token punctuation">)</span><span class="token operator">!=</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 成功关闭返回0，否则返回EOF</span> <span class="token function">fprintf</span><span class="token punctuation">(</span><span class="token constant">stderr</span><span class="token punctuation">,</span><span class="token string">"Error closing file\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>rewind(fp)</code>  可以让程序回到文件开始处</p></li></ul><ul><li><p>windows下使用<code>fopen</code>等函数时注意路径的写法：使用<code>/</code>或者<code>\\</code>作为目录分隔符</p></li><li><p>通过<code>argv</code>传递命令行参数：</p><pre class="line-numbers language-c"><code class="language-c"><span class="token comment" spellcheck="true">// argc为argv长度，argv是指针数组，*argv[0]为程序名，之后如*argv[1]为命令行参数</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token keyword">int</span> argc<span class="token punctuation">,</span> <span class="token keyword">char</span> <span class="token operator">*</span>argv<span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-11-13-c-tips/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Vim常用命令学习</title>
      <link>https://chengpengzhao.com/2020-11-09-vim-chang-yong-ming-ling-xue-xi/</link>
      <guid>https://chengpengzhao.com/2020-11-09-vim-chang-yong-ming-ling-xue-xi/</guid>
      <pubDate>Mon, 09 Nov 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;a href=&quot;https://book.douban.com/subje
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><a href="https://book.douban.com/subject/25869486/" target="_blank" rel="noopener">《Vim使用技巧》</a>里面的东西还是挺多的，适合每天啃一点、来回品味。当然也有一些地方有更优解，总的来说是本好书，基本上书里讲的都能够理解的话vim也用的很熟练了吧。</p><h1 id="Vim基础">1&emsp;Vim基础</h1><ul><li><code>vim -u NONE -N</code>：不加载vimrc、不进入vi兼容模式</li><li>用<code>.</code>命令的时候注意：在<strong>插入模式</strong>移动光标会<strong>重置</strong>修改状态！</li><li><code>C</code>   删除当前光标至行尾，并进入insert模式</li><li><code>S</code>   删除整行并进入insert</li><li><code>I</code>   移至行开头并进入inset； <code>A</code> 移至行尾并进入inset</li><li><code>0</code> 移动到开头，<code>^</code>移动到开头非空格处，<code>$</code>移动到行尾</li><li><code>cw</code>  删除光标位置到单词结尾间的字符</li><li><code>w</code> 跳转到下个单词开头，<code>b</code>跳转到上个单词开头，<code>e</code>跳转到下个单词结尾</li></ul><h1 id="普通模式">2&emsp;普通模式</h1><ul><li><p><code>&lt;C-a&gt;</code>和 <code>&lt;C-x&gt;</code> ：  数字加和减1（会把光标移到该行数字前)</p></li><li><p><code>10&lt;C-a&gt;</code> : 数字加10，上一条的补充</p></li><li><p><code>操作符+动作命令= 操作</code>：<br><code>g~</code>    改变大小写； <code>gu</code>   变为小写； <code>gU</code> 变为大写<br><code>gUaw</code>  把当前单词变为大写<br><code>~</code> 转换一个字母的大小写，同时光标后移一位<br><code>=</code>自动缩进有时挺好用</p></li><li><p><code>zz</code>  重绘屏幕，会把当前行移到屏幕中间</p></li><li><p><code>R</code>   进入替换模式，<code>gR</code>  虚拟替换模式、会将制表符当一组空格处理，  <code>&lt;Esc&gt;</code>返回普通模式</p></li></ul><h1 id="插入模式">3&emsp;插入模式</h1><ul><li><p><code>&lt;C-r&gt;{register}</code> 插入模式中粘贴寄存器内容</p></li><li><p><code>&lt;C-r&gt;&lt;C-p&gt;{register}</code>    相比上一条更智能，会修正不必要的缩进</p></li><li><p><code>&lt;C-r&gt;=</code>  表达式寄存器，可以做一些简单运算</p></li><li><p><code>&lt;C-r&gt;/</code>  把上次查找内容粘贴出来</p></li></ul><h1 id="可视模式">4&emsp;可视模式</h1><ul><li><p><code>gv</code>  重选上次的高亮选区； <code>o</code>    切换高亮选区的活动端</p></li><li><p>如果想构造能重复执行的工作，最好远离可视模式</p></li><li><p>常用文本对象(基础及扩展):</p><ol><li><code>w</code>  单词； <code>W</code>  字符串</li><li><code>s</code>  句子(以<code>.</code>为分隔符)；   <code>p</code> 段落(以空行为分隔符)</li><li><code>( [ { &lt;</code>    用另一半也行</li><li><code>t</code>  一个标签(tag,<code>html/xml</code>用)</li><li><code>i</code>  <code>textobj-indent</code>插件提供，选取缩进相同的一段文本</li><li><code>f</code>  <code>textobj-function</code>插件提供，选取一个函数</li><li><code>,</code>  <code>textobj-parameter</code>插件提供，选取函数的一个参数(<code>vi,</code> 不包括逗号)</li></ol></li></ul><h1 id="命令行模式">5&emsp;命令行模式</h1><ul><li><p>在多行上执行命令：</p><ol><li><code>:1</code> 跳转到行号处； <code>:$</code> 跳转到末尾； <code>:3d</code>  跳转并删除第3行</li><li><code>.</code> 表示当前行； <code>%</code> 表示<strong>所有行</strong>；  <code>1,$</code> 表示从第1行到末尾； <code>&#39;a</code> 表示位置标记a所在行；<code>0</code> 表示虚拟行、在第1行上方</li><li><code>/pattern/</code> 搜寻并跳转含有pattern的行； <code>/&lt;html&gt;/+1,/&lt;\/html&gt;/-1p</code> 可以进行<code>:{address}+n</code>类似的偏移(p命令表示print)</li></ol></li><li><p><code>:copy / :t</code>  复制命令； <code>:[range]copy {address}</code> 使用范例：</p><ol><li><code>:t6</code> 复制当前行到第六行； <code>:.t0</code>  复制当前行到第一行上方</li><li>此命令不会使用寄存器，这是它的优势。</li></ol></li><li><p><code>:move / :m</code> 移动行； <code>:[range]move {address}</code></p></li><li><p><code>@:</code> 重复上次的Ex命令；<code>&amp;</code>重复上次的<code>:substitute</code>命令</p></li><li><p><code>:[range]normal {command}</code>     对范围内每一行同时执行命令，如<code>:% normal A;</code>表示对所有行执行<code>A;</code>命令（跳到行尾加一个<code>;)</code>。修改完后会<strong>自动</strong>返回普通模式；注意<code>normal</code>命令执行前会把光标移到改行起始处</p></li><li><p><code>:&lt;C-r&gt;&lt;C-w&gt;</code>     将当前光标下的单词插入到命令行中（类似的有<code>&lt;C-r&gt;&lt;C-a&gt;</code>，范围更广）</p></li><li><p><code>q:</code>      普通模式下调出命令行窗口，每一行可以编辑，在某行按<code>&lt;CR&gt;</code>就会执行该行命令。（在命令行模式下按<code>&lt;C-f&gt;</code>也可进入命令行窗口）类似的也有<code>q/</code>：打开查找命令历史记录的命令行窗口</p></li><li><p><code>:!</code>  运行外部shell命令，符号<code>%</code>可用来代表当前文件名</p></li><li><p><code>&lt;C-z&gt;</code>把vim挂起到后台、<code>fg</code>唤醒一个被挂起的作业</p></li><li><p><code>:read !{cmd}</code>    把shell命令的输出读入到当前缓冲区</p></li><li><p><code>:write !sh</code>   缓冲区作为sh命令执行，<code>!</code>和<code>sh</code>间可以有空格 <code>write</code>和<code>!</code>之间一定有空格；<code>:write! sh</code>  将缓冲区内容写入名为<code>sh</code>的文件中</p></li><li><p><code>read</code>、<code>write</code>命令前都可加<code>[range]</code>约束</p></li></ul><h1 id="文件">6&emsp;文件</h1><ul><li><p>缓冲区（Buffer）中，<code>%</code>代表当前可见窗口，<code>#</code>代表轮换文件（<code>:ls</code>命令访问缓冲区，文件开头的数字为自动分配的编号）</p></li><li><p>在Vim中用 <code>:args filename</code> 打开（新建）一个文件，并添加到缓冲区</p></li><li><p>Glob模式： <code>*</code>代表当前目录所有文件，<code>**</code><strong>递归</strong>匹配子目录并找到所有文件，如<code>**/*.js</code>能匹配到该目录下所有js文件</p></li><li><p>:args `cat filename` ，将会把反引号里的shell命令执行结果作为args的参数，<code>args</code>命令，不接文件名显示当前所有缓冲区名、接文件名会新打开所匹配的文件到缓冲区</p></li><li><p><code>:on(ly)</code>或者<code>&lt;C-w&gt;o</code>， 只保留活动窗口，关闭其他</p></li><li><p><code>&lt;C-w&gt;=</code>  使窗口等宽等高； <code>&lt;C-w&gt;_</code>   最大化活动窗口高度； <code>&lt;C-w&gt;|</code>   最大化活动窗口宽度</p></li><li><p><code>&lt;C-w&gt;T</code>  打开新标签页, <code>{N} gt(/gT)</code> 标签页间跳转， <code>:tabm(ove) {N}</code> 将当前标签页移到N位置，N=0时为开头位置，N省略时为结尾</p></li><li><p><code>:!mkdir -p %:h</code>   把文件保存到不存在的目录中。其中<code>-p</code>表示创建任何不存在的中间目录、<code>%:h</code>表示当前缓冲区完整文件路径（去除文件名）</p></li><li><p><code>:wall</code>   保存缓冲区列表所有文件</p></li></ul><h1 id="更快地移动及跳转">7&emsp;更快地移动及跳转</h1><ul><li><p><code>gj</code> 往下移动一个屏幕行（非实际行）；其他移动命令同理在前面加个<code>g</code>表示按屏幕行移动</p></li><li><p>基于单词的移动。 单词开头：<code>w</code>、<code>b</code> ， 单词结尾：<code>e</code>、<code>ge</code>；（大写时则变成基于子串的移动）</p></li><li><p><code>m{letter}</code>创建位置标记，大写字母时为全局标记、小写是局部缓冲区标记</p></li><li><p>Vim中的自动位置标记（ `和&#39;都能跳转，但&#39;只能跳转到行、需要具体到列时最好用`）：</p><ol><li>`` : 上次跳转动作前的位置（结合<code>%</code>命令很好用）,<code>&lt;C-o&gt;</code>命令也能完成这一功能</li><li>`. ：上次修改的地方</li><li>`^ : 上次插入的地方</li><li>`[ : 上次修改或复制的起始位置（ `]为结束位置）</li><li>`&lt; : 上次高亮选区的起始位置 （`&gt;为结束位置）。</li></ol></li><li><p><code>surround.vim</code>插件使用：</p><ol><li><code>ds[...]</code>，如<code>ds&quot;</code>表示删除一对<code>&quot;</code>符号（<code>s</code>代表surround）</li><li><code>cs[...][...]</code>，如<code>cs&quot;(</code>表示将一对<code>&quot;</code>符号改为<code>()</code></li><li><code>ysiw]</code>，给一个单词两侧加一个<code>[]</code></li><li><code>yss&quot;</code>，给该行套一个<code>&quot; &quot;</code></li><li>可视模式下<code>S(</code>，给所选范围外部套一个<code>()</code></li></ol></li></ul><h1 id="文件间跳转">8&emsp;文件间跳转</h1><ul><li><code>H/M/L</code>   跳到屏幕最上方/正中间/最下方</li><li><code>gf</code>  跳到光标下文件名(go to file)</li><li><code>&lt;C-]&gt;</code>   跳到光标下关键字定义处</li><li><code>&lt;C-i&gt;</code>等价于<code>&lt;Tab&gt;</code></li></ul><h1 id="寄存器">9&emsp;寄存器</h1><ul><li><p>vim常见的操作会将内容拷贝到<strong>无名寄存器</strong><code>&quot;&quot;</code>，<code>&quot;&quot;p</code>等价于<code>p</code></p></li><li><p>命令前加<code>&quot;{register}</code> 指定寄存器，如<code>&quot;ayiw</code>、<code>&quot;bdd</code></p></li><li><p>寄存器用<strong>大写字母</strong>时表示把内容附加到指定寄存器后，而小写字母是覆盖原有内容</p></li><li><p>复制专用寄存器<code>&quot;0</code>，被复制的文本(<code>y</code>命令)会同时拷贝到无名寄存器和该专用寄存器中</p></li><li><p>系统剪贴板<code>&quot;+</code>、选择专用寄存器<code>&quot;*</code>（保存上次<code>v</code>命令选择的区域）</p></li><li><p><code>p</code>粘贴到当前光标后，<code>P</code>粘贴到光标前；插入模式中用<code>&lt;C-r&gt;{register}</code>或许更方便</p></li></ul><h1 id="宏、模式">10&emsp;宏、模式</h1><ul><li><p><code>@@</code>重复最近调用过的宏</p></li><li><p><code>:put a</code>，粘贴寄存器<code>&quot;a</code>的内容到新行，可用来编辑录制好的宏</p></li><li><p><code>qaq</code> ，录制一个空的宏，起到清空寄存器的作用</p></li><li><p>vim中的正则表达式：</p><ol><li><code>magic</code>模式，使用\m前缀，<code>^，$，.，*和[]</code>等字符含有特殊意义；而<code>+、?、()、和{}</code>等其它字符则按字面意义解释。magic为默认设置，表达式中的\m前缀可以省略； </li><li><code>no magic</code>模式，使用\M前缀，除了<code>^和$</code>之外的特殊字符，都将被视为普通文本； </li><li><code>very magic</code>模式，使用\v前缀，其后模式中除 <code>&#39;0&#39;-&#39;9&#39;，&#39;a&#39;-&#39;z&#39;，&#39;A&#39;-&#39;Z&#39; 和 &#39;_&#39;</code>之外的字符都当作特殊字符解释； </li><li><code>very nomagic</code>模式，使用\V前缀，其后模式中只有反斜杠（<code>\</code>）具有特殊意义，用于原义查找。</li></ol></li><li><p>vim正则表达式匹配重复部分：<code>()</code>与<code>\1</code>组合使用（引用第1-9个括号内容，0引用整个匹配）</p></li><li><p>强大的替换命令<code>:[range]s[ubstitute]/{pattern}/{string}/[flags]</code>； flags: <code>g</code>全局范围、<code>c</code>每次修改前确认、<code>n</code>抑制替换、<code>&amp;</code>用上一次的flag</p></li><li><p>查找和替换可以分开来，先用<code>/</code>查找、再用<code>%s//{...}/g</code>进行替换(<code>{pattern}</code>部分留空表示自动使用当前查找模式)</p></li></ul><h1 id="global命令">11&emsp;global命令</h1><ul><li><p><code>[range] g[lobal][!] /{pattern}/ [cmd]</code>，默认范围为<code>%</code>、默认<code>cmd</code>为<code>print</code>，该命令用于在<strong>所有匹配行</strong>上运行Ex命令</p></li><li><p><code>vglobal</code>或简写<code>:v</code>，在非匹配行上执行Ex命令、不修改匹配行</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-11-09-vim-chang-yong-ming-ling-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>NHK72h补全计划</title>
      <link>https://chengpengzhao.com/2020-10-16-nhk72h-bu-quan-ji-hua/</link>
      <guid>https://chengpengzhao.com/2020-10-16-nhk72h-bu-quan-ji-hua/</guid>
      <pubDate>Fri, 16 Oct 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;都说互联网是有记忆的，每当我寻找以前看过的某集记录片却发现被全网下架了的时候
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>都说互联网是有记忆的，每当我寻找以前看过的某集记录片却发现被全网下架了的时候就会开始质疑这句话。但后来一想，记忆本身就不是什么可靠的东西，会被遗忘、被美化、被篡改。<br><strong>ドキュメント72時間</strong>（NHK纪实72小时）是我一直唯一坚持看的纪录片。一方面内容比较贴近生活、能学到些当地文化，作为练口语和听力的材料也是很好的。<br>这里要感谢下每期提供资源的那些人（还有字幕组），自己租个网络电视台实在太贵；之前主要都是在b站上看，不过现在b站上很多资源都被删干净了，想找个之前一期全网搜都搜不到（我还去<a href="https://www.nhk-ondemand.jp/#/0/" target="_blank" rel="noopener">NHKオンデマンド</a>专门办了一个月会员）。<br>附几个我关注的经常传NHK纪录片的up主：<a href="https://space.bilibili.com/11468835/dynamic" target="_blank" rel="noopener">沧澜049</a>、<a href="https://space.bilibili.com/172070343/dynamic" target="_blank" rel="noopener">元气美少女字幕组</a>、<a href="https://space.bilibili.com/26747324/dynamic" target="_blank" rel="noopener">海老板家de大抽</a>……</p><p><br><br><br>于是某一天，我有了一个阴暗的想法，将每一期全部下载保存到NAS里。下面是<strong>NHK72h补全计划</strong>的目前进度：</p><p>[x] 2006年10月03日放送「東京 神宮外苑 100万人の花火大会」<br>[x] 2006年10月10日放送「東京 山谷 バックパッカーたちのTOKYO」<br>[x] 2006年10月17日放送「東京駅高速バスターミナル」<br>[ ] 2006年10月24日放送「新宿東口 献血ルーム」<br>[ ] 2006年10月31日放送「タクシー 本音の会話 東京編」<br>[ ] 2006年11月07日放送「タクシー 本音の会話 札幌編」<br>[x] 2006年11月14日放送「横浜中華街 青春グラフィティ」<br>[ ] 2006年11月21日放送「六本木 ひと坪オフィス」<br>[ ] 2006年11月28日放送「東名高速 足柄サービスエリア」<br>[x] 2006年12月05日放送「埼玉 となりのイスラム教徒」<br>[ ] 2006年12月12日放送「大阪医療センター 患者たちの相談室」</p><hr><p>[ ] 2007年01月09日放送「西銀座 宝くじ売り場」<br>[ ] 2007年01月16日放送「大阪 心斎橋のホームランキング」<br>[x] 2007年01月23日放送「コンビニのメリークリスマス」<br>[x] 2007年01月30日放送「上野アメ横 マンガ喫茶」<br>[x] 2007年02月06日放送「年始め ゴミ収集大作戦」<br>[x] 2007年02月13日放送「リゾートバイト 冬物語」<br>[x] 2007年02月20日放送「名古屋 大盛況！ リサイクルショップ」<br>[x] 2007年03月06日放送「福岡 人情屋台通り」<br>[x] 2007年03月13日放送「旅立ちのフェリー」</p><hr><p>[ ] 2012年07月03日放送「東北自動車道 あだたらサービスエリア」<br>[ ] 2012年07月10日放送「新大久保 国境なき八百屋さん」<br>[ ] 2012年07月17日放送「札幌すすきの24時間にぎりめし屋」<br>[x] 2012年07月19日放送「福岡博多 巨大クルーズ船来航」</p><hr><p>[x] 2013年04月05日放送「密着 歌舞伎町の眠らない花屋」<br>[ ] 2013年04月12日放送「さよなら渋谷?カマボコ駅舎」<br>[ ] 2013年04月19日放送「大阪 串カツエレジー」<br>[ ] 2013年04月26日放送「横須賀基地 お見合い大作戦」<br>[x] 2013年05月03日放送「旅立ちの新千歳空港」<br>[ ] 2013年05月10日放送「工場閉鎖の街で」<br>[ ] 2013年05月17日放送「熱唱！ひとりカラオケ」<br>[ ] 2013年05月24日放送「京都 縁切り神社」<br>[ ] 2013年05月31日放送「夜間救急 果てなき戦い」<br>[ ] 2013年06月07日放送「ネット生中継な人たち」<br>[ ] 2013年06月14日放送「ファミレス人生劇場」<br>[x] 2013年06月21日放送「“地下アイドル”の青春」<br>[ ] 2013年06月28日放送「高知競馬場に夢が咲く」<br>[ ] 2013年07月05日放送「巨大マンボウの前で」<br>[ ] 2013年07月19日放送「最後の避難所から」<br>[ ] 2013年07月26日放送「富士山登山口から」<br>[ ] 2013年08月02日放送「雨のち晴れ コインランドリー物語」<br>[ ] 2013年09月06日放送「健康ランドの“幸福論”」<br>[ ] 2013年09月13日放送「大阪?西成 貸しロッカーブルース」<br>[ ] 2013年09月20日放送「真夏のお墓参り 異人たちとの対話」<br>[ ] 2013年09月27日放送「飛べ！イプシロン」<br>[ ] 2013年10月04日放送「よしもと 正念場の夏合宿」<br>[ ] 2013年10月11日放送「汗と涙の24時間スポーツジム」<br>[ ] 2013年10月18日放送「何をつかむ？巨大ゲームセンター」<br>[x] 2013年10月25日放送「パウダールーム 女のホンネ」<br>[x] 2013年11月01日放送「“広島太郎”を探して」<br>[ ] 2013年11月08日放送「瀬戸内海ヒッチハイク漂流記」<br>[ ] 2013年11月15日放送「砂丘に呼びよせられて」<br>[ ] 2013年11月22日放送「新宿 巨大旅行カウンター」<br>[ ] 2013年12月06日放送「消印有効24時間マンモス郵便局」<br>[ ] 2013年12月13日放送「“縁結び列車”に乗って」<br>[x] 2013年12月20日放送「巨大書店?活字の森の歩き方」</p><hr><p>[x] 2014年01月10日放送「地方プロレス?3日間の旅巡業」<br>[ ] 2014年01月17日放送「260人の巨大シェアハウス」<br>[x] 2014年01月24日放送「激闘！起業家コンテスト」<br>[x] 2014年02月28日放送「最北のバス停で」<br>[x] 2014年03月07日放送「沖縄 眠らない床屋」<br>[x] 2014年03月14日放送「福島 早春のスーパーから」<br>[x] 2014年04月04日放送「密着！街角の写真プリント機」<br>[x] 2014年04月11日放送「巨大フェリーの人生航路」<br>[ ] 2014年04月18日放送「消費増税！24時間ディスカウントストア」<br>[x] 2014年04月25日放送「スカイツリーのふもとで」<br>[x] 2014年05月02日放送「若者ハローワークの青春」<br>[x] 2014年05月09日放送「上野公園?満開の桜の下には」<br>[x] 2014年05月23日放送「大都会?真夜中の大衆食堂」<br>[ ] 2014年05月30日放送「トランクルーム もうひとつの秘密の部屋」<br>[x] 2014年06月06日放送「恐山 死者たちの場所」<br>[x] 2014年06月13日放送「オン?ザ?ロード 国道16号の“幸福論”」<br>[x] 2014年07月04日放送「南国の不夜城24時間超巨大スーパー」<br>[x] 2014年07月18日放送「湘南?海を見つめる理由」<br>[x] 2014年07月25日放送「どしゃ降りのガソリンスタンドで」<br>[ ] 2014年08月01日放送「深夜の釣堀で見る夢は」<br>[x] 2014年08月22日放送「眠らぬ都会の動物病院」<br>[x] 2014年08月29日放送「歌舞伎町ネイルサロン 女の楽屋裏」<br>[x] 2014年09月05日放送「夏?原発に一番近い駅」<br>[x] 2014年09月12日放送「原爆ドームの見える岸辺で」<br>[x] 2014年09月19日放送「大病院の小さなコンビニ」<br>[x] 2014年10月03日放送「羽田空港 夏から秋へ」<br>[x] 2014年10月10日放送「ディープ浅草?真夜中の喫茶店」<br>[x] 2014年10月17日放送「上野アメ横?多国籍地下マーケット」<br>[ ] 2014年10月24日放送「何を打つのか 雑居ビルのボクシングジム」<br>[ ] 2014年10月31日放送「高円寺?何を求めて銭湯へ」<br>[ ] 2014年11月07日放送「山手線一周徒歩の旅?東京都心の“幸福論”」<br>[x] 2014年11月21日放送「木更津 湾岸?大盛り弁当屋ブルース」<br>[ ] 2014年11月28日放送「さすらいの“シャケバイ”」<br>[ ] 2014年12月12日放送「大阪ミナミ?真夜中のアングラ長屋」<br>[x] 2014年12月19日放送「新宿二丁目?深夜のおふくろの味」</p><hr><p>[x] 2015年01月09日放送「出産ラッシュ！日本一の産婦人科」<br>[x] 2015年01月16日放送「さらば！都心のボウリング場」<br>[x] 2015年01月23日放送「名古屋 地下街?聖なる夜の忘れ物」<br>[x] 2015年01月30日放送「北の大地の学生寮」<br>[x] 2015年02月06日放送「金券ショップでつかむ幸せは」<br>[ ] 2015年02月13日放送「便利屋、都会を走る」<br>[x] 2015年02月20日放送「赤羽 おでん屋エレジー」<br>[ ] 2015年02月27日放送「神戸?1月、パイ山で会いましょう」<br>[x] 2015年03月06日放送「秋田 真冬の自販機の前で」<br>[x] 2015年03月13日放送「自動車教習所 それぞれの旅路」<br>[ ] 2015年03月20日放送「日焼けサロン 小麦色の理由」<br>[x] 2015年04月03日放送「カプセルホテル ワンダーランド」<br>[x] 2015年04月10日放送「タクシー本音の会話～福島いわき編～」<br>[ ] 2015年04月17日放送「コスプレ専門ビル 彼女たちの夢の城」<br>[ ] 2015年04月24日放送「中古車から始まる人生は」<br>[x] 2015年05月01日放送「桜をたどって川上へ 多摩川3日間の旅」<br>[ ] 2015年05月08日放送「屋久島 巨木に集う人々」<br>[x] 2015年05月15日放送「駄菓子屋 子どもたちの小さな宇宙」<br>[x] 2015年05月22日放送「六本木?ケバブ屋 異邦人たちの交差点」<br>[ ] 2015年05月29日放送「高尾山?なぜかふらりと都会の山へ」<br>[x] 2015年06月05日放送「海辺の街のコンテナカラオケ」<br>[x] 2015年06月12日放送「大型連休?レンタルビデオ店で描く夢」<br>[x] 2015年06月19日放送「沖縄?追憶のアメリカンドライブイン」<br>[x] 2015年06月26日放送「ウワサの猫と商店街」<br>[x] 2015年07月03日放送「“はなキャバ”人生劇場」<br>[x] 2015年07月10日放送「福岡?久留米 とんこつラーメン物語」<br>[ ] 2015年07月17日放送「東京?下町 男と女のダンスホール」<br>[x] 2015年07月24日放送「路面電車に揺られて」<br>[ ] 2015年07月31日放送「田んぼの中のオアシスホテル」<br>[x] 2015年08月21日放送「ニューヨーク コインランドリー劇場」<br>[x] 2015年08月28日放送「中国?大連 日本食材スーパーで」<br>[x] 2015年09月04日放送「大仏を見上げる霊園で」<br>[x] 2015年09月18日放送「夏コミ！“日本一”のコンビニで」<br>[ ] 2015年10月02日放送「夏の終わり 国会前の路上で」<br>[x] 2015年10月09日放送「老舗ホテル また会う日まで」<br>[x] 2015年10月23日放送「旅漁師 イカ釣り人生」<br>[x] 2015年10月30日放送「ディープ東京 リトルマニラの片隅で」<br>[x] 2015年11月06日放送「街角のダビング店 よみがえる映像」<br>[x] 2015年11月13日放送「格安航空 眠らない空港で」<br>[x] 2015年11月27日放送「歌舞伎町 真夜中の調剤薬局」<br>[ ] 2015年12月04日放送「世界最大 古書の迷宮へようこそ」<br>[x] 2015年12月11日放送「占いの館 運命の交差点」<br>[x] 2015年12月18日放送「秋葉原 秘密の工房で」</p><hr><p>[x] 2016年01月08日放送「横浜 オールナイトでとんかつを」<br>[x] 2016年01月15日放送「東京かっぱ橋 食の道具街で」<br>[x] 2016年01月22日放送「札幌 聖夜のバスターミナル」<br>[x] 2016年01月29日放送「東京タワーで見る初夢は」<br>[x] 2016年02月19日放送「大阪?天神橋筋 商店街のベンチにて」<br>[x] 2016年02月26日放送「真冬の東京 その名は“はな子”」<br>[x] 2016年03月04日放送「冬?津軽 100円の温泉で」<br>[x] 2016年03月18日放送「恋に恋して バレンタイン神社」<br>[x] 2016年04月01日放送「日韓72時間 くらべちゃいましたSP」<br>[x] 2016年04月08日放送「昭和歌謡に引き寄せられて」<br>[x] 2016年04月15日放送「大都会 犬と猫のシェルターで」<br>[x] 2016年04月22日放送「さらば！俺たちの船橋オート」<br>[x] 2016年04月29日放送「秋田 真冬の自販機の前で?惜別編」<br>[x] 2016年05月06日放送「北のどんぶり飯物語」<br>[ ] 2016年05月13日放送「異国でハンコをたずさえて」<br>[x] 2016年05月20日放送「群馬 伊勢崎 いつものフードコートで」<br>[x] 2016年06月03日放送「ゆきゆきて 酷道439」<br>[x] 2016年06月17日放送「火山の島 フェリーにゆられて行ったり来たり」<br>[ ] 2016年06月24日放送「浅草 大人のジェットコースター」<br>[x] 2016年07月01日放送「京都 青春の鴨川デルタ」<br>[x] 2016年07月08日放送「囲碁の魔力に囚（とら）われて」<br>[ ] 2016年07月15日放送「広島 大統領を待つ街角で」<br>[x] 2016年07月22日放送「名古屋 レトロ喫茶へようこそ」<br>[ ] 2016年07月28日放送「突撃！ 秘密のネットオークション」<br>[x] 2016年08月04日放送スペシャル「ブラジル 祈り満つる秘密の聖地で」<br>[x] 2016年09月16日放送「女子刑務所 彼女たちの素顔」<br>[x] 2016年09月23日放送「長崎 お盆はド派手に花火屋で」<br>[x] 2016年09月30日放送「福井 真夏の無人氷屋」<br>[x] 2016年10月07日放送「大都会 モンスターに沸く公園で」<br>[x] 2016年10月14日放送「平塚 多国籍のお肉屋さん」<br>[x] 2016年10月21日放送「四国 海だけの小さな駅で」<br>[ ] 2016年10月28日放送「黄昏（たそがれ）のゴルフ打ちっ放し」<br>[ ] 2016年11月04日放送「夢見る巨大画材店」<br>[ ] 2016年11月11日放送「北アルプス 天空のテント村」<br>[x] 2016年11月18日放送「福岡?中洲 真夜中の保育園」<br>[x] 2016年11月25日放送「村長選挙 旅する投票箱」<br>[x] 2016年12月02日放送「六本木ハロウィーン 仮面の告白」<br>[x] 2016年12月16日放送「沖縄 7000人のウチナーンチュ大会」</p><hr><p>[x] 2017年01月13日放送「成田 聖夜の入国審査場」<br>[x] 2017年01月20日放送「なぜか大宮 喫茶店は待っている」<br>[x] 2017年01月27日放送「宮崎 路上ピアノが奏でる音は」<br>[x] 2017年02月10日放送「別府 百年の温泉で」<br>[x] 2017年02月17日放送「横須賀 軍艦の見える公園で」<br>[x] 2017年02月24日放送「激安肌着 ぬくもりを探して」<br>[ ] 2017年03月03日放送「黄金の串カツに願いを」<br>[x] 2017年03月10日放送「キリンが見える散歩道」<br>[x] 2017年03月17日放送「香港 チョンキンマンションへようこそ」<br>[x] 2017年04月07日放送「運命の七差路」<br>[x] 2017年04月14日放送「春 街角のかばん店で」<br>[x] 2017年04月21日放送「都会の小さいお葬式」<br>[x] 2017年04月28日放送「金剛山 ライブカメラの山頂で」<br>[x] 2017年05月12日放送「夜の森 桜のトンネルで」<br>[x] 2017年05月19日放送「生地とボタンと私」<br>[x] 2017年05月26日放送「禅寺修行、始めてみました。」<br>[x] 2017年06月02日放送「白い秘密の婚活ルーム」<br>[x] 2017年06月09日放送「東京渋谷 モスクで会いましょう」<br>[x] 2017年06月16日放送「ゆらゆら くらげに誘われて」<br>[x] 2017年06月30日放送「トラック一人旅 風に吹かれて」<br>[x] 2017年07月07日放送「空の密室 屋上観覧車」<br>[ ] 2017年07月14日放送「北九州 小倉 “百円酒場”のブルース」<br>[x] 2017年07月21日放送「巨大団地 中古ショップでハロー?グッバイ」<br>[x] 2017年07月28日放送「海が見える老人ホーム」<br>[x] 2017年08月25日放送「山奥の不夜城レストラン」<br>[x] 2017年09月01日放送「夏の甲子園 もうひとつの青春」<br>[x] 2017年09月15日放送「真夏の秋田 ババのアイスが恋しくて」<br>[x] 2017年09月22日放送「男が靴を磨くとき」<br>[x] 2017年09月29日放送「基地の町 大人のロックフェス」<br>[x] 2017年10月06日放送「それでもバイクで走る理由」<br>[x] 2017年10月20日放送「渋谷 スマホ修理店」<br>[x] 2017年10月27日放送「京都 静かすぎる図書館」<br>[x] 2017年11月03日放送「スペイン?カナリア諸島 マグロ漁師の短いバカンス」<br>[x] 2017年11月10日放送「英会話教室でシーユーアゲイン」<br>[x] 2017年11月17日放送「ゲストハウス 1泊3千円のオアシス」<br>[x] 2017年11月24日放送「“コリ”にまつわるエトセトラ」<br>[x] 2017年12月01日放送「今夜も、もう一枚 24時間印刷店」<br>[x] 2017年12月08日放送「小笠原諸島 週に1度の宅配便」<br>[x] 2017年12月15日放送「根室 “ほっこり弁当”冬物語」</p><hr><p>[x] 2018年01月12日放送「新宿?花園神社 夢は、夜ひらく」<br>[x] 2018年01月19日放送「眠らないパン屋 聖夜の贈り物」<br>[x] 2018年01月26日放送「津軽海峡 年越しフェリー」<br>[x] 2018年02月02日放送「伝説のゲーセン 大人たちの闘い」<br>[x] 2018年03月02日放送「COOL！下町 浅草?バッティングセンター」<br>[x] 2018年03月16日放送「渋谷 春の花から物々交換」<br>[x] 2018年04月06日放送「大空に飛行機を見上げて」<br>[x] 2018年04月13日放送「大都会ねずみパトロール」<br>[x] 2018年04月20日放送「東北 春を探して 国道45号線を行く」<br>[x] 2018年04月27日放送「街角の法律相談所」<br>[x] 2018年05月11日放送「旅する美容室」<br>[x] 2018年05月18日放送「島へ 山へ 走る図書館」<br>[x] 2018年05月25日放送「春の日本海 ホタルイカを待ちながら」<br>[x] 2018年06月01日放送「大阪?西成 24時間夫婦食堂」<br>[x] 2018年06月08日放送「1円パチンコに哀歓あり」<br>[x] 2018年06月15日放送「百貨店 化粧品フロアの女たち」<br>[x] 2018年06月22日放送「秋田“いのちの温泉”に集う人々」<br>[x] 2018年07月13日放送「バク転教室 明日に向かって跳べ！」<br>[x] 2018年07月20日放送「日本ダービー大行列」<br>[x] 2018年07月27日放送「命を運ぶ 大病院の引っ越し」<br>[x] 2018年08月03日放送「さよなら！ 私の愛した百貨店」<br>[x] 2018年08月24日放送「東京湾 真夏の海釣り公園」<br>[x] 2018年08月31日放送「関門海峡 海底トンネル」<br>[x] 2018年09月07日放送「海上保安学校 青春グラフィティー」<br>[x] 2018年09月21日放送「東京?新橋 ジューススタンド夏物語」<br>[x] 2018年09月28日放送「海外送金所から愛をこめて」<br>[x] 2018年10月05日放送「渋谷 “アムラーの聖地”へ」<br>[x] 2018年10月26日放送「函館 ハンバーガーと幸せと」<br>[x] 2018年11月02日放送「東京駅 “銀の鈴”で会いましょう」<br>[x] 2018年11月09日放送「さらば築地市場 いつもの立ち食いそば屋で」<br>[x] 2018年11月16日放送「3333段 日本一の石段の先には」<br>[x] 2018年11月30日放送「滋賀?草津 巨大パーキングエリア」<br>[x] 2018年12月07日放送「ニュータウンのホームセンター DIYな人々」<br>[x] 2018年12月14日放送「広島 作業服店 そこに現場があるから」</p><hr><p>[x] 2019年01月11日放送「新宿?音楽スタジオ ぼくらがバンドを組む理由」<br>[x] 2019年01月18日放送「仙台 出会いを求めて“相席ラウンジ”」<br>[x] 2019年01月25日放送「成田空港 格安航空会社（LCC）専用ターミナルで」<br>[x] 2019年02月01日放送「真冬のキャンプ場 富士山を眺めながら」<br>[x] 2019年02月15日放送「冬の東京 たい焼きエレジー」<br>[x] 2019年02月22日放送「大阪 道頓堀で物々交換」<br>[x] 2019年03月01日放送「旭川?宝くじ売り場 吹雪の中で見る夢は」<br>[x] 2019年03月15日放送「福岡 早春の不動産屋で」<br>[x] 2019年04月12日放送「密着！ 巨大転職フェア」<br>[x] 2019年04月19日放送「大阪?渡し船 片道1分の人生航路」<br>[x] 2019年04月26日放送「密着！“レンタル なんもしない人”」<br>[x] 2019年05月10日放送「長崎?五島列島 さよならフェリー」<br>[x] 2019年05月17日放送「学生街?高田馬場 いつかの“青春ロータリー”で」<br>[x] 2019年05月24日放送「樹木葬 桜の下のあなたへ」<br>[x] 2019年05月31日放送「眠らない巨大貨物ターミナル」<br>[x] 2019年06月07日放送「渋谷郵便局 街角の“平成史”」<br>[x] 2019年06月21日放送「“サバゲー”を生きる人たち」<br>[x] 2019年06月28日放送「断食 空腹の向こうがわ」<br>[x] 2019年07月05日放送「東京?阿佐ヶ谷 金魚の池のほとりには」<br>[x] 2019年07月26日放送「新宿 ウイッグ専門店」<br>[x] 2019年08月02日放送「神戸?激安靴店を歩けば」<br>[x] 2019年08月09日放送「クライミングジム 上を向いて登ろう」<br>[x] 2019年08月30日放送「沖縄?自動車学校 免許の先に見る夢は」<br>[x] 2019年09月06日放送「さらば東京！ 移住相談センター」<br>[x] 2019年09月13日放送「梅雨明けのコイン洗車場で」<br>[x] 2019年09月20日放送「訪問看護師 街をゆく」<br>[x] 2019年09月27日放送「熊本?阿蘇 10年に1度のバイク撮影会」<br>[x] 2019年10月11日放送「北の大地 献血バスが行く」<br>[x] 2019年10月18日放送「東京永田町 シェアオフィス」<br>[x] 2019年10月25日放送「夏の終わり ぐるっと大阪城公園」<br>[x] 2019年11月01日放送「中国?雲南省 カモメが見える都市公園」<br>[x] 2019年11月08日放送「福岡 泣いて笑って24時間歯医者」<br>[x] 2019年11月15日放送「銀座の酒屋の物語」<br>[x] 2019年11月22日放送「小さなウエディングストーリー」<br>[x] 2019年12月13日放送「長野 天空の絶景を眺めて」<br>[x] 2019年12月20日放送「尼崎 黄昏（たそがれ）のアミューズメント施設」</p><hr><p>[x] 2020年01月10日放送「激走400キロ！ 沖縄1周サバイバルラン」<br>[x] 2020年01月17日放送「青森?下北半島 “ワケあり”横丁」<br>[x] 2020年01月24日放送「秋葉原 電子部品に魅せられて」<br>[x] 2020年01月31日放送「宮崎 ナゾの巨大魚を追え！」<br>[x] 2020年02月07日放送「福島?浪江 ふるさとのスーパーで」<br>[x] 2020年02月14日放送「神戸 あの日のピアノを弾きながら」<br>[x] 2020年02月21日放送「東京?下町 24時間営業の焼き肉店」<br>[x] 2020年02月28日放送「“ヤンキー?インターン” 俺たち今日からスーツ着ます」<br>[x] 2020年03月06日放送「小さな屋台カフェ 千夜一夜物語」<br>[x] 2020年08月07日放送「ワークアウト！ 眠らない巨大スポーツジム」<br>[x] 2020年08月14日放送「星に願いを 都会の七夕まつり」<br>[x] 2020年09月04日放送「石川 なぎさドライブウェイ 思い出の砂浜で」<br>[x] 2020年09月11日放送「東京・タクシードライバー 街ゆく彼らの人生行路」<br>[x] 2020年09月18日放送「東京・隅田川 花火のない静かな夏に」<br>[x] 2020年09月25日放送「わたしが楽器を吹く理由」<br>[x] 2020年10月02日放送「としまえん 日本最古の回転木馬の前で」<br>[x] 2020年10月09日放送「園芸専門店 花と緑と幸せと」<br>[x] 2020年10月16日放送「歌舞伎町 さよなら人情キャバレー」<br>[x] 2020年10月23日放送「飲食店の厨(ちゅう)房機器 店主たちの夏」<br>[x] 2020年10月30日放送「川崎 丘の上の動物公園」<br>[x] 2020年11月06日放送「札幌・サンドイッチ店 24時間営業は続く」<br>[x] 2020年11月13日放送「アウトレット家具店 私が暮らしを変えるとき」<br>[x] 2020年11月20日放送「動物たちが眠る霊園で」<br>[ ] 2020年11月27日放送「ベッドタウンの小さなクリーニング店」<br>[ ] 2020年12月04日放送「石川 なぎさドライブウェイ 思い出の砂浜で」</p><p><br><br><br>2017年往前的实在是找不到了，如有资源欢迎各位大佬共享。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-10-16-nhk72h-bu-quan-ji-hua/#disqus_thread</comments>
    </item>
    
    <item>
      <title>VPS能做什么（总结几个我正在用的服务的配置过程）</title>
      <link>https://chengpengzhao.com/2020-08-03-vps-neng-yong-lai-zuo-shi-me/</link>
      <guid>https://chengpengzhao.com/2020-08-03-vps-neng-yong-lai-zuo-shi-me/</guid>
      <pubDate>Mon, 03 Aug 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;写在前面&quot;&gt;1&amp;emsp;写在前面&lt;/h1&gt;&lt;blockquote
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="写在前面">1&emsp;写在前面</h1><blockquote><p>VPS, Virtual Private Servers，中文即虚拟专用服务器  </p></blockquote><p>虽说入坑vps也有两年了，说来惭愧我至今仍分不清VPS、虚拟主机、云主机等一些专有名词的关系。<br>最近感觉自己对VPS的需求越来越高，入门级的小鸡已经空间不足了，故决定放弃续费几年前入手的bandwagon祖传vps。（翻出了最开始的账单，这种价位的搬瓦工现在也很少了、经常缺货中）<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200801220308.webp" alt><br>这段时间试了试阿里云（国内的话网站要备份，很多推荐国际站香港的服务器）、cloudcone（便宜，但感觉不稳），最终选择了大厂<a href="https://www.vultr.com/" target="_blank" rel="noopener">Vultr</a>的产品；一个月<code>$10</code>（我选的硅谷机房）还是有点心痛的，但至少方便管理些、所有服务都能放在一台机器上。<br>说到VPS、很多情况下还要牵涉到域名，我现在有两个域名：一个专门做博客、一个配置各种服务，都转移到了<a href="https://dash.cloudflare.com/" target="_blank" rel="noopener">cloudflare</a>上管理，域名续费一年的开支是<code>$8.18+$8.03</code>，累计起来每年要花近1000块,也算的上一笔不小的开支了（但相对于各种手游手一抖就是518,似乎也不算什么）。<br>那么回归正题，<strong>VPS能为我带来些什么呢？</strong> 记得最开始是fq、到后来的密码管理、网盘分享、webdv存文献、bt下载、NAS外网访问、qq机器人…<br>下面系统地记录一下自己用VPS搭建这些服务的步骤：（fq除外、我怕ip被封影响其他服务）  </p><h1 id="Bitwarden，密码管理服务">2&emsp;Bitwarden，密码管理服务</h1><p>之前的一篇<a href="https://chengpengzhao.com/2020-02-08-bitwarden-mi-ma-guan-li-ji-v2ray-da-jian/">post</a>有讲过具体搭建步骤，但废话比较多，我也懒得改了。新手还可以一看，和大佬一比也只能是班门弄斧了；<br>这次还是也顺便回顾下。</p><h2 id="安装docker、docker-compose">2.1&emsp;安装docker、docker-compose</h2><p>推荐去网上找一个一键安装脚本、省时省力，我在<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener">My_vimrc</a>（最初用来记录vim个人配置）这个仓库整理了一些折腾vps时用到的脚本，接下来讲到的一些配置文件也有放里面。  </p><h2 id="配置文件-docker-compose-yml">2.2&emsp;配置文件(docker-compose.yml)</h2><p>文件目录如下，其中<code>bw-data</code>中存放密码数据，最好及时备份，迁移到另一台vps时将这个文件夹拷贝覆盖就行。</p><pre class="line-numbers language-bash"><code class="language-bash">~/bitwarden├── bw-data│   ├── db.sqlite3│   ├── icon_cache│   ├── rsa_key.der│   ├── rsa_key.pem│   └── rsa_key.pub.der└── docker-compose.yml<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>docker-compose.yml</code>文件如下：</p><pre class="line-numbers language-yml"><code class="language-yml">version: "3"services:  bitwarden:    image: bitwardenrs/server    restart: always    ports:    - "8080:80"    - "8081:3012"    volumes:      - ./bw-data:/data    environment:      WEBSOCKET_ENABLED: "true"      SIGNUPS_ALLOWED: "false"          #允许注册，配置的时候打开，之后关闭就行      WEB_VAULT_ENABLED: "true"         #允许网页访问，配置好了可以关闭<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>其中左侧的<code>8080</code>端口（之后访问bitwarden的web页面所用端口）和<code>8081</code>端口（忘了啥用）可以随意改动，不过注意不要和其他服务端口冲突了（说个常识：http默认80端口、https默认443端口）。</p><h2 id="运行服务">2.3&emsp;运行服务</h2><p>在 <code>docker-compose.yml</code>目录下运行 <code>sudo docker-compose up -d</code>。 若未报错则访问<code>http://vps_ip:8080</code>应该能打开如下页面，但要正常使用还需配置<strong>https</strong>。<br>常用命令：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> docker <span class="token function">ps</span>  <span class="token comment" spellcheck="true">#列出当前的containers</span><span class="token function">sudo</span> docker-compose down<span class="token operator">&amp;&amp;</span><span class="token function">sudo</span> docker-compose up -d <span class="token comment" spellcheck="true">#先停止并移除，再创建并启用</span><span class="token function">sudo</span> docker-compose build --pull    <span class="token comment" spellcheck="true"># build、rebuild，有些情况下不需要用这步</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200802001113.webp" alt></p><h2 id="设置nginx代理（需要域名，并在托管商处申请到SSL证书）">2.4&emsp;设置nginx代理（需要域名，并在托管商处申请到SSL证书）</h2><ol><li><p>我的域名托管在<code>cloudflare</code>故以它为例，先添加一个DNS的<strong>A记录</strong>，名称我设置的是<code>bitwarden</code>，以后就通过<code>bitwarden.yourdomain.com</code>访问bitwarden服务。</p></li><li><p>之后在<code>SSL/TLS</code>选项中的<code>边缘证书</code>可以申请一个，保存好<code>cert.pem</code>和<code>cert.key</code>文件。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803103209.webp" alt></p></li><li><p>安装nginx，并进入配置文件夹，将之前获得的<code>cert.pem</code>和<code>cert.key</code>复制到<code>/etc/nginx</code>中。</p></li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> nginx<span class="token punctuation">;</span><span class="token function">cd</span>  /etc/nginx<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="4"><li>在<code>/etc/nginx/conf.d/</code>中新建<code>default.conf</code>，并编辑：</li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> vim /etc/nginx/conf.d/default.conf<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>加入如下内容：（更多配置请参考<a href="https://github.com/dani-garcia/bitwarden_rs/wiki/Proxy-examples" target="_blank" rel="noopener">官方文档</a>）</p><pre class="line-numbers language-default.conf"><code class="language-default.conf"># bitwarden# 需要改的地方已用注释标出server {  listen 443 ssl http2;  server_name yourdomain.com;  #这里改成自己的域名（之前DNS解析了的）  client_max_body_size 128M;  ssl on;  ssl_certificate cert.pem;         #之前获得的SSL证书  ssl_certificate_key cert.key;  ssl_session_timeout 5m;  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;  ssl_prefer_server_ciphers on;  location / {    proxy_pass http://127.0.0.1:8080;       #这里8080对应前面docker-compose里的设置，127.0.0.1代表本机ip    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header X-Forwarded-Proto $scheme;  }  location /notifications/hub {    proxy_pass http://127.0.0.1:8081;   #8081也对应前面设置    proxy_set_header Upgrade $http_upgrade;    proxy_set_header Connection "upgrade";  }  location /notifications/hub/negotiate {    proxy_pass http://127.0.0.1:8080;   #8080对应前面设置  }  # Optionally add extra authentication besides the AUTH_TOKEN  # If you don't want this, leave this part out  location /admin {    # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/    auth_basic "Private";    auth_basic_user_file /path/to/htpasswd_file;    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header X-Forwarded-Proto $scheme;    proxy_pass http://127.0.0.1:8080;   #8080对应前面设置  }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="定时备份数据">2.5&emsp;定时备份数据</h2><ol><li><p>需要先配置好github环境，用私钥免密码登录github（我把这一步写成了一个脚本，方便自己在别的机器上配置。）由于github配置因人而异、比较个性化，需要参考的话可以在<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener">My_vimrc</a>仓库找到。<br>我习惯保管好一对密钥，免得每次都要重新生成；关于<strong>非对称加密</strong>知识可以参考<a href="https://chengpengzhao.com/2020-03-04-ssh-yu-gpg-de-xue-xi-yu-shi-yong/">我之前的post</a>。  </p></li><li><p>先建立远程备份仓库并和本地绑定。</p></li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~/bitwarden/bw-data      <span class="token comment" spellcheck="true">#改成自己bitwarden所在位置</span><span class="token function">git</span> init<span class="token function">git</span> remote add origin git@github.com:xxxx/xxxx.git  <span class="token comment" spellcheck="true">#自己在github建的空仓库，这里用SSH进行clone</span><span class="token function">git</span> add -A<span class="token function">git</span> commit -m <span class="token string">"first push"</span><span class="token function">git</span> push -u origin master<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li>建立定时上传github的脚本，备份<code>bw-data</code>文件夹。</li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~<span class="token function">sudo</span> timedatectl set-timezone Asia/Shanghai<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">#修改系统时区</span><span class="token function">cat</span> <span class="token operator">>></span> backUp_Bitwarden.sh <span class="token operator">&lt;&lt;</span> <span class="token string">EOF#!/bin/shdate=\<span class="token variable"><span class="token variable">$(</span><span class="token function">date</span> '+%Y-%m-%d %H:%M'<span class="token variable">)</span></span>cd ~/bitwarden/bw-datagit add -Agit commit -m "backup at <span class="token variable">$date</span>"git pushEOF</span><span class="token function">chmod</span> +x backUp_Bitwarden.sh<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="3"><li>定时任务crontab建立。</li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 每天13:00备份一次</span><span class="token keyword">echo</span> <span class="token string">"00 13  * * * bash ~/backUp_Bitwarden.sh> ~/backup.log 2>&amp;1 &amp;"</span><span class="token operator">></span>bt.cron<span class="token punctuation">;</span><span class="token function">crontab</span> bt.cron<span class="token punctuation">;</span><span class="token function">rm</span> -rf bt.cron<span class="token punctuation">;</span><span class="token function">crontab</span> -l<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">#查看是否设置成功</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="Webdav，同步Zotero文献">3&emsp;Webdav，同步Zotero文献</h1><p>以前都是用坚果云存Zotero里的文献，方便在多设备同步。但随着文献数量越来越多，自己又经常做一些标注、修改，<strong>坚果云的免费空间</strong>已经完全不够用了，遂在VPS上搭一个webdav服务来存文献。</p><h2 id="docker-compose文件配置">3.1&emsp;docker-compose文件配置</h2><p>Webcam搭建起来很简单，只需要一个<code>docker-compose.yml</code>文件就行了，我选择在<code>~/webdav</code>建立服务：</p><pre class="line-numbers language-yml"><code class="language-yml">version: '3'services:  webdav:    image: bytemark/webdav    restart: always    ports:      - "8082:80"    environment:      AUTH_TYPE: Digest      USERNAME: yourname    #用户名      PASSWORD: yourpasswd  #密码    volumes:    # :左边为数据保存路径      - /srv/dav:/var/lib/dav<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="Zotero软件设置">3.2&emsp;Zotero软件设置</h2><ol><li>运行<code>sudo docker-compose up -d</code>后访问<code>http://vps_ip:8082</code>，应该会跳出如下弹窗，说明配置成功。</li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803133646.webp" alt></p><ol start="2"><li><p>打开Zotero，<code>编辑-首选项-同步-文件同步-使用WebDAV</code>，填入地址、用户名和密码，点击验证服务器，会提示创建zotero文件夹，之后验证成功后就可以愉快地同步了～</p></li><li><p><strong>注意</strong>，这个webdav是为内存比较小的VPS准备的，如果还要装<code>nextcloud</code>的话就没必要用这个了（nextcloud自带webdav，主页面左下角点击就是地址，账号密码输入nextcloud设置的admin用户就行）。</p></li></ol><h1 id="Nextcloud，私人网盘">4&emsp;Nextcloud，私人网盘</h1><blockquote><p>Nextcloud是一套用于创建网络硬盘的客户端－服务器软件。其功能与Dropbox相近，但Nextcloud是自由及开放源代码软件，每个人都可以在私人服务器上安装并运行它。</p></blockquote><h2 id="docker-compose文件配置-1">4.1&emsp;docker-compose文件配置</h2><p>文件夹结构如下：</p><pre class="line-numbers language-bash"><code class="language-bash">~/nextcloud├── app│   └── Dockerfile├── db.env├── docker-compose.yml└── web    ├── Dockerfile    └── nginx.conf<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>下面贴出每个文件的内容：</p><ul><li><code>docker-compose.yml</code></li></ul><pre class="line-numbers language-yml"><code class="language-yml">version: '3'# 运行后数据储存在/var/lib/docker/volumes下的nextcloud_db和nextcloud_nextcloud文件夹下services:  db:    image: mariadb    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW    restart: always    volumes:      - db:/var/lib/mysql    environment:      - MYSQL_ROOT_PASSWORD=        #这里需要填入要设定的初始密码    env_file:      - db.env  redis:    image: redis:alpine    restart: always    # command: redis-server --requirepass 123456      #这里的123456和后面redis密码对应，没啥用（为了解决部署后日志中一个bug）；    # 这一项设置后会拖慢上传速度，故取消  app:      #image: nextcloud:fpm-alpine    build: ./app    restart: always    volumes:      - nextcloud:/var/www/html    environment:        REDIS_HOST: redis        # REDIS_HOST_PASSWORD: 123456     #和前面对应，值不重要        # 这一项设置后会拖慢上传速度，故取消        MYSQL_HOST: db    env_file:      - db.env    depends_on:      - db      - redis  web:    build: ./web    restart: always    ports:      - 8083:80         #设置访问端口    volumes:      - nextcloud:/var/www/html:ro    depends_on:      - app  cron:    image: nextcloud:fpm-alpine    restart: always    volumes:      - nextcloud:/var/www/html    entrypoint: /cron.sh    depends_on:      - db      - redisvolumes:  db:  nextcloud:<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li><code>db.env</code>：</li></ul><pre class="line-numbers language-env"><code class="language-env">MYSQL_PASSWORD=MYSQL_DATABASE=nextcloudMYSQL_USER=nextcloudNEXTCLOUD_TRUSTED_DOMAINS=nextcloud.tdbrywwwcg.xyz<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>这里的密码和<code>docker-compose.yml</code>里要一致，<code>USER</code>随便起，<code>NEXTCLOUD_TRUSTED_DOMAINS</code>填自己的域名，后面配置代理。</p><ul><li><code>app/Dockerfile</code></li></ul><pre class="line-numbers language-Dockerfile"><code class="language-Dockerfile">FROM nextcloud:fpm-alpineRUN set -ex; \    \    apk add --no-cache \        ffmpeg \        imagemagick \        procps \        samba-client \#       libreoffice \    ;RUN set -ex; \    \    apk add --no-cache --virtual .build-deps \        $PHPIZE_DEPS \        imap-dev \        krb5-dev \        openssl-dev \        samba-dev \        bzip2-dev \    ; \    \    docker-php-ext-configure imap --with-kerberos --with-imap-ssl; \    docker-php-ext-install \        bz2 \        imap \    ; \    pecl install smbclient; \    docker-php-ext-enable smbclient; \    \    runDeps="$( \        scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions \            | tr ',' '\n' \            | sort -u \            | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \    )"; \    apk add --virtual .nextcloud-phpext-rundeps $runDeps; \    apk del .build-deps<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>配置这部分是为了之后在nextcloud里挂载Onedrive、GoogleDrive这些<strong>外部储存</strong>，需要用到<code>smbclient</code>等套件；很多教程<strong>没有</strong>这部分，而是通过安装好后再输入几个命令去配置、显得比较麻烦。  </p><ul><li><code>web/nginx.conf</code>和<code>web/Dockerfile</code></li></ul><p>nextcloud直接在docker里配置了nginx代理，不需要再在<code>/etc/nginx</code>中加，而且对新手来说内容比较复杂，故照搬<a href="https://github.com/nextcloud/docker/tree/master/.examples/docker-compose/insecure/mariadb-cron-redis/fpm" target="_blank" rel="noopener">example</a>里的就行了。  </p><h2 id="个人建议">4.2&emsp;个人建议</h2><ol><li>建立好上面的几个文件就可以构建了（国内的vps下载速度慢、可能要花很久）。</li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> docker-compose build --pull<span class="token punctuation">;</span><span class="token function">sudo</span> docker-compose up -d<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="2"><li><p>访问<code>http://vps_ip:8083</code>，不出意外应该能显示登录页面了。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803125447.webp" alt></p></li><li><p>如果不是对nginx很熟悉，<strong>非常不推荐设置nextcloud的反向代理</strong>。因为自己设置好后虽然能访问，很经常出现各种bug：上传错误、图标不显示、网址链接错误…  </p></li></ol><p><strong>踩了上面说的这些坑</strong>之后我也看了很多别人的设置，但仍未找到比较完美的解决方案，但一想不配置http、https也能用，只是网址比较难看而已，<strong>最终选择了妥协</strong>。</p><h1 id="Sharelist，分享工具">5&emsp;Sharelist，分享工具</h1><blockquote><p>ShareList 是一个易用的网盘工具，支持快速挂载 GoogleDrive、OneDrive ，可通过插件扩展功能。<br>它的优点体现在支持的网盘种类比较多，而且配置一次后只要拷贝配置文件就可以很方便在不同机器上部署。</p></blockquote><h2 id="部署服务">5.1&emsp;部署服务</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~<span class="token function">git</span> clone https://github.com/reruin/sharelist <span class="token operator">&amp;&amp;</span> <span class="token function">cd</span> sharelistvim docker-compose.yml<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><code>docker-compose.yml</code>中可修改端口，之后一样运行<code>sudo docker-compose up -d</code></p><pre class="line-numbers language-yml"><code class="language-yml">version: "3"services:  sharelist:    image: reruin/sharelist    volumes:      - $HOME/sharelist:/sharelist/cache    ports:      - "8084:33001"        #我把sharelist放在8084端口<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li>覆盖配置文件（可选）。</li></ul><p>如果之前用过sharelist、现在只是换了个机器部署的话，只需要拷贝覆盖目录中的<code>config.json</code></p><h2 id="nginx代理配置">5.2&emsp;nginx代理配置</h2><p>在<code>/etc/nginx/conf.d/default.conf</code>中加入如下内容：</p><pre class="line-numbers language-default.conf"><code class="language-default.conf"># sharelistserver {  listen 443 ssl http2;  server_name yourdomain.com;       #填入自己的域名  # Specify SSL config if using a shared one.  #include conf.d/ssl/ssl.conf;  # Allow large attachments  ssl on;  ssl_certificate cert.pem;  ssl_certificate_key cert.key;  ssl_session_timeout 5m;  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置  ssl_prefer_server_ciphers on;  location / {    proxy_pass http://127.0.0.1:8084;       #设置的sharelist端口      proxy_set_header Host  $host;      proxy_set_header X-Real-IP $remote_addr;      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      proxy_set_header X-Forwarded-Proto $scheme;      proxy_set_header Range $http_range;      proxy_set_header If-Range $http_if_range;      proxy_no_cache $http_range $http_if_range;  }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="Aria2，下载利器">6&emsp;Aria2，下载利器</h1><blockquote><p>Aria2是一款自由、跨平台命令行界面的下载管理器，该软件根据GPLv2许可证进行分发。支持的下载协议有：HTTP、HTTPS、FTP、Bittorrent和Metalink。</p></blockquote><p>我用的是<a href="https://github.com/P3TERX/Docker-Aria2-Pro" target="_blank" rel="noopener">P3TERX</a>大佬的<code>Aria2-Pro</code>Docker镜像，安装很简单：<br>由于Aria2只是个命令行，是否安装好了没法直接看出来，需要配置服务端并能连接成功才算成功了第一步；接着下载一个种子试试就知道了。</p><h2 id="服务端安装">6.1&emsp;服务端安装</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~<span class="token function">git</span> clone https://github.com/P3TERX/Docker-Aria2-Pro <span class="token operator">&amp;&amp;</span> <span class="token function">cd</span> Docker-Aria2-Pro<span class="token punctuation">;</span><span class="token comment" spellcheck="true"># 把&lt;TOKEN>改成要设置的密码</span><span class="token function">sudo</span> docker run -d \    --name aria2-pro \    --restart unless-stopped \    --log-opt max-size<span class="token operator">=</span>1m \    -e PUID<span class="token operator">=</span><span class="token variable">$UID</span> \    -e PGID<span class="token operator">=</span><span class="token variable">$GID</span> \    -e RPC_SECRET<span class="token operator">=</span><span class="token operator">&lt;</span>TOKEN<span class="token operator">></span> \    -e RPC_PORT<span class="token operator">=</span>6800 \    -p 6800:6800 \    -e LISTEN_PORT<span class="token operator">=</span>6888 \    -p 6888:6888 \    -p 6888:6888/udp \    -v ~/aria2-config:/config \    -v ~/downloads:/downloads \    p3terx/aria2-pro<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>安装好后可以在<code>~/aria2-config</code>文件夹修改配置。</p><h2 id="AriaNg-web客户端">6.2&emsp;AriaNg, web客户端</h2><p>下载一个<a href="https://github.com/mayswind/AriaNg/releases/download/1.1.6/AriaNg-1.1.6-AllInOne.zip" target="_blank" rel="noopener">AriaNg</a>的html文件，连接上服务端就可以开始用了。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803195418.webp" alt="AriaNg的Web界面"></p><h1 id="Zdir，目录列表">7&emsp;Zdir，目录列表</h1><blockquote><p><a href="https://github.com/helloxz/zdir" target="_blank" rel="noopener">Zdir</a>是一款使用PHP开发的目录列表程序，无需数据库，体积小巧，功能完善。</p></blockquote><p>我一般用它直接访问Aria2下载好的文件，部署也很简单：</p><ol><li><p><a href="http://45.77.1.137:8083/s/btmj7Bc6L9bzD4c/download" target="_blank" rel="noopener">下载</a>一键安装脚本，按照说明来配置。</p></li><li><p><code>zdir</code>文件夹里修改相关模板文件。（懂一点html知识就行）<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803195607.webp" alt="我的Zdir，图为Aria2下载文件夹"></p></li><li><p>nginx代理配置：</p></li></ol><pre class="line-numbers language-default.conf"><code class="language-default.conf">#zdirserver {    listen 80;    server_name  yourdomain.com;    location / {       proxy_pass http://127.0.0.1:1080;    #zdir端口，可以通过改脚本修改       proxy_redirect off;       proxy_set_header Host $host;       client_max_body_size 50m;           client_body_buffer_size 256k;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_max_temp_file_size 200m;  }location ~ .*\.(js|css|woff|woff2|gif|jpg|jpeg|png|bmp|swf|flv|mp4|ico)?$ {       proxy_pass http://127.0.0.1:1080;       proxy_redirect off;       proxy_set_header Host $host;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       expires 7d;        access_log off;  }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="frp，NAS内网穿透">8&emsp;frp，NAS内网穿透</h1><h2 id="win10虚拟机上安装黑群晖">8.1&emsp;win10虚拟机上安装黑群晖</h2><p>具体安装步骤和文件我传到了<a href="http://45.77.1.137:8083/s/ZC8tRFqXYaybRC7" target="_blank" rel="noopener">Nextcloud</a>里，这里注意虚拟机的网络一定要设置成<strong>桥接模式</strong>，原理可以参照这张路由器的图来说明：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200803194939.webp" alt><br>当选择<strong>非桥接模式</strong>时虚拟机相当于上面的路由器2，其处在win10主机派生出的局域网下，而win10主机和其他同一WIFI下的设备处于同一个上级局域网中，上级网络无法访问下级网络。<br>同样外网设备（不在路由器1的局域网下）也无法直接访问到NAS，常见的解决方法有两个：</p><ol><li>路由器1改成桥接模式，并设置端口转发；这种方式要求要有公网IP、并且路由器改模式可能需要向运营商申请，总的来说很麻烦。  </li><li>内网穿透，需要一个VPS和域名，利用VPS作为中转服务器将两个客户端相连。比较常用的内网穿透工具是国人开发的<a href="https://github.com/fatedier/frp" target="_blank" rel="noopener">frp</a>。</li></ol><h2 id="内网访问NAS">8.2&emsp;内网访问NAS</h2><p>在win10中通过<code>cmd</code>的<code>ipconfig</code>获取到本机ip，如果前面设置正确，同一局域网下的其他设备应该能通过<code>http://win10_ip:5000</code>访问到NAS主页（具体端口参考<a href="https://www.synology.com/zh-cn/knowledgebase/DSM/tutorial/Network/How_to_make_Synology_NAS_accessible_over_the_Internet" target="_blank" rel="noopener">群晖官网</a>）。  </p><p><del>## client（客户端）frpc配置</del><br><del>## server（服务端）frps配置 ~</del>  </p><h2 id="内网穿透从入坑到放弃">8.3&emsp;内网穿透从入坑到放弃</h2><p>frp的配置分为客户端和服务端，客户端（也就是黑群晖）可以开一个docker运行<code>frpc</code>，服务端（VPS）开一个<code>screen</code>运行<code>frps</code>，当然前提是写好配置文件。<br>说下我踩到的坑吧，第一天配置挺好可以正常访问、Nginx代理文件都写好了。结果第二天不知怎么的各种<code>http proxy EOF</code>错误，怎么改都弄不好，折腾了一个下午最终放弃了。</p><h1 id="yobot，手游机器人">9&emsp;yobot，手游机器人</h1><blockquote><p>yobot 是为公主连接公会战设计的辅助机器人，能够帮助公会战管理者提供自动化管理服务。 yobot 提供了群聊、web 页面两套用户交互方式，具有操作便捷、通知及时、数据详细的特点。 基于 QQ 的部分已不再支持，本项目正在向其他平台迁移</p></blockquote><p>按照<a href="https://yobot.win/" target="_blank" rel="noopener">官网</a>上的Linux-Mirai部署方式一步步来就行，注意QQ号必须先在VPS上登录并挂几天、不然容易被封或被屏蔽消息。</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-08-07 14:19:12</em></p></blockquote><h1 id="Calibre-web，个人书库">10&emsp;Calibre-web，个人书库</h1><h2 id="介绍">10.1&emsp;介绍</h2><p>最近开始用<a href="https://calibre-ebook.com/" target="_blank" rel="noopener">Calibre</a>整理书籍了，之前都是下载一本、往ipad里一丢、看完就不管了（有时随手就删了），导致想翻一翻之前看过的书都找不到地方；  并且因为自己在<strong>日亚</strong>买的正版书有版权限制，只能用注册过的kindle看，不方便管理。<code>Calibre</code>这款软件能很好解决我的需求：</p><ol><li>可以搜索书籍的<strong>元数据</strong>，整理起来很方便轻松。</li><li><code>DeDRM</code><a href="http://45.77.1.137:8083/s/SpkfEbLjgDjMsxo/download" target="_blank" rel="noopener">插件</a>能去除版权限制，可以将书籍转为<code>epub</code>等主流格式方便非<code>kindle</code>阅读器查看。  </li><li>结合<a href="https://github.com/janeczku/calibre-web" target="_blank" rel="noopener"><strong>Calibre-web</strong></a>，搭建线上图书馆（相比于桌面版增加了一些功能，也更便于分享）。  </li></ol><h2 id="VPS中用docker-compose安装">10.2&emsp;VPS中用docker-compose安装</h2><ol><li><p>建一个<code>books</code>（名称随意）文件夹并进入；</p></li><li><p>建立一个<code>docker-compose.yml</code>文件，内容如下：</p></li></ol><pre class="line-numbers language-yml"><code class="language-yml">version: "3"services:  calibre-web:    # 体验后还是这个image最好用    image: technosoft2000/calibre-web    container_name: calibre-web    environment:        - PUID= 1000     #run `id` in shell to get id for a user        - PGID= 1000        - SET_CONTAINER_TIMEZONE= true        - CONTAINER_TIMEZONE= Asia/Shanghai    volumes:        - ./calibre:/books  #存放书籍和app.db等数据库        # 我喜欢全放一个文件夹，方便管理        - ./calibre-web/app:/calibre-web/app        - ./calibre-web/kindlegen:/calibre-web/kindlegen        - ./calibre-web/config:/calibre-web/config    ports:        # 左边为外部端口，不要和其他服务冲突就行        - "8085:8083"    restart: always<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="3"><li><p>运行<code>sudo docker-compose up -d</code>，访问<code>http://vps_ip:8085</code>，在web中初始化、路径输入<code>/books</code>。</p></li><li><p>若输入后报错则是文件夹<strong>权限</strong>的问题，我一般用<code>sudo chmod -R 777 *</code>这种粗暴的方式解决。</p></li></ol><h2 id="群晖NAS中用docker安装">10.3&emsp;群晖NAS中用docker安装</h2><ol><li><p>映像中搜索<code>calibre-web</code>，找到<code>technosoft2000/calibre-web</code>并下载；</p></li><li><p><code>创建容器-高级设置-启动自动重新启动</code>、<code>卷-添加文件夹</code>如下：</p></li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200807151248.webp" alt></p><ol start="3"><li><p>运行状态可在<code>详情-终端机</code>中查看（拉去github资源需要一段时间）；</p></li><li><p>进入<code>web</code>配置，出错则检查<code>http</code>用户是否对文件夹具有<strong>完全控制</strong>权限。</p></li></ol><h2 id="备份">10.4&emsp;备份</h2><p>书籍的所有数据都在docker内的<code>/books</code>文件夹下（即外部的<code>pathTo/books/calibre</code>），其中<code>metadata.db</code>、<code>metadata_db_prefs_backup.json</code>以及书籍文件夹是和桌面版<code>calibre</code>软件互通的，也就是可以互相拷贝覆盖。<code>app.db</code>、<code>gdrive.db</code>记录了<code>calibre-web</code>上的一些操作（如书架设置、用户名和密码、googleDrive设置），需要将服务迁移到另一台机器上时记得备份这些文件。</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-11-13 23:22:02</em></p></blockquote><h1 id="Leanote，私有云笔记">11&emsp;Leanote，私有云笔记</h1><p>蚂蚁笔记虽然几年前就已经没更新了，但基本的功能挺全的，作为私有云笔记用起来没啥问题。我尝试了一个多月感觉还行，支持markdown、可以传图片、IOS下也有app、网页就能直接访问、备份方便…总之个人强力推荐吧，看了一些其他支持私人部署的笔记平台也都差不多的样。  </p><p>我用的是<a href="https://github.com/KeiferJu/docker-leanote" target="_blank" rel="noopener">docker部署</a>的方式，比较无脑，而且这个仓库是大佬整合制作的镜像，有不同版本可供选择（视vps配置），反正我512M内存祖传vps运行完全版Leanote也毫无压力。  </p><h1 id="FileRun，私人网盘">12&emsp;FileRun，私人网盘</h1><p>与之前的Nextcloud相比，FileRun私人网盘体积更加轻盈，部署起来没有那么多糟心的坑，也支持Webdav，适合部署在低配的机器上，只是传一传小文件（抱歉、低配硬盘根本不够用）、用webdav同步下一些app的数据（如OmniFocus之类的）。  </p><p>配置过程及其简单，官网<a href="https://docs.filerun.com/docker" target="_blank" rel="noopener">https://docs.filerun.com/docker</a>里说的明明白白，顶多改一改<code>volumes</code>方便换vps时同步数据、或者改一改文件夹权限之类的，不像nextcloud真的是各种错误（虽然nextcloud的功能确实强大、加上各种插件、社区也很活跃）。</p><h1 id="删去一些不必要的服务">13&emsp;删去一些不必要的服务</h1><p>用了一段时间后清理了一些平时基本不怎么用的服务，最后只留下<strong>Bitwarden</strong>、<strong>Leanote</strong>、和<strong>FileRun</strong>，别的比如nextcloud、Aria2、Calibre-web放到了我的群晖NAS（越用越香）上，最近手头有点紧，能省则省吧（最终还是不肯放弃bandwagon的祖传小鸡、被自己啪啪打脸）。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-08-03-vps-neng-yong-lai-zuo-shi-me/#disqus_thread</comments>
    </item>
    
    <item>
      <title>总结下最近看的几部生存题材的漫画</title>
      <link>https://chengpengzhao.com/2020-07-24-zong-jie-xia-zui-jin-kan-de-ji-bu-sheng-cun-ti-cai-de-man-hua/</link>
      <guid>https://chengpengzhao.com/2020-07-24-zong-jie-xia-zui-jin-kan-de-ji-bu-sheng-cun-ti-cai-de-man-hua/</guid>
      <pubDate>Sat, 25 Jul 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;近况&quot;&gt;1&amp;emsp;近况&lt;/h1&gt;&lt;p&gt;最近一直处在很咸鱼的状态
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="近况">1&emsp;近况</h1><p>最近一直处在很咸鱼的状态，一方面是因为疫情的原因、处在一个几乎没有人督促的环境下，学习效率非常低；但说到底这也是个借口，有点迷茫、对今后的生活缺乏考量、逃避现实这类词语比较合适吧。<br>当然并不是很闲没事做，毕业设计还有大块要做、想学的东西也只是开了个头…有时候不得不佩服下自己面对这些山一样多的任务还能够视而不见并毫无波动地打开了游戏界面，当然游戏对我来说没几天就会腻、然后就是动漫、小说、漫画、电影、换个游戏的轮流，总之就是不想去学习。<br>然后不知不觉<strong>几周</strong>就过去了，印象中好像刚到夏天吧，缓过神来7月已经快过完了，回想了下去年的这个时候自己在做什么来着，噢对那阵子好像挺努力的为了能够去日本交换半年，现在的自己还真是<strong>不像样</strong>啊。<br>好的，这样一来我的暑假也就已经结束了，再多的游戏到头也只是感觉到虚无，看来只有学习能使我快乐了，这不是玩梗也不是什么表情包，而是我现在好像真tm是这么想的，说白了就是追求到<strong>对自我的认同感</strong>才会让我真正快乐，如果自己对自己不满、厌恶的话自然就没法开心起来，更无法喜欢别人。<br>似乎有点儿偏题了，正好昨天思考了一番后找到了今后一段时间的目标了，那些无关紧要的东西就先总结总结然后放一放吧，说到总结最近好像看的几部<strong>漫画</strong>都是同一类型的，即都带有<strong>生存</strong>、<strong>人性</strong>、<strong>杀戮</strong>这些字眼，就按照我心目中的评分排序随便说下感受吧，当然要是剧透太多也不好我还是尽量不谈剧情（虽然有点难做到）。  </p><h1 id="最近看的几部漫画">2&emsp;最近看的几部漫画</h1><h2 id="今際の國のアリス（彌留之國的愛麗絲）">2.1&emsp;今際の國のアリス（彌留之國的愛麗絲）</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725164411.webp" alt></p><p>这几部漫画里我最先看也是我个人认为最能被称为神作的一部，好像也被翻译成<em>今际之国的闯关者</em> ，注意不要和另一本<code>今際の路のアリス（彌留之路的愛麗絲）</code>弄混了，虽然是同一个作者并且两部的背景有点相似（那本好像还没完结我没看过）。  </p><blockquote><p><strong>今際</strong>（いまわ）、今は限り、もうこれ限りという時、死にぎわ、臨終、最期。</p></blockquote><p>翻译成弥留我觉得很有感觉；<strong>アリス</strong>、应该是联想到了<em>不思議の国のアリス</em> 吧，确实<strong>弥留之国</strong>也挺不可思议的了。<br>故事背景是男主一行无意中进入了“弥留之国”，每个人都被发了一个“签证”，如果签证到期就会被激光穿透而死亡，签证可以通过参加“游戏”得到延期。所谓的“游戏”是根据扑克牌来的，花色和数字代表类型和停留天数，当然数字越大游戏越难，类型分为心理型、体能型、智力型、平衡型。当然这些生存游戏大多都是比较残忍、考验人性的，每个人都在为自己的目标到生命的最后一刻为止而竭尽全力着。<br>虽然第一眼看上去有点黑暗但这部漫画的三观还是很健康向上的，如果有一天我绝望到想要自杀了的话，那我应该会再拿出这部漫画看一遍吧。<br>这里说点别的，我很讨厌“正能量”这个词，当然我不是讨厌正能量本身，而是这个词总是被当做借口出现；特别是不去深入了解“负能量”、“黑暗”这些东西时，“正能量”也似乎太脆弱而无力了。<br>选一个我比较喜欢的游戏<code>♦K</code>谈一谈吧，这个游戏的设计非常简单，算是一个典型的博弈论案例了，比较考验智力，难点主要在判断对方思考到了哪一步。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725164503.webp" alt></p><p>但这部漫画的优秀之处在于最后将主题上升到了有关生命价值的讨论上来，结尾完全变成了心理战。这个游戏的设计者曾是个极富正义感的律师，一直在思考生命的价值及其差异，当苣屋（姑且算作男二吧）最后选择将自己写的数字直接告诉律师，让他来决定自己的死活，而律师到最后也贯彻了自己的理想，选择自己无法决定他人生命的价值这样一个选项。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725164544.webp" alt="(图片看不清可以右键在新页面打开放大)"><br>类似的更有意思的游戏还有很多~总言我非常喜欢这部漫画，无论是剧情铺垫、群英像的描绘、人性的探讨、画风、结局都还不错。  </p><p>之后看的几部虽然有新颖的点，但总感觉和弥留之国的爱丽丝相比要逊色一些，还是简单谈下印象吧。</p><h2 id="バトル·ロワイアル（生存遊戲-Battle-Royale）">2.2&emsp;バトル·ロワイアル（生存遊戲, Battle Royale）</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725194818.webp" alt></p><p>《大逃杀》的电影我之前也看过，和这部漫画剧情基本一致，谁先谁后就不太清楚了，故事背景是一个独裁国家、每年选出一个高三班级进行生死游戏、最终只有一人能生存。《生存游戏》虽然有点猎奇的因素，有些部分只是让人感觉恶俗、但反过来也只是为了说明游戏的无比残酷。重点在描述人类在这种生存的压力下所作出的美好或丑恶的选择：肆意屠杀、挣扎求生、逐渐崩坏、呼吁和平、反抗现实…<br>《生存游戏》里我最喜欢的角色要数三村信史了，他从一开始就选择了反抗现实，与这个不合理的社会与制度为敌，虽然最终没能成功而悲壮死去了，但丝毫不能掩盖他的光芒与血性，今后只会有更多人（比如主角）继承他的意志。<br>这部漫画给我带来的震撼体现在我无法指责他们的做法，有些选择虽然一看就不应该去做但说到底是因为我们没有身处对方的环境中、无法真正去理解他人的感受，毕竟是为了生存所做出的努力，可恨之人必有可怜之处。 不过这种漫画终究不适合三观尚不健全的小朋友们看，毕竟我还是不想看到男主那样的“天真”被人嘲笑。  </p><h2 id="神さまの言うとおり（要听神明的话）">2.3&emsp;神さまの言うとおり（要听神明的话）</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725201612.webp" alt></p><p>好像被拍成了电影，不过完全是那种恐怖、血腥、猎奇类型的吧，概括起来就是<strong>解谜版大逃杀游戏</strong>吧，如果要我用一个词谈感受的话，那就应该是“不合理”了。忽然被卷入大规模的死亡威胁、周围的同学一个个在游戏中惨死、到后来的神之子以及世界观的讲解，都在突出“不合理”这一点，让我不断感叹简直是太乱来了。<br>当然不得不说很多游戏设计得比较有创意（说的不好听就是奇葩），而且融合了日本的很多文化，如“撒豆驱鬼”、“七×七不可思议”、“浦岛太郎”、“天邪鬼迷宫”…  我一直在思考这部作品想要表达些什么（除了猎奇这方面），也许作者当初并没有想太多，作品的很多意义不就是由观众来决定么。我主要看的点应该是“在不合理的世界里贯彻自己的理想”吧，说到底为什么要选拔神之子、为什么要通过这样的方式，如果站在人类的视角来看怎么都太不合理了，但如果按照“弱肉强食”来理解也<strong>只能接受</strong>；神对于人类的存在不过是相当于人类对于动物而已，人类屠杀、虐待又或是圈养动物等一系列行为，就像神用这种“游戏”玩弄人类一样。关键是面对这样的环境每个人如何行动，有人选择“弑神”、有人享受这个环境、有人选择破坏一切、有人选择为重要的人不惜一切，最后的结尾虽然很遗憾，但也算是每个人都贯彻自己到最后而产生的一个结果罢，无可厚非。  </p><h2 id="トモダチゲーム（朋友遊戲）">2.4&emsp;トモダチゲーム（朋友遊戲）</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725202200.webp" alt></p><p>和《欺诈游戏》有点像，和上面几部漫画不同的是筹码不是生命而是金钱，游戏输了的话会欠下一大笔债务（也相当于要命了）；既然是朋友游戏、每个游戏在设计上都是围绕人际关系进行的，无论是朋友间的团队合作、互相猜疑和挑拨离间与利用、对他人人心的掌控程度，可以说是智商和情商的双重较量，每个游戏自己也稍微思考一下最后对答案的过程还是蛮<strong>有趣</strong>的。<br>这部漫画还没完结，总的来说值得一看吧，但也只是停留在有趣的层面，并没有太多引人深思的深刻之处。毕竟不是每个人都有那样的智商和人心操纵的能力，可怕可怕。  </p><h2 id="BTOOOM-（惊爆游戏）">2.5&emsp;BTOOOM!（惊爆游戏）</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725210654.webp" alt></p><p>“荒岛上的生存游戏”，好像还动画化了，之前看过一遍的时候感觉挺好看的，也是一群人被逼至绝境并被给予强力的武器（各种类型的炸弹），但故事的背景和世界观和前面几个相比更加真实，涉及到权力阶级的黑暗面、大国间的对抗等因素。<br>最让我印象深刻的是里面描绘的“游戏士兵”（自己取的名字）————大多数都是小孩，通过操纵无人机完成军队的各种任务，不用上战场、不用近距离接触人的死亡、闻不到任何血腥味，因此不会有任何罪恶感和情绪波动，就像是打游戏一样轻松，输了也不会有任何身体上的损失、更不会出现战争后的PTSD。这么一想像还是挺让人不寒而栗的。<br>《惊爆游戏》一个重要的主题就是信任，越是在这种绝境中人的猜忌、妒忌、恐惧、怨恨带来的后果就越致命，加上能够轻易行使暴力这种情况，往往脆弱一下就会导致崩溃。最典型的例子就是前期的大叔和圣域的幸存者街舞男，小小的猜疑经过恐惧放大、不自觉地将事情朝最坏的方向想，最后既丢失了自己的性命、又让他人陷入无限的自责甚至崩溃中。<br>第二遍看完感觉有些设定和场景还是比较反感的，不过瑕不掩瑜，作为生存类漫画总的来说我还是比较推荐的。</p><h1 id="其他相关">3&emsp;其他相关</h1><p>生存这一题材的作品还有很多，我就不一一细说了，随便列举几个曾经看过或玩过的吧：  </p><ol><li><p>漫画，<code>杀戮都市GANTZ</code>（动画看过，漫画准备有时间再看，好像评价挺高的）、<code>死囚乐园</code>（看过、挺好看）、<code>漂流網咖</code>（《恶之华》作者押見修造写的、两部都挺值得一看的，看似变态但三观十分正）。</p></li><li><p>游戏，AVG类型的，没接触过就算了，不推荐。</p></li></ol><ul><li><p>秘密游戏系列：一群之间或者有关系或者没关系的人被莫名绑架到了一起，手持 PDA ，对应着 PDA 上的身份和任务，开始了相互残杀游戏。<br><code>秘密游戏：杀手皇后(シークレットゲーム -KILLER QUEEN)</code>， <code>秘密游戏2：反叛(シークレットゲーム CODE:Revise)</code></p></li><li><p>给下一个牺牲者的死亡通告三部曲(次の犠牲者をオシラセシマス): 类似人狼游戏，规则比较复杂，动点脑筋推理起来还是有点意思的。<br><code>与君共渡这片无边无尽的黑暗(君とこの果てることない暗闇を)</code>、<code>克服死和绝望(死と絶望を乗り越えて)</code>、<code>死神降临于崩溃的世界(崩壊する世界に死神と)</code></p></li></ul><ol start="3"><li>电影，<code>人狼游戏1-7</code> : 生存版狼人杀，每一部的角色构成都有些不一样。</li></ol><h1 id="附：漫画资源">4&emsp;附：漫画资源</h1><p>都是汉化了的，放在<a href="https://sharelist.tdbrywwwcg.xyz/OneDrive_Big/%E6%BC%AB%E7%94%BB" target="_blank" rel="noopener">sharelist</a>里了。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-07-24-zong-jie-xia-zui-jin-kan-de-ji-bu-sheng-cun-ti-cai-de-man-hua/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Auto.js编写游戏脚本入门</title>
      <link>https://chengpengzhao.com/2020-06-15-autojs-xue-xi/</link>
      <guid>https://chengpengzhao.com/2020-06-15-autojs-xue-xi/</guid>
      <pubDate>Mon, 15 Jun 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;介绍&quot;&gt;1&amp;emsp;介绍&lt;/h1&gt;&lt;blockquote&gt;
&lt;p
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="介绍">1&emsp;介绍</h1><blockquote><p>Auto.js is a UiAutomator on android, does not need root access(安卓平台上的JavaScript自动化工具)</p></blockquote><p> 看作者的<code>github ID</code> <a href="https://github.com/hyb1996/Auto.js" target="_blank" rel="noopener">hyb1996</a>应该是个90后大佬；由于Auto.js很适合用来写安卓脚本，被国内各种灰产滥用是少不了的，毕竟很多人靠这个赚钱。<br> 我自己比较喜欢偶尔写一些<code>游戏脚本</code>用用，之前一直用<strong>按键精灵</strong>写脚本，找图找色功能比较好用，但需要设备有root权限，而且用久了发现有些功能实现起来还比较麻烦，故这次打算找个新平台尝试一下。Autojs由于是基于安卓的无障碍服务，只有个别命令需要root权限，此外还支持对控件的操作，功能看上去还挺强大。  </p><p> 因为我的需求是能够写<strong>游戏脚本</strong>，不像一般的APP可以直接操作控件，而只能通过基于坐标的操作完成。所以Autojs里关于控件的部分可以略过不看（除了多账号登录时的登录界面可能会用到一点控件操作，其他基本用不到），大致的学习流程：</p><ol><li>软件安装及环境搭建（版本选择、运行测试）</li><li><code>JavaScript</code>基础语法学习（变量类型、流程操作…）</li><li><code>Auto.js</code>分模块学习，如系统交互（文件读写、设备信息、打开应用…）、找图找色（游戏脚本的核心）、UI界面、多线程…</li></ol><h1 id="安装及环境配置">2&emsp;安装及环境配置</h1><p>我用的是最新的<a href="https://pro.autojs.org/" target="_blank" rel="noopener">Pro</a>版，去淘宝官方店买就行，也不贵；<code>app</code>安装好了就可以在手机上编脚本了，但由于效率低大多数情况都是在电脑上编连接手机（或模拟器）进行测试，官方是通过<code>VSCODE</code>的一个插件来实现这一交互的，虽然对像我这样的非VSCODE用户（Vim党）来说不够友好，但好像只有这一条路可走。<br>安装好后把<code>Auto.js-Pro-Ext</code>这个插件装上(Vim用户再装个vscodevim)，随便创建个<code>.js</code>文件会发现右边有个绿色的小安卓图标，点击后（或者通过快捷键<code>Ctrl+Shift+p</code>）发现可以通过输入IP（和电脑同一网络）、adb（插USB）两种方式连接，手机的话一般连接不会有什么问题，连接成功的话右下角会有一行提示。<br>要注意的是如果使用的是<strong>模拟器</strong>，这时候的网络配置就有点麻烦了。比如我用的雷电模拟器，需要开启网络桥接模式、并设置好静态IP才能连接上，具体操作可以看<a href="https://www.52pojie.cn/thread-1169466-1-1.html" target="_blank" rel="noopener">这篇文章</a>。<br>（非Vim用户直接跳过就行）Vim用户可能需要配置下自己习惯了的常用快捷键，直接在插件的设置里打开<code>settings.json</code>文件改就行了，范例如下：</p><pre class="line-numbers language-json"><code class="language-json"><span class="token punctuation">{</span>  <span class="token property">"vim.easymotion"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>  <span class="token property">"vim.incsearch"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>  <span class="token property">"vim.useSystemClipboard"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>  <span class="token property">"vim.useCtrlKeys"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>  <span class="token property">"vim.hlsearch"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>  <span class="token property">"vim.insertModeKeyBindings"</span><span class="token operator">:</span> <span class="token punctuation">[</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;C-h>"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;left>"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;C-l>"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;right>"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;C-j>"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;down>"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;C-k>"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;up>"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;C-d>"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"&lt;Delete>"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">]</span><span class="token punctuation">,</span>  <span class="token property">"vim.normalModeKeyBindings"</span><span class="token operator">:</span> <span class="token punctuation">[</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"E"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"$"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"H"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"^"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">]</span><span class="token punctuation">,</span>  <span class="token property">"vim.visualModeKeyBindings"</span><span class="token operator">:</span> <span class="token punctuation">[</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"E"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"$"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span>      <span class="token property">"before"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"H"</span>      <span class="token punctuation">]</span><span class="token punctuation">,</span>      <span class="token property">"after"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        <span class="token string">"^"</span>      <span class="token punctuation">]</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>  <span class="token punctuation">]</span><span class="token punctuation">,</span>  <span class="token property">"editor.formatOnSave"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>连接上了之后当然是必不可少的<code>hello world</code>测试，常用的输出方式有3种：</p><pre class="line-numbers language-js"><code class="language-js"><span class="token function">toast</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">//输出到手机屏幕</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//输出到日志</span><span class="token function">toastLog</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">//前两者之和</span>console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">//输出到控制台，console模块的一个成员函数，可以通过console.show()在手机上显示</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><h1 id="JavaScript基础">3&emsp;JavaScript基础</h1><p>推荐直接去<a href="https://www.w3school.com.cn/js/index.asp" target="_blank" rel="noopener">w3school</a>或者<a href="https://www.runoob.com/js/js-tutorial.html" target="_blank" rel="noopener">runoob</a>过一遍，这里只列举一些我觉得要注意的地方。</p><ul><li><p>直观感受，很多语法和C\C++一模一样（除了声明变量要用<code>var</code>、函数要加<code>function</code>…）。</p></li><li><p><code>undefined</code>：只声明过但未赋值的变量。</p></li><li><p><code>==</code>与<code>===</code>： 前者是<code>equality</code>、后者为<code>identity</code>，即后者不会进行类型转换，类型不同的结果一定不等。</p></li><li><p>JS的数据类型：</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> length <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span>                             <span class="token comment" spellcheck="true">// 数字</span><span class="token keyword">var</span> lastName <span class="token operator">=</span> <span class="token string">"Gates"</span><span class="token punctuation">;</span>                      <span class="token comment" spellcheck="true">// 字符串</span><span class="token keyword">var</span> cars <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string">"Porsche"</span><span class="token punctuation">,</span> <span class="token string">"Volvo"</span><span class="token punctuation">,</span> <span class="token string">"BMW"</span><span class="token punctuation">]</span><span class="token punctuation">;</span>         <span class="token comment" spellcheck="true">// 数组</span><span class="token keyword">var</span> x <span class="token operator">=</span> <span class="token punctuation">{</span>firstName<span class="token punctuation">:</span><span class="token string">"Bill"</span><span class="token punctuation">,</span> lastName<span class="token punctuation">:</span><span class="token string">"Gates"</span><span class="token punctuation">}</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// 对象</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>null</code>：类型是对象，不存在的事物。</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">null</span> <span class="token operator">===</span> undefined            <span class="token comment" spellcheck="true">// false</span><span class="token keyword">null</span> <span class="token operator">==</span> undefined             <span class="token comment" spellcheck="true">// true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>对象： 通过关键词 “new” 来声明 JavaScript 变量，则该变量会被创建为对象。</p><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//也可以通过person.firstName="..."的方式初始化</span><span class="token keyword">var</span> person <span class="token operator">=</span> <span class="token punctuation">{</span>firstName<span class="token punctuation">:</span> <span class="token string">"Bill"</span><span class="token punctuation">,</span>lastName <span class="token punctuation">:</span> <span class="token string">"Gates"</span><span class="token punctuation">,</span>id       <span class="token punctuation">:</span> <span class="token number">678</span><span class="token punctuation">,</span>fullName <span class="token punctuation">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>   <span class="token comment" spellcheck="true">//成员函数</span>  <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> <span class="token keyword">this</span><span class="token punctuation">.</span>lastName<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>在字符串中换行，需要加一个反斜杠(非ECMAScript标准）：</p><pre class="line-numbers language-js"><code class="language-js">document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">"demo"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>innerHTML <span class="token operator">=</span> <span class="token string">"Hello \Kitty!"</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p><code>String</code>和<code>Number</code>相加时，会将数字转为字符串；<code>String</code>和<code>Number</code>相减时，会将字符串转为数字；</p></li><li><p>数组添加元素： <code>array.push(&quot;value&quot;)</code></p></li><li><p>常用对象： Date() （获取时间）、 Math() (常用数学工具)</p></li><li><p><code>use strict;</code>: 定义 JavaScript 代码应该以“严格模式”执行。</p></li><li><p>JavaScript的对象通过<code>引用</code>来寻址：</p><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//person是个对象</span><span class="token keyword">var</span> x <span class="token operator">=</span> person<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// 这不会创建 person 的副本，x相当于person的别名，即引用</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ul><h1 id="Auto-js常用命令及模块">4&emsp;Auto.js常用命令及模块</h1><p>下面分几个部分把编写游戏脚本时可能用到的模块全部讲一下吧，顺便对自己也是个学习完善的过程，全部学完花的时间可能比较多，自己也还有别的事要做，尽量每天写一点吧。<br>官方文档地址：<a href="https://hyb1996.github.io/AutoJs-Docs/#/" target="_blank" rel="noopener">https://hyb1996.github.io/AutoJs-Docs/#/</a></p><h2 id="系统读写等操作">4.1&emsp;系统读写等操作</h2><h3 id="App、Device">4.1.1&emsp;App、Device</h3><ol><li>启动应用，有两种方式：</li></ol><ul><li><code>app.launchApp(appName)</code>，通过应用名称启动，即图标下显示的名称；</li><li><code>app.launch(packageName)</code>，通过包名启动，关于如何获取应用的包名后面会讲到，举个栗子：<code>app.launch(&quot;com.bilibili.priconne&quot;)</code>；</li></ul><ol start="2"><li><p>获取包名： <code>app.getPackageName(appName)</code>，与此相对的还有根据包名获取应用名，举个栗子：</p><pre class="line-numbers language-js"><code class="language-js">appName <span class="token operator">=</span> app<span class="token punctuation">.</span><span class="token function">getPackageName</span><span class="token punctuation">(</span><span class="token string">"公主连结R"</span><span class="token punctuation">)</span><span class="token function">toastLog</span><span class="token punctuation">(</span>appName<span class="token punctuation">)</span><span class="token comment" spellcheck="true">//输出：com.bilibili.priconne</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>读写系统剪切板</p><pre class="line-numbers language-js"><code class="language-js"><span class="token function">setClip</span><span class="token punctuation">(</span><span class="token string">"将剪切板设置为这段话"</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">//getClip()返回剪切板内容</span><span class="token function">toastLog</span><span class="token punctuation">(</span><span class="token string">"当前剪切板："</span><span class="token operator">+</span><span class="token function">getClip</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>等待应用界面出现，<code>waitForPackage(package[, period = 200])</code></p></li><li><p>停止脚本: <code>exit()</code></p></li><li><p>设置脚本需要的安卓版本号</p><pre class="line-numbers language-js"><code class="language-js"><span class="token function">requiresApi</span><span class="token punctuation">(</span><span class="token number">24</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">// 需要至少Android 7.0</span><span class="token function">requiresAutojsVersion</span><span class="token punctuation">(</span><span class="token string">"3.0.0"</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">//指定Autojs最低版本号</span><span class="token comment" spellcheck="true">//会自动检测当前版本号，若过低会报错</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>获取屏幕分辨率</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> Width<span class="token operator">=</span>device<span class="token punctuation">.</span>width<span class="token punctuation">;</span><span class="token keyword">var</span> Height<span class="token operator">=</span>device<span class="token punctuation">.</span>height<span class="token punctuation">;</span><span class="token function">toastLog</span><span class="token punctuation">(</span>Width<span class="token operator">+</span><span class="token string">"x"</span><span class="token operator">+</span>Height<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>获取设备识别码<br>Autojs里常用的设备标识是<code>IMEI</code>和<code>ANDROID_ID</code>。<code>IMEI</code>(International Mobile Equipment Identity)是15位数字组成的国际移动设备身份码，写在主板上和硬件绑定，就算刷机也没法改变。<code>AndroidId</code> 是一串64位的编码（十六进制字符串），是随机生成的设备的第一个引导，通过它可以知道设备的寿命；在设备恢复出厂设置或刷机后，该值可能会改变，故和系统绑定。<br>当脚本要商业化的时候，可以通过设备码区分不同用户；如果脚本写出来只是一个人用，获取设备码应该也没啥用。</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> deviceId<span class="token operator">=</span>device<span class="token punctuation">.</span><span class="token function">getIMEI</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> androidId<span class="token operator">=</span>device<span class="token punctuation">.</span><span class="token function">getAndroidId</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">toastLog</span><span class="token punctuation">(</span>deviceId<span class="token operator">+</span><span class="token string">"\n"</span><span class="token operator">+</span> androidId<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>Device模块有很多功能，比如调整音量、屏幕亮度、获取内存和电量…但感觉写游戏脚本都用不到所以直接跳过吧。</p></li></ol><h3 id="Files">4.1.2&emsp;Files</h3><p>稍微复杂一点的脚本可能涉及到日志记录，比如刷了多少次图、有没有error之类，所以对文件的处理还是挺有用的。</p><ol><li><p>返回路径</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> path1<span class="token operator">=</span>files<span class="token punctuation">.</span><span class="token function">cwd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//当前工作文件夹绝对路径</span><span class="token keyword">var</span> path2<span class="token operator">=</span>files<span class="token punctuation">.</span><span class="token function">path</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//相对路径转绝对路径</span><span class="token comment" spellcheck="true">//还有一些不太常用的如files.getSdcardPath()、files.listDir(path[, filter])</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>文件（夹）操作（返回bool）</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> path<span class="token operator">=</span><span class="token string">"/sdcard/newFolder/"</span><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>files<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>   <span class="token comment" spellcheck="true">//创建文件或文件夹，若已存在则返回false，（需要上一级文件夹已存在）</span>files<span class="token punctuation">.</span><span class="token function">createWithDirs</span><span class="token punctuation">(</span><span class="token string">"/sdcard/newFolder1/newFolder2"</span><span class="token punctuation">)</span>； <span class="token comment" spellcheck="true">//若不存在会创建一系列文件夹，比上一个命令更强大</span><span class="token comment" spellcheck="true">//还有些如删除文件、判断空文件夹等功能、略过。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>文件读写（和python好像- -）</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> path <span class="token operator">=</span> <span class="token string">"/sdcard/1.txt"</span><span class="token punctuation">;</span><span class="token keyword">var</span> text <span class="token operator">=</span> <span class="token string">"Hello, AutoJs"</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//以写入模式打开文件</span><span class="token keyword">var</span> file <span class="token operator">=</span> <span class="token function">open</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span> <span class="token string">"w"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//open函数还可以指定文件编码</span><span class="token comment" spellcheck="true">// "r"：读， "w"：写 ， "a"：从文件末尾附加</span>file<span class="token punctuation">.</span><span class="token function">write</span><span class="token punctuation">(</span>text<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//还可以：file.writeline()、file.writelines()</span><span class="token comment" spellcheck="true">// var text=file.read() ，或者file.readlines()</span>file<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><h3 id="Shell">4.1.3&emsp;Shell</h3><p>Autojs有shell函数和shell对象，前者适合执行单次命令，后者由于使用同一个shell进程所以对多条命令效率高：</p><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//shell函数，返回result对象；result.code返回码，成功为0；result.result，运行结果（字符串）；result.error，无错误时为空，若未获取到root权限可能返回"Permission denied"。</span><span class="token keyword">var</span> result<span class="token operator">=</span><span class="token function">shell</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">,</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">if</span><span class="token punctuation">(</span>result<span class="token punctuation">.</span>code<span class="token operator">==</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token function">toast</span><span class="token punctuation">(</span><span class="token string">"执行成功"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//shell对象</span><span class="token keyword">var</span> sh<span class="token operator">=</span><span class="token keyword">new</span> <span class="token class-name">Shell</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//构造函数</span>sh<span class="token punctuation">.</span><span class="token function">exec</span><span class="token punctuation">(</span><span class="token string">"ls"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//执行命令，注意该函数没有返回值！！  并且命令执行是"异步"的，不会等待上一步执行完成。</span>sh<span class="token punctuation">.</span><span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//强制退出</span>sh<span class="token punctuation">.</span><span class="token function">exitAndWaitFor</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//等待执行完成并退出</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h4 id="Android常用shell命令">4.1.3.1&emsp;Android常用shell命令</h4><ul><li><p>Input</p><pre class="line-numbers language-sh"><code class="language-sh">input text 'hello world'input keyevent 26  # Powerkey<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>am</p><pre class="line-numbers language-sh"><code class="language-sh"># 感觉对写脚本没太大帮助...am start ...am kill ...am force-stop ...am restart ...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>pm</p><pre class="line-numbers language-sh"><code class="language-sh">pm list packages #列出所有APP包，这个命令感觉有点用pm install ...pm uninstall ...<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>wm</p><pre class="line-numbers language-sh"><code class="language-sh">wm size #查看屏幕尺寸wm size 720x1280 # 修改尺寸wm size reset #还原<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><h2 id="游戏脚本核心">4.2&emsp;游戏脚本核心</h2><h3 id="触摸模拟（基于坐标）、Keys">4.2.1&emsp;触摸模拟（基于坐标）、Keys</h3><ol><li><p><code>sleep(n)</code>：暂停运行n毫秒，游戏脚本中最常出现的一个命令；有一些操作必须给它一定的缓冲时间才能正确运行完成。</p></li><li><p>随机数： <code>random(min,max)</code>指定区间、<code>random()</code>范围是[0,1)；点击坐标时常设置一个随机偏移，防止被检测到（每次都点同一个点还是太明显了）</p></li><li><p>分辨率适配问题，<code>setScreenMetrics(1080, 1920);</code>、表示脚本适合的屏幕宽高为1080x1920（编脚本时基于的设备），如果在别的分辨率手机上运行则会自动放缩光标。听上去很好的一个功能，一般游戏脚本必加这一行，但具体效果如何我没有测试过。</p></li><li><p><code>click(x,y)</code>：点击坐标（无需root权限），返回是否成功，点击过程大约150ms，可能被其他事件中断。更长时间的点击如<code>longClick(x,y)</code>、持续600ms。</p></li><li><p><code>press(x,y,duartion)</code>：按住坐标，一般超过500ms才被系统认为是长按。</p></li><li><p><code>swipe(x1,y1,x2,y2,duration)</code>： 从(x1,y1)滑动到(x2,y2)，持续duration。</p></li><li><p><code>RootAutomator</code><br>上面的几个触摸操作都是免root的，而基于RootAutomator对象的触摸需要root权限，优点是执行没有延迟，明显比click要快。</p><pre class="line-numbers language-sh"><code class="language-sh">var ra=new RootAutomator(); //初始化一个对象ra.tap(x,y,id); //id代表不同“手指”，用于多点触摸，不需要时可省略该参数ra.swipe(x1,y1,x2,y2,duration,id)ra.press(x,y,duration,id)// 这些命令组合在一起就能完成复杂的操作了~ra.touchDown(x,y,id)ra.touchMove(x,y,id)ra.touchUp(id)<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>模拟按键；（返回bool值）</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token function">back</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//按下返回键</span><span class="token function">home</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">//返回桌面</span>还有一些需要root权限的，开头字母大写<span class="token punctuation">:</span><span class="token comment" spellcheck="true">//Home()、Back()、Power()、Menu()、OK()、KeyCode()...</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li></ol><h3 id="colors、images">4.2.2&emsp;colors、images</h3><h4 id="colors">4.2.2.1&emsp;colors</h4><p>颜色常用十六进制值或RGB值来表示，如蓝色可表示为<code>#0000FF</code>或<code>(0,0,255)</code>，一般都是<code>#</code>后面带6位十六进制数，分别表示R、G、B，但Autojs是8位，前面多了一个<code>A(Alpha)</code>、表示透明度，即ARGB。</p><ol><li><p>Autojs通过一个16进制整数或一个字符串表示一个颜色，两者可以互相转换</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> myBlue<span class="token operator">=</span>colors<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>color<span class="token punctuation">.</span>BLUE<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//返回#ff0000ff,colors.BLUE代表蓝色，后面必须大写。</span><span class="token keyword">var</span> numBlue<span class="token operator">=</span>colors<span class="token punctuation">.</span><span class="token function">parseColor</span><span class="token punctuation">(</span><span class="token string">"#ff0000ff"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//返回-16776961,至于为什么是这个数我也不清楚，平时还是用字符串表示比较好。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>colors对象里还有一些判断两个颜色的相似度、返回A、R、G、B通道值的函数，平时也基本上用不上；颜色的用途主要体现在后面的多点找色上。</p></li></ol><h4 id="images">4.2.2.2&emsp;images</h4><p>游戏脚本的灵魂所在，images主要有图片处理、找图、找色几个部分；想让脚本识别游戏的某个区域、如果该区域的位置是固定的，通过构造多点比色比较快，而如果位置不固定则常用找图的方式，虽然占用资源比较多但准确性有保障。</p><ol><li>images对象使用完后必须回收，防止内存泄漏。</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> img<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span><span class="token string">"./name.png"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//读取图片，错误时返回null</span><span class="token comment" spellcheck="true">//var img=images.load(url); //从网址获取图片</span><span class="token comment" spellcheck="true">//...图片操作后回收</span>img<span class="token punctuation">.</span><span class="token function">recycle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">// 例外：captureScreen()返回的图片无需回收</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li><p>images对象能对图像进行复制、保存、Base64编码解码、剪切、调整大小、放缩、旋转、拼接、灰度化、阈值化、颜色控件转换、二值化、模糊与平滑处理、滤波…（强是很强大，就是基本上用不上）</p></li><li><p>获取截图权限：在找图找色之前往往要先获取当前屏幕的截图，这个截图一般是临时的、不会保存到文件（也可以设置保存）。 截图之前要向系统<strong>申请一次</strong>截图权限：</p></li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">requestScreenCapture</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">//可指定参数true（横屏截图） 或者 false（竖屏截图）</span>    <span class="token function">toast</span><span class="token punctuation">(</span><span class="token string">"请求截图失败"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><ol start="4"><li>请求截图: <code>captureScreen</code></li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//在此之前记住要请求一次截图权限</span><span class="token keyword">var</span> img<span class="token operator">=</span><span class="token function">captureScreen</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//可以指定保存路径path</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="5"><li>颜色获取，很重要的一个函数，后面多点找色时可以先用它获取参数值。</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//获取某点的ARGB颜色值</span><span class="token keyword">var</span> color<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">pixel</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//img是之前创建的images对象</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="6"><li>区域找色（一种颜色）；<code>findColor</code>、<code>findColorInRegion</code>、<code>findColorEquals</code></li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//首先说下region和threshold这两个参数，后面的找色函数options里都要用到：</span><span class="token comment" spellcheck="true">//region、找色区域，默认全图、指定[x,y]代表左上角点，从(x,y)到右下角；指定[x,y,width,height]则代表从(x,y)到(x+width,y+height)。</span><span class="token comment" spellcheck="true">//threshold、相似度临界值，0~255，默认为4；similarity=1-threshold/255，可以算出默认相似度达到了0.98，觉得太严了可以适当增大threshold</span><span class="token keyword">var</span> point <span class="token operator">=</span> images<span class="token punctuation">.</span><span class="token function">findColor</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span> <span class="token string">"#ff0000"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> region<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">]</span><span class="token punctuation">,</span> threshold<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//如果找到则返回一个点，如：{463.0, 1242.0}；找不到返回null。</span><span class="token comment" spellcheck="true">//这里颜色值是6位，8位也行不过会忽略A通道（透明度）。</span><span class="token comment" spellcheck="true">// findColorInRegion，功能和findColor一样，只是优化了下参数表示。</span><span class="token keyword">var</span> point<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">findColorInRegion</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span><span class="token string">"#ff0000"</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">1080</span><span class="token punctuation">,</span><span class="token number">1920</span><span class="token punctuation">,</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">// findColorEquals，要求颜色完全相等，相当于findColor的threshold参数设为0</span><span class="token keyword">var</span> point<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">findColorEquals</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span><span class="token string">"#ff0000"</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">1080</span><span class="token punctuation">,</span><span class="token number">1920</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="7"><li>多点找色：<code>findMultiColors</code>，先定位第一个点的颜色、根据(x,y)偏移获取并对比第二个点的颜色…以此类推，命令很麻烦，通常需要写一个函数来构造颜色列。</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> point <span class="token operator">=</span> images<span class="token punctuation">.</span><span class="token function">findMultiColors</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span> <span class="token string">"#ff949fc7"</span><span class="token punctuation">,</span>    <span class="token comment" spellcheck="true">//第一个点</span>    <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token number">60</span><span class="token punctuation">,</span> <span class="token string">"#ffe6efe6"</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token comment" spellcheck="true">//颜色Array，</span>    <span class="token punctuation">[</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token string">"#ffeef3e6"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>    <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token number">60</span><span class="token punctuation">,</span> <span class="token string">"#ffe6efe6"</span><span class="token punctuation">]</span><span class="token punctuation">,</span>    <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token operator">-</span><span class="token number">60</span><span class="token punctuation">,</span> <span class="token string">"#ffeef3e6"</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>    <span class="token punctuation">{</span> region<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">1548</span><span class="token punctuation">,</span> <span class="token number">803</span><span class="token punctuation">,</span> <span class="token number">140</span><span class="token punctuation">,</span> <span class="token number">140</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">//指定区域</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="8"><li>检测某坐标颜色：前几个命令都是根据颜色找坐标，这个是给坐标、比较颜色</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">if</span><span class="token punctuation">(</span>images<span class="token punctuation">.</span><span class="token function">detectsColor</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span><span class="token string">"#fed9a8"</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token number">200</span><span class="token punctuation">,</span><span class="token number">16</span><span class="token punctuation">,</span><span class="token string">"diff"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//最后两个参数可省略，代表threshold和匹配算法；x=100,y=200</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="9"><li>找图：有时候找颜色会匹配到一些奇怪的地方去，还得用找图来实现，有<code>images.findImage</code>、<code>images.findImageInRegion</code>、<code>images.matchTemplate</code>。</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> temp1<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span>pathToImage<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">var</span> point<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">findImage</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span>temp1<span class="token punctuation">,</span><span class="token punctuation">{</span> region<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">]</span><span class="token punctuation">,</span> threshold<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//同样findImageInRegion只是优化了下参数排列</span><span class="token comment" spellcheck="true">//matchTemplate可以同时返回找到的多个位置，通过max控制最大的结果数量</span><span class="token keyword">var</span> result<span class="token operator">=</span>images<span class="token punctuation">.</span><span class="token function">matchTemplate</span><span class="token punctuation">(</span>img<span class="token punctuation">,</span>temp1<span class="token punctuation">,</span><span class="token punctuation">{</span> region<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">]</span><span class="token punctuation">,</span> threshold<span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">,</span>max<span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">//返回类型是一个MatchingResult对象，有point和similarity这两个数据成员。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="脚本结构管理">4.3&emsp;脚本结构管理</h2><h3 id="Module">4.3.1&emsp;Module</h3><p>在一个文件里通过<code>module.exports =...;</code>把某个对象导出，从而可以在另一个文件通过<code>var name=require(&#39;file.js&#39;);</code>导入；相当于把整个文件当做一个函数，把exports的东西当做返回值。感觉用起来也不太方便，我选择不用这个功能。</p><h3 id="Threads">4.3.2&emsp;Threads</h3><ol><li>启动一个子线程，<code>threads.start</code>：</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token comment" spellcheck="true">//启动一个无限循环的线程</span><span class="token keyword">var</span> thread <span class="token operator">=</span> threads<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">//用thread对象可以控制线程运行状态，如果不需要操作可以改为：</span><span class="token comment" spellcheck="true">//threads.start(function(){</span>    <span class="token keyword">while</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span>        <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"子线程运行中..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">5000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>thread<span class="token punctuation">.</span><span class="token function">interrupt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li><p><code>threads.shutDownAll()</code>： 停止所有通过<code>threads.start()</code>启动的子线程</p></li><li><p>等待线程开始执行（一般start后需要一段时间）：<code>thread.waitFor();</code>（这里thread是前面创建的thread变量）</p></li><li><p>等待线程执行完成：<code>thread.join();</code>，参数可以指定一个等待时间</p></li><li><p>中断线程运行：<code>thread.interrupt();</code></p></li><li><p>注意多线程中的变量问题，涉及到<strong>线程安全</strong>，文档里说的很详细</p></li><li><p>线程间的通信与传递变量，通过<code>var connect = threads.disposable();</code>实现；发送结果：<code>connect.setAndNotify(s);</code>，接收结果：<code>connect.blockedGet(s);</code></p></li></ol><h2 id="交互界面">4.4&emsp;交互界面</h2><h3 id="Events、Dialogs、Console">4.4.1&emsp;Events、Dialogs、Console</h3><ol><li>Events模块主要用来监听按键、触摸、通知等，但放在单线程里可能会因为程序其他部分而无法及时执行，造成非预期的结果，常常和多线程<code>Threads</code>模块一起使用，如音量键关闭脚本的例子：</li></ol><pre class="line-numbers language-js"><code class="language-js"><span class="token function">auto</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>threads<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment" spellcheck="true">//在子线程中调用observeKey()从而使按键事件处理在子线程执行</span>    events<span class="token punctuation">.</span><span class="token function">observeKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">//启用按键监听</span>    events<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"key_down"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span>keyCode<span class="token punctuation">,</span> events<span class="token punctuation">)</span><span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">//常用事件有key、key_down、key_up、exit、toast、notification、touch(触摸某点)</span>        <span class="token keyword">if</span><span class="token punctuation">(</span>keyCode <span class="token operator">==</span> keys<span class="token punctuation">.</span>volume_up<span class="token punctuation">)</span><span class="token punctuation">{</span>  <span class="token comment" spellcheck="true">//音量上键关闭脚本</span>            <span class="token function">exit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token punctuation">}</span>    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>events<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">"exit"</span><span class="token punctuation">,</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>   <span class="token comment" spellcheck="true">//脚本停止运行时会触发exit事件</span>    <span class="token function">toast</span><span class="token punctuation">(</span><span class="token string">"脚本已结束"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">while</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span>    <span class="token function">log</span><span class="token punctuation">(</span><span class="token string">"脚本运行中..."</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li><code>Dialogs</code></li></ol><p>这部分提供对话框支持，但由于是弹出一个全屏的消息提示框，实际体验是并不太能用上；如果脚本和用户的交互性比较强的话可以考虑一下。</p><ol start="3"><li><code>Console</code></li></ol><p>控制台的作用更像是用于调试，但一般Windows下用VSCode写脚本也不需要在控制台上显示吧，所以这部分给人的感觉也是很鸡肋…不过<code>console</code>的UI是固定的，也可以悬浮、最小化；有时不想设计UI的时候可以偷懒直接拿<code>console</code>过来凑合用用。</p><h3 id="Floaty、UI">4.4.2&emsp;Floaty、UI</h3><p>界面设计这部分内容相当多，而且官方文档也有很多写得很简略（甚至一笔带过），要想真正从零开始设计出一个实用好看的UI出来还是有难度的；我是建议去网上多找几个模板文件运行运行，在别人的基础上修改起来就快多了，看不懂的地方再去翻翻文档解决。一般UI设计好后再和程序一对接（通过UI各组件的id），就可以打包做成apk了~</p><h1 id="脚本实战：PriconneR">5&emsp;脚本实战：PriconneR</h1><p>说来惭愧，作为一名二刺螈选手、PriconneR是我最近在玩的手游。一般我准备中长期玩的手游都会没事写写脚本，第一次从按键精灵转到用Autojs，就拿它作为案例练练手吧。</p><h2 id="不同机型适配">5.1&emsp;不同机型适配</h2><p>游戏脚本最开始要考虑的问题就是用户需求吧。如果只是自己用用，那就安卓模拟器随便选个分辨率就可以开始写了；但如果用户很多而且手机分辨率各不相同，那在一开始写的时候就要注意适配的问题。我属于前者所以用模拟器就完事了~</p><h2 id="需求分析">5.2&emsp;需求分析</h2><p>脚本需要实现哪些功能，这个需要对游戏有比较深的认识，至少要玩够一整天的游戏才会清楚哪些地方通过脚本实现比较方便、哪些地方手动就行了吧…把需要实现的功能全部列出来，有时候可能总结的不够全面，这时候可以看看别人是怎么写的（下载个游戏蜂窝app，看看别人写的脚本有哪些功能），毕竟论经验还是这些专门靠写脚本赚钱的人比较丰富吧。<br>以PriconneR为例，我总结了一些<strong>重复性高、比较枯燥</strong>的部分（每日任务），如：公会点赞、技能强化、日常探索、领取礼物和任务奖励、刷地下城、免费扭蛋、装备升星…   （玩过的肯定明白吧，每天都要刷的）</p><h2 id="基础模块编写与调试">5.3&emsp;基础模块编写与调试</h2><p>对于上面这些需求，可以按顺序来编写，比如可以拍一拍脑袋、就决定先实现日常探索这个功能吧！接下来要做的就是<strong>进一步分解</strong>，把要实现这个功能的<strong>每一个步骤</strong>列出来，把每一步作为一个<strong>基础模块</strong>写成一个function或是别的。<br>比如日常探索这个功能，首先要进入探索页面吧，为此需要定位的基准（如游戏主页）吧，毕竟在哪个页面运行的脚本谁也说不准，那么第一个模块就是<code>backToMainPage()</code>了；进入探索页面后还需要决定刷哪一关、用券刷还是手动刷、手动刷的话如何判断战斗结束、用券刷那么券没有了怎么办、刷完后会弹出一些确认窗口需要处理…一开始需要考虑的问题比较多没办法，但这些模块有很多是能直接放到别的功能中的，一般写着写着就会感觉越来越顺，之后要多考虑的往往是模块间的衔接，比如加个<code>sleep(time)</code>保证动作能够顺利完成。<br>然后是整合模块进行调试，看能不能完成目标功能，如果不能那么是哪一步出问题了（图片识别失败？、动作间停顿时间过短？、没考虑意外情况出现？…）。有时候并不能立刻发现问题，而要等到用一段时间后。</p><h2 id="功能实现">5.4&emsp;功能实现</h2><p>这一部分没啥好说的，一个功能完成、调试也没问题之后，那就下一个呗，只到实现所有当初列的需求功能。</p><h2 id="UI制作">5.5&emsp;UI制作</h2><p>官方提供了很多案例，网上也有许多大佬自己做的漂亮UI，选一个自己进行修改就行了。我选择的是一个悬浮窗类型的界面，可以最小化到窗口边缘不占位置，也方便及时调整脚本的运行状态。<br>一般勾选框比较常用，其次是下拉选择以及按钮，功能这块最好加一个中止当前脚本运行，防止脚本不正确运行。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200725183831.webp" alt></p><h2 id="使用中微调">5.6&emsp;使用中微调</h2><p>一般最经常调整的东西有两大块：一是间隔时间，即动作之间的<code>sleep(time)</code>如何决定，这个要不断地尝试改良，没别的；二是图片识别，有时候换个电脑换个模拟器脚本就没法识图了，这时往往要考虑：  </p><ol><li>是不是图片选取不恰当，太小或者太大或者特征不明显</li><li>识图函数准确度参数是不是设置的太高或太低了</li><li>是不是用多点找色、区域找色等函数代替识图更好</li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-06-15-autojs-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>log4cpp和gdb学习</title>
      <link>https://chengpengzhao.com/2020-05-24-log4cpp-he-gdb-xue-xi/</link>
      <guid>https://chengpengzhao.com/2020-05-24-log4cpp-he-gdb-xue-xi/</guid>
      <pubDate>Sun, 24 May 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;最近的状态：感觉什么都没干但时间过得飞快。  &lt;/p&gt;
&lt;p&gt;好多要学的课程
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>最近的状态：感觉什么都没干但时间过得飞快。  </p><p>好多要学的课程要写的代码，毕设进度也还不够，加上偶尔打打游戏不想学习，自然花在blog上的时间就更少了。</p><h1 id="log4cpp">1&emsp;log4cpp</h1><ol><li>介绍  </li></ol><p>最近开始准备写些C++的东西，因为是在<code>linux</code>下所以也没打算用一些IDE，但Debug还是需要的，因为刚入门所以就从常用的log工具<code>log4cpp</code>和调试工具<code>gdb</code>开始学起吧。  </p><blockquote><p>log4cpp是一个开源的C++类库，它提供了在C++程序中使用日志和跟踪调试的功能。使用log4cpp，可以很便利地将日志或者跟踪调试信息写入字符流、内存字符串队列、文件、回滚文件、调试器、Windows日志、syslog和远程syslog服务器中。<br>log4cpp是个基于LGPL的开源项目，移植自Java的日志处理跟踪项目log4j，并保持了API上的一致。其类似的支持库还包括Java(log4j)，C++(log4cpp、log4cplus)，C(log4c)，python(log4p)等。<br>log4cpp有如下优点：</p><ul><li>提供了可扩展的多种日志记录方式</li><li>提供了NDC(嵌套诊断上下文)，可用于多线程、多场景的跟踪调试</li><li>提供了完整的日志动态优先级控制，可随时调整需要记录的日志优先级</li><li>可通过配置文件完成所有配置并动态加载</li><li>性能优秀，内存占用小，经过编译后的log4cpp.dll大小仅有160kb</li><li>代码级的平台无关性，Log4cpp源代码经过编译后，适用于大多数主流的操作系统和开发工具</li><li>概念清晰，学习和使用方便，熟练程序员一天之内即可很好地应用log4cpp进行开发</li></ul></blockquote><ol start="2"><li>安装及配置  </li></ol><ul><li><p>下载<code>****.tar.gz</code>安装包</p></li><li><p>解压后进入目录，运行：</p><pre class="line-numbers language-bash"><code class="language-bash">./configure<span class="token comment" spellcheck="true">#可能需要root权限</span><span class="token function">make</span><span class="token function">make</span> check<span class="token function">make</span> <span class="token function">install</span><span class="token comment" spellcheck="true"># 默认安装在 /usr/local/下</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><ol start="3"><li>使用</li></ol><pre class="line-numbers language-bash"><code class="language-bash">g++ test.cpp -llog4cpp -lpthread<span class="token comment" spellcheck="true">#要加上log4cpp和pthread选项，不然会报错</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><ol start="4"><li>配置</li></ol><p>若官网的测试例子运行不成功，则有可能是因为找不到log4cpp动态库，解决方法：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> vim  /etc/ld.so.conf<span class="token comment" spellcheck="true">#文件末尾加入一行：（log4cpp动态库安装位置）</span><span class="token comment" spellcheck="true"># include /usr/local/lib</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>不过我一般用的CMake编译，只需要<code>target_link</code>一下就行了，不用改文件。</p><ol start="5"><li>自定义</li></ol><p>找一个别人封装好的<a href="https://github.com/meihao1203/log4cpp" target="_blank" rel="noopener">配置文件</a>，拿过来能用就行了，毕竟只是个工具。</p><ol start="6"><li>各模块介绍</li></ol><p>没时间所以先鸽着。</p><h1 id="gdb">2&emsp;gdb</h1><ol><li><p>介绍：</p><blockquote><p>GDB（GNU Debugger）是UNIX及UNIX-like下的强大调试工具，可以调试ada, c, c++, asm, minimal, d, fortran, objective-c, go, java,pascal等语言。</p></blockquote></li><li><p>使用配置：</p></li></ol><ul><li><p>先安装： <code>sudo apt-get install gdb</code></p></li><li><p>编译时加上<code>-g</code>选项，否则会出现<code>...(no debugging symbols found)...done.</code>标识<br><code>gdb filename</code> 进入调试界面</p></li></ul><ol start="3"><li>常用命令：</li></ol><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 打开要调试的程序（若在shell里用gdb指定了目标则不需要用）</span><span class="token function">file</span> filename<span class="token comment" spellcheck="true"># 回车键默认执行上一条命令</span><span class="token comment" spellcheck="true"># 查帮助</span><span class="token function">help</span> <span class="token function">command</span><span class="token comment" spellcheck="true"># 可视化界面</span>wi<span class="token comment" spellcheck="true"># 或者通过 gdb -tui main 进入</span><span class="token comment" spellcheck="true"># 温馨提示: sudo apt-get install cgdb 发现新大陆吧</span><span class="token comment" spellcheck="true"># 不过这种方式安装的cgdb版本可能过低，推荐去github上下载下来编译安装</span><span class="token comment" spellcheck="true"># cgdb常用命令：</span><span class="token comment" spellcheck="true"># i 切换到gdb； o 选择要显示的代码文件；</span><span class="token comment" spellcheck="true"># F5 - Send a run command to GDB.</span><span class="token comment" spellcheck="true"># F6 - Send a continue command to GDB.</span><span class="token comment" spellcheck="true"># F7 - Send a finish command to GDB.</span><span class="token comment" spellcheck="true"># F8 - Send a next command to GDB.</span><span class="token comment" spellcheck="true"># F10 - Send a step command to GDB.</span><span class="token comment" spellcheck="true"># 快捷键可以通过cgdbrc自己配置，用起来真的香</span><span class="token comment" spellcheck="true"># 显示n到n+10行的代码</span><span class="token comment" spellcheck="true"># list n</span>l n<span class="token comment" spellcheck="true">#(连续按回车会不断往下显示</span><span class="token comment" spellcheck="true"># 退出gdb窗口</span><span class="token comment" spellcheck="true"># quit</span>q<span class="token comment" spellcheck="true"># 添加断点</span><span class="token comment" spellcheck="true"># break</span><span class="token comment" spellcheck="true"># b function_name</span><span class="token comment" spellcheck="true"># b row_num</span><span class="token comment" spellcheck="true"># b file_name:row_num</span><span class="token comment" spellcheck="true"># b row_num if condition</span><span class="token comment" spellcheck="true"># 查看断点</span><span class="token comment" spellcheck="true"># info break</span>i b<span class="token comment" spellcheck="true"># 输出：编号，类型，显示状态，是否启用，地址，其他信息</span><span class="token comment" spellcheck="true"># an example:</span><span class="token comment" spellcheck="true"># Num     Type           Disp Enb Address            What</span><span class="token comment" spellcheck="true"># 1       breakpoint     keep y   0x0000000000001426 in main()</span><span class="token comment" spellcheck="true">#                                                    at /home/zcp/Desktop/log_gdb_test/testgdb.cpp:7</span><span class="token comment" spellcheck="true"># 禁用断点</span>disable Num<span class="token comment" spellcheck="true"># 删除断点</span><span class="token comment" spellcheck="true"># delete NUm</span>d Num<span class="token comment" spellcheck="true"># 运行程序</span><span class="token comment" spellcheck="true"># run</span>r<span class="token comment" spellcheck="true"># 单步执行(有断点的情况下)</span><span class="token comment" spellcheck="true"># 需要先运行</span><span class="token comment" spellcheck="true"># next</span>n<span class="token comment" spellcheck="true"># 恢复运行</span><span class="token comment" spellcheck="true"># continue</span>c<span class="token comment" spellcheck="true"># 跳入与跳出函数</span><span class="token comment" spellcheck="true"># 需要先在调用函数处设置一断点</span><span class="token comment" spellcheck="true"># 跳入函数： step</span>s<span class="token comment" spellcheck="true"># 跳出函数：finish</span>f<span class="token comment" spellcheck="true"># 打印变量</span><span class="token comment" spellcheck="true"># print var</span>p var<span class="token comment" spellcheck="true"># 还可以修改变量值</span>p var<span class="token operator">=</span>1<span class="token comment" spellcheck="true"># 打印指针所指内容</span>p *var<span class="token comment" spellcheck="true"># 如果是数组、则上述只能打印第一个值，需要用@并指定长度</span>p *var@len<span class="token comment" spellcheck="true"># 监控变量</span><span class="token comment" spellcheck="true"># 必须先运行程序，否则提示`NO symbol`</span><span class="token function">watch</span> varinfo <span class="token function">watch</span><span class="token comment" spellcheck="true"># 查看变量类型</span>whatis var<span class="token comment" spellcheck="true"># 栈跟踪</span><span class="token comment" spellcheck="true"># backtrace</span>bt<span class="token comment" spellcheck="true"># 运行shell命令</span><span class="token comment" spellcheck="true"># 在命令前加!即可</span><span class="token operator">!</span>ls<span class="token comment" spellcheck="true"># 设置运行参数</span><span class="token keyword">set</span> args <span class="token punctuation">..</span>.<span class="token comment" spellcheck="true"># 查看运行参数</span>show args<span class="token comment" spellcheck="true"># 查看当前目录、切换目录</span><span class="token comment" spellcheck="true"># 和shell命令一样</span><span class="token function">pwd</span><span class="token function">cd</span> <span class="token punctuation">..</span><span class="token comment" spellcheck="true"># 查看运行环境</span><span class="token comment" spellcheck="true"># show paths</span>path<span class="token comment" spellcheck="true"># 等效于shell中的echo $PATH</span><span class="token comment" spellcheck="true"># 查看程序运行状态</span><span class="token comment" spellcheck="true"># info program</span>i prog<span class="token comment" spellcheck="true"># 变量自动显示</span><span class="token comment" spellcheck="true"># display &lt;expr></span>disp <span class="token operator">&lt;</span>expr<span class="token operator">></span><span class="token comment" spellcheck="true"># 要取消则 undisplay</span>undis<span class="token comment" spellcheck="true"># 或者：</span>delete display <span class="token operator">&lt;</span>dnums<span class="token operator">></span><span class="token comment" spellcheck="true"># 显示display欣喜</span><span class="token comment" spellcheck="true"># info display</span>i dis<span class="token comment" spellcheck="true"># 继续运行到指定位置</span><span class="token comment" spellcheck="true"># until num</span>u num<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-05-24-log4cpp-he-gdb-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《やはり俺の青春ラブコメはまちがっている》抜粋</title>
      <link>https://chengpengzhao.com/2020-04-19-yaharian-noqing-chun-rabukomehamatigatuteiru-ba-cui/</link>
      <guid>https://chengpengzhao.com/2020-04-19-yaharian-noqing-chun-rabukomehamatigatuteiru-ba-cui/</guid>
      <pubDate>Sun, 19 Apr 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;更新于20
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><br><br></p><blockquote><p><em>更新于2020-12-07 15:40:43</em></p></blockquote><h1 id="前書き">1&emsp;前書き</h1><p>まず前提として、何年前にこの作品のアニメを見たことがある(今はほぼ忘れた)。日本語を勉強し、そして暇つぶしに何か読もうと思い、何冊のラノベをKindleで購入しました。値段が少し高いだが、読んでいて面白かったから買ってよかった。<br>確かにこの前完結したらしいの作品、ひねくれた「ぼっち」八幡と個性豊かなメンバーの青春ラブコメである。  </p><h1 id="摘録">2&emsp;摘録</h1><h2 id="1">2.1&emsp;1</h2><p>目次：<br>①とにかく比企谷八幡はくさっている。<br>②いつでも雪ノ下雪乃はつらぬいている。<br>③つねに由比ヶ浜結衣はきょろきょろしている。<br>④それでもクラスはうまくやっている。<br>⑤つまり材木座義輝はズレている。<br>⑥けれど戸塚彩加はついている。<br>⑦たまにラブコメの神様はいいことをする。<br>⑧そして比企谷八幡はかんがえる。あとがき</p><blockquote><p>「私はな、怒っているわけじゃないんだ」……あー、出た。出たよこれ。面倒くせぇパターンだよ。「怒らないから言ってごらん？」と同じパターンだよ。そう言って怒らなかった人を今まで見たことがない</p></blockquote><blockquote><p>彼らは昼休みにここで男女混合で昼食をとり、腹ごなしにバドミントンをする。放課後は暮れなずむ校舎をバックに愛を語らい、潮風を浴びて星を見る。</p></blockquote><blockquote><p>傍から見ていると青春ドラマの配役を頑張って演じているような、そんな薄ら寒さしか感じない。そこでの俺の役は「木」とかそんな感じだ</p></blockquote><blockquote><p>少女は斜陽の中で本を読んでいた。世界が終わったあとも、きっと彼女はここでこうしているんじゃないか、そう錯覚させるほどに、この光景は絵画じみていた。それを見たとき、俺は身体も精神も止まってしまった。──不覚にも見惚れてしまった</p></blockquote><blockquote><p>異論反論抗議質問口応えは認めない。しばらく頭を冷やせ。反省しろ</p></blockquote><blockquote><p>放課後、二人きりの教室。そよ風でカーテンが揺れ、傾いた日差しが降り注ぎ、そして勇気を出して告白した一人の少年。今でも克明に思い出すことができるあの子の声。『友達じゃダメかなぁ？』</p></blockquote><blockquote><p>その名の如く、雪の下の雪。どれほど美しかろうと、手に触れることも手に入れることもできず、ただその美しさを想うことしかできない存在</p></blockquote><blockquote><p>人間、嫌なことほどよく覚えているものだ。今でも夜中に思い出すたび、布団ひっかぶって「うわああぁぁぁー」ってしたくなる。</p></blockquote><blockquote><p>「持つ者が持たざる者に慈悲の心をもってこれを与える。人はそれをボランティアと呼ぶの。途上国にはＯＤＡを、ホームレスには炊き出しを、モテない男子には女子との会話を。困っている人に救いの手を差し伸べる」</p></blockquote><blockquote><p>「平塚先生曰く、優れた人間は憐れな者を救う義務がある」</p></blockquote><blockquote><p>「まずは居た堪れない立場のあなたに居場所を作ってあげましょう。知ってる？居場所があるだけで、星となって燃え尽きるような悲惨な最期を迎えずに済むのよ」</p></blockquote><blockquote><p>やはり青春なんて噓ばっかりだ。高校三年夏の大会で負けた自分たちを美しいものに仕立て上げるために涙を流し、大学受験に失敗して浪人した自分をごまかすために挫折は人生経験だと言い張ったり、好きな人に告白できない自分を偽るために相手の幸福を考えて身を引いたと嘯いたり。あとは、そうだな。こんなぎすぎすしてイラッとくるような女のことをツンデレとか言って、訪れるわけもないラブコメを期待したりとか、な。</p></blockquote><blockquote><p>やっぱり青春は擬態で欺瞞で虚偽妄言だ。</p></blockquote><blockquote><p>「残念だが、学校は社会に適応させるための訓練の場だ。社会に出れば君の意見など通らない。今のうちから強制されることに慣れておきたまえ」</p></blockquote><blockquote><p>「楽しいだけが世の中じゃないですよ。楽しきゃいいって価値観だけで世界が成立してたら全米が泣くような映画は作られないでしょ。悲劇に快楽を見出だすこともあるわけだし」</p></blockquote><blockquote><p>「高二病は高二病だ。高校生にありがちな思想形態だな。捻くれてることがかっこいいと思っていたり、『働いたら負け』とかネットなどでもてはやされているそれらしい意見を常に言いたがったり、売れている作家やマンガ家を『売れる前の作品のほうが好き』とか言い出す。みながありがたがるものを馬鹿にし、マイナーなものを褒め称える。そのうえ、同類のオタクをバカにする。変に悟った雰囲気を出しながら捻くれた論理を持ち出す。一言で言って嫌な奴だ」</p></blockquote><blockquote><p>考えることを放棄しない人間は好きだよ。捻くれてはいるが、ね</p></blockquote><blockquote><p>優しくて往々にして正しい。だが世の中が優しくなくて正しくないからな。さぞ生きづらかろう</p></blockquote><blockquote><p>要するに、気まずさというのは「何か話さないと」「仲良くしないと」という強迫観念があるから生まれるんだと思う。</p></blockquote><blockquote><p>人はみな完璧ではないから。弱くて、心が醜くて、すぐに嫉妬し蹴落とそうとする。不思議なことに優れた人間ほど生きづらいのよ、この世界は。そんなのおかしいじゃない。だから変えるのよ、人ごと、この世界を</p></blockquote><blockquote><p>少しだけ、自分の鼓動が速くなるのを感じた。心臓の刻む律動が秒針の速度を追い越してもっと先へ進みたいと、そう言っている気がした。</p></blockquote><blockquote><p>つまり、青春を謳歌している派手めな女子。短めのスカートに、ボタンが三つほど開けられたブラウス、覗いた胸元に光るネックレス、ハートのチャーム、明るめに脱色された茶髪、そのどれもが校則を完全に無視した出で立ちだった</p></blockquote><blockquote><p>「飢えた人に魚を与えるか、魚の獲り方を教えるかの違いよ。ボランティアとは本来そうした方法論を与えるもので結果のみを与えるものではないわ。自立を促す、というのが一番近いのかしら」</p></blockquote><blockquote><p>俺が思う限りでは努力というのは最低の解決方法だ。もう頑張るしかない、その他のどんな要素も入りえない、それは逆に言えばもはや為す術なしという意味でしかない。はっきり言って無策と変わらないのだ。いっそ見込みがないからやめろと言ってもらったほうがよほど楽だ。無駄な努力ほど虚しいものはない。だったら引導を渡してやってそのぶんの時間と労力を他のことに注いだほうが効率がいい</p></blockquote><blockquote><p>きっと彼女はコミュニケーション能力が高いのだろう。クラスでも派手なグループに属すほどなのだから単純な容姿の他に協調性も必要とされる。ただ、それは裏を返せば人に迎合することがうまい、つまり、孤独というリスクを背負ってまで自己を貫く勇気に欠けるということでもある</p></blockquote><blockquote><p>残念な奴に何を言っても残念な奴は残念だから理解ができない。</p></blockquote><blockquote><p>努力は自分を裏切らない。夢を裏切ることはあるけどな</p></blockquote><blockquote><p>「努力しても夢が叶うとは限らない。むしろ叶わないことのほうが多いだろ。でも、頑張った事実さえありゃ慰めにはなる」</p></blockquote><blockquote><p>「お前含めて、社会が俺に厳しいんでな。せめて俺くらいは俺に優しくしてあげようと思うわけ。みんなもっと自分を甘やかすべきだろ。みんなダメになればダメな奴はいなくなる」</p></blockquote><blockquote><p>一気に弛緩した空気が流れ始める。ある者はダッシュで購買に走り、ある者は机をがたがた動かして弁当を広げ、またある者は他の教室へと向かう</p></blockquote><blockquote><p>人は考える葦であるというように、気づけば何事か思案している</p></blockquote><blockquote><p>膨大な情報を会話という限られた表現手段によって伝えるのは難しい。パソコンと同じだ。莫大なデータをサーバにあげたりメールで送ったりするのには時間がかかる。だから、ぼっちは会話が少々不得手になりがち、というただそれだけのことなのだ。</p></blockquote><blockquote><p>「ぼくはいつ選ばれるのかなードキドキ」とか思ってた十歳の俺が可哀想すぎて泣けてくんだろ。」</p></blockquote><blockquote><p>金髪縦ロールに、「お前花魁なの？」ってほどに肩まで見える勢いで着崩した制服。スカートなんて「それ履く意味あんの？」ってくらい短い。</p></blockquote><blockquote><p>俺が相手だったら鼻息だけで殺されるレベル</p></blockquote><blockquote><p>友達だから、仲間だから、だから何を言ってもいいし、何をしてもいい。三浦はそう言っているのだ。そして、その言葉の裏には「それができないなら仲間ではない。したがって敵である」という意図が隠然と込められている。こんなものはただの踏み絵で異端審問だ</p></blockquote><blockquote><p>「だーからー、ごめんじゃなくて。なんか言いたいことあんでしょ？」そう言われて言える奴なんていない。こんなのは会話でも質問でもない。ただ謝らせたいだけで、攻撃がしたいだけなのだ。あほくさ。せいぜい身内で潰しあえよ。</p></blockquote><blockquote><p>別に助けてやろうなんて気はこれっぽっちもないんだけどよ、知ってる女の子が目の前で泣きそうになってると胃がきゅるきゅるして飯がまずくなんだよ。やっぱご飯くらいおいしく食べたいじゃねぇか。</p></blockquote><blockquote><p>もうやめろよ、めんどくせぇ。そういうの見てる側も気を使うんだよ。嫌な雰囲気なんて耐えられないんだよ。お前らの青春群像劇に観客巻き込んでんじゃねぇよ。</p></blockquote><blockquote><p>聞く者の身を竦ませる、極北の地に吹きすさぶ風のような、けれど極光の如く美しい声。</p></blockquote><blockquote><p>書きたいことが、誰かに伝えたいことがあるから書きたい。そして、誰かの心を動かせたならとても嬉しい。だから、何度だって書きたくなる。たとえそれが認められなくても、書き続ける。その状態を作家病というのだろう。だから俺の答えは決まっていた。「ああ、読むよ」</p></blockquote><blockquote><p>頭悪ぃなと自分でも思う。何の意味があんだよと本気で感じる。けど、少なくとも〝嫌な時間〟ではなくなった。まぁ、それだけだ</p></blockquote><blockquote><p>「人生は苦いから、コーヒーくらいは甘くていい……」</p></blockquote><blockquote><p>女の涙ほど信用ならないものはない</p></blockquote><blockquote><p>俺は暗くなりそうな気持ちを壁にぶつけた。青春に壁はつきものである</p></blockquote><blockquote><p>えー噓、何この気持ち。すっごい心臓ばくばく言ってる。これが男じゃなかったら速攻で告白して振られているところだよ。え、振られちゃうのかよ</p></blockquote><blockquote><p>自信なさげに下へと伏せられた瞳、由比ヶ浜のブレザーの裾を力なく握る指先、透き通るように白い肌。陽の光を浴びれば泡沫の夢の如く消え失せてしまいそうな、そんな儚げな存在だった。</p></blockquote><blockquote><p>男なら一度は言ってみたいセリフベスト三だった。ちなみに一位は『ここは俺に任せて先に行け』である。</p></blockquote><blockquote><p>誰かの顔色を窺って、ご機嫌とって、連絡を欠かさず、話を合わせて、それでようやく繫ぎとめられる友情など、そんなものは友情じゃない。その煩わしい過程を青春と呼ぶのなら俺はそんなものいらない。ぬるいコミュニティで楽しそうに振る舞うなど自己満足となんら変わらない。そんなものは欺瞞だ。唾棄すべき悪だ。</p></blockquote><blockquote><p>塵も積もれば山となる、という言葉をご存じだろうか。もしくは三人寄れば文殊の知恵でもいい。要するに、寄り集まった者たちはより強固になる、ということである。けれど、俺たちは、ダメな奴らが集まってダメなことをやってるだけだ。</p></blockquote><blockquote><p>ちょこまかと動き回る小さきものたちは何を考えているのかわからんが、せせこましく生きていた。何と言うか、東京のオフィス街にある高いビルから下を見下ろしたらこんな感じなのかもしれない。黒いスーツを着たサラリーマンたちが行き交う姿と働きアリの姿が重なって見える。いずれは俺もあのアリたちの如く、ビルから見下ろしたときの黒点の一つになるのだろうか。そのとき、何を思い俺は生きるのだろう。</p></blockquote><blockquote><p>その程度の安い同情で救われてたら、こんな性格になってねぇんだよ。そんな言葉一つで誰かの悩みが解決できるなら、そもそも悩みゃしねーんだよ。</p></blockquote><blockquote><p>葉山、お前は知らないだろう。なぜ人が人を褒めると思う？それはな、さらなる高みに持ち上げることで足元を掬いやすくし、高所から叩き落とすためなんだよっ！これを人は褒め殺しと呼ぶ</p></blockquote><blockquote><p>俺は確かにぼっちだが、だからといって他の仲良くよろしくやってる連中に嫉妬しているわけじゃない。その不幸を祈っているわけじゃない。……噓じゃないぞ？ほんとだぞ？別に俺たちは仲良しサークルでもないし、オトモダチでもない。何の因果か集まった、あるいは集められてしまった寄せ集めの集団だ。ただ俺は証明したいだけなのだ。ぼっちは可哀想な奴なんかじゃないと、ぼっちだから人に劣っているわけではないと</p></blockquote><blockquote><p>「知ってる？私、暴言も失言も吐くけれど、虚言だけは吐いたことがないの」風が止んだせいでその声はやけにクリアに聞こえた。ああ、知ってるよ。噓つきは、俺とあいつらだけだから</p></blockquote><blockquote><p>一年間、あそこでただ一人、誰と喋るでもなく静かに過ごしていた俺だけが知っている。俺の孤独で静謐な時間をあの風だけが知っている。他の誰でもない、俺だけが打てる、俺の魔球</p></blockquote><blockquote><p>だが、あれこそは俺の孤独の象徴、最強の鉾。虚空より降り来る、青春を謳歌せし者への鉄槌。</p></blockquote><blockquote><p>青春。漢字にしてわずか二文字ながら、その言葉は人の胸を激しく揺さぶる。世に出た大人たちには甘やかな痛みや郷愁を、うら若き乙女には永久の憧れを、そして、俺のような人間には強い嫉妬と暗い憎悪を抱かせる。</p></blockquote><blockquote><p>青春ラブコメには最後にこう付け加えてあるでしょう？「※この作品はフィクションであり、実在の事件、人物、団体とは関係ありません。」って。つまり、あんな青春ラブコメは噓八百です。みんな騙されているのです。</p></blockquote><p><br><br></p><blockquote><p><em>以下内容更新于2020-05-23 11:18:42</em></p></blockquote><h2 id="2">2.2&emsp;2</h2><p>目次：<br>⓪プロローグ<br>①こうして由比ヶ浜結衣は勉強することにした 。<br>②きっと、比企谷小町は大きくなったらお兄ちゃんと結婚する。と俺は思っている。<br>③いつでも葉山隼人は整えている。<br>④いろいろあって川崎沙希は拗ねている。<br>⑤またしても、比企谷八幡は元来た道へ引き返す。あとがき</p><blockquote><p>要するに彼らは弱いから群れとなって行動しているのだ。惰弱な生命の本能として集団行動をとっているだけだ。肉食獣に襲われたときに誰かを生贄として差し出すために寄り集まっている草食動物と変わらない。何食わぬ顔で草を食っているくせに、仲間を食い物にしているのだ。</p></blockquote><blockquote><p>風が吹いた。放課後の、気だるい空気を運び去るような、そんな運命的な風。夢を描いた一枚の紙を未来への紙飛行機のように飛ばしていく。詩的に表現したが、もちろん俺が今さっき書いていた紙だ。おいバカこの風マジふざけんな。</p></blockquote><blockquote><p>風が吹いた。重く、垂れ下がった暗幕を取り払うような、そんな宿命的な風。夢を託した一枚の布を未来永劫焼き付けるように神風に靡く。詩的に表現したが、要するにパンツが見えた。おい、でかしたこの風マジよくやった！</p></blockquote><blockquote><p>開け放たれた窓から、うららかな初夏の風が入ってきて一切れの紙が踊る。俺はそのセンチメンタルな光景に心を奪われ、風の行く末を問おうと紙切れの動きを目で追った。はらり、と。まるで零れ落ちた涙のように儚く、その紙は床へと舞い降りる。</p></blockquote><blockquote><p>優しさも同情も、愛も勇気も友達も、ついでにボールも俺には不要だ。</p></blockquote><blockquote><p>「勉強とか、意味なくない？社会に出たら使わないし……」「出た！バカの常套句！」</p></blockquote><blockquote><p>携帯電話ってやつはある種、ぼっちを加速させるデバイスだと思うのだ。電話が来ても放置とか着信拒否とかできるし、メールも返さなきゃそのままだ。人間関係を取捨選択できてコミュニケーションが気分次第でオンオフできる。</p></blockquote><blockquote><p>学校という場所は単に学業をするためだけの施設ではない。要するにここは社会の縮図であり、人類全体を箱庭にしたものだ。だから、戦争や紛争があるようにいじめだってあるし、格差社会を引き写したようにスクールカーストだってある。</p></blockquote><blockquote><p>要するに、あいつらリア充（笑）はそうやって自分の気持ちに噓ついて怒りを抑え込んで仲良くしようと振る舞ってるだけなんだ。</p></blockquote><blockquote><p>「知りたいか？」悪魔の問いかけに、哀れな仔羊、</p></blockquote><blockquote><p>早く帰ること風の如し、静かに居眠りすること林の如し、嫉妬すること火の如し、働かざること山の如し</p></blockquote><blockquote><p>果報は寝て待て</p></blockquote><blockquote><p>ぼっちは言葉の裏を読むスキルが無駄に高いから主語述語をしっかり言ってくんないとわかんないっての</p></blockquote><blockquote><p>それにしてもあれだ。女子力という単語を使っている女子のほうが余程女子力が低いということに気づかない女子は女子力が低いと思う。</p></blockquote><blockquote><p>爽やかな初夏の風が二人の間を通り抜けた</p></blockquote><blockquote><p>例えば、雪ノ下雪乃。彼女は誰にも理解されなくとも諦めも嘆きもしない。それでもなお貫き通すことが強さだと彼女は確信しているからだ。例えば、由比ヶ浜結衣。彼女は誰かを理解することについて諦めることも逃げることもしない。表面上であったとしても触れ合い続けることで何かが変わると祈っているからだ。</p></blockquote><blockquote><p>世の中には凄くいいお兄さんがいるんだなーと思ったら俺だった。思いがけないイイ話に不覚にも涙が出そうになってしまう</p></blockquote><blockquote><p>真実は残酷だというなら、きっと噓は優しいのだろう。だから、優しさは噓だ。</p></blockquote><blockquote><p>夜中に見上げた月みたいに、どこまでもついてくるくせに手が届かない。</p></blockquote><blockquote><p>俺に優しい人間はほかの人にも優しくて、そのことをつい忘れてしまいそうになる</p></blockquote><blockquote><p>いつだって期待して、いつも勘違いして、いつからか希望を持つのはやめた。だから、いつまでも、優しい女の子は嫌いだ。</p></blockquote><h2 id="3">2.3&emsp;3</h2><p>目次：<br>①こうして平塚静は新たな戦端の口火を切る。<br>②やはり戸塚彩加との青春ラブコメはまちがっていない。<br>③雪ノ下雪乃はやっぱり猫が好き。<br>④ちゃっかり比企谷小町は画策している。<br>⑤それでも材木座義輝は荒野に一人、慟哭す。<br>⑥ようやく彼と彼女の始まりが終わる。<br>ぼーなすとらっく！「たとえばこんなバースデーソング」</p><blockquote><p>守るべきもの、それは言い換えれば弱点にほかならない。かのギリシャの英雄アキレスにも、最強の僧兵武蔵坊弁慶にも弱点があったからこそ敗れた。きっと彼らは弱点さえなければ歴史に勝利者として名を刻んだはずである。</p></blockquote><blockquote><p>じめじめとした空気が校舎の中にわだかまっている。登校ラッシュの昇降口は人が密集していてなおさら不快指数が上がっていた。</p></blockquote><blockquote><p>ぼっち、という語感から暗がりの隅っこのほうにいると思われがちだが、俺クラスのぼっちともなるとむしろ堂々と振る舞ってしまう。そのため、俺の周りはさながら台風の目のごとく、ぽつんと学校内でエアポケットを形成していた</p></blockquote><blockquote><p>本来、ぼっちというのは誰にも迷惑をかけない存在だ。人と関わらないことによってダメージを与えない、究極的にエコでロハスでクリーンな生き物なのだ。</p></blockquote><blockquote><p>人生はリセットできないが、人間関係はリセットできる。ソースは俺。中学の同級生とか一人も連絡とってな……それはリセットじゃなくて、デリートでした、てへっ</p></blockquote><blockquote><p>とにかく、俺と由比ヶ浜の関係は一流の剣豪同士が間合いを測り合うようなあの瞬間に似ていた。「この勝負……、先に動いたほうが負けるな……」みたいな雰囲気である。</p></blockquote><blockquote><p>こういう空気になったときの結末はよく知っている。お互い、なんとなく距離を取って、なんとなく交流が途絶えて、そして、なんとなく二度と会うこともなくなる。ソースは俺。</p></blockquote><blockquote><p>女子からのメールは自動で敬語に変換するソフトとかあればいいのに。そしたら変な期待せずにすむのにな</p></blockquote><blockquote><p>世間話や一つの題材についてであれば話したりするが、個人のプライベートに触れることはかなり稀だ。</p></blockquote><blockquote><p>君子危うきに近寄らず、来る者は拒み、去る者は追わず</p></blockquote><blockquote><p>「ここは君たちの仲良しクラブではない。青春ごっこならよそでやりたまえ。私が君たち奉仕部に課したものは自己変革だ。ぬるま湯に浸かって自分を騙すことではない」</p></blockquote><blockquote><p>軽く手を振って自転車に跨ると、漕ぎ出そうとする。と、背中にくいっと抵抗感があった。何か引っかけでもしたのかと振り返ると戸塚が俺のシャツをつまんでいる。</p></blockquote><blockquote><p>しかし男だ。なんという絶対の安心感。戸塚相手なら優しくされても勘違いすることもないし、勢い余って告白してこっぴどく振られ、やたらめったらダメージを負うこともない。</p></blockquote><blockquote><p>まぁ、どっちにしても最後は「俺、何してるんだろ……」に行きついてしまうのが問題だ。</p></blockquote><blockquote><p>ホールに足を踏み入れると音の洪水に巻き込まれたみたいに一瞬にして違う世界が広がっている。煌めく電飾、立ち上る紫煙、大音響に負けない笑い声</p></blockquote><blockquote><p>「格ゲー仲間か……、わかりやすくていいな。そういうの」友達という言葉の曖昧さを排したその表現はちょっと気に入った。</p></blockquote><blockquote><p>俺のスタイルはいつだって、「悩むくらいなら諦める」だ。すぱっと、何事もなかったように振る舞えばいい。何かあったときだけ態度を変えるなんて、不誠実でいけないやな。</p></blockquote><blockquote><p>今日の小町は服装のせいかいつもより明るく元気に見えた。ボーダーのタンクトップに肩口が大きく開いた薄手でピンクのカットソーを合わせ、ややローライズ気味な腿より上丈のショートパンツ。そして、屈託のない弾けるような一級品の笑顔。どこに出しても恥ずかしくない自慢の妹だ。どこにも出さないけど。</p></blockquote><blockquote><p>軽く羽織った四分丈程度のクリーム色したカーディガン、ふんわりとした清楚なワンピースは胸よりやや下あたりがリボンで絞られ、いつもより柔らかな印象を与える。歩くたび、素足に履かれたシンプルなストラップサンダルが涼しげで軽やかな音を立てた。</p></blockquote><blockquote><p>誤解は誤解。真実ではない。ならそれを俺自身が知っていればいい。誰に何を思われても構わない。……いつも誤解を解こうとすればするほど悪い方向に進むしな。</p></blockquote><blockquote><p>俺が玄関前まで行くと、高津君は五段変速ギアのマウンテンバイクにまたがったまま、新聞紙でくるまれた包みを渡してきた。</p></blockquote><blockquote><p>青空はどこまでも澄み渡り、夏の始まりを予感させていた。今日は暑くなりそうだ。</p></blockquote><blockquote><p>時間の流れを感じる。俺も気付かぬ間に大人になりつつあるのだ。懐かしいよな、手ぶらでスキーのキャッチコピー。今となっては手ぶらって聞くと手ブラしか思いつかない。時間の流れを感じる。俺も気付かぬ間に大人になりつつあるのだ……。</p></blockquote><blockquote><p>ぶつくさ文句を垂れる俺を見て、小町は大きなため息を吐いて、アメリカ人がするような「はぁ～、こいつわかってねぇな～」みたいな肩を竦めるリアクションをした。おい、結構ムカつくぞ、その態度。</p></blockquote><blockquote><p>あー、その気持ちわかるなぁ。服選んでるときに話しかけるのほんとやめてほしい。服屋の店員さんはぼっちが放つ「話しかけんなオーラ」を感じ取るスキルを身につけたほうがいい。そのほうがたぶん売り上げ上がるぞ。</p></blockquote><blockquote><p>「言わなければわからないの？あなた、空気を吸って吐くだけしかできないならそこらのエアコンのほうがよほど優秀よ？」確かに。空気清浄とか節電とか超お役立ちだ。早く空気を読む機能を搭載してほしい。</p></blockquote><blockquote><p>雪ノ下が俺のクズさに全幅の信頼を寄せるように、俺もまたこいつとどうこうならないことに関してだけは絶対の自信を持っている。これはこれで信頼と呼べるのかもしれない。なにこれ、全然平和的じゃないんだけど。</p></blockquote><blockquote><p>パンドラちゃんが持ってた箱の中にはあらゆる災厄と一緒に希望が詰まってたっていうじゃんか。あれだよあれ。希望も災厄ってことだ</p></blockquote><blockquote><p>そのため息はこれまでのどのため息よりも深く、一番物憂げだった。知ろうともしてこなかったことを悔いているのだろうか。なら、それは無駄な後悔だ。</p></blockquote><blockquote><p>生きているというのは何よりも尊いんだ。それを恥ずかしく思うだなんてそのほうが恥ずかしいんだぞ？だから、俺のことを見て『はっずかし～ぷっくっすくす』とか笑っちゃう奴らに生きる価値とかないよな</p></blockquote><blockquote><p>けど、こうやって好きなものを好きに語れるっていうのはいいと思う。たとえ、それが一般的でなくても、大衆受けしなくても。自分が大好きなものをとるか、自分のことなんて別に好きでもない連中と仲良くすることをとるかなんて、考えるまでもない。</p></blockquote><blockquote><p>艶やかな黒髪、きめ細かく透き通るような白い肌、そして、整った端正な顔立ち。輝きを放つような類い稀なる容姿は清楚さを漂わせながらも、人懐っこい笑みのおかげで華やかさが加わっていた。</p></blockquote><blockquote><p>「ええ。容姿端麗、成績最高、文武両道、多芸多才、そのうえ温厚篤実……およそ人間としてあれほど完璧な存在もいないでしょう。誰もがあの人を褒めそやす……」</p></blockquote><blockquote><p>非モテ三原則【（希望を）持たず、（心の隙を）作らず、（甘い話を）持ち込ませず】を心に刻んで生きているのだ</p></blockquote><blockquote><p>世にいわゆる「いい女」というのはいても、「都合のいい女」というのはいないのである。</p></blockquote><blockquote><p>俺は本物の笑顔を知っている。媚びたり、騙したり、誤魔化したりしない、本物を。</p></blockquote><blockquote><p>心にもないことを言うのがリア充なのだろうか。つまり、噓つきはリア充の始まりである。</p></blockquote><blockquote><p>彼らの仲間意識というのは相当なもので、自分の群れ以外とはあまり話さない。単独行動時に他の群れに交じろうとしない。それを考えると結構排他的であり差別的だ。つまり、逆説的にぼっちマジ博愛主義者。何も愛さないということはすべてを愛することに等しい。</p></blockquote><blockquote><p>なんとなく自分の手を見て「そういや爪ちょっと伸びてきたな」とか「あれ、俺の生命線短くなってね」とかどうでもいい思考が次から次に湧いてくるから退屈はしない。時間を無駄に消費することに関しては自信がある。なんという無駄スキル……</p></blockquote><blockquote><p>そもそも俺が誰かを選ぼうだなんて間違っている。誰からも選ばれない人間が誰かを選ぼうだなんて笑っちまうぜ。</p></blockquote><blockquote><p>「あんたは夢を言い訳にして現実逃避してるだけなんですよ」</p></blockquote><blockquote><p>ユーザー視点っていうか、ユーザーどまりっていうか。表面だけなぞってきゃっきゃしてるだけっつーか</p></blockquote><blockquote><p>というのも、中二病を虚仮にして悦に入ってる姿がなんとも香ばしく歯痒かったからにほかならない。夢見る少年に、現実の厳しさを教えてやると息巻いている疲れた大人を見るような、そんな痛々しさがそこにはある。</p></blockquote><blockquote><p>正しいやり方が偉いだなんて、それこそが怠慢だと俺は思うのだ。教科書に従って、カリキュラムをこなして、ノルマを達成して……。それは今までの伝統と正攻法にのっとっているだけじゃないのか。過去の財産に依存して、権威に寄りかかって、未だ何者でもない自分自身を塗り固めるものではないのか。自分の正しさを何かに委ねることのどこに正しさがある。</p></blockquote><blockquote><p>額面で二十万円切ってる給料だったり、有名大学の悲惨な就職率だったり、年間の自殺者数だったり、増税だったり、納めても戻ってくるあてのない年金だったり。</p></blockquote><blockquote><p>みんな冗談混じりに働いたら負けだっつーが、あながち間違ってやしない。そんな世界で夢だけ追う生活は苦しくて悔しくて、考えただけでため息が出る。</p></blockquote><blockquote><p>ゲームライターになるだのラノベ作家になるだのって言い出すことは、普通の人間が聞けばそんなくだらない妄想と同じくらい荒唐無稽な夢だ。</p></blockquote><blockquote><p>疑いもせず、悲観論から入らず、好きだからの一言だけで自らの行く末を決めてしまえる愚直さが。愚かしいにもほどがあり、眩しいほどにまっすぐすぎる。好きだって、そう素直に言える強さがあまりにも眩しい。冗談交じりでも強がりでもなく心の底から言える無垢さは俺がしまいこんでしまったものだから。</p></blockquote><blockquote><p>根性？忍耐？精神論？石の上にも三年？違う、最初から狙ってた。だから、今までの敗北は敗北じゃない。ちょっとやそっとの敗北なんて勝利への布石だ。負けは認めるまで負けじゃない。</p></blockquote><blockquote><p>全部断たれて望みがゼロになっても、それでも吠え続けられるなら。何物にも拠らず己の純粋な意志だけを寄る辺として立ち続けるなら。なら、それをして夢と呼ぶのだろう。何者にも冒し難き貴い幻想。それゆえに一握りの者しか手にできない、世にも稀なる現実。</p></blockquote><blockquote><p>一瞬の躊躇はカードを選ぶためのものか、それとも自らの歩んできた道を振り返りでもしたか</p></blockquote><blockquote><p>雪ノ下は悔しげに唇を嚙みしめ、羞恥に頰を染めてそっとサマーベストの裾に手をかける。屈辱に震える指がなかなか裾を摑めず、見てるこっちがやきもきしてしまう</p></blockquote><blockquote><p>大貧民という現代社会に酷似したゲームの中にあって、儚くも輝く希望の存在だった</p></blockquote><blockquote><p>夢が叶うも叶わぬも運次第。勝つも負けるも運次第。ソースは『とっても！ラッキーマン』。何これ無理ゲーすぎる。だからまぁ、材木座の夢が叶うかどうかも運次第だよな</p></blockquote><blockquote><p>残照に照らされて、わずかに朱に染まる雪ノ下の頰。それをぽーっと眺めていた由比ヶ浜の口元にじわじわと喜びの色が滲み出てきた。少し瞳を潤ませるとがっと雪ノ下の右腕に抱きついた。</p></blockquote><blockquote><p>これで解放されるのだ、全部終わりにできる。痛々しい勘違いも見当違いの自衛行動も。たぶん、これすらも痛々しい勘違いで見当違いの自衛行動なんだろうけど</p></blockquote><blockquote><p>俺が彼女を彼女と認識せずに救ったのならば、彼女もまた、俺を俺と認識せずに救われたのだから。なら、その情動も優しさも俺に向けられているものではない。救ってくれた誰かへのものだ。だから勘違いしてはいけない。勝手に期待して勝手に失望するのはもうやめた。最初から期待しないし、途中からも期待しない。最後まで期待しない。</p></blockquote><blockquote><p>夕映えの中で細められた瞳が何を映しているかはわからなかった。</p></blockquote><blockquote><p>俺と由比ヶ浜が座っていた席と、雪ノ下のいた場所との間は僅か二メートル足らず。なぜか、ふと、その距離は越え難く、見えない線が引かれているように感じた。俺たちと彼女とを明確に分けるもの、その事実に、あるいは真実に気づくのはもう少し先のことだ</p></blockquote><blockquote><p>しかるに、赤ん坊が生まれたときに泣いているのは世に生まれ出た感動からではなく、母親から離れ、世界に初めて孤独を感じるから泣くのかもしれない。</p></blockquote><blockquote><p>俺が歩き出すと後ろのほうで何やら声が聞こえたが、ＢＧＭにまぎれてしまった。</p></blockquote><blockquote><p>皆が一様に声を張り上げ、全力で盛り上がっている、という演出をしているように見えてしまう。きっと彼ら彼女らリア充たちは騒いでいないと不安で仕方がないんだろう。</p></blockquote><blockquote><p>お前は美容室行ってどんな髪型にするか聞かれたときの俺か。はっきりしゃべれはっきり。</p></blockquote><blockquote><p>お前はあれか、自転車乗ってたら警察官に止められて防犯登録確認されてるときの俺か。はっきりしゃべれはっきり。</p></blockquote><blockquote><p>「これは俺の友達の友達の話なんだが……」「な、なんか聞いたことある展開だなぁ……」</p></blockquote><h2 id="4">2.4&emsp;4</h2><p>目次：<br>①こうして比企谷八幡の夏休みが過ぎてゆく。<br>②どうしても平塚静からは逃げられない。<br>③誰に対しても葉山隼人はそつがない。<br>④唐突に、海老名姫菜は布教を開始する。<br>⑤ひとり、雪ノ下雪乃は夜空を見上げる。<br>⑥不覚にも、比企谷八幡は水着を持ってきていない。<br>⑦最後に鶴見留美は自分の道を選び取る。<br>⑧そして、雪ノ下雪乃を乗せた車は走り出す。あとがき</p><blockquote><p>俺はキンキンに冷えたＭＡＸコーヒーを飲んだ。そこいらのカフェオレでは真似できない、喉に絡みつくような練乳独特の甘みが頭にまで染み渡る。かき氷にかけるのもおすすめだ。大人だって、甘えたいときがある。コーヒーはＭＡＸコーヒー。脳内で最近流行のステルスマーケティングを決めてみた。</p></blockquote><blockquote><p>「だって、お兄ちゃんと同じ学校行きたいもん」「……」思わず、うるっと来た。普段、俺にひとかけらの敬意も向けない妹が、ふとした瞬間に垣間見せた温かな愛情。目頭が熱くなり、虚空から雨滴が一滴、落ちそうになる。</p></blockquote><blockquote><p>俺の場合、そもそも誘われないだろうし、誘われてもあまりになにもしゃべらないので二度目からは呼ばれなくなるだろうからその心配はない。だいたい忘年会ってなんだよ、そんな簡単に忘れるなよ。あと、ぼくのことも忘れないでください。</p></blockquote><blockquote><p>友達や家族、あるいは恋人と連れ立って歩く人々の群れはやけに歩くのが遅い。終始横を気にしているからなのか、それとも会話することに注意を割いているから足もとがおろそかになっているのか、もしくは少しでも長い時間一緒にいたいと考えているからなのか。</p></blockquote><blockquote><p>お前に足りないものは、それは！情熱思想理念頭脳気品優雅さ勤勉さ！</p></blockquote><blockquote><p>そばに友人もいなけりゃ彼女もいない、一人、肩で風を切って歩けるぼっちは、想像力を働かせればいつだって世界がアミューズメントパークだ。</p></blockquote><blockquote><p>普段その手の本を読まないので、とんと見当がつかない。まぁ、人間、興味のあるものしか視界に入れないし認識しないよね。</p></blockquote><blockquote><p>日はいささか傾き始めたが、まだまだ暑く、べとつくような生ぬるい潮風が吹き抜けていた。夏の盛りだが、もともと埋め立て地なうえ、高層ビルが立ち並ぶこのあたりでは蟬しぐれも遠い。</p></blockquote><blockquote><p>なにも誰かと騒いではしゃぎまわることだけが夏休みの意義ではないのだ。なんだって「夏＝海・プール・バーベキュー・夏祭り・花火！」が正解みたいになってんのかって話だよ。涼しい部屋で一人読書するのも、風呂上がりに一人で「うひょー！」とか叫びながら裸でアイス食うのも、夜中にふと一人で夏の大三角見るのも、蚊取線香に火をつけて一人うっとりするのも、風鈴の音を聞きながら一人うとうとするのもどれも素敵な夏の思い出だろうが。夏は一人でいい。一人がいい。暑いし。今日も世界は俺が関わらずとも正常に回っている。</p></blockquote><blockquote><p>かけがえのない存在なんて怖いじゃないか。それを失ってしまったら取り返しがつかないだなんて。失敗することも許されないだなんて。二度と手に入らないだなんて。</p></blockquote><blockquote><p>彼ら彼女らスクールカーストが高い人間は自分より下のカーストにいる人間に対して悪感情など抱いていない場合が多い。悪感情どころかそもそも興味がないのだ。人間、興味がないものには自然と冷淡な態度を取ってしまうのと同じことだ。</p></blockquote><blockquote><p>休み＝遊ぶという方程式がごく自然と成り立っているのが恐ろしい。お前はあれか、スケジュール帳の予定が埋まってないと不安になっちゃう症候群の子か。頭の中では言葉がぽんぽん出てくるが、口が回りそうもない。</p></blockquote><blockquote><p>ぐいぐいと背丈を伸ばした入道雲が、茜に染まっている。涼しい風が吹き始めた。火照った頭を覚ますにはちょうどいい。夕涼みがてら歩いて帰ることにした。藍色と茜色とか入り混じる黄昏時。その境目を見極めるにはまだしばらくの時間がかかりそうだ。</p></blockquote><blockquote><p>なにもしなくていい。これはなかなかすばらしい。自分の生きる世界が満ち足りているということである。ただバイト中に言われる「あー、もうなにもしなくていいから」はなんであんなに嫌な気分になるんだろう。つらい。辛すぎてやめちゃったぞ。</p></blockquote><blockquote><p>駅までの道には燦々と太陽が降り注いでいた。街路樹はここぞとばかりにわしゃわしゃと枝葉を伸ばし、野良猫は木陰ですやすやと寝こけている。どこかの庭先から蚊取線香の匂いと昼のテレビ番組の音が流れてきた。</p></blockquote><blockquote><p>真夏の太陽よりも眩しい。だが、この笑顔は俺以外にも向けられているんだ……。そう思うと胸が苦しくなる。喉の奥に何かひっかかっていて、それが次第に痛みに変わっていく。心の傷跡がじゅくじゅくと膿んでいた。が、戸塚の可愛い笑顔を見ていたら二秒で治った。英語でいうと、スマイルがプリティでキュアした。戸塚可愛い。略してとつかわいい。</p></blockquote><blockquote><p>人付き合いが苦手な人間には往々にしてあることだが、久しぶりに人と接したとき、なぜか無闇にテンションが上がってしまうことがある。時間の隔たりがそうさせるのだろうか、翌日振り返って自己嫌悪に陥る例のアレだ。平塚先生が明日落ち込んでないといいけど。</p></blockquote><blockquote><p>こういう光景はなんだか懐かしいな。修学旅行や林間学校の帰りのバスみたいだ。はしゃぎ疲れたクラスメイトたちは元気を使い果たして静かになっているのだが、俺は特に元気を使うシーンもなかったせいで、一人冴え切った眼でずっと外を見ていたものだ。</p></blockquote><blockquote><p>組織に身を置くということは組織の負の側面を担うということでもある。ましてや長期間に及ぶ場合には先々のことを考えた立ち回りをしなければならない。下げたくもない頭を下げ、行きたくもない飲み会に行き、聞きたくもないことを聞かねばならない。嫌いな人間と毎日顔を合わせるどころか、一緒に働かねばならない。</p></blockquote><blockquote><p>君たちは別のコミュニティとうまくやる術を身につけたほうがいい」「いや、無理ですよあのへんと仲良くするなんて」「比企谷、違うよ。仲良くする必要はない。私はうまくやれと言っているんだ。敵対するわけでも無視するわけでもなく、さらっとビジネスライクに無難にやり過ごす術を身につけたまえ。それが社会に適応するということさ」</p></blockquote><blockquote><p>仲良くなるというのは感情の問題だが、うまくやること自体は技術の問題だ。話題をふり、話を合わせ、そいつの答えに共感してみせる。そうした過程の中で相手のストライクゾーンを絞り、また自分の守備範囲をそれとなく教える。これでうまくやることはできるだろう。</p></blockquote><blockquote><p>畢竟、人とうまくやるという行為は、自分を騙し、相手を騙し、相手も騙されることを承諾し、自分も相手に騙されることを承認する、その循環連鎖でしかないのだ。</p></blockquote><blockquote><p>組織や集団に属するうえで必要な技能であり、大人と学生を分けるのはスケールの違いでしかない。なら、結局それは虚偽と猜疑と欺瞞でしかない。</p></blockquote><blockquote><p>ただの「可愛いって言ってるアタシ可愛いアピール」</p></blockquote><blockquote><p>秘密の共有。これも人とうまくやるためのテクニックの一つなんだろうなぁと妙に感心してしまった。</p></blockquote><blockquote><p>彼女たちの距離は一メートルも離れてはいまい。傍目には同じグループと映っても不自然ではない。だがそこには目には見えない皮膜が、不可視の壁が、歴とした断絶があった。</p></blockquote><blockquote><p>スタンド使いとスタンド使いが引かれ合うように、ぼっちはぼっちを発見する能力に長けているらしい。</p></blockquote><blockquote><p>人生には一度や二度、孤独と向き合うべきときってもんがある。いや、なきゃいけない。始終誰かと一緒にいていつもいつでも傍に人がいるなんて、そっちのほうがよほど異常で気持ちが悪い。孤独であるときにしか学べない、感じられないことがきっと存在するはずなのだ。友達がいて学べることがあるなら、友達がいないことで学べることだってある。この二つは表裏一体で等しく価値があるはずだ。</p></blockquote><blockquote><p>あからさまに避けたりはしない。感情を露わにして舌打ちすることも苛立たしげに地面を蹴ることもない。入ってきたことを咎めるような真似もしない。ただ、空気だけで語るのだ。声を荒らげずとも弾劾は成立する。それは非言語的、非肉体的、非行為的な暴力であり、圧力だ。</p></blockquote><blockquote><p>なんでもないなんでもないってお前はあずきちゃんのＯＰかよ。俺はこれまでなんでもないと言って本当になんでもなかった人間を見たことがない。</p></blockquote><blockquote><p>小学生たちの心境を忖度するのであれば「キャー！留美チャン高校生ニ話シカケラレテル！カコイイ！私トモ仲良クシテネ！」ではなく、「はぁ？なんであいつが？」だろう。</p></blockquote><blockquote><p>鋳型に入れたような悪人は世の中にあるはずがありませんよ。平生はみんな善人なんです。少なくともみんな普通の人間なんです。それが、いざという間際に、急に悪人に変わるんだから恐ろしいのです。だから油断ができないんです。</p></blockquote><blockquote><p>悪ではないはずの自分が悪に染まるとき、人は理由を求めるのだ。反転する自分との整合性を保つため、世界を反転させる。</p></blockquote><blockquote><p>反転した世界における悪を断罪するがために、彼らは正義の剣を振るうのだ。自分だけでは自分を肯定できないから、だから彼らは徒党を組む。お互いに、まるでそれが周知の事実であるかのように、いかに悪辣で罪深いかを語り合い、正義感を純粋培養していく。小さな、本当に小さな不満の種を大きく育てる。それが欺瞞でなくてなんだというのだ。</p></blockquote><blockquote><p>どうしたい？別にどうもしたくはない。ただそのことについて話してみたいだけだ。要するに、テレビで戦争や貧困のドキュメンタリーを見て、可哀想だね大変だね私たちにもできることをしようねなどと言いながら、心地よい部屋で美味しいご飯を食べているのと変わらないのだ。じゃあ、そのうち何か動き始めるかというとそんなことはない。「今の自分たちの幸福のありがたみを知った」だなんてお為ごかしが入って終了だ。</p></blockquote><blockquote><p>その感情は美しく崇高だが、同時にひどく醜悪な言い訳にも見える。俺が憎悪した、欺瞞に満ちた青春の延長線上にあるものにすぎない。</p></blockquote><blockquote><p>将を射んと欲すればまず馬を射よってやつ」</p></blockquote><blockquote><p>だから別に驚きもしないし動揺もしないし意外にも思わないしびっくりもしないし動揺もしないし驚きもしない。何これ凄い動揺してる。</p></blockquote><blockquote><p>差し込む月明かりが戸塚の顔をほのかに照らす。艶めいた唇が誰かの名前を囁くように、むにゃと小さく動いた。幸福そうに、ほにゃっと柔らかな笑顔を浮かべた。さっきまであったもやもやはまた形を変えて、胸にわだかまる。</p></blockquote><blockquote><p>手もとにある携帯電話を覗くと、意外なことにまだ二十三時にもなっていない。都市部から離れると、時間の流れがゆっくりと感じられるものらしい。騒々しい電車の音も煌々と照る街灯もない。静かな夜だ。夜風の一つも浴びれば気分も落ち着くだろう。</p></blockquote><blockquote><p>林立する木々の間に長い髪を下ろした女の子が立っている。それこそ精霊や妖精の類いと幻視するような、どこか現実離れした光景だった。ふんわりとした月明かりに照らされて、白い肌は浮かび上がるようにほのかに光を放つ。そよ風が踊るたびに、なびく髪が舞う。妖精じみた彼女は月光を浴びながら小さな、とても小さな声で歌っている。寒気すらする闇の森の中で、囁くような歌声は不思議と耳に心地よかった。</p></blockquote><blockquote><p>一人残された俺はふと、夜空を見上げる。雪ノ下雪乃が見上げていたのと同じ空を。星々の光は遥か過去のものなのだそうだ。それこそ幾星霜の時を超えて、昔日の光を飛ばしている。誰もが過去に囚われている。どんなに先に進んだつもりでも、ふと見上げればありし日のできごとが星の光の如く、降り注いでくる。笑い飛ばすことも消し去ることもできず、ただずっと心の片隅に持ち続け、ふとした瞬間に蘇る</p></blockquote><blockquote><p>「おお、やるか。そのうち適当に連絡くれ」人から誘われたらいつも言ってる定型句がつい出てしまった。集団の端っこにいるとき、社交辞令で聞いてくるんだよな。</p></blockquote><blockquote><p>なんか、日本昔話で見たことあるようなご飯が出てきた。いや、いいけどね。どうせもう一杯くらい食べようと思ってたし、文句はないけどね。</p></blockquote><blockquote><p>目に飛び込んでくるのは鮮やかなブルー。恥ずかしげに腰を捻るとふわりとスカートがはためいた。絹織物のようにきめ細かな肌にビビッドな色合いのビキニはよく映える。先ほどの水遊びの名残なのか、水滴が弾かれるようにして艶やかな肌を滑っていく。優美な曲線を描く首筋を伝い、鎖骨の窪みに一瞬留まると、ふくよかな胸もとへと至る。</p></blockquote><blockquote><p>ちょこんとした爪先からくるぶし、ふくらはぎ、腿と色素の薄い肌があまりに眩しい。羽織っているパーカーは白を基調とし、戸塚の体格に比べるとやや大きい。眩しい白さと大きさのせいで、裸ワイシャツみたいに見えてしまうから困る。七分袖から伸びる、きゅっと細い手首が視界に入ると、こっちの心臓まできゅっとなる。上を着ていることがさらに艶めかしく、隠されていることで逆にその魅力が際立ってしまっていた。</p></blockquote><blockquote><p>自分が変われば世界が変わるというが、そんなことはない。既にできあがってしまった自分への評価も既存の人間関係もたやすくプラスには変わらない。人が人を評価するのは加点方式でも減点方式でもない。固定観念と印象でしかものを見ない。人は現実がありのままに見えるわけではない。見たいと欲した現実しか見ていないのだ。</p></blockquote><blockquote><p>リア充はリア充としての行動を求められ、ぼっちはぼっちであることを義務づけられ、オタクはオタクらしく振る舞うことを強要される。カーストが高い者が下に理解を示すことは寛大さや教養の深さとして認められるが、その逆は許されない。それが子供の王国の、腐りきったルールだ。実にくだらない。世界は変わらないが、自分は変えられる。なんてのは、結局そのくそったれのゴミみたいな冷淡で残酷な世界に順応して適応して負けを認めて隷属する行為だ。綺麗な言葉で飾って自分すら騙している欺瞞にすぎない。</p></blockquote><blockquote><p>だいたいの心霊現象はそうした思い込みや勘違いが生んでいるといっていい。つまり、熱い味噌汁を注いだお椀が動くのもコーンポタージュ缶の中にコーンが残っている気配を感じるのも思い込みや勘違いだ。この世には不思議なことなど何もないのだよ。</p></blockquote><blockquote><p>「しょうがない、か……」そうだ、しょうがない。誰だって空気には逆らえない。そのせいで誰かが辛い思いをしていると理解していても、どうにもならないことってある。空気や雰囲気には逆らえない。本意に沿わない行動をとらざるを得ないときだってある。〝みんな〟が言うから〝みんな〟がそうするから、そうしないと〝みんな〟の中に入れてもらえないから。でも〝みんな〟なんて奴はいない。喋りもしなければ殴りもしない。怒りも笑いもしない。集団の魔力が作り出した幻想だ。気づかないうちに生み出していた魔物だ。個人のちっぽけな悪意を隠すために創造された亡霊だ。仲間外れを食い殺して仲間にすら呪いを振りまく妖怪変化だ。かつて彼も、彼女もその被害者だった。</p></blockquote><blockquote><p>〝みんな〟であることを強要する世界を。誰かの犠牲の上で成り立つ下劣な平穏を。優しさや正義さえ塗りつぶし、悪辣なものに仕立て上げ、時を経てなお棘を残す、欺瞞でしかない空虚な概念を。過去と世界は変えることができない。起きてしまったことと〝みんな〟は変えることができない。けど、だからといって自分がそれに隷属しなくてはならないなんてことはない。過去は捨てられるし、世界はぶち壊して台無しにはできるのだ。</p></blockquote><blockquote><p>「誰かを貶めないと仲良くしてられないようなのが本物なわけねぇだろ」</p></blockquote><blockquote><p>「──鋳型に入れたような悪人は世の中にあるはずがありませんよ。平生はみんな善人なんです。少なくともみんな普通の人間なんです。それが、いざと言う間際に、急に悪人に変わるんだから恐ろしいのです。だから油断ができないんです」</p></blockquote><blockquote><p>「鋳型に入れたような善人もいないし、いざという間際に、急に善人に変わるようなことだってあるんだろうな。たぶん」——夏目漱石『こころ』</p></blockquote><h2 id="5">2.5&emsp;5</h2><p>目次：<br>①突然、比企谷家の平穏は崩れ去る。<br>②案の定、川崎沙希は憶えられていない。<br>③意外と戸塚彩加のセレクトは渋い。<br>④遺憾にも、平塚静の赤い糸の行方は誰も知らない。<br>⑤ふと比企谷小町は兄離れする日を思う。<br>⑥そして由比ヶ浜結衣は雑踏の中に消えていく。<br>⑦では、比企谷八幡は。<br>⑧すこしだけ、雪ノ下雪乃は立ち止まる。あとがき</p><blockquote><p>諸君、私は猫が好きだ。諸君、私は猫が大好きだ。アメリカンショートヘアが好きだ。三毛が好きだ。スフィンクスが好きだ。ラグドールが好きだ。アメリカンカールが好きだ。スコティッシュホールドが好きだ。ペルシャが好きだ。シンガプーラが好きだ。ロシアンブルーが好きだ。</p></blockquote><blockquote><p>「ねぇ、このあと暇？」「いやこのあとちょっとアレだから」断るときの常套句が無意識的に発動していた。誘われたらとりあえず断るという安定行動はほとんど本能に近い。『知らない電話番号には出ない』と同じくらい、現代社会においては常識的な行動だ。</p></blockquote><blockquote><p>正直すぎる意見だ。斧を数種類プレゼントしたい。高嶺の花どころかギアナ高地に咲いてる花だからな、あれは。</p></blockquote><blockquote><p>世界がもし一〇〇人の戸塚だったら戦争なんてきっと起きない。武器商人とか失業しちゃうね、これは。ストレス性物質が消えている。なんかラベンダー的な効果が発揮されていた。おかげで、いつもならイラッとする映画泥棒のにゅるにゅるしたダンスも今日ばかりは頭にこなかった。</p></blockquote><blockquote><p>俺たちはいつだって見たいと思ったものしか見ない。解釈の仕方は人の数だけあるものだ。映画の感想でも、人の印象でも。だから、理解しているとかわかってやれるなんていうのはおこがましい。理解した気になるのは罪であり悪だ。それなのに、俺たちはわかったふりをして生きないといけない。</p></blockquote><blockquote><p>理解していると、理解してもらっていると、不明瞭なお互いの認識をもって自らという存在、あるいは相手という存在をつどつど定義し直し、喧伝して生きていかないといけない。そうしないと自分という存在は雲散霧消してしまう、それくらいに曖昧で不確かなものなのだ。考えれば考えるほどわからなくなっていく様はさながらゲシュタルト崩壊のようですらある。崩れるたびに、またいくつかの情報を拾い直して自分や相手の像を構築し直す。それはシミュラクラ現象のような、どうとでも取れてしまう稚拙でプリミティブな像でしかないのだけれど。ホラーっていうなら、そのことこそがホラー。</p></blockquote><blockquote><p>実際、俺は行列というものはさほど苦手ではない。だいたいの人間が行列を嫌がる理由は時間が無駄になっていると感じたり、あるいは手持ち無沙汰な感覚が嫌だったり、誰かと一緒だと間が持たなかったりするのが原因なんだろうと思う。ディスティニーランドにデートで行ったカップルは別れるなんて都市伝説も繙いてみればこういう行列でのイライラや価値観の違いが浮き彫りになるのが原因なんじゃないだろうか。</p></blockquote><blockquote><p>「君も優しくて正しい。雪ノ下とは相容れない優しさであり正しさだが」</p></blockquote><blockquote><p>なぜに人はノスタルジーに惹かれるのだろうか。「昔は良かった」とか「古き良き時代」とか「昭和のかほり」とか、とかく過ぎた日ほど肯定的に捉える。過去を、昔を懐かしみ愛おしく想う。あるいは変わってしまったこと、変えられてしまったことを嘆き悔やむ。なら、本来的に変化というのは、悲しむべきことなんじゃないだろうか。成長も進化も変遷も、本当に喜ばしくて正しくて素晴らしいものなのだろうか。</p></blockquote><blockquote><p>自分が変わらずにいても、世界は、周囲は変わっていく。それに取り残されたくないから必死であとをついていっているだけなんじゃないだろうか。変わらなければ悲しみは生まれない。たとえ何も生まれなかったとしてもマイナス要素がでないというのは大きなメリットだと思うのだ。収支表を照らし合わせて赤字になってないならそれは経営方針としてけして間違いではない。だから俺は変わらないでいることを否定しない。過去の俺も、今の俺も否定する気はさらさらない。変わるなんてのは結局、現状から逃げるためなんだ。逃げることを選ばないなら変わらないでそこで踏ん張るべきだ。変わらないからこそ得られるものだってある。進化をＢボタンでキャンセルすると技覚えんの早くなるのと一緒だ。</p></blockquote><blockquote><p>薄桃色の浴衣はところどころに小さく花が咲き、朱色の帯が鮮やかに映える。ピンクがかった茶髪はいつものお団子ではなく、くいっとアップに纏め上げられている。下駄を履き慣れていないのか、その足取りはやけに危なっかしく、思わず二、三歩こちらから駆け寄ってしまった</p></blockquote><blockquote><p>勘違いも思い違いも思いこみももうしない。単なる偶然やただの現象に意味を見いだそうとしてしまうのは、「もてない男子」の悪い癖だ。</p></blockquote><blockquote><p>むしろ敏感なほうだ。敏感で、過敏で、過剰に反応してしまう。世の男子の八割は常に「こいつ俺のこと好きなんじゃね？」という想いを抱きながら生きているのだから。だからこそ、自らを戒める必要がある。いつだって、冷静で冷徹な自分が「そんなわけないだろ」と冷ややかな視線を向けてくるのだ。俺は他人をさして信じないが、それ以上に自分という存在を信じていない。</p></blockquote><blockquote><p>「覚えとけ、これ見よがしに目の前に良いものが置かれてたらまず罠だ。自分に都合のいいことには裏がある。これ常識」</p></blockquote><blockquote><p>口元の微笑は崩さず、視線だけが刹那俺を値踏みする。それだけで、さっきまでの温かさが噓のように、心が凍てついていくのがわかった。心が冷めれば、頭が覚める。脊髄に液体窒素でも流し込んだみたいに、きりりと思考が冴えていく。理性と論理と経験則が束になって感情と対峙した。判定を待つまでもなく、たやすくねじ伏せられる。また心得違いをするところだった。</p></blockquote><blockquote><p>個人を知る前にまずその人物の所属する組織で、場所で、位階で、肩書きである程度のあたりをつける。学校や会社、そうしたもので人間性を判断されることは多々ある。最近ではあまり聞かなくなったが、就職活動時にまことしやかに囁かれる学歴フィルターなどその最たるものだろう。</p></blockquote><blockquote><p>住む世界が違う、とは思わない。住む世界が違ったならどれだけ気分が楽だったか。なまじ同じ世界で生きているから面倒なのだ。</p></blockquote><blockquote><p>たぶん、いわゆるモテる男というのはこういうときに用意周到準備していてちゃんと気配りができる奴なんだろう。顔の良さ云々より、そういう細やかな采配が大事なのだ。たとえばまめにメール送るとか、遊びに行くときは事前に調べておくとか、長蛇の列に並んでいるとき小粋な会話で気を紛らわせるとか。</p></blockquote><blockquote><p>話しかけたりしないし、並んで歩かずに一歩後ろ歩くし、誰かの予定を邪魔しないように誰も誘わないし。気遣いの達人すぎて操気弾くらいなら今すぐ撃てるレベル。</p></blockquote><blockquote><p>夜闇になお際立つ濃紺の地は風雅さを漂わせ、大百合と秋草模様が涼しげな浴衣姿。</p></blockquote><blockquote><p>完璧と言って差し支えのないタイミングで出た言葉と仕草。だからこそ、予想済みだった攻撃に対する迎撃のような印象を受けた。</p></blockquote><blockquote><p>優れた存在は排除される。出る杭は打たれるのではない。抜いて捨てられるのだ。捨て置かれ雨風に晒されいずれ朽ち果てる。</p></blockquote><blockquote><p>こうやって部分肯定というか一部分を引き合いに出して好きとかいう奴の言葉は信用してはいけないのだ。「そのセンス、わたし結構好き～」と「──好き。そのセンスも……」はまったく別物だからな。ソースは中学時代の俺。今さらその程度の叙述トリックに引っかかる俺ではない</p></blockquote><blockquote><p>「好き嫌い言うなって母ちゃんにしつけられてるんで」</p></blockquote><blockquote><p>分かり合うことなんてできないし、分かったふりをされれば腹も立つ。無関心でいることがありがたい場合なんていくらだってある。雨の日に大荷物抱えてスっ転んだときとかクラス全員の前で先生からお説教されたときなんて、頼むからこのあと話しかけないでくれって願うもんだろ。優しく親しく声をかけることが救いにならないどころか、ダメージを与えうることにそろそろみんな気づくべきだ。同情や慈悲がとどめの一撃になることだって、ある。</p></blockquote><blockquote><p>「知らないことが悪いことだとは思わないけどな。知ってることが増えると面倒ごとも一気に増えるし」知ることはリスクを背負う行為に外ならない。知らなければ幸せなことはたくさんある。人の本当の気持ちなどその最たるものだろう。誰しもが多かれ少なかれ自分を人を騙し欺いて生きている。だから真実は常に人を傷つける。誰かの平穏を壊す存在でしかない。</p></blockquote><blockquote><p>俺でなくても、他の誰かでも為し得たことに対する評価は俺自身を肯定するものではない。行動が評価されることと人格が評価されることはまったくもって別のものだ。ただ一度の善行をもってその人間を善人と断ずることはできないように、俺の人格をその行動一つで決めつけられても困る。</p></blockquote><blockquote><p>「俺にそういうの期待すんな」きっと失望させてしまうから。だから、最初から俺に期待などしないでほしい</p></blockquote><blockquote><p>起きなかった仮定に意味はない。人生にもしもはない。たらればだけが人生だ。</p></blockquote><blockquote><p>もしかしたらありえたかもしれないその夢物語は、妙な現実味を帯びているせいで容易に否定や反論ができなかった。</p></blockquote><blockquote><p>逸らした視線は、いずれ前へ戻さなければならない。</p></blockquote><blockquote><p>炎の中に金属や塩類を投じれば、各元素特有の色を示す。青白い炎も触れる元素によって見え方を変じる。存外、人間も似たようなものなのだ。人と人が関われば、なにがしかの反応が生まれる。その色はさまざまだ。一人の人物でも触れる人が変わればその反応も変わる。色とりどりの花火のように、まったく違う色を導き出す。</p></blockquote><blockquote><p>今まで自分のことを嫌いだと思ったことなんてない。高い基本スペックも中途半端にいい顔もペシミスティックで現実的な思考も、まったくもって嫌いじゃない。だが、初めて自分を嫌いになりそうだ。勝手に期待して勝手に理想を押しつけて勝手に理解した気になって、そして勝手に失望する。何度も何度も戒めたのに、それでも結局直っていない。──雪ノ下雪乃ですら噓をつく。そんなことは当たり前なのに、そのことを許容できない自分が、俺は嫌いだ。</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-04-19-yaharian-noqing-chun-rabukomehamatigatuteiru-ba-cui/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Fortran学习</title>
      <link>https://chengpengzhao.com/2020-04-15-fortran-xue-xi/</link>
      <guid>https://chengpengzhao.com/2020-04-15-fortran-xue-xi/</guid>
      <pubDate>Wed, 15 Apr 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;没想到2020年了我还在学习Fortran，因为老师说组里的人都用的Fort
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>没想到2020年了我还在学习Fortran，因为老师说组里的人都用的Fortran，虽然我还是更偏向C++但暂且还是得会用Fortran吧，简单学习一下~</p><hr><h1 id="Fortran基础知识">1&emsp;Fortran基础知识</h1><ul><li><p><code>&amp;</code>符号标记<strong>下一行</strong>继续书写</p></li><li><p>Fortran程序单元：</p></li></ul><ol><li>声明，位于程序开头(变量声明放一起)</li><li>执行</li><li>终止, end program</li></ol><p>必须按这顺序来，比如声明不能插到执行语句里面，这点让我有点没法接受。</p><ul><li><p>变量类型声明</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">integer</span><span class="token operator">::</span> var1<span class="token punctuation">,</span> var2<span class="token keyword">real</span><span class="token operator">::</span> var1<span class="token keyword">character</span><span class="token punctuation">(</span>len<span class="token operator">=</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token operator">::</span> var1    <span class="token comment" spellcheck="true">!没数字时默认长度为1,若字符赋值长度小于len，则多余的用空格补</span><span class="token keyword">logical</span> <span class="token operator">::</span> var1<span class="token keyword">type</span><span class="token punctuation">,</span> <span class="token keyword">parameter</span> <span class="token operator">::</span> PI <span class="token operator">=</span> <span class="token number">3.14</span>    <span class="token comment" spellcheck="true">!常数定义，type为前面四种</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>整数和实数的转换</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">integer</span><span class="token operator">::</span> xx2<span class="token operator">=</span><span class="token keyword">real</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span>x3<span class="token operator">=</span>nint<span class="token punctuation">(</span>x2<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">!四舍五入</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>尽可能使用整形指数、因为实数的幂精度更低</p></li><li><p>fortran中乘方操作符是<code>**</code>：<code>a**b</code></p></li><li><p>永远不要对负数进行实数幂运算(没有定义负数的自然对数)</p></li><li><p>输入输出</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span> a<span class="token keyword">read</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token operator">*</span><span class="token punctuation">)</span> a <span class="token comment" spellcheck="true">!输入时用逗号或空格分隔</span><span class="token comment" spellcheck="true">! 第一数据域： 从哪个输入输出单元读入，*表示计算机标准输入</span><span class="token comment" spellcheck="true">! 第二数据域： 读入数据的格式，*表示表控输入（自由格式输入）</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p><code>implicit none</code>: 必须显示声明变量</p></li></ul><h1 id="分支结构">2&emsp;分支结构</h1><ul><li><p>逻辑数据类型： <code>.true. 和 .false.</code> (注意有两个句点)</p></li><li><p><code>/=</code>，<strong>不等于</strong> 的写法比较特殊</p></li><li><p>if分支</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">if</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token keyword">then</span>  ...<span class="token keyword">end if</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">select</span> <span class="token keyword">case</span> <span class="token punctuation">(</span>expr<span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">!根据expr的值判断属于哪个case</span>  <span class="token keyword">case</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>      ...  <span class="token keyword">case</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">)</span>      ...  <span class="token keyword">case</span> <span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">:</span><span class="token punctuation">)</span>      ...  <span class="token keyword">case</span> <span class="token keyword">default</span>      ...<span class="token keyword">end select</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>写分支条件时时刻考虑四舍五入误差！尽量用不等式而不是<code>==</code></p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">if</span> <span class="token punctuation">(</span>abs<span class="token punctuation">(</span>x<span class="token number">-10.</span><span class="token punctuation">)</span><span class="token operator">&lt;=</span><span class="token number">1.e-5</span><span class="token punctuation">)</span>  <span class="token keyword">then</span>  ...<span class="token keyword">end if</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="循环和字符操作">3&emsp;循环和字符操作</h1><ul><li><p>DO循环</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">do</span>  ...<span class="token keyword">end do</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>DO WHILE循环(一般不用或尽量少用)</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">do</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span>  ...<span class="token keyword">end do</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>DO计数循环</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">do</span> i <span class="token operator">=</span> start<span class="token punctuation">,</span> <span class="token keyword">end</span><span class="token punctuation">,</span> incr ...<span class="token keyword">end do</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>CYCLE和EXIT语句</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">do</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">5</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>i<span class="token operator">==</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token keyword">cycle</span> <span class="token comment" spellcheck="true">!相当于continue，退出当前循环</span>  <span class="token keyword">if</span> <span class="token punctuation">(</span>i<span class="token operator">==</span><span class="token number">4</span><span class="token punctuation">)</span> <span class="token keyword">exit</span>  <span class="token comment" spellcheck="true">!直接退出外层循环</span>  <span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token operator">*</span><span class="token punctuation">)</span> i<span class="token keyword">end do</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>字符串小tips</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">character</span><span class="token punctuation">(</span>len<span class="token operator">=</span><span class="token number">12</span><span class="token punctuation">)</span> <span class="token operator">::</span> a<span class="token operator">=</span><span class="token string">'hello'</span><span class="token operator">//</span><span class="token string">'world'</span><span class="token operator">//</span><span class="token string">"as"</span>   <span class="token comment" spellcheck="true">!连接操作符</span><span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token operator">*</span><span class="token punctuation">)</span> a<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">!子串抽取方式</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ul><h1 id="基本I-O操作">4&emsp;基本I/O操作</h1><ul><li>格式化write<pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">)</span> i<span class="token punctuation">,</span><span class="token keyword">result</span><span class="token number">100</span> <span class="token keyword">format</span> <span class="token punctuation">(</span><span class="token string">'The result for iteration '</span><span class="token punctuation">,</span> I3<span class="token punctuation">,</span> <span class="token string">' is '</span><span class="token punctuation">,</span> F7<span class="token number">.3</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">!100为语句标号， I3表示3个字符宽，F7.3表示7个字符宽、三位小数</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li>格式描述符汇总：(以输出为例，输入差不多)</li></ul><ol><li><p>整数输出——I</p><pre class="line-numbers language-Fortran"><code class="language-Fortran">rIw.m!其中 r代表重复计数（使用次数、即有多少变量套用该格式）! w代表域宽、即字符总数! m代表显示的最小位数<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>实数输出——F</p><pre class="line-numbers language-fortran"><code class="language-fortran">rFw.d<span class="token comment" spellcheck="true">! d代表小数位数</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>指数计数法输出——E</p><pre class="line-numbers language-fortran"><code class="language-fortran">rEw.d<span class="token comment" spellcheck="true">! 一般w>=d+7</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>科学计数法——ES</p><pre class="line-numbers language-fortran"><code class="language-fortran">rESw.d<span class="token comment" spellcheck="true">! 同上，为了不让星号填充需要w>=d+7</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>逻辑输出——L</p><pre class="line-numbers language-fortran"><code class="language-fortran">rLw<span class="token comment" spellcheck="true">!一般为右对齐</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>字符输出——A</p><pre class="line-numbers language-fortran"><code class="language-fortran">rA<span class="token punctuation">(</span>w<span class="token punctuation">)</span><span class="token comment" spellcheck="true">!也是右对齐</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>水平定位——X和T</p><pre class="line-numbers language-fortran"><code class="language-fortran">nX  Tc<span class="token comment" spellcheck="true">!n为要插入的空格数， c为列号</span><span class="token comment" spellcheck="true">! Tc跳转到特定一列</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>格式可通过<code>()</code>进行嵌套</p></li><li><p>改变输出行—— <code>/</code>,可单独放在一个逗号里或和接在其他格式符之后</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">)</span> a<span class="token punctuation">,</span>b<span class="token number">100</span> <span class="token keyword">format</span>（<span class="token number">1</span>X<span class="token punctuation">,</span>F7<span class="token number">.0</span><span class="token operator">/</span><span class="token punctuation">,</span><span class="token operator">/</span><span class="token punctuation">,</span>F7<span class="token number">.1</span>）<span class="token comment" spellcheck="true">! 推荐在format开头写1X空一格</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>双精度输出——D编辑符</p><pre class="line-numbers language-fortran"><code class="language-fortran">Dw.d<span class="token comment" spellcheck="true">!使用方法与E编辑符相仿，只是把字母“E”换成“D”。F编辑符也可用于双精度数据的输出，和用于实型数据输出相似。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ol><ul><li>文件处理<pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">open</span><span class="token punctuation">(</span>unit <span class="token operator">=</span> fp<span class="token punctuation">,</span> <span class="token keyword">file</span> <span class="token operator">=</span> <span class="token string">'filename'</span><span class="token punctuation">,</span> status <span class="token operator">=</span> <span class="token string">'unknown'</span><span class="token punctuation">,</span> iostat <span class="token operator">=</span> ierr<span class="token punctuation">)</span><span class="token comment" spellcheck="true">! fp为一个数字，I/O单元号； status为old时打开旧文件、new打开新文件、replace替换文件、scratch打开临时文件</span><span class="token keyword">write</span><span class="token punctuation">(</span>fp<span class="token punctuation">,</span><span class="token number">100</span><span class="token punctuation">)</span> x<span class="token number">100</span> <span class="token keyword">format</span> <span class="token punctuation">(</span>...<span class="token punctuation">)</span><span class="token keyword">close</span><span class="token punctuation">(</span>unit<span class="token operator">=</span>fp<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="数组">5&emsp;数组</h1><ul><li><p>声明数组</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">type</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">::</span> arr<span class="token punctuation">(/</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">/)</span>   <span class="token comment" spellcheck="true">!数组建构器</span><span class="token comment" spellcheck="true">!下标默认从1到n</span><span class="token keyword">integer</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token operator">::</span>arr2<span class="token operator">=</span><span class="token punctuation">(/</span>  <span class="token punctuation">(</span>i<span class="token punctuation">,</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">/)</span><span class="token comment" spellcheck="true">! 隐式DO循环</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>指定下标范围</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token operator">::</span>arr3<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li><li><p>数组操作</p></li></ul><ol><li>维度相同的两个数组可以直接相加减（相当于每个元素加减）</li><li>指定部分数组：<pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token operator">::</span> arr<span class="token operator">=</span><span class="token punctuation">(/</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">/)</span>arr<span class="token punctuation">(</span><span class="token punctuation">:</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">!整个数组</span>arr<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token number">3</span><span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">!第三个数为增量，若省略则默认1</span>arr<span class="token punctuation">(</span><span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">!从起始到下标为5的数</span>arr<span class="token punctuation">(</span><span class="token operator">::</span><span class="token number">1</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">!1代表增量，前面一个:代表整个数组</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ol><ul><li>时刻记得隐式Do循环<pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token operator">*</span><span class="token punctuation">)</span>  <span class="token punctuation">(</span>arr<span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span> i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">! arg1,arg2,..., index=istart,iend,incr</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li></ul><h1 id="过程">6&emsp;过程</h1><h2 id="子程序（subroutine）">6.1&emsp;子程序（subroutine）</h2><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">subroutine</span> name<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">)</span>    <span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token operator">::</span> a<span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">!无法检测越界，不应该用这种形式</span>    <span class="token comment" spellcheck="true">!tip: 永远别用不定大小的形参数组</span>    <span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token operator">::</span> b    <span class="token keyword">character</span><span class="token punctuation">(</span>len<span class="token operator">=</span><span class="token operator">*</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span> <span class="token operator">::</span> string  <span class="token comment" spellcheck="true">!*声明字符变量长度</span>    <span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">out</span><span class="token punctuation">)</span><span class="token operator">::</span> c    <span class="token comment" spellcheck="true">! intent属性声明输入输出</span><span class="token keyword">end subroutine</span> name<span class="token keyword">call</span> name<span class="token punctuation">(</span>arg<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ul><li><p>指针，pass-by-reference: 子程序和主程序是用<strong>地址传递</strong>方案通信的！<br>(注意主程序和子程序相对应的参数类型一致)</p></li><li><p>tip: 永远不要在子程序中使用stop语句</p></li><li><p>子程序能够作为参数传递</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">subroutine</span> sub_as_arg<span class="token punctuation">(</span>sub<span class="token punctuation">,</span>x<span class="token punctuation">)</span><span class="token keyword">external</span><span class="token operator">::</span> sub<span class="token comment" spellcheck="true">!作为参数传递时需要声明external</span><span class="token keyword">real</span><span class="token punctuation">,</span> intenet<span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token operator">::</span>x<span class="token keyword">end subroutine</span> sub_as_arg<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h2 id="模块">6.2&emsp;模块</h2><ul><li><p>一种提供程序单元<strong>共享数据</strong>的方式(独立编译)</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">module</span> modulename  <span class="token keyword">implicit none</span>  <span class="token keyword">save</span> <span class="token comment" spellcheck="true">!保证在模块中声明的数据被保护在不同过程间的引用中，一定记得加</span>  <span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token operator">::</span>arr  <span class="token keyword">contains</span>    <span class="token comment" spellcheck="true">! 模块也可以含子程序和函数</span>      <span class="token keyword">subroutine</span> sub1<span class="token punctuation">(</span><span class="token punctuation">)</span>      ...      <span class="token keyword">end subroutine</span> sub1<span class="token keyword">end module</span> modulename<span class="token keyword">use</span> modulename<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>为什么要在模块里套个子程序？直接写个子程序文件也行啊<br>答： 模块中编译过程和使用模块时，过程接口的所有细节对编译器都是有效的，即<strong>编译器可以捕捉程序员调用时可能犯的错误</strong>（如参数类型、个数错误）， explicit interface。而不在模块里的过程为implicit interface</p></li><li><p>推荐把过程放在模块里</p></li></ul><h2 id="函数-function-subprogram">6.3&emsp;函数(function subprogram)</h2><ul><li><p>声明函数</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">integer</span> <span class="token keyword">function</span> name<span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token comment" spellcheck="true">! or</span><span class="token keyword">function</span> name<span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token keyword">integer</span> <span class="token operator">::</span> name<span class="token comment" spellcheck="true">!注意函数声明和调用时都要声明其类型</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>函数有多个输入和<strong>一个输出</strong>，当需要多个输出时请用<strong>子程序</strong>!!</p></li><li><p>函数记得用<code>intent(in)</code>声明所有输入参数，防止函数意外修改（函数和子程序都是通过指针传参的）</p></li><li><p>函数可以当做参数传递，前提是被声明为外部量（external）</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">external</span> <span class="token operator">::</span> func1<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre></li></ul><h1 id="数组的高级特性">7&emsp;数组的高级特性</h1><ul><li><p>多维数组<code>real,dimension(3,6)::sum</code><br>多维数组内存分配： 一列一列来的</p></li><li><p>以列储存数组数据、按行序读取数据<br>(第一个下标变化最快、最后一个下标变化最慢)</p></li><li><p>数组构造器产生一维数组，需要借助<code>reshape</code>初始化多维数组</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span><span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token operator">::</span>arrarr<span class="token operator">=</span>reshape<span class="token punctuation">(</span><span class="token punctuation">(/</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">/)</span><span class="token punctuation">,</span><span class="token punctuation">(/</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">/)</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">!数列为：</span><span class="token comment" spellcheck="true">! 1 2 3</span><span class="token comment" spellcheck="true">! 1 2 3</span><span class="token comment" spellcheck="true">! 1 2 3</span><span class="token comment" spellcheck="true">! 1 2 3</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>用read语句能够方便地初始化多维数组</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token comment" spellcheck="true">!文件数据为： 1 1 1 1 2 2 2 2 3 3 3 3</span><span class="token keyword">real</span><span class="token punctuation">,</span><span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token operator">::</span>arr<span class="token keyword">open</span><span class="token punctuation">(</span>unit <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">,</span> <span class="token keyword">file</span> <span class="token operator">=</span> <span class="token string">'data.dat'</span><span class="token punctuation">,</span> status <span class="token operator">=</span> <span class="token string">'old'</span><span class="token punctuation">,</span> iostat <span class="token operator">=</span> ierr<span class="token punctuation">)</span><span class="token keyword">read</span><span class="token punctuation">(</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token operator">*</span><span class="token punctuation">)</span> arr<span class="token comment" spellcheck="true">!当然也可以使用类似 ((arr(i,j),j=1,3),i=1,4) 的隐式do循环，不过麻烦一点；但可以避免矩阵转置的问题</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>masked array assignment， 对多个数组元素进行操作<br>(对满足特定条件的元素执行指定操作)</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">where</span><span class="token punctuation">(</span>value<span class="token operator">></span><span class="token number">0.</span><span class="token punctuation">)</span>  logval<span class="token operator">=</span>log<span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token keyword">elsewhere</span>   logval<span class="token operator">=</span><span class="token number">-99999.</span><span class="token keyword">endwhere</span><span class="token comment" spellcheck="true">!value 可以是数组，where逐个对元素进行运算</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>forall, 逐个操作数组元素</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">forall</span><span class="token punctuation">(</span>i<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">:</span>n<span class="token punctuation">,</span>j<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">:</span>m<span class="token punctuation">,</span>work<span class="token punctuation">(</span>i<span class="token punctuation">,</span>j<span class="token punctuation">)</span><span class="token operator">/=</span><span class="token number">0.</span><span class="token punctuation">)</span>  work<span class="token punctuation">(</span>i<span class="token punctuation">,</span>j<span class="token punctuation">)</span><span class="token operator">=</span><span class="token number">1.</span><span class="token operator">/</span>work<span class="token punctuation">(</span>i<span class="token punctuation">,</span>j<span class="token punctuation">)</span><span class="token keyword">end forall</span><span class="token comment" spellcheck="true">! 相比于嵌套的do循环，forall的优点在于语句可以按照任意顺来执行</span><span class="token comment" spellcheck="true">! 若有多条语句，则上一条完全执行完了（对所有元素）再进行下一条的执行</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>可分配数组</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span> <span class="token keyword">allocatable</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token punctuation">:</span><span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">)</span> <span class="token operator">::</span> arr1<span class="token keyword">allocate</span><span class="token punctuation">(</span>arr1<span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token keyword">stat</span><span class="token operator">=</span>status<span class="token punctuation">)</span><span class="token comment" spellcheck="true">! 分配成功，stat返回0</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li><li><p>传递多维数组</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token comment" spellcheck="true">!plan 1</span><span class="token keyword">subroutine</span> process <span class="token punctuation">(</span><span class="token keyword">data</span><span class="token punctuation">,</span>n<span class="token punctuation">,</span>m<span class="token punctuation">)</span><span class="token keyword">integer</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token operator">::</span>n<span class="token punctuation">,</span>m    <span class="token comment" spellcheck="true">!通过每一维度取值范围传递多维数组</span><span class="token keyword">end subroutine</span> process<span class="token comment" spellcheck="true">!plan 2</span><span class="token keyword">subroutine</span> process1 <span class="token punctuation">(</span><span class="token keyword">data</span><span class="token punctuation">)</span><span class="token keyword">real</span> <span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">dimension</span><span class="token punctuation">(</span><span class="token punctuation">:</span><span class="token punctuation">,</span><span class="token punctuation">:</span><span class="token punctuation">)</span> <span class="token operator">::</span> <span class="token keyword">data</span>   <span class="token comment" spellcheck="true">!不定结构的形参数组（只有子程序有显式接口时才能使用）</span><span class="token comment" spellcheck="true">! 使用时常在子程序外套一个模块</span><span class="token keyword">end subroutine</span> process1<span class="token comment" spellcheck="true">!plan 3</span><span class="token comment" spellcheck="true">!不定大小的数组（用*代替最后一个维度），不应该再使用</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>save属性和语句</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">,</span><span class="token keyword">save</span><span class="token operator">::</span>sums<span class="token comment" spellcheck="true">!保证在调用过程之间不修改保存的局部变量和数组。（需要多次调用时）</span><span class="token comment" spellcheck="true">! save不能出现在与形参的关联中</span><span class="token comment" spellcheck="true">! 类型声明中初始化的局部变量都会自动保存，隐含save属性</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>fortran程序在退出过程后，默认所有局部变量和数组的值成为未定义，用save可以保存这些变量</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">save</span><span class="token operator">::</span> var1<span class="token punctuation">,</span>var2<span class="token keyword">save</span>    <span class="token comment" spellcheck="true">!不指定变量时，该过程或模块中所有的局部变量都会被无改变的保存起来</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre></li><li><p>自动数组： 子程序中的非形参数组，过程完成后自动释放空间</p></li></ul><ul><li><p><code>pure</code>前缀的function或subroutine的限制：<br>不修改输入参数、局部变量无save属性（不初始化）…</p></li><li><p><code>elemental</code>前缀，定义一个过程为‘逐元’的，即该过程用标量输入和输出定义。</p></li><li><p>内部过程<br>内部过程（internal procedures）包含在宿主程序单元（host program unit）中，只能在宿主中调用，且能够访问宿主中的变量。用于完成一些重复低级操作</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">program</span> name  ...  <span class="token keyword">contains</span>  <span class="token keyword">real</span> <span class="token keyword">function</span> name2<span class="token punctuation">(</span>...<span class="token punctuation">)</span>      ...  <span class="token keyword">end function</span> name2<span class="token keyword">end program</span> name<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="附加的内置数据类型">8&emsp;附加的内置数据类型</h1><ul><li><p><code>real</code>，默认4字节（32位），最多7个有效数字？</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">real</span><span class="token punctuation">(</span><span class="token keyword">kind</span><span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">::</span> val_1<span class="token keyword">real</span><span class="token punctuation">(</span><span class="token keyword">kind</span><span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token operator">::</span> val_2<span class="token keyword">real</span><span class="token punctuation">(</span><span class="token keyword">kind</span><span class="token operator">=</span><span class="token number">4</span><span class="token punctuation">)</span><span class="token operator">::</span> val_3<span class="token keyword">real</span><span class="token punctuation">(</span><span class="token keyword">kind</span><span class="token operator">=</span><span class="token number">8</span><span class="token punctuation">)</span><span class="token operator">::</span> val_4<span class="token comment" spellcheck="true">!对不同计算机、一个32位的实数可能是kind=1，也可能是kind=4...</span><span class="token keyword">write</span><span class="token punctuation">(</span><span class="token operator">*</span><span class="token punctuation">,</span><span class="token string">'("The kind for single precision is ",I2)'</span><span class="token punctuation">)</span> <span class="token keyword">kind</span><span class="token punctuation">(</span><span class="token number">0.0</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">!可用上述命令判断计算机对类别号的定义</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>为了使程序移植性好，一般用selected_real_kind函数</p><pre class="line-numbers language-fortran"><code class="language-fortran">kind_number<span class="token operator">=</span>selected_real_kind<span class="token punctuation">(</span>p<span class="token operator">=</span>precision<span class="token punctuation">,</span>r<span class="token operator">=</span>range<span class="token punctuation">)</span><span class="token keyword">real</span><span class="token punctuation">(</span><span class="token keyword">kind</span><span class="token operator">=</span>kind_number<span class="token punctuation">)</span><span class="token operator">::</span>var<span class="token comment" spellcheck="true">!   p为精度位数，r为所需指数范围(10^r)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="派生数据类型">9&emsp;派生数据类型</h1><ul><li><p>任何数值、元素组合在一起，定义用户自己的类型</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">type</span> <span class="token operator">::</span> type_name  <span class="token keyword">sequence</span>    <span class="token comment" spellcheck="true">!当需要派生数据占据连续内存空间时使用，否则随机分配内存空间</span>  <span class="token keyword">character</span><span class="token punctuation">(</span>len<span class="token operator">=</span><span class="token number">14</span><span class="token punctuation">)</span><span class="token operator">::</span> first  <span class="token keyword">integer</span><span class="token operator">::</span>age  <span class="token keyword">character</span><span class="token punctuation">:</span>sex<span class="token keyword">end type</span> type_name<span class="token keyword">type</span><span class="token punctuation">(</span>type_name<span class="token punctuation">)</span><span class="token operator">::</span> variables <span class="token comment" spellcheck="true">!声明此类型的变量</span>var<span class="token operator">=</span>type_name<span class="token punctuation">(</span><span class="token string">'first_var'</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">,</span><span class="token string">'M'</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">!直接初始化方式</span>var<span class="token operator">%</span>age<span class="token operator">=</span><span class="token number">15</span>  <span class="token comment" spellcheck="true">!通过%访问成员</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>通常将一个程序中所有派生数据定义在一个模块中</p></li><li><p>派生数据类型的函数(常放入模块的contains里)</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">type</span><span class="token operator">::</span>vector  ...<span class="token keyword">end type</span> vector<span class="token keyword">type</span><span class="token punctuation">(</span>vector<span class="token punctuation">)</span> <span class="token keyword">function</span> vector_add<span class="token punctuation">(</span>v1<span class="token punctuation">,</span>v2<span class="token punctuation">)</span>  ...<span class="token keyword">end function</span> vector_add<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>associate结构，临时关联某个变量或表达式，增强可读性(fortran2003特性)</p><pre class="line-numbers language-fortran"><code class="language-fortran">associate<span class="token punctuation">(</span>x<span class="token operator">=></span>.... <span class="token punctuation">&amp;</span>y<span class="token operator">=></span>.... <span class="token punctuation">)</span>  statements<span class="token keyword">end</span> associate<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li></ul><h1 id="过程和模块的高级特性">10&emsp;过程和模块的高级特性</h1><ul><li><p>作用域相关</p></li><li><p>递归过程</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">recursive</span> <span class="token keyword">subroutine</span> name<span class="token punctuation">(</span>n<span class="token punctuation">,</span><span class="token keyword">result</span><span class="token punctuation">)</span>  ...  <span class="token keyword">call</span> name<span class="token punctuation">(</span>n<span class="token number">-1</span><span class="token punctuation">,</span><span class="token keyword">result</span><span class="token punctuation">)</span><span class="token keyword">end subroutine</span><span class="token keyword">recursive</span> <span class="token keyword">function</span> fact<span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token keyword">RESULT</span><span class="token punctuation">(</span>answer<span class="token punctuation">)</span><span class="token comment" spellcheck="true">! 对于递归函数比较特殊，需指定一个形参answer接受调用返回值</span>  answer<span class="token operator">=</span>n<span class="token operator">*</span>fact<span class="token punctuation">(</span>n<span class="token number">-1</span><span class="token punctuation">)</span><span class="token keyword">end function</span> fact<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>可选参数与参数顺序</p><pre class="line-numbers language-fortran"><code class="language-fortran">calc<span class="token punctuation">(</span>first<span class="token operator">=</span><span class="token number">3.</span><span class="token punctuation">,</span>second<span class="token operator">=</span><span class="token number">1.</span><span class="token punctuation">,</span>third<span class="token operator">=</span><span class="token number">2.</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">!指定参数顺序，有可选参数时比较实用</span><span class="token keyword">function</span> calc<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token keyword">integer</span><span class="token punctuation">,</span> <span class="token keyword">intent</span><span class="token punctuation">(</span><span class="token keyword">in</span><span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token keyword">optional</span><span class="token operator">::</span>a <span class="token comment" spellcheck="true">!定义一个可选参数</span><span class="token keyword">if</span> present<span class="token punctuation">(</span>a<span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">!如果使用时有这个参数</span>  ...<span class="token keyword">end if</span><span class="token keyword">end function</span> calc<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><p>显式接口，除了module还可用interface</p><pre class="line-numbers language-fortran"><code class="language-fortran"><span class="token keyword">interface</span>  <span class="token keyword">subroutine</span> name<span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">)</span>  ...  <span class="token keyword">end subroutine</span> name<span class="token keyword">end interface</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>每一个接口都是个独立的作用域</p></li></ul><p><br><br></p><blockquote><p>不行学不下去了，我还是去啃我的C++ Primer吧。</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-04-15-fortran-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《美丽新世界》个人摘录</title>
      <link>https://chengpengzhao.com/2020-03-31-mei-li-xin-shi-jie-ge-ren-zhai-lu/</link>
      <guid>https://chengpengzhao.com/2020-03-31-mei-li-xin-shi-jie-ge-ren-zhai-lu/</guid>
      <pubDate>Tue, 31 Mar 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;最近看书的时间不太够了，
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>最近看书的时间不太够了，一是要做毕设（进度本来就有点落后）、二是刚买个显示屏游戏去了；不知不觉今年就过了1/4，读书任务还是得完成的，只能减一减睡眠时间了。<br>《美丽新世界》还是挺有意思的，可能很多人还会向往这样的生活吧，实在是可怕。我看的版本是<strong>上海译文</strong>的，《美丽新世界》和《重返美丽新世界》二合一本。  </p><h1 id="摘录">2&emsp;摘录</h1><blockquote><p>真相是重大的，但更重大的事情，从实际的角度看，是对真相保持沉默。极权体制的宣传工作者只需对某些话题保持沉默，拉下丘吉尔先生所说的“铁幕”将群众和政治领导人认为不好的事实或争论隔绝开来，这对思想的影响就要比最雄辩的谴责或最不可抗拒的逻辑驳斥更卓有成效</p></blockquote><blockquote><p>未来最重要的曼哈顿计划将由政府资助，对政治家和参与其中的科学家所说的“幸福的问题”进行探究 —— 换句话说，让人们热爱奴役身份的问题。没有经济上的安稳，对奴役身份的热爱就不可能存在。</p></blockquote><blockquote><p>只有在对人的身心进行深刻革命的情况下才能实现对奴役身份的热爱。要实现这一革命，除了其他手段之外，我们还需要下面这些发现与发明。首先，心理暗示技术的飞跃 —— 先是通过婴儿培育，然后借助药物如莨菪碱。其次，全方位的对人与人的差别的认识，使得政府能够为任何个体分配他或她在社会和经济等级体系中适合的位置。（圆凿方枘将会带来对社会体制有害的想法和煽动起他人的不满。）第三，（因为无论现实多么美妙，人们总是希望去度假。）酒精和尼古丁的替代品，能比杜松子酒或海洛因带来更强烈的快感，而且危害更小。第四，（但这将是一个长期的计划，需要经过几代人时间的极权主义控制才能成功实现。）一个不会出错的优生学机制，目的是使人类的繁衍实现标准化，协助管理者的任务。</p></blockquote><blockquote><p>“我们培育群众憎恨郊野，”主任总结道，“但与此同时，我们安排他们热爱一切郊野运动。与此同时，我们确保所有的郊野运动都需要使用精密的器械。因此，促使他们会去消费工业品和交通工具。于是就采取了电击这一手段。”</p></blockquote><blockquote><p>虽然确实有水滴石穿这回事，但这些话并不像水滴，毋宁说，它们更像是蜡滴，一滴滴地附着在它们滴落的石头上，将它包裹起来，和它结合在一起，直到最后，那块石头变成了一个深红色的蜡团。“直到最后那个孩子的思想就是这些话，而这些话就是那个孩子的思想。不只是孩提时的思想，他长大了也会秉承这个思想 —— 一辈子都是这样。思想的判断、欲望和决定都由这些暗示所主宰，而所有的暗示都是我们的暗示！”主任志得意满地高声说道，“国家的暗示。”</p></blockquote><blockquote><p>母亲、一夫一妻制、恋爱，所以水喷得老高，泡沫四溅，汹涌澎湃，因为冲动只有一个发泄口。我的爱人，我的宝贝。难怪那些可怜的前现代人都那么疯狂、邪恶和可怜。他们的世界不让他们轻松面对，不允许他们保持理性、高尚和快乐。由于母亲和爱人，由于他们没有接受培育服从的禁令，由于有那些诱惑和寂寞的悔恨，由于有种种疾病和无尽的孤立的痛苦，由于种种无常和贫穷 —— 他们不得不产生强烈的情感。而有了强烈的情感（更何况是在孤独和弃世的绝望中），他们怎么能稳定呢？</p></blockquote><blockquote><p>“稳定，”主宰者坚持说道，“稳定是首要的终极的需要。稳定。因此就有了这一切。”</p></blockquote><blockquote><p>被抑制的冲动决堤了，这道洪水就是情感，这道洪水就是激情，这道洪水甚至就是疯狂。它取决于浪潮的力量和堤坝的高度与强度。无拘无束的水流顺着指定的河道自由地流淌，成为平静的康庄之河。胚胎饿了，日复一日，替代血液不停地以每分钟八百转的速度旋转着。瓶中的婴儿放声啼哭，一个护士马上拿着一瓶外分泌激素出现了。在欲望与满足的间隙潜伏着情感，将这个间隙缩短，打破一切旧的不必要的障碍。“幸运的男孩子们！”主宰者说道，“我们尽心尽力不辞辛劳，为的就是让你们过着轻松的情感生活 —— 尽可能地不让你们产生任何情感。”</p></blockquote><blockquote><p>但我可是一个贝塔，我在受精室里工作，从来没有人教过我这些事情。这不是我应该做的事情。而且，补衣服是不对的。衣服破了就扔掉买新的。‘补丁越多越是穷光蛋’，难道不是吗？补衣服是反社会的举动。但这里什么都不一样，就像和一群疯子生活在一起。他们所做的每一件事情</p></blockquote><blockquote><p>对于她来说，回到文明就是回到了苏摩，她可以躺在床上，不停地度假，不用回归现实，忍受头痛或呕吐，不会有喝完仙人掌酒之后常有的那种感觉，似乎你做了某件令你抬不起头做人的如此羞耻的反社会的举动。苏摩完全没有这些不良后果。它所赋予的假期是完美的，如果度假后的早上你觉得不好受，那并不是你自身的问题，而是和假期的快乐相比较的结果。解决方法就是继续度假。她贪婪地要求更大更频繁的剂量</p></blockquote><blockquote><p>“你不能要我听到父亲和母亲还能一本正经。谁会因为一个男孩能不能得到一个女孩而感到兴奋呢？”（野人的脸抽搐了一下，但赫姆霍兹若有所思地看着地板，什么也没有看见。）“不会的。”他长叹一声，总结道，“不会的。我们需要另外一种疯狂与激烈的描写。但那是什么呢？是什么呢？能从哪里去发掘呢？”他沉默了，然后摇了摇头，“我不知道，”他最后说道，“我真的不知道。”</p></blockquote><blockquote><p>“不，当然没有必要。有一类卑微的工作是用坚苦卓绝的精神忍受着的， 最低陋的事情往往指向最崇高的目标。我想要去做点崇高的事情。难道你就不明白吗？”</p></blockquote><blockquote><p>野人站在那儿看着这一幕。“啊，美丽的新世界，啊，美丽的新世界！”在他的脑海中，这些有如歌声般的语句似乎换了个调子。它们嘲讽着他的不幸与悔恨，以愤世嫉俗的可恶的调子调侃他！他们狞笑着，一直就像噩梦那样卑劣、丑陋、令人作呕。现在，突然间，它们就像嘹亮的军号在召集武装，“啊，美丽的新世界！”米兰达在宣告美好的可能性，要将噩梦变成美好而高贵的事物。“啊，美丽的新世界！”它是一个挑战，更是一个命令。</p></blockquote><blockquote><p>“你们愿意做奴隶吗？”他们刚走进医院就听到野人说道。他的脸涨得通红，他的眼睛闪耀着热烈而愤慨的光芒。“你们愿意当婴儿吗？是的，婴儿。呜呜呜地哭泣和呕奶。”他被他们野兽般的愚昧激怒了，开始羞辱这些原本想要拯救的人。但这些侮辱</p></blockquote><blockquote><p>根本无法穿透他们厚厚的愚昧的硬壳。他们一脸茫然地盯着他，眼睛里带着迟钝而阴郁的怨恨。“是的，在呕奶呢！”他高喊着。悲伤与悔恨、同情与责任现在都被忘得一干二净，被一股强烈的压倒一切的对这些称不上是人的怪物的仇恨吞没。“难道你们不想成为自由的人吗？难道你们就不明白人性和自由为何物吗？”愤怒使他变得口齿清晰，这些话滔滔不绝地脱口而出。“难道你们就不知道吗？”他重复着，但没有人回答这个问题。“很好。”他冷冰冰地说道，“我会教导你们。我会让你们获得自由，无论你们想不想要。”他推开一扇朝向医院内庭的窗户，开始将那些盛着苏摩的小药盒一把把地扔出窗外。那群穿着卡其布制服的乌合之众惊呆了，惊恐地看着这一肆意妄为离经叛道的做法。</p></blockquote><blockquote><p>因为我们的世界与《奥赛罗》的世界并不一样。没有钢铁你怎么能造出汽车呢？ —— 没有社会的动荡，你就写不出悲剧。如今的世界很太平，人们过着幸福的生活，他们想要什么就有什么，不会想要得到无法企及的东西。他们享受着富裕与安宁，没有病痛，不会害怕死亡。他们很幸福，不知道激情与年老为何物，他们不会受到父母的干预。他们没有感情深厚的妻子、孩子或爱人。他们所接受的培育使得他们不由自主地表现出应有的行为，就算出了什么岔子，还有苏摩呢。而你却把它们扔出窗外，以自由的名义，野人先生，自由！”他哈哈大笑，“以为德尔塔知道什么是自由！现在你还以为他们能看得懂《奥赛罗》！我的好伙计！</p></blockquote><blockquote><p>事实上，比起痛苦的过度补偿，幸福看上去总是很猥琐。当然，稳定没有动荡那么壮观。得到满足当然比不上与不幸进行搏斗那么令人心醉神迷，也不像与诱惑进行斗争，或由于激情或困惑而遭到致命的打击那么动人心魄。幸福从来就不是宏伟壮丽的</p></blockquote><blockquote><p>所有由于某种原因拥有了太强烈的自我意识的个体。他们都是不满足于正统思想的人，有自己的思想的人，无法融入集体生活。总而言之，每一个人都是独特的。我都有点羡慕你了，华生先生。</p></blockquote><blockquote><p>顺理成章地，我们能够摆脱上帝了。宗教情怀能够补偿我们的失落，但我们并不感到失落。失落和宗教情感是多余的。为什么在永葆青春的愿望已经得到满足的情况下我们还要去追求永葆青春的替代品呢？当我们可以一直享乐时，为什么要去禁欲呢？当我们的心灵和肉体一直愉快活跃时，为什么我们需要平静呢？当我们有苏摩的时候，为什么要寻求慰藉呢？当我们有社会秩序时，为什么要祈求永恒呢？”</p></blockquote><blockquote><p>“不如说是文明的错。上帝与机器、科学药品和普遍幸福是不相容的。你必须作出选择。我们的文明选择了机器、药品与幸福。这就是为什么我得把这些书锁在保险柜里的原因。它们是禁书。要是人们看到这些东西，他们会吓坏的 ……”</p></blockquote><blockquote><p>“有吗？”轮到主宰者提问了，“你可以肆意地与一个雄化雌体风流快活，不用担心你的儿子的情妇会把你的眼睛挖出来。‘天道的车轮已经循环过来了。’如果爱德蒙活在今天，他会怎么样呢？坐在充气沙发上，搂着一个女孩子的腰肢，嚼着性荷尔蒙口香糖，观看着感官电影。无疑，上帝是公正的，但他的律法是由人制定的。说到底，是人组织了社会。天命由人不由主。”</p></blockquote><blockquote><p>“但贞洁意味着激情，贞洁意味着神经衰弱，而激情与神经衰弱意味着动荡。动荡意味着文明的终结。没有愉快的恶习，就没有安稳的文明。”</p></blockquote><blockquote><p>文明绝对不需要高贵或英勇。这些事情是政治低效的表现。在像我们这么一个组织得当的社会，没有人能有机会去做高贵或英勇的事情。只有在极其动荡的时候才有这样的机会。有了战争和忠诚；有了需要抵制的诱惑，值得去争取或捍卫的爱情，高贵或英勇显然才有意义。但如今已经没有战争了。最需要关注的事情是不让你太爱上某个人。如今没有忠诚可言。一个人所接受的培育使得他会不由自主地做出应该做的事情。而你应该做的事情大体上是如此愉快，所有的自然本能都可以自由放纵，没有任何诱惑需要抵制。即使糟糕的事情不幸地发生了，怕什么呢，还有苏摩能够让你度假，逃避事实。苏摩总是能平息你的愤怒，让你与敌人和解，让你能平静地忍受。在以前，你只能努力克制和经过多年的道德训练才能做到这一点。而现在，只需要吞下两三片半克的药片就可以了。现在每个人都是正人君子。一瓶苏摩就能让你掌握一半的命运。不需要眼泪的基督教精神 —— 这就是苏摩。”</p></blockquote><blockquote><p>把一切不愉快的事情消灭掉，而不是学会去忍受它。是默然忍受命运暴虐的飞箭流石，还是挺身反抗人世的天涯的苦难，通过斗争把它们扫清 …… 但你们两样都不会去做，既不会去忍受也不会去反抗。你们只是把飞箭和流石一笔勾销了。</p></blockquote><blockquote><p>“我不要舒适。我要上帝，我要诗歌，我要真正的危险，我要自由，我要美好，我要罪恶。”穆斯塔法 · 蒙德说道：“事实上，你要求的是不幸福的权利。”“那好吧。”野人轻蔑地说道，“我正是在要求不幸福的权利。”“还有变老、变丑、变得性无能的权利，患上梅毒和癌症的权利，吃不饱的权利，肮脏的权利，总是生活在对明天的忧虑中的权利，患上伤寒的权利，受各种难以言状的痛苦折磨的权利。”</p></blockquote><blockquote><p>从长远来看，通过惩罚手段去控制不合乎要求的行为不如通过奖励对合乎要求的行为进行强化来得有效。而且，大体上，以恐怖手段实施统治的政府不如以非暴力的手段对环境与男女老少的思想和情感实施操纵的政府那么运作有效。惩罚暂时能够停止不合乎要求的行为，但无法永久消除被惩罚者沉溺其中的念头。而且，惩罚的身心影响或许就</p></blockquote><blockquote><p>当一个国家的经济生活陷入萧条时，中央政府只能为保证基本的福利承担起更多的责任。它必须制订精密的计划应对严峻的局面，它必须对民众的活动实施更大的控制，如果恶化的经济状况造成政治动荡或公然叛乱的话（这是非常可能出现的情况），中央政府必须进行干涉以维持公共秩序和自己的权威。从而，权力越来越集中于行政人员与官僚阶层的手中。但权力的本质就是：即使是那些并没有主动追求权力而是被迫接受权力的人也会渴望得到更多的权力。“不叫我们遇见试探，”我们祈祷 —— 我们有充分的理由这么做，因为当人类面对的诱惑的魅力太强大或时间太久时，他们总是会屈服。</p></blockquote><blockquote><p>在任何国家，当人口的数量对可利用的资源带来沉重的压力时，这些诱惑必定会出现。人口过剩导致经济萧条和社会动荡。而动荡和萧条又会导致中央政府实施更多的管制和强化他们的权力。如果没有宪政传统，权力的加强或许将以独裁专制的形式出现。由于人口过多导致动荡致使独裁势力崛起几乎是不可避免的事情。我敢打赌，再过二十年，全世界的人口过剩的不发达国家将会陷入极权主义统治之下。</p></blockquote><blockquote><p>那些先天不足的人又怎么样呢？我们的医药和社会服务保全了他们的性命，让他们得以繁衍自己的后代。帮助不幸的人显然是好事。但不良变异的结果正成批量地遗传给我们的后代，一点一滴地污染我们这个物种赖以繁衍后代的基因库，显然也是很糟糕的事情。我们陷入了伦理上的两难境地，必须倾注所有的智慧和善意，才能找到一条中庸之道</p></blockquote><blockquote><p>随着小人物的消失，越来越多的经济权力被越来越少的人掌握。在独裁体制下，技术进步造就了大型商业，进而消灭小型商业，并由政府掌控 —— 也就是说，由一小撮党的领袖和执行命令的士兵、警察和公务员控制。在资本主义民主国家，例如美国，是由查尔斯 · 赖特 · 米尔斯 [1] 教授所说的“权力精英”。这些权力精英直接雇佣着美国工厂、办公室和商店里的几百万劳动力，通过向数千万人贷款去购买他们的产品间接控制着他们，并且通过掌握大众通讯传媒，影响着基本上每个人的思想、情感和行为。套用温斯顿 · 丘吉尔的话说：“从未有如此之多的人被如此之少的人如此程度地实施操控。”</p></blockquote><blockquote><p>人类是为了安息日而创造的，他必须牺牲自己与生俱来的个人特征，伪装成集体活动的组织者心目中标准化的合乎理想的会交际的人。合乎理想的人会展现出“合群活跃”（多么美妙的字眼！）和对集体拥有高度忠诚，总是乐意服从命令，有归属感。合乎理想的人必须有合乎理想的妻子，非常合群，有极强的适应力，不仅接受她的丈夫首先要忠于企业这个事实，而且自己也非常忠诚。就像弥尔顿对亚当与夏娃的评论：“他只为了上帝而生存，而为了上帝，她在他的身体中。”在一个重要的方面，合乎理想的组织人的妻子要比我们的第一位母亲糟糕得多。她与亚当得到主的允许可以放纵不羁地沉溺于“年轻的嬉戏”。</p></blockquote><blockquote><p>当前的社会伦理只不过是在为过度组织化的不良后果进行开脱。它代表了从不得已而为之的事情中寻求价值，将坏事变成好事的可悲的尝试。它是一个非常不切实际因此极度危险的道德体系。社会整体的价值被认为要比它的组成部分的个体的价值更大，但它并不是一个像蚂蚁穴或白蚁窝那样的有机体。它只是一个组织，一台社会机器。它的价值只在于与生命和意识的关系。一个组织既没有意识也没有生命。它只有工具性和派生的价值。它本身并不美好，它的价值完全在于它如何能够让构成集体总和的个体获益。让组织优先于个人就是让目标服从于手段，希特勒和斯大林已经清楚地展现了这一点。</p></blockquote><blockquote><p>在独裁制度更有效率的明天，或许暴力行为不会像在希特勒和斯大林的统治下那么多。未来的独裁者的臣民将会没有痛苦地被一帮经过高度培训的社会工程师实施组织管理。“我们这个时代的社会工程的挑战，”一位这门新科学的热情的支持者写道，“就像五十年前技术工程遇到的挑战一样。如果说二十世纪的前半叶是技术工程师的时代，后半叶或许将会是社会工程师的时代。”——而我猜想二十一世纪将会是世界主宰、科学等级体制和美丽新世界的时代。</p></blockquote><blockquote><p>宣传可以分为两种 —— 理性的宣传号召与发言人和听众的正当的自我利益一致的行为，但非理性的宣传并不与正当的自我利益一致，而是诉诸激情，并由激情主宰。就个人的行动而言，有的动机比正当的自我利益更加高尚，但是，在政治与经济领域，当必须采取集体行动时，正当的自我利益或许是最有效的动机。如果政治家和他们的选民的行动总是在倡导实现自己或国家的长期利益，这个世界将会成为人间乐园。而实际的情况是，他们的行动总是有悖自己的正当利益，只是为了满足最不体面的激情。结果，这个世界就成为了悲惨之地。</p></blockquote><blockquote><p>号召与正当的自我利益一致的行为的宣传诉诸理性，通过基于当前所能获得的完整而忠实的证据进行合乎逻辑的辩论。而号召由卑劣的自我利益所驱动的行动的宣传提出的是断章取义的虚假的证据，回避符合逻辑的辩论，试图通过简单地重复口号，气急败坏地斥责国外或国内的替罪羊，狡猾地将最卑劣的激情与最崇高的理想勾兑了去影响受骗者。因此，暴行以上帝为名义被奉为不朽的功绩，最自私卑劣的现实政治被奉为宗教准则和爱国责任。</p></blockquote><blockquote><p>重塑对普遍人性本质的信仰，对人性的潜能的信仰，对人性以及对理性与真理作出回应的力量的信仰，是比展现物质成功或虔诚地崇拜某种特别的法律和政治形式更可靠的对抗极权主义的壁垒。</p></blockquote><blockquote><p>只有警醒的人才能够维护他们的自由，只有那些一直理智地活在当下的人才能有望通过民主制度实现自我治理。一个社会的绝大多数成员如果大部分时间不是活在当下和可预测的未来，而是生活在虚无飘渺的运动、肥皂剧、神话构建的奇幻迷离的世界里时，将很难抵挡想要操纵控制他们的人一步步的侵蚀。</p></blockquote><blockquote><p>今天的独裁者在宣传中主要依靠重复、镇压和文过饰非 —— 重复他们希望被当成真理接受的口号，镇压他们希望忽略的事实，激情的唤醒与合理化或许会为了党派或政府的利益而被利用。随着操纵的艺术和科学得到更深入的了解，无疑，未来的独裁者将学会将这些技术与无休止的消遣结合在一起。在西方，它们正构成威胁，将维护个体自由和民主制度的理性宣传淹没在无关紧要的琐事的海洋中。</p></blockquote><blockquote><p>群体能够像它的成员那样保持道德和理性，而乌合之众则混乱不堪，没有自己的目的，根本无法进行理智的行动和务实的思考。置身于乌合之众中，人们会失去理性思考和作出符合道德抉择的能力。他们的暗示感受性被增强到失去了自己的判断力和意志的程度，他们变得非常容易兴奋，失去了所有个体或集体的责任感，突然间会感到暴怒、兴奋和恐慌。简而言之，一个置身于乌合之众中的人的行为就像吞下了大剂量的强力兴奋剂。他们是我称之为“畜群中毒”症状的受害者，就像酒精一样，畜群毒害是一种烈性的外向性的毒药。畜群中毒的个体逃避责任、思想和道德，陷入一种恐慌状态，像动物一样失去了思考能力。</p></blockquote><blockquote><p>知识分子却像庭院里的母鸡，三三两两，各自信步而行，你无法利用他们去创造历史，也不能作为构成集体的一分子派上用场”。知识分子讲求实证，会惊讶于逻辑的矛盾和谬误。他们认为过度简化是思想的原罪，不受宣传人员惯用的口号、没有根据的断言和空泛的大而化之等手段的影响。</p></blockquote><blockquote><p>如今正在进行的洗脑采用综合手段，其有效性一定程度上依赖于对暴力的系统利用，一定程度上依赖于巧妙的心理操纵。它表明《一九八四》的路线正朝《美丽新世界》的路线转变。</p></blockquote><blockquote><p>在《美丽新世界》里，服用苏摩的习惯并不是个人的恶习，它是一种政治制度，是“权利法案”规定的生命、自由与追求幸福的个中要义。但这一最宝贵的个体不可被剥夺的权利同时也是保卫独裁者的最强大的武器。</p></blockquote><blockquote><p>如果独裁者愿意的话，他能够利用这些药品实施政治目的。他能通过改变被统治者的大脑的化学状态，让他们安于被奴役的状态，从而保证政治上的长治久安。他能使用镇静剂平息激动的人群，用兴奋剂去唤醒麻木不仁的人民的热情，用迷幻剂让可怜的人不去想到自己的悲剧。</p></blockquote><blockquote><p>任何法律或社会制度如果使得官员有可能陷入诱惑都是不好的。任何法律或社会制度能够让官员不受诱惑去滥用被授予的权力谋求私利或为某个政治、经济或教会组织的利益服务，都是好的。</p></blockquote><blockquote><p>统计标准只在精算中才有意义，在现实生活中并没有意义。在现实生活中，没有所谓的平均意义上的人，只有特定的男女老少，每个人都有其与生俱来的身心特征，所有人都在尝试（或被迫）将自己的生物多样性硬生生地挤入文化模式的统一性中。</p></blockquote><blockquote><p>历史并不是一门科学，而且只能在作伪与断章取义的情况下才能让它似乎是一门科学</p></blockquote><blockquote><p>如果人类真的是一个社会性物种的成员，如果他们的个体特征微不足道并能够通过适当的培育而完全定型的话，那么，显然就不需要自由了，国家迫害要求实现自由的异端人士将会被正当化。对于白蚁来说，为白蚁窝服务就是最好的自由。但人类并没有彻底的社会性，他们只是有一定的群居性。他们的社会不是像白蚁窝或蚁穴那样的有机体，而只是组织，换言之，是为了集体生活而创造的机器</p></blockquote><blockquote><p>但不幸的是，光有正确的知识与合理的原则并不足够。平淡的真相或许会被令人兴奋激动的谎言所掩盖。对激情的巧妙利用总是良好的决心所无法抵挡的。只有接受彻底的对宣传手段进行分析和看穿它的诡辩的培训，才能消除虚伪而有害的宣传的影响。</p></blockquote><blockquote><p>正统教育者所采用的方法从过去到现在一直很低效。在奉行科学的独裁者的统治下，教育将会真正起到作用 —— 结果就是，绝大多数男男女女长大之后会热爱他们的奴役，永远不会想到革命。我们似乎没有理由相信完全符合科学的独裁体制会被推翻。与此同时，世界上仍有自由存在。确实，许多年轻人似乎并不珍惜自由。但我们当中有人仍然相信，失去了自由，人就不能成为完整意义上的人，因此，自由是最高的价值。或许现在威胁自由的力量实在是太强大了，没办法长久地抵抗下去，但不管怎样，我们的责任就是尽自己的能力进行抵抗。</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-03-31-mei-li-xin-shi-jie-ge-ren-zhai-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>一次印象深刻的回国之旅</title>
      <link>https://chengpengzhao.com/2020-03-14-yi-ci-yin-xiang-shen-ke-de-hui-guo-zhi-lu/</link>
      <guid>https://chengpengzhao.com/2020-03-14-yi-ci-yin-xiang-shen-ke-de-hui-guo-zhi-lu/</guid>
      <pubDate>Sat, 14 Mar 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;写于202
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><br><br></p><blockquote><p><em>写于2020-03-11 21:01:16</em></p></blockquote><p>虽然飞机坐过有好几次了，但像这次这样给我留下深刻印象的只怕这辈子也不会有第二次吧；毕竟是在国内外疫情防控的关键时期。  </p><ol><li><p>凌晨5点我在酒店早早地醒来。这两天不知怎么的总是失眠，感觉全身都在发热、一意识到这一点更加睡不着了，生怕检查体温的时候出问题而被拒绝乘机之类的；第一次体会到心理作用对人的影响可以这么大。  </p></li><li><p>搭乘京急空港線エアポート急行、10多分钟便到了熟悉的羽田机场国际航站楼（好像过几天就改名了），地铁上人比我想象中的要多，不过很多应该都是去上班的，像我这样推着几个大箱子的倒很少。  </p></li><li><p>趁着人不多的时候赶紧提前办了登机手续，期间被测了次体温36.4度，总算是松了一口气，虽然当时精神状态还是很差，但应该是能登机的（能回来就好，回不来的话呆日本真不知道该怎么办）。漫长的等待之后，飞机总算要起飞了，稍微看了下周围大概只有1/3的乘客，看来航空公司也是不好过；而且都是隔开坐的，避免了近距离接触，这方面还是做得不错。等的时候还听到周围人说日语，心想工作真是不容易，这种时候也还必须舍弃和家人呆一起而出差到中国。  </p></li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200314210300.webp" alt title="羽田机场一览"></p><ol start="4"><li><p>顺利到首都机场了，虽然想早点拿着行李直奔单位开始隔离，但听到空姐说请暂时呆在座位上听防疫人员安排时，就心想“啊，看来要折腾一阵子了，这架势说不定会直接拉去集中隔离”。填完健康申报表、中途在飞机上又被测了次体温后，总算是能够下飞机了；紧接着就是一个个全副武装的人员，再一次测体温、交表、过海关…期间好像还有那种红外测温的装置，感觉自己仿佛身临以前看过的生化类电影，说实话没有太多真实感。  </p></li><li><p>走着走着，看到周围一排排座椅，差点以为自己走错了地方（这不是候机的地方嘛？）。后来看新闻才知道：</p></li></ol><blockquote><p>在首都国际机场T3航站楼D区开辟专门区域，作为来自疫情严重国家的航班停靠专区，对所有乘客完成卫生检疫、体温筛查、信息核录、进港中转等流程后，分类进行转送。</p></blockquote><p>这里要吐槽一下这新闻发布的也<strong>太慢了</strong>，我们一飞机人当时都处于<em>我在哪、我要到哪去</em>的状态，而且周围工作人员也几乎没啥具体说明；国人还好，毕竟大致也猜得到具体状况，我倒替那几个日本人担心，不知道他们懂不懂中文，不懂的话只怕要被这阵势吓到hh…  </p><ol start="6"><li>拿了行李之后直接被引导到一辆大巴上（一共好几辆），大巴上等了有差不多1个小时，嘀咕这效率也就这样，看来是紧急出台的措施，嘛理解倒能理解。周围的人也是一副不安的表情，但没有一个人主动去问要到哪里去，之后要干什么，可能大家都多少猜到了，而且问了也没啥用反正到了就知道的事，还是要尽量减少和他人接触。  </li></ol><ol start="7"><li>不得不说大巴上的空气挺闷的，虽然好像是一直在换气（听得到声音），但还是难受，后来回想起来这应该是整个旅程中最危险的部分，最接近密闭空间这一要素。  大巴最后开进了中国新国展（国际展览中心），第一次看到那么多警卫、全副武装的医护人员，看来这里就是隔离点？下车后排队进去登记，我机智快速地拿了行李并抢到了靠前的位置。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200314210351.webp" alt title="到处都是防护服"></li></ol><p>后来才知道，这只是个集散点：  </p><blockquote><p>针对入境进京人员的疫情防控，北京市在中国国际展览中心新馆（顺义区）设立专门的集散点，由各省区市和北京市16区及开发区分别派驻工作组，做好24小时的分流转送工作。目的地为外省区市的，由相关省区市具体负责转送和安全防护工作。目的地为北京的，由属地各区具体负责转送和安全防护工作。有固定居所的，各区安排专车专人送至居住小区，严格执行14天的居家观察；无固定居所的，各区安排专车专人送至本区集中观察点；短期进京且有商务等行程目的地的，安排专车专人送至指定宾馆，并接受健康管理。对私家车来接且确定为居家观察的，各区负责登记接机人员和旅客详细信息、签订承诺书后，核实无误的允许返回居住小区。到达居住小区后，由街乡和社区在小区门口做好对接，出示居家观察告知书，签订居家观察承诺书，落实14天居家观察有关要求，做好日常服务保障。</p></blockquote><ol start="8"><li>这个地方还真是空旷，进馆后不由得感叹道；北京市内不同的区分开进行登记，每个进行登记的人都是一身装备（不由得想这防疫物资这么多的嘛）。对方问了些基本情况之后，马上打电话派人去核实，说是在核实之前必须等着，要是不行就要去安排的酒店集中隔离；这时候才感觉到自己有多么幸运，单位里给安排了隔离的住处，不用担心一日三餐等基本生活需求；那些在家隔离的想必挺辛苦的吧，如果一个人的话要自己处理协调保障生存、如果和家人在一起的话会连累对方（对方也必须再次隔离）；那些只好酒店隔离的也不容易，陌生的环境、价格也应该不便宜（具体不知道是怎么算的、不过钱应该还是会要的吧，毕竟免费这种好事大多是假的）。这么一想，自己好像是最无忧无虑的那个，也就没什么抱怨的理由了。  </li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200314210458.webp" alt title="谈 笑 风 生"></p><ol start="9"><li>期间也见了各种各样的人，比如旁边有位小姐姐就和工作人员吵起来了，看她状况应该是只能去酒店隔离但她不想去，说是像监狱一样什么的、家人都在国外什么的、在巴士上就开始在忍了之类的话，估计是很厌恶国内环境的那类人；还有位和我一个区的，也是只能去酒店隔离、最后专车送到酒店门口时却因为不清楚价格问题不肯下车、说着我录音了之类的话，属于那种比较在意维护自己权益的那类人，还是比较强悍的。  </li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200314211049.webp" alt title="专车送到单位"></p><p>我的话下意识还是对舔狗比较讨厌的，无论是过分舔国内还是国外某些国家、对他们都会敬而远之。</p><ol start="10"><li>最后折腾到傍晚才到单位，小巴车（我也不知道怎么称呼这种车，据我爸说这种车是接送领导用的，笑）上的消毒液气味着实难受，不过想到他们能花这么大成本把每一个人送到隔离点也是不容易。  到隔离住处后总算是见到了熟悉的宿管，量了次体温后立马开始隔离，饭按时送到门口。饿了一天的我（路上根本没机会可以吃东西、谁都不敢摘口罩）久违地吃到了普普通通炒出来的菜后也是感动到不行。原来这就是中国菜的味道，我感慨道。</li></ol><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200314211333.webp" alt title="平淡无奇的盒饭也是这么好吃"></p><ol start="11"><li>没有了失眠的理由，当天晚上早早地睡了，一觉爽快地睡到天亮，开始了我的隔离生活。  </li></ol><p><br><br></p><blockquote><p><em>以下内容更新于2020-03-14 21:15:04</em></p></blockquote><ul><li><p>忽然想起小学的时候，一次爷爷奶奶出去走亲戚而我不想去呆在家里，那天中午去楼下买的7块钱辣椒炒肉的盒饭，就觉得非常美味了。  </p></li><li><p>这几天很是庆幸自己选择了一个好时机回国，如果再晚一天就出台了一个政策、说是留学回国前要审批什么的，那样的话就不知道要等到什么时候了。  </p></li><li><p>自己应该是最近的国外回京的人们中第一批经历这些的吧，好在当天的航班人不多；看TG里好像这几天有大批回国的、也有好多抱怨强制隔离、不够人性化什么的。确实有很多可以指摘的地方，我应该算是很幸运的了，那个集中隔离的小姐姐也说“天啊你们单位这么好还提供隔离的地方”，我一切都看在眼里，深知自己没有资格去抱怨什么，只希望双方都能多一份理解、弱势的一方能得到合适合理的待遇。  </p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-03-14-yi-ci-yin-xiang-shen-ke-de-hui-guo-zhi-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>さらば、霓虹</title>
      <link>https://chengpengzhao.com/2020-03-09-saraba-ni-hong/</link>
      <guid>https://chengpengzhao.com/2020-03-09-saraba-ni-hong/</guid>
      <pubDate>Mon, 09 Mar 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;现在&quot;&gt;1&amp;emsp;现在&lt;/h1&gt;&lt;p&gt;每次离开一个呆了一段时间
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="现在">1&emsp;现在</h1><p>每次离开一个呆了一段时间的地方都会产生一些乱七八糟的感慨，与其望着一地行李发呆，不如写点什么，顺便做个阶段性的总结吧。  </p><h2 id="返程计划">1.1&emsp;返程计划</h2><p>首先，这次离开的有些匆忙，受疫情影响大量航班都取消了，我先后买了海南航空、中国国际航空、南方航空的机票，结果最后取消得只剩南航的了，而且不知道将来一周日本疫情将如何发展；如果变严重导致中国彻底禁止日本方面入境的话那我就gg了，所以干脆提前十多天回京。（想必旅途也比较艰辛、而且丝毫不能大意）<br>这是羽田机场明天的航班状况，到北京的只剩一班，着实可怕，希望后天不会有什么变动。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200309202952.webp" alt></p><h2 id="买票感受">1.2&emsp;买票感受</h2><p>曲折的买票经历算是让我积累的一些经验，比如特殊时期在<code>去哪儿</code>等一些平台上买票有多么的不靠谱：  </p><ol><li>信息更新不及时，比如我第一次买的海南航空的机票，官网明确说取消了，平台上还是放在上面卖</li><li>服务质量贼差，电话电话打不通、线上发消息对话模板一套一套的，根本无法交流</li><li>改个票二十多个小时没动静，退票瞬间发短信过来了（然后白白交了几百手续费）</li></ol><p>所以特殊时期还是尽量<strong>在航空公司官网</strong>买票，及时查看<strong>机场实时信息</strong>相关网页。</p><h2 id="遗憾">1.3&emsp;遗憾</h2><p>遗憾还是有一些的，回顾呆在日本这5个多月，其实没有出去玩太多地方，甚至不如那些来观光一周的游客。一是学业压力比较大，，想学的也挺多；二是很多计划因为コロナウイルス被我直接取消了：<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200309204217.webp" alt><br>这些天每天打开テレビ都是コロナコロナ，搞得甚至自己都有点麻木了，这是最可怕的，明明那么多人在不断逝去，而不在漩涡中心的我们却什么也感觉不到。</p><h1 id="过去">2&emsp;过去</h1><p>有时候怀疑时间是不是个外挂选手，感觉昨天才出发、东西搬到宿舍立马躺床上睡着了。不知不觉夏天过去了，秋天好像很短暂，冬天就下了一次小雪，啊现在算是春天了吧，好像有的地方樱花已经开了，不记得在哪见着了地上的花瓣。</p><h2 id="收获">2.1&emsp;收获</h2><p>虽然现在没啥闲情具体回顾，毕竟要干的事情还很多，压力依旧挺大；但随便扯一扯也花不了多少时间。<br>最大的收获肯定是认识了许多大佬，来自不同国家的优秀的人；虽然现在我们做着相似的事情、但从小的生活环境、接收的教育却千差万别，一想到这件事就让我感到很奇妙。来自越南的博士我对他的家乡几乎一无所知，只知道过去发生过<strong>红色高棉</strong>这样残酷的往事，但他能说一口十分流利标准的英语，本科在美国读、硕士来到日本，在国际比赛上拿奖、被邀请去参加诺贝尔颁奖式。还有主动向我搭话的那位日本老哥，一查他的学术背景就知道是大佬，刚从美国交换1年回来，和我这种半吊子的留学不一样；他颠覆了我对日本人的英语口语水平的印象。<br>当然还不得不提给我这个留学机会的教授，虽然已经60了还奔波于出差、上课之间，光是这几个月我在<code>FB</code>上就看到他去了英国、美国、中国、德国、韩国…需要倒时差的旅途几乎是家常便饭，只能说很厉害了。<br>当然也见了许多身着一样制服的上班族、戴着小黄帽背着大书包的小学生、哦对了当然还有真的不怕冷？的JK（气温都快零下了还是穿着短裙）、也有在湖边搭个帐篷当作家的流浪汉、来到日本开拉面店的中国小哥、日语说的贼地道毫无口音的英国人…</p><h2 id="感受">2.2&emsp;感受</h2><p>提一些生活了这些时间的一点杂感吧：  </p><ol><li>吃的东西好贵啊，贯穿始终的想法</li><li>食物的实惠程度（怎样省钱）：    傍晚的超市&gt;傍晚的便利店&gt;白天的超市&gt;白天的便利店&gt;其他店面</li><li>便利店真的啥都有，而且简直遍地都是</li><li>垃圾分类真的麻烦；千万不要指望在哪碰到个公共垃圾桶，不存在的</li><li>生活各方面服务比较好，有什么手续都说的很清楚</li><li>即使不懂日语，只要有钱，可以生活的很好（这不是废话么。不过这里重点是突出便利性，很多地方有中文翻译、中文售货员）</li><li>外国人很多，超级多，大多数外国人对日本的印象不错（生活质量方面）</li><li>日本房子都很紧凑，简直不要太挤，毕竟国土面积狭小</li><li>早餐大家都在家吃的，要么就便利店解决，别想早上有哪个店铺开门能去吃早餐（例外也有，比如名古屋的モーニング）</li><li>地铁其实也挺复杂的，各种类型、各种不同所属会社，刚开始经常坐错地铁</li></ol><h1 id="将来">3&emsp;将来</h1><p>记得刚来日本的时候，去店里吃顿饭都十分紧张，生怕听不懂对方说的话，不知道怎么点餐被别人用怪异的眼神盯着（甚至嘲笑），是的这些我都经历过，所以已经不算什么了（笑）。<br>现在就算有些时候仍会卡住但至少能开口说了，跟日本人打电话也感觉没啥问题；英语也是，以前从来没跟外国人交流过，一开口一直处于紧张状态。但现在被教授逼得不开口不行，结果发现也没啥，大不了换个更简单的说法，只要对方能理解就行（以后还是要多加强英语学习）。<br>有朝一日再来吧，去探索更多没去过的地方；希望世界各国疫情都早日结束，恢复正常的生产生活。<br><br><br>马上要回去接受隔离咯，希望返程顺利</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-03-09-saraba-ni-hong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>SSH、GPG学习与使用</title>
      <link>https://chengpengzhao.com/2020-03-04-ssh-yu-gpg-de-xue-xi-yu-shi-yong/</link>
      <guid>https://chengpengzhao.com/2020-03-04-ssh-yu-gpg-de-xue-xi-yu-shi-yong/</guid>
      <pubDate>Wed, 04 Mar 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;记得&lt;strong&gt;第一
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>记得<strong>第一次</strong>接触到SSH是在开始折腾博客那会，照着网上的教程一步步来设置<code>Github</code>环境、生成<code>SSH key</code>什么的，然后每次<code>git push</code>的时候就不用输密码了。<br><strong>第二次</strong>接触到它是在买了VPS之后，听说大佬们为了增加安全性都是通过密钥登录的，这里用的也是<code>SSH key</code>。<br>而接触到<code>GPG</code>是最近逛别人博客时，发现有好几个都留了个叫<em>PGP公钥</em> 的东西，如<a href="https://printempw.github.io/about/" target="_blank" rel="noopener">PRIN</a>和<a href="https://neoatlantis.org/identserv/" target="_blank" rel="noopener">NeoAtlantis</a>的博客。正好印象中记得Github里好像有个<code>GPG key</code>，出于好奇于是学习了下相关知识，说不定以后用得到。  </p><h1 id="SSH">2&emsp;SSH</h1><h2 id="是什么">2.1&emsp;是什么</h2><blockquote><p>SSH(Secure Shell)，一种加密的网络传输协议，来实现SSH客户端与服务器之间的连接。</p></blockquote><blockquote><p>SSH是每一台Linux电脑的标准配置。</p></blockquote><p>众所周知，SSH主要用于远程登录；说它安全是因为采用了非对称加密，但也不是没有风险。由于具体的实现细节我没必要去关注，涉及到密码学一些知识也看不到，只求知道大概的原理和使用方法就行。  </p><h2 id="公钥和私钥">2.2&emsp;公钥和私钥</h2><p>首先是这两个基础概念，非常重要  </p><ul><li><strong>私钥</strong>  </li></ul><ol><li>非公开（废话），打死不交给别人</li><li>用私钥加密的数据<strong>只有</strong>对应的公钥可以解密</li></ol><ul><li><strong>公钥</strong>  </li></ul><ol><li>公开</li><li>用公钥加密的数据<strong>只有</strong>对应的私钥可以解密</li></ol><p>这不没区别么？？？好像真是这样，除了公钥和私钥是<strong>成对的</strong>、随便规定一个为公钥、那么另一个就叫私钥好了。<strong>数学上</strong>据说没区别，但是平常使用中，<strong>私钥的地位远远高于公钥</strong>；而且很多工具都设计成：<strong>私钥包含公钥信息</strong>,即<strong>私钥可以推导出公钥</strong>、<strong>私钥包含公钥</strong>。<br>所以使用中千万不要弄混了，一般带有<code>pub</code>字眼的为公钥(public key)。</p><h2 id="SSH登录">2.3&emsp;SSH登录</h2><p>梳理下利用SSH登录<code>vps</code>的流程吧，虽然个人理解的可能不太准确…  </p><ol><li>客户端向<code>vps</code>发起一个登录请求</li><li><code>vps</code>生成一串随机数，利用之前配置好的公钥(<code>authorized_keys</code>)进行加密，将加密后字符串传给客户端</li><li>客户端利用私钥(<code>id_rsa</code>)进行解密，将解密后的字符串外加一些别的(<code>sessionKey</code>之类的、我也不知道是啥)字符串；将整合得到的新的“摘要”用<strong>私钥</strong>加密，发给<code>vps</code></li><li><code>vps</code>对“摘要”用<strong>公钥</strong>解密，通过解密得到的文本判断是否认证该客户端登录</li></ol><p>可以看到整个过程充分利用了公钥和私钥可以互相加密与解密的特点，通常说<strong>公钥加密、私钥解密</strong></p><h2 id="常用命令">2.4&emsp;常用命令</h2><ul><li>首先得生成一对SSH密钥<pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># Github帮助里就有</span>ssh-keygen -t rsa -b 4096 -C <span class="token string">"your_email@example.com"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre>用默认值、按几下空格就生成了，<code>passphrase</code>不填（填了的话每次还得输一遍安全密码），毕竟用<code>SSH keys</code>的目的就是想偷点懒不必每次输入密码。<br>注意密钥的<strong>位置</strong>默认是：<pre class="line-numbers language-bash"><code class="language-bash">~/.ssh/id_rsa~/.ssh/id_rsa.pub<span class="token comment" spellcheck="true">#也就是说和当前$USER有关，若为root，则在/root/.ssh/</span><span class="token comment" spellcheck="true">#若为xxx，则在/home/xxx/.ssh/</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre></li><li>若不是在本机生成的密钥（如从别的地方拷贝过来的），还要将SSH 密钥添加到<code>ssh-agent</code><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 注意.ssh文件夹的权限、所属用户组</span><span class="token function">sudo</span> -u <span class="token variable">$USER</span> /bin/bash -c <span class="token string">"sudo chmod -R 700 <span class="token variable">$HOME</span>/.ssh"</span> <span class="token operator">&amp;&amp;</span> \<span class="token function">sudo</span> -u <span class="token variable">$USER</span> /bin/bash -c <span class="token string">"sudo chown -R <span class="token variable">$USER</span>:<span class="token variable">$USER</span> <span class="token variable">$HOME</span>/.ssh"</span> <span class="token operator">&amp;&amp;</span>\<span class="token function">sudo</span> -u <span class="token variable">$USER</span> /bin/bash -c <span class="token string">"sudo chmod 600 <span class="token variable">$HOME</span>/.ssh/id_rsa.pub"</span> <span class="token operator">&amp;&amp;</span> \<span class="token function">eval</span> <span class="token variable"><span class="token variable">$(</span>ssh-agent -s<span class="token variable">)</span></span> <span class="token operator">&amp;&amp;</span> ssh-add ~/.ssh/id_rsa <span class="token operator">&amp;&amp;</span> \<span class="token function">ssh</span> -T git@github.com<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li></ul><p>如果已经把<code>$HOME/.ssh/id_rsa.pub</code>添加到了<code>Github</code>，那么运行下面的命令后应该就会出现类似下面的问候（当然用户名、邮箱之类的要配置好）：</p><pre><code>Agent pid 19103Identity added: /home/zcp/.ssh/id_rsa (/home/zcp/.ssh/id_rsa)Hi chengpengzhao! You&#39;ve successfully authenticated, but GitHub does not provide shell access.</code></pre><h2 id="密钥管理">2.5&emsp;密钥管理</h2><p>不知道多少人是每换一个环境（比如换台电脑、换个操作系统、换台VPS）就把上述的<code>SSH keys</code>配置流程重新走一遍的，然后保存了一大堆的私钥。固然，这样安全性比较高，但我更偏向于只使用<strong>一对</strong>密钥，生成之后好好保管着，然后要用的时候复制到相关环境里。<br>最近学shell脚本顺便就写了个自己用的<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener">一键配置Linux环境</a>，我甚至把<strong>SSH公钥</strong>和<strong>加密后的私钥</strong>都放到了<code>Github Repository</code>里，目的是尽可能减少本地管理的密钥数量。这里加密是利用<code>GnuPG</code>完成的。</p><h1 id="GPG">3&emsp;GPG</h1><h2 id="是什么-1">3.1&emsp;是什么</h2><p>刚开始分不清<code>GPG</code>和<code>PGP</code>，以为有一个是写错了，后来才知道原来<code>PGP</code>代表<code>Pretty Good Privacy</code>，是一个加密用的商业软件；<code>GPG</code>是<code>GnuPG</code>的简称，是一个开源软件、<code>PGP</code>的替代品。还有个叫<code>OpenPGP</code>的一套标准，大多数<code>PGP</code>软件都遵循它。 <code>GPG</code>可以用来实现非对称的<strong>文件加密</strong>、对数据进行<strong>签名</strong>等操作；这也是它最主要的两个用途，如GitHub里<code>Verified</code>的签名就是用它实现的：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200304001924.webp" alt></p><h2 id="密钥和子密钥">3.2&emsp;密钥和子密钥</h2><p><code>PGP</code>中有密钥对和子秘钥的概念，如果我们只使用主密钥对，那么私钥泄露后只能吊销整个密钥，所以一般不使用主密钥，而是通过产生一系列用途各异的子秘钥进行操作。好像可以单独导出子秘钥，但公钥由于是公开的，所以主公钥、子公钥都是捆绑在一起的。 (试过只导出一个子公钥，结果和导出所有公钥的输出一模一样)<br><strong>使用建议</strong>：主私钥不要放在网络上，平时只用子私钥操作，并且最好设定一个过期时间；一般用三个子私钥(A验证+E加密+S签名) 。<br><br><br>关于一些人建议将<code>PGP key</code>上传到一些<code>key server</code>，我是<strong>反对</strong>这种做法的，因为公钥服务器上的key<strong>无法删除</strong>，只能被吊销，而且可能暴露你的email等信息。而又几乎没有任何好处，谁会真正去<code>key server</code>上搜你的公钥？搜到的公钥安全性也没有保障；建议公开公钥到更加安全的地方。<br>服务器上的公钥更多的是利用gnupg的<strong>相互签署机制</strong>，即可以签署别人的公钥，即告诉其他人自己是信任这个人的公钥的真实性的；但说真的有多少人会真正用到这个功能呢，总之<strong>不推荐</strong>传<code>key server</code>。<br><br></p><h2 id="常用命令-1">3.3&emsp;常用命令</h2><h3 id="生成密钥">3.3.1&emsp;生成密钥</h3><pre class="line-numbers language-bash"><code class="language-bash">gpg --full-gen-key<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>选择因需求而异，我是默认类型、44096位、永不过期、用户标识、密钥安全密码。<br>生成完后会出现类似下面输出：</p><pre><code>gpg: 密钥 404AAAD7FED2325E 被标记为绝对信任gpg: 目录‘/home/zcp/.gnupg/openpgp-revocs.d’已创建gpg: 吊销证书已被存储为‘/home/zcp/.gnupg/openpgp-revocs.d/9C0281B1DDCCD3289CE3B297404AAAD7FED2325E.rev’公钥和私钥已经生成并被签名。pub   rsa3072 2020-03-03 [SC]      9C0281B1DDCCD3289CE3B297404AAAD7FED2325E      uid                      zzzcp      sub   rsa3072 2020-03-03 [E]</code></pre><p>可以看出会自动产生一个用于加密的<strong>子密钥对</strong></p><h3 id="常见缩写含义">3.3.2&emsp;常见缩写含义</h3><pre><code>A    =&gt;    AuthenticationC    =&gt;    CertifyE    =&gt;    EncryptS    =&gt;    Sign?    =&gt;    Unknown capabilitysec  =&gt;    Secret Keyssb  =&gt;    Secret SuBkeypub  =&gt;    Public Keysub  =&gt;    Public Subkey</code></pre><h3 id="添加子密钥对">3.3.3&emsp;添加子密钥对</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#专家模式</span>gpg --expert --edit-key  xxxx <span class="token comment" spellcheck="true"># 进入GPG界面，接下来help看帮助，addkey加子秘钥</span><span class="token comment" spellcheck="true"># 只有在专家模式下能够自定义密钥用途</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>生成后的输出:</p><pre><code>sec  rsa4096/BF5738A17E62F3FC     创建于：2020-03-04  有效至：永不       可用于：SC     信任度：绝对        有效性：绝对ssb  rsa4096/53BF89B0D716836D     创建于：2020-03-04  有效至：永不       可用于：Essb  rsa3072/A11C5129AAE5BA77     创建于：2020-03-04  有效至：永不       可用于：Sssb  rsa3072/F63314C02344A273     创建于：2020-03-04  有效至：永不       可用于：A[ 绝对 ] (1). JiyoTomare (この、くそったれな世界に、精一杯愛をこめて) &lt;cavsarpwgnckamekerokardank89@gmail.com&gt;</code></pre><ul><li><strong>重中之重</strong><br>生成完之后千万不要一激动按<code>&lt;Ctrl+C&gt;</code>退出gpg界面了，输入<code>save</code><strong>正确的退出</strong>!!!</li></ul><h3 id="生成注销证书">3.3.4&emsp;生成注销证书</h3><p>密钥作废时使用（我没用过所以还不清楚具体怎么用），需要用到的时候再学吧</p><pre class="line-numbers language-bash"><code class="language-bash">gpg --gen-revoke <span class="token punctuation">[</span>ID<span class="token punctuation">]</span><span class="token comment" spellcheck="true">#ID可以是邮箱或者是密钥标识的那一长串字符串</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h3 id="列出密钥">3.3.5&emsp;列出密钥</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 列出所有公钥、子公钥</span>gpg --list-keys --keyid-format LONG<span class="token comment" spellcheck="true"># 列出所有密钥、子密钥</span>gpg --list-secret-keys --keyid-format LONG<span class="token comment" spellcheck="true"># 更简洁的命令：</span>gpg -k <span class="token comment" spellcheck="true"># 列出公钥</span>gpg -K <span class="token comment" spellcheck="true"># 列出私钥</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="输出密钥">3.3.6&emsp;输出密钥</h3><p>推荐分开输出，即每个子私钥保存一个文件，不混在一起</p><pre class="line-numbers language-bash"><code class="language-bash">gpg --fingerprint <span class="token comment" spellcheck="true">#输出公钥指纹，用来核对公钥的可靠性</span>gpg --armor --output public-key.txt --export <span class="token punctuation">[</span>ID<span class="token punctuation">]</span>  <span class="token comment" spellcheck="true">#导出公钥</span>gpg --armor --output secret-key --export-secret-key <span class="token punctuation">[</span>ID<span class="token punctuation">]</span> <span class="token comment" spellcheck="true">#导出主私钥，注意安全性！！！</span>gpg --armor --output sign-subkey --export-secret-subkeys <span class="token punctuation">[</span>ID<span class="token punctuation">]</span>   <span class="token comment" spellcheck="true">#导出有[S]标识、签名用子私钥</span>gpg --armor --output encrypt-subkey --export-secret-subkeys <span class="token punctuation">[</span>ID<span class="token punctuation">]</span> <span class="token comment" spellcheck="true">#导出有[E]标识、加密用子私钥</span>gpg --armor --output authentication-subkey --export-secret-subkeys <span class="token punctuation">[</span>ID<span class="token punctuation">]</span> <span class="token comment" spellcheck="true">#导出有[A]标识、认证用子私钥</span><span class="token comment" spellcheck="true"># --armor选项不启用，就会导出二进制格式文件</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>妥善保管自己的私钥!</strong></p><h3 id="删除密钥">3.3.7&emsp;删除密钥</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#一般要先删除子私钥才能删除主私钥</span>gpg --delete-secret-keys <span class="token punctuation">[</span>ID<span class="token punctuation">]</span>gpg --delete-keys <span class="token punctuation">[</span>ID<span class="token punctuation">]</span><span class="token comment" spellcheck="true">#如果想全部删除推荐直接删文件夹,即删除 $HOME/.gnupg</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>确保把所有数据都删除了。之后再就只导入子私钥了，主私钥妥善保管，一般不使用。</p><h3 id="导入密钥">3.3.8&emsp;导入密钥</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#从本地文件导入</span>gpg --import <span class="token punctuation">[</span>密钥文件<span class="token punctuation">]</span><span class="token comment" spellcheck="true"># 从URL导入</span>curl https://cdn.jsdelivr.net/gh/chengpengzhao/Zcp-s-PGP-Signatures/Zcp_PGP.pub <span class="token operator">|</span> gpg --import<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>我导入完成后的输出：</p><pre><code>/home/zcp/.gnupg/pubring.kbx----------------------------sec#  rsa4096 2020-03-04 [SC]      77F37C33368AD0B5D52810D1BF5738A17E62F3FCuid           [ 未知 ] JiyoTomare (この、くそったれな世界に、精一杯愛をこめて) &lt;cavsarpwgnckamekerokardank89@gmail.com&gt;ssb   rsa4096 2020-03-04 [E]ssb   rsa3072 2020-03-04 [S]ssb   rsa3072 2020-03-04 [A]</code></pre><p>可以看到信用等级是<code>[未知]</code>，可以通过<code>gpg --edit-key ID</code>再运行<code>trust</code>命令调整。<br>带<code>#</code>号说明<strong>缺失</strong>当前私钥，因为我为了安全没有导入主私钥</p><h3 id="加密解密">3.3.9&emsp;加密解密</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 加密：</span><span class="token comment" spellcheck="true"># recipient指定接收者的公钥ID</span>gpg --recipient <span class="token punctuation">[</span>ID<span class="token punctuation">]</span> --output encrypt.txt --encrypt input.txt<span class="token comment" spellcheck="true"># 也可以按喜好加上--armor选项等</span><span class="token comment" spellcheck="true"># ***************************************</span><span class="token comment" spellcheck="true"># 解密：</span>gpg --decrypt encrypt.txt --output decrypt.txt<span class="token comment" spellcheck="true"># 虽然是常识性问题但还是再提一下，解密要用公钥对应的私钥！</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="签名">3.3.10&emsp;签名</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 第一种方式，生成二进制签名文件</span>gpg --sign input.txt  <span class="token comment" spellcheck="true"># 当然也可以加上--output参数</span><span class="token comment" spellcheck="true"># 第二种方式，生成ASCII格式签名</span>gpg --clearsign input.txt<span class="token comment" spellcheck="true"># 第三种，签名和原文本分开（前两种的签名文件中包含了所有原文本，所以体积会比较大）</span>gpg --armor --detach-sign input.txt  <span class="token comment" spellcheck="true">#不加armor生成会二进制</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>当然也可以结合签名和加密，用<strong>自己的私钥签名，他人的公钥加密</strong>:</p><pre class="line-numbers language-bash"><code class="language-bash">gpg --local-user <span class="token punctuation">[</span>发信者ID<span class="token punctuation">]</span> --recipient <span class="token punctuation">[</span>接收者ID<span class="token punctuation">]</span> --armor --detach-sign --encrypt input.txt<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h3 id="验证签名">3.3.11&emsp;验证签名</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 注意签名在前，被签名文件在后</span>gpg --verify demo.txt.asc demo.txt<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h1 id="我的PGP-keys">4&emsp;我的PGP keys</h1><p>我把自己的身份验证方法放在了<code>Github</code>一个仓库里，所有的提交都是经过<code>PGP key</code>验证了的。<br><a href="https://github.com/chengpengzhao/Zcp-s-PGP-Signatures" target="_blank" rel="noopener">Zcp’s PGP Signatures</a><br><br><br>前面介绍的<code>GnuPGP</code>主要在Linux环境下使用，Windows中推荐<code>WSL</code>或者用<code>Gpg4win</code>软件。总的来说我们使用<code>PGP keys</code>的目的就是：</p><ol><li>供他人验证身份，来证实某消息确实出自自己之手、并且未被第三人修改过。</li><li>加密消息，通过他人公开的公钥能够向对方发送加密了的讯息，而只有持有对应私钥的他本人能够解密。</li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-03-04-ssh-yu-gpg-de-xue-xi-yu-shi-yong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>《1984》个人读书摘录</title>
      <link>https://chengpengzhao.com/2020-02-29-1984-ge-ren-du-shu-zhai-lu/</link>
      <guid>https://chengpengzhao.com/2020-02-29-1984-ge-ren-du-shu-zhai-lu/</guid>
      <pubDate>Sat, 29 Feb 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;&lt;em&gt;剧透警告&lt;/em&gt;&lt;/p&gt;
&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><em>剧透警告</em></p><h1 id="前言">1&emsp;前言</h1><p>最近试着休息时尽量多看点杂书，不知不觉已经看完几本了。中文偏向于读一些引发人思考类型的，日文和英文因为读起来比较费劲还是读轻小说这种书有意思，不然根本读不下去。  </p><p>看完的第一本是<a href="https://zh.wikipedia.org/zh-hans/%E4%B9%94%E6%B2%BB%C2%B7%E5%A5%A5%E5%A8%81%E5%B0%94" target="_blank" rel="noopener">George Orwell</a>的名作之一：<a href="https://book.douban.com/subject/4820710/" target="_blank" rel="noopener">《1984》</a><br>好像有挺多中译版，我随便下载了个花城出版社的，掏出我吃灰许久的<em>乞丐版 Kindle</em> ，边看边做了些标注，后来发现好像可以导出kindle的摘录，试了下感觉还不错。<br>…于是就诞生了这篇《1984》个人摘录；读完感受很多，但感觉没太多想说的，正如温斯顿在读那本奥勃良给的<em>果尔德施坦因的书</em> 时的感受。<br>偶然在日亚里看到<em>1984日本語新訳版</em>，翻了下评论感觉很有趣，感觉里面的句子用日语表达也挺好的，比如我觉得“哎呦还不错”的一句：  </p><blockquote><p>「彼女は理解しなかった──幸福などというものは存在しないこと、唯一の勝利は自分たちが死んでからずっと先のはるか未来にしかないこと、党に宣戦布告した瞬間から自分は死人だと考えるべきだということを。」</p></blockquote><h1 id="摘录">2&emsp;摘录</h1><p>每条摘录下面随便瞎bb几句，免得一大片绿油油的。<br><br><br></p><blockquote><p>只有思想警察会读他写的东西，然后把它从存在中和记忆中除掉。你自己，甚至在一张纸上写的一句匿名的话尚且没有痕迹存留，你怎么能够向未来呼吁呢？</p></blockquote><ul><li>刚开始读的时候不以为然，到后面才体会到电幕和思想警察真是无处不在，就像里面常出现的一句台词：”Big brother is watching you!”</li></ul><blockquote><p>但是这种知识存在于什么地方呢 ? 只存在于他自己的意识之中，而他的意识反正很快就要被消灭的。如果别人都相信党说的谎话 – 如果所有记录都这么说 – 那么这个谎言就载入历史而成为真理。党的一句口号说， “ 谁控制过去就控制未来；谁控制现在就控制过去。 “ 虽然从其性质来说，过去是可以改变的，但是却从来没有改变过。凡是现在是正确的东西，永远也是正确的。这很简单。所需要的只是一而再再而三，无休无止地克服你自己的记忆。他们把这叫做 “ 现实控制 “ ；用新话来说是 “ 双重思想 “ 。</p></blockquote><ul><li>双重思想是1984里的世界很有意思的一个东西…这句党的口号也很有意思，在<a href="https://www.zhihu.com/question/34606774" target="_blank" rel="noopener">知乎</a>上也有相应讨论。<strong>我的理解</strong>：</li></ul><p><strong>控制过去</strong>即统治阶级对历史“稍作修改”，以便巩固自身位置，自然就“控制了未来”； 而<strong>控制现在</strong>我觉得说的是统治者利用权力消灭那些质疑自身、追寻真相的人，让他们发不了声，剩下的则是接受了自己建构的历史观、世界观的大众，从而真正做到控制过去。<br>总而言之，<strong>控制未来是最终目的，手段是控制过去，控制现在是为了保障这一手段的有效性。</strong></p><blockquote><p>如果除了你自己的记忆以外不存在任何记录，那你怎么能够确定哪怕是最明显的事实呢 ?</p></blockquote><ul><li>过去不但被改变了，而且被实际毁掉了。</li></ul><blockquote><p>全部历史都象一张不断刮干净重写的羊皮纸。这一工作完成以后，无论如何都无法证明曾经发生过伪造历史的事。</p></blockquote><ul><li>这段是描述温斯顿在部内的工作。</li></ul><blockquote><p>事实上这连伪造都谈不上。这不过是用一个谎话来代替另一个谎话。你所处理的大部分材料与实际世界里的任何东西都没有关系，甚至连赤裸裸的谎言中所具备的那种关系也没有。原来的统计数字固然荒诞不经，改正以后也同样荒诞不经。</p></blockquote><ul><li>结合现实发生的一些事之后再看这句话显得格外讽刺。</li></ul><blockquote><p>很多时候都是要你凭空瞎编出来的。比如，富裕部预测本季度鞋子的产量是一亿四千五百万双。至于实际产量提出来的数字，是六千二百万双。但是温斯顿在重新改写预测时把数字减到五千七百万双，以便可以象通常那样声称超额完成了计划。反正，六千二百万并不比五千七百万更接近实际情况，也不比一亿四千五百万更接近实际情况。</p></blockquote><ul><li>真相有时候还真是难得一见。</li></ul><blockquote><p>很可能一双鞋子也没有生产。更可能的是，没有人知道究竟生产了多少双，更没有人关心这件事。你所知道的只是，每个季度在纸面都生产了天文数字的鞋子，但是大洋国里却有近一半的人口打赤脚。每种事实的纪录都是这样，不论大小。一切都消隐在一个影子世界里，最后甚至连今年是哪一年都弄不清了。</p></blockquote><ul><li>没有人关心这件事暗示每个人都几乎心知肚明这些报道全是胡编乱造的？</li></ul><blockquote><p>最后我们要使得大家在实际上不可能犯任何思想罪，因为将来没有词汇可以表达。凡是有必要使用的概念，都只有一个词来表达，意义受到严格限制，一切附带含意都被消除忘掉。</p></blockquote><ul><li>从语言词汇上入手感觉难度有点高，并且没有词汇表达也可以通过如行动、表情神态等其他方面来表现出一个人的思想，该犯的还是犯。</li></ul><blockquote><p>温斯顿看着那张没有眼睛的脸上的嘴巴忙个不停在一张一合，心中有一种奇怪的感觉，觉得这不是一个真正的人，而是一种假人。说话的不是那个人的脑子，而是他的喉头。说出来的东西虽然是用词儿组成的，但不是真正的话，而是在无意识状态中发出来的闹声，象鸭子呱呱叫一样。</p></blockquote><ul><li>这里描述的是一位相信英社和老大哥的“正统思想”外围党员。</li></ul><blockquote><p>无产者和牲口都是自由的。</p></blockquote><ul><li>1984中很多条条框框都是只对核心党员和外围党员适用，而对普通无产者则是无所谓；这些无产者们是很“自由”的，尽管这种“自由”十分廉价。<br>我认为这也是那句著名的口号：<strong>战争即和平，自由即奴役，无知即力量</strong>中，为何自由在前奴役在后的原因。</li></ul><blockquote><p>他忽然觉得现代生活中真正典型的一件事情倒不在于它的残酷无情、没有保障，而是简单枯燥、暗淡无光、兴致索然。</p></blockquote><ul><li>个个是骁勇的战士和狂热的信徒，团结一致地前进，大家思想一致、口号一致。</li></ul><blockquote><p>电幕日以继夜地在你的耳边聒噪着一些统计数字，证明今天人们比五十年前吃得好，穿得暖，住得宽敞，玩得痛快 – 他们比五十年前活得长寿，工作时间比五十年前短，身体比五十年前高大、健康、强壮，日子比五十年前过得快活，人比五十年前聪明，受到教育比五十年前多。但没有一句话可以证明是对的或者是不对的。</p></blockquote><ul><li>一切都消失在迷雾中，过去给抹掉了，而抹掉本身也被遗忘。</li></ul><blockquote><p>四月的芬芳空气引诱了他。蓝色的天空是他今年以来第一次看到比较有些暖意，于是突然之间，他觉得在中心站度过这个喧闹冗长的夜晚，玩那些令人厌倦吃力的游戏，听那些报告讲话，靠杜松子酒维持勉强的同志关系，都教他无法忍受了。</p></blockquote><ul><li>然后温斯顿漫步走进了无产者人来人往的伦敦街道。</li></ul><blockquote><p>这是一种伪装。小地方你如果守规矩，大地方你就能打破规矩。</p></blockquote><ul><li>让我想到日语里的一句ことわざ： <strong>肉を切らせて骨を切る</strong></li></ul><blockquote><p>“ 我们是死者， “ 他说。</p></blockquote><ul><li>这句话在后面也出现过几次，第一次时裘莉亚回答：“我们还没有死”，后面那次她的回答变成了乖乖附和。</li></ul><blockquote><p>他闭上眼睛躺着，仍浸沉在梦境中的气氛里。这是一场光亮夺目、场面很大的梦，他的整个一生，好象夏日傍晚雨后的景色一样，展现在他的前面。这都是在那玻璃镇纸里面发生的，玻璃的表面成了苍穹，苍穹之下，什么东西都充满了柔和的清澈的光芒，一望无际。</p></blockquote><ul><li>他们俩在爱的小屋惬意地生活那段短暂的时光，温斯顿躺在床上思考着人生，并回想起他的母亲和他的童年。</li></ul><blockquote><p>“ 还有几分钟你就须要走了， “ 奥勃良说， “ 我们以后再见 – 要是有机会再见的话 - -“ 温斯顿抬头看他。 “ 在没有黑暗的地方 ?” 他迟疑地问。</p></blockquote><ul><li>那只怕是没机会再见了（小声bb）</li></ul><blockquote><p>战争的基本行为就是毁灭，不一定是毁灭人的生命，而是毁灭人类的劳动产品。有些物资原来会使得群众生活得太舒服了，因而从长期来说，也会使得他们太聪明了，战争就是要把这些物资打得粉碎，化为轻烟，沉入海底</p></blockquote><ul><li>毁灭人类的劳动产品的手段大概有千万种</li></ul><blockquote><p>战争计划总是以在满足了本国人口最低需要后把可能剩余的物资耗尽为度</p></blockquote><ul><li>这应该说使1984构造的世界中战争存在的意义</li></ul><blockquote><p>如果他有机会接触外国人，他就会发现外国人同他自己一样也是人，他所听到的关于外国人的话大部分都是谎言。他所生活的封闭天地就会打破，他的精神所依的恐惧、仇恨、自以为是就会化为乌有。</p></blockquote><ul><li>对我来说接触到的信息源越多越好，不论真假；但一个人大脑的处理量是有限的，也难免会有一些偏见</li></ul><blockquote><p>上等人的目标是要保持他们的地位。中等人的目标是要同高等人交换地位。下等人的特点始终是，他们劳苦之余无暇旁顾，偶而才顾到日常生活以外的事，因此他们如果有目标的话，无非是取消一切差别，建立一个人人平等的社会。</p></blockquote><ul><li>作者将社会中的人分为这三类的观点挺有意思。</li></ul><blockquote><p>从即将夺得权力的那批人的观点来看，人类平等不再是要争取实现的理想，而是要避免的危险。</p></blockquote><ul><li>显而易见，多数人是利益驱动型，没理由不去尽力维护现有的利益。</li></ul><blockquote><p>说真的，只要不给他们比较的标淮，他们从来不会意识到自己受压迫。</p></blockquote><ul><li>即使有比较的标准有时候也不会觉得自己受压迫，比如美丽新世界中Beta会觉得“幸好自己不是Alpha”，而Alpha也会认为“自己是Alpha真是太好了”；只要人们的欲望、需求得到了满足。</li></ul><blockquote><p>简单乏味的生活所产生的不满，被有意识地引导到向外发泄出来，消失在两分钟仇恨这样的花样上。</p></blockquote><ul><li><strong>仇恨言论引导</strong>是巩固政权、转移内部矛盾屡试不爽的好工具。</li></ul><blockquote><p>全世界到处都是一样，几亿，几十亿的人，都不知彼此的存在，被仇恨和谎言的高墙隔开，但几乎是完全一样的人</p></blockquote><ul><li>和前面那段对外国人的论述观点一致。</li></ul><blockquote><p>没有人会为了废除权力而夺取权力。权力不是手段，权力是目的。</p></blockquote><blockquote><p>建立专政不是为了保卫革命；反过来进行革命是为了建立专政。迫害的目的是迫害。拷打的目的是拷打。权力的目的是权力</p></blockquote><ul><li>在很多人眼里权力是一种手段，但作者认为权力就是目的。</li></ul><blockquote><p>你必须明白的第一件事情是，权力是集体的。个人只是在停止作为个人的时候才有权力。你知道党的口号‘自由即奴役 ‘ 。你有没有想到过这句口号是可以颠倒过来的 ? 奴役即自由。一个人在单独和自由的时候总是要被打败的。所以必然如此，是因为人都必死，这是最大的失败。但是如果他能完全绝对服从，如果他能摆脱个人存在，如果他能与党打成一片而做到他就是党，党就是他，那么他就是全能的、永远不朽。</p></blockquote><ul><li>那么个人也可以假装被奴役同时利用集体的权力来得到属于自己的自由与利益。</li></ul><blockquote><p>所谓权力乃是对人的权力，是对身体，尤其是对思想的权力，对物质 – 你们所说的外部现实 – 的权力并不重要。</p></blockquote><ul><li>但通过物质能明显体现出这种权力。</li></ul><blockquote><p>那么，你是不是开始明白我们要创建的是怎样一种世界？这种世界与老派改革家所设想的那种愚蠢的、享乐主义的乌托邦正好相反。这是一个恐惧、叛卖、折磨的世界，一个践踏和被践踏的世界，一个在臻于完善的过程中越来越无情的世界。我们这个世界里，所谓进步就是朝向越来越多痛苦的进步。</p></blockquote><ul><li>反乌托邦，虚弱空洞的精神世界。</li></ul><blockquote><p>以前的各种文明以建筑在博爱和正义上相标榜。我们建筑在仇恨上。在我们的世界里，除了恐惧、狂怒、得意、自贬以外，没有别的感情。其他一切都要摧毁。我们现在已经摧毁了革命前遗留下来的思想习惯。我们割断了子女与父母、人与人、男人与女人之间的联系；没有人再敢信任妻子、儿女、朋友。而且在将来，不再有妻子或朋友。子女一生下来就要脱离母亲，好象蛋一生下来就从母鸡身边取走一样、性的本能要消除掉。生殖的事要弄得象发配给证一样成为一年一度的手续形式。我们要消灭掉性的快感。我们的神经病学家正在研究这个问题。除了对党忠诚以外，没有其他忠诚。除了爱老大哥以外，没有其他的爱。除了因打败敌人而笑以外，没有其他的笑。不再有艺术，不再有文学，不再有科学。我们达到万能以后就不需要科学了。美与丑中再有区别。不再有好奇心，不再有生命过程的应用。一切其他乐趣都要消灭掉</p></blockquote><ul><li>和美丽新世界中对本能的放纵恰恰相反，但思想上好像却差不多。</li></ul><blockquote><p>但是，温斯顿，请你不要忘了，对于权力的沉醉，却永远存在，而且不断地增长，不断地越来越细腻。每时每刻，永远有胜利的欢悦，践踏束手待毙的敌人的快感。如果你要设想一幅未来的图景，就想象一只脚踩在一张人脸上好了 – 永远如此。 “</p></blockquote><blockquote><p>那张脸永远在那里给你践踏。异端分子、社会公敌永远在那里，可以一而再再而三地打败他们，羞辱他们。你落到我们手中以后所经历的一切，会永远继续下去，而且只有更厉害。间谍活动、叛党卖国、逮捕拷打、处决灭迹，这种事情永远不会完。这个世界不仅是个胜利的世界，也同样是个恐怖的世界。党越有力量，就越不能容忍；反对力量越弱，专制暴政就越严。</p></blockquote><ul><li>永远不会结束。</li></ul><blockquote><p>“ 有时候， “ 她说， “ 他们用什么东西来威胁你，这东西你无法忍受，而且想都不能想。于是你就说，‘别这样对我，对别人去，对某某人去。 ‘ 后来你也许可以伪装这不过是一种计策，这么说是为了使他们停下来，真的意思并不是这样。但是这不对。当时你说的真是这个意思。你认为没有别的办法可以救你，因此你很愿意用这个办法来救自已。你真的愿意这事发生在另外一个人身上。他受得了受不了，你根本不在乎。你关心的只是你自己。 “</p></blockquote><ul><li>裘莉亚对彼此出卖对方行为的描述。</li></ul><blockquote><p>他抬头看着那张庞大的脸。他花了四十年的功夫才知道那黑色的大胡子后面的笑容是什么样的笑容。哦，残酷的、没有必要的误会！哦，背离慈爱胸怀的顽固不化的流亡者！他鼻梁两侧流下了带着酒气的泪。但是没有事，一切都很好，斗争已经结束了。他战胜了自己。他热爱老大哥。</p></blockquote><ul><li>思想陷入“歧途”的人最终总算能够带着干干净净的思想死去，“像肥皂泡一样漂浮在空中”。</li></ul><h1 id="感受">3&emsp;感受</h1><p>后半段剧情我是没想到，甚至还和温斯顿一样天真的以为奥勃良是兄弟会的，兄弟会是存在的…最后那段也挺棒，正奇怪为什么前一页还在101室被“教育”后一页就坐在咖啡馆喝起了杜松子酒，看到最后才恍然大悟。<br>中间那段在店铺楼上简陋小屋的生活还是蛮惬意的，但当背后那个冷酷的声音响起、当原来挂画片的位置露出来那个电幕的时候，一切都结束了。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-02-29-1984-ge-ren-du-shu-zhai-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>用八爪鱼采集器爬取COMSOL培训视频</title>
      <link>https://chengpengzhao.com/2020-02-16-yong-ba-zhua-yu-cai-ji-qi-pa-qu-comsol-pei-xun-shi-pin/</link>
      <guid>https://chengpengzhao.com/2020-02-16-yong-ba-zhua-yu-cai-ji-qi-pa-qu-comsol-pei-xun-shi-pin/</guid>
      <pubDate>Sun, 16 Feb 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;整理邮件垃圾箱时偶然发现
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>整理邮件垃圾箱时偶然发现COMSOL（多物理场仿真软件）中国给我发了条有用的信息：</p><pre><code>COMSOL 用户，您好！新型冠状病毒肺炎的疫情仍在持续，在疫情期间，COMSOL 中国将向所有注册用户免费开放 15 个专题，共计 160 小时的视频培训资料，供大家观看学习。此次开放的培训视频包含基础理论讲解、案例演示，以及课后答疑等内容。点击以下链接，登入后即可观看：https://cn.comsol.com/video-training</code></pre><p>看到这样的白嫖机会怎能不心动？立马打开网页准备下载，发现一个个下载实在过于繁琐，看来这又是一个给我练习爬虫的机会。<br>事不宜迟，打开Pycharm，首先用Python轻松获得了所有第一层链接；但随后发现内部的视频加载比较难处理。虽然网页上能够获取到视频链接，python里即使用上Cookies登录也无法得到最后加载完成后的html，应该是对方网站采用了ajax或者其他异步加载策略吧。<br>本来考虑下一步用python模拟浏览器登录的，但之前没写过相关代码，感觉挺耗时就放弃了。想到之前好像听说有几个爬虫软件很好用，于是下了一个试用下，果然没让我失望。</p><h1 id="八爪鱼采集流程">2&emsp;八爪鱼采集流程</h1><h2 id="简介">2.1&emsp;简介</h2><p><a href="https://www.bazhuayu.com/about" target="_blank" rel="noopener">八爪鱼</a>据说是用C#写的，基于Firefox内核浏览器，通过模拟人浏览网页的行为（如打开网页，点击网页中的某个按钮等操作），对网页内容进行全自动提取。  </p><p>我用下来总的感觉就是：  </p><ol><li>“傻瓜式”，基本上不需要什么教程就可以进行简单页面的爬取</li><li>思路非常清晰，每一步该做什么、会得到什么样的结果，都能很直观地从界面里看到</li><li>效率高；如果不是经常和爬虫打交道，写代码花费的时间将远超用软件爬取</li><li>上限够用；比如可以通过cookies模拟登录、自动翻页、xpath定位…足够满足像我这样没有太高要求的用户</li></ol><h2 id="实操">2.2&emsp;实操</h2><h3 id="获取每个部分的URL">2.2.1&emsp;获取每个部分的URL</h3><p>首先打开八爪鱼采集器，新建自定义任务，地址输入<a href="https://cn.comsol.com/video-training" target="_blank" rel="noopener">https://cn.comsol.com/video-training</a>。在界面下方的浏览器窗口中点击相应按钮，程序会自动帮我们选取相同tag的元素；<br>这里我创建一个<code>循环点击每个链接</code>的循环，来依次进入每个在线播放视频的界面并保存相应的视频下载地址及介绍信息。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216213150.webp" alt></p><h3 id="模拟登录">2.2.2&emsp;模拟登录</h3><p>发现没有登录是无法进入视频在线播放界面的，这里采用cookies模拟登录的方法：首先在浏览器里登录，调出开发者工具找到当前发出请求用的cookies，直接粘贴到采集器相应栏中。  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216213527.webp" alt><br><br><br>刷新页面后发现已经变成登录后的界面~</p><h3 id="获取视频下载链接">2.2.3&emsp;获取视频下载链接</h3><p>点击浏览器中视频部分，观察智能提示中提取到的字段，惊喜地发现其中含有正确的下载链接；但八爪鱼采集器不方便直接下载这种大文件，这里选择只导出链接及课程介绍性文字。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216214041.webp" alt></p><h3 id="采集并导出数据">2.2.4&emsp;采集并导出数据</h3><p>确认流程没有问题之后就可以开始本地采集了，我第一次采集的时候由于两个步骤的间隔时间设的太短导致网页还没加载出来就进入了下一个循环；稍作修改第二次就采集成功了。<br>选择CSV格式导出数据（还支持Excel和html格式）~</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216214922.webp" alt></p><h2 id="后续步骤">2.3&emsp;后续步骤</h2><p>下载大文件当然是用IDM神器，把数据文本全部粘贴到剪切板，IDM就能识别并下载其中所有的链接。<br>（我的宿舍网络环境下载速度竟然达到了40M/s，着实惊到我了）</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216215210.webp" alt></p><p>可以看到下载下来的视频文件名是乱的，这个好解决：根据CSV字典编一个重命名的小程序就行了，也就几分钟的事。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216215321.webp" alt></p><h1 id="总结">3&emsp;总结</h1><p>演示的只是个很简单的小例子，数据量也不大，用八爪鱼这类采集软件能够很快的完成任务；但对于一些大型任务而言，用模拟浏览器的行为来爬取的效率是很低的。<br>比如我趁<strong>科学文库免费</strong>这段时间爬取所有书籍下载链接：（花了3个小时才爬了1万多条）</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200216220521.webp" alt><br><br></p><p>不过我没那么大的数据量需求，所以可能今后会更偏向于使用这种软件来快速完成数据的获取。毕竟写程序的话改一个bug的时间都够我用八爪鱼爬一遍了。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-02-16-yong-ba-zhua-yu-cai-ji-qi-pa-qu-comsol-pei-xun-shi-pin/#disqus_thread</comments>
    </item>
    
    <item>
      <title>折腾下闲置的VPS，部署Bitwarden_rs和sharelist</title>
      <link>https://chengpengzhao.com/2020-02-08-bitwarden-mi-ma-guan-li-ji-sharelist-da-jian/</link>
      <guid>https://chengpengzhao.com/2020-02-08-bitwarden-mi-ma-guan-li-ji-sharelist-da-jian/</guid>
      <pubDate>Tue, 11 Feb 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;折腾下闲置的VPS&quot;&gt;1&amp;emsp;折腾下闲置的VPS&lt;/h1&gt;&lt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="折腾下闲置的VPS">1&emsp;折腾下闲置的VPS</h1><p>本科时同学推荐搬瓦工的VPS，当然那时我连VPS是什么都不知道，听说能够翻过围墙所以就买了。对Linux一窍不通的我在曾经的doubi根据地上的文章指引下，也能够搭建一个比较舒服的上网环境，当时感到十分愉快（用的当然是那些一键脚本）。<br>过了一年除了IP被封过两次、换了几个机房、换了几个一键脚本以外，倒也还没觉得有啥不满；毕竟如果是买市面上那些服务每个月的钱也差不多。<br>人总是在不断学习进步的，我总算学会了一些linux基本操作，可以用XShell登一登我的VPS没事<code>ls</code>一下。但看到大佬们用自己的VPS搭各种服务器到时候，还是非常羡慕的，于是忍不住也尝试下，顺便学习下后端相关知识。<br><br></p><p>由于时间有限，以能用为唯一目的，多余的知识没时间更没必要去掌握（毕竟专业和这个毫不相关），操作全部记录在这方便以后换VPS时再搭一遍。</p><h1 id="Bitwarden-rs部署">2&emsp;Bitwarden_rs部署</h1><h2 id="前言">2.1&emsp;前言</h2><p>好用的密码管理软件之一，<code>_rs</code>版本相对于官方版精简了不少，部署也比较简单。网上大多数bitwarden_rs部署教程的文章我基本上都过了一遍，我遇到的主要问题有：</p><ol><li>部署后用Chrome浏览器无法登录与注册账号，IOS系统无法登录 (——后确定为<strong>未用https</strong>的原因)  </li><li>网上关于申请https这部分往往一笔带过，什么Nginx反向代理啦….看得我这样的零基础玩家云里雾里。  </li></ol><p>结果大量时间都花在如何启用https上了，真让人头大。</p><h2 id="步骤">2.2&emsp;步骤</h2><h3 id="VPS初始配置">2.2.1&emsp;VPS初始配置</h3><p>经过几次重装OS后学乖了，把初始配置做成一个脚本。 </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> -i<span class="token function">apt-get</span> <span class="token function">install</span> curl -y<span class="token function">apt-get</span> <span class="token function">install</span> <span class="token function">git</span> -y<span class="token function">apt-get</span> <span class="token function">install</span> vim -y<span class="token comment" spellcheck="true">#=========================</span><span class="token comment" spellcheck="true">#Vim配置</span>curl -fLo ~/.vim/autoload/plug.vim --create-dirs \    https://cdn.jsdelivr.net/gh/junegunn/vim-plug/plug.vim<span class="token comment" spellcheck="true">#=========================</span><span class="token function">git</span> clone https://github.com/chengpengzhao/My_vimrc.git<span class="token function">cd</span> My_vimrc<span class="token function">git</span> checkout dev-WSL<span class="token function">cp</span> ./<span class="token string">'.vimrc(ssh)'</span> ~/.vimrc<span class="token comment" spellcheck="true">#=========================</span><span class="token comment" spellcheck="true">#安装Docker、docker-compose</span><span class="token function">sudo</span> curl -fsSL https://get.docker.com <span class="token operator">|</span> <span class="token function">bash</span> -s docker --mirror Aliyun<span class="token function">sudo</span> curl -L <span class="token string">"https://github.com/docker/compose/releases/download/1.24.0/docker-compose-<span class="token variable"><span class="token variable">$(</span><span class="token function">uname</span> -s<span class="token variable">)</span></span>-<span class="token variable"><span class="token variable">$(</span><span class="token function">uname</span> -m<span class="token variable">)</span></span>"</span> -o /usr/local/bin/docker-compose<span class="token function">sudo</span> <span class="token function">chmod</span> +x /usr/local/bin/docker-composesystemctl start dockersystemctl <span class="token function">enable</span> docker<span class="token comment" spellcheck="true">#=========================</span><span class="token comment" spellcheck="true"># 安装acme.sh</span><span class="token function">apt-get</span> <span class="token function">install</span> <span class="token function">cron</span> socat -ycurl https://get.acme.sh <span class="token operator">|</span> sh<span class="token function">source</span> ~/.bashrc<span class="token function">export</span> Namesilo_Key<span class="token operator">=</span><span class="token string">"xxxxxxxxxxxxx"</span>（我的域名提供商）apt <span class="token function">install</span> firewalld -yfirewall-cmd --permanent --add-service<span class="token operator">=</span>http firewall-cmd --permanent --add-service<span class="token operator">=</span>https firewall-cmd --reload <span class="token function">service</span> docker restart<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>步骤因人而异，大致都差不多。</p><h3 id="一般部署">2.2.2&emsp;一般部署</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">mkdir</span> -p /opt/bitwarden <span class="token operator">&amp;&amp;</span> <span class="token function">cd</span> /opt/bitwarden<span class="token function">cat</span> <span class="token operator">>></span> docker-compose.yml <span class="token operator">&lt;&lt;</span> <span class="token string">EOFversion: "3"services:  bitwarden:    image: bitwardenrs/server    restart: always    ports:    - "8080:80"    - "8081:3012"    volumes:      - ./bw-data:/data    environment:      WEBSOCKET_ENABLED: "true"      SIGNUPS_ALLOWED: "true"      WEB_VAULT_ENABLED: "true"EOF</span>docker-compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>端口相关知识我真的一窍不通…反正能用<code>ip:8081</code>访问就行。</p><h3 id="启用https">2.2.3&emsp;启用https</h3><p>稀里糊涂的装了个acme.sh脚本、在NameSilo申请了个API key；</p><pre class="line-numbers language-bash"><code class="language-bash">acme.sh --issue --dns dns_namesilo --dnssleep 900 -d my_domain_name.com<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>看到没有报错的时候真的松了口气，然而证书是申请了，怎么绑到之前的bitwarden_rs的domain里我还是不会。<br>后面发现<a href="https://chengpengzhao.com/files_store/%E5%BC%80%E6%BA%90%E5%AF%86%E7%A0%81%E7%AE%A1%E7%90%86%E5%99%A8%EF%BC%9ABitwarden_rs%20%E7%AC%AC%E4%B8%89%E6%96%B9%E7%89%88%E6%9C%AC%E9%83%A8%E7%BD%B2%20-%20%E8%80%81%E5%85%84de%E5%8D%9A%E5%AE%A2%20(2020-02-11%20%E4%B8%8A%E5%8D%889_45_29).html">这篇教程</a>和其他的都有些不一样，于是抱着一丝希望试了下…总算是解决了问题。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cat</span> <span class="token operator">>></span> docker-compose.yml <span class="token operator">&lt;&lt;</span> <span class="token string">EOFversion: "3"services:  bitwarden:    image: bitwardenrs/server    restart: always    volumes:      - ./bw-data:/data    environment:      WEBSOCKET_ENABLED: "true"      SIGNUPS_ALLOWED: "true"  caddy:    image: abiosoft/caddy    restart: always    volumes:      - ./Caddyfile:/etc/Caddyfile:ro      - caddycerts:/root/.caddy    ports:      - 80:80      - 443:443    environment:      ACME_AGREE: "true"       DOMAIN: "bitwarden.koko.cat"      EMAIL: "example@gmail.com"volumes:  caddycerts:EOF</span><span class="token function">cat</span> <span class="token operator">>></span> Caddyfile <span class="token operator">&lt;&lt;</span> <span class="token string">EOF{<span class="token variable">$DOMAIN</span>} {    tls {<span class="token variable">$EMAIL</span>}    header / {        Strict-Transport-Security "max-age=31536000;"        X-XSS-Protection "1; mode=block"        X-Frame-Options "DENY"    }    proxy /notifications/hub/negotiate bitwarden:80 {        transparent    }    # Notifications redirected to the websockets server    proxy /notifications/hub bitwarden:3012 {        websocket    }    # Proxy the Root directory to Rocket    proxy / bitwarden:80 {        transparent    }}EOF</span>docker-compose down <span class="token operator">&amp;&amp;</span> docker-compose up -d<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="定时备份">2.2.4&emsp;定时备份</h3><p>直接用github备份算了，或者定时手动导出到你觉得安全的位置。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~ssh-keygen -t rsa<span class="token function">cat</span> ~/.ssh/id_rsa.pub<span class="token comment" spellcheck="true">#之后在github上导入，新建私人repository</span><span class="token function">cd</span> /opt/bitwarden/bw-data<span class="token function">git</span> init<span class="token function">git</span> remote add origin git@github.com:xxxx/xxxx.git<span class="token function">git</span> add -A<span class="token function">git</span> commit -m <span class="token string">"first push"</span><span class="token function">git</span> push -u origin master<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>建立脚本并定时运行：  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~<span class="token function">cat</span> <span class="token operator">>></span> backup.sh <span class="token operator">&lt;&lt;</span> <span class="token string">EOF#!/bin/bashdate=<span class="token variable"><span class="token variable">$(</span><span class="token function">date</span> '+%Y-%m-%d %H:%M'<span class="token variable">)</span></span>cd /opt/bitwarden/bw-datagit add -Agit commit -m "backup at <span class="token variable">$date</span>"git pushEOF</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>bash ~/gitback.sh</code>试运行，设置定时任务</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token keyword">echo</span> <span class="token string">"15 05 * * * bash ~/gitback.sh > ~/siteback.log 2>&amp;1 &amp;"</span> <span class="token operator">></span> bt.cron<span class="token function">crontab</span> bt.cron<span class="token function">rm</span> -rf bt.cron<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>自动备份部分白嫖的<a href="https://www.moerats.com/archives/858/" target="_blank" rel="noopener">Rat’s Blog</a>。<br>查看定时任务可通过<code>crontab -l</code></p><h1 id="Sharelist分享云盘">3&emsp;Sharelist分享云盘</h1><p><a href="https://github.com/reruin/sharelist" target="_blank" rel="noopener">项目地址</a><br>这个搭起来就简单多了，dockerr都给你准备好了，只需要注意安装完成后配置云盘可能比较复杂；我选用的是<strong>链接分享</strong>的方式，可以自己指定文件夹且不需要获取API之类的复杂操作。  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">wget</span> --no-check-certificate -qO-  https://cdn.jsdelivr.net/gh/reruin/sharelist/netinstall.sh <span class="token operator">|</span> <span class="token function">bash</span><span class="token function">cd</span> sharelistdocker-compose up<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p><br><br></p><blockquote><p><em>以下内容更新于2020-06-23 13:48:33</em></p></blockquote><h1 id="更新：加入Nginx学习与使用-（推荐从这部分看起）">4&emsp;更新：加入Nginx学习与使用 （推荐从这部分看起）</h1><p>之前配置好的bitwarden用了几个月，昨天忽然发现移动端没法同步了，因为刚开始配置的时候就出现过这个问题所以一下子就定位到是<strong>https</strong>的问题。ping了一下域名竟然没ping通，不知道又是不是DNS服务器抽风了。正好对<code>namesilo</code>不太了解，干脆直接把域名转移到了<code>cloudflare</code>下。选择<code>cloudflare</code>是因为它的种种优点，而且设置起来比较方便。</p><h2 id="namesilo域名转移到cloudflare">4.1&emsp;namesilo域名转移到cloudflare</h2><ol><li>在<code>cloudflare</code>中添加要转移的域名，在<code>namesilo</code>中将DNS解析改为<code>cloudflare</code>（会提示你怎么做）。  </li><li><code>cloudflare</code>里要有付款方式；我之前已经用过很久<code>cloudflare</code>了，所以这步略过。</li><li>在<code>namesilo</code>里将域名解锁（unlock图标），之后在<code>cloudflare</code>中申请转移，会要求输入一个授权码；</li><li><code>namesilo</code>里找到<code>send email</code>，授权码会发到邮箱里，在<code>cloudflare</code>输入后会提示正在转移中（这步会付款）。</li><li>过一会儿<code>namesilo</code>会再发邮件提示正在转移域名，点进相关网址可以立即通过转移（省时间）。</li></ol><h2 id="cloudflare的ssl-tls设置">4.2&emsp;cloudflare的ssl-tls设置</h2><p>一般将加密模式设置为<strong>完全</strong>（<code>cloudflare</code>前一阵子出了简体中文版网页，更香了有没有），之后再到源服务器选项下创建源证书，之后要放到VPS上的。（我直接创了个15年有效期的），将公钥和私钥保存为<code>cert.pem</code>和<code>cert.key</code>。  </p><h2 id="cloudflare的DNS设置">4.3&emsp;cloudflare的DNS设置</h2><p>虽然对这些方面一窍不通，但在用的过程中还是有点心得之类的东西：<br>比如在解析像<code>Github Page</code>这种时可以只用<code>CNAME</code>记录，而在解析<code>ip地址</code>时一般只用<code>A</code>记录就行了。另外通常会设置多条记录，一条给根域名(@表示或直接输入完整域名)、另一条给<code>www</code>（名称）的前缀，之后可以根据喜好随便加几条（如<code>0</code>、<code>000</code>…）。<br>这些记录的内容都是指向同一个<code>ip地址</code>、即VPS的ip，在没有用<code>Nginx</code>配置时，无论是用<code>www.yoursite</code>还是<code>yoursite</code>、<code>0.yoursite</code>、<code>000.yoursitez</code>访问，页面应该都是相同的。</p><h2 id="VPS上启动docker-compose容器">4.4&emsp;VPS上启动docker-compose容器</h2><p>先以bitwarden为例讲下吧：</p><ol><li><p>去网上学习下常用的几个命令如<code>docker ps</code>、<code>docker-compose down &amp;&amp; docker-compose up -d</code>、<code>docker-compose restart</code>，大概了解下怎么使用；</p></li><li><p>按照<a href="#toc-heading-6">一般部署</a>这部分创建好<code>docker-compose.yml</code>文件，这里<code>8080</code>和<code>8081</code>可以改成别的，后面访问网页就是通过8080端口。</p></li><li><p>部署成功后用<code>docker ps</code>应该能看到运行状态，并且通过<code>VPS的ip地址:8080</code>的方式能够访问bitwarden网页，这时已经完成了一大半。（浏览器会提示<em>不安全</em>，因为还没有SSL证书）</p></li><li><p>最后用<code>Nginx</code>将<code>VPS的ip地址:8080</code>和<code>准备好的域名</code>“绑在一起”就好了。</p></li></ol><h2 id="Nginx学习与使用">4.5&emsp;Nginx学习与使用</h2><p>之前看别人教程的时候都是“接下来用Nginx弄个反代…完”、这种节奏，看来是默认大家都会<code>Nginx</code>了（哭了出来）。<br>本着<strong>原理可以不弄太懂，关键不影响使用</strong>的懒人态度，直到今天我也终于开始Google搜索<em>Nginx入门</em> 了。</p><ol><li><p>安装，想当然的输入 <code>sudo apt-get install nginx</code> ，嗯？能行，好、下一步。</p></li><li><p>命令，检测配置<code>nginx -t</code>、 重载配置<code>nginx -s reload</code>、启动<code>nginx</code>，暂时先记这几个了。</p></li><li><p>文件位置，输入<code>whereis nginx</code>查一查再说；  </p><ul><li>噢? <code>/usr/share/nginx</code>目录下放有个html目录，打开<code>VPS的ip地址</code>显示的<code>Welcome to nginx!</code>原来就是这个<code>index.html</code>。  </li><li><code>/etc/nginx</code>下的<code>nginx.conf</code>应该就是配置文件了，用<code>vim</code>打开看下吧，里面有一行<code>include /etc/nginx/conf.d/*.conf;</code>，也就是说我在<code>/etc/nginx/conf.d</code>目录下建的<code>.conf</code>文件也会当做配置文件读入。</li></ul></li><li><p>随便到网上找一个配置文件例子，比如我找了个<code>default.conf</code>，放在<code>conf.d</code>目录下的：</p><ul><li>注意这里用到了之前申请的源证书<code>cert.pem</code>和<code>cert.key</code>。  </li><li>从配置文件可以发现可以有多个<code>server</code>，之后我们只需为bitwarden、sharelist等各配置一个server就行了。  </li></ul></li></ol><pre class="line-numbers language-conf"><code class="language-conf">#设定虚拟主机配置server {  #侦听443端口，这个是ssl访问端口  listen    443;  #定义使用 访问域名  server_name  yoursite.com  #定义服务器的默认网站根目录位置,这里的html指的是/usr/share/nginx/html目录  root html;  # 这些都是腾讯云推荐的配置，直接拿来用就行了，只是修改证书的路径，注意这些路径是相对于/etc/nginx  ssl on;  ssl_certificate cert.pem;  ssl_certificate_key cert.key;  ssl_session_timeout 5m;  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      #按照这个协议配置  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置  ssl_prefer_server_ciphers on;  #默认请求  location / {  root html;  index index.html;  }  #静态文件，nginx自己处理  location ~ ^/(images|javascript|js|css|flash|media|static)/ {      #过期30天，静态文件不怎么更新，过期可以设大一点，      #如果频繁更新，则可以设置得小一点。      expires 30d;  }  #禁止访问 .htxxx 文件  #    location ~ /.ht {  #    deny all;  #}}server{  # 80端口是http正常访问的接口  listen 80;  server_name  yoursite.com;  # 在这里，我做了https全加密处理，在访问http的时候自动跳转到https  rewrite ^(.*) https://$host$1 permanent;}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="5"><li>为<code>bitwarden</code>配置server：<br>在<a href="https://github.com/dani-garcia/bitwarden_rs/wiki/Proxy-examples" target="_blank" rel="noopener">Bitwarden_rs的github</a>可以找到相应的例子，只需要粘贴到<code>default.conf</code>上再稍作修改，最后运行<code>nginx -s reload</code>就行了。下面是我的配置：</li></ol><pre class="line-numbers language-conf"><code class="language-conf">server {  listen 443 ssl http2;  server_name  0.yoursite.com;  #这里改成自己的域名，可以加前缀（之前DNS解析了的）  # Specify SSL config if using a shared one.  #include conf.d/ssl/ssl.conf;  # Allow large attachments  client_max_body_size 128M;  location / {    proxy_pass http://127.0.0.1:8080;       #这里8080对应前面的设置，127.0.0.1代表本机ip    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header X-Forwarded-Proto $scheme;  }  location /notifications/hub {    proxy_pass http://127.0.0.1:8081;   #8081对应前面的设置    proxy_set_header Upgrade $http_upgrade;    proxy_set_header Connection "upgrade";  }  location /notifications/hub/negotiate {    proxy_pass http://127.0.0.1:8080;   #8080对应前面的设置  }  # Optionally add extra authentication besides the AUTH_TOKEN  # If you don't want this, leave this part out  location /admin {    # See: https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/    auth_basic "Private";    auth_basic_user_file /path/to/htpasswd_file;    proxy_set_header Host $host;    proxy_set_header X-Real-IP $remote_addr;    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    proxy_set_header X-Forwarded-Proto $scheme;    proxy_pass http://127.0.0.1:8080;   #8080对应前面的设置  }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><ol start="6"><li>顺便附上<code>sharelist</code>的Nginx设置：</li></ol><pre class="line-numbers language-conf"><code class="language-conf">server {  listen 443 ssl http2;  server_name  www.yoursite.com;  # Specify SSL config if using a shared one.  #include conf.d/ssl/ssl.conf;  # Allow large attachments  location / {    proxy_pass http://127.0.0.1:33001;      proxy_set_header Host  $host;      proxy_set_header X-Real-IP $remote_addr;      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;      proxy_set_header X-Forwarded-Proto $scheme;      proxy_set_header Range $http_range;      proxy_set_header If-Range $http_if_range;      proxy_no_cache $http_range $http_if_range;  }}<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-02-08-bitwarden-mi-ma-guan-li-ji-sharelist-da-jian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>开始使用TiddlyWiki个人笔记系统和Gnucash个人财务管理系统</title>
      <link>https://chengpengzhao.com/2020-02-05-kai-shi-shi-yong-tiddlywiki-ge-ren-bi-ji-xi-tong-he-gnucash-ge-ren-cai-wu-guan-li-xi-tong/</link>
      <guid>https://chengpengzhao.com/2020-02-05-kai-shi-shi-yong-tiddlywiki-ge-ren-bi-ji-xi-tong-he-gnucash-ge-ren-cai-wu-guan-li-xi-tong/</guid>
      <pubDate>Wed, 05 Feb 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;最近事情比较多，想看的书
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>最近事情比较多，想看的书、想学的、不得不学的…其中很多都是无意中逛别人博客后发现的，比如财务管理、GTD、如何整理笔记、保险相关知识…  </p><p>我之所以会把这些事的优先级放这么高，<strong>核心目的</strong>还是在于想让自己早点养成习惯，从而提高效率。（不不不，真正原因是现在离最近一个DDL都还有1个多月，不趁此机会做点有意义的事岂不是浪费了宝贵的时间）<br>无论是通过知识、金钱、时间的管理让自己的生活变得有条理、还是通过某个工具使自己的工作能更高效地完成，本质都是围绕如何提高生产力这个话题。之前看过的一个Vim讲座:<a href="https://www.youtube.com/watch?v=eX9m3g5J-XA" target="_blank" rel="noopener">7 Habits For Effective Text Editing </a>里总结的三步感觉很不错：  </p><blockquote><ol><li>Detect inefficiency</li><li>Find a quicker way</li><li>Make it a habit</li></ol></blockquote><p>当然，如果一个工具的学习成本对自己来说过高，那么入坑之前一定要慎重考虑。</p><h1 id="TiddlyWiki">2&emsp;TiddlyWiki</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200205140622.webp" alt></p><p>关于笔记、备忘录的管理，之前一直用的Onenote，其实也还够用（除了不支持markdown）。陆陆续续尝试了Evernote、Notion、Leannote、Gitnote等工具，总觉得哪差了点；算了还是先想一想自己的需求吧：</p><ul><li>安全性，最近开始对个人信息敏感起来了，能本地的绝不随便放到网上、放网上备份的尽量加密；</li><li>功能全，支持Markdown，免费也能用的很舒服；</li><li>跨平台，编辑、查找方便；</li></ul><p>综合这几点我最后选择了Tiddlywiki，原因：</p><ol><li>本质就是一个html文件，备份、转移方便</li><li>也可以放在Github Page里，直接线上编辑保存</li><li>支持加密，放在网上别人也看不了内容</li><li>插件扩展能力较强</li></ol><h2 id="入门">2.1&emsp;入门</h2><p><a href="http://tw5-zh.tiddlyspot.com/" target="_blank" rel="noopener">繁体中文网站</a>翻译的比较全，把目录里的条目过一遍基本上就会了，重点关注<strong>tiddler</strong>这个概念以及<strong>如何建立目录结构</strong>、<strong>如何对条目进行链接和筛选</strong>。<br>插件的安装可以直接在<em>官方插件库</em>里找，但更多的时候是先导出别人页面里安装的插件（如json格式）、然后直接导入自己的Tiddlywiki。</p><h2 id="使用">2.2&emsp;使用</h2><p>首先是页面样式的设置，在控制面板一个个尝试就行，一直改到自己满意。</p><p>TiddlyWiki有它自己的一套类似Markdown的语法，功能挺强，但我平常用用Markdown就够了，所以懒得学。平常使用起来和别的软件没太大区别，没啥好讲的。</p><blockquote><p>插件推荐：</p><ul><li>Adds support of MathJax   ；Markdown必备</li><li>adds the ability to encrypt single tiddlers    ；可以给单个条目加密</li><li>Context search - provides visual highlight of search results  ；针对文章内容的搜索</li><li>Markdown parser   ；Markdown必备</li><li>TW5-EnhancedSearchResults – Show search results in a tab  ；扩展搜索功能</li><li>Checklist Plugin  ；增加 Todolist 支持</li></ul></blockquote><p>没必要花太多时间在配置上面，重点是如何系统地管理知识。</p><h2 id="归档方案">2.3&emsp;归档方案</h2><p>总原则是比较占空间的非文本一律不直接放到Tiddlywiki里，而是通过链接来引用，本体可以放在网盘、github等云储存工具里。</p><ol><li>网页，可通过<a href="https://archive.org/web/" target="_blank" rel="noopener">wayback machine</a>、<a href="http://Archive.is" target="_blank" rel="noopener">Archive.is</a>等进行备份，防止有一天被404。  </li></ol><p>我的做法是通过Chrome右键另存为<a href="https://zh.wikipedia.org/wiki/MHTML" target="_blank" rel="noopener">Mhtml</a>，然后把文件放在GitHub仓库里，在Tiddlywiki里直接引用就行了。  </p><p>这里有一个要注意的地方，<strong>Windows里保存下来的Mhtml为Dos格式，当被转换成Unix格式后将无法正常打开</strong>。所以在上传到GitHub之前一定要确保进行以下设置：（万恶的CRLF换行符）</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> config --global core.autocrlf <span class="token boolean">false</span><span class="token function">git</span> config --global core.filemode <span class="token boolean">false</span><span class="token function">git</span> config --global core.safecrlf <span class="token boolean">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>但这种方法的<strong>缺点</strong>是不能直接在线预览，需要先下载mhtml再打开 ；对于比较简洁的页面可以通过<code>Singlefile</code>这款插件（Chrome和Firefox都有）直接保存单文件html，非常好用。引用GitHub里的html文件链接时在前面加上<code>https://htmlpreview.github.io/?</code>，便可以做到点击直接预览。（或者直接给仓库打开GitHub Page，通过自己的GitHub page链接访问）</p><ol start="2"><li><p>图片，传到GitHub图床</p></li><li><p>其他大文件，Onedrive、GoogleDrive、百度云…</p></li></ol><h1 id="Gnucash">3&emsp;Gnucash</h1><p>都是成年人了，也该有点财务方面的意识了吧。以前一直过着有钱就花、没钱吃土这种无忧无虑的生活，虽说不奢望有朝一日财务自由，但对于了解自己的财务状况、学习基本的投资理财知识来说，养成一个记账的习惯还是很有必要的。  </p><h2 id="基础知识">3.1&emsp;基础知识</h2><ol><li><p>The 5 Basic Accounts:</p><ul><li>Assets: 资产</li><li>Liabilities: 负债</li><li>Equity: 所有者权益</li><li>Income: 收入</li><li>Expenses: 支出</li></ul></li><li><p>The Accounting Equation:</p></li></ol><blockquote><p>Assets - Liabilities = Equity + (Income - Expenses)</p></blockquote><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200205165439.webp" alt></p><p>这个等式是复式记账法（每一笔账都要按规定的会计科目，至少在两个账户上相互联系地进行分类记录）的核心。<br>不过更常看到的是不包括收入和支出部分的等式：</p><blockquote><p>Assets = Liabilities + Equity</p></blockquote><p>它反映了资产来源的两个方面：一个是负债（比如向银行贷款多少钱），另一个是所有者权益（说实话我没学过财务所以看不懂它）。</p><h2 id="使用-1">3.2&emsp;使用</h2><p>由于国内用的人比较少，帮助文档只有英文版，但界面已经汉化了，修改语言要编辑<code>gnucash\etc\gnucash</code>文件夹里的<code>environment</code>文件。<br>首先按它的向导初始化，科目类别不要想太多全部选上都行，后面按自己需求进行编辑。界面大概这个样子：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200205195713.webp" alt></p><p>新建会计科目的时候会有个期初余额窗口，刚开始添加自己的资产时会用到。<strong>由于复式记账每一笔钱都必须要有来源和去向</strong>，添加的资产肯定是不能凭空而来的，这里默认是来自所有者权益中的期初余额项（有点像自己找自己贷款的感觉）。</p><p><strong>现有资产</strong>全部添加完之后就可以开始开心的记账历程了，初期推荐<code>&lt;Ctrl-t&gt;</code>打开窗口进行每一笔的记账：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200205200520.webp" alt></p><p>对于重复性的支出，可以建立计划交易任务….暂时这几个功能就够用了，之后年末做一个报表统计分析下数据，看看自己有没有又变穷了点~</p><h2 id="收获">3.3&emsp;收获</h2><p>虽然才开始用，但收获还是挺多的，特别深的一个感悟就是<strong>保险的作用</strong>，<a href="https://chengpengzhao.com/files_store//%E4%BB%A5%E6%8A%95%E8%B5%84%E7%9A%84%E8%A7%92%E5%BA%A6%E6%9D%A5%E7%9C%8B%EF%BC%8C%E4%B9%B0%E4%BF%9D%E9%99%A9%E7%9A%84%E4%BA%BA%E6%98%AF%E4%B8%8D%E6%98%AF%E6%84%9A%E8%A0%A2%E7%9A%84%EF%BC%9F%20-%20%E7%9F%A5%E4%B9%8E%20(2020-02-05%20%E4%B8%8B%E5%8D%888_41_43).html">知乎这个问题</a>也给了我很多启发。<br>其实刚开始看到别人把保险列入资产里时我还是很不解的，因为我印象中的保险（特别是国内的保险）都带有理赔难、一文不值、买了跟没买一样等标签（也不知道是谁在什么时候给我贴上去的）。但无论如何，<strong>保险是个人潜在金融风险的重要防御手段，也是家庭最基本的防线</strong>，人生在世有那么多意外，说不定哪天自己就被楼顶跳楼的那个人砸中了呢？有了保险，我们可以规避风险、为家庭减负，作为一个有家庭有社会角色的人（虽然我还没有）如果不考虑这些风险是不负责任的。  </p><p>关于保险的话题我还有很多要学习的地方，一段时间后再总结下吧…</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-02-05-kai-shi-shi-yong-tiddlywiki-ge-ren-bi-ji-xi-tong-he-gnucash-ge-ren-cai-wu-guan-li-xi-tong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>matery主题改动日志</title>
      <link>https://chengpengzhao.com/2020-01-17-bo-ke-gai-dong-ri-zhi/</link>
      <guid>https://chengpengzhao.com/2020-01-17-bo-ke-gai-dong-ri-zhi/</guid>
      <pubDate>Fri, 17 Jan 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;折腾是永无止境的，刚开始觉得很完美的东西用一段时间后就开始发现各种不顺眼，于
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>折腾是永无止境的，刚开始觉得很完美的东西用一段时间后就开始发现各种不顺眼，于是东改西改；人就是这么不知足。  </p><h1 id="前言">1&emsp;前言</h1><p>当前博客主题套用的<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank" rel="noopener">hexo-theme-matery</a>，功能都很齐全了，看是挺好看的；于是当时果断换成了这个主题。<br>但同时这个优点也成了一部分人眼中的<strong>缺点</strong>：花里胡哨、不实用、加载速度慢。我看了很多个用这个主题的博客，虽然自认为自己网站的速度已经很慢了，但仍有许多人的博客加载速度在不断刷新我的下限，总算进去了，看到的却是满屏的雪花飘…当然并不是这样不好，毕竟不同人的审美不同，但至少这些不是我想要的。当然我也看到了许多极简但文章很好的博客，让我不禁想要拍手称快。<br>有了比较之后，就不难发现自己现在的主题存在一些不需要的元素。经过几天<code>html、css、js</code>的学习（能看懂源码任何一部分的作用、但细节需要一个个<del>百度</del>谷歌的程度），就可以开始进行精简和个性化主题了~</p><h1 id="方法">2&emsp;方法</h1><p>为了增加容错率，先把blog源码全部上传到github一个私人仓库里（除非你觉得让别人看到也没什么），建个dev分支然后就可以开始进行修改咯~每修改一个地方记得commit一下，方便意外时想要回退某个修改前的版本（git现学现用）</p><h1 id="记录">3&emsp;记录</h1><h2 id="更换主题后立即做的改动">3.1&emsp;更换主题后立即做的改动</h2><ul><li>关闭所有动画效果，修改导航栏，自定义页面，增加标题自动编号</li><li>调整渲染器对LaTeX公式的支持</li><li>RSS由atom改为rss2，能够不打开博客预览全文</li><li>界面改成英文，方便偶尔到访的老外</li><li>防止文章目录过长时溢出，加入滑动栏</li><li>解决英文标点<code>&#39;</code>显示为<code>’</code>的问题</li></ul><h2 id="去掉jsdelivr图片加速">3.2&emsp;去掉jsdelivr图片加速</h2><blockquote><p><em>以下内容更新于2020-01-14 15:01:23</em></p></blockquote><p>虽然之前看别人博客弄了个github图床的免费CDN加速，但也看到些讨论说它不靠谱的地方；我用了一段时间后感觉并没有多大提升，于是赶紧删了所有免费加速。毕竟免费背后它可能会做一些小动作，自己又没有太多相关专业知识还是敬而远之为好。</p><h2 id="去掉百度统计">3.3&emsp;去掉百度统计</h2><blockquote><p><em>以下内容更新于2020-01-15 16:13:07</em></p></blockquote><p>不得不说百度真是辣鸡，谷歌的话提交了之后没过几天就有反馈了，而百度…<br>测试blog的时候发现百度统计、自动推送的相关代码加载占用了相当一部分时间，而且推送跟没推送没啥区别，要它有何用；我只能说，再见百度。</p><h2 id="修改归档页面布局">3.4&emsp;修改归档页面布局</h2><blockquote><p><em>以下内容更新于2020-01-17 17:17:56</em></p></blockquote><p>归档的作用是让来访者快速找到感兴趣的文章，而matery主题的归档页面采用了时间线的布局，虽然眼前一亮但<strong>一点都不方便</strong>！还不如主页里的posts紧凑l，完全没起到相应的作用；这部分肯定是要大改特改的，删除不必要的元素，减少间隔、简化样式。</p><h2 id="减少链接层级">3.5&emsp;减少链接层级</h2><p>默认的posts链接为<code>permalink: :year/:month/:day/:title/</code>，分了个三、四级，不利于搜索引擎爬取；而且我的<code>post title</code>都有注明日期，这样就和前面重复了，不必要。&emsp;直接改成了<code>permalink: :title/</code>。<br><strong>副作用是之前文章的评论消失、文章浏览计数器全部重置</strong></p><h2 id="简化footer信息">3.6&emsp;简化footer信息</h2><p>能删则删，如运行时间实在没必要精确到秒吧…</p><h2 id="图片压缩、lazyload">3.7&emsp;图片压缩、lazyload</h2><p>图片是拖慢博客速度最大的一个原因之一，我喜欢每篇博客放一张自己以前拍的照片、截的图，累积起来占用了不少空间；为了避免在图片加载完成之前只能傻等着的尴尬局面，加个lazyload插件还是很管用的；但注意加了之后<strong>hexo-douban</strong>的图片会加载不出来，需要给其<strong><img></strong>标签贴一个<strong>no-lazy</strong>属性。</p><h2 id="bug修复">3.8&emsp;bug修复</h2><blockquote><p><em>以下内容更新于2020-01-19 23:37:23</em><br>之前调了一些元素的位置，导致出现下一页按钮出现显示错位（可能是改变了哪个<code>width</code>属性引起的），解决方法是干脆换个边显示。</p></blockquote><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200119232732.webp" alt="next错位"></p><h2 id="调整posts分类">3.9&emsp;调整posts分类</h2><p>之前的分类方法有些不合理，重新规划了下。大多数博客都有<code>categories</code>和<code>tags</code>两种分类方式:</p><ul><li><p>其中<code>categories</code>往往是互不关联、范围比较广的分类，如生活、学习、工作…在写post之前，最好先确定几个大的分类方向，尽量涵盖所有文章类型；在这基础之上扩展出多个子分类，之后将post对号入座；必要时再增添新的子分类，让博客的分类树不断完善。<br><code>Hexo</code>支持多级子分类，如下列写法：</p><pre class="line-numbers language-yml"><code class="language-yml">categories:  -  [学习, 语言, 英语   ]  -  [工作, 工具 ]<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>代表该post同时属于<code>学习</code>和<code>工作</code>两个同级分类，而<code>语言</code>是<code>学习</code>的子分类，<code>英语</code>又是<code>语言</code>的子分类。  注意<strong>英文逗号后必须有一个空格</strong>，而中括号前后的空格则无所谓。  </p></li><li><p><code>tags</code>则相对随意一些，它是另一个维度的分类，可以比较具体，<code>tag</code>之间也可以有重复的地方。此外，不同于<code>categories</code>常事先就规定好，<code>tags</code>往往是写完post拍一下脑袋当场确定的。  </p></li></ul><p>总的来说<code>tags</code>比较乱、相互之间没有什么顺序，而<code>categories</code>注重层级，结构清晰。</p><h2 id="一些元素的小调整">3.10&emsp;一些元素的小调整</h2><p>将文章标题字体改小了点，防止移动端预览时文字超出card；修改目录栏样式，使其能够清晰地显示各级分类，tags样式不需要改动；</p><h2 id="修复移动端hexo-douban中图片不能正常显示">3.11&emsp;修复移动端hexo-douban中图片不能正常显示</h2><p>解决方案是在<code>head</code>中添加一段<code>&lt;meta name=&quot;referrer&quot; content=&quot;no-referrer&quot;&gt;</code>；这么做的<strong>副作用</strong>会导致<strong>不蒜子计数器</strong>无法正常工作，折中方案是只在<code>hexo-douban</code>相关页面添加该<code>&lt;meta&gt;</code>标签：</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-03-29 10:18:59</em></p></blockquote><h2 id="在post卡片页面显示文章创建时间和修改时间">3.12&emsp;在post卡片页面显示文章创建时间和修改时间</h2><p>有时候写完一篇post之后并不是就放在那不管了，过了一段时间可能会要修改修改，这时候在页面中清晰地体现出来还是方便了他人不少的。实现也比较简单，连我这样的萌新都能改。</p><h2 id="评论端由Valine修改为utterances">3.13&emsp;评论端由Valine修改为utterances</h2><p>很早之前就想改一改评论端的实现方式了，之前一直是依靠Leancloud，但按照现在这个趋势放在它上面还是不放心，指不定哪天就没了呢。<br>一直觉得用Github issue的方式实现评论很方便，虽然提高了评论的门槛（需要fq才能显示评论界面），但反正平时没啥人留言，所以其实无所谓。自己管理起来方便就行。</p><h2 id="去掉post卡片的图片部分，图片全部放到gallery里">3.14&emsp;去掉post卡片的图片部分，图片全部放到gallery里</h2><p>图片太多确实拖慢了网站的访问速度，虽然都是我自己拍的挑选出来的照片，但想了想还是主页简洁一点好；（很早之前就改了忘记记录下来了- -）<br><br><br></p><blockquote><p><em>以下内容更新于2020-07-28 16:05:12</em></p></blockquote><h2 id="禁用cloudflare的Rocket-Loader功能">3.15&emsp;禁用cloudflare的Rocket Loader功能</h2><p>最近调试博客的时候发现国内访问时评论区加载不出来，分析后发现是<code>ajax.cloudflare.com</code>网站的<code>rocket-loader.min.js</code>在国内网络环境下请求不到，之前还以为是utterances评论端的问题。</p><h2 id="图片全部转webp，并加上免费的CDN">3.16&emsp;图片全部转webp，并加上免费的CDN</h2><p>因为一直用github当图床，而国内好像不能访问<code>https://raw.githubusercontent.com</code>的内容，所以没办法又不情愿地加上了jsdelivr的CDN加速；顺便写了个shell脚本将图片批量压缩并转为webp格式了（IOS端好像暂时还无法识别webp）。</p><h2 id="恢复valine评论端-MiniValine-，并实现与utteranc-es的切换">3.17&emsp;恢复valine评论端(MiniValine)，并实现与utteranc.es的切换</h2><p>由于很多人是从国内访问，github时不时抽风，导致utteranc.es有时加载不出来；为了优化访客体验，决定暂时恢复valine评论系统，并根据<a href="https://bestzuo.cn/" target="_blank" rel="noopener">Sanarous’s Blog</a>增加了一个用来切换评论系统的滑块。</p><h2 id="MiniValine换成魔改版Valine">3.18&emsp;MiniValine换成魔改版Valine</h2><p>换上Minivaline几个小时之后发现ipad访问时不显示评论框，可能是和主题有冲突，折腾了一阵子找不到原因之好放弃；搬出原来的valine照着别人改了下，加上了mathjax支持、自定义表情包、添加身份标示、卡片式留言板…话说适配移动端设备真是麻烦，特别是ios系统、调试起来都很复杂，不过还好最后问题都找到解决方法了。</p><br><hr><blockquote><p>待记录…</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-01-17-bo-ke-gai-dong-ri-zhi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>入坑WSL(Windows Subsystem for Linux)</title>
      <link>https://chengpengzhao.com/2020-01-13-ru-keng-wsl-windows-sub-system-for-linux/</link>
      <guid>https://chengpengzhao.com/2020-01-13-ru-keng-wsl-windows-sub-system-for-linux/</guid>
      <pubDate>Tue, 14 Jan 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;在笔记本上装Ubuntu用了几个月之后，由于一些软件只能在windows下运
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>在笔记本上装Ubuntu用了几个月之后，由于一些软件只能在windows下运行，来回切换系统也挺麻烦的，故决定安装个WSL(Windows Subsystem for Linux)试试。意外感觉用起来挺舒服的；一是平常需求也不多，就用下Shell命令、github、Vim；二是要运行一些大型程序的时候也不会在笔记本上作死，直接阿里云租个抢占式的服务器岂不美滋滋。<br>WSL也是让我重新启用了封印多年的Win10更新的一个原因，之前因为觉得强制更新贼烦直接彻底禁用了，导致我的Windows一直停留在1803版本，而且我想启动更新都启动不了；于是一狠心干脆重装windows算了。好在用了一段时间WSL后感觉这一阵折腾还是挺值的。  </p><h1 id="WSL安装">1&emsp;WSL安装</h1><p><strong>更新windows，越新越好</strong>-&gt; <strong>打开开发者模式</strong>-&gt;<strong>Windows功能中勾选Subsystems</strong>-&gt;<strong>应用商店安装Ubuntu</strong>-&gt;<strong>初始设置</strong>-&gt;<strong>配置使用环境</strong><br><br><br>安装过程没什么要说的，主要是如何配置让WSL使用更加方便；由于没有图形界面（当然也可以有不过感觉没必要装）很多软件都不需要装，直接用Windows版就行了。我就只装了python、Vim、OpenFOAM、Git等一些通过shell来运行的东西。  </p><h1 id="WSL配置">2&emsp;WSL配置</h1><p>都是一些常规操作，尽量流程化也方便以后在别的机器上配置。<br>更详细的过程： <a href="https://zhuanlan.zhihu.com/p/61542198" target="_blank" rel="noopener">随手找的一篇知乎文章</a></p><h2 id="更换软件源">2.1&emsp;更换软件源</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#使用 root 权限登录，后续输入密码</span><span class="token function">sudo</span> -i<span class="token comment" spellcheck="true">#接下来备份当前源，输入以下命令</span><span class="token function">cp</span> /etc/apt/sources.list /etc/apt/sources.list.old<span class="token comment" spellcheck="true">#这个sources.list文件就是源文件，打开在开头添加阿里云的源</span>vim /etc/apt/sources.list<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>用阿里云的源，复制保存即可：</p><pre class="line-numbers language-list"><code class="language-list">deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>然后就是熟悉的无脑一波：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token function">sudo</span> <span class="token function">apt-get</span> upgrade<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> build-essential<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="外观配置">2.2&emsp;外观配置</h2><p>装好SSL后最重要的一步。要是每次打开shell是一个丑到吐的界面，根本没有心情往下用，那么更别谈提高生产力了。<br>刚开始折腾了好久那个用Ubuntu图标打开的终端界面，怎么调都很难看，后面发现可以<code>&lt;Shift&gt;</code>+右键直接打开Linux Shell，这个界面比原来那个要好多了。所以就这样凑合用了一段时间…<br><strong>直到</strong>我发现了正在开发中的Windows Terminal，虽然还在开发设置只能通过修改<code>profiles.json</code>文件完成，但最后的效果还是可以的；配置文件的位置大概在<code>C:\Users\Administrator\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState</code>，(后面那一串不知道是不是每台电脑都一样),直接照它的注释编辑就行了。<br><a href="https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/windowsterminal" target="_blank" rel="noopener">Github上</a>有很多相关的Schemes，选个顺眼的就行~<br><br><br><br>这里还是具体操作一下如何有效率地换Schemes吧，首先clone项目到本地进入<code>windowsterminal</code>文件夹，运行<code>Linux shell</code>命令：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cat</span> * <span class="token operator">></span> log  <span class="token comment" spellcheck="true">#将所有.json文件拼接到一起</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>然后用Vim打开，录制一个宏，给大括号末尾添加个<code>,</code>号，最后粘贴log文件到<code>profiles.json</code>，之后就可以直接一个个地看主题效果了。  </p><blockquote><p>如果不是在WSL环境下，我还真不知道如何有效率地编辑，只怕会一个个文件打开然后用记事本粘贴到<code>profiles.json</code>里试吧；这也是为什么我觉得Linux好用的地方。虽然Windows下也可以用Gvim，但我尝试了几番用户体验实在是糟糕，没用几分钟就忍不住卸载了。</p></blockquote><p><br><br></p><p>我的配置文件是这样的：</p><pre class="line-numbers language-json"><code class="language-json">// To view the default settings<span class="token punctuation">,</span> hold <span class="token string">"alt"</span> while clicking on the <span class="token string">"Settings"</span> button.// For documentation on these settings<span class="token punctuation">,</span> see<span class="token operator">:</span> https<span class="token operator">:</span>//aka.ms/terminal-documentation<span class="token punctuation">{</span>    <span class="token property">"$schema"</span><span class="token operator">:</span> <span class="token string">"https://aka.ms/terminal-profiles-schema"</span><span class="token punctuation">,</span>    <span class="token property">"defaultProfile"</span><span class="token operator">:</span> <span class="token string">"{2c4de342-38b7-51cf-b940-2309a097f518}"</span><span class="token punctuation">,</span>    <span class="token property">"initialCols"</span><span class="token operator">:</span> <span class="token number">120</span><span class="token punctuation">,</span>    <span class="token property">"initialRows"</span><span class="token operator">:</span> <span class="token number">30</span><span class="token punctuation">,</span>    // 亮色或暗色主题，可选值 <span class="token string">"light"</span><span class="token punctuation">,</span> <span class="token string">"dark"</span><span class="token punctuation">,</span> <span class="token string">"system"</span>    <span class="token property">"requestedTheme"</span><span class="token operator">:</span> <span class="token string">"dark"</span><span class="token punctuation">,</span>    // 合并标题栏和标签栏    <span class="token property">"showTabsInTitlebar"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>    // 如果 showTabsInTitlebar 与本值同为 <span class="token boolean">false</span> 时，自动隐藏标签栏    <span class="token property">"alwaysShowTabs"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>    // 在标题栏上显示当前活动标签页的标题    <span class="token property">"showTerminalTitleInTitlebar"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>    // 双击选择时用于分词的字符    <span class="token property">"wordDelimiters"</span><span class="token operator">:</span> <span class="token string">""</span><span class="token punctuation">,</span>    // 选择时复制到剪贴板    <span class="token property">"copyOnSelect"</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>    //这一部分profiles是默认配置    <span class="token property">"profiles"</span><span class="token operator">:</span>    <span class="token punctuation">[</span>        <span class="token punctuation">{</span>            // Make changes here to the powershell.exe profile            <span class="token property">"guid"</span><span class="token operator">:</span> <span class="token string">"{61c54bbd-c2c6-5271-96e7-009a87ff44bf}"</span><span class="token punctuation">,</span>            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Windows PowerShell"</span><span class="token punctuation">,</span>            <span class="token property">"commandline"</span><span class="token operator">:</span> <span class="token string">"powershell.exe"</span><span class="token punctuation">,</span>            <span class="token property">"hidden"</span><span class="token operator">:</span> <span class="token boolean">false</span>        <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span>            // Make changes here to the cmd.exe profile            <span class="token property">"guid"</span><span class="token operator">:</span> <span class="token string">"{0caa0dad-35be-5f56-a8ff-afceeeaa6101}"</span><span class="token punctuation">,</span>            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"cmd"</span><span class="token punctuation">,</span>            <span class="token property">"commandline"</span><span class="token operator">:</span> <span class="token string">"cmd.exe"</span><span class="token punctuation">,</span>            <span class="token property">"hidden"</span><span class="token operator">:</span> <span class="token boolean">false</span>        <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span>            <span class="token property">"guid"</span><span class="token operator">:</span> <span class="token string">"{2c4de342-38b7-51cf-b940-2309a097f518}"</span><span class="token punctuation">,</span>            <span class="token property">"hidden"</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Ubuntu"</span><span class="token punctuation">,</span>            <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"Windows.Terminal.Wsl"</span>        <span class="token punctuation">}</span>    <span class="token punctuation">]</span><span class="token punctuation">,</span>    // Add custom color schemes to this array    //这一部分覆盖上面的一些设置<span class="token property">"profiles"</span><span class="token operator">:</span><span class="token punctuation">[</span>    <span class="token punctuation">{</span>        // 每个 Profile 的唯一标识符，生成方法见下        <span class="token property">"guid"</span><span class="token operator">:</span> <span class="token string">"{2c4de342-38b7-51cf-b940-2309a097f518}"</span><span class="token punctuation">,</span>        // 设置为 <span class="token boolean">true</span> 即可在新建菜单中隐藏        <span class="token property">"hidden"</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>        // 名字，会显示在菜单中        <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Ubuntu"</span><span class="token punctuation">,</span>        // 启动命令行        <span class="token property">"commandline"</span><span class="token operator">:</span> <span class="token string">"wsl.exe"</span><span class="token punctuation">,</span>        // 启动目录<span class="token punctuation">,</span>从当前路径启动        <span class="token property">"startingDirectory"</span><span class="token operator">:</span> <span class="token string">"."</span><span class="token punctuation">,</span>        // 字体设置<span class="token punctuation">,</span>改了一圈回来还是觉得默认的挺好        <span class="token property">"fontFace"</span><span class="token operator">:</span> <span class="token string">"Consolas"</span><span class="token punctuation">,</span>        <span class="token property">"fontSize"</span><span class="token operator">:</span> <span class="token number">12</span><span class="token punctuation">,</span>        // 背景亚克力透明效果（窗口失去焦点时无效）        <span class="token property">"useAcrylic"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>        <span class="token property">"acrylicOpacity"</span><span class="token operator">:</span> <span class="token number">0.75</span><span class="token punctuation">,</span>        // 背景图片(不能和上面的效果同时用？<span class="token punctuation">)</span>        //<span class="token property">"backgroundImage"</span> <span class="token operator">:</span> <span class="token string">"X:\\assets\\background.png"</span><span class="token punctuation">,</span>        //<span class="token property">"backgroundImageOpacity"</span> <span class="token operator">:</span> <span class="token number">0.5</span><span class="token punctuation">,</span>        // <span class="token property">"backgroundImageStretchMode"</span> <span class="token operator">:</span> <span class="token string">"uniformToFill"</span><span class="token punctuation">,</span>        // 菜单与标签中显示的图标        //<span class="token property">"icon"</span><span class="token operator">:</span> <span class="token string">"X:\\assets\\UbuntuLogo.scale-100.png"</span><span class="token punctuation">,</span>        // 配色方案，见下        <span class="token property">"colorScheme"</span><span class="token operator">:</span> <span class="token string">"synthwave"</span><span class="token punctuation">,</span>        // 光标颜色        <span class="token property">"cursorColor"</span><span class="token operator">:</span> <span class="token string">"#FFFFFF"</span><span class="token punctuation">,</span>        // 光标类型，可选值 <span class="token string">"vintage"</span> ( ▃ <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"bar"</span> ( ┃ <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"underscore"</span> ( ▁ <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"filledBox"</span> ( █ <span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"emptyBox"</span> ( ▯ <span class="token punctuation">)</span>        <span class="token property">"cursorShape"</span><span class="token operator">:</span> <span class="token string">"vintage"</span>        // ... 其他配置请参见官方文档    <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span>            <span class="token property">"guid"</span><span class="token operator">:</span> <span class="token string">"{b453ae62-4e3d-5e58-b989-0a998ec441b8}"</span><span class="token punctuation">,</span>            <span class="token property">"hidden"</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>            <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"Azure Cloud Shell"</span><span class="token punctuation">,</span>            <span class="token property">"source"</span><span class="token operator">:</span> <span class="token string">"Windows.Terminal.Azure"</span>        <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token property">"schemes"</span><span class="token operator">:</span>     <span class="token punctuation">[</span>        <span class="token punctuation">{</span>          <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"synthwave"</span><span class="token punctuation">,</span>          <span class="token property">"black"</span><span class="token operator">:</span> <span class="token string">"#000000"</span><span class="token punctuation">,</span>          <span class="token property">"red"</span><span class="token operator">:</span> <span class="token string">"#f6188f"</span><span class="token punctuation">,</span>          <span class="token property">"green"</span><span class="token operator">:</span> <span class="token string">"#1ebb2b"</span><span class="token punctuation">,</span>          <span class="token property">"yellow"</span><span class="token operator">:</span> <span class="token string">"#fdf834"</span><span class="token punctuation">,</span>          <span class="token property">"blue"</span><span class="token operator">:</span> <span class="token string">"#2186ec"</span><span class="token punctuation">,</span>          <span class="token property">"purple"</span><span class="token operator">:</span> <span class="token string">"#f85a21"</span><span class="token punctuation">,</span>          <span class="token property">"cyan"</span><span class="token operator">:</span> <span class="token string">"#12c3e2"</span><span class="token punctuation">,</span>          <span class="token property">"white"</span><span class="token operator">:</span> <span class="token string">"#ffffff"</span><span class="token punctuation">,</span>          <span class="token property">"brightBlack"</span><span class="token operator">:</span> <span class="token string">"#000000"</span><span class="token punctuation">,</span>          <span class="token property">"brightRed"</span><span class="token operator">:</span> <span class="token string">"#f841a0"</span><span class="token punctuation">,</span>          <span class="token property">"brightGreen"</span><span class="token operator">:</span> <span class="token string">"#25c141"</span><span class="token punctuation">,</span>          <span class="token property">"brightYellow"</span><span class="token operator">:</span> <span class="token string">"#fdf454"</span><span class="token punctuation">,</span>          <span class="token property">"brightBlue"</span><span class="token operator">:</span> <span class="token string">"#2f9ded"</span><span class="token punctuation">,</span>          <span class="token property">"brightPurple"</span><span class="token operator">:</span> <span class="token string">"#f97137"</span><span class="token punctuation">,</span>          <span class="token property">"brightCyan"</span><span class="token operator">:</span> <span class="token string">"#19cde6"</span><span class="token punctuation">,</span>          <span class="token property">"brightWhite"</span><span class="token operator">:</span> <span class="token string">"#ffffff"</span><span class="token punctuation">,</span>          <span class="token property">"background"</span><span class="token operator">:</span> <span class="token string">"#000000"</span><span class="token punctuation">,</span>          <span class="token property">"foreground"</span><span class="token operator">:</span> <span class="token string">"#dad9c7"</span>        <span class="token punctuation">}</span>    <span class="token punctuation">]</span><span class="token punctuation">,</span>    // Add any keybinding overrides to this array.    // To unbind a default keybinding<span class="token punctuation">,</span> set the command to <span class="token string">"unbound"</span>    <span class="token property">"keybindings"</span><span class="token operator">:</span> <span class="token punctuation">[</span>        //各窗口间移动        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"action"</span><span class="token operator">:</span> <span class="token string">"moveFocus"</span><span class="token punctuation">,</span> <span class="token property">"direction"</span><span class="token operator">:</span> <span class="token string">"down"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+j"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"action"</span><span class="token operator">:</span> <span class="token string">"moveFocus"</span><span class="token punctuation">,</span> <span class="token property">"direction"</span><span class="token operator">:</span> <span class="token string">"left"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+h"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"action"</span><span class="token operator">:</span> <span class="token string">"moveFocus"</span><span class="token punctuation">,</span> <span class="token property">"direction"</span><span class="token operator">:</span> <span class="token string">"right"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+l"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token property">"action"</span><span class="token operator">:</span> <span class="token string">"moveFocus"</span><span class="token punctuation">,</span> <span class="token property">"direction"</span><span class="token operator">:</span> <span class="token string">"up"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+k"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        //分割 <span class="token punctuation">,</span>分割后的窗口好像只能通过exit命令关闭？没有快捷键        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"splitHorizontal"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"ctrl+shift+o"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"splitVertical"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"ctrl+shift+e"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        //新建标签页        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"closeTab"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"ctrl+shift+w"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"newTab"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"ctrl+alt+t"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"closePane"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"unbound"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        //标签页移动        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"nextTab"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+2"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>        <span class="token punctuation">{</span> <span class="token property">"command"</span><span class="token operator">:</span> <span class="token string">"prevTab"</span><span class="token punctuation">,</span> <span class="token property">"keys"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"alt+1"</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span>    <span class="token punctuation">]</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>guid</code>复制它默认的就完事了，字体可以自己安装，或者到<code>计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink</code>注册表找一找系统自带哪些，选个好看的（我觉得windowsterminal自带的字体Consolas就挺好的了）。然后就是快捷键，虽说V平常都在Vim里进行窗口分割什么的，但如果执行shell命令还是在Vim外打开比较方便，之前Ubuntu里用的是Terminator终端，所以这里快捷键也是依照之前的习惯来的；为了避免和Vim配置冲突不必要的快捷键能关则关。<strong>最终效果</strong>:<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200114104052.webp" alt></p><h2 id="增加右键菜单">2.3&emsp;增加右键菜单</h2><p>如果不想每次打开都要cd半天的话还是加一个在当前目录直接右键打开terminal的功能比较好；根据<a href="https://printempw.github.io/windows-terminal-setup-guide/" target="_blank" rel="noopener">PRIN博客</a>的设置，建立批处理文件：</p><pre class="line-numbers language-bat"><code class="language-bat">@echo offreg.exe add "HKEY_CLASSES_ROOT\Directory\Background\shell\wt" /f /ve /d "Windows Terminal here"reg.exe add "HKEY_CLASSES_ROOT\Directory\Background\shell\wt" /f /v "Icon" /t REG_EXPAND_SZ /d "X:\assets\terminal.ico"reg.exe add "HKEY_CLASSES_ROOT\Directory\Background\shell\wt\command" /f /ve /t REG_EXPAND_SZ /d "\"%%LOCALAPPDATA%%\Microsoft\WindowsApps\wt.exe\""pause<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>管理员运行后就可以看到右键菜单了，当然<code>profiles.json</code>里要设置<code>&quot;startingDiretory&quot; : &quot;.&quot;</code>。</p><h2 id="配置zsh">2.4&emsp;配置zsh</h2><p>之前一直使用bash，感觉挺顺手的，直到前几天逛别人博客发现了Zsh这种强大的终端。</p><h3 id="zsh安装">2.4.1&emsp;zsh安装</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> zsh<span class="token keyword">echo</span> <span class="token variable">$SHELL</span> <span class="token comment" spellcheck="true"># 查看当前shell</span><span class="token function">cat</span> /etc/shells <span class="token comment" spellcheck="true">#查看系统所有shell</span>chsh -s <span class="token variable"><span class="token variable">$(</span><span class="token function">which</span> zsh<span class="token variable">)</span></span> <span class="token comment" spellcheck="true">#设置zsh为默认终端</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><h3 id="oh-my-zsh安装及zsh配置">2.4.2&emsp;oh-my-zsh安装及zsh配置</h3><pre class="line-numbers language-bash"><code class="language-bash">sh -c <span class="token string">"<span class="token variable"><span class="token variable">$(</span>curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh<span class="token variable">)</span></span>"</span> <span class="token comment" spellcheck="true">#安装oh-my-zsh</span><span class="token function">ls</span> ~/.oh-my-zsh/themes <span class="token comment" spellcheck="true">#查看可用主题</span>vim ~/.zshrc <span class="token comment" spellcheck="true">#编辑配置文件；如修改主题为ys，增加插件等。相当于bash的bashrc文件</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> autojump<span class="token punctuation">;</span><span class="token function">git</span> clone git://github.com/zsh-users/zsh-autosuggestions <span class="token variable">$ZSH_CUSTOM</span>/plugins/zsh-autosuggestions<span class="token punctuation">;</span><span class="token function">git</span> clone git://github.com/zsh-users/zsh-syntax-highlighting <span class="token variable">$ZSH_CUSTOM</span>/plugins/zsh-syntax-highlighting  <span class="token comment" spellcheck="true">#安装autojump、zsh-autosuggestions、zsh-syntax-highlighting三个插件</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>再在<code>~/.zshrc</code>的插件部分改为：</p><pre class="line-numbers language-bash"><code class="language-bash">plugins<span class="token operator">=</span><span class="token punctuation">(</span>  <span class="token function">git</span>  autojump  zsh-autosuggestions  zsh-syntax-highlighting<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><code>.zshrc</code>相当于bash里的<code>.bashrc</code>，之前bash里的环境变量设置可以直接搬过来；关于更多zsh以及oh-my-zsh的用法有待进一步学习…</p><h2 id="Vim配置">2.5&emsp;Vim配置</h2><p>不同于在Ubuntu里面使用Vim，WSL里有的快捷键可能变得不能用了，比如往前删除我常常用<code>&lt;ctrl-8&gt;</code>代替<code>&lt;backspace&gt;</code>，但WSL里这一排快捷键就失效了。所以最好的选择就是给自己的<code>Vimrc</code>配置文件直接新建一个用于WSL的branch，对一些命令进行微调。  </p><p>这是我的<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener">vimrc配置仓库</a>，里面记录了我学习Vim的历程，我看了很多人的配置文件，提取了一些出彩的地方整合在一起,每条设置都写了注释，也方便别人学习。  </p><p>Vim本身就是一个不断磨合的过程，不存在一成不变的配置，将来我也会不断更新我的<code>.vimrc</code>~<br><br><br>其中值得一讲的就是与windows剪切板的通信，之前在Ubuntu系统Vim通过<code>&quot;+y</code>就可以访问系统剪切板，设置一个映射<code>noremap &lt;C-y&gt; &quot;+y</code>就能很好的解决和系统剪切板的互相访问；<br>对于WSL，普遍的做法是通过<code>/mnt/c/Windows/System32/clip.exe</code>将Vim的内容传到windows剪切板。粘贴则是直接通过<code>paste模式</code>下<code>&lt;Ctrl+Shift+V&gt;</code>进行操作。只需要在<code>.vimrc</code>中如下设置：</p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token comment" spellcheck="true">"适配Linux子系统，能够正常和windows复制粘贴文本</span><span class="token comment" spellcheck="true">"利用/mnt/c/Windows/System32/clip.exe</span>func<span class="token operator">!</span> <span class="token function">GetSelectedText</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    normal gv<span class="token comment" spellcheck="true">"xy</span>    <span class="token keyword">let</span> result <span class="token operator">=</span> <span class="token function">getreg</span><span class="token punctuation">(</span><span class="token string">"x"</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> resultendfunc<span class="token string">"if !has("</span><span class="token builtin">clipboard</span><span class="token string">") &amp;&amp; executable("</span><span class="token operator">/</span>mnt<span class="token operator">/</span><span class="token keyword">c</span><span class="token operator">/</span>Windows<span class="token operator">/</span>System32<span class="token operator">/</span>clip<span class="token operator">.</span>exe<span class="token comment" spellcheck="true">")</span><span class="token comment" spellcheck="true">"复制</span><span class="token builtin">noremap</span> <span class="token operator">&lt;</span><span class="token keyword">silent</span><span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">y</span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token keyword">call</span> <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">'/mnt/c/Windows/System32/clip.exe'</span><span class="token punctuation">,</span> <span class="token function">GetSelectedText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">&lt;</span>CR<span class="token operator">></span><span class="token comment" spellcheck="true">"剪切</span><span class="token builtin">noremap</span> <span class="token operator">&lt;</span><span class="token keyword">silent</span><span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">x</span><span class="token operator">></span> <span class="token punctuation">:</span><span class="token keyword">call</span> <span class="token function">system</span><span class="token punctuation">(</span><span class="token string">'/mnt/c/Windows/System32/clip.exe'</span><span class="token punctuation">,</span> <span class="token function">GetSelectedText</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>gvx<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>特别需要注意的是</strong>：一定要确认WSL有权限访问<code>clip.exe</code>。</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-02-10 11:05:47</em></p></blockquote><h1 id="总结，WSL初始化配置脚本">3&emsp;总结，WSL初始化配置脚本</h1><p>试了试WSL2结果升级后打都打不开，bug一堆，萌新劝退…只好又回到WSL重新安装一遍环境，真的是手贱。<br>免得每次配置都东凑西凑，做个小结好了  </p><h2 id="配置软件源">3.1&emsp;配置软件源</h2><p><a href="./#toc-heading-3">前面</a>提到过，不再细讲</p><h2 id="常用软件安装">3.2&emsp;常用软件安装</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> update -y<span class="token function">sudo</span> <span class="token function">apt-get</span> upgrade -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> <span class="token function">git</span> -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> curl -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> vim-gtk3 -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> zsh -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> tree -y<span class="token function">sudo</span> apt <span class="token function">install</span> build-essential cmake python3-dev -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> python3-pip -y<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> nodejs -y<span class="token comment" spellcheck="true"># sudo apt-get install nodejs-legacy -y</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> <span class="token function">npm</span> -y<span class="token function">sudo</span> <span class="token function">npm</span> <span class="token function">install</span> -g hexo-clicurl -fLo ~/.vim/autoload/plug.vim --create-dirs \    https://cdn.jsdelivr.net/gh/junegunn/vim-plug/plug.vimcurl -LO https://github.com/BurntSushi/ripgrep/releases/download/11.0.2/ripgrep_11.0.2_amd64.deb<span class="token function">sudo</span> dpkg -i ripgrep_11.0.2_amd64.debsh -c <span class="token string">"<span class="token variable"><span class="token variable">$(</span>curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh<span class="token variable">)</span></span>"</span> <span class="token comment" spellcheck="true">#安装oh-my-zsh</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="Vim及zsh配置">3.3&emsp;Vim及zsh配置</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> autojump<span class="token punctuation">;</span><span class="token function">git</span> clone git://github.com/zsh-users/zsh-autosuggestions <span class="token variable">$ZSH_CUSTOM</span>/plugins/zsh-autosuggestions<span class="token punctuation">;</span><span class="token function">git</span> clone git://github.com/zsh-users/zsh-syntax-highlighting <span class="token variable">$ZSH_CUSTOM</span>/plugins/zsh-syntax-highlighting  <span class="token comment" spellcheck="true">#安装autojump、zsh-autosuggestions、zsh-syntax-highlighting三个插件</span>chsh -s <span class="token variable"><span class="token variable">$(</span><span class="token function">which</span> zsh<span class="token variable">)</span></span> <span class="token comment" spellcheck="true">#设置zsh为默认终端</span><span class="token function">git</span> clone https://github.com/chengpengzhao/My_vimrc.git<span class="token function">cd</span> My_vimrc<span class="token function">git</span> checkout dev-WSL<span class="token function">cp</span> .vimrc ~/.vimrc<span class="token function">cp</span> .zshrc ~/.zshrc<span class="token function">mkdir</span> ~/.vim/UltiSnips<span class="token function">cp</span> *.snippets ~/.vim/UltiSnips/<span class="token comment" spellcheck="true"># cp ./'.vimrc(ssh)' ../.vimrc</span><span class="token function">source</span> ~/.zshrc<span class="token comment" spellcheck="true">#先打开Vim运行PlugInstall</span><span class="token function">cd</span> ~/.vim/plugged/YouCompleteMepython3 install.py --all<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="Github配置">3.4&emsp;Github配置</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> config --global user.name <span class="token string">"chengpengzhao"</span><span class="token function">git</span> config --global user.email <span class="token string">"chengpengzhao@foxmail.com"</span><span class="token function">git</span> config --global core.quotepath <span class="token boolean">false</span>  <span class="token comment" spellcheck="true">#防止用tab键自动补全的中文文件名乱码</span><span class="token function">git</span> config --global core.autocrlf <span class="token boolean">false</span><span class="token function">git</span> config --global core.filemode <span class="token boolean">false</span><span class="token function">git</span> config --global core.safecrlf <span class="token boolean">true</span>ssh-keygen -t rsa -C <span class="token string">"chengpengzhao@foxmail.com"</span>vim ~/.ssh/id_rsa.pub     <span class="token comment" spellcheck="true">#  复制添加到github</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-01-13-ru-keng-wsl-windows-sub-system-for-linux/#disqus_thread</comments>
    </item>
    
    <item>
      <title>正则表达式学习笔记</title>
      <link>https://chengpengzhao.com/2020-01-11-zheng-ze-biao-da-shi-xue-xi-bi-ji/</link>
      <guid>https://chengpengzhao.com/2020-01-11-zheng-ze-biao-da-shi-xue-xi-bi-ji/</guid>
      <pubDate>Sat, 11 Jan 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;之前学过一遍正则表达式，结果好久不用基本上忘了，每次用都得重新打开网页搜索下
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>之前学过一遍正则表达式，结果好久不用基本上忘了，每次用都得重新打开网页搜索下；由于网上讲的参差不齐，还是自己总结下吧。<br>大家都推荐这本书：  <a href="https://book.douban.com/subject/11589967/" target="_blank" rel="noopener">精通正则表达式 第3版</a></p><h1 id="特殊作用">1&emsp;特殊作用</h1><ul><li><p>大写往往代表对小写能匹配的字符取补集</p></li><li><p><code>[_a-zA-z0-9]</code> : 中括号的作用——匹配中括号内任意一种(连字符<code>-</code>只有放在字符组开头时才不表示范围)</p></li><li><p><code>(\d))</code> : 小括号创建一个捕获分组，也可用来决定竖线的作用范围</p></li><li><p><code>(?:the|The|THE)</code> : 非捕获分组,无法后向引用(效率高)，解决使用小括号的副作用</p></li><li><p><code>(?=pattern)</code> : 非捕获匹配，正向肯定查找；如<code>Windows(?=95|98|NT|2000)</code>能匹配<code>Windows2000</code>中的<code>Windows</code>；类似方向相反但作用相同的为<code>(?&lt;=pattern)</code></p></li><li><p><code>(?!pattern)</code> ; 非捕获匹配，正向否定查找；如<code>Windows(?!95|98|NT|2000)</code>能匹配<code>Windows3.1</code>中的<code>Windows</code>；类似方向相反但作用相同的为<code>(?&lt;!pattern)</code></p></li><li><p><code>(?=...)</code> : 这一类表达式都可以看作一个“空位”，它们本身不占用字符</p></li><li><p><code>(\d)\d\1</code> : 其中<code>\1</code>表示引用前面分组中的内容，如该表达式可匹配<code>707</code>; 或者有时用<code>$1</code>这种形式也可</p></li><li><p><code>\</code> : 转义符， 如<code>\(</code>表示匹配左括号本身</p></li><li><p><code>^</code> : 行起始位置(或整个文档的开头);  <code>$</code> : 行结束位置  (锚位符)</p></li><li><p><code>$</code> : 行或字符串的结尾位置；和<code>^</code>一样都不占用字符</p></li><li><p><code>[^\d]</code> : 当<code>^</code>放在中括号里时表示对该中括号里的匹配内容取反(匹配单个未列出的字符)</p></li><li><p><code>|</code> : <strong>并集</strong>，多个选项中选择一个.如<code>(the|The|THE)</code></p></li><li><p><code>[a-z] [^m-r]</code> : <strong>交集</strong>，空格表示“且”，该式表示匹配a到z之间但不包含m到r间的字符</p></li><li><p><code>.*?</code> : 非贪婪匹配的一个组合形式，类似的<code>?</code>字符还可以跟在<code>*,+,?，{n}，{n,}，{n,m}</code>后表示非贪婪匹配</p></li></ul><h1 id="表示数量">2&emsp;表示数量</h1><ul><li><p><code>\d{3}</code> : 花括号为量词，数字表明出现几次，可以有多个选项如: <code>\d{3,4}</code>，匹配3位或4位数字</p></li><li><p><code>*</code> : 量词，出现次数大于等于0(贪婪)   相当于<code>{0,}</code></p></li><li><p><code>+</code> : 量词，出现次数大于等于1   相当于<code>{1,}</code></p></li><li><p><code>?</code> : 量词，0个或1个(懒惰)   相当于<code>{0,1}</code></p></li></ul><h1 id="数字">3&emsp;数字</h1><ul><li><p><code>[0-9]</code> : 匹配单个数字, 相当于<code>\d</code></p></li><li><p><code>[01357]</code> : 匹配列出的数字中的一个</p></li><li><p><code>\D</code> : 匹配一个非数字字符</p></li></ul><h1 id="其他">4&emsp;其他</h1><ul><li><p><code>.</code> : 匹配任意字符，<strong>但好像有的版本没把换行符算进去</strong>，这时可用<code>(.|\n)</code>表示任意字符</p></li><li><p><code>\w</code> : 匹配字母、数字和下划线</p></li><li><p><code>\s</code> : 空白字符，一共四种，相当于<code>[ \t\n\r]</code> ;空格、制表符、换行符、回车符</p></li><li><p><code>\b</code> : 匹配单词边界，不消耗字符(零宽度断言)，如<code>\b\w{7}\b</code></p></li></ul><h1 id="正则表达式小工具Reg-Exper-Tester">5&emsp;正则表达式小工具Reg_Exper-Tester</h1><p>自己结合别人的代码揉合的一个正则表达式测试以及可视化的工具，感觉还是挺有用的，比网上80%的正则表达式工具都要好吧，不然就不需要我重新做一个了。<br>Demo: &lt; <a href="https://chengpengzhao.com/Reg_Exper-Tester/">https://chengpengzhao.com/Reg_Exper-Tester/</a> &gt;</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-01-11-zheng-ze-biao-da-shi-xue-xi-bi-ji/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Git学习笔记</title>
      <link>https://chengpengzhao.com/2020-01-08-git-learning/</link>
      <guid>https://chengpengzhao.com/2020-01-08-git-learning/</guid>
      <pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;git学习笔记&quot;&gt;1&amp;emsp;git学习笔记&lt;/h1&gt;&lt;p&gt;学习
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="git学习笔记">1&emsp;git学习笔记</h1><p>学习自：<br><a href="https://www.liaoxuefeng.com/wiki/896043488029600" target="_blank" rel="noopener">廖雪峰的官方网站</a></p><h2 id="基础">1.1&emsp;基础</h2><ul><li><p>千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件，他们自作聪明地在每个文件开头添加了0xefbbbf（十六进制）的字符，你会遇到很多不可思议的问题，比如，网页第一行可能会显示一个“?”，明明正确的程序一编译就报语法错误，等等，都是由记事本的弱智行为带来的。建议下载Notepad++代替记事本。记得把Notepad++的默认编码设置为UTF-8 without BOM</p></li><li><p><code>git status / git diff / git log (--pretty=oneline)</code></p></li><li><p>工作区–暂存区–HEAD（master…)</p></li><li><p>HEAD指向master, master指最新的提交，上个版本HEAD^，上上个HEAD^^…</p></li></ul><h2 id="版本控制">1.2&emsp;版本控制</h2><ul><li><p><code>git reset --hard HEAD^</code>  # 回滚到上一个版本 （或：<code>git reset --hard</code>版本号代码）</p></li><li><p><code>reset</code>后只是本地回退到之前版本，若要更新到远程库需要强制推送<code>git push -f</code>,当前版本之后的commit会全部消失</p></li><li><p><code>git relog</code>  #记录每一次命令，可用作回到未来版本; <code>git log</code> 可在回退之前版本前用来查看提交历史</p></li><li><p><code>git checkout -- readme.txt</code>   #丢弃工作区修改，恢复上一版本状态（未add之前用）</p></li><li><p><code>git reset HEAD filename</code>    # add但未commit用，撤销暂存区内容</p></li><li><p><code>git rm filename</code>  # 删除版本库文件，若是误删可用<code>git checkout -- readme.txt</code>恢复</p></li></ul><h2 id="分支">1.3&emsp;分支</h2><ul><li><p>Github中远程库的名字是origin, <code>git push -u origin master</code>  #把当前分支master推送到origin, -u 建立本地和远程分支的关联，以后推送可以简化命令。</p></li><li><p>通过ssh支持的原生git协议速度最快。</p></li><li><p>创建分支dev后，新建了一个指针dev，现在HEAD指向dev，再编辑的话dev前移，master指针不变</p></li><li><p><code>git checkout -b dev</code>  #创建并切换到新分支 = <code>git branch dev</code> + <code>git checkout dev</code></p></li><li><p><code>git checkout -b dev origin/dev</code>  # 创建远程origin的dev分支到本地,本地和远程分支的名称最好一致；</p></li><li><p>建立本地分支和远程分支的关联，使用<code>git branch --set-upstream branch-name origin/branch-name</code></p></li><li><p><code>git switch -c dev</code>    #创建并切换到新分支(和 <code>git checkout -b dev</code> 一样)</p></li><li><p><code>git branch</code>  #查看当前分支  <code>git checkout master</code>   切换HEAD到master分支上 (还可用<code>git switch master</code>)</p></li><li><p><code>git merge dev</code>  #合并指定分支和当前分支</p></li><li><p><code>git branch -d dev</code>  #删除dev分支</p></li><li><p>丢弃一个没有被合并过的分支，可以通过<code>git branch -D &lt;name&gt;</code>强行删除。</p></li><li><p>Git用<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;，=======，&gt;&gt;&gt;&gt;&gt;&gt;&gt;</code>标记出不同分支的内容</p></li><li><p><code>git log --graph --pretty=oneline --abbrev-commit</code>  #查看分支合并情况</p></li><li><p>合并分支时，加上–no-ff参数就可以用普通模式合并，合并后的历史有分支，能看出来曾经做过合并，而fast forward合并就看不出来曾经做过合并。</p></li><li><p>一般都是在dev上工作，形成版本时发布到master</p></li><li><p>时刻注意远程分支和本地分支的区别；   <code>git branch -a</code> 查看所有分支，带有<code>remote/origin/xxx</code>的是远程分支</p></li><li><p><code>git push origin --delete xxx</code> 删除某个远程分支<code>remote/origin/xxx</code></p></li></ul><h2 id="bug处理">1.4&emsp;bug处理</h2><ul><li><p><code>git stash</code>  #储存当前工作区，修复bug时用，先新建分支修复bug/  <code>git stash pop</code> 恢复工作现场并删除stash / <code>git stash list</code> 查看stash区</p></li><li><p><code>git checkout master</code> + <code>git checkout -b issue-xxx</code>  #创建修复bug的分支</p></li><li><p><code>git switch master</code> + <code>git merge --no-ff -m &quot;merged bug fix&quot;</code>   #修复完成后删除该分支</p></li><li><p><code>git cherry-pick xxx</code>  / 在当前分支重复一遍xxx修改</p></li><li><p><code>git remote -v</code> #查看远程库信息  <code>git push origin xxx</code>  #推送xxx分支到origin</p></li></ul><h2 id="标签管理">1.5&emsp;标签管理</h2><ul><li><p><code>git tag v1.0</code>  #创建tag，便于管理     <code>git tag</code> 查看所有标签</p></li><li><p><code>git tag v0.9 xxx</code>   #为commit id 为xxx 的操作打标签 /  <code>git show v0.9</code>  #查看标签对应commit</p></li><li><p><code>git tag -a v1.0 -m &quot;...&quot; xxx</code> #标签也可以加上-m</p></li><li><p><code>git push origin --tags</code>   #推送标签到origin</p></li><li><p><code>git tag -d v0.9</code> #标签本地删除  / <code>git push origin :refs/tags/v0.9</code> #远程删除标签</p></li></ul><h1 id="工作流">2&emsp;工作流</h1><p><br><br></p><blockquote><p><em>以下内容更新于2020-02-29 10:12:35</em></p></blockquote><p>最近用git发现每次忘记的都是同样的场景下那几个同样的命令，所以为了更方便自己及时查阅，按照工作流再总结一遍Git的一些命令。<br>这里默认<strong>用Github作为远程仓库</strong>，所以用命令时要<em>时刻注意远程和本地的区别</em>  </p><h2 id="git配置">2.1&emsp;git配置</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> config --global user.name <span class="token string">"xxx"</span><span class="token function">git</span> config --global user.email <span class="token string">"xxx@xxxx.com"</span><span class="token function">git</span> config --global core.quotepath <span class="token boolean">false</span>  <span class="token comment" spellcheck="true">#防止用tab键自动补全的中文文件名被转义</span><span class="token function">git</span> config --global core.autocrlf <span class="token boolean">false</span>  <span class="token comment" spellcheck="true"># 不自动转换换行符</span><span class="token function">git</span> config --global core.filemode <span class="token boolean">false</span>  <span class="token comment" spellcheck="true"># 忽略文件权限，多人时慎用</span><span class="token function">git</span> config --global core.safecrlf <span class="token boolean">true</span>   <span class="token comment" spellcheck="true"># 拒绝提交包含混合换行符的文件</span><span class="token function">git</span> config --global core.pager <span class="token function">cat</span>    <span class="token comment" spellcheck="true"># 更改Git难受的分页器显示</span><span class="token function">git</span> config --global core.editor vim   <span class="token comment" spellcheck="true">#修改ecommit的ditor为vim</span><span class="token function">git</span> config --global alias.lg <span class="token string">"log --color --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all"</span>             <span class="token comment" spellcheck="true">#让git log 更好看，配置自定义命令 git lg</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>上述命令是在shell中完成的，如果要检查当前配置可运行<code>git config --list</code>，或者直接查看<em>配置文件</em>：  </p><pre class="line-numbers language-bash"><code class="language-bash">vim   /etc/gitconfig    <span class="token comment" spellcheck="true"># 系统上每一个用户及他们仓库的通用配置。 如果使用带有 --system 选项的 git config 时，它会从此文件读写配置变量</span>vim ~/.gitconfig <span class="token comment" spellcheck="true">#(或 ~/.config/git/config)：只针对当前用户。 可以传递 --global 选项让 Git 读写此文件。</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>当然第二项比较常用。</p><p><strong>SSH配置</strong>：  </p><pre class="line-numbers language-bash"><code class="language-bash">ssh-keygen -t rsa -C <span class="token string">"xxx@xxxx.com"</span>   <span class="token comment" spellcheck="true"># Github注册邮箱</span>vim ~/.ssh/id_rsa.pub     <span class="token comment" spellcheck="true">#  内容复制添加到github</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>这样一来自己电脑上存有私钥，github里的是公钥，可以免去每次push输入用户名和密码。</p><h2 id="初始化一个Git（本地和远程同步）">2.2&emsp;初始化一个Git（本地和远程同步）</h2><h3 id="从空的Github仓库clone">2.2.1&emsp;从空的Github仓库clone</h3><p>这种方法最简单，没什么好说的，<code>git clone</code>就完事了，配置了SSH的话推荐<code>Clone with SSH</code>。<br>之后将本地仓库的文件移动到<code>clone</code>下来的仓库中，提交一次Github就行了。</p><h3 id="关联本地仓库到远程">2.2.2&emsp;关联本地仓库到远程</h3><p>如果本地已经<code>git init</code>了一个仓库，并做了很多次修改，现在想上传到Github里，这时候可以关联一个Github的新仓库并<code>push</code>一次:  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> gitrepository  <span class="token comment" spellcheck="true">#进入本地仓库文件夹</span><span class="token function">git</span> remote add origin git@github.com:xxx/xxx.git   <span class="token comment" spellcheck="true">#还是推荐用SSH地址</span><span class="token comment" spellcheck="true"># 假设本地已经commit完了</span><span class="token function">git</span> push -u origin master  <span class="token comment" spellcheck="true"># 初次push指定远程分支</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p><code>-u</code>的作用相当于<code>--set-upstream</code>，如果你直接不带参数<code>git push</code>的话Github会提示你：  </p><pre><code>fatal: The current branch master has no upstream branch.To push the current branch and set the remote as upstream, use    git push --set-upstream origin master</code></pre><h2 id="移除commit">2.3&emsp;移除commit</h2><h3 id="移除之前所有的commit">2.3.1&emsp;移除之前所有的commit</h3><p>这种情况比较少，一般是删了一些文件不想让别人看到，所以<code>commit</code>也需要清空：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> checkout --orphan latest_branch   <span class="token comment" spellcheck="true">#新建并切换到一个本地分支</span><span class="token function">git</span> add -A<span class="token function">git</span> commit -am <span class="token string">"delete all of the previous commit messages"</span><span class="token function">git</span> branch -D master     <span class="token comment" spellcheck="true">#删除master分支</span><span class="token function">git</span> branch -m master     <span class="token comment" spellcheck="true">#重命名当前分支为master</span><span class="token function">git</span> push -f origin master    <span class="token comment" spellcheck="true">#强制更新</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="回滚到之前某个版本">2.3.2&emsp;回滚到之前某个版本</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> log  <span class="token comment" spellcheck="true">#查看想要回滚到的版本代号</span><span class="token function">git</span> reset --hard CommitID   <span class="token comment" spellcheck="true">#回滚当前分支到该版本，本地</span><span class="token function">git</span> push -f  <span class="token comment" spellcheck="true">#强制更新</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h3 id="删除中间某些commit">2.3.3&emsp;删除中间某些commit</h3><p>这种情况比较复杂；比如发现之前某个版本的改动需要删除，但那个版本之后的改动又需要保留  </p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> log    <span class="token comment" spellcheck="true">#查看待删除分支之前的那个commit的ID</span><span class="token function">git</span> checkout -b fixing CommitID   <span class="token comment" spellcheck="true">#切出来一个新分支</span><span class="token function">git</span> merge -s ours CommitID_2    <span class="token comment" spellcheck="true">#这里的commitID为待删除commit中最新的那一个</span><span class="token comment" spellcheck="true"># -s : strategy ; ours表示保留当前分支内容，theirs表示保留另一个版本而放弃当前版本</span><span class="token function">git</span> merge master    <span class="token comment" spellcheck="true">#再合并CommitID_2后的commit （可能会出现冲突）</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="Add与Commit操作">2.4&emsp;Add与Commit操作</h2><h3 id="只提交已有文件改动，不新增文件">2.4.1&emsp;只提交已有文件改动，不新增文件</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> commit -a<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h3 id="撤销改动">2.4.2&emsp;撤销改动</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> reset    <span class="token comment" spellcheck="true">#撤销add操作</span><span class="token function">git</span> reset --hard    <span class="token comment" spellcheck="true">#重置所有改动，至上一commit状态</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h3 id="修改上次commit">2.4.3&emsp;修改上次commit</h3><p>已经commit完，发现漏掉文件:</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> add files<span class="token function">git</span> commit --amend<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>先撤销上次commit，但不修改文件：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> reset --soft HEAD^<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h3 id="从仓库中去掉某文件">2.4.4&emsp;从仓库中去掉某文件</h3><p>有时发现仓库里上传了不该传的东西，需要删除：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 建立一个.gitignore文件，写入忽略的文件名单</span><span class="token comment" spellcheck="true"># 删除仓库中已有文件</span><span class="token function">git</span> <span class="token function">rm</span> --cached filename   <span class="token comment" spellcheck="true">#但保留了本地文件</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="远程分支">2.5&emsp;远程分支</h2><h3 id="拉取一个远程分支">2.5.1&emsp;拉取一个远程分支</h3><p>且当前仓库不存在该分支：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> fetch  <span class="token comment" spellcheck="true">#同步本地仓库</span><span class="token function">git</span> checkout <span class="token function">test</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h3 id="删除远程分支">2.5.2&emsp;删除远程分支</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> push origin --delete <span class="token function">test</span><span class="token comment" spellcheck="true"># 注意:</span><span class="token function">git</span> branch -D <span class="token function">test</span>    <span class="token comment" spellcheck="true">#只是删除了本地分支</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h3 id="推送本地新分支到远程">2.5.3&emsp;推送本地新分支到远程</h3><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> push --set-upstream origin new_branch<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2020-01-08-git-learning/#disqus_thread</comments>
    </item>
    
    <item>
      <title>fvSchemes学习</title>
      <link>https://chengpengzhao.com/2019-12-15-fvschemes-xue-xi/</link>
      <guid>https://chengpengzhao.com/2019-12-15-fvschemes-xue-xi/</guid>
      <pubDate>Sun, 15 Dec 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;在学习fvSchemes
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>在学习fvSchemes之前，先得把CFD课程过一遍，不然很多格式都不知道是怎么回事。  </p><p>打开终端，输入：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> <span class="token variable">$FOAM_TUTORIALS</span><span class="token function">grep</span> -r  <span class="token string">"Schemes"</span> * -h <span class="token operator">|</span><span class="token function">sort</span> -n<span class="token operator">|</span><span class="token function">uniq</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>可以看到输出里面包含所有关键字：</p><pre class="line-numbers language-cpp"><code class="language-cpp">d2dt2SchemesddtSchemesdivSchemes    echo <span class="token string">"Modifying the fvSchemes to contain only default schemes"</span><span class="token operator">-</span>e s<span class="token operator">/</span><span class="token string">"\(fvSchemes[ \t]*\)\([0-9]\);"</span><span class="token operator">/</span><span class="token string">"\1 1;"</span><span class="token operator">/</span>g \    <span class="token keyword">for</span> FV_SC in `find <span class="token punctuation">.</span> <span class="token operator">-</span>name fvSchemes`gradSchemesgradSchemes <span class="token punctuation">{</span> <span class="token keyword">default</span> Gauss linear<span class="token punctuation">;</span> <span class="token punctuation">}</span>    integrationSchemesinterpolationSchemes    interpolationSchemesinterpolationSchemes <span class="token punctuation">{</span> <span class="token keyword">default</span> linear<span class="token punctuation">;</span> <span class="token punctuation">}</span>laplacianSchemeslaplacianSchemes <span class="token punctuation">{</span> <span class="token keyword">default</span> Gauss linear corrected<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token operator">*</span> limited corrected <span class="token number">0.5</span> on all laplacianSchemes because the mesh is so poor    object      fvSchemes<span class="token punctuation">;</span>SCHEMES_FILE<span class="token operator">=</span><span class="token string">"FvSchemes"</span>SCHEMES_TEMP<span class="token operator">=</span><span class="token string">"FvSchemes.temp"</span><span class="token function">setDefaultFvSchemes</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        setDefaultFvSchemes <span class="token operator">>></span> $<span class="token punctuation">{</span>FV_SC<span class="token punctuation">}</span>snGradSchemessnGradSchemes <span class="token punctuation">{</span> <span class="token keyword">default</span> corrected<span class="token punctuation">;</span> <span class="token punctuation">}</span>    solver setting in fvSolution <span class="token operator">and</span> a <span class="token function">div</span><span class="token punctuation">(</span>phi<span class="token punctuation">,</span>age<span class="token punctuation">)</span> scheme in fvSchemes<span class="token punctuation">.</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>稍微整理下，关键字有：</p><pre class="line-numbers language-cpp"><code class="language-cpp">d2dt2SchemesddtSchemesdivSchemesgradSchemesinterpolationSchemeslaplacianSchemessnGradSchemes<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><strong>这里就涉及到一个小技巧，当不知道某一个关键词有哪些可选项的时候该怎么办</strong></p><ol><li>banana方法<br>我是在wolf dynamic的教程中学到的，即将一个选项的值替换成一个肯定不存在的值，如<code>banana</code>，这样就可以从输出信息中找到有哪些选项。（当然在某些情况这个方法不起作用）  </li><li>利用Linux自身的强大查找命令，如<code>grep</code>、<code>find</code>…我还没怎么学会，平时就用用简单的grep。  </li><li>利用OpenFOAM自带命令，如<code>foamInfo</code>、<code>foamSearch</code>等，缺点是说明比较少，不知道哪些能搜到哪些搜不到，一切随缘。常见用法，如：<pre class="line-numbers language-bash"><code class="language-bash"> foamSearch <span class="token variable">$FOAM_TUTORIALS</span> fvSchemes ddtSchemes.default foamSearch <span class="token variable">$FOAM_TUTORIALS</span> fvSchemes <span class="token string">"divSchemes.div(phi,U)"</span> foamSearch -c <span class="token variable">$FOAM_TUTORIALS</span> fvSolution solvers.p.solver <span class="token comment" spellcheck="true">#-c 则会统计每个关键词信息出现的数量</span> foamSearch <span class="token variable">$FOAM_TUTORIALS</span> RAS.RASModel turbulenceProperties<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre> 可见foamSearch这一命令用的好的话对学习OpenFOAM还是很有帮助的  </li><li>直接从代码里找？ 这个我没试过，因为C++还没到家，看着头疼，不过能看的懂代码的话应该会好很多。</li><li>Vim里的<code>vim-OpenFoam-syntax</code>插件，带有自动提示补全功能，有一定作用但需要有一些经验才能很好使用。</li></ol><h1 id="总览">2&emsp;总览</h1><h2 id="文件实例">2.1&emsp;文件实例</h2><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">//文件说明</span>FoamFile<span class="token punctuation">{</span>version     <span class="token number">2.0</span><span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//版本号</span>format      ascii<span class="token punctuation">;</span>              <span class="token comment" spellcheck="true">//文本格式</span><span class="token keyword">class</span>       <span class="token class-name">dictionary</span><span class="token punctuation">;</span>         <span class="token comment" spellcheck="true">//类型为字典文件</span>location    <span class="token string">"system"</span><span class="token punctuation">;</span>           <span class="token comment" spellcheck="true">//所在目录</span>object      fvSchemes<span class="token punctuation">;</span>          <span class="token comment" spellcheck="true">//对象名</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//时间一阶导项(非定常项)格式</span>ddtSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         Euler<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//梯度项格式</span>gradSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         Gauss linear<span class="token punctuation">;</span><span class="token function">grad</span><span class="token punctuation">(</span>T<span class="token punctuation">)</span>         Gauss linear<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//散度项格式</span>divSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         none<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//拉普拉斯项格式</span>laplacianSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         none<span class="token punctuation">;</span><span class="token function">laplacian</span><span class="token punctuation">(</span>DT<span class="token punctuation">,</span>T<span class="token punctuation">)</span> Gauss linear corrected<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//插值格式</span>interpolationSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         linear<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//面法向梯度格式</span>snGradSchemes<span class="token punctuation">{</span><span class="token keyword">default</span>         corrected<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment" spellcheck="true">//需要用来计算通量的场</span>fluxRequired<span class="token punctuation">{</span><span class="token keyword">default</span>         no<span class="token punctuation">;</span>T<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="keywords">2.2&emsp;keywords</h2><table><thead><tr><th align="center">子字典关键字</th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>interpolationSchemes</code></td><td align="center">网格体心至面心插值格式</td></tr><tr><td align="center"><code>snGradSchemes</code></td><td align="center">面法向梯度格式</td></tr><tr><td align="center"><code>timeScheme</code></td><td align="center">时间导数项$\frac{\partial}{\partial t}$ $\frac{\partial ^2}{\partial t^2}$</td></tr><tr><td align="center"><code>divSchemes</code></td><td align="center">散度(对流)项格式 $\nabla \cdot$</td></tr><tr><td align="center"><code>gradSchemes</code></td><td align="center">梯度项格式$\nabla$</td></tr><tr><td align="center"><code>laplacianSchemes</code></td><td align="center">拉普拉斯项格式$\nabla ^2$</td></tr><tr><td align="center"><code>fluxRequired 如(wallDist)</code></td><td align="center">需要计算通量的场</td></tr></tbody></table><blockquote><p>以下结果与OpenFOAM版本有关，我用的是OpenFoam-dev(7)</p></blockquote><pre class="line-numbers language-cpp"><code class="language-cpp">Valid schemes are <span class="token operator">:</span><span class="token function">61</span><span class="token punctuation">(</span>CoBlendedGammaGammaVLUSTMUSCLMUSCLVMinmodMinmodVOSPREOSPREVPhiQUICKQUICKVSFCDSFCDVSuperBeeSuperBeeVUMISTUMISTVbiLinearFitblendedcellCoBlendedclippedLinearcubiccubicUpwindFitdownwindfilteredLinearfilteredLinear2filteredLinear2VfilteredLinear3filteredLinear3VfixedBlendedlimitWithlimitedCubiclimitedCubicVlimitedLinearlimitedLinearVlimiterBlendedlinearlinearFitlinearPureUpwindFitlinearUpwindlinearUpwindVlocalBlendedlocalMaxlocalMinmidPointoutletStabilisedpointLinearquadraticFitquadraticLinearFitquadraticLinearUpwindFitquadraticUpwindFitreverseLinearskewCorrectedupwindvanAlbadavanAlbadaVvanLeervanLeerVweighted<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="关于default">2.3&emsp;关于default</h2><p>如果…Schemes 子字典中的 default关键词已经被指定， 那么子字典中所有的项都会应用这个格式。用户也可以指定 default 为 none。 这种情况下，用户必须强制为每个项指定离散格式。<br>推荐把default指定为none，这样的话强制用户对方程的每个需要离散的项进行设定，有助于对问题的理解。<br>总的来说就是<strong>从ERROR中学习</strong>。</p><h1 id="逐项分析">3&emsp;逐项分析</h1><p>可参考OpenFOAM官网的<a href="https://www.openfoam.com/documentation/guides/latest/doc/guide-schemes.html" target="_blank" rel="noopener">Extended Code Guide</a>，上面有一些说明。</p><h2 id="ddtSchemes-frac-partial-partial-t-left-phi-right">3.1&emsp;ddtSchemes $\frac{\partial }{\partial t}\left(\phi\right)$</h2><pre class="line-numbers language-cpp"><code class="language-cpp">Valid ddt schemes are <span class="token operator">:</span><span class="token function">8</span><span class="token punctuation">(</span>CoEulerCrankNicolsonEulerSLTSbackwardboundedlocalEulersteadyState<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="CoEuler">3.1.1&emsp;CoEuler</h3><p>Courant number <strong>limited first-order Euler</strong> implicit/explicit ddt.<br>This scheme should only be used for <strong>steady-state</strong> computations using transient codes where <strong>local time-stepping</strong> is preferable to under-relaxation for transport consistency reasons.<br>例子，如：</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token keyword">default</span> CoEuler phi rho <span class="token number">1</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><ul><li>phiName: Name of the flux field used to calculate the local time-step </li><li>rhoName: Name of the density field used to obtain the volumetric flux from the mass flux if required </li><li>maxCo: Maximum local Courant number</li></ul><h3 id="CrankNicolson">3.1.2&emsp;CrankNicolson</h3><p><strong>Second-order</strong> Crank-Nicolson implicit ddt using the current and previous time-step fields as well as the previous time-step ddt.<br>The Crank-Nicolson scheme is often <strong>unstable</strong> for complex flows in complex geometries and it is necessary to “off-centre” the scheme to stabilize it while retaining <strong>greater temporal accuracy than the first-order Euler-implicit scheme</strong>.  Off-centering is specified via the mandatory coefficient \c ocCoeff in the range [0,1] following the scheme name e.g.</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token keyword">default</span>         CrankNicolson <span class="token number">0.9</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>or with an optional “ramp” function to transition from the Euler scheme to Crank-Nicolson over a initial period to avoid start-up problems, e.g.</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token keyword">default</span>         CrankNicolsonocCoeff<span class="token punctuation">{</span>    type scale<span class="token punctuation">;</span>    scale linearRamp<span class="token punctuation">;</span>    duration <span class="token number">0.01</span><span class="token punctuation">;</span>    value <span class="token number">0.9</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>With a coefficient of <strong>1 the scheme is fully centred</strong> and second-order, with a coefficient of <strong>0 the scheme is equivalent to Euler-implicit</strong>.  A coefficient of <strong>0.9</strong> has been found to be suitable for a range of cases for which higher-order accuracy in time is needed and provides similar accuracy and stability to the backward scheme.  However, <strong>the backward scheme has been found to be more robust and provides formal second-order accuracy in time.</strong>  </p><p>The advantage of the Crank-Nicolson scheme over backward is that <strong>only the new and old-time values are needed</strong>, the additional terms relating to the fluxes and sources are evaluated at the mid-point of the time-step which provides the opportunity to limit the fluxes in such a way as to ensure <strong>boundedness</strong> while maintaining <strong>greater accuracy in time compared to the Euler-implicit scheme</strong>.  This approach is now used with MULES in the interFoam family of solvers.  <strong>Boundedness cannot be guaranteed with the backward scheme.</strong><br>Note: The Crank-Nicolson coefficient for the implicit part of the RHS is related to the off-centering coefficient by <code>cnCoeff = 1.0/(1.0 + ocCoeff)</code>;  </p><p>Forward Euler:<br>$$<br>\frac{\partial }{\partial t}\left(\phi^{n}\right)\approx\frac{\phi^{n+1}-\phi^{n}}{\Delta t}<br> \tag{3-1}$$</p><p>Backward Euler:<br>$$<br>\frac{\partial }{\partial t}\left(\phi^{n}\right)\approx\frac{\phi^{n}-\phi^{n-1}}{\Delta t}<br> \tag{3-2}$$</p><p>Fully centred CN:  Forward Euler + Backward Euler:</p><p>$$<br>\frac{\partial }{\partial t}\left(\phi^{n}\right)\approx\frac{\phi^{n+1}-\phi^{n}}{2\Delta t}<br>+\frac{\phi^{n}-\phi^{n-1}}{2\Delta t}=\frac{\phi^{n+1}-\phi^{n-1}}{2\Delta t}<br> \tag{3-3}$$<br>假设 ocCoeff: $\lambda$，则：<br>$$<br>\frac{\partial }{\partial t}\left(\phi^{n}\right)\approx\frac{\lambda}{1+\lambda}\frac{\phi^{n+1}-\phi^{n}}{\Delta t}+\frac{1}{1+\lambda}\frac{\phi^{n}-\phi^{n-1}}{\Delta t}<br> \tag{3-4}$$<br>显然，当 $\lambda=0$ ，退化成Backward Euler； $\lambda=1$，为完全的CrankNicolson格式。</p><blockquote><p>突然发现有好多要学的，未完待续…&emsp;&emsp;<em>2019-12-16 00:03:56</em></p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-12-15-fvschemes-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Airfoil optimization for Vertical Axis Hydrokinetic Turbine using genetic algorithm(3)---Evaluation of PARSEC parametrization</title>
      <link>https://chengpengzhao.com/2019-12-11-evaluation-of-parsec-paraterization/</link>
      <guid>https://chengpengzhao.com/2019-12-11-evaluation-of-parsec-paraterization/</guid>
      <pubDate>Wed, 11 Dec 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;Evaluation-of-PARSEC-parametrizat
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="Evaluation-of-PARSEC-parametrization">1&emsp;Evaluation of PARSEC parametrization</h1><p>The principles that parametrization technique should satisfy are:</p><ul><li>Minimize the number of degrees of freedom.</li><li>Be able to represent a wide range of existing airfoils.</li><li>Parameters should be simple to formulate and impose.</li><li>The parametrization should result in effective and efficient optimization.</li></ul><p>The parametric section(PARSEC) parametrization scheme, which uses the unknown linear combination of base functions to express characteristics of the airfoil, uses 11 different geometrical characteristics of airfoil to solve a system of linear equations. The describing parameters are less enough and sometimes even limit the accuracy and robustness of this method. On the other hand, the physical-based parameters can avoid arbitrary airfoil geometry, which leads to good convergence when combined with genetic algorithm or other optimization methods.<br>The PARSEC parameters are easy to understand and impose too, so the left question is whether this parametrization scheme can represent a wide range of existing airfoils.</p><h1 id="Representation-of-NACA0012-airfoil-by-PARSEC-parametrization">2&emsp;Representation of NACA0012 airfoil by PARSEC parametrization</h1><p>The purpose of Representation is to analyse the residual differences between the approximate and the official airfoil shape. Actually, it’s difficult to tell the differences on figures because they are hardly discernible. Thus a quantitative analysis is proposed.</p><h2 id="Fitting-analysis">2.1&emsp;Fitting analysis</h2><p>Kulfan<sup id="fnref:1"><a href="#fn:1" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="KULFAN B M, BUSSOLETTI J E. 《Fundamental》 Parametric Geometry Representations for Aircraft Component Shapes[J]. 2006: 46. .">[1]</span></a></sup> suggested that the residual differences between the approximated airfoils and the actual airfoil geometry show be compared with typical wind tunnel model tolerance, which the tighter tolerance for $\frac{x}{c}\leqslant20%$ is less than the thickness of a piece of printer paper.  </p><p>$$<br>z^{error}=|z^{target}-z^{approx}|<br> \tag{2-1}$$</p><p>And the tolerance criterion<sup id="fnref:2"><a href="#fn:2" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="KULFAN B M. Universal Parametric Geometry Representation Method[J/OL]. Journal of Aircraft, 2008, 45(1): 142–158[2019–12–09]. https://arc.aiaa.org/doi/10.2514/1.29958. DOI:10.2514/1.29958.">[2]</span></a></sup> is: </p><p>$$<br>z^{error}&lt;\left{<br>\begin{aligned}<br>    4\times10^{-4}, \frac{x}{c}&lt;0.2 \<br>    8\times10^{-4}, \frac{x}{c}&gt;0.2<br>\end{aligned}<br>\right.<br> \tag{2-2}$$<br>The representation process is conducted by using the genetic algorithm, defining the matching residual as the object function. Root-mean-square error(RMSE) is calculated by the following expression:  </p><p>$$<br>RMSE_{Z}=\left(\frac{1}{N} \sum_{i=1}^{N}\left(z_{i}^{ \text { target }}-z_{i}^{\text {approx }}\right)^{2}\right)^{1/2}<br> \tag{2-3}$$</p><h2 id="Genetic-algorithm">2.2&emsp;Genetic algorithm</h2><p>Genetic algorithms(GA)<sup id="fnref:3"><a href="#fn:3" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="MUKESH R, LINGADURAI K, SELVAKUMAR U. Airfoil Shape Optimization Using Non-Traditional Optimization Technique and Its Validation[J/OL]. Journal of King Saud University - Engineering Sciences, 2014, 26(2): 191–197[2019–12–10]. https://linkinghub.elsevier.com/retrieve/pii/S1018363913000159. DOI:10.1016/j.jksues.2013.04.003.">[3]</span></a></sup> is a robust and accurate method for global aerodynamic shape optimization and this can be often suggested in the literature. In contrast to gradient optimization approaches, it offers an alternative approach with several attractive features. The basic idea associated with the GA is to search for optimal solutions using an analogy to the theory of evolution.   </p><p>During solution advance (or “evolution” using GA terminology) each chromosome is ranked according to its fitness vector––one fitness value for each objective. The higher-ranking chromosomes are selected to continue to the next generation while the probability of the selection of lower-ranking chromosomes is less.   </p><p>In every generation, a new set of artificial creatures (strings) is created using bits and pieces of the fittest of the old;an occasional new part is tried for good measure. While randomized, genetic algorithms are no simple random walk. They efficiently exploit historical information to speculate on new search points with expected improved performance. The newly selected chromosomes in the next generation are manipulated using various operators (combination, crossover, or mutation) to create the final set of chromosomes for the new generation. These chromosomes are then evaluated for fitness and the process continues––iterating from generation to generation––until a suitable level of convergence is obtained or until a specified number of generations has been completed.  </p><p>GA optimization requires no gradients; it does not need the sensitivity of derivatives. It theoretically works well in non-smooth design spaces containing several or perhaps many local extrema. It is also an attractive method for multi-objective design optimization applications offering the ability to compute the so called “Pareto optimal sets” instead of the limited single design point traditionally provided by other methods. The basic genetic algorithm important steps and the work flow of the GA is depicted in the next figure:<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191211231210.webp" alt title="GA"></p><p>The optimization process uses Dakota software, and here’s the relating <code>.in</code> file settings:  </p><pre><code>method soga  seed = 10525  max_function_evaluations = 2000  initialization_type   unique_random  crossover_type   multi_point_parameterized_binary = 2   crossover_rate = 0.8  mutation_type   offset_normal    mutation_scale = 0.1  fitness_type    merit_function  replacement_type   elitist  convergence_type   best_fitness_tracker   percent_change = 0.05   num_generations = 10</code></pre><h2 id="Results">2.3&emsp;Results</h2><h3 id="Figures">2.3.1&emsp;Figures</h3><p>The iteration history of GA shows the matching residual drops into a very low level after about 20 generation.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191211233103.webp" alt title="iteration history"><br>The error comparison with typical wind tunnel tolerance represents that only a slight part is beyond the value, which indicates the PARSEC approximate airfoil matches the actual NACA0012 airfoil geometry well.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191211234037.webp" alt title="Typical WT Model Tolerance"><br>And the figure below shows that the PARSEC parametrization can represent a large range of airfoils.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191211234705.webp" alt></p><p>The last figure is a comparison between approximate and actual NACA0012 airfoil.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191211234818.webp" alt></p><h3 id="Code">2.3.2&emsp;Code</h3><p><em>plot iteration history from Dakota output files</em></p><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">from</span> __future__ <span class="token keyword">import</span> division<span class="token keyword">import</span> os<span class="token keyword">import</span> reg <span class="token operator">=</span> os<span class="token punctuation">.</span>walk<span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span>files <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token keyword">for</span> path<span class="token punctuation">,</span> dir_list<span class="token punctuation">,</span> file_list <span class="token keyword">in</span> g<span class="token punctuation">:</span>    <span class="token keyword">for</span> file_name <span class="token keyword">in</span> file_list<span class="token punctuation">:</span>        files<span class="token punctuation">.</span>append<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>path<span class="token punctuation">,</span>                                  file_name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">for</span> item <span class="token keyword">in</span> files<span class="token punctuation">:</span>    <span class="token keyword">if</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'population_(.*).dat'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">:</span>        <span class="token keyword">continue</span>    <span class="token keyword">else</span><span class="token punctuation">:</span>        num <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'population_(.*).dat'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>        <span class="token keyword">with</span> open<span class="token punctuation">(</span><span class="token string">'population_'</span> <span class="token operator">+</span> num <span class="token operator">+</span> <span class="token string">'.dat'</span><span class="token punctuation">,</span> <span class="token string">'r'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>            lines <span class="token operator">=</span> f<span class="token punctuation">.</span>readlines<span class="token punctuation">(</span><span class="token punctuation">)</span>            x <span class="token operator">=</span> <span class="token punctuation">[</span>float<span class="token punctuation">(</span>num<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token operator">*</span> len<span class="token punctuation">(</span>lines<span class="token punctuation">)</span>            y <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>            <span class="token keyword">for</span> line <span class="token keyword">in</span> lines<span class="token punctuation">:</span>                line <span class="token operator">=</span> line<span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>                line <span class="token operator">=</span> line<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">'\t'</span><span class="token punctuation">)</span>                y<span class="token punctuation">.</span>append<span class="token punctuation">(</span>float<span class="token punctuation">(</span>line<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        f <span class="token operator">=</span> open<span class="token punctuation">(</span><span class="token string">'population_data.txt'</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">)</span>        <span class="token keyword">for</span> i <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>            f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>str<span class="token punctuation">(</span>x<span class="token punctuation">[</span>i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'  '</span> <span class="token operator">+</span> str<span class="token punctuation">(</span>y<span class="token punctuation">[</span>i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span>            f<span class="token punctuation">.</span>write<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span>        f<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><em>plot a large range of airfoils</em></p><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">import</span> re<span class="token keyword">import</span> os<span class="token keyword">import</span> matplotlib<span class="token punctuation">.</span>pyplot <span class="token keyword">as</span> plt<span class="token keyword">def</span> <span class="token function">findpath_and_plot</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">:</span>    current <span class="token operator">=</span> os<span class="token punctuation">.</span>getcwd<span class="token punctuation">(</span><span class="token punctuation">)</span>    path <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'(.*?)/airfoil_data.txt'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>    os<span class="token punctuation">.</span>chdir<span class="token punctuation">(</span>path<span class="token punctuation">)</span>    X<span class="token punctuation">,</span> Low<span class="token punctuation">,</span> Up <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>    f <span class="token operator">=</span> open<span class="token punctuation">(</span><span class="token string">'airfoil_data.txt'</span><span class="token punctuation">,</span> <span class="token string">'r'</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> line <span class="token keyword">in</span> f<span class="token punctuation">.</span>readlines<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        value <span class="token operator">=</span> <span class="token punctuation">[</span>float<span class="token punctuation">(</span>s<span class="token punctuation">)</span> <span class="token keyword">for</span> s <span class="token keyword">in</span> line<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">]</span>        X<span class="token punctuation">.</span>append<span class="token punctuation">(</span>value<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>        Low<span class="token punctuation">.</span>append<span class="token punctuation">(</span>value<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span>        Up<span class="token punctuation">.</span>append<span class="token punctuation">(</span>value<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span>    plt<span class="token punctuation">.</span>plot<span class="token punctuation">(</span>X<span class="token punctuation">,</span> Low<span class="token punctuation">,</span> X <span class="token punctuation">,</span> Up<span class="token punctuation">)</span>    os<span class="token punctuation">.</span>chdir<span class="token punctuation">(</span>current<span class="token punctuation">)</span><span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span>    g <span class="token operator">=</span> os<span class="token punctuation">.</span>walk<span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span>    files <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>    <span class="token keyword">for</span> path<span class="token punctuation">,</span> dir_list<span class="token punctuation">,</span> file_list <span class="token keyword">in</span> g<span class="token punctuation">:</span>        <span class="token keyword">for</span> file_name <span class="token keyword">in</span> file_list<span class="token punctuation">:</span>            files<span class="token punctuation">.</span>append<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>path<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> item <span class="token keyword">in</span> files<span class="token punctuation">:</span>        <span class="token keyword">if</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'airfoil_data.txt'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">:</span>            <span class="token keyword">continue</span>        <span class="token keyword">else</span><span class="token punctuation">:</span>            findpath_and_plot<span class="token punctuation">(</span>item<span class="token punctuation">)</span>    plt<span class="token punctuation">.</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="References">3&emsp;References</h1><div id="footnotes"><hr><div id="footnotelist"><ol style="list-style: none; padding-left: 0; margin-left: 40px"><li id="fn:1"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">1.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">KULFAN B M, BUSSOLETTI J E. 《Fundamental》 Parametric Geometry Representations for Aircraft Component Shapes[J]. 2006: 46. .<a href="#fnref:1" rev="footnote"> ↩</a></span></li><li id="fn:2"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">2.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">KULFAN B M. Universal Parametric Geometry Representation Method[J/OL]. Journal of Aircraft, 2008, 45(1): 142–158[2019–12–09]. https://arc.aiaa.org/doi/10.2514/1.29958. DOI:10.2514/1.29958.<a href="#fnref:2" rev="footnote"> ↩</a></span></li><li id="fn:3"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">3.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">MUKESH R, LINGADURAI K, SELVAKUMAR U. Airfoil Shape Optimization Using Non-Traditional Optimization Technique and Its Validation[J/OL]. Journal of King Saud University - Engineering Sciences, 2014, 26(2): 191–197[2019–12–10]. https://linkinghub.elsevier.com/retrieve/pii/S1018363913000159. DOI:10.1016/j.jksues.2013.04.003.<a href="#fnref:3" rev="footnote"> ↩</a></span></li></ol></div></div>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-12-11-evaluation-of-parsec-paraterization/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Airfoil optimization for Vertical Axis Hydrokinetic Turbine using genetic algorithm(2)---Modified PARSEC Parametrization</title>
      <link>https://chengpengzhao.com/2019-12-09-parsec/</link>
      <guid>https://chengpengzhao.com/2019-12-09-parsec/</guid>
      <pubDate>Tue, 10 Dec 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;Modified-PARSEC-Parametrization&quot;&gt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="Modified-PARSEC-Parametrization">1&emsp;Modified PARSEC Parametrization</h1><p>As mentioned before, the PARSEC parametrization popularized by Sobieczky actually defines a set of shape functions, and the upper and lower curve of airfoil can be determined by a combination of these functions.</p><p>$$<br>Z_{k}=\sum_{n=1}^{6} a_{n,k}X_{k}^{n-\frac{1}{2}}<br> \tag{1-1}$$</p><p> The original PARSEC parametrization has these 11 parameters, each affecting a physical characteristic of airfoil. However, there is a large range of airfoil profiles that set the trailing edge thickness to zero. Then the physical meaning of trailing edge direction becomes abstract. To avoid this circumstances, several adaptations have been proposed to the original PARSEC, which directly use the trailing edge angle of upper and lower curve( $\theta_{TE,up}$ , $\theta_{TE,low}$) instead of $\alpha_{TE}$ and $\beta_{TE}$. Besides, the x coordinate of trailing edge is set to be 1 for convenience, and the difference of leading edge radius between upper and lower curve is also considered.<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/master/img/20191208182309.webp" alt> <img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191209234914.webp" alt><br>Then the 11 parameters become:</p><ul><li>Leading edge radius $R_{LE,UP} , R_{LE,LOW}$</li><li>upper crest location $X_{UP},Z_{UP}$</li><li>lower crest location $X_{LO},Z_{LO}$</li><li>upper and lower curvature $Z_{XXUP},Z_{XXLO}$</li><li>trailing edge coordinate $Z_{TE}$</li><li>upper trailing edge angle  $\theta_{TE,up}$</li><li>lower trailing edge angle $\theta_{TE,low}$</li></ul><p>The coefficients of shape functions can be found by imposing some constraints, take the upper curve as an example:</p><p>$$<br>\begin{aligned}<br>    Z_{up}=\sum_{n=1}^{6} a_{n}x_{k}^{n-\frac{1}{2}}=a_{1} x^{0.5}+a_{2} x^{1.5}+a_{3} x^{2.5}+a_{4} x^{3.5}+a_{5} x^{4.5}+a_{6} x^{5.5}<br>\end{aligned}<br> \tag{1-2}$$</p><p> The first and second order derivative can be expressed as:</p><p> $$<br> \begin{aligned}<br>     \frac{dZ_{u p}}{dx}=0.5 a_{1} x^{-0.5}+1.5 a_{2} x^{0.5}+2.5 a_{3} x^{1.5}+3.5 a_{4} x^{2.5}+4.5 a_{5} x^{3.5}+5.5 a_{6} x^{4.5}<br> \end{aligned}<br>  \tag{1-3}$$</p><p>$$<br>\begin{aligned}<br>    \frac{d^{2}Z_{u p}}{dx^{2}}=&amp;-0.25 a_{1} x^{-1.5}+0.75 a_{2} x^{-0.5}+3.75 a_{3} x^{0.5}+8.75 a_{4} x^{1.5}\&amp;+15.75 a_{5} x^{2.5}+24.75 a_{6} x^{3.5} \end{aligned}<br>\tag{1-4}$$</p><h2 id="Leading-edge-radius-can-be-calculated-by-the-following-equation">1.1&emsp;Leading edge radius can be calculated by the following equation:</h2><p>$$<br>\begin{aligned}<br>    R_{LE}&amp;=\left| \frac{\left( 1+\left( \frac{dZ}{dx}\right)^{2} \right) ^{\frac{3}{2}}}{\frac{d^{2}Z}{dx^{2}}}\right| <em>{x=x</em>{te}} =\left| \frac{\left[1+\left(\sum_{n=1}^{6}\left(n-\frac{1}{2}\right) a_{n} \cdot x^{n-\frac{3}{2}}\right)^{2}\right]^{\frac{3}{2}}}{\sum_{n=1}^{6}\left(n-\frac{1}{2}\right)\left(n-\frac{3}{2}\right) a_{n} \cdot x^{n-\frac{5}{2}}} \right|\ &amp;=\left|\frac{\left[1+\left(\frac{a_{1}}{2 x^{1 / 2}}+\sum_{n=2}^{6}\left(n-\frac{1}{2}\right) a_{n} \cdot x^{n-\frac{3}{2}}\right)^{2}\right]^{3 / 2} }{-\frac{a}{4 x^{3 / 2}}+\sum_{n=2}^{6}\left(n-\frac{1}{2}\right)\left(n-\frac{3}{2}\right) a_{n} \cdot x^{n-\frac{5}{2}}}\right|\&amp;=\left|\frac{\left(\frac{a_{1}}{2 x^{1 / 2}}\right)^{3}\left[\left(\frac{2 x^{1 / 2}}{a_{1}}\right)^{2}+\left(1+\frac{2 x^{1 / 2}}{a_{1}} \sum_{n=2}^{6}\left(n-\frac{1}{2}\right) a_{n} \cdot x^{n-\frac{3}{2}}\right)^{2}\right]^{3 / 2}}{\left(-\frac{a_{1}}{4 x^{3 / 2}}\right)\left(1+\left(-\frac{4 x^{3 / 2}}{a_{1}}\right) \sum_{n=2}^{6}\left(n-\frac{1}{2}\right)\left(n-\frac{3}{2}\right) a_{n} \cdot x^{n-\frac{5}{2}}\right)}\right|<br>\end{aligned}<br> \tag{1-5}$$<br>When x tends to be zero, then:</p><p>$$<br>R_{LE} \stackrel{x \rightarrow 0}{\longrightarrow}\left|\frac{a_{1}^{2}}{2}\right|<br> \tag{1-6}$$<br>Thus the value $a_1$ for the upper curve $a_{1,up}=\sqrt{2R_{LE,up}}$ , and for the lower curve $a_{1,low}=-\sqrt{2R_{LE,low}}$ .</p><h2 id="At-the-upper-crest-position">1.2&emsp;At the upper crest position:</h2><p>$$<br>z\left( x_{up}\right)=z_{up}=\sum_{n=1}^{6} a_{n}x_{up}^{n-\frac{1}{2}}<br> \tag{1-7}$$</p><h2 id="The-first-order-derivative-at-the-upper-crest-position-is-supposed-to-be-zero-according-to-PARSEC-parametrization">1.3&emsp;The first order derivative at the upper crest position is supposed to be zero according to PARSEC parametrization:</h2><p>$$<br>\left[\frac{dZ_{u p}}{dx}\right]<em>{x=x</em>{up}}=\sum_{n=1}^{6}\left(n-\frac{1}{2}\right) a_{n} \cdot x_{up}^{n-\frac{3}{2}}=0<br> \tag{1-8}$$</p><h2 id="The-second-order-derivative-at-upper-crest-position-is-defined-as-a-control-parameter-Z-XXUP">1.4&emsp;The second order derivative at upper crest position is defined as a control parameter $Z_{XXUP}$ :</h2><p>$$<br>\left[\frac{d^{2}Z_{u p}}{dx^{2}}\right]<em>{x=x</em>{up}}=Z_{XXUP}=\sum_{n=2}^{6}\left(n-\frac{1}{2}\right)\left(n-\frac{3}{2}\right) a_{n} \cdot x_{up}^{n-\frac{5}{2}}<br> \tag{1-9}$$</p><h2 id="The-trailing-edge-angle-can-be-expressed-as">1.5&emsp;The trailing edge angle can be expressed as:</h2><p>$$<br>tan\left(\theta_{te,up}\right)=\left[\frac{dy}{dx}\right]<em>{x=x</em>{te}}=\sum_{n=1}^{6}\left(n-\frac{1}{2}\right) a_{n} \cdot x_{te}^{n-\frac{3}{2}}<br> \tag{1-10}$$</p><h2 id="The-trailing-edge-coordinate-left-X-te-Z-te-right-should-also-satisfy-the-function">1.6&emsp;The trailing edge coordinate $\left(X_{te}, Z_{te}\right)$ should also satisfy the function:</h2><p>$$<br>Z\left(X_{te}\right)=Z_{te}=\sum_{n=1}^{6} a_{n,k}X_{te}^{n-\frac{1}{2}}<br> \tag{1-11}$$</p><p>The coefficients $a_{n}$ can therefore be found by solving (1-6)—(1-11). The matrix form of these equations:</p><p>$$<br>\begin{aligned}<br>\begin{bmatrix}<br> 1&amp; 0 &amp;0  &amp;0  &amp;0  &amp;0 \<br>x_{te}^{\frac{1}{2}} &amp;  x_{te}^{\frac{3}{2}}&amp;  x_{te}^{\frac{5}{2}}&amp;  x_{te}^{\frac{7}{2}}&amp;  x_{te}^{\frac{9}{2}}&amp; x_{te}^{\frac{11}{2}}\<br>x_{up}^{\frac{1}{2}} &amp;  x_{up}^{\frac{3}{2}}&amp;  x_{up}^{\frac{5}{2}}&amp;  x_{up}^{\frac{7}{2}}&amp;  x_{up}^{\frac{9}{2}}&amp; x_{up}^{\frac{11}{2}}\<br> \frac{1}{2}x_{te}^{-\frac{1}{2}}&amp; \frac{3}{2}x_{te}^{\frac{1}{2}} &amp; \frac{5}{2}x_{te}^{\frac{3}{2}} &amp; \frac{7}{2}x_{te}^{\frac{5}{2}} &amp; \frac{9}{2}x_{te}^{\frac{7}{2}} &amp; \frac{11}{2}x_{te}^{\frac{9}{2}}\<br> \frac{1}{2}x_{up}^{-\frac{1}{2}}&amp; \frac{3}{2}x_{up}^{\frac{1}{2}} &amp; \frac{5}{2}x_{up}^{\frac{3}{2}} &amp; \frac{7}{2}x_{up}^{\frac{5}{2}} &amp; \frac{9}{2}x_{up}^{\frac{7}{2}} &amp; \frac{11}{2}x_{up}^{\frac{9}{2}}\<br>-\frac{1}{4}x_{up}^{-\frac{3}{2}} &amp; \frac{3}{4}x_{up}^{-\frac{1}{2}} &amp; \frac{15}{4}x_{up}^{\frac{1}{2}} &amp; \frac{35}{4}x_{up}^{\frac{3}{2}} &amp; \frac{63}{4}x_{up}^{\frac{5}{2}} &amp; \frac{99}{4}x_{up}^{\frac{7}{2}}<br>\end{bmatrix}\begin{bmatrix}<br>a_1\<br>a_2\<br>a_3\<br>a_4\<br>a_5\<br>a_6\<br>\end{bmatrix}=\begin{bmatrix}<br>\sqrt{2R_{LE,up}} \<br>Z_{TE}\<br>Z_{up}\<br>tan\left(\theta_{te,up}\right)\<br>0\<br>Z_{XXUP}\<br>\end{bmatrix}<br>\end{aligned}<br> \tag{1-12}$$<br>Similar equations apply for the lower curve.</p><h1 id="Python-Code">2&emsp;Python Code</h1><p>It’s not difficult to find some scripts about PARSEC parametrization, and actually <a href="https://github.com/dqsis/parsec-airfoils" target="_blank" rel="noopener">This person</a>‘s code helped me a lot(I just need to make some small changes).</p><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">from</span> __future__ <span class="token keyword">import</span> division<span class="token keyword">from</span> math <span class="token keyword">import</span> <span class="token operator">*</span><span class="token keyword">import</span> numpy <span class="token keyword">as</span> np<span class="token keyword">import</span> matplotlib<span class="token punctuation">.</span>pyplot <span class="token keyword">as</span> plt<span class="token comment" spellcheck="true"># ========================================================================================</span><span class="token keyword">def</span> <span class="token function">pcoef</span><span class="token punctuation">(</span>        xte<span class="token punctuation">,</span> yte<span class="token punctuation">,</span> rle<span class="token punctuation">,</span>        x_cre<span class="token punctuation">,</span> y_cre<span class="token punctuation">,</span> d2ydx2_cre<span class="token punctuation">,</span> th_cre<span class="token punctuation">,</span>        surface<span class="token punctuation">)</span><span class="token punctuation">:</span>    <span class="token triple-quoted-string string">"""evaluate the PARSEC coefficients"""</span>    <span class="token comment" spellcheck="true"># Initialize coefficients</span>    coef <span class="token operator">=</span> np<span class="token punctuation">.</span>zeros<span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true"># 1st coefficient depends on surface (pressure or suction)</span>    <span class="token keyword">if</span> surface<span class="token punctuation">.</span>startswith<span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span>sqrt<span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> rle<span class="token punctuation">)</span>    <span class="token keyword">else</span><span class="token punctuation">:</span>        coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">=</span> sqrt<span class="token punctuation">(</span><span class="token number">2</span> <span class="token operator">*</span> rle<span class="token punctuation">)</span>    <span class="token comment" spellcheck="true"># Form system of equations</span>    A <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span>        <span class="token punctuation">[</span>xte <span class="token operator">**</span> <span class="token number">1.5</span><span class="token punctuation">,</span> xte <span class="token operator">**</span> <span class="token number">2.5</span><span class="token punctuation">,</span> xte <span class="token operator">**</span> <span class="token number">3.5</span><span class="token punctuation">,</span> xte <span class="token operator">**</span> <span class="token number">4.5</span><span class="token punctuation">,</span> xte <span class="token operator">**</span> <span class="token number">5.5</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span>x_cre <span class="token operator">**</span> <span class="token number">1.5</span><span class="token punctuation">,</span> x_cre <span class="token operator">**</span> <span class="token number">2.5</span><span class="token punctuation">,</span> x_cre <span class="token operator">**</span> <span class="token number">3.5</span><span class="token punctuation">,</span> x_cre <span class="token operator">**</span> <span class="token number">4.5</span><span class="token punctuation">,</span>         x_cre <span class="token operator">**</span> <span class="token number">5.5</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token number">1.5</span> <span class="token operator">*</span> sqrt<span class="token punctuation">(</span>xte<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2.5</span> <span class="token operator">*</span> xte <span class="token operator">**</span> <span class="token number">1.5</span><span class="token punctuation">,</span> <span class="token number">3.5</span> <span class="token operator">*</span> xte <span class="token operator">**</span> <span class="token number">2.5</span><span class="token punctuation">,</span>         <span class="token number">4.5</span> <span class="token operator">*</span> xte <span class="token operator">**</span> <span class="token number">3.5</span><span class="token punctuation">,</span> <span class="token number">5.5</span> <span class="token operator">*</span> xte <span class="token operator">**</span> <span class="token number">4.5</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token number">1.5</span> <span class="token operator">*</span> sqrt<span class="token punctuation">(</span>x_cre<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2.5</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">1.5</span><span class="token punctuation">,</span> <span class="token number">3.5</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">2.5</span><span class="token punctuation">,</span>         <span class="token number">4.5</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">3.5</span><span class="token punctuation">,</span> <span class="token number">5.5</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">4.5</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token number">0.75</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> sqrt<span class="token punctuation">(</span>x_cre<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">3.75</span> <span class="token operator">*</span> sqrt<span class="token punctuation">(</span>x_cre<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">8.75</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">1.5</span><span class="token punctuation">,</span>         <span class="token number">15.75</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">2.5</span><span class="token punctuation">,</span> <span class="token number">24.75</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token number">3.5</span><span class="token punctuation">]</span>    <span class="token punctuation">]</span><span class="token punctuation">)</span>    B <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span>        <span class="token punctuation">[</span>yte <span class="token operator">-</span> coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> sqrt<span class="token punctuation">(</span>xte<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span>y_cre <span class="token operator">-</span> coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> sqrt<span class="token punctuation">(</span>x_cre<span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span>tan<span class="token punctuation">(</span>th_cre <span class="token operator">*</span> pi <span class="token operator">/</span> <span class="token number">180</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0.5</span> <span class="token operator">*</span> coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> sqrt<span class="token punctuation">(</span>xte<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">0.5</span> <span class="token operator">*</span> coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">/</span> sqrt<span class="token punctuation">(</span>x_cre<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        <span class="token punctuation">[</span>d2ydx2_cre <span class="token operator">+</span> <span class="token number">0.25</span> <span class="token operator">*</span> coef<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> x_cre <span class="token operator">**</span> <span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1.5</span><span class="token punctuation">)</span><span class="token punctuation">]</span>    <span class="token punctuation">]</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true"># Solve system of linear equations</span>    X <span class="token operator">=</span> np<span class="token punctuation">.</span>linalg<span class="token punctuation">.</span>solve<span class="token punctuation">(</span>A<span class="token punctuation">,</span> B<span class="token punctuation">)</span>    <span class="token comment" spellcheck="true"># Gather all coefficients</span>    coef<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">:</span><span class="token number">6</span><span class="token punctuation">]</span> <span class="token operator">=</span> X<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">:</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">]</span>    <span class="token comment" spellcheck="true"># Return coefficients</span>    <span class="token keyword">return</span> coef<span class="token comment" spellcheck="true"># ========================================================================================</span><span class="token comment" spellcheck="true"># Sample coefficients  NACA0012</span><span class="token triple-quoted-string string">'''leading edge radius (rle_suc rle_pre)pressure and suction surface crest locations (x_pre, y_pre, x_suc, y_suc)curvatures at the pressure and suction surface crest locations (d2y/dx2_pre, d2y/dx2_suc)trailing edge coordinates (x_TE, y_TE)trailing edge angles between the pressure and suction surface and the horizontal axis (th_pre, th_suc)'''</span>rle_suc<span class="token operator">=</span> <span class="token punctuation">.</span><span class="token number">014927</span>rle_pre<span class="token operator">=</span> <span class="token punctuation">.</span><span class="token number">014181</span>x_suc <span class="token operator">=</span> <span class="token punctuation">.</span><span class="token number">29866</span>y_suc <span class="token operator">=</span> <span class="token punctuation">.</span><span class="token number">059404</span>x_pre <span class="token operator">=</span> <span class="token punctuation">.</span><span class="token number">29962</span>y_pre <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">0.059632</span>d2ydx2_suc <span class="token operator">=</span> <span class="token operator">-</span><span class="token punctuation">.</span><span class="token number">42399</span>d2ydx2_pre <span class="token operator">=</span> <span class="token number">0.445281</span>yte <span class="token operator">=</span> <span class="token number">0</span>th_suc <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">7.672047</span>th_pre <span class="token operator">=</span> <span class="token number">7.59506</span>xte <span class="token operator">=</span> <span class="token number">1.0</span> <span class="token comment" spellcheck="true"># Trailing edge x position</span><span class="token comment" spellcheck="true"># Evaluate pressure (lower) surface coefficients</span>cf_pre <span class="token operator">=</span> pcoef<span class="token punctuation">(</span>xte<span class="token punctuation">,</span> yte<span class="token punctuation">,</span> rle_pre<span class="token punctuation">,</span>               x_pre<span class="token punctuation">,</span> y_pre<span class="token punctuation">,</span> d2ydx2_pre<span class="token punctuation">,</span> th_pre<span class="token punctuation">,</span>               <span class="token string">'pre'</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true"># Evaluate suction (upper) surface coefficients</span>cf_suc <span class="token operator">=</span> pcoef<span class="token punctuation">(</span>xte<span class="token punctuation">,</span> yte<span class="token punctuation">,</span> rle_suc<span class="token punctuation">,</span>               x_suc<span class="token punctuation">,</span> y_suc<span class="token punctuation">,</span> d2ydx2_suc<span class="token punctuation">,</span> th_suc<span class="token punctuation">,</span>               <span class="token string">'suc'</span><span class="token punctuation">)</span>x <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">1</span> <span class="token operator">-</span> np<span class="token punctuation">.</span>cos<span class="token punctuation">(</span>np<span class="token punctuation">.</span>linspace<span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> np<span class="token punctuation">.</span>ceil<span class="token punctuation">(</span><span class="token number">1e3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">*</span> np<span class="token punctuation">.</span>pi<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span>uppery <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span>lowery <span class="token operator">=</span> np<span class="token punctuation">.</span>array<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">*</span> len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token keyword">for</span> i <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">7</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    uppery <span class="token operator">=</span> uppery <span class="token operator">+</span> cf_suc<span class="token punctuation">[</span>i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">*</span> x <span class="token operator">**</span> <span class="token punctuation">(</span>i <span class="token operator">-</span> <span class="token number">1</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span>    lowery <span class="token operator">=</span> lowery <span class="token operator">+</span> cf_pre<span class="token punctuation">[</span>i <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">]</span> <span class="token operator">*</span> x <span class="token operator">**</span> <span class="token punctuation">(</span>i <span class="token operator">-</span> <span class="token number">1</span> <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true"># ========================================================================================</span><span class="token comment" spellcheck="true"># Plot this airfoil</span><span class="token keyword">def</span> <span class="token function">Naca0012</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">:</span>    y<span class="token operator">=</span><span class="token number">0.594689181</span><span class="token operator">*</span><span class="token punctuation">(</span><span class="token number">0.298222773</span><span class="token operator">*</span>sqrt<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">0.127125232</span><span class="token operator">*</span>x <span class="token operator">-</span> <span class="token number">0.357907906</span><span class="token operator">*</span>x<span class="token operator">**</span><span class="token number">2</span> <span class="token operator">+</span> <span class="token number">0.291984971</span><span class="token operator">*</span>x<span class="token operator">**</span><span class="token number">3</span> <span class="token operator">-</span> <span class="token number">0.105174606</span><span class="token operator">*</span>x<span class="token operator">**</span><span class="token number">4</span><span class="token punctuation">)</span>    <span class="token keyword">return</span> yf2 <span class="token operator">=</span> np<span class="token punctuation">.</span>vectorize<span class="token punctuation">(</span>Naca0012<span class="token punctuation">)</span>Nacay<span class="token operator">=</span>f2<span class="token punctuation">(</span>x<span class="token punctuation">)</span>Error_up<span class="token operator">=</span>Nacay<span class="token operator">-</span>upperyError_lo<span class="token operator">=</span><span class="token operator">-</span>Nacay<span class="token operator">-</span>loweryRMS_up<span class="token operator">=</span><span class="token number">0</span>RMS_lo<span class="token operator">=</span><span class="token number">0</span><span class="token keyword">for</span> item <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span>len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>    RMS_up<span class="token operator">=</span>RMS_up<span class="token operator">+</span><span class="token punctuation">(</span>uppery<span class="token punctuation">[</span>item<span class="token number">-1</span><span class="token punctuation">]</span><span class="token operator">-</span>Nacay<span class="token punctuation">[</span>item<span class="token number">-1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span>    RMS_lo<span class="token operator">=</span>RMS_lo<span class="token operator">+</span><span class="token punctuation">(</span>lowery<span class="token punctuation">[</span>item<span class="token number">-1</span><span class="token punctuation">]</span><span class="token operator">+</span>Nacay<span class="token punctuation">[</span>item<span class="token number">-1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">**</span><span class="token number">2</span>RMS_up<span class="token operator">=</span>sqrt<span class="token punctuation">(</span>RMS_up<span class="token operator">/</span>len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span>RMS_lo<span class="token operator">=</span>sqrt<span class="token punctuation">(</span>RMS_lo<span class="token operator">/</span>len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span>RMS<span class="token operator">=</span>sqrt<span class="token punctuation">(</span><span class="token number">0.5</span><span class="token operator">*</span>RMS_up<span class="token operator">**</span><span class="token number">2</span><span class="token operator">+</span><span class="token number">0.5</span><span class="token operator">*</span>RMS_lo<span class="token operator">**</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#plt.plot(x, uppery, x, lowery)</span><span class="token comment" spellcheck="true">#plt.gca().axis('equal')</span>lines<span class="token operator">=</span>plt<span class="token punctuation">.</span>plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span> uppery<span class="token punctuation">,</span><span class="token string">'o--'</span><span class="token punctuation">,</span>x<span class="token punctuation">,</span>lowery<span class="token punctuation">,</span> <span class="token string">'o--'</span><span class="token punctuation">)</span>plt<span class="token punctuation">.</span>setp<span class="token punctuation">(</span>lines<span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token string">'b'</span><span class="token punctuation">,</span> linewidth<span class="token operator">=</span><span class="token number">2.0</span><span class="token punctuation">)</span>lines2<span class="token operator">=</span>plt<span class="token punctuation">.</span>plot<span class="token punctuation">(</span>x<span class="token punctuation">,</span>Nacay<span class="token punctuation">,</span>x<span class="token punctuation">,</span><span class="token operator">-</span>Nacay<span class="token punctuation">)</span>plt<span class="token punctuation">.</span>setp<span class="token punctuation">(</span>lines2<span class="token punctuation">,</span> color<span class="token operator">=</span><span class="token string">'r'</span><span class="token punctuation">,</span> linewidth<span class="token operator">=</span><span class="token number">2.0</span><span class="token punctuation">)</span>plt<span class="token punctuation">.</span>show<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">with</span> open<span class="token punctuation">(</span><span class="token string">'airfoil_data.txt'</span><span class="token punctuation">,</span> <span class="token string">'w'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span>len<span class="token punctuation">(</span>x<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        f<span class="token punctuation">.</span>write<span class="token punctuation">(</span><span class="token string">"%s\t\t%s\t\t%s\n"</span> <span class="token operator">%</span> <span class="token punctuation">(</span>x<span class="token punctuation">[</span>i<span class="token number">-1</span><span class="token punctuation">]</span><span class="token punctuation">,</span> Error_lo<span class="token punctuation">[</span>i<span class="token number">-1</span><span class="token punctuation">]</span><span class="token punctuation">,</span>Error_up<span class="token punctuation">[</span>i<span class="token number">-1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-12-09-parsec/#disqus_thread</comments>
    </item>
    
    <item>
      <title>controlDict学习</title>
      <link>https://chengpengzhao.com/2019-12-04-controldict-wen-jian-xue-xi/</link>
      <guid>https://chengpengzhao.com/2019-12-04-controldict-wen-jian-xue-xi/</guid>
      <pubDate>Wed, 04 Dec 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;blockquote&gt;
&lt;p&gt;个人学习用，总结、整理了网上一些controlDi
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><blockquote><p>个人学习用，总结、整理了网上一些controlDict解析</p></blockquote><h1 id="文件结构">1&emsp;文件结构</h1><p>一个例子:</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">//文件说明</span><span class="token punctuation">{</span>    version     <span class="token number">2.0</span><span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//版本号</span>    format      ascii<span class="token punctuation">;</span>              <span class="token comment" spellcheck="true">//文本格式</span>    <span class="token keyword">class</span>       <span class="token class-name">dictionary</span><span class="token punctuation">;</span>         <span class="token comment" spellcheck="true">//类型为字典文件</span>    location    <span class="token string">"system"</span><span class="token punctuation">;</span>           <span class="token comment" spellcheck="true">//所在目录</span>    object      controlDict<span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">//对象名</span><span class="token punctuation">}</span>application     interFoam<span class="token punctuation">;</span>          <span class="token comment" spellcheck="true">//求解器名称</span><span class="token comment" spellcheck="true">//时间控制</span>startFrom       startTime<span class="token punctuation">;</span>          <span class="token comment" spellcheck="true">//设置计算开始时间为startTime</span>startTime       <span class="token number">0</span><span class="token punctuation">;</span>                  <span class="token comment" spellcheck="true">//定义startTime</span>stopAt          endTime<span class="token punctuation">;</span>            <span class="token comment" spellcheck="true">//设置计算结束时间为endTime</span>endTime         <span class="token number">3</span><span class="token punctuation">;</span>                  <span class="token comment" spellcheck="true">//定义endTime</span>deltaT          <span class="token number">0.005</span><span class="token punctuation">;</span>              <span class="token comment" spellcheck="true">//设置时间步长</span><span class="token comment" spellcheck="true">//计算结果输出控制</span>writeControl    adjustableRunTime<span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">//按照计算时间控制输出</span>writeInterval   <span class="token number">0.1</span><span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//输出时间间隔,单位秒[s],与writeControl配合使用</span>purgeWrite      <span class="token number">0</span><span class="token punctuation">;</span>                  <span class="token comment" spellcheck="true">//输出是否覆盖先前记录,0为不覆盖,1可用于稳态计算,默认0</span>writeFormat     ascii<span class="token punctuation">;</span>              <span class="token comment" spellcheck="true">//计算结果输出文件格式指定</span>writePrecision  <span class="token number">10</span><span class="token punctuation">;</span>                 <span class="token comment" spellcheck="true">//控制输出有效数字位数,与writeFormat配合使用,默认6</span>writeCompression uncompressed<span class="token punctuation">;</span>      <span class="token comment" spellcheck="true">//是否压缩</span>timeFormat      general<span class="token punctuation">;</span>            <span class="token comment" spellcheck="true">//时间目录名称指定</span>timePrecision   <span class="token number">6</span><span class="token punctuation">;</span>                  <span class="token comment" spellcheck="true">//时间目录名称有效数字位数,与timeFormat配合使用,默认6</span><span class="token comment" spellcheck="true">//时间步长自适应控制</span>adjustTimeStep  yes<span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//是否开启时间步长自适应</span>maxCo           <span class="token number">0.5</span><span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//最大库郎数</span>maxDeltaT       <span class="token number">1.0</span><span class="token punctuation">;</span>                <span class="token comment" spellcheck="true">//最大时间步长</span><span class="token comment" spellcheck="true">//字典读取控制</span>runTimeModifiable yes<span class="token punctuation">;</span>              <span class="token comment" spellcheck="true">//每个时间步是否读取所修改的字典文件设定</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="逐项分析">2&emsp;逐项分析</h1><p><code>system</code>目录下的<code>controlDict</code>文件用来设置 <strong>时间和输入输出控制</strong>，包括 <strong>时间控制</strong>， <strong>计算结果输出控制</strong>，<strong>时间步长自适应控制</strong>， <strong>字典读取控制</strong> 和 <strong>运行时加载库或者函数控制</strong> 五个部分。</p><h2 id="application">2.1&emsp;application</h2><p>查看<code>$FOAM_TUTORIALS</code>里所用到的求解器，输入命令：</p><pre class="line-numbers language-cpp"><code class="language-cpp">foamSearch $FOAM_TUTORIALS controlDict application<span class="token comment" spellcheck="true">//结果显示：</span>application     adjointShapeOptimizationFoam<span class="token punctuation">;</span>application     blockMesh<span class="token punctuation">;</span>application     boundaryFoam<span class="token punctuation">;</span>application     buoyantPimpleFoam<span class="token punctuation">;</span>application     buoyantSimpleFoam<span class="token punctuation">;</span>application     cavitatingFoam<span class="token punctuation">;</span>application     chemFoam<span class="token punctuation">;</span>application     chtMultiRegionFoam<span class="token punctuation">;</span>application     coalChemistryFoam<span class="token punctuation">;</span>application     coldEngineFoam<span class="token punctuation">;</span>application     compressibleInterFoam<span class="token punctuation">;</span>application     compressibleMultiphaseInterFoam<span class="token punctuation">;</span>application     dnsFoam<span class="token punctuation">;</span>application     DPMFoam<span class="token punctuation">;</span>application     driftFluxFoam<span class="token punctuation">;</span>application     dsmcFoam<span class="token punctuation">;</span>application     electrostaticFoam<span class="token punctuation">;</span>application     financialFoam<span class="token punctuation">;</span>application     fireFoam<span class="token punctuation">;</span>application     foamyHexMesh<span class="token punctuation">;</span>application     icoFoam<span class="token punctuation">;</span>application     icoUncoupledKinematicParcelFoam<span class="token punctuation">;</span>application     interFoam<span class="token punctuation">;</span>application     interMixingFoam<span class="token punctuation">;</span>application     interPhaseChangeFoam<span class="token punctuation">;</span>application     laplacianFoam<span class="token punctuation">;</span>application     mdEquilibrationFoam<span class="token punctuation">;</span>application     mdFoam<span class="token punctuation">;</span>application     mhdFoam<span class="token punctuation">;</span>application     moveDynamicMesh<span class="token punctuation">;</span>application     MPPICFoam<span class="token punctuation">;</span>application     multiphaseEulerFoam<span class="token punctuation">;</span>application     multiphaseInterFoam<span class="token punctuation">;</span>application     nonNewtonianIcoFoam<span class="token punctuation">;</span>application     PDRFoam<span class="token punctuation">;</span>application     pimpleFoam<span class="token punctuation">;</span>application     pisoFoam<span class="token punctuation">;</span>application     porousSimpleFoam<span class="token punctuation">;</span>application     potentialFoam<span class="token punctuation">;</span>application     potentialFreeSurfaceFoam<span class="token punctuation">;</span>application     reactingFoam<span class="token punctuation">;</span>application     reactingMultiphaseEulerFoam<span class="token punctuation">;</span>application     reactingParcelFoam<span class="token punctuation">;</span>application     reactingTwoPhaseEulerFoam<span class="token punctuation">;</span>application     rhoCentralFoam<span class="token punctuation">;</span>application     rhoPimpleFoam<span class="token punctuation">;</span>application     rhoPorousSimpleFoam<span class="token punctuation">;</span>application     rhoSimpleFoam<span class="token punctuation">;</span>application     scalarTransportFoam<span class="token punctuation">;</span>application     shallowWaterFoam<span class="token punctuation">;</span>application     simpleFoam<span class="token punctuation">;</span>application     simpleReactingParcelFoam<span class="token punctuation">;</span>application     snappyHexMesh<span class="token punctuation">;</span>application     solidDisplacementFoam<span class="token punctuation">;</span>application     solidEquilibriumDisplacementFoam<span class="token punctuation">;</span>application     sprayFoam<span class="token punctuation">;</span>application     SRFPimpleFoam<span class="token punctuation">;</span>application     SRFSimpleFoam<span class="token punctuation">;</span>application     twoLiquidMixingFoam<span class="token punctuation">;</span>application     twoPhaseEulerFoam<span class="token punctuation">;</span>application     XiEngineFoam<span class="token punctuation">;</span>application     XiFoam<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>tutorial里基本上平时常用到的、不常用的solver都有，根据自己的研究方向选几个相关的再慢慢研究细节吧。</p><h2 id="时间控制">2.2&emsp;时间控制</h2><h3 id="startFrom-startTime">2.2.1&emsp;startFrom, startTime</h3><table><thead><tr><th align="center"><strong>startFrom</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>firstTime</code></td><td align="center">所有时间目录中最早的时间步</td></tr><tr><td align="center"><code>latestTime</code></td><td align="center">所有时间目录中最近的时间步</td></tr><tr><td align="center"><code>startTime</code></td><td align="center">用户指定开始时间，需指定<code>startTime</code>的值</td></tr></tbody></table><h3 id="stopAt-endTime">2.2.2&emsp;stopAt, endTime</h3><table><thead><tr><th align="center"><strong>stopAt</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>endTime</code></td><td align="center">用户指定结束时间，需指定<code>endTime</code>的值</td></tr><tr><td align="center"><code>writeNow</code></td><td align="center">当前时间步完成时结束计算并且输出计算结果</td></tr><tr><td align="center"><code>noWriteNow</code></td><td align="center">当前时间步完成时结束计算但不输出计算结果</td></tr><tr><td align="center"><code>nextWrite</code></td><td align="center">下一个时间步完成时结束计算并且输出计算结果</td></tr></tbody></table><h3 id="deltaT">2.2.3&emsp;deltaT</h3><p>时间步长控制，有时需要控制 $Co=\frac{\delta t|U|}{\delta x}&lt;1$ $\delta t$ 为时间步、就是这的deltaT; $|U|$ 为某网格单元内的速度矢量的模 $\delta x$ 为速度方向的网格长度。</p><h2 id="输出控制">2.3&emsp;输出控制</h2><h3 id="writeControl-writeInterval">2.3.1&emsp;writeControl,writeInterval</h3><table><thead><tr><th align="center"><strong>writeControl</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>timeStep</code></td><td align="center">按照时间步输出，间隔由关键字<code>writeInterval</code>指定</td></tr><tr><td align="center"><code>runTime</code></td><td align="center">按照计算时间输出，间隔由关键字<code>writeInterval</code>指定</td></tr><tr><td align="center"><code>adjustableRunTime</code></td><td align="center">时间自适应下按照计算时间输出，间隔由关键字<code>writeInterval</code>指定</td></tr><tr><td align="center"><code>cpuTime</code></td><td align="center">按照CPU时间输出，间隔由关键字<code>writeInterval</code>指定</td></tr><tr><td align="center"><code>clockTime</code></td><td align="center">按照挂钟时间(真实时间)输出，间隔由关键字<code>writeInterval</code>指定</td></tr></tbody></table><h3 id="purgeWrite">2.3.2&emsp;purgeWrite</h3><table><thead><tr><th align="center">0</th><th align="center">关闭该功能，不覆盖输出结果</th></tr></thead><tbody><tr><td align="center">n(n为大于0的整数)</td><td align="center">输出n次数据后，自动覆盖先前输出结果</td></tr></tbody></table><h3 id="writeFormat-writePrecision">2.3.3&emsp;writeFormat,writePrecision</h3><table><thead><tr><th align="center"><strong>writeFormat</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>ascii</code></td><td align="center">文本格式，由<code>writePrecision</code>控制有效数字位数，方便阅读</td></tr><tr><td align="center"><code>binary</code></td><td align="center">二进制格式，直接将内存内容写入文件，能够减小文件存储空间，提高读写效率</td></tr></tbody></table><h3 id="writeCompression-timeFormat-timePrecision">2.3.4&emsp;writeCompression, timeFormat, timePrecision</h3><table><thead><tr><th align="center"><strong>writeCompression</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>off</code></td><td align="center">不压缩</td></tr><tr><td align="center"><code>on</code></td><td align="center">gzip 压缩格式</td></tr></tbody></table><table><thead><tr><th align="center"><strong>timeFormat</strong></th><th align="center">说明</th></tr></thead><tbody><tr><td align="center"><code>fixed</code></td><td align="center"><code>±m.dddddd</code>，其中<code>d</code>由<code>timePrecision</code>来控制</td></tr><tr><td align="center"><code>scientific</code></td><td align="center"><code>±m.dddddd±xx</code>，其中<code>d</code>由<code>timePrecision</code>来控制</td></tr><tr><td align="center"><code>general</code></td><td align="center">使用<code>scientific</code>格式，默认小数点后有<code>4</code>位有效位数，也可通过<code>timePrecision</code>来调节</td></tr></tbody></table><h3 id="runTimeModifiable">2.3.5&emsp;runTimeModifiable</h3><p>Switch for whether dictionaries, e.g. <code>controlDict</code>, are re-read during a simulation at the beginning of each time step, allowing the user to modify parameters during a simulation. </p><h3 id="graphFormat">2.3.6&emsp;graphFormat</h3><table><thead><tr><th>raw</th><th>采用原ASCII格式输出</th></tr></thead><tbody><tr><td>gnuplot</td><td>采用gunplot格式输出</td></tr><tr><td>xmgr</td><td>采用Grace/xmgr格式输出</td></tr><tr><td>jplot</td><td>采用jPlot格式输出</td></tr></tbody></table><h2 id="时间步长自适应控制">2.4&emsp;时间步长自适应控制</h2><table><tr><th>参数名</th><th>参数值</th><th>说明</th></tr><tr><td rowspan="2">adjustTimeStep</td><td>yes</td><td>允许依据最大Courant数自动调节时间步长</td></tr><tr><td>no</td><td>不允许程序自动调节时间步长</td></tr><tr><td>maxCo</td><td>0.5</td><td>最大允许的Courant数，若Co数大于指定值，自动缩小时间步长</td></tr><tr><td>maxDeltaT</td><td>0.1</td><td>自动调整时间步长时，最大允许的时间步长</td></tr><tr><td rowspan="2">runTimeModifiable (设置在求解过程中是否允许修改以上参数)</td><td>yes</td><td>允许，求解器会在每个时间步计算的开始读入controlDict文件</td></tr><tr><td>no</td><td>不允许，求解器不会在每个时间步开始读入controlDict文件</td></tr></table><h2 id="运行时加载库或者函数控制">2.5&emsp;运行时加载库或者函数控制</h2><p>设置运行时需要加载的库或函数如下所示：</p><table><thead><tr><th align="center">libs</th><th align="center">如<code>libgroovyBC.so</code>等</th><th align="center">调用的动态库文件列表</th></tr></thead><tbody><tr><td align="center">functions</td><td align="center">probes, singleGraph等</td><td align="center">调用的附加函数列表</td></tr></tbody></table><p>举个例子，<code>incompressible/pimpleFoam/RAS/TJunction/system/controlDict</code>中相关部分：</p><pre class="line-numbers language-cpp"><code class="language-cpp">functions<span class="token punctuation">{</span>    probes    <span class="token punctuation">{</span>        <span class="token comment" spellcheck="true">// Where to load it from</span>        <span class="token function">libs</span>            <span class="token punctuation">(</span><span class="token string">"libsampling.so"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        type            probes<span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// Name of the directory for probe data</span>        name            probes<span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// Write at same frequency as fields</span>        writeControl    writeTime<span class="token punctuation">;</span>        writeInterval   <span class="token number">1</span><span class="token punctuation">;</span>        <span class="token comment" spellcheck="true">// Fields to be probed</span>        <span class="token function">fields</span>          <span class="token punctuation">(</span>p U<span class="token punctuation">)</span><span class="token punctuation">;</span>        <span class="token function">probeLocations</span>        <span class="token punctuation">(</span>            <span class="token punctuation">(</span> <span class="token number">1e-06</span> <span class="token number">0</span> <span class="token number">0.01</span> <span class="token punctuation">)</span>        <span class="token comment" spellcheck="true">// at inlet</span>            <span class="token punctuation">(</span><span class="token number">0.21</span> <span class="token operator">-</span><span class="token number">0.20999</span> <span class="token number">0.01</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true">// at outlet1</span>            <span class="token punctuation">(</span><span class="token number">0.21</span> <span class="token number">0.20999</span> <span class="token number">0.01</span><span class="token punctuation">)</span>   <span class="token comment" spellcheck="true">// at outlet2</span>            <span class="token punctuation">(</span><span class="token number">0.21</span> <span class="token number">0</span> <span class="token number">0.01</span><span class="token punctuation">)</span>         <span class="token comment" spellcheck="true">// at central block</span>        <span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><hr><p>下面介绍最常用的probes和singleGraph函数的使用方法。</p><h3 id="probes函数">2.5.1&emsp;probes函数</h3><p>该函数功能为程序运行时监测:q指定坐标点场数据随时间的变化。首先在controlDict文件内添加以下语句，调用probes功能的相关函数。</p><pre class="line-numbers language-cpp"><code class="language-cpp">functions  <span class="token punctuation">{</span>    <span class="token macro property">#includeFunc probes   </span><span class="token comment" spellcheck="true">// 在functions列表中添加probes函数</span> <span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>接着运行以下命令，复制probes文件至system文件夹下，</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cp</span> -r <span class="token variable">$FOAM_ETC</span>/caseDicts/postProcessing/probes/probes system<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>probes文件的内容如下，</p><p>通过修改fields参数中可添加需监测的场，修改probeLocations的坐标值可添加监测点的坐标值。运行求解器后，指定坐标点的监测场随时间变化的数据输出至postProcessing/probes/0文件夹。</p><h3 id="singleGraph函数">2.5.2&emsp;singleGraph函数</h3><p>该函数功能为对计算结果数据取样并可视化。首先在controlDict文件内的functions列表中添加singleGraph函数，接着运行以下命令，复制singleGraph文件至system文件夹，</p><pre class="line-numbers language-BASH"><code class="language-BASH">cp -r $FOAM_ETC/caseDicts/postProcessing/graphs/singleGraph system<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>singleGraph文件的内容如下，  </p><pre class="line-numbers language-cpp"><code class="language-cpp"> <span class="token function">start</span>  <span class="token punctuation">(</span><span class="token number">0.01</span> <span class="token number">0.025</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// 取样的起始点坐标</span>  <span class="token function">end</span>   <span class="token punctuation">(</span><span class="token number">0.01</span> <span class="token operator">-</span><span class="token number">0.025</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment" spellcheck="true">// 取样的终点坐标</span>  <span class="token function">fields</span> <span class="token punctuation">(</span>U p<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">// 取样场的名称</span>  <span class="token comment" spellcheck="true">// Sampling and I/O settings </span>  <span class="token macro property">#includeEtc ”caseDicts/postProcessing/graphs/sampleDict.cfg” </span>  <span class="token comment" spellcheck="true">// Override settings here, e.g. </span>  <span class="token comment" spellcheck="true">// setConfig { type midPoint; } </span>  <span class="token comment" spellcheck="true">// Must be last entry </span>  <span class="token macro property">#includeEtc ”caseDicts/postProcessing/graphs/graph.cfg” </span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>修改fields参数中可添加需采样的场，修改start 和end参数可设置取样点的坐标范围。计算完成后，在算例文件夹下输入命令postProcess -func singleGraph，可对数据取样并输出至postProcessing/singleGraph文件夹。输出数据文件可直接通过gnuplot软件（需预先安装）处理实现可视化。</p><h3 id="foreCoeffs">2.5.3&emsp;foreCoeffs</h3><p>翼型模拟时常需要得到 $C_{p},C_{L},C_{D}$ 等数据，可以利用OpenFOAM的相关工具，推荐在controlDict里直接include然后在<code>system</code>文件夹里重新写一个文件。</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">//controlDict里加入</span>functions <span class="token punctuation">{</span>    <span class="token macro property">#<span class="token directive keyword">include</span> <span class="token string">"forceCoeffs"</span></span><span class="token punctuation">}</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>新文件内容如下：</p><pre class="line-numbers language-cpp"><code class="language-cpp"><span class="token comment" spellcheck="true">//文件名forceCoeffs</span><span class="token comment" spellcheck="true">/*--------------------------------*- C++ -*----------------------------------*\  =========                 |  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox   \\    /   O peration     | Website:  https://openfoam.org    \\  /    A nd           | Version:  dev     \\/     M anipulation  |-------------------------------------------------------------------------------Description    Calculates lift, drag and moment coefficients by summing forces on    specified patches for a case where the solver is incompressible (pressure    is kinematic, e.g. m^2/s^2).\*---------------------------------------------------------------------------*/</span>forceCoeffs<span class="token punctuation">{</span>    <span class="token comment" spellcheck="true">// Mandatory entries</span>    type            forceCoeffs<span class="token punctuation">;</span>    <span class="token function">libs</span>            <span class="token punctuation">(</span><span class="token string">"libforces.so"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">patches</span>         <span class="token punctuation">(</span>airfoil<span class="token operator">-</span>l1 airfoil<span class="token operator">-</span>l2 airfoil<span class="token operator">-</span>h1 airfoil<span class="token operator">-</span>h2<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Optional entries</span>    <span class="token comment" spellcheck="true">// Field names</span>    p               p<span class="token punctuation">;</span>    U               U<span class="token punctuation">;</span>    rho     rhoInf<span class="token punctuation">;</span>    log         <span class="token boolean">true</span><span class="token punctuation">;</span>    rhoInf      <span class="token number">1.225</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Reference pressure [Pa]</span>    pRef            <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Include porosity effects?</span>    porosity        yes<span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Store and write volume field representations of forces and moments</span>    writeFields     yes<span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Centre of rotation for moment calculations</span>    <span class="token function">CofR</span>            <span class="token punctuation">(</span><span class="token number">0.25</span> <span class="token number">0</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Lift direction</span>    <span class="token function">liftDir</span>         <span class="token punctuation">(</span><span class="token number">0</span> <span class="token number">1</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Drag direction</span>    <span class="token function">dragDir</span>         <span class="token punctuation">(</span><span class="token number">1</span> <span class="token number">0</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Pitch axis</span>    <span class="token function">pitchAxis</span>       <span class="token punctuation">(</span><span class="token number">0</span> <span class="token number">0</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Freestream velocity magnitude [m/s]</span>    magUInf         <span class="token number">50</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Reference length [m]</span>    lRef            <span class="token number">1</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Reference area [m2]</span>    Aref            <span class="token number">1.2</span><span class="token punctuation">;</span>    <span class="token comment" spellcheck="true">// Spatial data binning</span>    <span class="token comment" spellcheck="true">// - extents given by the bounds of the input geometry</span>    binData    <span class="token punctuation">{</span>        nBin        <span class="token number">21</span><span class="token punctuation">;</span>        <span class="token function">direction</span>   <span class="token punctuation">(</span><span class="token number">1</span> <span class="token number">0</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>        cumulative  yes<span class="token punctuation">;</span>    <span class="token punctuation">}</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>具体内容可参考<a href="https://www.openfoam.com/documentation/guides/latest/doc/guide-fos-forces-force-coeffs.html" target="_blank" rel="noopener">OpenFOAM在线文档</a>。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-12-04-controldict-wen-jian-xue-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Airfoil optimization for Vertical Axis Hydrokinetic Turbine using genetic algorithm(1)---airfoil parametrization</title>
      <link>https://chengpengzhao.com/2019-12-02-airfoil-paraterizaton/</link>
      <guid>https://chengpengzhao.com/2019-12-02-airfoil-paraterizaton/</guid>
      <pubDate>Mon, 02 Dec 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;Airfoil-parametrization&quot;&gt;1&amp;emsp;A
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="Airfoil-parametrization">1&emsp;Airfoil parametrization</h1><p>The numerical search for the optimum shape of an airfoil is of great interest for aircraft and turbine designers. A typical aerodynamic optimization procedure often consists four stages:<sup id="fnref:1"><a href="#fn:1" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="MASTERS D A, TAYLOR N J, RENDALL T. Review of Aerofoil Parametrisation Methods for Aerodynamic Shape Optimisation[C]//53rd AIAA Aerospace Sciences Meeting. Kissimmee, Florida: American Institute of Aeronautics and Astronautics, 2015.">[1]</span></a></sup></p><ol><li>Shape parametrization/control</li><li>Mesh generation/deformation</li><li>Flow solution</li><li>Optimization</li></ol><p>However, the whole process is computationally intense and requires a large amount of individual flow filed simulations resulting in very long CPU runtime. In order to optimize an airfoil shape using several of algorithms, the first step is to define the airfoil geometry, or in another words, to describe the airfoil with some suitable parameters which control its shape.<br>Shape parametrization method can be categorized as either <strong>constructive</strong> or <strong>deformative</strong>. Constructive methods represent airfoil based on series of parameters while deformative methods take an existing airfoil then deform it to create the new shape. Masters<sup id="fnref:2"><a href="#fn:2" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="MASTERS D A, TAYLOR N J, RENDALL T C S. Geometric Comparison of Aerofoil Shape Parametrization Methods[J]. AIAA Journal, 2017, 55(5): 1575–1589">[2]</span></a></sup> presented a comprehensive review of  constructive and deformative methods with a detailed comparison of seven airfoil parametrization methods.</p><hr><p>Many parametrization techniques are in use nowadays ,  some may have better shape control while others may show faster convergence rate. Anyway, there are several objectives that any parametrization technique should satisfy:<sup id="fnref:3"><a href="#fn:3" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="P. SALUNKE N, AHAMAD R. A. J, CHANNIWALA S A. Airfoil Parametrization Techniques: A Review[J]. American Journal of Mechanical Engineering, 2014, 2(4): 99–102.">[3]</span></a></sup></p><ul><li>Minimize the number of degrees of freedom.</li><li>Be able to represent a wide range of existing airfoils.</li><li>Parameters should be simple to formulate and impose.</li><li>The parametrization should result in effective and efficient optimization.</li></ul><p>Earlier, Hick<sup id="fnref:4"><a href="#fn:4" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="HICKS R, HENNE P. Wing design by numerical optimization[C]//Aircraft Systems and Technology Meeting. Seattle,WA,U.S.A.: American Institute of Aeronautics and Astronautics, 1977.">[4]</span></a></sup> represented the airfoil with a set of <strong>shape functions</strong>, and then a class of parametrization techniques has been presented based on the linear combination of shape functions. Kuruvila<sup id="fnref:5"><a href="#fn:5" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="KURUVILA G, TA’ASAN S, SALAS M. Airfoil design and optimization by the one-shot method[C]//33rd Aerospace Sciences Meeting and Exhibit. Reno,NV,U.S.A.: American Institute of Aeronautics and Astronautics, 1995.">[5]</span></a></sup> proposed an polynomial function to parametrize upper and lower curves of an airfoil using orthogonal shape functions. Onur<sup id="fnref:6"><a href="#fn:6" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="ONUR N. Application of Wagner Functions in Symmetrical Airfoil Design[J]. Journal of Aircraft, 1997, 34(2): 259–261.">[6]</span></a></sup> developed a Fourier series expansion of the Wagner functions which can represent a large class of airfoils. Another approach using combination of shape functions is proposed by <strong>Sobieczky</strong><sup id="fnref:7"><a href="#fn:7" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="LI P, SEEBASS R, SOBIECZKY H. Manual aerodynamic optimization of an oblique flying wing[C]//36th AIAA Aerospace Sciences Meeting and Exhibit. Reno,NV,U.S.A.: American Institute of Aeronautics and Astronautics, 1998.">[7]</span></a></sup>; many known classical as well as more sophisticated airfoils can be duplicated by this parametric section(<strong>PARSEC</strong>) method with good accuracy and the key concept is that design parameters should be based on the aerodynamic performance. Recently, some other modified PARSEC methods have also been proposed which provide more flexibility in defining the airfoil geometry compared with that of the conventional PARSEC method<sup id="fnref:8"><a href="#fn:8" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="SHAHROKHI A, JAHANGIRIAN A. Airfoil shape parametrization for optimum Navier–Stokes design with genetic algorithm[J]. Aerospace Science and Technology, 2007, 11(6): 443–450.">[8]</span></a></sup>.<br><strong>B-Spline</strong> method is also an effective and accurate representation for shape optimization of airfoil. However, the drawback of the regular B-Spline representation is its inability to represent a conic sections accurately. Therefore, a special form of B-Spline, nonuniform rational B-Spline(<strong>NURBS</strong>) is adapted. Lepine<sup id="fnref:9"><a href="#fn:9" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="LEPINE J, GUIBAULT F, TREPANIER J-Y. Optimized Nonuniform Rational B-Spline Geometrical Representation for Aerodynamic Design of Wings[J]. AIAA Journal, 2001, 39(11): 2033–2041.">[9]</span></a></sup> investigates the performance of NURBS for the aerodynamic design of a wing, and this method has been shown to be capable of accurately representing a large family of airfoils with 13 or fewer control points.<br><strong>Rogalsky</strong><sup id="fnref:10"><a href="#fn:10" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="ROGALSKY T P. Acceleration of differential evolution for aerodynamic design[M], 2004.DELLA VECCHIA P, DANIELE E, DʼAMATO E. An airfoil shape optimization technique coupling PARSEC parametrization and evolutionary algorithm[J]. Aerospace Science and Technology, 2014, 32(1): 103–110.">[10]</span></a></sup> proposes a new <strong>Bezier-PARSEC</strong> (BP) parametrization method which accelerates the convergence of aerodynamic design using Differential Evolution. The results show the number of function evaluations required by Differential Evolution has been reduced significantly.  </p><p>Airfoil consists of two curves namely camber line and thickness distribution.The upper and lower curves of the airfoil can be obtained by adding and subtracting the <strong>thickness</strong>  distribution to and from the <strong>camber</strong> line. So the airfoil can be constructed by camber and thickness curves parametrization or directly built by upper and lower curves. Next, three common parametrization method will be introduced: PARSEC method completes upper and lower curves directly while B-Spline and Bezier-PARSEC method use camber-thickness definition, on which the aerodynamic properties of an airfoil are more directly dependent.</p><h1 id="Bezier-Parametrization">2&emsp;Bezier Parametrization</h1><h2 id="Bezier-curve">2.1&emsp;Bezier curve</h2><p>A Bezier curve(B-Spline) is controlled with the help of its control points in a plane. It passes through initial and final control points but not each intermediate control point which defines the shape of the airfoil.<br>A $n$ degree Bezier curve is defined by $n+1$ control points:<br>$$<br>P(t)=\sum_{i=0}^{n} P_{i} B_{i}^{n}(t)<br> \tag{2-1}$$<br>where $P_{i}$ are control points, $t\in[0,1]$ and $B_{i}^{n}(t)$ are $n$ basis functions:<br>$$<br>B_{i}^{n}=\frac{n !}{i !(n-i) !}(1-t)^{n-i} t^{i}<br> \tag{2-2}$$</p><p>For example, a three-degree B-Spline having $n=3$ :<br>$$<br>\begin{aligned} B_{0}^{3} &amp;=(1-t)^{3} \ B_{1}^{3} &amp;=3 t(1-t)^{2} \ B_{2}^{3} &amp;=3 t^{2}(1-t) \ B_{i}^{n} &amp;=t^{3} \end{aligned}<br> \tag{2-3}$$<br>There are four control points $(x_i,y_i) , i=0,1,2,3$.<br>So this curve can be described by the equations below:<br>$$<br>\left{\begin{array}{l}{x(t)=x_{0}(1-t)^{3}+3 x_{1} t(1-t)^{2}+3 x_{2} t^{2}(1-t)+x_{3} t^{3}} \ {y(t)=y_{0}(1-t)^{3}+3 y_{1} t(1-t)^{2}+3 y_{2} t^{2}(1-t)+y_{3} t^{3}}\end{array}\right.<br> \tag{2-4}$$</p><h2 id="Advantages">2.2&emsp;Advantages</h2><p>This parametrization has many properties that are<br>attractive for aerodynamic design.</p><ul><li>The end points are automatically fixed at the two end vertices.</li><li>At an endpoint, the curve is tangent to<br>the vector between that endpoint and the closest control point, making it simple to join curves with first order continuity.</li><li>The curve always lies within the convex figure defined by the extreme points of the polygon.</li><li>The curve is nth order continuous throughout and never oscillates wildly away from its defining control points.</li></ul><h2 id="Disadvantages">2.3&emsp;Disadvantages</h2><ul><li><p>Higher computational cost comparing to the shape functions method<sup id="fnref:11"><a href="#fn:11" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="SONG W, KEANE A. A Study of Shape Parametrisation Methods for Airfoil Optimisation[C]//10th AIAA/ISSMO Multidisciplinary Analysis and Optimization Conference. Albany, New York: American Institute of Aeronautics and Astronautics, 2004.">[11]</span></a></sup></p></li><li><p>Discontinuous second derivative at the camber and thickness crests which can result in inaccurate flow field simulations. </p></li></ul><h1 id="PARSEC">3&emsp;PARSEC</h1><p>Parsec method is a effective method of airfoil parametrization. 11 basic Parameters are used to completely define the airfoil shape. An airfoil shape is defined by basic geometric parameters instead of the coefficients of shape functions themselves.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191208182309.webp" alt title="PARSEC"><br>These parameters are :</p><ul><li>Leading edge radius $r_{LE}$ </li><li>upper crest location $X_{UP},Z_{UP}$ </li><li>lower crest location $X_{LO},Z_{LO}$ </li><li>upper and lower curvature $Z_{XXUP},Z_{XXLO}$ </li><li>trailing edge coordinate $Z_{TE}$ </li><li>trailing edge direction $\alpha_{TE}$</li><li>trailing edge wedge angle $\beta_{TE}$</li><li>trailing edge thickness $\Delta_{TE}$<br>This method describes the airfoil shape by a linear combination of shape functions :<br>$$<br>Z_{k}=\sum_{n=1}^{6} a_{n,k}X_{k}^{n-\frac{1}{2}}<br>\tag{3-1}$$<br>The subscript $k$ will take values 1 and 2 for upper and lower surface respectively, and coefficients $a_{n,k}$ can be solved with the help of defined geometric parameters.<br>Parsec method has become one of the most robust method for airfoil parametrization due to its ability to avoid a more arbitrary and less physically based airfoil geometry. Della<sup id="fnref:12"><a href="#fn:12" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="DELLA VECCHIA P, DANIELE E, DʼAMATO E. An airfoil shape optimization technique coupling PARSEC parametrization and evolutionary algorithm[J]. Aerospace Science and Technology, 2014, 32(1): 103–110.">[12]</span></a></sup> presented an optimization technique that deals with PARSEC parametrization method and Nash equilibrium genetic algorithm, Grey<sup id="fnref:13"><a href="#fn:13" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="GREY Z J, CONSTANTINE P G. Active subspaces of airfoil shape parametrizations[J]. arXiv:1702.02909 [math], 2017.">[13]</span></a></sup> compared PARSEC with another airfoil shape parametrization and studied the active subspaces present in transonic lift and drag coefficients.<h2 id="Advantages-1">3.1&emsp;Advantages</h2></li><li>Oyama<sup id="fnref:14"><a href="#fn:14" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="OYAMA A, OBAYASHI S, NAKAHASHI K, 等. Fractional Factorial Design of Genetic Coding for Aerodynamic Optimization[J]. 1999.">[14]</span></a></sup> compared the performance of B-Spline method, orthogonal shape functions and Sobieczky method. The results show EA(Evolutionary Algorithms) using Sobieczky method has reached to the airfoil shape of best performance while EA using B-Spline curves is slightly less than Sobieczky.</li><li>This parametrization gives the design space wide enough, which helps finding a global optimum.  </li><li>The ability to minimize an optimization phenomena known as epistasis( the nonlinear manner in which the objective function is dependent on the design parameters)</li></ul><h2 id="Disadvantages-1">3.2&emsp;Disadvantages</h2><ul><li>Doesn’t provide sufficient control over the trailing edge shape where important flow phenomenon can take place.(Change difficulty at the trailing edge)<sup id="fnref:15"><a href="#fn:15" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="SHAHROKHI A, JAHANGIRIAN A, FOULADI N. Navier- Stokes Optimization Using Genetic Algorithm and a Flexible Parametric Airfoil Method[J]. 2006: 4.">[15]</span></a></sup></li></ul><h1 id="Bezier-Parsec-Parametrization">4&emsp;Bezier-Parsec Parametrization</h1><p>This method combines Bezier and PARSEC parametrization techniques, which have advantages of both technique. This parametrization uses four Bezier curves to define the leading edge and trailing edge of the camber line and thickness distribution, and then solves the coefficients of Bezier curves using PARSEC parameters.<br>For example, <strong>BP 3434</strong> parametrization($ijkl$ represents the order of leading and tailing edge of thickness curve and camber curve) uses third degree Bezier curves for two leading edges curves and fourth degree Bezier curves for trailing edges to define the airfoil<sup id="fnref:16"><a href="#fn:16" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="DERKSEN R W, ROGALSKY T. Optimum aerofoil parametrization for aerodynamic design[C]//Algarve, Portugal: 2009: 197–206.">[16]</span></a></sup><sup id="fnref:17"><a href="#fn:17" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="DERKSEN R W, ROGALSKY T. Bezier-PARSEC: An optimized aerofoil parameterization for design[J]. Advances in Engineering Software, 2010, 41(7–8): 923–930.">[17]</span></a></sup>.<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191208182517.webp" alt title="Beizier-Parsec"></p><h2 id="Advantages-2">4.1&emsp;Advantages</h2><ul><li>Increased robustness and convergence speed for aerodynamic optimization using genetic algorithms</li><li>Fit the known shape of a wide range of existing airfoil profiles</li></ul><h2 id="Disadvantages-2">4.2&emsp;Disadvantages</h2><ul><li>The Bezier control parameters in Bezier-PARSEC parametrization are hard to control</li></ul><h1 id="References">5&emsp;References</h1><div id="footnotes"><hr><div id="footnotelist"><ol style="list-style: none; padding-left: 0; margin-left: 40px"><li id="fn:1"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">1.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">MASTERS D A, TAYLOR N J, RENDALL T. Review of Aerofoil Parametrisation Methods for Aerodynamic Shape Optimisation[C]//53rd AIAA Aerospace Sciences Meeting. Kissimmee, Florida: American Institute of Aeronautics and Astronautics, 2015.<a href="#fnref:1" rev="footnote"> ↩</a></span></li><li id="fn:2"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">2.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">MASTERS D A, TAYLOR N J, RENDALL T C S. Geometric Comparison of Aerofoil Shape Parametrization Methods[J]. AIAA Journal, 2017, 55(5): 1575–1589<a href="#fnref:2" rev="footnote"> ↩</a></span></li><li id="fn:3"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">3.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">P. SALUNKE N, AHAMAD R. A. J, CHANNIWALA S A. Airfoil Parametrization Techniques: A Review[J]. American Journal of Mechanical Engineering, 2014, 2(4): 99–102.<a href="#fnref:3" rev="footnote"> ↩</a></span></li><li id="fn:4"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">4.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">HICKS R, HENNE P. Wing design by numerical optimization[C]//Aircraft Systems and Technology Meeting. Seattle,WA,U.S.A.: American Institute of Aeronautics and Astronautics, 1977.<a href="#fnref:4" rev="footnote"> ↩</a></span></li><li id="fn:5"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">5.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">KURUVILA G, TA’ASAN S, SALAS M. Airfoil design and optimization by the one-shot method[C]//33rd Aerospace Sciences Meeting and Exhibit. Reno,NV,U.S.A.: American Institute of Aeronautics and Astronautics, 1995.<a href="#fnref:5" rev="footnote"> ↩</a></span></li><li id="fn:6"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">6.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">ONUR N. Application of Wagner Functions in Symmetrical Airfoil Design[J]. Journal of Aircraft, 1997, 34(2): 259–261.<a href="#fnref:6" rev="footnote"> ↩</a></span></li><li id="fn:7"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">7.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">LI P, SEEBASS R, SOBIECZKY H. Manual aerodynamic optimization of an oblique flying wing[C]//36th AIAA Aerospace Sciences Meeting and Exhibit. Reno,NV,U.S.A.: American Institute of Aeronautics and Astronautics, 1998.<a href="#fnref:7" rev="footnote"> ↩</a></span></li><li id="fn:8"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">8.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">SHAHROKHI A, JAHANGIRIAN A. Airfoil shape parametrization for optimum Navier–Stokes design with genetic algorithm[J]. Aerospace Science and Technology, 2007, 11(6): 443–450.<a href="#fnref:8" rev="footnote"> ↩</a></span></li><li id="fn:9"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">9.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">LEPINE J, GUIBAULT F, TREPANIER J-Y. Optimized Nonuniform Rational B-Spline Geometrical Representation for Aerodynamic Design of Wings[J]. AIAA Journal, 2001, 39(11): 2033–2041.<a href="#fnref:9" rev="footnote"> ↩</a></span></li><li id="fn:10"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">10.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">ROGALSKY T P. Acceleration of differential evolution for aerodynamic design[M], 2004.DELLA VECCHIA P, DANIELE E, DʼAMATO E. An airfoil shape optimization technique coupling PARSEC parametrization and evolutionary algorithm[J]. Aerospace Science and Technology, 2014, 32(1): 103–110.<a href="#fnref:10" rev="footnote"> ↩</a></span></li><li id="fn:11"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">11.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">SONG W, KEANE A. A Study of Shape Parametrisation Methods for Airfoil Optimisation[C]//10th AIAA/ISSMO Multidisciplinary Analysis and Optimization Conference. Albany, New York: American Institute of Aeronautics and Astronautics, 2004.<a href="#fnref:11" rev="footnote"> ↩</a></span></li><li id="fn:12"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">12.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">DELLA VECCHIA P, DANIELE E, DʼAMATO E. An airfoil shape optimization technique coupling PARSEC parametrization and evolutionary algorithm[J]. Aerospace Science and Technology, 2014, 32(1): 103–110.<a href="#fnref:12" rev="footnote"> ↩</a></span></li><li id="fn:13"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">13.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">GREY Z J, CONSTANTINE P G. Active subspaces of airfoil shape parametrizations[J]. arXiv:1702.02909 [math], 2017.<a href="#fnref:13" rev="footnote"> ↩</a></span></li><li id="fn:14"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">14.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">OYAMA A, OBAYASHI S, NAKAHASHI K, 等. Fractional Factorial Design of Genetic Coding for Aerodynamic Optimization[J]. 1999.<a href="#fnref:14" rev="footnote"> ↩</a></span></li><li id="fn:15"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">15.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">SHAHROKHI A, JAHANGIRIAN A, FOULADI N. Navier- Stokes Optimization Using Genetic Algorithm and a Flexible Parametric Airfoil Method[J]. 2006: 4.<a href="#fnref:15" rev="footnote"> ↩</a></span></li><li id="fn:16"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">16.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">DERKSEN R W, ROGALSKY T. Optimum aerofoil parametrization for aerodynamic design[C]//Algarve, Portugal: 2009: 197–206.<a href="#fnref:16" rev="footnote"> ↩</a></span></li><li id="fn:17"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">17.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">DERKSEN R W, ROGALSKY T. Bezier-PARSEC: An optimized aerofoil parameterization for design[J]. Advances in Engineering Software, 2010, 41(7–8): 923–930.<a href="#fnref:17" rev="footnote"> ↩</a></span></li></ol></div></div>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-12-02-airfoil-paraterizaton/#disqus_thread</comments>
    </item>
    
    <item>
      <title>用Vim写Markdown</title>
      <link>https://chengpengzhao.com/2019-11-30-markdown-vim-shi-yong/</link>
      <guid>https://chengpengzhao.com/2019-11-30-markdown-vim-shi-yong/</guid>
      <pubDate>Sat, 30 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;自从接触了Vim之后就成了它的脑残粉，无论些什么东西都想拿它来试试，每天还坚
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>自从接触了Vim之后就成了它的脑残粉，无论些什么东西都想拿它来试试，每天还坚持练习盲打；前几天刚总结了写Markdown时可能用到的语法，马上想到如何利用mapping让在Vim写Markdown变得更简单。<br>当然现在那么多写markdown的工具，比如我之前一直用的Typora就感觉很不错，但毕竟是别人的软件，有一些你想要的功能它没有那就没办法，但Vim的话只要学几天Vimscript就能自己实现一些功能、自己定义觉得方便的快捷键，简直随心所欲为所欲为。<br>有些人总是喜欢折腾，我也不例外，连专业学习都能丢在一边，先把这边折腾完再说。<br><strong>下面简单介绍我专门为写Markdown定义的Vim快捷键</strong>，刚开始是B站的一个<a href="https://www.bilibili.com/video/av56946680/" target="_blank" rel="noopener">大佬</a>给我的启发，我在它的基础上改进了一下，为了方便我自己的使用。</p><hr><h1 id="最基础的语法">1&emsp;最基础的语法</h1><p>这个设置不设置快捷键区别不是很大，但感觉还是快了那么一点点，毕竟可以少按几次<code>Enter</code>。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130174945.gif" alt title="title"><br>相关<code>.vimrc</code>配置文件：</p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">f</span> <span class="token operator">&lt;</span>Esc<span class="token operator">></span><span class="token operator">/</span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>CR<span class="token operator">></span><span class="token punctuation">:</span><span class="token keyword">nohlsearch</span><span class="token operator">&lt;</span>CR<span class="token operator">></span>i<span class="token operator">&lt;</span>Del<span class="token operator">></span><span class="token operator">&lt;</span>Del<span class="token operator">></span><span class="token operator">&lt;</span>Del<span class="token operator">></span><span class="token operator">&lt;</span>Del<span class="token operator">></span><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token number">1</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>#<span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>kA<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token number">2</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>##<span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>kA<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token number">3</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>###<span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>kA<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token number">4</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>####<span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>kA<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token number">5</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>#####<span class="token operator">&lt;</span>Space<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>kA<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这里通过&lt;++&gt;这样一个比较特殊的标记来进行光标的快速移动，从而<strong>定位到下一输入处</strong>。我的<code>localLeader</code>定义为<code>/</code>符号，怎么按舒服怎么定义就行。<br><em><code>&lt;localLeader&gt;f</code></em>的mapping定义中用了多个<code>&lt;Del&gt;</code>而没有用d、s之类的命令是为了防止把<code>&lt;++&gt;</code>符号复制到剪切板中。</p><h1 id="代码、空格、段落">2&emsp;代码、空格、段落</h1><p>这几个用Vim就方便很多了，至少我用Typora时想多打几个空格每次都要先百度然后复制<code>&amp;emsp;</code>，多空几行也得先打出一个<code>&lt;br&gt;</code>再复制，代码段插入的话Typora有快捷键，不过最后输入代码语言的时候还得鼠标点，感觉还是挺麻烦的。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130175151.gif" alt title="code"><br>相关<code>.vimrc</code>配置文件：</p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">c</span> ```<span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span>```<span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>4kA<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span>s ``<span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>F`i<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">/</span> &amp;emsp<span class="token punctuation">;</span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>a<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>CR<span class="token operator">></span> <span class="token operator">&lt;</span><span class="token keyword">br</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>a<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p><code>autocmd Filetype markdown</code>可以保证只在打开<code>.md</code>文件的时候启用这些快捷键，而别的时候则不用，防止没必要的冲突。</p><h1 id="字体、分隔线">3&emsp;字体、分隔线</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130175938.gif" alt title="字体"><br>这几个的实现方法都比较简单，先输入再移动光标到中间处；类似的还有删除线和下划线。</p><h1 id="图片和链接">4&emsp;图片和链接</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130180444.gif" alt title="link"><br>这里首先展示了当前剪切板的内容，因为一般我们都是先通过PicGo等软件把图片传到图床上，再复制链接到markdown里这样一个流程。（只需要将图片往配制好的PicGo一拖，过几秒它会自动复制链接到剪切板）所以在Vim直接读取剪切板的内容连同相应格式粘贴出来就行了。<br>相关<code>.vimrc</code>配置文件：</p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">p</span> <span class="token operator">!</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">&lt;</span>C<span class="token operator">-</span>R<span class="token operator">></span><span class="token operator">+</span> <span class="token string">"&lt;++>"</span><span class="token punctuation">)</span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>F<span class="token punctuation">]</span>i<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span>a <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">&lt;</span>C<span class="token operator">-</span>R<span class="token operator">></span><span class="token operator">+</span> <span class="token string">"&lt;++>"</span><span class="token punctuation">)</span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>F<span class="token punctuation">]</span>i<span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">l</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">-</span><span class="token operator">&lt;</span>Enter<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h1 id="脚注引用（自动编号）">5&emsp;脚注引用（自动编号）</h1><p>我想这个功能是一般markdown编辑器都不具备的吧，脚注是一个相对来说输入比较麻烦的东西，如果能通过一个键插入而且自动编号的话会方便许多。当然对那些文章里不怎么用脚注的人来说这个功能也没啥用。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130181356.gif" alt title="footnote"><br>一开始我使用普通的计数方式，即按一次相应快捷键计数器+1,但这样没法保证保存退出后下一次再打开文件时变量还保持那个数。最终实现是通过正则表达式对前文进行搜索匹配出现次数来实现自动编号的。由于Vimscript没学几天很多命令都不太熟，也可能有更简单的实现方式。</p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token keyword">function</span><span class="token operator">!</span> <span class="token function">Count</span><span class="token punctuation">(</span>pattern<span class="token punctuation">,</span>startline<span class="token punctuation">)</span>  <span class="token keyword">let</span> <span class="token keyword">l</span><span class="token punctuation">:</span>cnt <span class="token operator">=</span> <span class="token number">0</span>  <span class="token keyword">silent</span><span class="token operator">!</span> exe a<span class="token punctuation">:</span>startline <span class="token operator">.</span> <span class="token string">',.s/'</span> <span class="token operator">.</span> a<span class="token punctuation">:</span>pattern <span class="token operator">.</span> <span class="token string">'/\=execute(''let l:cnt += 1'')/gn'</span>  <span class="token keyword">return</span> <span class="token keyword">l</span><span class="token punctuation">:</span>cnt<span class="token keyword">endfunction</span><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>expr<span class="token operator">></span> <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F12<span class="token operator">></span> <span class="token function">eval</span><span class="token punctuation">(</span><span class="token function">Count</span><span class="token punctuation">(</span><span class="token string">'\[\^\d\+\]'</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token builtin">autocmd</span> Filetype markdown imap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">n</span> <span class="token punctuation">[</span>^<span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F12<span class="token operator">></span><span class="token punctuation">]</span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>ya<span class="token punctuation">[</span>Go<span class="token operator">&lt;</span>C<span class="token operator">-</span>O<span class="token operator">></span><span class="token keyword">p</span><span class="token punctuation">:</span> <span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span><span class="token operator">&lt;</span>C<span class="token operator">-</span><span class="token keyword">o</span><span class="token operator">></span><span class="token keyword">f</span><span class="token punctuation">]</span>a<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="公式（自动编号）">6&emsp;公式（自动编号）</h1><p>有了前面的函数，这一部分也比较好实现了，只要把正则表达式改一下就行了；这两部分我多定义了两个几乎不会被按到的键的组合作为输出的过渡，单独计算出函数返回值，以免在复杂的字符串中调用函数使得输出位置不正确。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130182420.gif" alt title="math"><br>可以从下面的gif看出，即使重新进入文件，仍能够按正常的顺序进行编号。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130182620.gif" alt title="math2"></p><pre class="line-numbers language-vim"><code class="language-vim"><span class="token keyword">function</span><span class="token operator">!</span> <span class="token function">Findtitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> <span class="token function">range</span><span class="token punctuation">(</span><span class="token function">line</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>        <span class="token keyword">if</span> <span class="token function">matchstr</span><span class="token punctuation">(</span><span class="token function">getline</span><span class="token punctuation">(</span><span class="token function">line</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span><span class="token operator">-</span>i<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token string">'^# \+'</span><span class="token punctuation">)</span><span class="token operator">!=#</span><span class="token string">''</span>            <span class="token keyword">let</span> <span class="token keyword">l</span><span class="token punctuation">:</span>latesttitleline<span class="token operator">=</span><span class="token function">line</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span><span class="token operator">-</span>i            <span class="token keyword">break</span>        <span class="token keyword">else</span>            <span class="token keyword">let</span> <span class="token keyword">l</span><span class="token punctuation">:</span>latesttitleline<span class="token operator">=</span><span class="token function">line</span><span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span>        <span class="token keyword">endif</span>    <span class="token keyword">endfor</span>    <span class="token keyword">return</span> <span class="token keyword">l</span><span class="token punctuation">:</span>latesttitleline<span class="token keyword">endfunction</span><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>expr<span class="token operator">></span> <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F11<span class="token operator">></span> <span class="token function">Count</span><span class="token punctuation">(</span><span class="token string">'^# \+'</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token builtin">autocmd</span> Filetype markdown inoremap <span class="token operator">&lt;</span>expr<span class="token operator">></span> <span class="token operator">&lt;</span>Leader<span class="token operator">></span><span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F11<span class="token operator">></span> <span class="token function">Count</span><span class="token punctuation">(</span><span class="token string">' \\tag{\d\+-\d\+}'</span><span class="token punctuation">,</span><span class="token function">Findtitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token builtin">autocmd</span> Filetype markdown imap <span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token keyword">q</span> <span class="token operator">&lt;</span>ESC<span class="token operator">></span><span class="token keyword">o</span>$$<span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span>Enter<span class="token operator">></span> \<span class="token keyword">tag</span><span class="token punctuation">{</span><span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F11<span class="token operator">></span><span class="token operator">-</span><span class="token operator">&lt;</span>Leader<span class="token operator">></span><span class="token operator">&lt;</span>localLeader<span class="token operator">></span><span class="token operator">&lt;</span>F11<span class="token operator">></span><span class="token punctuation">}</span>$$<span class="token operator">&lt;</span>Enter<span class="token operator">></span><span class="token operator">&lt;</span>BS<span class="token operator">></span><span class="token operator">&lt;</span><span class="token operator">+</span><span class="token operator">+</span><span class="token operator">></span><span class="token operator">&lt;</span>Esc<span class="token operator">></span>2iA<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h1 id="写英文blog时的单词补全">7&emsp;写英文blog时的单词补全</h1><p>Vim的这个补全功能十分强大，而且可以自己定义dictionary，比如把一些自己的专业词汇加入dict里面。<br>用法也十分简单，加一个mapping快捷键之后，每次只需要<code>Ctrl+Space</code>就能查看候选词。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130212638.gif" alt title="auto-complete"><br>能够很好地帮助像我这样的英语渣渣记住一些单词的拼写。（毕竟用多了就记得了）</p><h1 id="其他工具">8&emsp;其他工具</h1><p>平时用得到的基本上都写进去了，表格我尽量不用所以没放进去。我还加了一些小工具，比如说按<code>&lt;F2&gt;</code>会在下一行插入一个时间戳：</p><blockquote><p><em>以下内容更新于2019-11-30 18:50:47</em>  </p></blockquote><h2 id="Markdown-Preview">8.1&emsp;Markdown-Preview</h2><p>忘了介绍写markdown用的这个工具了，能够实现实时的显示，对就像gif里看到的这样。<a href="https://github.com/iamcco/markdown-preview.nvim" target="_blank" rel="noopener" title="Preview">github相关页面</a><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130190437.gif" alt title="preview"></p><h2 id="Ultisnips">8.2&emsp;Ultisnips</h2><p>接下来介绍一个非常强大的插件，叫做<strong>ultisnips</strong>，它也能自定义来实现许多复杂的命令，但它的原理不是mapping而是<strong>snippet</strong>，当你输入一段特定的字符串时它会用事先定义好的另一段字符串来代替它。<br>它也内置了许多命令，可以在安装的vim-snippets插件里找到相关文件，比如markdown里的一些命令：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20191130195703.gif" alt title="ultisnips"><br>第一次没按出来是因为screenkey这个小程序的原因- -，但相比自己定义的命令来说它自带的补全还是比较复杂的。  </p><h1 id="下一步计划">9&emsp;下一步计划</h1><p>Markdown里面写LaTeX公式是最复杂的一个部分，因为公式里面包含的语法比所有Markdown本身的语法还要多，导致写公式的时候效率极低，导致最后要么是图片复制粘贴、要么是<code>Mathpix snapping tool</code>直接识别（能直接识别为什么要自己输入一遍）。<br>根据<a href="https://castel.dev/post/lecture-notes-1/" target="_blank" rel="noopener" title="dalao">How I’m able to take notes in mathematics lectures using LaTeX and Vim</a>这篇文章，如何结合自己的需要，让在Vim里输入公式变得简单？这便是下一步的计划。</p><hr><blockquote><p>这是我的<a href="https://github.com/chengpengzhao/My_vimrc" target="_blank" rel="noopener" title=".vimrc">.vimrc</a>文件，专门记录一些更新。</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-30-markdown-vim-shi-yong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>python爬虫入门练习——Sourceforge自动下载</title>
      <link>https://chengpengzhao.com/2019-11-28-python-pa-chong-ru-men-lian-xi-sourceforge-zi-dong-xia-zai/</link>
      <guid>https://chengpengzhao.com/2019-11-28-python-pa-chong-ru-men-lian-xi-sourceforge-zi-dong-xia-zai/</guid>
      <pubDate>Thu, 28 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;明确需求&quot;&gt;1&amp;emsp;明确需求&lt;/h1&gt;&lt;p&gt;SourceFo
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="明确需求">1&emsp;明确需求</h1><p>SourceForge与Github类似，是一套合作式软件开发管理系统，上面有大量的开源项目——这是<a href="https://zh.wikipedia.org/wiki/SourceForge" target="_blank" rel="noopener">Wiki百科</a>的描述。然而在我的印象里，它只是个广告一堆下载速度贼慢找半天找不到下载链接在哪的网站；以前在它上面下载过几次东西体验极差，这次又有了需求（找遍了网上只有这一个地方能下载）  </p><h2 id="下载地址">1.1&emsp;下载地址</h2><p>最近在学pyfoam的用法，正好看到OpenFOAM有个workshop讲的很详细，然而源文件没有，于是来到了这个网址<a href="https://sourceforge.net/projects/openfoam-extend/files/OpenFOAM_Workshops/" target="_blank" rel="noopener">https://sourceforge.net/projects/openfoam-extend/files/OpenFOAM_Workshops/</a>进行下载，发现了历年的讲座都有！这么好的资源当然要下载下来。然而面对着这一层层的文件夹SourceForge竟然不让你直接下载，只能点进去一个个文件下载（这要点到什么时候）。<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128181612.webp" alt="层层文件夹"><br>这就算了，每当你下载一个文件时不时会让你等个5s<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128181905.webp" alt>迅速得出结论：这是个练习爬虫的好机会。</p><h2 id="下载要求">1.2&emsp;下载要求</h2><ul><li>能够全程自动，不需要时时盯着看程序运行状况</li><li>下载的文件按照原有的文件夹结构分类放好，文件名不变</li><li>若运行时遇到断网等特殊情况，下次运行能自动从上次的断点开始，不用重新下载</li></ul><h1 id="分析网站">2&emsp;分析网站</h1><p>开工开工，首先打开Chrome或Firefox浏览器调出控制台，查看HTML代码。</p><h2 id="找到目标位置">2.1&emsp;找到目标位置</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128182850.webp" alt><br>可以发现在<code>&lt;th scope=&quot;row&quot; headers=&quot;files_name_h&quot;&gt;</code>下有我们想要的文件夹的相对链接，而且每一层的结构都类似，故可以通过正则表达式轻易地定位到该部分。</p><h2 id="找到最终的下载链接">2.2&emsp;找到最终的下载链接</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128185016.webp" alt><br>前面的多级文件夹都是采用的相对链接，而到最后每个文件可以看到肯定是有个绝对链接的，点击该href就能下载。</p><h1 id="Python实现">3&emsp;Python实现</h1><p>前面的都找到之后就可以编py程序了，因为每个文件夹下都可能有文件和文件夹并存，最好先把文件结构建立起来。利用相对链接建立文件夹，再把相应的绝对链接储存在文本文件中，以便下一步下载。</p><h2 id="获取下载链接，建立文件夹">3.1&emsp;获取下载链接，建立文件夹</h2><p>python3环境，采用requests库，引入多个header随机切换，设定一小段休眠时间，通过嵌套的函数建立层层文件夹：<br><strong>getlinks.py</strong></p><pre class="line-numbers language-python"><code class="language-python"><span class="token comment" spellcheck="true"># coding=utf-8</span><span class="token keyword">import</span> requests<span class="token keyword">import</span> re<span class="token keyword">import</span> os<span class="token keyword">import</span> random<span class="token keyword">import</span> timemy_headers <span class="token operator">=</span> <span class="token punctuation">[</span>    <span class="token string">"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36"</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0"</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14"</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)"</span><span class="token punctuation">,</span>    <span class="token string">'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'</span><span class="token punctuation">,</span>    <span class="token string">'Opera/9.25 (Windows NT 5.1; U; en)'</span><span class="token punctuation">,</span>    <span class="token string">'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)'</span><span class="token punctuation">,</span>    <span class="token string">'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)'</span><span class="token punctuation">,</span>    <span class="token string">'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12'</span><span class="token punctuation">,</span>    <span class="token string">'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9'</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7"</span><span class="token punctuation">,</span>    <span class="token string">"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "</span><span class="token punctuation">]</span><span class="token keyword">def</span> <span class="token function">find_and_print_links</span><span class="token punctuation">(</span>html<span class="token punctuation">)</span><span class="token punctuation">:</span>    headers <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token string">'User-Agent'</span><span class="token punctuation">:</span> random<span class="token punctuation">.</span>choice<span class="token punctuation">(</span>my_headers<span class="token punctuation">)</span>    <span class="token punctuation">}</span>    response <span class="token operator">=</span> requests<span class="token punctuation">.</span>get<span class="token punctuation">(</span>html<span class="token punctuation">,</span> headers<span class="token operator">=</span>headers<span class="token punctuation">)</span>    pattern <span class="token operator">=</span> re<span class="token punctuation">.</span>compile<span class="token punctuation">(</span><span class="token string">'&lt;th scope="row" headers="files_name_h">&lt;a href="(.*?)"'</span><span class="token punctuation">,</span> re<span class="token punctuation">.</span>S<span class="token punctuation">)</span>    downloadurl <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span>pattern<span class="token punctuation">,</span> str<span class="token punctuation">(</span>response<span class="token punctuation">.</span>text<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> item <span class="token keyword">in</span> downloadurl<span class="token punctuation">:</span>        t <span class="token operator">=</span> <span class="token number">0.1</span>        time<span class="token punctuation">.</span>sleep<span class="token punctuation">(</span>t<span class="token punctuation">)</span>        <span class="token keyword">if</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'https:'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">:</span>            <span class="token keyword">if</span> <span class="token operator">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span><span class="token string">'.'</span> <span class="token operator">+</span> item<span class="token punctuation">)</span><span class="token punctuation">:</span>                os<span class="token punctuation">.</span>makedirs<span class="token punctuation">(</span><span class="token string">'.'</span> <span class="token operator">+</span> item<span class="token punctuation">)</span>            html <span class="token operator">=</span> <span class="token string">'https://sourceforge.net'</span> <span class="token operator">+</span> item            find_and_print_links<span class="token punctuation">(</span>html<span class="token punctuation">)</span>        <span class="token keyword">else</span><span class="token punctuation">:</span>            path <span class="token operator">=</span> <span class="token string">'.'</span> <span class="token operator">+</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'(/projects/.*)/.*/download'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>            <span class="token keyword">if</span> <span class="token operator">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">:</span>                os<span class="token punctuation">.</span>makedirs<span class="token punctuation">(</span>path<span class="token punctuation">)</span>            <span class="token keyword">with</span> open<span class="token punctuation">(</span>path <span class="token operator">+</span> <span class="token string">'/'</span> <span class="token operator">+</span> <span class="token string">'links.txt'</span><span class="token punctuation">,</span> <span class="token string">'a'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>                f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>str<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">)</span>                f<span class="token punctuation">.</span>write<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span>                f<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span>    html <span class="token operator">=</span> <span class="token string">"https://sourceforge.net/projects/openfoam-extend/files/OpenFOAM_Workshops/"</span>    find_and_print_links<span class="token punctuation">(</span>html<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>为了防止程序中途出错下次重头开始，设置了一个if条件判断当前文件夹是否已经生成；我大概运行了几分钟就建立好了全部的文件夹并获得了所有下载链接。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128191933.webp" alt></p><h2 id="读取文本文件，下载至相应位置">3.2&emsp;读取文本文件，下载至相应位置</h2><p>os.walk命令能够读取文件夹里的所有文件并很容易转化成一个List，之后只需要判断每个item里是否含有文本文件，有就逐一下载到本地。<br>下载采用的是非常强大的下载利器<a href="https://you-get.org/" target="_blank" rel="noopener">you-get</a>，什么Youtube、B站上的视频音频通通一个命令就能下载。<br><strong>downloadfiles.py</strong></p><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">import</span> re<span class="token keyword">import</span> os<span class="token keyword">def</span> <span class="token function">findlinks_and_download</span><span class="token punctuation">(</span>item<span class="token punctuation">)</span><span class="token punctuation">:</span>    current <span class="token operator">=</span> os<span class="token punctuation">.</span>getcwd<span class="token punctuation">(</span><span class="token punctuation">)</span>    path <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'(.*?)\\\\links.txt'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>    <span class="token comment" spellcheck="true"># If you use linux, change the '\\\\' to '/'</span>    os<span class="token punctuation">.</span>chdir<span class="token punctuation">(</span>path<span class="token punctuation">)</span>    f <span class="token operator">=</span> open<span class="token punctuation">(</span><span class="token string">'links.txt'</span><span class="token punctuation">,</span> <span class="token string">'r'</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> line <span class="token keyword">in</span> f<span class="token punctuation">.</span>readlines<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        filename_with_suffix<span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'https://sourceforge.net/projects.*/(.*?)/download'</span><span class="token punctuation">,</span>line<span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>        <span class="token keyword">if</span> <span class="token operator">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span>filename_with_suffix<span class="token punctuation">)</span><span class="token punctuation">:</span>            os<span class="token punctuation">.</span>system<span class="token punctuation">(</span><span class="token string">"you-get "</span> <span class="token operator">+</span> <span class="token string">"-O"</span><span class="token operator">+</span>filename_with_suffix<span class="token operator">+</span><span class="token string">"  "</span><span class="token operator">+</span> line <span class="token punctuation">)</span>    os<span class="token punctuation">.</span>chdir<span class="token punctuation">(</span>current<span class="token punctuation">)</span><span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span>    g <span class="token operator">=</span> os<span class="token punctuation">.</span>walk<span class="token punctuation">(</span><span class="token string">'.'</span><span class="token punctuation">)</span>    files <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>    <span class="token keyword">for</span> path<span class="token punctuation">,</span> dir_list<span class="token punctuation">,</span> file_list <span class="token keyword">in</span> g<span class="token punctuation">:</span>        <span class="token keyword">for</span> file_name <span class="token keyword">in</span> file_list<span class="token punctuation">:</span>            files<span class="token punctuation">.</span>append<span class="token punctuation">(</span>os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>path<span class="token punctuation">,</span> file_name<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> item <span class="token keyword">in</span> files<span class="token punctuation">:</span>        <span class="token keyword">if</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span><span class="token string">'links.txt'</span><span class="token punctuation">,</span> item<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">:</span>            <span class="token keyword">continue</span>        <span class="token keyword">else</span><span class="token punctuation">:</span>            findlinks_and_download<span class="token punctuation">(</span>item<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>短短几十行代码就能够解决我的需求，而且今后遇到要在sourceforge下载东西时直接拿来用就行。（好在sourceforge没有什么反爬措施，我基本上没遇到被403或其他访问失败的情况）</p><h2 id="成果展示">3.3&emsp;成果展示</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191128193025.webp" alt><br>下是下好了，接下来就是一段漫长的学习了…</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-28-python-pa-chong-ru-men-lian-xi-sourceforge-zi-dong-xia-zai/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Markdown-Tips</title>
      <link>https://chengpengzhao.com/2019-11-26-markdown-tips/</link>
      <guid>https://chengpengzhao.com/2019-11-26-markdown-tips/</guid>
      <pubDate>Tue, 26 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;很早之前就想总结一下Markdown的一些语法了，记得刚开始学的时候随便搜一
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>很早之前就想总结一下Markdown的一些语法了，记得刚开始学的时候随便搜一下就能找到很多人总结的文章，胡乱地看了一通结果到自己真正写的时候还是一个一个语法地搜，虽然Typora用着很舒服但用久了之后却发现自己的Markdown水平依旧没有任何长进，一离开Typora的帮助,比如换了个环境（学校电脑，没权限安装Typora)还是得一个个查。<br>于是开始逼自己用更泛用的工具写BLog，正好前些日子在学Vim,逐渐体会到其强大之处，干脆就用它写Markdown文章好了，配合<a href="https://github.com/iamcco/markdown-preview.nvim" target="_blank" rel="noopener">MarkdownPreview</a>插件，也觉得挺方便的。（重点是能够<strong>自定义快捷键</strong>） 下面就按照常用的程度记录下Markdown的一些语法吧，方便自己以后查询，看自己曾经写的总比看别人写的印象深~</p><h1 id="最基础的语法">1&emsp;最基础的语法</h1><pre><code># h1级标题## h2级标题### h3级标题#### h4级标题##### h5级标题###### h6级标题</code></pre><p>文章的层次得要有的吧，平常写东西前三级就够用了，注意#和标题之间要有<strong>空格</strong>，而且要放在行头，像# 这种写法是不会被认作标题的。<br>这个语法太简单了怎么都不会忘的吧，但为了完整起见还是列在这。<br>标题可以用等号和连字符表示：</p><pre><code>This is an H1=============This is an H2-------------</code></pre><p>有时候你可能只是想打一个分隔线，但由于<strong>少空了一行</strong>导致前一行成了一个二级标题。这里的=和-任意个数都可以，关键是位置；上面的范例在真正写作的时候是不应该出现的（除非你太闲了想多打几个=玩）。</p><h1 id="很常用的语法（对于我来说）">2&emsp;很常用的语法（对于我来说）</h1><p>由于每个人使用Markdown的需求不同，常使用的语法可能相差很大。有的人可能主要用来写小说、日记，这时候其实用的语法并不多；有的可能写代码比较多，或者是写LaTeX的公式较多；甚至是使用表格更多（我觉得Markdown里的表格还是挺麻烦的，而且也不太好控制格式）。<br>我由于是流体力学专业，公式是肯定不会少的，但代码平常也用得很多，下面就从我的需求出发列一下我常用的语法。</p><h2 id="代码">2.1&emsp;代码</h2><p>普通的行内引用： `your code`  ；代码块：```&emsp;  ``` 其中三个斜点要单独占一行，第一个```后可标注该代码语言名称，一般比较常用的语言都可以识别出来。<br>好像代码块还有别的表示方式如~~~、4个空格或者1个水平制表符，但有的可能显示不出来我也不知道是不是编译器的原因。</p><h2 id="空格">2.2&emsp;空格</h2><p>这应该是最让Markdown新手抓狂的一个语法了，当我想拉开两个词的距离而多次按下<code>&lt;Space&gt;</code>时却发现，只有最开始那个空格是有效的，然后你打开百度搜索发现原来Markdown里面有这么多种空格的表达方式。我觉得最多记住一个就够了,比如我偶尔用下<code>&amp;emsp;</code>，但输入太过麻烦后面一想也基本没必要用，除非你有强迫症想让每段开头都空两个字符;或者直接在Vim加一个快捷键方便打空格。</p><h2 id="段落">2.3&emsp;段落</h2><p>毫无疑问这是第二个让新手不得不Google一下的地方，当你按下<code>&lt;Enter&gt;</code>想换个行或者多空几行时，却发现并不奏效。<br>Markdown 段落没有特殊的格式，直接编写文字就好，段落的<strong>换行</strong>是使用<strong>两个以上空格加上回车</strong>。<br><strong>空行</strong> : 也有很多种方法，推荐只记住<code>&lt;br&gt;</code>或者<code>&lt;br/&gt;</code>、<code>&lt;/br&gt;</code>这几个都行，这也是HTML的表示方法。（感觉空行还是挺常用的）  </p><h2 id="字体">2.4&emsp;字体</h2><p>首先是斜体和粗体：</p><pre><code>*斜体文本*_斜体文本_**粗体文本**__粗体文本__</code></pre><p>假如要输入一段<strong>粗体中包含<em>斜体</em>的文本</strong> ，如果全部用<code>*</code>可能就容易出错，而混搭起来层次比较清晰——本来是这么想的，但好像有时候嵌套会出现问题：</p><ul><li>斜体外套粗体：<code>**a_b_c**   **a*b*c**   __a*b*c__   __a_b_c__</code><br>显示结果如下：<strong>a_b_c</strong>   <strong>a<em>b</em>c</strong>   <strong>a<em>b</em>c</strong>   <strong>a_b_c</strong> &emsp;结果倒挺让我意外的。</li><li>粗体外加斜体：<code>_a**b**c_  *a**b**c*  *a__b__c*  _a__b__c_</code><br>显示结果如下：<em>a<strong>b</strong>c</em>  <em>a<strong>b</strong>c</em>  <em>a__b__c</em>  <em>a__b__c</em><br>总结这几个测试可以得出，<code>*</code>的优先度是大于<code>_</code>的，<strong><code>*</code>内部的<code>_</code>将失去<code>_</code>原有的作用</strong>； 而且在<code>_</code>里面的<code>_</code>也会失去作用。  </li><li>代码符号`的优先度又比<code>*</code>高，所以其内部的文字格式通过<code>*</code>控制不了。  </li></ul><p><strong>需要强调的是不同的Markdown引擎对于这些细节的处理是不一样的，我的主题用的是hexo自带的hexo-renderer-marked，当换成其他引擎如hexo-renderer-markdown-it、hexo-renderer-kramed时结果可能会不一样</strong> </p><h2 id="分隔线">2.5&emsp;分隔线</h2><pre><code>|  ***|  * * *| ******| - - -| ---| ___|   《hr》</code></pre><p>忽略前面的|（分隔线在我Blog的编译器里优先度比代码快还高，不加|根本显示不出来），而hr标签则更高，不改成中文符号根本没法显示。  （别的编译器可能显示结果又不一样）<br>随便用哪个都行，推荐<code>---</code>，因为不需要按Shift键，比较方便。</p><h2 id="删除、下划线">2.6&emsp;删除、下划线</h2><p>删除：<code>~~delete~~</code><br>下划：<code>&lt;u&gt;underline&lt;/u&gt;</code>这个复杂一点，是HTML标签<br><strong><u>测试时间到</u></strong>： </p><ul><li>与加粗的比较：<ul><li>加粗在外部： <code>__a~~b~~c__  __a&lt;u&gt;b&lt;/u&gt;c__</code><br>正常显示： <strong>a<del>b</del>c</strong>  <strong>a<u>b</u>c</strong></li><li>加粗在内部：<code>~~a__b__c~~  &lt;u&gt;a__b__c&lt;/u&gt;</code><br>加粗在内部： <del>a__b__c</del>  <u>a__b__c</u>  </li></ul></li><li>删除与下划并存：<code>~~a&lt;u&gt;b&lt;/u&gt;c~~</code>  <code>&lt;u&gt;a~~b~~c&lt;/u&gt;</code><br>显示结果  ： <del>a<u>b</u>c</del>    <u>a<del>b</del>c</u>  </li><li>其他测试均未出现问题所以不用列出来了</li></ul><p>如果把<code>__</code>换成<code>**</code>则均能正常显示，结合前面的可以得出的结论：<br><strong>加粗和斜体只记住<code>*</code>就行了，忘记<code>_</code>吧!</strong><br>当然这些结论也只适用于hexo-renderer-marked引擎（真希望有朝一日Markdown能有一个统一的完整的引擎）</p><h2 id="链接和图片">2.7&emsp;链接和图片</h2><h3 id="链接">2.7.1&emsp;链接</h3><pre class="line-numbers language-markdown"><code class="language-markdown"><span class="token url">[名称](地址 <span class="token string">"title"</span>)</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>地址</span><span class="token punctuation">></span></span>          :直接写一个网址上去也能识别为可点击的链接<span class="token url">[名称][<span class="token variable">链接名称</span>]</span><span class="token url-reference url"><span class="token punctuation">[</span><span class="token variable">链接名称</span><span class="token punctuation">]</span><span class="token punctuation">:</span> 地址</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>若要使用第三种方法，两行之间至少要空一行才能正常显示。注意使用链接时地址一定要<strong>写完整</strong>，前面的<code>http://</code>不要丢了，不然会按照相对地址进行跳转。<br>链接还可以加个title，在地址后用引号的形式写上就行；当把鼠标移到链接上时就会显示title了。<br>举个例子：<br><a href="https://onlinelibrary.wiley.com/doi/abs/10.1002/we.2306" target="_blank" rel="noopener" title="这是一篇文献">Airfoil optimisation for vertical‐axis wind turbines with variable pitch</a></p><h3 id="图片">2.7.2&emsp;图片</h3><p>和链接极为相似，只是前面多了个<code>!</code>号，注意是英文的感叹号。第一个框里面的名称基本上空着就行，或者简单写个描述，防止哪天图片挂了之后忘记当初这张图是啥样的。<br>当然也可以用HTML标签来表示图片，还能加上更多的格式控制，不过显得比较麻烦</p><pre class="line-numbers language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>img</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>图片网址<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>说到图片肯定离不开图床，毕竟图片太多的时候总不能全往一个地方塞。这里推荐PicGo这款软件，Windows和Linux下都能用，添加图片也很方便，看看它总结的一些图床吧：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191127104125.webp" alt><br>我还是白嫖的Github当作图床，不过缺点是有时候国内访问速度很慢甚至打不开（对我来说没影响就行），不过好像还有免费的<a href="https://www.jsdelivr.com/" target="_blank" rel="noopener">CDN加速可以用</a>。<br>同样图片也可以加一个title，鼠标移上去的时候会显示出来。像我这个Hexo主题还会在下方显示一行图注。</p><h2 id="列表">2.8&emsp;列表</h2><pre><code>- a+ b* c</code></pre><p>这三种都可以表示无序列表，还是推荐使用<code>-</code>，因为按键最简单；注意要<strong>留一个空格</strong>。</p><pre><code>1. a2. b3. c</code></pre><p>有序列表也很简单，也是注意要留一个<strong>空格</strong>。<br>然后是列表的嵌套，说是添加四个空格，不过有的好像只加了两个就能够显示出来。<br><strong>注意一个使用细节：</strong>列表的最后一行和下一段文字之间<strong>一定要先空一行再说</strong>，不然文章的层次会出现问题。总之没事多空一行没坏处~  </p><h2 id="引用">2.9&emsp;引用</h2><h3 id="区块引用">2.9.1&emsp;区块引用</h3><p>有时候想引用一下某人的名言警句，放弃难看的<code>“ ”</code>直接另起一行使用<code>&gt;</code>吧。而且这个也能嵌套（不知道这里嵌套有什么用）：</p><pre><code>&gt; a&gt; &gt; b&gt; &gt; &gt; c</code></pre><ul><li>注意在<code>&gt;</code>后<strong>最好加上空格</strong>，虽然实际情况是不加空格有的编译器也能显示出来，但加空格总<strong>不会出错</strong>。 </li><li>第一行用了<code>&gt;</code>相当于创了个引用块，接下来的内容都会被当作引用，直到遇见<strong>一个空行</strong>。  </li></ul><h3 id="脚注引用">2.9.2&emsp;脚注引用</h3><p>这又是一个让人蛋疼的地方，<br>脚注引用这部分并不在markdown的基本语法里，所以有的引擎比如我这个hexo默认的hexo-renderer-marked就没办法直接显示脚注。为了能够用脚注我折腾了一个下午，引擎换来换去，解决一个个新冒出来的问题，最后还是放弃了，换回了原来的hexo-renderer-marked。<br>好在最后找到了这个<a href="https://github.com/kchen0x/hexo-reference" target="_blank" rel="noopener">hexo-reference</a>插件，只需要一个命令：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">npm</span> <span class="token function">install</span> hexo-reference --save<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>再在根目录的<code>_config.yml</code>中加入：</p><pre class="line-numbers language-xml"><code class="language-xml">Plugins:  - hexo-reference<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>就能够使用脚注了！使用方法：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191127211059.webp" alt><br>举个例子：Rogalsky<sup id="fnref:1"><a href="#fn:1" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="ROGALSKY T P. Acceleration of differential evolution for aerodynamic design[M]. 2004.">[1]</span></a></sup><br>更高端一点，可以在脚注内容里面加上链接，点击直接进入文献相关页面：De Tavernier<sup id="fnref:2"><a href="#fn:2" rel="footnote"><span class="hint--top hint--error hint--medium hint--rounded hint--bounce" aria-label="[DE TAVERNIER D, FERREIRA C, BUSSEL G. Airfoil optimisation for vertical‐axis wind turbines with variable pitch[J]. Wind Energy, 2019, 22(4): 547–562.](https://onlinelibrary.wiley.com/doi/abs/10.1002/we.2306)]  ">[2]</span></a></sup><br>用户体验极佳~</p><h2 id="公式">2.10&emsp;公式</h2><p>首先得要有公式的引擎，毕竟公式这么复杂的东西Markdown自己很难搞定吧。一般推荐用MathJax引擎，配置好了之后可以用LaTeX语法写公式了~</p><h3 id="行间公式">2.10.1&emsp;行间公式</h3><p><code>$a_1+a_2$</code> : 显示为 $a_1+a_2$</p><h3 id="独立公式">2.10.2&emsp;独立公式</h3><p><code>$$\frac{\partial \rho}{\partial t}+\nabla \cdot(\rho \mathbf{v})=0 \tag{1.1}$$</code><br>显示为：<br>$$\frac{\partial \rho}{\partial t}+\nabla \cdot(\rho \mathbf{v})=0 \tag{1.1}$$<br>注意要另起一行开始再开始输入<code>$$</code>才有效。如果想要给公式加序号，在公式输完了后空个格加入<code>\tag{1.1}</code>就行,这种方式是<strong>手动编号</strong>。<br>加入编号是为了引用，引用也只能手动输入<code>$(1.1)$</code>，显示为$(1.1)$。还是比较麻烦的。</p><h3 id="LaTeX的自动编号公式">2.10.3&emsp;LaTeX的自动编号公式</h3><p>对于公式的处理又是Markdown里的一大难题，下面这一段LaTeX语句可能放在别的引擎里就识别不出来了。</p><pre><code>$$\begin{equation}x^n+y^n=z^n\end{equation}$$</code></pre><p>显示为：</p><p>$$\begin{equation}<br>x^n+y^n=z^n<br>\end{equation}$$<br>当然这些规则都可以通过Mathjax的配置进行修改，比如有的blog的mathjax配置段没有：</p><pre class="line-numbers language-js"><code class="language-js">TeX<span class="token punctuation">:</span> <span class="token punctuation">{</span>equationNumbers<span class="token punctuation">:</span> <span class="token punctuation">{</span> autoNumber<span class="token punctuation">:</span> <span class="token string">"AMS"</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>自然就不会显示自动编号。关于公式的具体语法，实在是太复杂了，不是一下子能说的清楚的；不过世界上也有大佬能够在课堂上用Markdown写公式做笔记，详见<a href="https://castel.dev/post/lecture-notes-1/" target="_blank" rel="noopener">How I’m able to take notes in mathematics lectures using LaTeX and Vim</a>。实在是太强了… </p><h1 id="其他语法">3&emsp;其他语法</h1><h2 id="表格">3.1&emsp;表格</h2><p>我是不太建议用表格的，毕竟Markdown里表格的输入并不方便，特别是比较复杂的表格，光是<code>|</code>都够你输入了，当然如果是有像Typora这样的工具的话，表格输入还是方便了不少，但Markdown无法对表格进行一些比较高级的控制，如合并单元格。</p><pre><code>| 左对齐 | 右对齐 | 居中对齐 || :-----| ----: | :----: || 单元格 | 单元格 | 单元格 || 单元格 | 单元格 | 单元格 |</code></pre><h2 id="转义-HTML等">3.2&emsp;转义/ HTML等</h2><p><code>\</code>反斜线转义字符用来显示特定的符号，这个用法在一些程序语言里非常常见。<br>另外Markdown还支持许多HTML元素的显示，但不是特殊情况一般不用，毕竟是用来方便我们写作的，没必要搞些特别复杂的东西，要求太高的话出门右拐LaTeX左拐Word欢迎你。 </p><div id="footnotes"><hr><div id="footnotelist"><ol style="list-style: none; padding-left: 0; margin-left: 40px"><li id="fn:1"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">1.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;">ROGALSKY T P. Acceleration of differential evolution for aerodynamic design[M]. 2004.<a href="#fnref:1" rev="footnote"> ↩</a></span></li><li id="fn:2"><span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">2.</span><span style="display: inline-block; vertical-align: top; margin-left: 10px;"><a href="https://onlinelibrary.wiley.com/doi/abs/10.1002/we.2306" target="_blank" rel="noopener">DE TAVERNIER D, FERREIRA C, BUSSEL G. Airfoil optimisation for vertical‐axis wind turbines with variable pitch[J]. Wind Energy, 2019, 22(4): 547–562.</a>]<a href="#fnref:2" rev="footnote"> ↩</a></span></li></ol></div></div>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-26-markdown-tips/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Linux/Windows使用记录</title>
      <link>https://chengpengzhao.com/2019-11-22-linux-windows-shi-yong-ji-lu/</link>
      <guid>https://chengpengzhao.com/2019-11-22-linux-windows-shi-yong-ji-lu/</guid>
      <pubDate>Fri, 22 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;Ubuntu出现U盘能识别但打不开&quot;&gt;1&amp;emsp;Ubuntu出
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="Ubuntu出现U盘能识别但打不开">1&emsp;Ubuntu出现U盘能识别但打不开</h1><p>这个问题困扰了我很久，不知道是什么原因造成的，网上给出的大多数解决方案也都行不通，而且有时候重启下又可以正常打开了，不知道电脑是哪里抽风。  </p><h2 id="问题描述">1.1&emsp;问题描述</h2><p>插入U盘后在桌面不显示图标，打开文件管理器能在左侧菜单看到U盘名称，但在点击时会弹出:</p><pre><code>Not Authorized polkit authority not available and caller is not uid 0</code></pre><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191123153150.webp" alt> </p><h2 id="解决方案">1.2&emsp;解决方案</h2><p>不保证所有步骤都有用，但流水线走下来就能打开了</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> usbmount<span class="token function">sudo</span> gedit /etc/usbmount/usbmount.conf<span class="token comment" spellcheck="true">#到FILESYSTEM 在其中添加vfat,ntfs（对应我原来系统的原文件中FILESYSTEM选项中没有ntfs）</span><span class="token comment" spellcheck="true">#FS_MOUNTOPTIONS这个选项里加入”"-fstype= vfat,iocharset=utf8,codepage=936,umask=000,users”</span><span class="token function">sudo</span> /etc/init.d/udev restart <span class="token comment" spellcheck="true"># 重启udev</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> exfat-utils<span class="token function">fdisk</span> -l  <span class="token comment" spellcheck="true">#确定U盘的磁盘基本情况，记住盘符</span><span class="token comment" spellcheck="true">#如 我的U盘显示的是：</span><span class="token comment" spellcheck="true">#设备        起点     末尾     扇区  大小 类型</span><span class="token comment" spellcheck="true">#/dev/sdc1   2048 60063710 60061663 28.7G Microsoft 基本数据</span><span class="token function">sudo</span> <span class="token function">fsck</span> -C -a /dev/sdc1   <span class="token comment" spellcheck="true">#进行自动修复</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>修复后显示如下信息，看来还是有问题：</p><pre class="line-numbers language-bash"><code class="language-bash">fsck，来自 util-linux 2.31.1fsck.fat 4.1 <span class="token punctuation">(</span>2017-01-24<span class="token punctuation">)</span>0x41: Dirty bit is set. Fs was not properly unmounted and some data may be corrupt. Automatically removing dirty bit.<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>没办法只能想另一个暴力点的方式：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> udisksctl <span class="token function">mount</span> --block-device /dev/sdc1<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>然后就可以打开U盘了，但可能还是没有权限编辑它，这好办，u盘里打开终端：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">chmod</span> -R 777 *<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>虽说这种不安全的命令还是少用为好，但还是挺方便的。</p><blockquote><p><em>以下内容更新于2019-11-28 16:22:19</em></p></blockquote><h1 id="Linux系统空间清理">2&emsp;Linux系统空间清理</h1><p>Ubuntu也用了一段时间了，不知不觉磁盘空间少了很多，想要清理清理。但又不像windows那样直观怕一不小心把不该删的东西删了就不好了。网上找了一下方案，发现还是这位大佬的总结最全面，这一节以下部分<strong>均摘自</strong><a href="https://www.linuxdashen.com/debianubuntu%E6%B8%85%E7%90%86%E7%A1%AC%E7%9B%98%E7%A9%BA%E9%97%B4%E7%9A%848%E4%B8%AA%E6%8A%80%E5%B7%A7" target="_blank" rel="noopener">Linux大神博客</a>。  </p><h2 id="删除残余的配置文件">2.1&emsp;删除残余的配置文件</h2><pre class="line-numbers language-bash"><code class="language-bash">dpkg --list <span class="token operator">|</span> <span class="token function">grep</span> <span class="token string">"^rc"</span> <span class="token operator">|</span> <span class="token function">cut</span> -d <span class="token string">" "</span> -f 3 <span class="token operator">|</span> <span class="token function">xargs</span> <span class="token function">sudo</span> dpkg --purge<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="删除没有用的deb软件安装包">2.2&emsp;删除没有用的deb软件安装包</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> clean <span class="token operator">&amp;&amp;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> autoclean<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h2 id="删除孤儿软件包">2.3&emsp;删除孤儿软件包</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> autoremove  <span class="token operator">&amp;&amp;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> deborphan <span class="token operator">&amp;&amp;</span>deborphan <span class="token operator">|</span> <span class="token function">xargs</span> <span class="token function">sudo</span> <span class="token function">apt-get</span> purge -y<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="删除过时的软件包">2.4&emsp;删除过时的软件包</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">aptitude</span> search ?obsolete<span class="token function">sudo</span> <span class="token function">apt-get</span> purge <span class="token operator">&lt;</span>name<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h2 id="清理日志文件">2.5&emsp;清理日志文件</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> ncdu <span class="token operator">&amp;&amp;</span><span class="token function">sudo</span> ncdu /var/log <span class="token function">sudo</span> <span class="token function">dd</span> if<span class="token operator">=</span>/dev/null of<span class="token operator">=</span>/var/log/shadowsocks.log<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="baobab硬盘空间用量分析工具">2.6&emsp;baobab硬盘空间用量分析工具</h2><pre class="line-numbers language-bash"><code class="language-bash">baobab<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="删除大容量软件包">2.7&emsp;删除大容量软件包</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> debian-goodies <span class="token operator">&amp;&amp;</span>dpigs -H --lines<span class="token operator">=</span>20<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h2 id="使用ubuntu-tweak来清理">2.8&emsp;使用ubuntu-tweak来清理</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> gdebi <span class="token operator">&amp;&amp;</span><span class="token function">sudo</span> gdebi ubuntu-tweak*.deb<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><blockquote><p><em>以下内容更新于2019-12-08 09:19:51</em></p></blockquote><h1 id="Win10卸载Vmware后键盘失灵">3&emsp;Win10卸载Vmware后键盘失灵</h1><h2 id="起因">3.1&emsp;起因</h2><p>好久没有用Windows系统了，昨天登进去清了下没用的软件，顺手把Vmware卸载了（都有双系统了还要你干嘛）；今天再进Win忽然发现键盘全部失效了（笔记本自带和外接），还以为是中病毒了紧张的不行，Google一下原来是卸载Vmware时它把注册表给整了下。</p><h2 id="解决方案-1">3.2&emsp;解决方案</h2><p>好在只是键盘有问题，鼠标能正常使用，不然我只怕只有重装系统这一条路了。</p><ol><li>登录界面，打开虚拟键盘，输入密码正常登录</li><li>打开设备管理器，找到键盘查看其状态，显示：由于其配置信息（注册表中的）不完整或已损坏，Windows 无法启动这个硬件设备</li><li>Windows菜单中找到<code>Windows轻松使用</code>，点开找到<code>虚拟键盘</code>，然后打开注册表（<code>Win+R</code>输入<code>regedit</code>）</li><li>定位到<code>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}</code>，删除<code>UpperFilters</code>项（窗口别关了）</li><li>卸载设备，重新启动。 发现键盘的状态图标中黄色感叹号没了，但还是没法使用。</li><li>还是在刚刚的注册表项，添加<code>UpperFilters</code><strong>字符串</strong>，内容为<code>kbdclass</code>。</li><li>卸载设备，重新启动，问题解决。</li></ol><blockquote><p><em>以下内容更新于2020-01-04 10:24:24</em></p></blockquote><h1 id="跨平台使用Github时出现换行符自动转换提示">4&emsp;跨平台使用Github时出现换行符自动转换提示</h1><p>解决方案来自<a href="https://github.com/cssmagic/blog/issues/22" target="_blank" rel="noopener">CSS魔法 - 博客</a>，网上也有很多人遇到过这个问题，这里直接把方案搬过来了。</p><h2 id="起因-1">4.1&emsp;起因</h2><p>在各操作系统下，文本文件所使用的换行符是不一样的。UNIX/Linux 使用的是 0x0A（LF），早期的 Mac OS 使用的是 0x0D（CR），后来的 OS X 在更换内核后与 UNIX 保持一致了。但 DOS/Windows 一直使用 0x0D0A（CRLF）作为换行符。</p><p>安装好 GitHub 的 Windows 客户端之后，这个功能默认处于“自动模式”。当你在签出文件时，Git 试图将 UNIX 换行符（LF）替换为 Windows 的换行符（CRLF）；当你在提交文件时，它又试图将 CRLF 替换为 LF。</p><p>如果你手头的这个文件是一个包含中文字符的 UTF-8 文件，那么这个“换行符自动转换”功能 在提交时是不工作的（但签出时的转换处理没有问题）。</p><h2 id="解决方案-2">4.2&emsp;解决方案</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> config --global core.autocrlf <span class="token boolean">false</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>关闭此功能，并开启换行符检查：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> config --global core.safecrlf <span class="token boolean">true</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><br><br></p><blockquote><p><em>以下内容更新于2020-01-08 10:02:04</em></p></blockquote><h1 id="Ubuntu系统启动时间过长">5&emsp;Ubuntu系统启动时间过长</h1><h2 id="起因-2">5.1&emsp;起因</h2><p>由于SSD空间不够，整个Linux系统是放在机械硬盘上的，本身启动就不如Win10,再加上启动过程中一些不必要的服务加载，导致每次都要花搓一把炉石的时间；终于忍无可忍，于是开始找加速方法…<br><a href="https://www.jianshu.com/p/11491ee15344" target="_blank" rel="noopener">详细内容可参考这篇简书</a></p><h2 id="解决方案-3">5.2&emsp;解决方案</h2><h3 id="系统分析工具">5.2.1&emsp;系统分析工具</h3><pre class="line-numbers language-bash"><code class="language-bash">systemd-analyze blame<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>使用<code>systemd</code>自带分析工具，查看各项服务启动时间，开完机后马上运行下；<br>然后针对启动时间过长的服务，如果不是系统必须的，则直接使用下面的命令禁用它：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> systemctl disable xxx.service<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>若<code>disable</code>不能彻底禁用，则改用<code>mask</code>：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> systemctl mask xxx.service<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h3 id="应用启动程序">5.2.2&emsp;应用启动程序</h3><p>去Ubuntu的应用市场搜这个管理子启动的应用，下载下来用就是了，很简单。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200108100454.webp" alt><br><br><br></p><p>经过上面两步我的Ubuntu启动时间至少快了一倍~</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-01-11 17:21:43</em></p></blockquote><h1 id="Windows下图片颜色显示问题">6&emsp;Windows下图片颜色显示问题</h1><h2 id="起因-3">6.1&emsp;起因</h2><p>重装windows也有一段时间了，今天用Lightroom准备处理下单反相片的时候发现图片显示和单反里显示的有很大不同，对比度很高而且及其难看，简直没法继续后处理下去；于是从软件的各个选项开始排查…</p><h2 id="解决方案-4">6.2&emsp;解决方案</h2><p>最后发现是Win10自身颜色校正没有弄好，不关软件的事；按Win键然后搜索颜色管理，如图：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store2/img/20200111171027.webp" alt><br>设置成<strong>Adobe RGB</strong>（单反的颜色空间也设置成Adobe RGB)，然后校准下显示器；重启再次打开Lightroom，OK问题解决~</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-02-09 20:46:44</em></p></blockquote><h1 id="Windows开机一会儿就卡死">7&emsp;Windows开机一会儿就卡死</h1><h2 id="起因-4">7.1&emsp;起因</h2><p>一般Windows死机有两种：蓝屏或是彻底卡死；第一种对于Win10用户来说应该是家常便饭了，不过我的笔记本最近总是用着用着忽然卡住，按<code>Num Lock</code>也没反应的那种，这就很难受了，只能强制重启。<br>原因排查起来就比较困难了，我之前的ThinkPad用了几年后也有这个问题，不过重装系统之后就没再出现过。但现在用的神舟是刚重装完最新的win10，数据也比较多舍不得重装，一时间有点不知所措。<br><br><br>无非是硬盘、驱动、显卡、系统之中的哪一项出了毛病。让我花时间一个个排查是不可能的，换台新本因为没钱是不现实的。最效率的方法应该是将有过同样问题的人的解决方案全部试一遍，之后就随缘了。</p><h2 id="解决方案-5">7.2&emsp;解决方案</h2><p>能否真正解决这个问题不能保证，至少我把前3项过了一遍之后死机情况就暂时没出现过了。(实践之前电脑处于开机不到三分钟就卡死然后强制重启继续卡死的循环中…)  </p><ul><li>桌面右键-显示设置-电源和睡眠-（屏幕和睡眠都调成从不），在电源高级选项里将<strong>关闭硬盘时间</strong>设置长一些，如2000分钟</li><li>拔插电源（这都能想出来）</li><li>更新所有驱动</li><li>电脑保养，清下灰什么的</li><li>换个（固态）硬盘——穷人的折中方案</li></ul><h1 id="Python环境变量问题">8&emsp;Python环境变量问题</h1><h2 id="起因-5">8.1&emsp;起因</h2><p>最近重装了WSL，由Ubuntu换到了Debian，据说更稳定一些。但遇到了个小问题：pythonn3-pip安装一些库之后调用还是提示<code>command not found</code>，估计着是环境变量没设置好。  </p><h2 id="解决方案-6">8.2&emsp;解决方案</h2><p>进入python查看相关路径：</p><pre class="line-numbers language-bash"><code class="language-bash">python3<span class="token operator">>></span><span class="token operator">></span>  <span class="token function">import</span> sys <span class="token operator">>></span><span class="token operator">></span> sys.path<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>我机器的运行结果是：</p><pre class="line-numbers language-python"><code class="language-python"><span class="token punctuation">[</span><span class="token string">''</span><span class="token punctuation">,</span> <span class="token string">'/usr/lib/python37.zip'</span><span class="token punctuation">,</span> <span class="token string">'/usr/lib/python3.7'</span><span class="token punctuation">,</span> <span class="token string">'/usr/lib/python3.7/lib-dynload'</span><span class="token punctuation">,</span> <span class="token string">'/home/zcp/.local/lib/python3.7/site-packages'</span><span class="token punctuation">,</span> <span class="token string">'/usr/local/lib/python3.7/dist-packages'</span><span class="token punctuation">,</span> <span class="token string">'/usr/lib/python3/dist-packages'</span><span class="token punctuation">]</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>原来pip下载的包放到了<code>/home/zcp/.local/lib</code>路径下，而这一路径未被加入<code>PATH</code>里，自然会提示错误。<br>我用的zsh，故只需在<code>.zshrc</code>中加入该PATH就行：</p><pre class="line-numbers language-bash"><code class="language-bash">vim ~/.zshrc<span class="token comment" spellcheck="true"># 文件中加入下面一行</span><span class="token function">export</span> PATH<span class="token operator">=</span>/home/zcp/.local/bin:<span class="token variable">$PATH</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>再<code>source ~/.zshrc</code>一下，问题解决~</p><p><br><br></p><blockquote><p><em>以下内容更新于2020-05-12 21:19:28</em></p></blockquote><h1 id="Ubuntu的引导修复">9&emsp;Ubuntu的引导修复</h1><p>刚开始接触Linux系统时就遇到了这个问题，折腾了好像有一整天，当时忘记把解决方法记录下来了，结果在不久的将来又遇到了几次这个问题，真是醉了（可能是因为我安装的是第三方的ubuntu镜像，默认装了一些专业相关的软件）。</p><h2 id="解决方案-7">9.1&emsp;解决方案</h2><h3 id="摆脱gurb界面">9.1.1&emsp;摆脱gurb界面</h3><p>欣喜的安装完Ubuntu系统、重启，却进入了一片黑的grub界面，不要慌，愚蠢的系统需要你来引导一下：</p><pre class="line-numbers language-grub"><code class="language-grub"># 方法1set root=(hd # 按Tab补全，找到Linux系统所在盘符set prefix=(hd*,**)/boot/grubinsmod normalnormal# 方法2set root=(hd set prefix=(hd*,**)/boot/grublinux /boot/vmli...initrd /initrd...#...表示按Tab补全boot<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>两种方法我都用过，上次装双系统用的方法2，这次在旧电脑装ubuntu用方法1就奏效了。</p><h3 id="修复引导">9.1.2&emsp;修复引导</h3><ul><li><p>第一种方法，用u盘进入它上面的ubuntu系统，安装boot-repair软件进行修复<br>装双系统时我这样一弄就能成功引导了，但这次却不管用，不知道啥原因</p></li><li><p>用<code>rEFind</code>软件进行引导<br>经过前一个步骤进入系统后，直接在<a href="http://www.rodsbooks.com/refind/" target="_blank" rel="noopener">rEFind官网</a>下载deb包安装就行了，之后重启进入bios调整boot顺序，将rEFind放在第一位。</p></li></ul>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-22-linux-windows-shi-yong-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>从Hugo折腾到Hexo过程记录</title>
      <link>https://chengpengzhao.com/2019-11-20-cong-hugo-zhe-teng-dao-hexo-guo-cheng-ji-lu/</link>
      <guid>https://chengpengzhao.com/2019-11-20-cong-hugo-zhe-teng-dao-hexo-guo-cheng-ji-lu/</guid>
      <pubDate>Wed, 20 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;本来对自己之前基于hug
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>本来对自己之前基于hugo的博客感觉挺满意的，直到某一天手贱点开了一篇关于如何把豆瓣读书等模块加入到博客中的文章，于是羡慕之情油然而生。<br>在网上搜了一下发现是有个大佬写了个基于Hexo的<a href="https://github.com/mythsman/hexo-douban" target="_blank" rel="noopener">小插件</a>，顿时心灰意冷，因为当时从零基础开始折腾博客花费了太多时间，到最后也没完全弄懂。<br>一边纠结着到底要不要换成Hexo一边看着程序员大佬们的博客，忽然眼前一亮发现了一款比较好的主题<a href="https://github.com/chengpengzhao/hexo-theme-fluid" target="_blank" rel="noopener">Fluid</a> ，Material Design 风格而且功能比较多文档描述的很详细，大呼为什么没有早点发现这么好的东西，于是开始了为期3天的折腾之旅。</p><hr><p>折腾到一半发现这个hexo-theme-fluid主题主页两边比较空，想改看了下源码却不知道从何开始下手；再加上不知道这个主题和hexo-douban是否兼容，又有点犹豫了，后悔花了时间却啥也没干成之余，无意间又发现了一款Material Design的主题 <a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank" rel="noopener"><strong>hexo-theme-matery</strong></a>！功能更加全面而且也很好看，阅读时目录、上下一篇等小细节也做的不错，于是义无反顾地选择了它。  </p><hr><p>用户体验还是很不错的，折腾完后我非常高兴。总算可以不再去弄这些华丽胡哨的，专心去读书写作了（其实都是借口）。</p><p><strong>下面简单记录一下我从零开始建立这个基于Hexo的博客的过程，由于有很多这方面的文章，我只记录一些比较细节的东西，防止自己再次踩坑</strong> </p><h1 id="首先得安装Hexo吧">2&emsp;首先得安装Hexo吧</h1><p>发现和hugo其实差不太多，但好像hugo当时没有必须要nodejs吧，这里我先<strong>升级了npm和nodejs</strong> ，防止版本过低又弄出什么bug</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> apt update<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> git-core <span class="token comment" spellcheck="true">#git是肯定要有的</span><span class="token function">sudo</span> <span class="token function">npm</span> <span class="token function">install</span> npm@latest -g<span class="token function">sudo</span> <span class="token function">npm</span> cache clean -f<span class="token function">sudo</span> <span class="token function">npm</span> <span class="token function">install</span> -g n<span class="token function">sudo</span> n stable<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> nodejs-legacynode -v<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>安装hexo~       <code>sudo npm install -g hexo-cli</code> </p><h1 id="当前操作系统配置Key（差点忘记）">3&emsp;当前操作系统配置Key（差点忘记）</h1><p>免得每次push的时候都得输入用户名密码，让更新blog变得更方便。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> ~/.sshssh-keygen -t rsa -C <span class="token string">"邮件地址"</span><span class="token comment" spellcheck="true">#敲入代码后连续按3次回车，最终会生成一个文件在用户目录下，打开用户目录，找到.ssh\id_rsa.pub文件，记事本打开并复制里面的内容。打开你的 GitHub 主页，进入个人设置 -> SSH and GPG keys -> New SSH key，并将刚刚复制的内容填入 Key 那里。</span><span class="token function">ssh</span> -T git@github.com<span class="token comment" spellcheck="true">#如果提示Are you sure you want to continue connecting (yes/no)?，输入yes 并回车</span><span class="token function">git</span> config --global user.name <span class="token string">"你的 GitHub 用户名"</span><span class="token function">git</span> config --global user.email  <span class="token string">"你的 GitHub 注册邮箱"</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>之后如果要clone自己的仓库到本地时记得选择用<strong>SSH</strong>的URL来clone，这样在push时就可以不用输入用户名和密码了。(不过windows下我好像就用了普通的URLclone结果也不用输入密码，不太清楚原理) </p><h1 id="建立站点下载主题">4&emsp;建立站点下载主题</h1><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">mkdir</span> Hexo_site<span class="token function">cd</span> Hexo_sitehexo init<span class="token function">cd</span> themes<span class="token function">git</span> clone -b develop https://github.com/blinkfox/hexo-theme-matery.git<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>接着只要运行</p><pre class="line-numbers language-bash"><code class="language-bash">hexo clean <span class="token operator">&amp;&amp;</span> hexo g \hexo s<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>就可以看到这个主题模板已经建立好了。</p><p><br><br><br><br><br></p><h1 id="具体配置过程（重中之重）">5&emsp;具体配置过程（重中之重）</h1><p>前面的所有步骤15分钟内就可以完成，真正难在怎么去自定义这个模板，修改成自己舒服的样式才是最重要的嘛。不然大家为什么花那么多时间去折腾。<br>我这个主题的文档也说明的非常详细了，可以对照着<a href="https://github.com/blinkfox/hexo-theme-matery/blob/develop/README_CN.md" target="_blank" rel="noopener">它</a>从头到尾先根据自己情况修改一遍。 </p><h2 id="如何建立新页面">5.1&emsp;如何建立新页面</h2><p>照着说明文档建立了tags、about、categories等页面之后，大概明白了怎么去配置菜单栏，首先在<code>_config.yml</code>中建立起一二级菜单，排好序、选好图标、确定url名称，下面是我主题配置文件相关部分：</p><pre class="line-numbers language-yml"><code class="language-yml">menu:  Index:    url: /    icon: fas fa-home  Tags:    url: /tags    icon: fas fa-tags  Categories:    url: /categories    icon: fas fa-bookmark  Archives:    url: /archives    icon: fas fa-archive  About:    url: /about    icon: fas fa-user-circle  Contact:    url: /contact    icon: fas fa-comments  Friends:    url: /friends    icon: fas fa-address-book  Medias:    icon: fas fa-list    children:      - name: Books        url: /books        icon: fas fa-book      - name: Games        url: /games        icon: fas fa-gamepad      - name: Movies        url: /movies        icon: fas fa-film      - name: Hitokoto        url: /hitokoto        icon: fas fa-comment-alt<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>建好了之后去根目录<code>/source</code>文件夹下建好相应子文件夹，这里我的<code>/books /games /movies</code>是之后用hexo-douban插件生成的页面所以不需要建立文件夹。<br>然后先可以去看下效果，发现有的页面已经接近完美了，因为layout里面就有相关的样式设置。这时候需要<strong>认真阅读</strong><code>themes/hexo-theme-matery/layout</code>相关样式文件(.ejs),然后到处抄一点最后完成自定义页面的布局…<br>我是不怎么会抄所以只能做一个简单的<a href="https://chengpengzhao.com/hitokoto/">一言</a>页面。 </p><h2 id="豆瓣插件的安装">5.2&emsp;豆瓣插件的安装</h2><p>终于到这部分了，害得我花了几天折腾博客的罪魁祸首。关于怎么安装，作者的<a href="https://github.com/mythsman/hexo-douban" target="_blank" rel="noopener">github</a>上已经说的很清楚了，这里主要问题是适配和一些小问题的解决：</p><h3 id="适配主题">5.2.1&emsp;适配主题</h3><p>我自己不太会弄，这里参考了<a href="https://licardo.cn/posts/11199/" target="_blank" rel="noopener">一位医学大佬</a>的解决方案。啥都不用想，抄就完事了，多轻松。</p><h3 id="关于弹窗">5.2.2&emsp;关于弹窗</h3><p>弄好之后发现每次打开豆瓣读书相关页面会弹出三个空白窗口，在网上搜了一下发现是Hexo4.0新版本的问题，详细请参考<a href="https://github.com/hexojs/hexo/issues/3796" target="_blank" rel="noopener">这里</a>，我的解决方法是将根目录的配置文件中相关部分改为：</p><pre class="line-numbers language-yml"><code class="language-yml">external_link:  enable: true  field: post<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>然后就不会出现不需要的弹窗了，或者将hexo版本降至3.9</p><h2 id="关于Markdown把英文的引号’显示成’的解决方案">5.3&emsp;关于Markdown把英文的引号’显示成’的解决方案</h2><p>这个不是主题的问题，而是相关插件hexo-renderer-marked的设置问题。<br>在<code>/node_modules/hexo-renderer-marked</code>文件夹下，找到<code>index.js</code>，将其中<strong>smartypants</strong>选项改成：</p><pre class="line-numbers language-js"><code class="language-js">smartypants<span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>应该就没问题了。</p><h2 id="评论系统的邮件提醒问题">5.4&emsp;评论系统的邮件提醒问题</h2><p>如果用的是Valine评论系统并打开了回复邮件提醒但没设置模板，那么对方可能忽然收到这样一封莫名其妙的邮件：</p><pre class="line-numbers language-bash"><code class="language-bash">您请求重设应用xxxx 的密码。点击下列链接来重设您的帐号密码（链接在 48 小时内有效）：https://leancloud.cn/reset.html?token<span class="token operator">=</span>xxxxxxxxxxxxxxxxx<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>我刚建立好博客的时候也有这个问题，还好被别人提醒了。于是干脆部署了<a href="https://github.com/DesertsP/Valine-Admin" target="_blank" rel="noopener">Valine Admin</a>，是Valine 评论系统的扩展和增强，可以确保对方收到了自己的回复，并定时检查博客的新留言情况。<br>缺点是步骤比较复杂，还得先实名认证一下（现在的实名认证越来越嚣张了，动不动就给你采集个人脸信息。没办法，有空子谁不想钻呢）。</p><h2 id="关于CNAME">5.5&emsp;关于CNAME</h2><p>上传到github之前记得在根目录<code>source</code>文件夹下建立一个无后缀叫做<code>CNAME</code>的文档，里面写上自己用来当博客的域名（买了域名的）。这样保证每次上传后不用重复去github设定自定义域名。  </p><h2 id="404页面">5.6&emsp;404页面</h2><p>发现这个主题好像没有404页面，于是自己建了一个。步骤很简单：</p><pre class="line-numbers language-bash"><code class="language-bash">hexo new page <span class="token string">"404"</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>然后去编辑<code>/source/404</code>下的<code>index.md</code>文件就行了，觉得不够好看的再去<code>layout</code>建立个样式文件。   </p><h1 id="关于post">6&emsp;关于post</h1><p>记住post的Front-matter选项还是很有必要的，这里把主题相关说明文档抄了一部分过来：  </p><p><code>Front-matter</code> 选项中的所有内容均为<strong>非必填</strong>的。但仍然建议至少填写 <code>title</code> 和 <code>date</code> 的值。</p><table><thead><tr><th align="center">配置选项</th><th align="center">默认值</th><th align="center">描述</th></tr></thead><tbody><tr><td align="center">title</td><td align="center"><code>Markdown</code> 的文件标题</td><td align="center">文章标题，强烈建议填写此选项</td></tr><tr><td align="center">date</td><td align="center">文件创建时的日期时间</td><td align="center">发布时间，强烈建议填写此选项，且最好保证全局唯一</td></tr><tr><td align="center">author</td><td align="center">根 <code>_config.yml</code> 中的 <code>author</code></td><td align="center">文章作者</td></tr><tr><td align="center">img</td><td align="center"><code>featureImages</code> 中的某个值</td><td align="center">文章特征图，推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如: <code>http://xxx.com/xxx.jpg</code></td></tr><tr><td align="center">top</td><td align="center"><code>true</code></td><td align="center">推荐文章（文章是否置顶），如果 <code>top</code> 值为 <code>true</code>，则会作为首页推荐文章</td></tr><tr><td align="center">cover</td><td align="center"><code>false</code></td><td align="center"><code>v1.0.2</code>版本新增，表示该文章是否需要加入到首页轮播封面中</td></tr><tr><td align="center">coverImg</td><td align="center">无</td><td align="center"><code>v1.0.2</code>版本新增，表示该文章在首页轮播封面需要显示的图片路径，如果没有，则默认使用文章的特色图片</td></tr><tr><td align="center">password</td><td align="center">无</td><td align="center">文章阅读密码，如果要对文章设置阅读验证密码的话，就可以设置 <code>password</code> 的值，该值必须是用 <code>SHA256</code> 加密后的密码，防止被他人识破。前提是在主题的 <code>config.yml</code> 中激活了 <code>verifyPassword</code> 选项</td></tr><tr><td align="center">toc</td><td align="center"><code>true</code></td><td align="center">是否开启 TOC，可以针对某篇文章单独关闭 TOC 的功能。前提是在主题的 <code>config.yml</code> 中激活了 <code>toc</code> 选项</td></tr><tr><td align="center">mathjax</td><td align="center"><code>false</code></td><td align="center">是否开启数学公式支持 ，本文章是否开启 <code>mathjax</code>，且需要在主题的 <code>_config.yml</code> 文件中也需要开启才行</td></tr><tr><td align="center">summary</td><td align="center">无</td><td align="center">文章摘要，自定义的文章摘要内容，如果这个属性有值，文章卡片摘要就显示这段文字，否则程序会自动截取文章的部分内容作为摘要</td></tr><tr><td align="center">categories</td><td align="center">无</td><td align="center">文章分类，本主题的分类表示宏观上大的分类，只建议一篇文章一个分类</td></tr><tr><td align="center">tags</td><td align="center">无</td><td align="center">文章标签，一篇文章可以多个标签</td></tr><tr><td align="center">reprintPolicy</td><td align="center">cc_by</td><td align="center">文章转载规则， 可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprint 或 pay 中的一个</td></tr></tbody></table><blockquote><p><strong>注意</strong>:</p><ol><li>如果 <code>img</code> 属性不填写的话，文章特色图会根据文章标题的 <code>hashcode</code> 的值取余，然后选取主题中对应的特色图片，从而达到让所有文章都的特色图<strong>各有特色</strong>。</li><li><code>date</code> 的值尽量保证每篇文章是唯一的，因为本主题中 <code>Gitalk</code> 和 <code>Gitment</code> 识别 <code>id</code> 是通过 <code>date</code> 的值来作为唯一标识的。</li><li>如果要对文章设置阅读验证密码的功能，不仅要在 Front-matter 中设置采用了 SHA256 加密的 password 的值，还需要在主题的 <code>_config.yml</code> 中激活了配置。有些在线的 SHA256 加密的地址，可供你使用：<a href="http://tool.oschina.net/encrypt?type=2" target="_blank" rel="noopener">开源中国在线工具</a>、<a href="http://encode.chahuo.com/" target="_blank" rel="noopener">chahuo</a>、<a href="http://tool.chinaz.com/tools/hash.aspx" target="_blank" rel="noopener">站长工具</a>。</li><li>您可以在文章md文件的 front-matter 中指定 reprintPolicy 来给单个文章配置转载规则</li></ol></blockquote><p>下面是一个例子，防止自己将来忘记所以列出了尽可能多的选项：</p><pre class="line-numbers language-markdown"><code class="language-markdown"><span class="token hr punctuation">---</span> title: typoradate: 2019-11-20 author:  img: /source/images/xxx.jpg top: true cover: true coverImg: /images/1.jpg password:toc: false mathjax: false summary: 这是你自定义的文章摘要内容，如果这个属性有值，文章卡片摘要就显示这段文字，否则程序会自动截取文章的部分内容作为摘要 categories: Markdown tags:   <span class="token list punctuation">-</span> Typora   <span class="token list punctuation">-</span> Markdown <span class="token hr punctuation">---</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><br><br><br></p><blockquote><p> <strong>2019/11/22更新</strong>  <em>有人说我的博客打不开，再加上我Godaddy买的域名没办法续费，干脆连着domain全部搬家</em></p></blockquote><h1 id="CDN加速，把DNS迁移到cloudflare">7&emsp;CDN加速，把DNS迁移到cloudflare</h1><h2 id="注册帐号">7.1&emsp;注册帐号</h2><p>翻了下好像中文只在帮助里有一小部分，主要还是英文。在注册之前可以先解除原来第三方的托管，我之前用的是DNSPOD，大半年没看一打开DNS怎么这么多条。<br>毫不犹豫能删的先全删了再说，然后进我买域名的Godaddy里将DNS托管改为cloudflare(按照它这里给的提示)。<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122191602.webp" alt><br>然后托管成功之后先把DNS给加上（因为之前全删了)，我是用的github平台，直接用CNAME加了@和www,指向<a href="https://chengpengzhao.github.io" target="_blank" rel="noopener">chengpengzhao.github.io</a> 。当然也可以使用A方式加ip就行了，我懒得去ping一下ip所以没用这种方法。<br>接下来的部分就难到我了，简直选择困难，这也体现了cloudflare的强大之处：这配置项也太多了吧。只能慢慢看它的说明一个个设置，先开个版块记录一下有哪些坑。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122193259.webp" alt> </p><h2 id="cloudflare设置">7.2&emsp;cloudflare设置</h2><h3 id="Scrape-Shield">7.2.1&emsp;Scrape Shield</h3><p>这一大项是关于反爬虫的，可以适当打开几个保护措施，但其中的Hotlink Protection可以选择关闭，不然在别人blog加你友链时他那边没法显示你的头像（不要问我怎么知道的）。<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122193950.webp" alt>  </p><h3 id="Speeding">7.2.2&emsp;Speeding</h3><p>这个里面有很多选项可以加快博客的访问速度，我先全部打开试了试，发现在浏览博客时很多效果都没了，直接不让加载，要按F5才能刷新出来。经过排查应该是Brotli这个选项的问题，因为我只关了这个然后问题就解决了，当然也不排除是别的原因。<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191123160848.webp" alt></p><h3 id="Page-Rules">7.2.3&emsp;Page Rules</h3><p>据说这个功能挺强大的，我也不太会就按照网上别人的设置弄了一下，先看看实际效果如何吧。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191123161014.webp" alt> </p><h2 id="将整个域名迁移到cloudflare">7.3&emsp;将整个域名迁移到cloudflare</h2><p>既然能够放在一起那我为什么还要多记一个账号的信息呢，godaddy再见了您。<br>首先在DNS管理页面能够看到当前domain所在运营商，如下图：<img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122194606.webp" alt>  </p><p>点击<code>Manage domain</code>就可以开始迁移流程了，不过在此之前需要在cloudflare账号中绑定<strong>支付手段</strong>，可以是VISA卡或者PayPal，不支持银联等国内的支付产品（不过可以通过Paypal绑定银联卡）。<br>然后你会收到Godaddy发来的一系列邮件，这里<strong>注意</strong>要想马上迁移完成需要登录Godaddy账号点一下Accept，中文版网站我好像没找到这个选项，切成英文就OK了：  </p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122195510.webp" alt><br>过了15分钟左右就会收到Godaddy最后煽情的告别邮件：</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/20191122195930.webp" alt><br>大功告成，接下来就可以享受cloudflare的服务了，域名的费用是8美刀一年，应该算是比较便宜的吧。我当初在Godaddy上买10年也花了580人民币，续费好像更贵。</p><h1 id="Post排版自定义">8&emsp;Post排版自定义</h1><p>忽然觉得Post如果有很多一二三级标题的话就有点难阅读了，有时候一眼看过去不能立即分辨出来这是第几级标题。所以感觉编号还是很重要的，但在写文章的时候还要注意编号就太不效率了，最后我选择<strong>给Post标题加入自动编号</strong>。  </p><h2 id="标题自动编号">8.1&emsp;标题自动编号</h2><h3 id="先折腾一番再说">8.1.1&emsp;先折腾一番再说</h3><p>百度了一下自动编号的实现方式，根据这个主题的layout立马试了下，对<code>layout/_partial</code>文件夹下<code>post-detail-toc.ejs</code>文件的开头部分作了些修改：</p><pre class="line-numbers language-css"><code class="language-css"><span class="token selector"><span class="token id">#articleContent</span> h1 </span><span class="token punctuation">{</span>    <span class="token property">counter-increment</span><span class="token punctuation">:</span> counter_h<span class="token number">1</span><span class="token punctuation">;</span>    <span class="token property">counter-reset</span><span class="token punctuation">:</span> counter_h<span class="token number">2</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector"><span class="token id">#articleContent</span> h1<span class="token pseudo-element">:before</span> </span><span class="token punctuation">{</span>    <span class="token property">content</span><span class="token punctuation">:</span> <span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">1</span><span class="token punctuation">)</span><span class="token string">"　"</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector"><span class="token id">#articleContent</span> h2 </span><span class="token punctuation">{</span>    <span class="token property">counter-increment</span><span class="token punctuation">:</span> counter_h<span class="token number">2</span><span class="token punctuation">;</span>    <span class="token property">counter-reset</span><span class="token punctuation">:</span> counter_h<span class="token number">3</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector"><span class="token id">#articleContent</span> h2<span class="token pseudo-element">:before</span> </span><span class="token punctuation">{</span>    <span class="token property">content</span><span class="token punctuation">:</span> <span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">1</span><span class="token punctuation">)</span><span class="token string">"."</span><span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">2</span><span class="token punctuation">)</span><span class="token string">"　"</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector"><span class="token id">#articleContent</span> h3 </span><span class="token punctuation">{</span>    <span class="token property">counter-increment</span><span class="token punctuation">:</span> counter_h<span class="token number">3</span><span class="token punctuation">;</span>    <span class="token property">counter-reset</span><span class="token punctuation">:</span> counter_h<span class="token number">4</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token selector"><span class="token id">#articleContent</span> h3<span class="token pseudo-element">:before</span> </span><span class="token punctuation">{</span>    <span class="token property">content</span><span class="token punctuation">:</span> <span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">1</span><span class="token punctuation">)</span><span class="token string">"."</span><span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">2</span><span class="token punctuation">)</span><span class="token string">"."</span><span class="token function">counter</span><span class="token punctuation">(</span>counter_h<span class="token number">3</span><span class="token punctuation">)</span><span class="token string">"　"</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这段代码利用css的counter属性实现自动编号；但编号有是有了，我发现侧边目录也就是Toc仍没有编号，并且点击右侧跳转当前标题会被上面的状态栏挡住，还是需要进一步修改。<br>在<code>matery.css</code>里改来改去，还是有点小问题，而且侧边栏的编号不知道怎么加，最后我放弃了这条思路。</p><h3 id="最后采用的方法">8.1.2&emsp;最后采用的方法</h3><p>抱着一点期待在github上翻了下，还真的有相关的小工具，<a href="https://github.com/r12f/hexo-heading-index" target="_blank" rel="noopener">hexo-heading-index</a>，按照说明先用npm安装：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">npm</span> <span class="token function">install</span> hexo-heading-index --save<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>再在根目录的<code>_config.yml</code>中插入相关设置：</p><pre class="line-numbers language-yml"><code class="language-yml">heading_index:  enable: true  index_styles: "{1} {1} {1} {1} {1} {1}"  connector: "."  global_prefix: ""  global_suffix: "&emsp;"<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>可以根据个人喜好适当修改，这里我用了个<code>&amp;emsp</code>来让序号和标题隔得更开一点。再<code>hexo s</code>看看效果，恩不错，还是白嫖人家写的东西好。但仍有个小问题就是在<strong>不想要出现序号的地方也给编了号</strong>，比如说我的<a href="https://chengpengzhao.com/friends/">友情链接</a>。这里中部的文字也是Post的格式所以也给加上了编号，看起来自然不太舒服。<br>但这个插件好像没更新过了不知道怎么设置不编号的区域，所以只能自己改源码。好在代码写得还比较清楚，我通过<strong>只对前三级标题编号，在不想自动编号的地方用后三级标题</strong>的方式解决，只需要在<code>hexo-heading-index/lib/index.js</code>中稍作修改：</p><pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">updateHeadingIndexes</span><span class="token punctuation">(</span>options<span class="token punctuation">,</span> data<span class="token punctuation">)</span> <span class="token punctuation">{</span>    <span class="token keyword">var</span> $ <span class="token operator">=</span> cheerio<span class="token punctuation">.</span><span class="token function">load</span><span class="token punctuation">(</span>data<span class="token punctuation">,</span> <span class="token punctuation">{</span> decodeEntities<span class="token punctuation">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">var</span> headings <span class="token operator">=</span> <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'h1, h2, h3'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//这里修改需要几级标题</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p><code>headings</code>里面只保留想要自动编号的部分就行了。大功告成~ </p><h2 id="一级标题下自动插入分隔线">8.2&emsp;一级标题下自动插入分隔线</h2><p>只需要在<code>hexo-theme-matery/source/js/matery.js</code>中相应部分加一行就行了：</p><pre class="line-numbers language-js"><code class="language-js">    <span class="token comment" spellcheck="true">/*文章内容详情的一些初始化特性*/</span>    <span class="token keyword">let</span> articleInit <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>        <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#articleContent a'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">attr</span><span class="token punctuation">(</span><span class="token string">'target'</span><span class="token punctuation">,</span> <span class="token string">'_blank'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token function">$</span><span class="token punctuation">(</span><span class="token string">'#articleContent h1'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">after</span><span class="token punctuation">(</span><span class="token string">'&lt;hr>'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment" spellcheck="true">//一级标题后加一行分隔线</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>然后可以在<code>matery.css</code>里修改下分隔线的样式：</p><pre class="line-numbers language-css"><code class="language-css"><span class="token comment" spellcheck="true">/*修改hr的样式*/</span><span class="token selector">hr  </span><span class="token punctuation">{</span>  <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">20</span>px <span class="token number">0</span><span class="token punctuation">;</span>  <span class="token property">height</span><span class="token punctuation">:</span> <span class="token number">3</span>px<span class="token punctuation">;</span>  <span class="token property">border</span><span class="token punctuation">:</span> none<span class="token punctuation">;</span>    <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">0</span><span class="token punctuation">;</span>    <span class="token property">border-top</span><span class="token punctuation">:</span> <span class="token number">1</span>px solid <span class="token hexcode">#ccc</span><span class="token punctuation">;</span>  <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode">#272822</span><span class="token punctuation">;</span>  <span class="token property">background-image</span><span class="token punctuation">:</span> <span class="token function">repeating-linear-gradient</span><span class="token punctuation">(</span>    -<span class="token number">45</span>deg,    white,    white <span class="token number">4</span>px,    transparent <span class="token number">4</span>px,    transparent <span class="token number">8</span>px  <span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>如果你也觉得再让一级标题居中会更舒服的话，只需在h1样式中加入<code>text-align: center;</code>就OK了。 </p><blockquote><p><em>以下内容更新于2019-12-02 20:08:06</em></p></blockquote><h1 id="调整hexo-renderer-marked中Mathjax公式显示">9&emsp;调整hexo-renderer-marked中Mathjax公式显示</h1><p>发现默认的mathjax和marked的配置有的冲突，一些公式没法正常显示，做如下调整：</p><ul><li><code>layout/post.ejs</code>文件中相关部分调整，防止()内的内容显示为公式<pre class="line-numbers language-js"><code class="language-js"><span class="token operator">&lt;</span>script<span class="token operator">></span>  MathJax<span class="token punctuation">.</span>Hub<span class="token punctuation">.</span><span class="token function">Config</span><span class="token punctuation">(</span><span class="token punctuation">{</span>      tex2jax<span class="token punctuation">:</span> <span class="token punctuation">{</span>inlineMath<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">'$'</span><span class="token punctuation">,</span> <span class="token string">'$'</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        displayMath<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">"$$"</span><span class="token punctuation">,</span><span class="token string">"$$"</span><span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span>        processEscapes<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>        skipTags<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'script'</span><span class="token punctuation">,</span> <span class="token string">'noscript'</span><span class="token punctuation">,</span> <span class="token string">'style'</span><span class="token punctuation">,</span> <span class="token string">'textarea'</span><span class="token punctuation">,</span> <span class="token string">'pre'</span><span class="token punctuation">,</span> <span class="token string">'code'</span><span class="token punctuation">]</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span>  TeX<span class="token punctuation">:</span> <span class="token punctuation">{</span>equationNumbers<span class="token punctuation">:</span> <span class="token punctuation">{</span> autoNumber<span class="token punctuation">:</span> <span class="token string">"AMS"</span> <span class="token punctuation">}</span>   <span class="token punctuation">}</span>  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token operator">&lt;</span><span class="token operator">/</span>script<span class="token operator">></span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre></li><li><code>node_modules/marked/lib/marked.js</code>文件修改正则表达式部分，调整渲染策略<pre class="line-numbers language-js"><code class="language-js"><span class="token keyword">var</span> inline <span class="token operator">=</span> <span class="token punctuation">{</span>  escape<span class="token punctuation">:</span> <span class="token operator">/</span><span class="token operator">^</span>\\<span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token operator">!</span>"#$<span class="token operator">%</span>'<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">*</span><span class="token operator">+</span><span class="token punctuation">,</span>\<span class="token operator">-</span><span class="token punctuation">.</span><span class="token operator">/</span><span class="token punctuation">:</span><span class="token punctuation">;</span><span class="token operator">&lt;=</span><span class="token operator">></span><span class="token operator">?</span>@\<span class="token punctuation">[</span>\<span class="token punctuation">]</span><span class="token operator">^</span>_<span class="token template-string"><span class="token string">`|~])/,//escape: escape: /^\\([!"#$%&amp;'()*+,\-./:;&lt;=>?@\[\]\\^_`</span></span><span class="token punctuation">{</span><span class="token operator">|</span><span class="token punctuation">}</span><span class="token operator">~</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">/</span><span class="token punctuation">,</span>br<span class="token punctuation">:</span> <span class="token regex">/^ {2,}\n(?!\s*$)/</span><span class="token punctuation">,</span><span class="token comment" spellcheck="true">//br: /^( {2,}|\\)\n(?!\s*$)/,</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre>其余部分未作调整。</li></ul><blockquote><p><em>以下内容更新于2019-12-04 16:39:37</em></p></blockquote><h1 id="hexo-prism-plugin相关语言支持及缩写">10&emsp;hexo-prism-plugin相关语言支持及缩写</h1><pre><code>    Markup - markup, html, xml, svg, mathml    CSS - css    C-like - clike    JavaScript - javascript, js    ABAP - abap    Augmented Backus–Naur form - abnf    ActionScript - actionscript    Ada - ada    ANTLR4 - antlr4, g4    Apache Configuration - apacheconf    APL - apl    AppleScript - applescript    AQL - aql    Arduino - arduino    ARFF - arff    AsciiDoc - asciidoc, adoc    6502 Assembly - asm6502    ASP.NET (C#) - aspnet    AutoHotkey - autohotkey    AutoIt - autoit    Bash - bash, shell    BASIC - basic    Batch - batch    BBcode - bbcode    Bison - bison    Backus–Naur form - bnf, rbnf    Brainfuck - brainfuck    BrightScript - brightscript    Bro - bro    C - c    C# - csharp, cs, dotnet    C++ - cpp    CIL - cil    CoffeeScript - coffeescript, coffee    CMake - cmake    Clojure - clojure    Crystal - crystal    Content-Security-Policy - csp    CSS Extras - css-extras    D - d    Dart - dart    Diff - diff    Django/Jinja2 - django, jinja2    DNS zone file - dns-zone-file, dns-zone    Docker - docker, dockerfile    Extended Backus–Naur form - ebnf    Eiffel - eiffel    EJS - ejs    Elixir - elixir    Elm - elm    Embedded Lua templating - etlua    ERB - erb    Erlang - erlang    F# - fsharp    Firestore security rules - firestore-security-rules    Flow - flow    Fortran - fortran    FreeMarker Template Language - ftl    G-code - gcode    GDScript - gdscript    GEDCOM - gedcom    Gherkin - gherkin    Git - git    GLSL - glsl    GameMaker Language - gml, gamemakerlanguage    Go - go    GraphQL - graphql    Groovy - groovy    Haml - haml    Handlebars - handlebars    Haskell - haskell, hs    Haxe - haxe    HCL - hcl    HTTP - http    HTTP Public-Key-Pins - hpkp    HTTP Strict-Transport-Security - hsts    IchigoJam - ichigojam    Icon - icon    Inform 7 - inform7    Ini - ini    Io - io    J - j    Java - java    JavaDoc - javadoc    JavaDoc-like - javadoclike    Java stack trace - javastacktrace    Jolie - jolie    JQ - jq    JSDoc - jsdoc    JS Extras - js-extras    JS Templates - js-templates    JSON - json    JSONP - jsonp    JSON5 - json5    Julia - julia    Keyman - keyman    Kotlin - kotlin    LaTeX - latex, tex, context    Less - less    LilyPond - lilypond, ly    Liquid - liquid    Lisp - lisp, emacs, elisp, emacs-lisp    LiveScript - livescript    LOLCODE - lolcode    Lua - lua    Makefile - makefile    Markdown - markdown, md    Markup templating - markup-templating    MATLAB - matlab    MEL - mel    Mizar - mizar    Monkey - monkey    MoonScript - moonscript, moon    N1QL - n1ql    N4JS - n4js, n4jsd    Nand To Tetris HDL - nand2tetris-hdl    NASM - nasm    nginx - nginx    Nim - nim    Nix - nix    NSIS - nsis    Objective-C - objectivec    OCaml - ocaml    OpenCL - opencl    Oz - oz    PARI/GP - parigp    Parser - parser    Pascal - pascal, objectpascal    Pascaligo - pascaligo    PC-Axis - pcaxis, px    Perl - perl    PHP - php    PHPDoc - phpdoc    PHP Extras - php-extras    PL/SQL - plsql    PowerShell - powershell    Processing - processing    Prolog - prolog    .properties - properties    Protocol Buffers - protobuf    Pug - pug    Puppet - puppet    Pure - pure    Python - python, py    Q (kdb+ database) - q    Qore - qore    R - r    React JSX - jsx    React TSX - tsx    Ren&#39;py - renpy    Reason - reason    Regex - regex    reST (reStructuredText) - rest    Rip - rip    Roboconf - roboconf    Robot Framework - robotframework, robot    Ruby - ruby, rb    Rust - rust    SAS - sas    Sass (Sass) - sass    Sass (Scss) - scss    Scala - scala    Scheme - scheme    Shell session - shell-session    Smalltalk - smalltalk    Smarty - smarty    Solidity (Ethereum) - solidity    Soy (Closure Template) - soy    SPARQL - sparql, rq    Splunk SPL - splunk-spl    SQF: Status Quo Function (Arma 3) - sqf    SQL - sql    Stylus - stylus    Swift - swift    TAP - tap    Tcl - tcl    Textile - textile    TOML - toml    Template Toolkit 2 - tt2    Turtle - turtle, trig    Twig - twig    TypeScript - typescript, ts    T4 Text Templates (C#) - t4-cs, t4    T4 Text Templates (VB) - t4-vb    T4 templating - t4-templating    Vala - vala    VB.Net - vbnet    Velocity - velocity    Verilog - verilog    VHDL - vhdl    vim - vim    Visual Basic - visual-basic, vb    WebAssembly - wasm    Wiki markup - wiki    Xeora - xeora, xeoracube    Xojo (REALbasic) - xojo    XQuery - xquery    YAML - yaml, yml    Zig - zig</code></pre><blockquote><p><em>以下内容更新于2019-12-10 08:48:18</em></p></blockquote><h1 id="RSS订阅中文章显示不完整问题">11&emsp;RSS订阅中文章显示不完整问题</h1><p>解决方法：将atom改为rss2<br>具体参照<code>node_modules/hexo-generator-feed</code>设置说明<br>我的根目录<code>_confg.yml</code>:  </p><pre class="line-numbers language-yml"><code class="language-yml">feed:   type: rss2   path: rss2.xml   limit: false   hub:   icon: /medias/logo.png  content: true  content_limit: 140   content_limit_delim: '...'   order_by: -date<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-20-cong-hugo-zhe-teng-dao-hexo-guo-cheng-ji-lu/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Install Dakota 6.11 on Ubuntu 18.04</title>
      <link>https://chengpengzhao.com/2019-11-19-install-dakota-6.11-on-ubuntu-18.04/</link>
      <guid>https://chengpengzhao.com/2019-11-19-install-dakota-6.11-on-ubuntu-18.04/</guid>
      <pubDate>Tue, 19 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;First I’d like to thank &lt;a href=&quot;https
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>First I’d like to thank <a href="https://chienfm.com/dakota/Compile-Dakota-for-Ubuntu-16.04/" target="_blank" rel="noopener">Chien Nguyen</a>  for his blog, it’s very helpful for a noob to linux like me.</p><p>Dakota released the verison 6.11 on Fri 11/15/2019, and I’ll share you how I install it on Ubuntu18.04 step by step.</p><h1 id="What-is-Dakota">1&emsp;What is Dakota</h1><p>It’s a powerful toolkit which include:</p><ul><li>optimization with gradient and nongradient-based methods;</li><li>uncertainty quantification with sampling, reliability, stochastic expansion, and epistemic methods;</li><li>parameter estimation using nonlinear least squares (deterministic) or Bayesian inference (stochastic); and</li><li>sensitivity/variance analysis with design of experiments and parameter study methods.</li></ul><h1 id="Before-installation">2&emsp;Before installation</h1><h2 id="Install-some-nessesary-packages">2.1&emsp;Install some nessesary packages</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> gcc g++ gfortran cmake cmake-curses-gui libboost-dev \libboost-all-dev libblas-dev liblapack-dev libopenmpi-dev openmpi-bin \openmpi-doc xorg-dev libmotif-dev<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>You can check the necessary packages from this <a href="https://dakota.sandia.gov/content/install-required-tools-and-libraries" target="_blank" rel="noopener">website</a>. I also installed the HDF5 here and the required version of HDF5 for Dakota 6.11 is 1.10.5.</p><h2 id="Download-the-GUI-and-source-code-from-official-webiste">2.2&emsp;Download the GUI and source code from official webiste.</h2><p> And extract files to appropriate place.</p><h1 id="Build">3&emsp;Build</h1><p>I extracted the packages in <code>$HOME/DAKOTA</code> and made two directories which will be used for build and install Dakota.</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> <span class="token operator">&amp;&amp;</span> <span class="token function">mkdir</span> DAKOTA<span class="token function">cd</span> DAKOTA<span class="token function">mkdir</span> dakota_build <span class="token operator">&amp;&amp;</span> <span class="token function">mkdir</span> dakota_installation<span class="token function">export</span> DAK_BUILD<span class="token operator">=</span><span class="token variable">$HOME</span>/DAKOTA/dakota_build<span class="token function">export</span> DAK_INSTALL<span class="token operator">=</span><span class="token variable">$HOME</span>/DAKOTA/dakota_installation<span class="token function">export</span> DAK_SRC<span class="token operator">=</span><span class="token variable">$HOME</span>/DAKOTA/dakota-6.11.0-release-public.src-UI<span class="token function">cd</span> <span class="token variable">$DAK_BUILD</span><span class="token function">cp</span> <span class="token variable">$DAK_SRC</span>/cmake/BuildDakotaTemplate.cmake <span class="token variable">$DAK_SRC</span>/cmake/BuildDakotaCustom.cmake<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>Then, you can begin to build the source code with several options. You may check this <a href="https://dakota.sandia.gov/content/detailed-cmake-options" target="_blank" rel="noopener">website</a> for more informations.</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> cmake <span class="token keyword">.</span> <span class="token variable">$DAK_SRC</span>/cmake/BuildDakotaCustom.cmake <span class="token variable">$DAK_SRC</span> -DCMAKE_INSTALL_PREFIX<span class="token operator">=</span><span class="token variable">$DAK_INSTALL</span> \ -DDAKOTA_HAVE_MPI:BOOL<span class="token operator">=</span>TRUE \ -DDAKOTA_HAVE_HDF5:BOOL<span class="token operator">=</span>TRUE<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>Run make and install:</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">make</span> -j4<span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span> <span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>Just wait for a few minutes and at last add the environment variables to <code>.bashrc</code> :</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> gedit ~/.bashrc<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>Add the following lines at the end of <em>bashrc</em>  and save</p><p><code>export PATH=”$PATH:export PATH=&quot;$PATH:$HOME/DAKOTA/dakota_installation/bin&quot;</code></p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">source</span> ~/.bashrc<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>Finally, you may need this command to verify the file permissions:</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">chmod</span> -R 777 *<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h1 id="Test">4&emsp;Test</h1><p>Now you can just open a terminal and input <code>dakota -v</code> and if everything goes well you will see:</p><pre class="line-numbers language-bash"><code class="language-bash">Dakota version 6.11 released Nov 15 2019.Repository revision c3efb375 <span class="token punctuation">(</span>2019-11-07<span class="token punctuation">)</span> built XXX XX XXXX XX:XX:XX<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>Congratulations! Let’s enjoy dakota now~</p><h1 id="GUI">5&emsp;GUI</h1><p>You guys may meet some problems when trying to open the dakota GUI, because the dakota GUI requires JAVA 8. <a href="https://www.oracle.com/technetwork/es/java/javase/downloads/jdk8-downloads-2133151.html?printOnly=1" target="_blank" rel="noopener">jdk-8u231-linux-x64.tar.gz</a> should be a good choice for you.</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/Dakota%20GUI%20_001.webp" alt></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-19-install-dakota-6.11-on-ubuntu-18.04/#disqus_thread</comments>
    </item>
    
    <item>
      <title>入坑Linux(3)——常用软件安装及配置</title>
      <link>https://chengpengzhao.com/2019-11-15-ru-keng-linux-3-chang-yong-ruan-jian-an-zhuang-ji-pei-zhi/</link>
      <guid>https://chengpengzhao.com/2019-11-15-ru-keng-linux-3-chang-yong-ruan-jian-an-zhuang-ji-pei-zhi/</guid>
      <pubDate>Fri, 15 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;OpenFOAM相关&quot;&gt;1&amp;emsp;OpenFOAM相关&lt;/h1
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="OpenFOAM相关">1&emsp;OpenFOAM相关</h1><p>用Linux的原因就是学习OpenFOAM，所以当然要摆在第一位！正如<a href="/2019/11/linux1">前面</a>所说，我用的自定义镜像自带了使用OpenFOAM需要的一些工具，不用额外安装。不过后面我又下载了多个OpenFOAM版本，与其相关的内容我会单独拿出来。</p><h1 id="显卡驱动！！">2&emsp;显卡驱动！！</h1><p>很有可能装好双系统后出现无法显示Ubuntu桌面的情况，大概率是显卡驱动没装好。这时候需要按Ctrl+Alt+F1，进入命令行界面，输入账号密码，进行显卡驱动的安装<br>还有一个坑就是在安装linux时一定要在开机界面<strong>禁用N卡</strong>不然极大概率开不了机。</p><h1 id="Terminator终端">3&emsp;Terminator终端</h1><p>既然是Linux，终端必须要好看</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:gnome-terminator<span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> terminator<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>安装完成后进行配置：<code>sudo vim ~/.config/terminator/config #之后粘贴下面一段</code></p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token punctuation">[</span>global_config<span class="token punctuation">]</span>  handle_size <span class="token operator">=</span> 1  inactive_color_offset <span class="token operator">=</span> 1.0  title_font <span class="token operator">=</span> mry_KacstQurn Bold 11  title_hide_sizetext <span class="token operator">=</span> True<span class="token punctuation">[</span>keybindings<span class="token punctuation">]</span>  broadcast_all <span class="token operator">=</span> None  broadcast_group <span class="token operator">=</span> None  go_down <span class="token operator">=</span> <span class="token operator">&lt;</span>Alt<span class="token operator">></span>j  go_left <span class="token operator">=</span> <span class="token operator">&lt;</span>Alt<span class="token operator">></span>h  go_right <span class="token operator">=</span> <span class="token operator">&lt;</span>Alt<span class="token operator">></span>l  go_up <span class="token operator">=</span> <span class="token operator">&lt;</span>Alt<span class="token operator">></span>k  layout_launcher <span class="token operator">=</span> None<span class="token punctuation">[</span>layouts<span class="token punctuation">]</span>  <span class="token punctuation">[</span><span class="token punctuation">[</span>default<span class="token punctuation">]</span><span class="token punctuation">]</span>    <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token punctuation">[</span>child1<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span>      parent <span class="token operator">=</span> window0      profile <span class="token operator">=</span> default      <span class="token function">type</span> <span class="token operator">=</span> Terminal    <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token punctuation">[</span>window0<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">]</span>      parent <span class="token operator">=</span> <span class="token string">""</span>      <span class="token function">type</span> <span class="token operator">=</span> Window<span class="token punctuation">[</span>plugins<span class="token punctuation">]</span><span class="token punctuation">[</span>profiles<span class="token punctuation">]</span>  <span class="token punctuation">[</span><span class="token punctuation">[</span>default<span class="token punctuation">]</span><span class="token punctuation">]</span>    background_darkness <span class="token operator">=</span> 0.76    background_type <span class="token operator">=</span> transparent    cursor_color <span class="token operator">=</span> <span class="token string">"#3036ec"</span>    custom_command <span class="token operator">=</span> tmux    font <span class="token operator">=</span> Ubuntu Mono 13    foreground_color <span class="token operator">=</span> <span class="token string">"#ffffff"</span>    login_shell <span class="token operator">=</span> True    show_titlebar <span class="token operator">=</span> False    use_system_font <span class="token operator">=</span> False<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>再在右键菜单中添加open in terminator：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:daniel-marynicz/filemanager-actions<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> filemanager-actions-nautilus-extension<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p><code>fma-config-tool</code>  启动</p><p>1)新建action命名：Open in Terminator在Action标签页勾选”Display item in location context menu”<br>在Command标签页填写<code>Path:/usr/bin/terminator，parameters:--working-directory=%d/%b</code></p><p>2)配置Preferences勾选”Create a root ‘FileManager-Action’ menu”</p><h1 id="Foxit-Reader">4&emsp;Foxit Reader</h1><p>可以使用系统自带PDF阅读器，不过Foxit功能更多，但速度没有自带的快。</p><h1 id="Typora">5&emsp;Typora</h1><p>Markdown编辑器，十分好用，强烈推荐，在我使用Vim之前一直用的这款软件。<br>安装过程很简单我就不提了，这里说下如何<strong>在ubuntu中调整Typora显示宽度</strong>：</p><p>默认展示渲染结果的宽度太窄了（github主题的最大宽度是860px）</p><blockquote><p>github.css文件中某处：</p></blockquote><pre><code>#write{    max-width: 860px;    margin: 0 auto;    padding: 20px 30px 40px 30px;    padding-top: 20px;    padding-bottom: 100px;}</code></pre><p><strong>解决方法</strong>：</p><p>1.搜索安装目录下的github.css文件</p><blockquote><p>linux下： <code>${TYPORA_HOME}/resources/app/style/themes/github.css</code></p></blockquote><p>2.修改<code>#white</code>下的<code>max-width</code>为你想要的宽度， 像素值或者百分比， 建议85%。重启Typora即可。</p><h2 id="我用的Typora主题">5.1&emsp;我用的Typora主题</h2><p>基于自带的Github主题进行了一点修改，下载下来放在相关文件夹里就能用:<a href="https://github.com/chengpengzhao/theme_github_mzz" target="_blank" rel="noopener">theme_github_mzz</a></p><h1 id="copyQ">6&emsp;copyQ</h1><p>类似Windows下的Ditto，剪切板管理工具。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:hluk/copyq<span class="token punctuation">;</span><span class="token function">sudo</span> apt update<span class="token punctuation">;</span><span class="token function">sudo</span> apt <span class="token function">install</span> copyq<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h1 id="GoldenDict">7&emsp;GoldenDict</h1><p>Linux下很好用的翻译软件，需要一些自定义配置。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> goldendict<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>下面分享下我的设置，连字典在内打包成zip了，文件可能有点大(<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiGKCerIXlf89v4JN?e=iiuB9x" target="_blank" rel="noopener">Download</a>)<br>dictionary文件夹放在主目录就行，配置文件夹<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiGMuQ5h9Fb_KwZEN?e=fkhkOa" target="_blank" rel="noopener">.goldendict</a>也放在主目录。<br>注意同时要安装translate-shell</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">git</span> clone https://github.com/soimort/translate-shell<span class="token function">cd</span> translate-shell/<span class="token function">make</span><span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>下面是我的使用效果：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E9%80%89%E5%8C%BA_001.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E9%80%89%E5%8C%BA_002.webp" alt></p><h1 id="indicator-sysmonitor">8&emsp;indicator-sysmonitor</h1><p>可以显示网速、系统内存、CPU使用情况。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:fossfreedom/indicator-sysmonitor  <span class="token punctuation">;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> update  <span class="token punctuation">;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> indicator-sysmonitor <span class="token punctuation">;</span>indicator-sysmonitor <span class="token operator">&amp;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><p>我的设置为<code>{net} C: {cpu} M: {mem}</code></p><h1 id="VLC播放器">9&emsp;VLC播放器</h1><p>Linux系统下还算好用的播放器</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:videolan/master-daily<span class="token punctuation">;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token punctuation">;</span><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> vlc<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h1 id="Git">10&emsp;Git</h1><p>Github用户必装，没啥说的</p><h1 id="Tree">11&emsp;Tree</h1><p>可以显示文件夹的多层结构，很直观。<code>sudo apt-get install tree</code></p><h1 id="snap">12&emsp;snap</h1><p>用来安装一些软件。我的系统镜像是日本的DEXCS做的，其中的snap服务有点问题，重装下：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> apt autoremove --purge snapd<span class="token function">sudo</span> apt <span class="token function">install</span> snapd<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><h1 id="Onenote">13&emsp;Onenote</h1><p>记笔记的软件还是得要的，虽然不如Windows下的运行速度快，但勉强能用。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> snap <span class="token function">install</span> p3x-onenote<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h1 id="unar">14&emsp;unar</h1><p> 防止解压zip出现乱码或是rar解压错误<br> 有时候如果直接右键解压会出现中文乱码的情况，正确操作应该是打开终端，敲入：<br> <code>unar xxxx</code><br>安装很简单</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> <span class="token function">unrar</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h1 id="网易云音乐">15&emsp;网易云音乐</h1><p>敲代码时怎么能少了音乐</p><h1 id="Matlab">16&emsp;Matlab</h1><p>因为不想切回Windows所以在Ubuntu下也安装了一个，具体安装过程比较复杂，前面一篇blog提到了一些问题的解决方法。</p><h1 id="mathpix-snipping-tool">17&emsp;mathpix-snipping-tool</h1><p>将图片中的公式转为LaTex格式，写论文的神器!!!</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> snap <span class="token function">install</span> mathpix-snipping-tool<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h1 id="Zotero">18&emsp;Zotero</h1><p>文献管理神器，之前一直用Endnote，直到一位大佬给我安利了这款开源软件，相比之下Endnote简直太难用了。<br>安装不难，为了方便使用我在桌面建了个快捷方式，参考一下：</p><pre><code>[Desktop Entry]Name=ZoteroExec=bash -c &quot;/home/zcp/Downloads/Zotero_linux-x86_64/zotero -url %U&quot;Icon=/home/zcp/Downloads/Zotero_linux-x86_64/chrome/icons/default/default256.jpgType=ApplicationTerminal=falseCategories=Office;MimeType=text/plain</code></pre><p>我用的插件有<code>ZotFile</code>、<code>Markdown Here</code>、<code>Scihub</code>。使用坚果云同步</p><h1 id="Vim">19&emsp;Vim</h1><p>神器，萌新劝退，我还在学习中，为了用Vim专门练习了一周的盲打。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> vim<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>为了提高效率，配置文件非常重要，在网上可以找到一对大佬的配置文件，装着许多自己听都没听过的插件…输入<code>vim ~/.vimrc</code>即可进行配置！<br>我把自己的配置文件也传到了网盘里(<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiGTxtVXNlnNpW7DS?e=IJUAAV" target="_blank" rel="noopener">Download</a>)<br>这是我Vim配置后的外观（在Terminator终端中）：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/vimr001.webp" alt><br>这是OpenFOAM文件的自动补全与高亮：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/OpenFOAM-zcp-dev-run-elbow-system_002.webp" alt></p><h1 id="picgo">20&emsp;picgo</h1><p>写blog上传图片到图库常用软件，Windows下也有。</p><h1 id="Firefox浏览器">21&emsp;Firefox浏览器</h1><p>差点忘了还有浏览器，用自带的就行，注意系统自带的是国际版的，创建帐号后想在别的系统上同步时记得也要下载国际版的Firefox，国内版和国际版不互通的。</p><h2 id="Firefox常用插件及扩展">21.1&emsp;Firefox常用插件及扩展</h2><ul><li>百度网盘万能助手： Linux版百度网盘官方链接我一直打不开，无可奈何只能用这个下载。</li><li>Default Bookmark Folder: 解决Firefox中保存书签默认在<em>其他书签</em> 的问题。</li><li>Dualsub: 油管看视频时可显示双语字幕，很棒。</li><li>Zotero Connector: 导文献用。</li><li>Tampermonkey: 油猴脚本，很强大。</li></ul><h1 id="Sylpheed">22&emsp;Sylpheed</h1><p>官网：<a href="https://sylpheed.sraoss.jp/ja/" target="_blank" rel="noopener">Sylpheed</a><br>好像也是日本人做的软件，用于邮件管理，我在用了网页版gmail、Windows上的foxmail、Outlook客户端、Linux上的Evolution、Thunderbird之后，真心觉得Sylpheed是最适合我的：跨平台、绑定帐号容易、功能强大、支持插件，简直太棒。我用的是3.7版的。</p><p>安装过程：</p><p>首先从官网下载SourceCode，解压后在相应文件夹内打开终端；或者直接Ctrl+Alt+T打开终端输入以下命令：</p><pre class="line-numbers language-bash"><code class="language-bash">svn checkout svn://sylpheed.sraoss.jp/sylpheed/trunk sylpheed<span class="token function">cd</span> sylpheed<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>先检查依赖软件是否完整，缺什么装什么：</p><pre class="line-numbers language-bash"><code class="language-bash">./configure<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>我运行完后发现缺少gtk+2.0，故<code>sudo apt-get install gtk2.0</code></p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">make</span><span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>本体安装完成，之后还可以装几个插件，我装了htmlview(<strong>Sylpheed的理念是不推荐在电子邮件中使用html，所以用它写邮件时不带html，但能通过这个插件正常显示收到的带html的邮件</strong>)</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> plugin<span class="token function">git</span> clone https://github.com/chengpengzhao/sylpheed-plugin-factory.git<span class="token function">cd</span> sylpheed-plugin-factory./autogen.sh./configure<span class="token function">make</span><span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span><span class="token function">cd</span> -<span class="token comment" spellcheck="true">#接下来正式装htmlview</span><span class="token function">git</span> clone https://github.com/chengpengzhao/sylpheed-htmlview.git<span class="token function">cd</span> sylpheed-htmlview<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> libwebkitgtk-dev./autogen.sh./configure --enable-webkitgtk<span class="token function">make</span><span class="token function">sudo</span> <span class="token function">make</span> <span class="token function">install</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>使用界面展示：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/Sylpheed%203.7.0_001.webp" alt></p><h1 id="GIMP">23&emsp;GIMP</h1><p>Linux系统下可以代替PS的图像处理软件，功能强大、运行速度快、开源。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:otto-kesselgulasch/gimp<span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> -y gimp<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h1 id="PyCharm">24&emsp;PyCharm</h1><p>因为最近要用python做一个优化程序的interface，vim上不方便debug所以还是安装了大名鼎鼎的PyCharm，直接去官网下载然后解压出来就行了。<br>我下载的是pycharm-community-2019.2.5，解压出来后</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">cd</span> bin./pycharm.sh<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>就可以运行了，不过为了以后运行方便我还是在桌面建了一个快捷方式。</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> gedit /usr/share/applications/pycharm.desktop<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>复制粘贴保存关闭一条龙：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token punctuation">[</span>Desktop Entry<span class="token punctuation">]</span>Type<span class="token operator">=</span>ApplicationName<span class="token operator">=</span>PycharmGenericName<span class="token operator">=</span>Pycharm3Comment<span class="token operator">=</span>Pycharm3:The Python IDEExec<span class="token operator">=</span><span class="token string">"/home/zcp/Downloads/pycharm-community-2019.2.5/bin/pycharm.sh"</span> %fIcon<span class="token operator">=</span>/home/zcp/Downloads/pycharm-community-2019.2.5/bin/pycharm.jpgTerminal<span class="token operator">=</span>pycharmCategories<span class="token operator">=</span>Pycharm<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>根据安装位置不同稍作修改即可，接着添加权限再拷到桌面就行了</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">chmod</span> +x /usr/share/applications/pycharm.desktop <span class="token function">cp</span> /usr/share/applications/pycharm.desktop /home/zcp/Desktop/<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>双击选择trust，搞定。</p><blockquote><p><em>以下内容更新于2019-11-30 20:18:59</em></p></blockquote><h1 id="Peek-、screenkey">25&emsp;Peek 、screenkey</h1><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> add-apt-repository ppa:peek-developers/stable<span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> peek<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><p>Peek是用来录制gif的一款软件，<a href="https://gitlab.com/wavexx/screenkey" target="_blank" rel="noopener" title="screenkey">screenkey</a>使用python写的能录制屏幕按键的工具。</p><blockquote><p><em>以下内容更新于2019-12-08 17:34:49</em></p></blockquote><p>卸载了Ubuntu上的onenote和邮件管理软件，原因是运行有点卡，影响效率。这两者转到平板上使用，通过电脑编辑文件再快速传到平板。</p><blockquote><p><em>以下内容更新于2019-12-10 08:35:30</em>  </p></blockquote><p>Onenote和Sylpheed也卸载了，原因也是运行速度慢，不适合在我笔记本Ubuntu上用；PDF阅读器也改成了系统自带的版本，因为阅读PDF做笔记转移到了平板上，电脑打开PDF只要求快就够了。<br><br><br><br></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-15-ru-keng-linux-3-chang-yong-ruan-jian-an-zhuang-ji-pei-zhi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>入坑Linux(2)——常用命令及快捷键</title>
      <link>https://chengpengzhao.com/2019-11-13-ru-keng-linux-2-chang-yong-ming-ling-ji-kuai-jie-jian/</link>
      <guid>https://chengpengzhao.com/2019-11-13-ru-keng-linux-2-chang-yong-ming-ling-ji-kuai-jie-jian/</guid>
      <pubDate>Wed, 13 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;常用快捷键&quot;&gt;1&amp;emsp;常用快捷键&lt;/h1&gt;&lt;p&gt;Linux和
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="常用快捷键">1&emsp;常用快捷键</h1><p>Linux和Windows最大的一个不同就是终端的使用，Win虽然有cmd但我们平时基本生活学习用的较少，大多靠鼠标点击完成操作；而Linux很多操作都是通过终端输入命令来完成，包括软件的安装、文本的编辑等，如何在尽量不用鼠标的情况下保持高效率，则是我们在用Linux时经常要思考的问题。</p><table><thead><tr><th align="center">快捷键</th><th align="center">描述</th></tr></thead><tbody><tr><td align="center"><strong>Ctrl+Alt+T</strong></td><td align="center">启动终端</td></tr><tr><td align="center">F11</td><td align="center">全屏切换</td></tr><tr><td align="center">Ctrl+Shift+C</td><td align="center">复制</td></tr><tr><td align="center"><strong>Ctrl+Shift+V</strong></td><td align="center">粘贴(鼠标中键)</td></tr><tr><td align="center"><strong>Ctrl+Shift+W</strong></td><td align="center">关闭标签页</td></tr><tr><td align="center"><strong>Ctrl+Shift+Q</strong></td><td align="center">关闭所有终端窗口</td></tr><tr><td align="center">Ctrl+Shift++</td><td align="center">放大窗口（包括窗口内的字体）</td></tr><tr><td align="center">Ctrl+-</td><td align="center">缩写窗口（包括窗口内的字体）</td></tr><tr><td align="center">Ctrl+0</td><td align="center">普通大小（阿拉伯数字 0）</td></tr><tr><td align="center">Ctrl+D</td><td align="center">在空白处执行将结束当前会话（同exit 命令功能）</td></tr><tr><td align="center"><strong>Ctrl+A</strong></td><td align="center">光标移动到行的开头（ahead）</td></tr><tr><td align="center"><strong>Ctrl+E</strong></td><td align="center">光标移动到行的结尾</td></tr><tr><td align="center">Ctrl+Left-Arrow</td><td align="center">光标移动到上一个单词的词首</td></tr><tr><td align="center">Ctrl+Right-Arrow</td><td align="center">光标移动到下一个单词的词尾</td></tr><tr><td align="center"><strong>Ctrl+U</strong></td><td align="center">剪切从行的开头到光标前一个位置的所有字符</td></tr><tr><td align="center"><strong>Ctrl+W</strong></td><td align="center">删除光标位置的前一个单词（同alt+backspace 组合键功能）</td></tr><tr><td align="center"><strong>Ctrl+Y</strong></td><td align="center">粘贴最后一次被删除的单词</td></tr><tr><td align="center"><strong>Ctrl+L</strong></td><td align="center">清除当前屏幕内容（同 clear命令功能）</td></tr><tr><td align="center">Ctrl+S</td><td align="center">暂停屏幕输出</td></tr><tr><td align="center">Ctrl+Q</td><td align="center">继续屏幕输出</td></tr><tr><td align="center"><strong>Ctrl+C</strong></td><td align="center">取消（break）当前行输入</td></tr><tr><td align="center"><strong>Ctrl+R</strong></td><td align="center">搜索之前用过的命令</td></tr></tbody></table><br>加粗的是我觉得平常用的比较多的快捷键，当然还有很多快捷键我没有全部列出来。<br><br><h1 id="常用shell命令">2&emsp;常用shell命令</h1><ul><li><code>ls</code> 列出当前目录下的所有文件（不显示隐藏文件）若要显示隐藏文件: <code>ls -a</code> </li><li><code>cd</code> 进入某个目录</li><li>几种符号的定义：<code>..</code> 上级文件夹; <code>.</code> 当前文件夹;  <code>~</code> 当前用户文件夹(<code>pwd</code>= <code>echo ~</code>);    <code>\</code>  另起一行</li><li><code>cd -</code>返回进入此目录之前所在的目录</li><li><code>mkdir dirname</code> 新建目录</li><li><code>rmdir dirname</code> 删除空目录</li><li><code>touch file</code>创建一个空的名字为file的空文件</li><li><code>rm filename</code> 删除文件; <code>rm -rf dirname</code> 删除非空目录及其包含的所有文件</li><li><code>cp file file1</code> 复制file文件为file1</li><li><code>mv file1 file2</code>将文件1<strong>重命名</strong>为文件2</li><li><code>mv file1 dir1</code> 将文件1<strong>移动</strong>到目录1中</li><li><code>sudo dpkg -i  file.deb</code>  安装下载的deb软件包</li><li><code>apt-get</code> 程序安装与卸载命令的标志，需要管理员权限</li><li><code>install</code> 安装指定程序，举例：<code>sudo apt-get install vim</code> </li><li><code>remove</code> 卸载指定的程序，一般最好加上“–purge”执行清除式卸载；并在程序名称后添加*号。举例：<code>sudo apt-get remove --purge nvidia*</code>  卸载 nvidia 的驱动及其配置文件</li><li><code>update</code> 更新本地软件源文件，需要管理员权限，举例：<code>sudo apt-get update</code> </li><li><code>sudo apt-get upgrade</code>自动更新软件</li><li><code>sudo apt autoremove</code>卸载一些不用了的软件</li><li>温馨提示: 养成习惯，安裝任何套件以前先:<pre><code>sudo apt-get update &amp;&amp; sudo apt-get upgrade</code></pre></li><li><code>!xx</code>  ：Linux 命令行下执行该命令，会执行最近一条包含有 xx关键字的历史命令</li><li>结束某程序运行（强制):<br><code>ps -A| grep xxx</code>记住列出的ID号，再执行：<code>kill ID</code></li><li>软件的依赖关系有错误时：<code>sudo apt-get upgrade -f</code></li><li><code>sudo nautilus .</code> :以管理员权限打开当前目录，当无法在窗口中删除或者粘贴文件时可以使用</li></ul><h1 id="使用过程中碰到的一些命令">3&emsp;使用过程中碰到的一些命令</h1><h2 id="gt-dev-null-2-gt-amp-1">3.1&emsp;&gt; /dev/null 2&gt;&amp;1</h2><p>命令后附加 <code>&gt;/dev/null 2&gt;&amp;1</code> 常用来避免shell命令或者程序等运行中有内容输出。</p><p>0:表示键盘输入(stdin)   1:表示标准输出(stdout),系统默认是1  2:表示错误输出(stderr)</p><p>shell命令：<code>command &gt;/dev/null 2&gt;&amp;1 &amp;</code>  等同于  <code>command 1&gt;/dev/null 2&gt;&amp;1 &amp;</code></p><p>1)command:表示shell命令或一个可执行的程序</p><p>2)&gt;:表示重定向到</p><p>3)/dev/null:表示Linux的空设备文件</p><p>4)2:表示标准错误输出</p><p>5)&amp;1:&amp;表示等同于的意思,2&gt;&amp;1,表示2的输出重定向等同于1的重定向</p><p>6)&amp;:表示后台执行这条指令</p><p>1&gt;/dev/null:表示标准输出重定向到空设备文件,即不输出任何信息到终端。</p><p>2&gt;&amp;1:表示错误输出重定向等同于标准输出,因为之前标准输出已经重定向到了空设备文件,所以错误输出也重定向到空设备文件。</p><p>上述例子中的shell命令的意思就是在后台执行这个程序,并将错误输出2重定向到标准输出1,然后将标准输出1全部放到/dev/null文件,也就是清空.</p><h2 id="挂载映像文件">3.2&emsp;挂载映像文件</h2><p>在安装Matlab过程中遇到的</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">mount</span> -t auto -o loop R2016b_glnxa64_dvd1.iso /Matlab2016b<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="给软件创建快捷方式">3.3&emsp;给软件创建快捷方式</h2><p>仍然以Matlab为例</p><pre><code>sudo gedit /usr/share/applications/matlab.desktop#快捷方式都在这个文件夹里</code></pre><p>把下列复制粘贴进去，修改相关路径即可</p><pre><code>[Desktop Entry]Type=ApplicationName=MatlabGenericName=MATLABComment=Matlab:The Language of Technical ComputingExec=sh /home/ubuntu/MATLAB/R2016b/bin/matlab -desktopIcon=/home/ubuntu/MATLAB/R2016b/toolbox/nnet/nnresource/icons/matlab.jpgStartupNotify=trueTerminal=falseCategories=Development;Matlab;</code></pre><p>配置文件中Name、Exec与Icon要指定好。<br><br><strong>顺便把ubuntu matlab界面字太小的解决方案放下面：</strong><br>  MathWorks suggested the following procedure, which works well for me (R2017b). Quoting from their email:<br>Tuning a high-DPI Linux system requires two steps</p><pre><code>Setting the MATLAB scale factorCalibrating the system&#39;s DPI</code></pre><p>The MATLAB scale factor affects MATLAB desktop and the size/position of windows. The system DPI determines the scale and font size of axes and labels. To set the MATLAB scale factor, please use the following MATLAB commands:</p><pre><code>&gt;&gt; s = settings;s.matlab.desktop.DisplayScaleFactor&gt;&gt; s.matlab.desktop.DisplayScaleFactor.PersonalValue = 1.5</code></pre><p>To calibrate the system DPI to match the scale facto, please use the following terminal commands :</p><pre><code>% xdpyinfo | grep resolution  resolution:    96x96 dots per inch% xrandr --dpi 144</code></pre><p>The DPI value chosen should be the resolution found with xdpyinfo multiplied by the MATLAB scale factor that was set. In the example, 96 × 1.5 = 144.<br>MATLAB must be restarted after Step 2.<br><br><br><br></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-13-ru-keng-linux-2-chang-yong-ming-ling-ji-kuai-jie-jian/#disqus_thread</comments>
    </item>
    
    <item>
      <title>入坑Linux(1)——双系统安装</title>
      <link>https://chengpengzhao.com/2019-11-12-ru-keng-linux-1-shuang-xi-tong-an-zhuang/</link>
      <guid>https://chengpengzhao.com/2019-11-12-ru-keng-linux-1-shuang-xi-tong-an-zhuang/</guid>
      <pubDate>Tue, 12 Nov 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;原以为自己不会接触到Linux系统，毕竟一直舒服地用着Win没什么不满。直到
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>原以为自己不会接触到Linux系统，毕竟一直舒服地用着Win没什么不满。直到接触了OpenFOAM，在Win上运行实在是不方便，于是装了个虚拟机开始研究Linux，用了一段时间之后还是感觉不太舒服，毕竟是虚拟机，加上笔记本性能也一般；为了追求流畅的体验还是决定装个双系统，于是开始了漫长的踩坑爬坑之旅…</p><h1 id="Linux系统安装">1&emsp;Linux系统安装</h1><p>以我安装Ubuntu为例，简单说下步骤；网上很多关于双系统安装的帖子，但不能完全照搬，不然会出各种各样的bug；推荐先多浏览几篇，总结之间的不同点，再针对性进行学习。</p><h2 id="安装盘准备">1.1&emsp;安装盘准备</h2><p>一般用usb或光盘制作一个启动盘，usb的话推荐工具<a href="https://rufus.ie/" target="_blank" rel="noopener">Rufus</a>。先把镜像下好，如<em>ubuntu-18.04-desktop-amd64.iso</em>,我这里装的是日本人做的一个集成了很多OpenFOAM使用工具的<strong>自定义镜像</strong>，从官网<a href="http://dexcs.gifu-nct.ac.jp/download/" target="_blank" rel="noopener">DEXCS</a>可以下载，使用说明可以参看我收集的一些<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiF8lBMfSMFrlD_9g?e=p5G2Fx" target="_blank" rel="noopener">文档</a>（日语）。注意文件系统格式、分区策略等选项不要随便选，选之前百度一下；总之一般制作启动盘这一步比较简单。</p><h2 id="空出一个磁盘来">1.2&emsp;空出一个磁盘来</h2><p>推荐使用<a href="http://www.diskgenius.cn/" target="_blank" rel="noopener">DiskGenius</a>进行系统分区，清出一块磁盘后记住一定保持<strong>未格式化</strong>的状态。</p><h2 id="Linux系统分区">1.3&emsp;Linux系统分区</h2><p>前两步完成之后就可以重启进入Bios设置从U盘启动然后开始安装Ubuntu系统了。前面的选项随便点过就行，到安装类型界面开始一定要谨慎，一般我们手动分配分区，直接选择最后一项<em>其他选项</em> 。<br>如果不知道怎么创建分区，请暂停安装过程，拿出手机百度一下直到明白了Linux的分区构成，如“/”、“/home”、“/swap”、“/boot”的含义。<br>我不喜欢太多分区所以只分了“/”和“/home”，注意千万不要选错磁盘把Win系统给删了。硬盘名称一般有sda、sdb等…<br>然后静静等待，安装完成！So easy！</p><h2 id="安装引导！！！">1.4&emsp;安装引导！！！</h2><p>如果觉得已经大功告成那真是太天真了，重启之后你会发现，直接进入了grub界面…关于如何设置引导从而开机能够进入双系统选择界面的帖子，网上更是数不胜数；我当初几乎试了个遍，最后还是以失败告终。就在我将要放弃的时候，在油管上找到了一个视频<a href="https://www.youtube.com/watch?v=S1k49TrVBCM&t=5s" target="_blank" rel="noopener">How to install refind boot manager in windows</a>,按照上面说的步骤安装了<em>refindboot</em> ，重启之后终于进入了我想要的系统选择界面！！！谢天谢地!!!<br>相关文件我也传到OneDrive上了。(<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiGC1OwPafZ_XQc4I?e=1jdKIA" target="_blank" rel="noopener">Download</a>)<br><br><br><br><br></p><h1 id="一些基本设置">2&emsp;一些基本设置</h1><p>至此，便可以暂时抛下Windows，在Ubuntu的世界里遨游了。刚开始可以进入设置选项翻一翻，这里主要提两点：</p><h2 id="双系统时间不一致">2.1&emsp;双系统时间不一致</h2><p>Ubuntu默认时间是把BIOS时间当成GMT+0时间，Windows则认为BIOS时间就是你的本地时间。Ubuntu18.04的解决方案是在终端输入：</p><pre class="line-numbers language-sh"><code class="language-sh">timedatectl set-local-rte 1 --adjust-system-clock<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><h2 id="输入法的安装">2.2&emsp;输入法的安装</h2><p>Ubuntu1804默认的输入法系统是ibus，网上推荐用搜狗输入法,但它基于fcitx而且安装后可能会出现系统黑屏或者无限循环登录等bug（亲身经历），所以对于像我这样的萌新还是老老实实用ibus吧。<br><br>但ibus的几个中文输入法都有点bug，（用一段时间就卡住之类的），直到我找到了<strong>Sunpinyin</strong>这款输入法。<br><br>安装Sunpinyin:</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> update<span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> ibus-sunpinyin<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>若没有ibus，则先安装ibus框架：</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> <span class="token function">apt-get</span> <span class="token function">install</span> ibus ibus-clutter ibus-gtk ibus-gtk3 ibus-qt4<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>之后在终端中输入命令： <code>ibus-setup</code>将 “在应用程序窗口中启用内嵌编辑模式” 选项取消，输入<code>ibus restart</code>；<br>安装好Sunpinyin后需要改一下自动翻页的设置，如果打不开设置窗口则可能是缺少组件(<a href="https://1drv.ms/u/s!Am1bWNpX3V8CiGFcROX68nM4GXRq?e=aX9DK9" target="_blank" rel="noopener">Download</a>)。通过</p><pre class="line-numbers language-bash"><code class="language-bash"><span class="token function">sudo</span> gdebi python-ibus_1.5.5-1ubuntu3.2_all.deb<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>安装即可。</p><h1 id="Ubuntu系统备份">3&emsp;Ubuntu系统备份</h1><p>说是可以完全复制到另一台电脑上，我还没有试过，等有机会再自己的台式机上尝试一下再来修改，先把步骤放在这。</p><h2 id="1-备份前先清理一下缓存">3.1&emsp;1. 备份前先清理一下缓存</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true"># 清理旧版本的软件缓存</span><span class="token function">sudo</span> <span class="token function">apt-get</span> autoclean <span class="token punctuation">;</span> <span class="token comment" spellcheck="true"># 清理所有软件缓存</span><span class="token function">sudo</span> <span class="token function">apt-get</span> clean <span class="token punctuation">;</span><span class="token comment" spellcheck="true"># 删除系统不再使用的孤立软件</span><span class="token function">sudo</span> <span class="token function">apt-get</span> autoremove<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h2 id="2-tar命令备份">3.2&emsp;2. tar命令备份</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#备份前先切换到root用户，避免权限问题</span><span class="token function">sudo</span> <span class="token function">su</span> <span class="token punctuation">;</span><span class="token comment" spellcheck="true">#继续在终端中输入以下指令，进入系统根目录：</span><span class="token function">cd</span> / <span class="token punctuation">;</span><span class="token comment" spellcheck="true">#开始备份系统，在终端中输入：</span><span class="token function">tar</span> cvpzf backup.tgz --exclude<span class="token operator">=</span>/proc --exclude<span class="token operator">=</span>/lost+found --exclude<span class="token operator">=</span>/backup.tgz --exclude<span class="token operator">=</span>/mnt --exclude<span class="token operator">=</span>/sys --exclude<span class="token operator">=</span>/media / --warning<span class="token operator">=</span>no-file-change<span class="token comment" spellcheck="true">#耐心等待......</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>简单看一下这个命令：</p><ul><li>‘tar’ 是用来备份的程序</li><li>c - 新建一个备份文档</li><li>v - 详细模式， tar程序将在屏幕上实时输出所有信息。</li><li>p - 保存许可，并应用到所有文件。</li><li>z - 采用‘gzip’压缩备份文件，以减小备份文件体积。</li><li>f - 说明备份文件存放的路径， Ubuntu.tgz 是本例子中备份文件名。</li><li>“/”是我们要备份的目录，在这里是整个文件系统。</li><li>在档案文件名“backup.tgz”和要备份的目录名“/”之间给出了备份时必须排除在外的目录。有些目录是无用的，例如“/proc”、“/lost+ found”、“/sys”。当然，“backup.tgz”这个档案文件本身必须排除在外，否则你可能会得到一些超出常理的结果。如果不把“/mnt”排除在外，那么挂载在“/mnt”上的其它分区也会被备份。另外需要确认一下“/media”上没有挂载任何东西(例如光盘、移动硬盘)，如果有挂载东西， 必须把“/media”也排除在外。</li><li>备份完成后，在文件系统的根目录将生成一个名为“backup.tgz”的文件，它的尺寸有可能非常大。现在你可以把它烧录到DVD上或者放到你认为安全的地方去。<br>  在备份命令结束时你可能会看到这样一个提示：’tar: Error exit delayed from previous errors’，多数情况下你可以忽略它。</li></ul><h2 id="3-恢复系统">3.3&emsp;3. 恢复系统</h2><pre class="line-numbers language-bash"><code class="language-bash"><span class="token comment" spellcheck="true">#备份前先切换到root用户，避免权限问题</span><span class="token function">sudo</span> <span class="token function">su</span><span class="token punctuation">;</span><span class="token comment" spellcheck="true">#再切换到/（根目录）</span><span class="token function">cd</span> / <span class="token punctuation">;</span><span class="token comment" spellcheck="true">#删除整个文件系统</span><span class="token function">rm</span> -fr /* <span class="token punctuation">;</span><span class="token comment" spellcheck="true">#解压缩</span><span class="token function">tar</span> xvpfz backup.tgz <span class="token punctuation">;</span><span class="token comment" spellcheck="true">#重新创建那些在备份时被排除在外的目录；</span><span class="token function">sudo</span> <span class="token function">mkdir</span> proc lost+found mnt sys media<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p><br><br><br></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-11-12-ru-keng-linux-1-shuang-xi-tong-an-zhuang/#disqus_thread</comments>
    </item>
    
    <item>
      <title>想起来还有个Blog就随便记录下(9.26-10.25)</title>
      <link>https://chengpengzhao.com/2019-09-28-liu-xue-9.26-10.10/</link>
      <guid>https://chengpengzhao.com/2019-09-28-liu-xue-9.26-10.10/</guid>
      <pubDate>Sat, 28 Sep 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;2019-09-26-北京-东京&quot;&gt;1&amp;emsp;2019-09-
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="2019-09-26-北京-东京">1&emsp;2019-09-26　北京-东京</h1><h2 id="首都国际机场出发">1.1&emsp;首都国际机场出发</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-1.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-2.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-3.webp" alt></p><h2 id="羽田空港到着">1.2&emsp;羽田空港到着</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-4.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-5.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-6.webp" alt><br>    ようやく留学生活が始まる。半年前から色々準備していたけど、まだまだ足りないんだ。何年も日本語を独学で学んでいたが、日本人と直接コミュニケーションをすることはなかった。<br>    9.26午前0时羽田空港に着いてからずっと緊張が止まらない。これからどんな生活になるだろう、何をすればいいのか、今の僕はまだ想像できない。ターミナルの中をあてもなく歩いていた、今夜はなかなか眠れなそうだ。</p><h2 id="to-矢上キャンパス-by-地下鉄">1.3&emsp;to 矢上キャンパス by 地下鉄</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-7.webp" alt><br>    朝5時ごろになって、京急線のりばの入口も開いた。周りの人たちはターミナルのベンチで寝ている。みんなも大変だよねって思いながら、僕は空港を離れ、大学への電車に乗り込んだ。</p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-8.webp" alt><br>    大学の手続きが終わって、学生寮でチェックインして、疲れ切ってベットに横になった。ここで僕はひとりだ。誰も僕のことを知らない。孤独だがもう慣れた。<br>    留学の目的を忘れずに語学力をあげよう。ここでしか得られない知識を学ぼう。とても内気な人間だから、友達を作るのは難しいと思う。なるべく研究室の皆と話せればいいと思う。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/201909-9.webp" alt></p><h1 id="2019-09-28-みなとみらい">2&emsp;2019-09-28　みなとみらい</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-1.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-2.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-3.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-4.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-5.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-6.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-7.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-8.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-9.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-10.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-11.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-12.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-13.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-14.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-15.webp" alt></p><h1 id="2019-09-29——2019-10-05-風邪">3&emsp;2019-09-29——2019-10-05　風邪</h1><p>……風邪、休み中</p><h1 id="2019-10-06-雨">4&emsp;2019-10-06　雨</h1><p>　　今日は雨だ、日本に来てから10日で初めての雨だ。朝早起きするつもりだったが、なかなか出来なかった。日本での朝食は面倒だと思いながら、昨日買ったカップ麺を食べ始めた。中国ではほとんど皆外で朝ご飯を食べるから、色んな朝食を食べる店があって朝からとてもにぎやかだ。<br>　　一週間を経って風邪がようやく完治した、明日から研究室に行かなくちゃ。午後商店街をぶらついて、電気屋さんでドライヤーと体重計を買いたかったが、結局高いのでアマゾンでもっと安いのを注文した。<br>　　今夜は勉強しよう、明日のために。不安だから勉強に集中すべきだ。</p><h1 id="2019-10-07-充実">5&emsp;2019-10-07　充実　</h1><p>　　今は初めて食堂で昼ご飯を食べた。やっぱり外の店より安いね、牛丼と豆腐とサラダと味噌汁全部で800円なんて思わなかった。昨日ラーメン屋で900円もかかったのに、量がまだ足りないように感じた。<br>　　朝十時から午後四時まで研究室にいたけど、皆との会話がほとんどない。しょうがないことだと思う、一週間前に一度だけ会った間柄だから。これからみんなと仲良くしようと思いながら、明日また頑張ろうと思う。<br>　　自分の日本語能力が限られてる以上、自分に興味を持ってない方と、友達になるのは難しいと思う。だからまず自分からそうじゃない人をさがすべきだ。例えば中国に興味がある人とか、中国語を勉強してる人…一緒に勉強できるなら幸いだ。　　</p><h1 id="2019-10-08-カタカナ">6&emsp;2019-10-08　カタカナ</h1><p>　　日本に来てから一番印象深いのはあっちこっちでカタカナばかりなことだ。特に食べ物の名前でカタカナが多すぎる。店に行ったらメニューがほとんど読めない、特にイタリア、インド風の料理。時には辞書で単語を探しても見つけられなくて、本当に辛かった。<br>　　やはり単語量が足りないんだ。僕の考えた解決方法は店に行く前に、必ず食べログなどのアプリでメニューを読んだり、ネットで調べたりすることだ。日本人はみんなそれを読めるなんて、大したことだと思う。<br>　　それにしても、カタカナ語の中に英語からの言葉が多いと思う。英語が上手な人ならそのカタカナを一回読んだら、すぐに意味が分かる場合もたくさんあると思う。　　</p><h1 id="2019-10-09-メディカル化粧品">7&emsp;2019-10-09　メディカル化粧品</h1><p>　　日本の化粧品と言えば、世界中の女性に注目されていると思う。特に薬用化粧品、或いはメディカル化粧品は人気が高く、中国では皆「药妆」と呼ばれている。でも、僕のようなおとことしてはそれを知ることもなかった。今日tomod’sという店に入ってたら、とても驚いた。いろんな種類の化粧品があって、目が眩くなるくらいだった。<br>　　「やはりこんな場所は彼女もない俺が来る所じゃない」と呟きながら、僕は隣りのラーメン屋に入った。　　</p><h1 id="2019-10-10-買い物">8&emsp;2019-10-10　買い物</h1><p>　　明日台風が来るそうだから、夕方スーパーへ買い物に行った。思ったより人が多かった。この三日間は、できるだけ家から出ないようにするために物を買っておこう、とみんな思っているからだろう。僕もいろんな食べ物を買って、3000円もかかった。お金って本当にすぐ飛んでいくと思うね。　</p><h1 id="2019-10-11-井の中の蛙">9&emsp;2019-10-11　井の中の蛙</h1><p>　　けさ映画を見（／観）に行った、台風が来る前内に。ガンダーラという曲は本当に素晴らしい。初めて聴いたけど、結構古い曲だった。昔の時代の音楽を、僕はすごく気に入っている。<br>　　ことわざも一つ学んだ。「井の中の蛙大海を知らず、されど空の青さを知る」。確か前半部分は中学の頃教科書で読んだことがある。荘子の秋水篇だった。でも後半部分は知らなかった。ネットで調べたところ、日本人が付け足したそうだ。狭い世界に囚われてると物事がよく見えないが、狭い世界で生きてるからこそ見えるものもある。いい言葉だと思う。<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20191011-1.webp" alt><br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20191011-2.webp" alt></p><h1 id="2019-10-12——2019-10-25-勉強中">10&emsp;2019-10-12——2019-10-25　勉強中</h1><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/20190928-6.webp" alt></p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-09-28-liu-xue-9.26-10.10/#disqus_thread</comments>
    </item>
    
    <item>
      <title>本地LaTeX公式实时编辑器（个人用）</title>
      <link>https://chengpengzhao.com/2019-06-03-zi-ji-zuo-de-latex-gong-shi-bian-ji-qi-ge-ren-yong/</link>
      <guid>https://chengpengzhao.com/2019-06-03-zi-ji-zuo-de-latex-gong-shi-bian-ji-qi-ge-ren-yong/</guid>
      <pubDate>Mon, 03 Jun 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;LaTeX-公式编辑-with-MathJax-by-zcp&quot;&gt;1
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="LaTeX-公式编辑-with-MathJax-by-zcp">1&emsp;LaTeX 公式编辑 with MathJax by zcp</h1><h2 id="MathJax">1.1&emsp;MathJax</h2><p>官网 ：<a href="https://www.mathjax.org/" target="_blank" rel="noopener">MathJax</a></p><h2 id="codecogs">1.2&emsp;codecogs</h2><p>就是从这个网站抄下来的：<a href="https://www.codecogs.com/latex/eqneditor.php" target="_blank" rel="noopener">codecogs</a></p><h2 id="tablesgenerator">1.3&emsp;tablesgenerator</h2><p>还有这个：<a href="http://www.tablesgenerator.com/" target="_blank" rel="noopener">tablesgenerator</a><br><br><br>最近在学LaTeX，自己用的是Texlive2019+Texmaker，据说CTEX很久没更新了大家都不推荐使用；编辑器我也试了Texstudio、Texworks、WinEdt等，还是感觉Texmaker的界面和自动补齐功能比较好。</p><p>排版过程遇到的一个问题就是公式的输入，由于刚开始学命令都记不住，如果输入一下编译一下实在太慢，于是去网上找了找有没有可以实时显示的LaTeX公式编辑工具，果然codecogs的网站就很不错，感觉非常好用。</p><p>但不足之处就是不稳定，有时候加载不出来，而且广告看着难受还要点掉；然后去网上找了下好像没有本地版的这种工具，因为以前blog弄过mathjax，知道怎么在html中显示公式，于是萌生了把codecogs的方便之处copy下来，做一个html再加上mathjax的实时显示。</p><p>离线版的LaTeX实时公式编辑就这么完成了~</p><h2 id="在线版用法">1.4&emsp;在线版用法</h2><p>网址： <a href="https://chengpengzhao.com/latex_htm_zcp/">https://chengpengzhao.com/latex_htm_zcp/</a></p><h2 id="本地版用法">1.5&emsp;本地版用法</h2><ol><li><a href="https://github.com/chengpengzhao/latex_htm_zcp" target="_blank" rel="noopener">clone或download</a>到本地</li><li>打开<strong>latex_zcp</strong>文件夹</li><li>双击 <strong>LaTeX 公式编辑 with MathJax by zcp.htm</strong></li><li>愉快的输入公式吧~</li></ol><h1 id="附：">2&emsp;附：</h1><p>顺便把一个<a href="http://www.tablesgenerator.com/" target="_blank" rel="noopener">生成LaTeX表格</a>的工具网页的源码搬下来了，方便离线用。<a href="https://chengpengzhao.com/LaTeX_Table_Generator_zcp/">在线版</a>也传到<a href="https://github.com/chengpengzhao/LaTeX_Table_Generator_zcp" target="_blank" rel="noopener">github</a>里了~</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-06-03-zi-ji-zuo-de-latex-gong-shi-bian-ji-qi-ge-ren-yong/#disqus_thread</comments>
    </item>
    
    <item>
      <title>这个博客的建立过程</title>
      <link>https://chengpengzhao.com/2019-05-26-meng-xin-jian-bo-ke-de-guo-cheng/</link>
      <guid>https://chengpengzhao.com/2019-05-26-meng-xin-jian-bo-ke-de-guo-cheng/</guid>
      <pubDate>Sun, 26 May 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;前言&quot;&gt;1&amp;emsp;前言&lt;/h1&gt;&lt;p&gt;之前也说了，我是用的Gi
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="前言">1&emsp;前言</h1><p>之前也说了，我是用的Github Page加Hugo的方式搭建的博客，其实还有很多比如jekyll、hexo等部署静态网站的工具；而托管的服务器方面，有的大佬选择直接自己租一台，还有<a href="https://www.jianshu.com/p/a44a6347031c" target="_blank" rel="noopener">一些途径</a>我就不多说了。</p><p><a href="https://help.github.com/en/categories/github-pages-basics" target="_blank" rel="noopener">github pages</a>直接托管在github上，比较方便所以很多人都用的这种方式，不过要求至少要会一点git控制命令，git相关教程我记得放在bookmarks里了，真正常用也就那么几个语句，比较容易上手。而之所以选择<a href="https://gohugo.io/documentation/" target="_blank" rel="noopener">hugo</a>纯粹是因为朋友推荐，我搭好了之后看有的hexo主题写的特详细，顿时有点后悔，觉得自己走了很多弯路，不过hugo也是很好用的虽然网上资料可能不是太多。</p><p>接下来我就详细叙述下这个博客的建立的过程，我也是萌新有些地方具体的原理可能不太清楚，不过只要搭的像个样子不就行了。</p><h1 id="步骤">2&emsp;步骤</h1><h2 id="安装-hugo、git、nodejs">2.1&emsp;安装 hugo、git、nodejs</h2><p>用hugo部署网站一般先是在本地调试，通过hugo server命令可以在浏览器<a href="http://localhost:1313" target="_blank" rel="noopener">http://localhost:1313</a> 查看效果，然后用git将文件传到github里；nodejs是之后给网页加一些模块脚本要用的，用的机会不是很多。具体的安装步骤我觉得就没必要讲了，百度一下一大把的东西，又不复杂。</p><h3 id="常用的Git命令">2.1.1&emsp;常用的Git命令</h3><ol><li><p>克隆远程库： git clone+目标库网址\<br> （如<strong>git clone <a href="https://github.com/chengpengzhao/latex_htm_zcp" target="_blank" rel="noopener">https://github.com/chengpengzhao/latex_htm_zcp</a></strong> ）</p></li><li><p>添加远程库： <strong>git remote add origin</strong>+目标库网址，若提示失败在前面用 <strong>git remote rm origin</strong> 命令。</p></li><li><p>同步到本地库：<strong>git pull origin master</strong>  ，这个时候再使用命令：<strong>git push -u origin master</strong>  就能将本地库的内容推送到远程仓库；加上了-u参数，Git不但会把本地的master分支内容推送的远程新的master分支，还会把本地的master分支和远程的master分支关联起来，在以后的推送或者拉取时就可以简化命令。下一次直接使用 <strong>git pull</strong> 或者<strong>git push</strong>.</p></li><li><p>本地修改完进行同步： </p><p> <strong>git add -A</strong>  (注意下add各参数的意义)</p><p> <strong>git commit -m “your message”</strong></p><p> <strong>git push origin master</strong></p></li></ol><h2 id="hugo的文件夹结构">2.2&emsp;hugo的文件夹结构</h2><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store//img/hugo%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84.webp" alt="我的hugo文件夹">如图hugo一般是这些文件夹（除了node_modules）加上一个config.toml配置文件（还有些文件是我后来写的上传东西用的脚本）。</p><ul><li><p>archetypes：放模版文件？这个我真不知道有啥用，具体看hugo文档肯定有说明</p></li><li><p>content：写的文章都放这里面，md格式，要写博客<a href="http://www.markdown.cn/#acknowledgement" target="_blank" rel="noopener">markdown语法</a>必须要先学一学</p></li><li><p>data：我的是空的，不知道干嘛的</p></li><li><p>layouts：十分重要！网页的结构全在里面，各种html代码</p></li><li><p>public：用hugo生成网页后的文件，把这些上传到github里就够了，所以通常在public文件夹里面建立.git项目。</p></li><li><p>resources：我的是空的</p></li><li><p>static：有三个文件夹，css里面放字体文件，img放图片，js放网页加载时所用的脚本。</p></li><li><p>themes：下载后的主题放在这里面，不过我一般把主题自己修改后里面的东西挪到layouts和static里，所以我这里面也是空的。</p></li><li><p>config.toml：配置文件，一般每个主题都会说明下这个文件怎么写。</p></li></ul><p>推荐<strong>先在本地把网站安排好了再上传</strong>，不然改来改去很麻烦。</p><h2 id="下载hugo主题">2.3&emsp;下载hugo主题</h2><p><a href="https://themes.gohugo.io/" target="_blank" rel="noopener">https://themes.gohugo.io/</a>上可以找到很多好看的主题，仔细阅读所选主题的相关说明，把它下载到本地，把各个文件夹里的东西放到hugo的相应文件夹里，然后用hugo命令在本地查看效果。一般主题都会有一个exampleSite，可以看看里面config.toml设置和文章的格式。（必须先熟悉hugo文件夹结构后再进行这一步）</p><p>hugo server启动后网页(localhost1313)显示的内容会随着你的修改实时变动，所以在写博客时十分好用，这也是hugo的一大优点吧。</p><h2 id="熟悉所下载主题的模块">2.4&emsp;熟悉所下载主题的模块</h2><p>如果你想要自己对主题做一些修改，比如加入评论系统啊、显示来访数、动态效果、搜索功能……那就必须经过最苦逼的这一个步骤了，把主题layouts和static里的文件一个个的啃一遍，知道每个文件大概实现了什么功能。一般好一点的主题都会说明一下它有哪些模块，怎么加入一些常用模块；总之在这方面花的时间应该是最多的。</p><p>建议把这部分放在最后进行，或者干脆不做修改直接拿他的主题用也行。下面我简单分类介绍下我博客中这几个模块添加的艰辛历程：</p><h3 id="访问计数模块">2.4.1&emsp;访问计数模块</h3><p>我用的是<a href="http://busuanzi.ibruce.info/" target="_blank" rel="noopener">不蒜子</a>网页计数器，这个还比较简单，layouts文件夹里相应的html位置加入代码就行。</p><h3 id="评论模块">2.4.2&emsp;评论模块</h3><p>由于在国内，某些评论系统被墙不好用，我用的是<a href="https://valine.js.org/" target="_blank" rel="noopener">Valine</a>的评论系统，也是在相应的html中插入代码；这里要注意页面的格式设置，可能会造成字体、方框大小不太合适，这时候要在css文件中修改格式。常采用开发者工具先找到控制对应字体的文件位置，再做相应修改。</p><h3 id="搜索模块">2.4.3&emsp;搜索模块</h3><p>我的主题自带了对<a href="https://www.algolia.com/" target="_blank" rel="noopener">algolia</a>搜索模块的支持，所以注册、设置下来没有花太多功夫，这个好像还要装到本地，然后每次写了posts之后要用<strong>npm run algolia</strong>命令更新索引目录。</p><h3 id="数学公式模块">2.4.4&emsp;数学公式模块</h3><p><a href="https://www.mathjax.org/#gettingstarted" target="_blank" rel="noopener"><strong>Mathjax</strong></a>没得说。</p><h3 id="特殊效果模块">2.4.5&emsp;特殊效果模块</h3><p>可以加入一些动态背景效果（比如像我这样），或者甚至你可以加一个live2D的看板娘。</p><h1 id="总结">3&emsp;总结</h1><p>不要在意具体的细节，知道代码的作用、大体的框架、实现的方式，然后进行粗略的调整就行了。如果把这些代码看成是一个个贴了标签的黑盒，那么对于我们这些非专业人士来说，读懂标签就够用了。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-05-26-meng-xin-jian-bo-ke-de-guo-cheng/#disqus_thread</comments>
    </item>
    
    <item>
      <title>日本語で作文——文章を書こう</title>
      <link>https://chengpengzhao.com/2019-04-06-ri-ben-yu-dezuo-wen/</link>
      <guid>https://chengpengzhao.com/2019-04-06-ri-ben-yu-dezuo-wen/</guid>
      <pubDate>Sat, 06 Apr 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;漢字と符号及び原稿用紙の使い方について&quot;&gt;1&amp;emsp;漢字と符号
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="漢字と符号及び原稿用紙の使い方について">1&emsp;漢字と符号及び原稿用紙の使い方について</h1><h2 id="表示体系">1.1&emsp;表示体系</h2><ol><li>漢字：　　音読み、訓読み<br> $<br> \begin{cases}<br> 和語：&amp; \text{畳、下駄…}  \\<br> 漢語：&amp; \text{就職、拡大…}<br> \end{cases}<br> $</li><li>外来語：　パン、カルテ、フォーク…</li><li>混合：連絡係、人間ドック</li><li>ローマ字：JR、WTO</li></ol><h2 id="使い状態">1.2&emsp;使い状態</h2><ol><li><p>假名书写: 助词、语法作用词</p></li><li><p>汉字词： 日制汉字、繁体字、不同与中文的简体字</p></li><li><p>相同读音不同汉字： あう：会う、合う、遭う、逢う…</p></li><li><p>送り仮名(送假名)：嬉しい、爽やか、柔らかい…</p></li></ol><h2 id="符号の使い方">1.3&emsp;符号の使い方</h2><ol><li>コンマ(、)：横書きの時「，」　停顿或断开</li><li>ピリオド (。)：横書きの時「．」　句子完了</li><li>クエスチョンマーク(？)：　不经常用</li><li>感嘆符(！)：情绪激昂</li><li>鍵括弧<del>かぎかっこ</del>(「」)：引用，类似中文的‘  ’ ，双重『』表示书名等或引用中引用</li><li>括弧<del>かっこ</del>()：注释说明</li><li>リーダー(……)：省略、中黒(・)：单词并列</li><li>ダッシュ(ー)：　插入句，副标题（前后都要有）</li></ol><h2 id="基本原则">1.4&emsp;基本原则</h2><ol><li>标题空3格，段开头空1格，句子结尾时符号不能放一行开头</li><li>促音拗音都是占一格</li></ol><h1 id="簡潔で分かりやすい文章について">2&emsp;簡潔で分かりやすい文章について</h1><ul><li>简明易懂（clear、correct、concise）</li></ul><ol><li><p>一句传达一个事项： 少用て・が不间断连句导致句子关系混乱、注意句子切断和接续词使用</p></li><li><p>明确呼应关系：  注意主谓一致，修饰关系要明确</p></li><li><p>修饰成分尽量名词化：格助词+の＋名词、名词词组…</p><p> <em>（深み、深さ、深め）都是名词化，区别？</em></p><p> <em>―　さ：具体的な事柄、み：抽象的な概念、め：状態</em></p></li></ol><h1 id="自他動詞の表現について">3&emsp;自他動詞の表現について</h1><h2 id="区別">3.1&emsp;区別</h2><ol><li><p>$<br>\begin{cases}<br>自：&amp; \text{现象、状态、结果}  \他：&amp; \text{带宾语、意志动作}<br>\end{cases}<br>$</p></li><li><p>四种形态：</p><p>$<br>\begin{cases}<br>自他动词句同时存在：&amp; \text{ドアが開いた／僕がドアを開けた}  \\<br>自他同形：&amp; \text{店がオープンした／私は店をオープンします}  \\<br>只有他动词：&amp; \text{予定を変更した／予定が変更された(受身形)}  \\<br>只有自动词：&amp; \text{方法がはっきりしない／方法をはっきりさせよう(使役形)}<br>\end{cases}<br>$</p></li></ol><h2 id="形式">3.2&emsp;形式</h2><ol><li>自动词使役句：表述意志性动作； 他动词被动态： 隐去动作主体</li><li>「もともと地上には道はない。歩く人が多くなれば、それが道になるのだ」―魯迅</li><li>使役态和被动态的作用： <strong>统一视点</strong>、连贯主题</li></ol><h1 id="主題の「は」と主格の「が」について">4&emsp;主題の「は」と主格の「が」について</h1><h2 id="「は」的功能">4.1&emsp;「は」的功能</h2><ol><li><p>替代格成分，构成主题</p></li><li><p>～は～が～：表设定说明内容范围的概念</p></li><li><p>表对比。</p></li></ol><h2 id="「が」的用法">4.2&emsp;「が」的用法</h2><ol><li>中立叙述：自然现象或状态主体</li><li>强调主语（惊讶、疑惑、不解）</li></ol><h2 id="使用选择">4.3&emsp;使用选择</h2><ol><li><p>句子中：</p><ol><li><p>は：主题-述题，围绕主题阐述（说明部分为表述重点）</p></li><li><p>が：主格-谓语，整体作为现象状态描述</p></li></ol></li><li><p>段落中：</p><ol><li>は：确立主题，统一表述视点</li><li>が：围绕主题某侧面进行解说</li></ol></li></ol><h1 id="格助詞と指示代名詞について">5&emsp;格助詞と指示代名詞について</h1><h2 id="格助词：">5.1&emsp;格助词：</h2><ol><li>を：<ol><li>表示通过、离开、移动、活动范围的场所</li><li>明示宾语成分</li></ol></li><li>に：　时间点、目的地、动作涉及对象、状态的对象</li><li>で：　场所工具、手段、原因、范围、时间数量…</li><li>から：　时间地点、渠道、来源、起因</li></ol><h2 id="指示代词">5.2&emsp;指示代词</h2><ol><li>$<br> \begin{cases}<br> こ：&amp; \text{重点引导后面内容 }  \そ：&amp; \text{重点在指示前面内容}<br> \end{cases}<br> $</li><li>それ／その／そんな：作为旁观者客观叙述</li><li>こ系列常用于自己写文章时，或以前面内容展开，心理距离近</li></ol><h1 id="総合分析">6&emsp;総合分析</h1><h2 id="記事・報道文の書き方">6.1&emsp;記事・報道文の書き方</h2><ol><li>「です・ます形」多用于对读者或听众述说的语气，「だ体」多用于较客观的报道。</li><li>5W1H式纪事： Who、What、Ｗhere、When、Ｗhy、How</li><li>客观公正，第三人称立场为主</li></ol><h2 id="伝言・留守メモの書き方">6.2&emsp;伝言・留守メモの書き方</h2><ol><li>伝言$<br> \begin{cases}<br> ～は、～と言う／話す \～そうだ、～ということだ\口语化表达：～とか、～が言うには\end{cases}<br> $</li><li>授受：<strong>动作、物品、恩惠</strong>的流向$<br> \begin{cases}<br> 接受：くれる、くださる\给：やる、あげる、さしあげる\请求：もらう、いただく(自谦,常用)\end{cases}<br> $</li></ol><h2 id="メール・ファックスの書き方">6.3&emsp;メール・ファックスの書き方</h2><ol><li>敬語の分類:<table align="center"><tr>        <th>3分類</th>        <th>5分類</th>        <th>機能</th>        <th>例</th>    </tr>    <tr>        <td>尊敬語</td>        <td>尊敬語</td>        <td rowspan="2" 　>話題の人物への敬意を示す</td>    <td>いらっしゃる</td> </tr><tr>        <td rowspan="2" 　>謙譲語</td>        <td>謙譲語１(贬低自己)</td>        <td>伺う、申し上げる</td>   </tr><tr>        <td>謙譲語2（郑重叙述）</td>      <td rowspan="2" 　>話し手の品格を保持する</td>   <td>参る、申す</td>   </tr><tr>         <td rowspan="2" 　>丁寧語</td>        <td>美化語</td> <td>お酒、お料理</td> </tr><tr>         <td>丁寧語</td>        <td>聞き手・場面への配慮を示す</td> <td>です・ます</td> </tr></table>  </li><li>表达形式</li></ol><ul><li>尊敬語：<br>$<br>  \begin{cases}<br>  敬語動詞(特殊)：召し上がる、おっしゃる\お／ご···ください／です／になる／なさる\お＋ます形(和語動詞)、サ変動詞語幹\助動詞「れる・られる」\end{cases}<br>$</li><li>謙譲語：<br>$<br>  \begin{cases}<br>  敬語動詞(特殊)：いただく、参る、申す\お／ご···する(いたす)／いただく、使役形＋いただく\お＋ます形(和語動詞)、サ変動詞語幹\end{cases}<br>$</li><li>丁寧語：　「です・ます」<br>$<br>  \begin{cases}<br>  メール：主题明确、逐条写、对外语\ファックス：书信格式、日期右上、信函用语（拝啓、敬具）\end{cases}<br>$</li></ul><ol start="3"><li>句尾决定句意，敬意主要体现在句尾部分</li></ol>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-04-06-ri-ben-yu-dezuo-wen/#disqus_thread</comments>
    </item>
    
    <item>
      <title>python爬虫入门练习——爬取北航课程中心课件资源</title>
      <link>https://chengpengzhao.com/2019-03-21-python-pa-chong-ru-men-lian-xi/</link>
      <guid>https://chengpengzhao.com/2019-03-21-python-pa-chong-ru-men-lian-xi/</guid>
      <pubDate>Thu, 21 Mar 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;p&gt;目标是课程中心7195条课程信息下的所有资源~：&lt;/p&gt;
&lt;h1 id=&quot;前
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>目标是课程中心7195条课程信息下的所有资源~：</p><h1 id="前言">1&emsp;前言</h1><p>首先声明我现在还只是个萌新，某一天忽然想学一下爬虫，然后去百度随便找了个教程然后看了开头一点点，于是想随便找个项目练习一下，所以就写了个简单的爬取课件资源的py程序。<br><br>为什么只看了一点点呢，因为实在看不下去啊，当时的心理状态：“他在讲什么，这软件干嘛的，这库咋用的，为什么他知道这么多啊……”然后想算了找本书学学可能更好吧，于是我翻开了目录：<br><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E7%9B%AE%E5%BD%95.webp" alt><br>幸好我先看视频配置好了环境，这些东西都还有印象，要是先看书的话简直就是新手劝退。果然学一个东西之前还是要进行一些取舍，根据自己的目的来，看要达到一个什么水平，之后分配适当的时间，能不用就不学，毕竟不是自己专业相关的东西，纯属娱乐，能迅速达到自己的目标就行了，虽然有些功利但毕竟光陰矢の如し。<br><br>首先是几个惯例性问题：<br></p><h2 id="What">1.1&emsp;What</h2><p>啥是爬虫啊？百度告诉我们<a href="https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB/5162711?fr=aladdin" target="_blank" rel="noopener">爬虫</a>就是<strong>请求</strong>网站并<strong>提取数据</strong>的<strong>自动化</strong>程序，我之前平常玩玩手游，又菜又不想花太多时间，经常用按键精灵写一些简单脚本完成重复性的动作，当然其中也涉及到很多循环判断。Web spider也是个类似的东西，能够免去许多重复性的工作，所以其实技术含量倒没啥，而且大佬们都把轮子给造好了，我们只需要伸手就能用；真正要下点功夫的也就是和一些反爬虫斗智斗勇，有时候也容易走偏甚至触犯法律。</p><h2 id="Why">1.2&emsp;Why</h2><p>为什么要用爬虫，或者说什么时候用；当然是你需要大量数据的时候，这些数据可以是各种类型的，比如文本可以用来进行一些大数据分析、用来给AI学习、用来抢票…….来看看知乎大神们的回答：<a href="https://www.zhihu.com/question/27621722" target="_blank" rel="noopener">利用爬虫技术能做到哪些很酷很有趣很有用的事情？</a>肯定比我想得到的用法要多。</p><h2 id="Where">1.3&emsp;Where</h2><p>JAVA | PYTHON |    PHP | C# | C/C++……这么多语言，随便哪个都能拿来写爬虫，要我推荐当然是pyhton啊，毕竟人家是IEEE Spectrum 2018 编程语言 Top 1，所以我也是从pyhton爬虫开始学（别的都用的太少不熟悉- -），如果你没学过，正好我推荐<a href="https://www.coursera.org/specializations/python" target="_blank" rel="noopener">密歇根大学Charles Severance教授</a>的一系列<a href="https://www.py4e.com/materials" target="_blank" rel="noopener">python课程</a>，什么听说你被墙了网站打不开，没关系我都下好了<a href="https://pan.baidu.com/s/1cQIpwzDUblokfrwxOMFcJg" target="_blank" rel="noopener">打包</a>送你<em>ofek</em>。然后我用的是python3，软件推荐pyCharm，谁用谁知道。</p><h1 id="爬之前需要了解的">2&emsp;爬之前需要了解的</h1><p>真正动手开始写才知道写博客真的挺花时间的。</p><h2 id="网页基础">2.1&emsp;网页基础</h2><p>学爬虫的一个好处就是你可以顺带了解到几乎每天都会接触的网页的一些知识，从而带来许多方便之处；比如某天登录一个网址它默认帮你填充了密码但是你忘了具体是什么想看一下，你只需要看一眼开发者工具里浏览器发出的请求就可以了。(我是觉得比打开保存的密码表单一个个找要快，当然你也许有更好的管理密码的工具)<br><br>这段对我来说真的不好写，毕竟是个外行人，<a href="https://cuiqingcai.com/?s=%E7%88%AC%E8%99%AB" target="_blank" rel="noopener">崔老师的博客</a>和书里都有很详细的讲解，我就简单讲下我的认识吧：</p><ul><li><p>打开你的浏览器开发者工具，Elements下那块一堆尖括号让人难受的字符串就是html——HyperText Markup Language，它包含许许多多的标签，很多时候在这里面就藏了我们想要的东西（当然这只是最幸运的情况），接下来的工作就是如何让计算机能识别并且提出这些东西出来。</p></li><li><p>点击Network项，会发现一排东西，XHR、JS、CSS、Img……有些时候没那么幸运，html里空空如也，这说明该网站使用的是别的加载方式如ajax等；这时不妨去XHR里瞧一瞧说不定就发现了呢，JS（JavaScript）有很多都是写好的函数用来控制网页的行为，我是还没仔细研究过这块；CSS主要用来美化网页布局如排版、字体等；img就如其名，简单易懂。</p></li><li><p>点击Application项，在storage找到<strong>Cookies</strong>，这是个非常重要的东西，网站用它辨别你的身份，所以爬虫常用它进行伪装，让对方认为是一个人在操作模拟器点击浏览网页；当然这只是第一步很简单的伪装。</p><p>  <img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E5%8C%97%E8%88%AAvpnweb.webp" alt></p></li><li><p>点进一个请求，看到右边有<strong>Requests Headers</strong>、<strong>Response Headers</strong>等等，这又是一个非非非常重要的一项，里面清清楚楚的记载了浏览器是如何<u>发送请求</u>并且网站端是如何<u>响应</u>的，所以如果你的爬虫不按它的格式发请求还妄想访问它，等待你的只会是一系列的奇葩<a href="https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/5053660?fr=aladdin" target="_blank" rel="noopener">状态码</a>。</p><p>  <img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/header.webp" alt></p></li></ul><h2 id="Python相关库">2.2&emsp;Python相关库</h2><ul><li>先说点别的，好像有种叫做可视化爬虫的东西，就算不怎么懂编程都能爬些数据，我没接触过，不过也是一种选择吧。</li><li><strong>requests库</strong>，用来发送请求，python内置的urllib也能用，不过好像这个更方便。（自行安装）</li><li><a href="https://www.crummy.com/software/BeautifulSoup/" target="_blank" rel="noopener">Beautiful Soup</a>，用来解析html的库，官网有点意思，十分出色，好像还有几个如XPath、Pyquery，功能都差不多，先只学一个以后不够用再说。</li><li>还有如re、os这些库，用来进行字符串匹配和文件操作的，也很常用。</li><li>数据储存方面，我现在还用不到MongoDB、MySQL这些东西，所以相关库就暂且不提。</li></ul><p>(总算快到正片了…)</p><h1 id="py爬虫思路及过程—以北航课程中心为例">3&emsp;py爬虫思路及过程—以北航课程中心为例</h1><h2 id="明确需求">3.1&emsp;明确需求</h2><ol><li>获取北航课程中心的所有课程，信息（类别、名称、链接、教师）储存为一个文本文档。</li><li>筛选想下载的课程（抱歉，我全都要），进入链接并判断是否有课件资源，建立文件夹储存课件以及详细的课程信息。<br></li></ol><h2 id="分析网站">3.2&emsp;分析网站</h2><p>由于我不在北航，校外访问首先要登录<a href="https://e.buaa.edu.cn/users/sign_in" target="_blank" rel="noopener">北航vpn</a>，首先打开开发者工具刷新网址，可以看到有一个Name是sign_in，明显就是我们要找的；然后，点击登录后（<u>首先你得有个北航课程中心的账号</u>）发现Headers里面多了Form Data这一项，里面记录了你的账号密码和一个<strong>authenticity_token</strong>以及一些键名，发送请求时肯定是要按照这个格式来；<br></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E8%AF%BE%E7%A8%8B%E4%B8%AD%E5%BF%83%E7%99%BB%E5%BD%95.webp" alt></p><p>不过细心的你可能发现每次authenticity_token的值都在变化，你可能会说：这要我怎么请求啊？但北航怎么会难为你呢，更加细心的你在网站的<strong>html源代码</strong>里一搜便搜到了竟然有这个值，所以你只需要先提取出来再加入你的请求中就行了，多简单。</p><p>当你满怀欣喜进入一门课程的界面时，又发现右上角竟然还是没有登录的状态？？对这个设定让我当初下课件的时候特别难受，你还得再点一下登录按钮然后会自动跳转进portal界面然后你再返回课程界面按下F5！而且过了一会又会变成需要登录的状态，这个细节在写爬虫的时候也得注意一下，这里不细讲了，毕竟程序员们都在说：<br></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/Talk%20is%20cheap.webp" alt><br></p><h2 id="请求获取解析储存数据">3.3&emsp;请求获取解析储存数据</h2><p>首先看下一共有多少条目课程：<br></p><h3 id="coursesinfo-spider-py">3.3.1&emsp;coursesinfo_spider.py</h3><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">import</span> requests<span class="token keyword">from</span> urllib<span class="token punctuation">.</span>parse <span class="token keyword">import</span> urlencode<span class="token keyword">from</span> requests<span class="token punctuation">.</span>exceptions <span class="token keyword">import</span> ConnectionError<span class="token keyword">import</span> json<span class="token keyword">from</span> multiprocessing <span class="token keyword">import</span> Pools <span class="token operator">=</span> requests<span class="token punctuation">.</span>Session<span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token comment" spellcheck="true">#会话维持</span><span class="token comment" spellcheck="true">#返回当页的json</span><span class="token keyword">def</span> <span class="token function">get_one_page</span><span class="token punctuation">(</span>pagenumber<span class="token punctuation">)</span><span class="token punctuation">:</span>    data<span class="token operator">=</span><span class="token punctuation">{</span>        <span class="token string">'pageSize'</span><span class="token punctuation">:</span> <span class="token string">'50'</span><span class="token punctuation">,</span>        <span class="token string">'pageNumber'</span><span class="token punctuation">:</span> pagenumber<span class="token punctuation">,</span>        <span class="token string">'orderParams'</span><span class="token punctuation">:</span> <span class="token string">'[{"field":"updateDate","dir":"desc"}]'</span><span class="token punctuation">,</span>        <span class="token string">'searchParams'</span><span class="token punctuation">:</span> <span class="token string">'[]'</span><span class="token punctuation">,</span>        <span class="token string">'specialParams'</span><span class="token punctuation">:</span> <span class="token string">'[]'</span>    <span class="token punctuation">}</span>  loginurl<span class="token operator">=</span><span class="token string">'https://course.e.buaa.edu.cn/opencourse/course/list?'</span><span class="token operator">+</span>urlencode<span class="token punctuation">(</span>data<span class="token punctuation">)</span>    headers <span class="token operator">=</span> <span class="token punctuation">{</span>        <span class="token string">'Accept'</span><span class="token punctuation">:</span> <span class="token string">'application/json, text/javascript, */*; q=0.01'</span><span class="token punctuation">,</span>        <span class="token string">'Accept-Encoding'</span><span class="token punctuation">:</span> <span class="token string">'gzip, deflate, br'</span><span class="token punctuation">,</span>        <span class="token string">'Host'</span><span class="token punctuation">:</span><span class="token string">'course.e.buaa.edu.cn'</span><span class="token punctuation">,</span>        <span class="token string">'Connection'</span><span class="token punctuation">:</span> <span class="token string">'keep-alive'</span><span class="token punctuation">,</span>        <span class="token string">'User-Agent'</span><span class="token punctuation">:</span> <span class="token string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'</span><span class="token punctuation">,</span>        <span class="token string">'Cookie'</span><span class="token punctuation">:</span> （<span class="token comment" spellcheck="true">#这个我可不能告诉你） ,</span>        <span class="token string">'Referer'</span><span class="token punctuation">:</span> <span class="token string">'https://course.e.buaa.edu.cn/opencourse/course/list'</span><span class="token punctuation">,</span>        <span class="token string">'X-Requested-With'</span><span class="token punctuation">:</span> <span class="token string">'XMLHttpRequest'</span>    <span class="token punctuation">}</span>     <span class="token comment" spellcheck="true">#我是老老实实按照它的请求写的，当然少写几个也可能没啥问题</span>    <span class="token keyword">try</span><span class="token punctuation">:</span>        login<span class="token operator">=</span>s<span class="token punctuation">.</span>post<span class="token punctuation">(</span>loginurl<span class="token punctuation">,</span> headers<span class="token operator">=</span>headers<span class="token punctuation">)</span>        <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'status code:'</span><span class="token punctuation">,</span> login<span class="token punctuation">.</span>status_code<span class="token punctuation">)</span>        <span class="token keyword">if</span> login<span class="token punctuation">.</span>status_code <span class="token operator">==</span> <span class="token number">200</span><span class="token punctuation">:</span>            <span class="token keyword">return</span> login<span class="token punctuation">.</span>content<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span>    <span class="token keyword">except</span> ConnectionError<span class="token punctuation">:</span>        <span class="token keyword">return</span> None<span class="token comment" spellcheck="true">#返回generator，当前页上的所有课程</span><span class="token keyword">def</span> <span class="token function">parse_page</span><span class="token punctuation">(</span>pagenumber<span class="token punctuation">)</span><span class="token punctuation">:</span>    text<span class="token operator">=</span>get_one_page<span class="token punctuation">(</span>pagenumber<span class="token punctuation">)</span>    data <span class="token operator">=</span> json<span class="token punctuation">.</span>loads<span class="token punctuation">(</span>text<span class="token punctuation">)</span>    <span class="token keyword">for</span> item <span class="token keyword">in</span> data<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'content'</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        <span class="token keyword">yield</span> <span class="token punctuation">{</span>            <span class="token string">'Type'</span><span class="token punctuation">:</span>item<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'courseType'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>            <span class="token string">'Title'</span><span class="token punctuation">:</span>item<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'title'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>            <span class="token string">'url'</span><span class="token punctuation">:</span><span class="token string">"https://course.e.buaa.edu.cn/opencourse/course/detail/"</span><span class="token operator">+</span>str<span class="token punctuation">(</span>item<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'id'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>            <span class="token string">'Teacher'</span><span class="token punctuation">:</span>item<span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'teachers'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>get<span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">)</span>        <span class="token punctuation">}</span><span class="token comment" spellcheck="true">#以字符串形式返回当前页的课程</span><span class="token keyword">def</span> <span class="token function">each_page_content</span><span class="token punctuation">(</span>pagenumber<span class="token punctuation">)</span><span class="token punctuation">:</span>    content <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>    <span class="token keyword">for</span> item <span class="token keyword">in</span> parse_page<span class="token punctuation">(</span>pagenumber<span class="token punctuation">)</span><span class="token punctuation">:</span>        content<span class="token punctuation">.</span>append<span class="token punctuation">(</span>item<span class="token punctuation">)</span>    <span class="token keyword">return</span> content<span class="token comment" spellcheck="true">#主程序</span><span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">'__main__'</span><span class="token punctuation">:</span>    pool <span class="token operator">=</span> Pool<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token comment" spellcheck="true">#多线程，这里数据就几千条，其实没必要</span>    content<span class="token operator">=</span>list<span class="token punctuation">(</span><span class="token punctuation">)</span>    result<span class="token operator">=</span>pool<span class="token punctuation">.</span>map<span class="token punctuation">(</span>each_page_content<span class="token punctuation">,</span> <span class="token punctuation">[</span>i  <span class="token keyword">for</span> i <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">]</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> j <span class="token keyword">in</span> range<span class="token punctuation">(</span>len<span class="token punctuation">(</span>result<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">:</span>        content<span class="token operator">=</span>content<span class="token operator">+</span>result<span class="token punctuation">[</span>j<span class="token punctuation">]</span>    pool<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>    pool<span class="token punctuation">.</span>join<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token keyword">with</span> open<span class="token punctuation">(</span><span class="token string">'beihangcourses.txt'</span><span class="token punctuation">,</span> <span class="token string">'w'</span><span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>        <span class="token keyword">for</span> item <span class="token keyword">in</span> content<span class="token punctuation">:</span>            f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>json<span class="token punctuation">.</span>dumps<span class="token punctuation">(</span>item<span class="token punctuation">,</span> ensure_ascii<span class="token operator">=</span><span class="token boolean">False</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">'\n'</span><span class="token punctuation">)</span>        f<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>                   <span class="token comment" spellcheck="true">#储存为字典形式运行结果</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>运行结果：<br></p><p><img src="/medias/loading.gif" data-original="https://cdn.jsdelivr.net/gh/chengpengzhao/pic_store/img/%E8%AF%BE%E7%A8%8B%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%9C.webp" alt><br></p><h3 id="download-courses-py">3.3.2&emsp;download_courses.py</h3><pre class="line-numbers language-python"><code class="language-python"><span class="token keyword">import</span> requests<span class="token keyword">from</span> bs4 <span class="token keyword">import</span> BeautifulSoup<span class="token keyword">import</span> re<span class="token keyword">import</span> os<span class="token keyword">class</span> <span class="token class-name">Login</span><span class="token punctuation">(</span>object<span class="token punctuation">)</span><span class="token punctuation">:</span>                       <span class="token comment" spellcheck="true">#模拟登录北航vpn模块</span>    <span class="token keyword">def</span> <span class="token function">__init__</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>        self<span class="token punctuation">.</span>headers <span class="token operator">=</span> <span class="token punctuation">{</span>            <span class="token string">'User-Agent'</span><span class="token punctuation">:</span> <span class="token string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'</span><span class="token punctuation">,</span>            <span class="token string">'Host'</span><span class="token punctuation">:</span> <span class="token string">'e.buaa.edu.cn'</span>        <span class="token punctuation">}</span>        self<span class="token punctuation">.</span>login_url <span class="token operator">=</span> <span class="token string">'https://e.buaa.edu.cn/users/sign_in'</span>        self<span class="token punctuation">.</span>session <span class="token operator">=</span> requests<span class="token punctuation">.</span>Session<span class="token punctuation">(</span><span class="token punctuation">)</span>        f <span class="token operator">=</span> open<span class="token punctuation">(</span><span class="token string">"beihangcourses.txt"</span><span class="token punctuation">,</span> <span class="token string">"r"</span><span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true"># 读取之前保存的文件</span>        str <span class="token operator">=</span> f<span class="token punctuation">.</span>read<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token comment" spellcheck="true"># 将txt文件的所有内容读入到字符串str中</span>        a <span class="token operator">=</span> str<span class="token punctuation">.</span>split<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span>        self<span class="token punctuation">.</span>content <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>        <span class="token keyword">for</span> item <span class="token keyword">in</span> a<span class="token punctuation">:</span>            item <span class="token operator">=</span> eval<span class="token punctuation">(</span>item<span class="token punctuation">)</span>            self<span class="token punctuation">.</span>content<span class="token punctuation">.</span>append<span class="token punctuation">(</span>item<span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">token</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>        response <span class="token operator">=</span> self<span class="token punctuation">.</span>session<span class="token punctuation">.</span>get<span class="token punctuation">(</span>self<span class="token punctuation">.</span>login_url<span class="token punctuation">,</span> headers<span class="token operator">=</span>self<span class="token punctuation">.</span>headers<span class="token punctuation">)</span><span class="token punctuation">.</span>text        soup <span class="token operator">=</span> BeautifulSoup<span class="token punctuation">(</span>response<span class="token punctuation">,</span> <span class="token string">'lxml'</span><span class="token punctuation">)</span>        token<span class="token operator">=</span>soup<span class="token punctuation">.</span>find<span class="token punctuation">(</span>attrs<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'name'</span><span class="token punctuation">:</span> <span class="token string">'authenticity_token'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span>attrs<span class="token punctuation">[</span><span class="token string">'value'</span><span class="token punctuation">]</span>  <span class="token comment" spellcheck="true">#获取登录authenticity_token</span>        <span class="token keyword">return</span> token    <span class="token keyword">def</span> <span class="token function">login</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span> email<span class="token punctuation">,</span> password<span class="token punctuation">)</span><span class="token punctuation">:</span>        post_data <span class="token operator">=</span> <span class="token punctuation">{</span>            <span class="token string">'utf8'</span><span class="token punctuation">:</span> <span class="token string">'✓'</span><span class="token punctuation">,</span>            <span class="token string">'authenticity_token'</span><span class="token punctuation">:</span> self<span class="token punctuation">.</span>token<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>            <span class="token string">'user[login]'</span><span class="token punctuation">:</span> email<span class="token punctuation">,</span>            <span class="token string">'user[password]'</span><span class="token punctuation">:</span> password<span class="token punctuation">,</span>            <span class="token string">'commit'</span><span class="token punctuation">:</span> <span class="token string">'登录 Login'</span><span class="token punctuation">,</span>        <span class="token punctuation">}</span>        response <span class="token operator">=</span> self<span class="token punctuation">.</span>session<span class="token punctuation">.</span>post<span class="token punctuation">(</span>self<span class="token punctuation">.</span>login_url<span class="token punctuation">,</span> data<span class="token operator">=</span>post_data<span class="token punctuation">,</span> headers<span class="token operator">=</span>self<span class="token punctuation">.</span>headers<span class="token punctuation">)</span>        <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'status_code:'</span><span class="token punctuation">,</span>response<span class="token punctuation">.</span>status_code<span class="token punctuation">)</span>        <span class="token keyword">if</span> response<span class="token punctuation">.</span>status_code <span class="token operator">==</span> <span class="token number">200</span><span class="token punctuation">:</span>            <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'\n登录北航vpn成功'</span><span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">logincourse</span><span class="token punctuation">(</span>self<span class="token punctuation">)</span><span class="token punctuation">:</span>       <span class="token comment" spellcheck="true">#登录课程中心以下载资源</span>        self<span class="token punctuation">.</span>headers1 <span class="token operator">=</span> <span class="token punctuation">{</span>            <span class="token string">'User-Agent'</span><span class="token punctuation">:</span> <span class="token string">'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'</span><span class="token punctuation">,</span>        <span class="token punctuation">}</span>        self<span class="token punctuation">.</span>post_url <span class="token operator">=</span> <span class="token string">'https://sso-443.e.buaa.edu.cn/login?service=https%3A%2F%2Fcourse.e.buaa.edu.cn%2Fsakai-login-tool%2Fcontainer'</span>        response1 <span class="token operator">=</span> self<span class="token punctuation">.</span>session<span class="token punctuation">.</span>get<span class="token punctuation">(</span>self<span class="token punctuation">.</span>post_url<span class="token punctuation">,</span> headers<span class="token operator">=</span>self<span class="token punctuation">.</span>headers1<span class="token punctuation">)</span>    <span class="token keyword">def</span> <span class="token function">view_page</span><span class="token punctuation">(</span>self<span class="token punctuation">,</span>page<span class="token punctuation">)</span><span class="token punctuation">:</span>        headers<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'Cookie'</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true">#这个也不能告诉你吧}</span>        result<span class="token operator">=</span>self<span class="token punctuation">.</span>session<span class="token punctuation">.</span>get<span class="token punctuation">(</span>self<span class="token punctuation">.</span>content<span class="token punctuation">[</span>page<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">'url'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> headers<span class="token operator">=</span>headers<span class="token punctuation">)</span><span class="token punctuation">.</span>content<span class="token punctuation">.</span>decode<span class="token punctuation">(</span><span class="token string">"utf-8"</span><span class="token punctuation">)</span>        <span class="token keyword">return</span> result<span class="token keyword">def</span> <span class="token function">get_data</span><span class="token punctuation">(</span>page<span class="token punctuation">)</span><span class="token punctuation">:</span>          <span class="token comment" spellcheck="true">#下载某一课程的资源</span>    code<span class="token operator">=</span>login<span class="token punctuation">.</span>view_page<span class="token punctuation">(</span>page<span class="token punctuation">)</span>    soup <span class="token operator">=</span> BeautifulSoup<span class="token punctuation">(</span>code<span class="token punctuation">,</span> <span class="token string">'lxml'</span><span class="token punctuation">)</span>    token <span class="token operator">=</span> soup<span class="token punctuation">.</span>find<span class="token punctuation">(</span>attrs<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'class'</span><span class="token punctuation">:</span> <span class="token string">'bd'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span>contents    introduction<span class="token operator">=</span>re<span class="token punctuation">.</span>sub<span class="token punctuation">(</span><span class="token string">'&lt;[^&lt;]+?>'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> str<span class="token punctuation">(</span>token<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>replace<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>    dagang<span class="token operator">=</span>re<span class="token punctuation">.</span>sub<span class="token punctuation">(</span><span class="token string">'&lt;[^&lt;]+?>'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> str<span class="token punctuation">(</span>token<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>replace<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>    ziyuan<span class="token operator">=</span>token<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span>    teacher_info<span class="token operator">=</span>re<span class="token punctuation">.</span>sub<span class="token punctuation">(</span><span class="token string">'&lt;[^&lt;]+?>'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">,</span> str<span class="token punctuation">(</span>token<span class="token punctuation">[</span><span class="token number">7</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>replace<span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">,</span> <span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">.</span>strip<span class="token punctuation">(</span><span class="token punctuation">)</span>    file_name<span class="token operator">=</span>validateTitle<span class="token punctuation">(</span>login<span class="token punctuation">.</span>content<span class="token punctuation">[</span>page<span class="token punctuation">]</span><span class="token punctuation">[</span><span class="token string">"Title"</span><span class="token punctuation">]</span><span class="token punctuation">)</span>    folder_path <span class="token operator">=</span> <span class="token string">"E:/course_data/"</span> <span class="token operator">+</span> file_name <span class="token operator">+</span> <span class="token string">"/"</span>    <span class="token keyword">if</span> str<span class="token punctuation">(</span>ziyuan<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token string">'&lt;div>无&lt;/div>'</span><span class="token punctuation">:</span>        folder_path<span class="token operator">=</span><span class="token string">"E:/course_data/"</span> <span class="token operator">+</span> file_name <span class="token operator">+</span><span class="token string">"（无课件）"</span><span class="token operator">+</span><span class="token string">"/"</span>    <span class="token keyword">if</span> <span class="token operator">not</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span>folder_path<span class="token punctuation">)</span> <span class="token punctuation">:</span>        os<span class="token punctuation">.</span>makedirs<span class="token punctuation">(</span>folder_path<span class="token punctuation">)</span>    os<span class="token punctuation">.</span>chdir<span class="token punctuation">(</span>folder_path<span class="token punctuation">)</span>    <span class="token keyword">with</span> open<span class="token punctuation">(</span>file_name<span class="token operator">+</span><span class="token string">'.txt'</span><span class="token punctuation">,</span> <span class="token string">'w+'</span><span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span> <span class="token keyword">as</span> f<span class="token punctuation">:</span>  <span class="token comment" spellcheck="true"># 课程信息写入</span>        f<span class="token punctuation">.</span>write<span class="token punctuation">(</span>introduction<span class="token operator">+</span><span class="token string">'\n\n'</span><span class="token operator">+</span>dagang<span class="token operator">+</span><span class="token string">'\n\n'</span><span class="token operator">+</span>teacher_info<span class="token punctuation">)</span>        f<span class="token punctuation">.</span>close<span class="token punctuation">(</span><span class="token punctuation">)</span>    pattern <span class="token operator">=</span> re<span class="token punctuation">.</span>compile<span class="token punctuation">(</span><span class="token string">'.*?&lt;a href="(.*?)">(.*?)&lt;/a>'</span><span class="token punctuation">,</span> re<span class="token punctuation">.</span>S<span class="token punctuation">)</span>  <span class="token comment" spellcheck="true"># re.S: .能匹配换行</span>    downloadurl <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span>pattern<span class="token punctuation">,</span> str<span class="token punctuation">(</span>ziyuan<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">print</span><span class="token punctuation">(</span>file_name<span class="token punctuation">)</span>    <span class="token keyword">print</span><span class="token punctuation">(</span>downloadurl<span class="token punctuation">)</span>    <span class="token keyword">if</span> <span class="token operator">not</span> re<span class="token punctuation">.</span>search<span class="token punctuation">(</span><span class="token string">'请先登录后再查看资源！'</span><span class="token punctuation">,</span> str<span class="token punctuation">(</span>downloadurl<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">==</span>None<span class="token punctuation">:</span>        login<span class="token punctuation">.</span>login<span class="token punctuation">(</span>email<span class="token operator">=</span><span class="token string">'#输入你的账号'</span><span class="token punctuation">,</span> password<span class="token operator">=</span><span class="token string">'#输入密码'</span><span class="token punctuation">)</span>        login<span class="token punctuation">.</span>logincourse<span class="token punctuation">(</span><span class="token punctuation">)</span>        code <span class="token operator">=</span> login<span class="token punctuation">.</span>view_page<span class="token punctuation">(</span>page<span class="token punctuation">)</span>        soup <span class="token operator">=</span> BeautifulSoup<span class="token punctuation">(</span>code<span class="token punctuation">,</span> <span class="token string">'lxml'</span><span class="token punctuation">)</span>        token <span class="token operator">=</span> soup<span class="token punctuation">.</span>find<span class="token punctuation">(</span>attrs<span class="token operator">=</span><span class="token punctuation">{</span><span class="token string">'class'</span><span class="token punctuation">:</span> <span class="token string">'bd'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span>contents        ziyuan <span class="token operator">=</span> token<span class="token punctuation">[</span><span class="token number">5</span><span class="token punctuation">]</span>        downloadurl <span class="token operator">=</span> re<span class="token punctuation">.</span>findall<span class="token punctuation">(</span>pattern<span class="token punctuation">,</span> str<span class="token punctuation">(</span>ziyuan<span class="token punctuation">)</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> file <span class="token keyword">in</span> downloadurl<span class="token punctuation">:</span>        <span class="token keyword">try</span><span class="token punctuation">:</span>            r <span class="token operator">=</span> login<span class="token punctuation">.</span>session<span class="token punctuation">.</span>get<span class="token punctuation">(</span>file<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">)</span>        <span class="token keyword">except</span><span class="token punctuation">:</span>            <span class="token keyword">continue</span>        <span class="token keyword">if</span> os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>exists<span class="token punctuation">(</span>file<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token operator">==</span><span class="token boolean">False</span><span class="token punctuation">:</span>            <span class="token keyword">try</span><span class="token punctuation">:</span>                <span class="token keyword">with</span> open<span class="token punctuation">(</span>validateTitle<span class="token punctuation">(</span>file<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"wb"</span><span class="token punctuation">)</span> <span class="token keyword">as</span> code<span class="token punctuation">:</span>                    code<span class="token punctuation">.</span>write<span class="token punctuation">(</span>r<span class="token punctuation">.</span>content<span class="token punctuation">)</span>                    <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"dowload over:"</span><span class="token operator">+</span>file<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span>            <span class="token keyword">except</span><span class="token punctuation">:</span>                <span class="token keyword">continue</span><span class="token keyword">def</span> <span class="token function">validateTitle</span><span class="token punctuation">(</span>title<span class="token punctuation">)</span><span class="token punctuation">:</span>   <span class="token comment" spellcheck="true">#  规范奇葩的文件名和课程名！</span>    rstr <span class="token operator">=</span> r<span class="token string">'[(\s* )(/)(\\)(\:)(\*)(\?)(\")(\&lt;)(\>)(\|)]'</span>  <span class="token comment" spellcheck="true"># '/ \ : * ? " &lt; > |'</span>    new_title <span class="token operator">=</span> re<span class="token punctuation">.</span>sub<span class="token punctuation">(</span>rstr<span class="token punctuation">,</span> <span class="token string">"_"</span><span class="token punctuation">,</span> title<span class="token punctuation">)</span>  <span class="token comment" spellcheck="true"># 替换为下划线</span>    <span class="token keyword">return</span> new_title<span class="token keyword">if</span> __name__ <span class="token operator">==</span> <span class="token string">"__main__"</span><span class="token punctuation">:</span> <span class="token comment" spellcheck="true">#主程序</span>    login <span class="token operator">=</span> Login<span class="token punctuation">(</span><span class="token punctuation">)</span>    login<span class="token punctuation">.</span>login<span class="token punctuation">(</span>email<span class="token operator">=</span><span class="token string">'#输入你的账号'</span><span class="token punctuation">,</span> password<span class="token operator">=</span><span class="token string">'#输入密码'</span><span class="token punctuation">)</span>    login<span class="token punctuation">.</span>logincourse<span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token keyword">for</span> i <span class="token keyword">in</span> range<span class="token punctuation">(</span><span class="token comment" spellcheck="true">#起始下载项,#看你想下载多少):</span>        get_data<span class="token punctuation">(</span>i<span class="token punctuation">)</span>        <span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">'下载完毕'</span><span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><h3 id="几点说明">3.3.3&emsp;几点说明</h3><ul><li>requests.Session()用来维持一次登录，这个很重要，不然每次都是相互独立的请求；</li><li>validateTitle是我后来加的，程序各种报错发现是一些课程名竟然有些./\符号；</li><li>我用的是<a href="http://www.runoob.com/regexp/regexp-syntax.html" target="_blank" rel="noopener">正则表达式</a>，强烈推荐学习，让你的搜索能力一夜猛增；</li><li>写了能用我就懒得改了，改是肯定有很多地方能改清晰简洁点的；</li><li>判断的地方有待完善，运行太长时有时还是会出现“请先登录后再查看资源”提示</li></ul><h1 id="总结">4&emsp;总结</h1><p>学习爬虫中的第一个小练习，也是第一篇有点内容的博客，以后有空会进一步学习下验证码的识别、app的爬取、分布式爬虫等知识，时间有限，下一个练习不知道啥时才能做完- -    博客坚持2周一篇，这几天花的时间多了点。</p>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-03-21-python-pa-chong-ru-men-lian-xi/#disqus_thread</comments>
    </item>
    
    <item>
      <title>Welcome to CP Zhao&#39;s Blog</title>
      <link>https://chengpengzhao.com/2019-03-18-hello-world/</link>
      <guid>https://chengpengzhao.com/2019-03-18-hello-world/</guid>
      <pubDate>Mon, 18 Mar 2019 00:00:00 GMT</pubDate>
      <description>
      
        
        
          
          
            &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css&quot;&gt;&lt;h1 id=&quot;总算把博客建的差不多了&quot;&gt;1&amp;emsp;总算把博客建的差不多了!&lt;
          
        
      
      </description>
      
      
      <content:encoded><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><h1 id="总算把博客建的差不多了">1&emsp;总算把博客建的差不多了!</h1><p>&emsp;&emsp;作为一个非计算机专业的萌新来说，自己搭一个博客真的是一个痛苦的过程，面对一排排的html代码还有json、css文件，简直不知道该干嘛，说实话我现在想改个字体大小都找不到地方，凑合着就这样吧。</p><p>&emsp;&emsp;我用的是Github Page加Hugo的方式，并且注册了一个自己的域名<del>用来装b</del>，之后我会详细的介绍博客建立的过程以及需要的相关知识，让更多的非程序员能够更方便的拥有一个属于自己的Blog。</p><h1 id="Why-I’m-writing-a-Blog">2&emsp;Why I’m writing a Blog</h1><p>&emsp;&emsp;为什么要写博客？我一开始也抱有这个问题，明明是个很浪费时间的事情，但是还是有那么多程序员去做了，而且做的很好，让人一眼就觉得这是个<del>会装b</del>优秀的程序员，所以我决定也尝试一下，当然简单一点用CSDN博客、简书、博客园这些平台也不错，但还是自己搭建的比较有成就感，于是开始了漫无止境的踩坑爬坑之旅。<br>&emsp;&emsp;然后就是博客很容易体现一个人的价值观，帮助对方了解自己的观点、帮助自己有条理的表达观点，毕竟书写是为了更多的思考；当然博客也能逼自己去学习，刚开始写博客可能有很多想说的，但如果停止了学习，就会发现能写出来的东西越来越少，如果说逼自己一下例如7天写一篇blog，那么无形中自己就会坚持去学点东西，去思考怎样表达的更清楚。</p><p> &emsp;&emsp;最后引用下不知道哪看到的一段话作为结尾吧：</p><blockquote><p>Do you know where the word “blog” comes from?<br>It’s the elision of the words Web and log, referring to the World Wide Web (the Internet) and a log book, originally a daily written record of a sailing ship’s progress, so called because wooden floats were used to measure a ship’s speed.<br>      So you can see this blog as a sort of measure of our progress toward the mystical land of universal language access, if you like. Or, I suppose, you can see it as a chunk of wood caught in a spider’s web.<br>      Either way, I hope it will be useful to you.</p></blockquote>]]></content:encoded>
      
      <comments>https://chengpengzhao.com/2019-03-18-hello-world/#disqus_thread</comments>
    </item>
    
  </channel>
</rss>
