<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="/css/rss.css" ?>
<rss version="2.0"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>荷塘月色的博客</title>
    <link>https://www.yansheng.fun/</link>
    
	<script xmlns="http://www.w3.org/1999/xhtml" src="/js/rss.js"></script>

    <atom:link href="/rss2.xml" rel="self" type="application/rss+xml"/>
    
    <description>生活不止漫无天日的代码和bug，还有诗和远方。</description>
    <pubDate>Sun, 04 Jun 2023 18:07:57 GMT</pubDate>
    <generator>http://hexo.io/</generator>
    
    <item>
      <title>Python版雪花算法生成唯一ID</title>
      <link>https://www.yansheng.fun/article/5a542ac.html</link>
      <guid>https://www.yansheng.fun/article/5a542ac.html</guid>
      <pubDate>Sun, 28 May 2023 17:54:30 GMT</pubDate>
      <description>
      
        &lt;h2 id=&quot;一-雪花算法图解&quot;&gt;一、雪花算法图解&lt;/h2&gt;
&lt;p&gt;理论一大堆，总结如下图：&lt;br&gt;
&lt;img src=&quot;https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/20200826115308653.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaWZlaXllY2h1YW4=,size_16,color_FFFFFF,t_70#pic_center&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;br&gt;
下方为源码，返回的结果为19位，为10进制表示，使用二进制表示就是64位，所以不必有所疑惑。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<h2 id="一-雪花算法图解">一、雪花算法图解</h2><p>理论一大堆，总结如下图：<br><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/20200826115308653.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZlaWZlaXllY2h1YW4=,size_16,color_FFFFFF,t_70#pic_center" alt="在这里插入图片描述"><br>下方为源码，返回的结果为19位，为10进制表示，使用二进制表示就是64位，所以不必有所疑惑。</p><a id="more"></a><h2 id="二-源码">二、源码</h2><h4 id="1-异常捕获块">1、异常捕获块</h4><p>文件名：<a href="http://exceptions.py" target="_blank" rel="noopener">exceptions.py</a></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">InvalidSystemClock</span><span class="params">(Exception)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    时钟回拨异常</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line">    <span class="keyword">pass</span></span><br></pre></td></tr></table></figure><h4 id="2-唯一id生成块">2、唯一id生成块</h4><p>文件名：<a href="http://xuehuaid.py" target="_blank" rel="noopener">xuehuaid.py</a></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Twitter's Snowflake algorithm implementation which is used to generate distributed IDs.</span></span><br><span class="line"><span class="comment"># https://github.com/twitter-archive/snowflake/blob/snowflake-2010/src/main/scala/com/twitter/service/snowflake/IdWorker.scala</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> logging</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> .exceptions <span class="keyword">import</span> InvalidSystemClock</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 64位ID的划分</span></span><br><span class="line">WORKER_ID_BITS = <span class="number">5</span></span><br><span class="line">DATACENTER_ID_BITS = <span class="number">5</span></span><br><span class="line">SEQUENCE_BITS = <span class="number">12</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 最大取值计算</span></span><br><span class="line">MAX_WORKER_ID = <span class="number">-1</span> ^ (<span class="number">-1</span> &lt;&lt; WORKER_ID_BITS)  <span class="comment"># 2**5-1 0b11111</span></span><br><span class="line">MAX_DATACENTER_ID = <span class="number">-1</span> ^ (<span class="number">-1</span> &lt;&lt; DATACENTER_ID_BITS)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 移位偏移计算</span></span><br><span class="line">WOKER_ID_SHIFT = SEQUENCE_BITS</span><br><span class="line">DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS</span><br><span class="line">TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS</span><br><span class="line"></span><br><span class="line"><span class="comment"># 序号循环掩码</span></span><br><span class="line">SEQUENCE_MASK = <span class="number">-1</span> ^ (<span class="number">-1</span> &lt;&lt; SEQUENCE_BITS)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Twitter元年时间戳</span></span><br><span class="line">TWEPOCH = <span class="number">1288834974657</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">logger = logging.getLogger(<span class="string">'flask.app'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">IdWorker</span><span class="params">(object)</span>:</span></span><br><span class="line">    <span class="string">"""</span></span><br><span class="line"><span class="string">    用于生成IDs</span></span><br><span class="line"><span class="string">    """</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, datacenter_id, worker_id, sequence=<span class="number">0</span>)</span>:</span></span><br><span class="line">        <span class="string">"""</span></span><br><span class="line"><span class="string">        初始化</span></span><br><span class="line"><span class="string">        :param datacenter_id: 数据中心（机器区域）ID</span></span><br><span class="line"><span class="string">        :param worker_id: 机器ID</span></span><br><span class="line"><span class="string">        :param sequence: 其实序号</span></span><br><span class="line"><span class="string">        """</span></span><br><span class="line">        <span class="comment"># sanity check</span></span><br><span class="line">        <span class="keyword">if</span> worker_id &gt; MAX_WORKER_ID <span class="keyword">or</span> worker_id &lt; <span class="number">0</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">'worker_id值越界'</span>)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> datacenter_id &gt; MAX_DATACENTER_ID <span class="keyword">or</span> datacenter_id &lt; <span class="number">0</span>:</span><br><span class="line">            <span class="keyword">raise</span> ValueError(<span class="string">'datacenter_id值越界'</span>)</span><br><span class="line"></span><br><span class="line">        self.worker_id = worker_id</span><br><span class="line">        self.datacenter_id = datacenter_id</span><br><span class="line">        self.sequence = sequence</span><br><span class="line"></span><br><span class="line">        self.last_timestamp = <span class="number">-1</span>  <span class="comment"># 上次计算的时间戳</span></span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_gen_timestamp</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="string">"""</span></span><br><span class="line"><span class="string">        生成整数时间戳</span></span><br><span class="line"><span class="string">        :return:int timestamp</span></span><br><span class="line"><span class="string">        """</span></span><br><span class="line">        <span class="keyword">return</span> int(time.time() * <span class="number">1000</span>)</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">get_id</span><span class="params">(self)</span>:</span></span><br><span class="line">        <span class="string">"""</span></span><br><span class="line"><span class="string">        获取新ID</span></span><br><span class="line"><span class="string">        :return:</span></span><br><span class="line"><span class="string">        """</span></span><br><span class="line">        timestamp = self._gen_timestamp()</span><br><span class="line"></span><br><span class="line">        <span class="comment"># 时钟回拨</span></span><br><span class="line">        <span class="keyword">if</span> timestamp &lt; self.last_timestamp:</span><br><span class="line">            logging.error(<span class="string">'clock is moving backwards. Rejecting requests until &#123;&#125;'</span>.format(self.last_timestamp))</span><br><span class="line">            <span class="keyword">raise</span> InvalidSystemClock</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> timestamp == self.last_timestamp:</span><br><span class="line">            self.sequence = (self.sequence + <span class="number">1</span>) &amp; SEQUENCE_MASK</span><br><span class="line">            <span class="keyword">if</span> self.sequence == <span class="number">0</span>:</span><br><span class="line">                timestamp = self._til_next_millis(self.last_timestamp)</span><br><span class="line">        <span class="keyword">else</span>:</span><br><span class="line">            self.sequence = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">        self.last_timestamp = timestamp</span><br><span class="line"></span><br><span class="line">        new_id = ((timestamp - TWEPOCH) &lt;&lt; TIMESTAMP_LEFT_SHIFT) | (self.datacenter_id &lt;&lt; DATACENTER_ID_SHIFT) | \</span><br><span class="line">                 (self.worker_id &lt;&lt; WOKER_ID_SHIFT) | self.sequence</span><br><span class="line">        <span class="keyword">return</span> new_id</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">_til_next_millis</span><span class="params">(self, last_timestamp)</span>:</span></span><br><span class="line">        <span class="string">"""</span></span><br><span class="line"><span class="string">        等到下一毫秒</span></span><br><span class="line"><span class="string">        """</span></span><br><span class="line">        timestamp = self._gen_timestamp()</span><br><span class="line">        <span class="keyword">while</span> timestamp &lt;= last_timestamp:</span><br><span class="line">            timestamp = self._gen_timestamp()</span><br><span class="line">        <span class="keyword">return</span> timestamp</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line">    worker = IdWorker(<span class="number">1</span>, <span class="number">2</span>, <span class="number">0</span>)</span><br><span class="line">    print(worker.get_id())</span><br></pre></td></tr></table></figure><h2 id="三-python雪花库">三、python雪花库</h2><p>当然，如果不嫌麻烦，可以安装python雪花id生成库，如下：</p><h4 id="1-安装">1、安装</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install pysnowflake</span><br></pre></td></tr></table></figure><h4 id="2-启动">2、启动</h4><p>启动pysnowflake —pysnowflake基于Tornado开发，启动时相当于一个服务</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">snowflake_start_server \</span><br><span class="line">--address=0.0.0.0 \</span><br><span class="line">--port=8910 \</span><br><span class="line">--dc=1 \</span><br><span class="line">--worker=1 \</span><br><span class="line">--log_file_prefix=/tmp/pysnowflask.log</span><br></pre></td></tr></table></figure><p>参数说明：可以通过–help查看</p><blockquote><p>—address：本机的IP地址默认localhost<br>—dc：数据中心唯一标识符默认为0<br>—worker：工作者唯一标识符默认为0<br>—log_file_prefix：日志文件所在位置</p></blockquote><p>也可以后台启动，如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nohup snowflake_start_server --address=127.0.0.1 --port=8910 --dc=1 --worker=1 --log_file_prefix=/tmp/pysnowflask.log&gt;/dev/null &amp;</span><br></pre></td></tr></table></figure><h4 id="3-获取id">3、获取id</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> snowflake.client</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_snowflake_uuid</span><span class="params">()</span>:</span></span><br><span class="line">    guid = snowflake.client.get_guid()</span><br><span class="line">    <span class="keyword">return</span> guid</span><br><span class="line">get_snowflake_uuid()</span><br></pre></td></tr></table></figure><hr><p>转自：<a href="https://blog.csdn.net/feifeiyechuan/article/details/108236261" target="_blank" rel="noopener">https://blog.csdn.net/feifeiyechuan/article/details/108236261</a></p><p><a href="https://blog.csdn.net/LAM1006_csdn/article/details/122873748" target="_blank" rel="noopener">https://blog.csdn.net/LAM1006_csdn/article/details/122873748</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/5a542ac.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>解决PyCharm缓存文件过大问题</title>
      <link>https://www.yansheng.fun/article/2cebf237.html</link>
      <guid>https://www.yansheng.fun/article/2cebf237.html</guid>
      <pubDate>Sat, 20 May 2023 16:52:32 GMT</pubDate>
      <description>
      
        &lt;p&gt;使用pycharm一段时间后 ，C盘空间也越来越小。这是因为pycharm在C盘生成了大量的缓存文件。解决C盘占用过大，有两个方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;方法一：直接删除pycharm缓存文件（暴力有效）&lt;/li&gt;
&lt;li&gt;方法二：更改缓存文件路径&lt;/li&gt;
&lt;/ol&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>使用pycharm一段时间后 ，C盘空间也越来越小。这是因为pycharm在C盘生成了大量的缓存文件。解决C盘占用过大，有两个方法：</p><ol><li>方法一：直接删除pycharm缓存文件（暴力有效）</li><li>方法二：更改缓存文件路径</li></ol><a id="more"></a><h2 id="方法一">方法一</h2><p>content.dat.storageData是pycharm的缓存文件，动辄几个G，直接将其删除即可。不会影响pycharm使用。缺点就是每隔一段时间要记得清理，否则C盘可能就要爆炸。</p><p><strong>content.dat.storageData文件</strong>一般存在于C:\Users\xxx.PyCharm2017.2\system\caches\content.dat.storageData路径下。或者C:\Users\Administrator\AppData\Local\JetBrains\PyCharm2020.1\caches\content.dat.storageData路径下。</p><h2 id="方法二">方法二</h2><p>pycharm缓存文件默认存储在C盘，我们可以将缓存文件存储位置更改到其他盘。</p><ol><li><p>找到pycharm安装目录bin文件夹下的idea.properties文件，如<code>E:\pycharm\PyCharm 2019.2.5\bin</code><br><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/2021050400015573.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM5MjIwMzM0,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p></li><li><p>用记事本打开并修改idea.properties文件，我修改好的文件如下</p></li></ol><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Use $&#123;idea.home.path&#125; macro to specify location relative to IDE installation home.</span></span><br><span class="line"><span class="comment"># Use $&#123;xxx&#125; where xxx is any Java property (including defined in previous lines of this file) to refer to its value.</span></span><br><span class="line"><span class="comment"># Note for Windows users: please make sure you're using forward slashes (e.g. c:/idea/system).</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Uncomment this option if you want to customize path to IDE config folder. Make sure you're using forward slashes.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># idea.config.path=$&#123;user.home&#125;/.PyCharm/config</span></span><br><span class="line"><span class="meta">idea.config.path</span>=<span class="string">D:/.PyCharm2019.2/config</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Uncomment this option if you want to customize path to IDE system folder. Make sure you're using forward slashes.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># idea.system.path=$&#123;user.home&#125;/.PyCharm/system</span></span><br><span class="line"><span class="meta">idea.system.path</span>=<span class="string">D:/.PyCharm2019.2/system</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Uncomment this option if you want to customize path to user installed plugins folder. Make sure you're using forward slashes.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># idea.plugins.path=$&#123;idea.config.path&#125;/plugins</span></span><br><span class="line"><span class="meta">idea.plugins.path</span>=<span class="string">D:/.PyCharm2019.2/config/plugins</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Uncomment this option if you want to customize path to IDE logs folder. Make sure you're using forward slashes.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># idea.log.path=$&#123;idea.system.path&#125;/log</span></span><br><span class="line"><span class="meta">idea.log.path</span>=<span class="string">D:/.PyCharm2019.2/system/log</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Maximum file size (kilobytes) IDE should provide code assistance for.</span></span><br><span class="line"><span class="comment"># The larger file is the slower its editor works and higher overall system memory requirements are</span></span><br><span class="line"><span class="comment"># if code assistance is enabled. Remove this property or set to very large number if you need</span></span><br><span class="line"><span class="comment"># code assistance for any files available regardless their size.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.max.intellisense.filesize</span>=<span class="string">2500</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Maximum file size (kilobytes) IDE is able to open.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.max.content.load.filesize</span>=<span class="string">20000</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># This option controls console cyclic buffer: keeps the console output size not higher than the specified buffer size (Kb).</span></span><br><span class="line"><span class="comment"># Older lines are deleted. In order to disable cycle buffer use idea.cycle.buffer.size=disabled</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.cycle.buffer.size</span>=<span class="string">1024</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Configure if a special launcher should be used when running processes from within IDE.</span></span><br><span class="line"><span class="comment"># Using Launcher enables "soft exit" and "thread dump" features</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.no.launcher</span>=<span class="string">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># To avoid too long classpath</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.dynamic.classpath</span>=<span class="string">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Uncomment this property to prevent IDE from throwing ProcessCanceledException when user activity</span></span><br><span class="line"><span class="comment"># detected. This option is only useful for plugin developers, while debugging PSI related activities</span></span><br><span class="line"><span class="comment"># performed in background error analysis thread.</span></span><br><span class="line"><span class="comment"># DO NOT UNCOMMENT THIS UNLESS YOU'RE DEBUGGING IDE ITSELF. Significant slowdowns and lockups will happen otherwise.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#idea.ProcessCanceledException=disabled</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># There are two possible values of idea.popup.weight property: "heavy" and "medium".</span></span><br><span class="line"><span class="comment"># If you have WM configured as "Focus follows mouse with Auto Raise" then you have to</span></span><br><span class="line"><span class="comment"># set this property to "medium". It prevents problems with popup menus on some</span></span><br><span class="line"><span class="comment"># configurations.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.popup.weight</span>=<span class="string">heavy</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Removing this property may lead to editor performance degradation under Windows.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">sun.java2d.d3d</span>=<span class="string">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Set swing.bufferPerWindow=false to workaround a slow scrolling in JDK6 (see IDEA-35883),</span></span><br><span class="line"><span class="comment"># But this may lead to performance degradation in JDK8, because it disables a double buffering,</span></span><br><span class="line"><span class="comment"># which is needed to eliminate tearing on blit-accelerated scrolling and to restore</span></span><br><span class="line"><span class="comment"># a frame buffer content without the usual repainting, even when the EDT is blocked.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">swing.bufferPerWindow</span>=<span class="string">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Removing this property may lead to editor performance degradation under X Window.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">sun.java2d.pmoffscreen</span>=<span class="string">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Enables HiDPI support in JBRE</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">sun.java2d.uiScale.enabled</span>=<span class="string">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Applicable to the Swing text components displaying HTML (except JEditorPane).</span></span><br><span class="line"><span class="comment"># Rebases CSS size map depending on the component's font size to let relative</span></span><br><span class="line"><span class="comment"># font size values (smaller, larger) scale properly. JBRE only.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">javax.swing.rebaseCssSizeMap</span>=<span class="string">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Workaround to avoid long hangs while accessing clipboard under Mac OS X.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#ide.mac.useNativeClipboard=True</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Maximum size (kilobytes) IDEA will load for showing past file contents -</span></span><br><span class="line"><span class="comment"># in Show Diff or when calculating Digest Diff</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#idea.max.vcs.loaded.size.kb=20480</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># IDEA file chooser peeks inside directories to detect whether they contain a valid project</span></span><br><span class="line"><span class="comment"># (to mark such directories with a corresponding icon).</span></span><br><span class="line"><span class="comment"># Uncommenting the option prevents this behavior outside of user home directory.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#idea.chooser.lookup.for.project.dirs=false</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#-----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Experimental option that does a number of things to make truly smooth scrolling possible:</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Enables hardware-accelerated scrolling.</span></span><br><span class="line"><span class="comment">#     Blit-acceleration copies as much of the rendered area as possible and then repaints only newly exposed region.</span></span><br><span class="line"><span class="comment">#     This helps to improve scrolling performance and to reduce CPU usage (especially if drawing is compute-intensive).</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Enables "true double buffering".</span></span><br><span class="line"><span class="comment">#     True double buffering is needed to eliminate tearing on blit-accelerated scrolling and to restore</span></span><br><span class="line"><span class="comment">#     frame buffer content without the usual repainting, even when the EDT is blocked.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Adds "idea.true.smooth.scrolling.debug" option.</span></span><br><span class="line"><span class="comment">#     Checks whether blit-accelerated scrolling is feasible, and if so, checks whether true double buffering is available.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Enables handling of high-precision mouse wheel events.</span></span><br><span class="line"><span class="comment">#     Although Java 7 introduced MouseWheelEven.getPreciseWheelRotation() method, JScrollPane doesn't use it so far.</span></span><br><span class="line"><span class="comment">#     Depends on the Editor / General / Smooth Scrolling setting, remote desktop detection and power save mode state.</span></span><br><span class="line"><span class="comment">#     Ideally, we need to patch the runtime (on Windows, Linux and Mac OS) to improve handling of the fine-grained input data.</span></span><br><span class="line"><span class="comment">#     This feature can be toggled via "idea.true.smooth.scrolling.high.precision" option.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Enables handling of pixel-perfect scrolling events.</span></span><br><span class="line"><span class="comment">#     Currently this mode is available only under Mac OS with JetBrains Runtime.</span></span><br><span class="line"><span class="comment">#     This feature can be toggled via "idea.true.smooth.scrolling.pixel.perfect" option.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Enables interpolation of scrolling input (scrollbar, mouse wheel, touchpad, keys, etc).</span></span><br><span class="line"><span class="comment">#     Smooths input which lacks both spatial and temporal resolution, performs the rendering asynchronously.</span></span><br><span class="line"><span class="comment">#     Depends on the Editor / General / Smooth Scrolling setting, remote desktop detection and power save mode state.</span></span><br><span class="line"><span class="comment">#     The feature can be tweaked using the following options:</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation" - the main switch</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.scrollbar" - scrollbar interpolation</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.scrollbar.delay" - initial delay for scrollbar interpolation (ms)</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.mouse.wheel" - mouse wheel / touchpad interpolation</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.mouse.wheel.delay.min" - minimum initial delay for mouse wheel interpolation (ms)</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.mouse.wheel.delay.max" - maximum initial delay for mouse wheel interpolation (ms)</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.precision.touchpad" - precision touchpad interpolation</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.precision.touchpad.delay" - initial delay for precision touchpad interpolation (ms)</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.other" - interpolation of other input sources</span></span><br><span class="line"><span class="comment">#       "idea.true.smooth.scrolling.interpolation.other.delay" - initial delay for other input source interpolation (ms)</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># * Adds on-demand horizontal scrollbar in editor.</span></span><br><span class="line"><span class="comment">#     The horizontal scrollbar is shown only when it's actually needed for currently visible content.</span></span><br><span class="line"><span class="comment">#     This helps to save editor space and to prevent occasional horizontal "jitter" on vertical touchpad scrolling.</span></span><br><span class="line"><span class="comment">#     This feature can be toggled via "idea.true.smooth.scrolling.dynamic.scrollbars" option.</span></span><br><span class="line"><span class="comment">#-----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment">#idea.true.smooth.scrolling=true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># IDE can copy library .jar files to prevent their locking. Set this property to 'false' to enable copying.</span></span><br><span class="line"><span class="comment">#---------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.jars.nocopy</span>=<span class="string">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#-----------------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Change to 'enabled' if you want to receive instant visual notifications</span></span><br><span class="line"><span class="comment"># about fatal errors that happen to an IDE or plugins installed.</span></span><br><span class="line"><span class="comment">#-----------------------------------------------------------------------</span></span><br><span class="line"><span class="meta">idea.fatal.error.notification</span>=<span class="string">disabled</span></span><br></pre></td></tr></table></figure><p>我们需要对以下4个位置进行修改，将原有路径用 # 号注释掉（默认是注释掉的），添加自定义的路径（将缓存文件位置设置为你指定的盘）</p><ul><li>修改config路径</li></ul><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># idea.config.path=$&#123;user.home&#125;/.PyCharm/config</span></span><br><span class="line"><span class="meta">idea.config.path</span>=<span class="string">D:/.PyCharm2019.2/config</span></span><br></pre></td></tr></table></figure><ul><li>修改system路径</li></ul><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># idea.system.path=$&#123;user.home&#125;/.PyCharm/system</span></span><br><span class="line"><span class="meta">idea.system.path</span>=<span class="string">D:/.PyCharm2019.2/system</span></span><br></pre></td></tr></table></figure><ul><li>修改plugins路径</li></ul><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># idea.plugins.path=$&#123;idea.config.path&#125;/plugins</span></span><br><span class="line"><span class="meta">idea.plugins.path</span>=<span class="string">D:/.PyCharm2019.2/config/plugins</span></span><br></pre></td></tr></table></figure><ul><li>修改log路径</li></ul><figure class="highlight properties"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># idea.log.path=$&#123;idea.system.path&#125;/log</span></span><br><span class="line"><span class="meta">idea.log.path</span>=<span class="string">D:/.PyCharm2019.2/system/log</span></span><br></pre></td></tr></table></figure><ol><li>将c盘的缓存文件<code>.PyCharm2019.2</code>剪切到你指定的盘（此处是D盘）。注意此处位置与步骤2中文件路径配置的一致性。</li><li>重启pycharm<br>注意：可能会提示重新激活pycharm。激活可以参考<br><a href="https://www.cnblogs.com/linybo/p/10368315.html" target="_blank" rel="noopener">https://www.cnblogs.com/linybo/p/10368315.html</a></li></ol>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/2cebf237.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Python解决“argument after  must be an iterable”报错</title>
      <link>https://www.yansheng.fun/article/b955235.html</link>
      <guid>https://www.yansheng.fun/article/b955235.html</guid>
      <pubDate>Thu, 18 May 2023 18:30:01 GMT</pubDate>
      <description>
      
        &lt;p&gt;Python解决“argument after  must be an iterable”报错&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>Python解决“argument after  must be an iterable”报错</p><a id="more"></a><p>使用threading.Thread创建线程时报了“argument after * must be an iterable”这样的一个错误</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">th = threading.Thread(target=executeThread, args=(name))</span><br><span class="line"></span><br><span class="line">th.start()</span><br></pre></td></tr></table></figure><p>这种写法是错误的，args中少了一个逗号</p><p>正确的写法：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">th = threading.Thread(target=executeThread, args=(name,))</span><br><span class="line"></span><br><span class="line">th.start()</span><br></pre></td></tr></table></figure><hr><p>转自：<a href="https://blog.csdn.net/watson2017/article/details/127519231" target="_blank" rel="noopener">https://blog.csdn.net/watson2017/article/details/127519231</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/b955235.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>MySQL快速生成大量测试数据方法（无需编写代码、或存储过程）</title>
      <link>https://www.yansheng.fun/article/b0648873.html</link>
      <guid>https://www.yansheng.fun/article/b0648873.html</guid>
      <pubDate>Wed, 03 May 2023 09:09:52 GMT</pubDate>
      <description>
      
        &lt;p&gt;有时我们需要在数据库中构建大量的基础数据（比如千万级别数据）进行查询操作的性能测试或者 &lt;strong&gt;sql&lt;/strong&gt; 优化。我们通常会采用如下两种方式来创建测试数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;方式一：编写代码，通过代码批量插库&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;方式二：编写存储过程和函数执行&lt;/p&gt;
&lt;p&gt;但这两种方法都略显麻烦，本文使用 &lt;strong&gt;MySQL&lt;/strong&gt; 自带的压力测试工具 &lt;strong&gt;mysqlslap&lt;/strong&gt; 来实现测试数据的构建。如果想要了解 &lt;strong&gt;mysqlslap&lt;/strong&gt; 更详细的用法，可以参考我之前写的文章（&lt;a href=&quot;https://www.hangge.com/blog/cache/detail_3068.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;点击查看&lt;/a&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>有时我们需要在数据库中构建大量的基础数据（比如千万级别数据）进行查询操作的性能测试或者 <strong>sql</strong> 优化。我们通常会采用如下两种方式来创建测试数据：</p><ul><li><p>方式一：编写代码，通过代码批量插库</p></li><li><p>方式二：编写存储过程和函数执行</p><p>但这两种方法都略显麻烦，本文使用 <strong>MySQL</strong> 自带的压力测试工具 <strong>mysqlslap</strong> 来实现测试数据的构建。如果想要了解 <strong>mysqlslap</strong> 更详细的用法，可以参考我之前写的文章（<a href="https://www.hangge.com/blog/cache/detail_3068.html" target="_blank" rel="noopener">点击查看</a>）</p></li></ul><a id="more"></a><h3 id="1-准备工作">1，准备工作</h3><p>假设我们要在 <strong>people</strong> 表里插入 <strong>1</strong> 百万条随机的测试数据，表结构如下：</p><p><a href="https://www.hangge.com/blog/cache/detail_3071.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/fb87edea03036fb105101139e720788e.png" alt="原文:MySQL - 快速生成大量测试数据方法（无需编写代码、或存储过程）"></a></p><h3 id="2-插入数据">2，插入数据</h3><p>（1）我们执行如下命令实现数据插入，为提高效率这里开启 <strong>10</strong> 个客户端线程同时插入，总共执行 <strong>1</strong> 百万次操作：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --concurrency=10 --number-of-queries=1000000 --create-schema=hangge --query="INSERT INTO people(name,age) VALUES (uuid(), RAND() * 100)"</span><br></pre></td></tr></table></figure><p>（2）执行完毕可以发现总耗时 <strong>208</strong> 秒：</p><p><a href="https://www.hangge.com/blog/cache/detail_3071.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/70c9a7a2f757cb7d097953494e2b2c54.png" alt="原文:MySQL - 快速生成大量测试数据方法（无需编写代码、或存储过程）"></a></p><p>（3）查看数据库，可以发现测试数据已经创建成功：</p><p><a href="https://www.hangge.com/blog/cache/detail_3071.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/ef35d0193a573d7e293441c83e170ee6.png" alt="原文:MySQL - 快速生成大量测试数据方法（无需编写代码、或存储过程）"></a></p><hr><p>原文出自：<a href="https://www.hangge.com/" target="_blank" rel="noopener">www.hangge.com</a> 转载请保留原文链接：<a href="https://www.hangge.com/blog/cache/detail_3071.html" target="_blank" rel="noopener">https://www.hangge.com/blog/cache/detail_3071.html</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/b0648873.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>NGINX一个server监听多个端口</title>
      <link>https://www.yansheng.fun/article/d638cc8b.html</link>
      <guid>https://www.yansheng.fun/article/d638cc8b.html</guid>
      <pubDate>Wed, 03 May 2023 09:09:52 GMT</pubDate>
      <description>
      
        
        
          &lt;p&gt;NGINX一个server监听多个端口&lt;/p&gt;
&lt;figure class=&quot;highlight nginx&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;li
        
      
      </description>
      
      
      <content:encoded><![CDATA[<p>NGINX一个server监听多个端口</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">server</span> &#123;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">9018</span>;</span><br><span class="line">    <span class="attribute">listen</span> <span class="number">9019</span>;</span><br><span class="line">    <span class="attribute">location</span> / &#123;</span><br><span class="line">        <span class="attribute">try_files</span> <span class="variable">$uri</span> <span class="variable">$uri</span>/ /index,html;</span><br><span class="line">        <span class="attribute">root</span> /home/;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/d638cc8b.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>MySQL自带的数据库压力测试工具mysqlslap使用详解</title>
      <link>https://www.yansheng.fun/article/a9ec7224.html</link>
      <guid>https://www.yansheng.fun/article/a9ec7224.html</guid>
      <pubDate>Wed, 03 May 2023 09:07:48 GMT</pubDate>
      <description>
      
        &lt;h3 id=&quot;1-基本介绍&quot;&gt;1，基本介绍&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;mysqlslap&lt;/strong&gt; 是 &lt;strong&gt;MySQL&lt;/strong&gt; 从 &lt;strong&gt;5.1.4&lt;/strong&gt; 版开始官方自带的一个压力测试工具。它通过模拟多个并发客户端访问 &lt;strong&gt;MySQL&lt;/strong&gt; 来执行压力测试，我们通过结果信息可以了解数据库的性能状况。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mysqlslap&lt;/strong&gt; 是系统运维和 &lt;strong&gt;DBA&lt;/strong&gt; 人员应该掌握一些常见的压力测试工具之一，其主要工作场景就是对数据库服务器做基准测试。比如：服务器的硬件资源能够支持多大的访问压力呢？优化了操作系统的内核参数后，是否提升了性能？调整了 &lt;strong&gt;MySQL&lt;/strong&gt; 配置参数后，对性能有多少影响？&lt;/li&gt;
&lt;/ul&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<h3 id="1-基本介绍">1，基本介绍</h3><ul><li><strong>mysqlslap</strong> 是 <strong>MySQL</strong> 从 <strong>5.1.4</strong> 版开始官方自带的一个压力测试工具。它通过模拟多个并发客户端访问 <strong>MySQL</strong> 来执行压力测试，我们通过结果信息可以了解数据库的性能状况。</li><li><strong>mysqlslap</strong> 是系统运维和 <strong>DBA</strong> 人员应该掌握一些常见的压力测试工具之一，其主要工作场景就是对数据库服务器做基准测试。比如：服务器的硬件资源能够支持多大的访问压力呢？优化了操作系统的内核参数后，是否提升了性能？调整了 <strong>MySQL</strong> 配置参数后，对性能有多少影响？</li></ul><a id="more"></a><h3 id="2-简单用法">2，简单用法</h3><p>（1）我们执行如下命令对数据库做一个简单的自动测试，<strong>–auto-generate-sql</strong> 作用是自动生成测试 <strong>SQL</strong>。</p><p><strong>注意</strong>：如果我们没有人为指定测试数据库，则默认是 <strong>mysqlslap</strong>（该数据库会自动创建，测试完毕自动删除）。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --auto-generate-sql</span><br></pre></td></tr></table></figure><p>（2）运行结果如下：</p><ul><li><strong>Average number of seconds to run all queries</strong>：运行所有语句的平均秒数</li><li><strong>Minimum number of seconds to run all queries</strong>：运行所有语句的最小秒数</li><li><strong>Maximum number of seconds to run all queries</strong>：运行所有语句的最大秒数</li><li><strong>Number of clients running queries</strong>：客户端数量</li><li><strong>Average number of queries per client</strong>：每个客户端运行查询的平均数</li></ul><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/8b1fe4695ed4ae4f729f0f43a12ffb6c.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h3 id="3-打印实际的测试过程">3，打印实际的测试过程</h3><p>（1）测试的过程需要生成测试表，插入测试数据，我们可以添加 <strong>–only-print</strong> 来打印实际的测试过程（不会实际执行）：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --auto-generate-sql --only-print</span><br></pre></td></tr></table></figure><p>（2）运行结果如下，可以看到整个测试完成后会自动删除测试库，不会在数据库中留下痕迹。</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/d06a12b608428b66aa0e3fdc8381f3fc.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h3 id="4-添加并发">4，添加并发</h3><p>（1）我们可以添加如下两个参数，模拟并发处理查询请求：</p><ul><li><strong>–concurrency=100</strong>：指定同时有 <strong>100</strong> 个客户端连接</li><li><strong>–number-of-queries=1000</strong>：指定总的测试查询次数（并发客户端数 * 每个客户端的查询次数），这样本样例平均每个客户端查询 <strong>10</strong> 次</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --concurrency=100 --number-of-queries=1000 --auto-generate-sql</span><br></pre></td></tr></table></figure><p>（2）运行结果如下（注意结果是完成 <strong>1000</strong> 次查询的总时间）：</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/aaf952f1282d39f97ead522aaf3207b8.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h3 id="5-重复的次数">5，重复的次数</h3><p>（1）使用 <strong>–iterations</strong> 参数可以设置迭代执行的次数，即重复的次数（相同的测试进行 <strong>N</strong> 次，求一个平均值）。该次数指的是整个步骤的重复次数，包括准备数据、测试 <strong>load</strong>、清理。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --iterations=3 --concurrency=100 --number-of-queries=1000 --auto-generate-sql</span><br></pre></td></tr></table></figure><p>（2）执行结果如下（注意结果是完成 <strong>1000</strong> 次查询的总时间）：</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/23282ffe8a476e177a687c3ab88dfa1d.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h3 id="6-自动生成复杂表">6，自动生成复杂表</h3><p>（1）自动测试时，创建的表结构非常简单，只有两列，实际的产品环境肯定会更复杂，我们可以使用参数指定测试表的列的数量和类型：</p><ul><li><strong>–number-int-cols=5</strong>：指定生成 <strong>5</strong> 个 <strong>int</strong> 类型的列</li><li><strong>–number-char-cols=20</strong>：指定生成 <strong>20</strong> 个 <strong>char</strong> 类型的列</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --number-int-cols=5 --number-char-cols=20 --auto-generate-sql</span><br></pre></td></tr></table></figure><p>（2）执行结果如下：</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/773649f77d0f42822bd2eb858568d82b.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h3 id="7-使用自己的测试库和测试语句">7，使用自己的测试库和测试语句</h3><p>（1）自动测试可以帮助我们了解硬件层面的状况，我们也可以对指定的产品库进行测试：</p><ul><li><strong>–create-schema=hangge</strong>：指定的测试库是 <strong>hangge</strong>（测试完毕不会自动删除）</li><li><strong>–query=“SELECT * FROM people;”</strong>：使用自定义的测试语句</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --concurrency=10 --number-of-queries=100 --create-schema=hangge --query=``"SELECT * FROM people"</span><br></pre></td></tr></table></figure><p>（2）自定义的测试语句可以同时写多条：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --concurrency=10 --number-of-queries=100 --create-schema=hangge --query=``"SELECT * FROM people;SELECT AVG(age) FROM people"</span><br></pre></td></tr></table></figure><p>（3）如果测试多个复杂的语句，我们也可以先把多个查询语句写入了一个 <strong>sql</strong> 文件中，然后使用此文件执行测试：</p><ul><li><strong>–query=“select_query.sql”</strong>：指定了测试文件是 <strong>select_query.sql</strong></li><li><strong>–delimiter=&quot;;&quot;</strong>：指定 <strong>sql</strong> 文件中语句间的分隔符是;</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysqlslap -uroot -pHangge_123 --concurrency=10 --number-of-queries=100 --create-schema=hangge --query=``"select_query.sql"` `--delimiter=``";"</span><br></pre></td></tr></table></figure><h4 id="附一：解决-unknown-variable-default-character-set-utf8-错误">附一：解决“unknown variable ‘default-character-set=utf8’”错误</h4><p>（1）如果我们执行 <strong>mysqlslap</strong> 命令时报如下错误：</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/0dcde0e1fdc2ae77a25a57f8df3fcea8.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><p>（2）解决办法有两种。一种是编辑 <strong>MySQL</strong> 配置文件 <strong>/etc/my.cnf</strong>，将里面如下配置注释掉：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">default-character-set=utf8</span><br></pre></td></tr></table></figure><p>（3）或者我们可以在命令中添加 <strong>–no-defaults</strong> 参数（该参数必须放在第一位），使得本次命令不读取默认配置参数：</p><p><a href="https://www.hangge.com/blog/cache/detail_3068.html#" target="_blank" rel="noopener"><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/img_convert/bc0f891ae9013ce1b4257265b9ee7758.png" alt="原文:mysqlslap - MySQL自带的数据库压力测试工具使用详解（附样例）"></a></p><h4 id="附二：快速生成大量测试数据">附二：快速生成大量测试数据</h4><p>使用 <strong>mysqlslap</strong> 也可以在数据库中构建大量的基础数据（比如千万级别数据）进行查询操作的性能测试或者 <strong>sql</strong> 优化，具体操作可以参考我写的另一篇文章：</p><ul><li><a href="https://www.hangge.com/blog/cache/detail_3071.html" target="_blank" rel="noopener">MySQL - 快速生成大量测试数据方法（无需编写代码、或存储过程）</a></li></ul><hr><p>原文出自：<a href="https://www.hangge.com/" target="_blank" rel="noopener">www.hangge.com</a> 转载请保留原文链接：<a href="https://www.hangge.com/blog/cache/detail_3068.html" target="_blank" rel="noopener">https://www.hangge.com/blog/cache/detail_3068.html</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/a9ec7224.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>MySQL 报错1040 ‘Too many connections‘ 原因及解决方案</title>
      <link>https://www.yansheng.fun/article/f772e40f.html</link>
      <guid>https://www.yansheng.fun/article/f772e40f.html</guid>
      <pubDate>Wed, 03 May 2023 09:00:39 GMT</pubDate>
      <description>
      
        &lt;p&gt;MySQL 报错1040 ‘Too many connections’&lt;/p&gt;
&lt;h3 id=&quot;报错原因&quot;&gt;报错原因&lt;/h3&gt;
&lt;p&gt;实际连接数超过了mysql 允许的最大连接数，访问量过高，MySQL服务器抗不住。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>MySQL 报错1040 ‘Too many connections’</p><h3 id="报错原因">报错原因</h3><p>实际连接数超过了mysql 允许的最大连接数，访问量过高，MySQL服务器抗不住。</p><a id="more"></a><h3 id="解决办法">解决办法</h3><p>1、修改max_connections，如果这个值已经很大，2、这个时候就要考虑增加从服务器分散读压力；<br>Windows 找到mysql.ini（Linux 修改/etc/my.cnf文件，在[mysqld]中新增max_connections=N）。修改允许最大连接数max_connections=N,默认是100 一般设置到500～1000比较合适（这建立在机器能支撑的情况下，因为如果连接数越多，介于MySQL会为每个连接提供连接缓冲区，就会开销越多的内存，所以要适当调整该值，不能盲目提高设值。），最后重启mysql,一定要重启。</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/20210512145520914.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU1ODM3ODMy,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">net stop mysql</span><br><span class="line">net start mysql</span><br></pre></td></tr></table></figure><p>2、临时修改查看最大连接数：</p><p>通配符查看当前状态的连接数量，以定夺该值的大小。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> <span class="keyword">variables</span> <span class="keyword">like</span> <span class="string">"%max_connections%"</span>;</span><br></pre></td></tr></table></figure><p>通配符查看当前状态的连接数量，以定夺该值的大小。</p><p>修改命令：set global max_connections=1000;（重启mysql服务后会失效）</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">show</span> <span class="keyword">global</span> <span class="keyword">status</span> <span class="keyword">like</span> <span class="string">"Max_used_connections"</span>;</span><br></pre></td></tr></table></figure><p>修改命令：set global max_connections=1000;（重启mysql服务后会失效）</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/20210512145647476.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzU1ODM3ODMy,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><hr><p>转自：<a href="https://blog.csdn.net/m0_55837832/article/details/116707242" target="_blank" rel="noopener">https://blog.csdn.net/m0_55837832/article/details/116707242</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/f772e40f.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Grafana修改Dashboard默认时间范围</title>
      <link>https://www.yansheng.fun/article/491976e8.html</link>
      <guid>https://www.yansheng.fun/article/491976e8.html</guid>
      <pubDate>Tue, 02 May 2023 09:58:16 GMT</pubDate>
      <description>
      
        &lt;p&gt;正常我们导入Dashboard后都会有个默认的时间查询条件，我们可以选择不同的区间进行查询，但是如果需要修改默认的时间，就需要保存为模板级别才可以。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>正常我们导入Dashboard后都会有个默认的时间查询条件，我们可以选择不同的区间进行查询，但是如果需要修改默认的时间，就需要保存为模板级别才可以。</p><a id="more"></a><p>1.设置我们需要的时间条件，比如1小时。</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/bb332934377b4bc482ea891c6c313be0.png" alt="在这里插入图片描述"></p><p>2.保存模板</p><p>然后保存模板的时候勾选<code>Save current time range as dashboard default</code>，这样该Dashboard的默认时间就变成最近1小时了。<br><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/31473e2584ca4bb6b86e341fb2b75c95.png" alt="在这里插入图片描述"></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/491976e8.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Grafana常用模板</title>
      <link>https://www.yansheng.fun/article/8eb221b3.html</link>
      <guid>https://www.yansheng.fun/article/8eb221b3.html</guid>
      <pubDate>Sun, 30 Apr 2023 17:19:17 GMT</pubDate>
      <description>
      
        &lt;p&gt;Grafana常用模板&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>Grafana常用模板</p><a id="more"></a><p>1、监控物理机/虚拟机ID（Linux）</p><blockquote><p>8919<br>9276<br>1860</p></blockquote><p>2、监控物理机/虚拟机ID（windows）</p><blockquote><p>10467<br>10171<br>2129</p></blockquote><p>3、监控容器ID</p><blockquote><p>3146<br>8685<br>10000<br>8588<br>315</p></blockquote><p>4、监控数据库ID</p><blockquote><p>7362<br>10101</p></blockquote><p>5、监控网站或者协议端口ID</p><blockquote><p>http监控某个网站<br>icmp监控某台机器<br>tcp监控某个端口<br>dns监控dns<br>9965</p></blockquote><p>Nginx</p><blockquote><p>9614<br>2949</p></blockquote><hr><p>转自：<a href="https://zclinux.blog.csdn.net/article/details/129408105" target="_blank" rel="noopener">https://zclinux.blog.csdn.net/article/details/129408105</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/8eb221b3.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Windows查看端口占用、杀死进程</title>
      <link>https://www.yansheng.fun/article/498c7510.html</link>
      <guid>https://www.yansheng.fun/article/498c7510.html</guid>
      <pubDate>Sun, 30 Apr 2023 17:13:31 GMT</pubDate>
      <description>
      
        
        
          &lt;p&gt;下面的逻辑：&lt;/p&gt;
&lt;p&gt;1.查看9182端口占用哪个进程占用？&lt;br&gt;
2.查看5708进程的内容。&lt;br&gt;
3.杀死5708进程。&lt;/p&gt;
&lt;figure class=&quot;highlight bash&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pr
        
      
      </description>
      
      
      <content:encoded><![CDATA[<p>下面的逻辑：</p><p>1.查看9182端口占用哪个进程占用？<br>2.查看5708进程的内容。<br>3.杀死5708进程。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\Administrator&gt;netstat -ano | findstr 9182</span><br><span class="line">  TCP    0.0.0.0:9182           0.0.0.0:0              LISTENING       5708</span><br><span class="line">  TCP    [::]:9182              [::]:0                 LISTENING       5708</span><br><span class="line"></span><br><span class="line">C:\Users\Administrator&gt;tasklist | findstr 5708</span><br><span class="line">test.exe          5708 Services                   0     19,364 K</span><br><span class="line"></span><br><span class="line">C:\Users\Administrator&gt;taskkill /f /pid 5708</span><br><span class="line">成功: 已终止 PID 为 5708 的进程。</span><br><span class="line"></span><br><span class="line">C:\Users\Administrator&gt;</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/498c7510.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Linux磁盘挂载</title>
      <link>https://www.yansheng.fun/article/d9233db9.html</link>
      <guid>https://www.yansheng.fun/article/d9233db9.html</guid>
      <pubDate>Sun, 30 Apr 2023 13:06:41 GMT</pubDate>
      <description>
      
        &lt;p&gt;Linux系统磁盘一般都是启动+数据盘，这里主要是介绍下数据盘是怎么挂载到系统的。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>Linux系统磁盘一般都是启动+数据盘，这里主要是介绍下数据盘是怎么挂载到系统的。</p><a id="more"></a><h2 id="相关命令">相关命令</h2><p>fdisk -l 查看系统中的磁盘</p><p>mkfs.xfs 格式化磁盘为xfs格式</p><p>mount 将磁盘挂载到已有的目录中</p><p>blkid 查看磁盘id</p><h3 id="注意事项">注意事项</h3><p>如果没有将挂载信息写到 <code>/etc/fstab</code> 文件中，系统重启后挂载会失效！！！即命令行mount是临时性的！！！</p><p>但是实际上数据是没有丢的，重新挂载即可；之后别忘了写 <code>/etc/fstab</code> 文件。</p><h2 id="案例">案例</h2><p>将 <code>/dev/sdb</code> 盘挂载到 <code>/home/data</code> 路径下。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># fdisk -l</span></span><br><span class="line">WARNING: fdisk GPT support is currently new, and therefore <span class="keyword">in</span> an experimental phase. Use at your own discretion.</span><br><span class="line"></span><br><span class="line">磁盘 /dev/sda：107.4 GB, 107374182400 字节，209715200 个扇区</span><br><span class="line">Units = 扇区 of 1 * 512 = 512 bytes</span><br><span class="line">扇区大小(逻辑/物理)：512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳)：512 字节 / 512 字节</span><br><span class="line">磁盘标签类型：gpt</span><br><span class="line">Disk identifier: 2C0D47B2-7A2E-4CCB-AA74-DE89E65271A7</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">#         Start          End    Size  Type            Name</span></span><br><span class="line"> 1         2048       411647    200M  EFI System      EFI System Partition</span><br><span class="line"> 2       411648      2508799      1G  Microsoft basic </span><br><span class="line"> 3      2508800    209713151   98.8G  Linux LVM       </span><br><span class="line"></span><br><span class="line">磁盘 /dev/sdb：859.0 GB, 858993459200 字节，1677721600 个扇区</span><br><span class="line">Units = 扇区 of 1 * 512 = 512 bytes</span><br><span class="line">扇区大小(逻辑/物理)：512 字节 / 512 字节</span><br><span class="line">I/O 大小(最小/最佳)：512 字节 / 512 字节</span><br><span class="line"></span><br><span class="line">……</span><br><span class="line"></span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># mkfs.xfs /dev/sdb</span></span><br><span class="line">Discarding blocks...Done.</span><br><span class="line">meta-data=/dev/sdb               isize=512    agcount=4, agsize=52428800 blks</span><br><span class="line">         =                       sectsz=512   attr=2, projid32bit=1</span><br><span class="line">         =                       crc=1        finobt=0, sparse=0</span><br><span class="line">data     =                       bsize=4096   blocks=209715200, imaxpct=25</span><br><span class="line">         =                       sunit=0      swidth=0 blks</span><br><span class="line">naming   =version 2              bsize=4096   ascii-ci=0 ftype=1</span><br><span class="line"><span class="built_in">log</span>      =internal <span class="built_in">log</span>           bsize=4096   blocks=102400, version=2</span><br><span class="line">         =                       sectsz=512   sunit=0 blks, lazy-count=1</span><br><span class="line">realtime =none                   extsz=4096   blocks=0, rtextents=0</span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># mkdir /home/data</span></span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># mount /dev/sdb /home/data/</span></span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># df -h</span></span><br><span class="line">文件系统                 容量  已用  可用 已用% 挂载点</span><br><span class="line">devtmpfs                  24G     0   24G    0% /dev</span><br><span class="line">tmpfs                     24G     0   24G    0% /dev/shm</span><br><span class="line">tmpfs                     24G     0   24G    0% /sys/fs/cgroup</span><br><span class="line">/dev/sda2               1014M  169M  846M   17% /boot</span><br><span class="line">/dev/mapper/centos-home   39G   33M   39G    1% /home</span><br><span class="line">tmpfs                    4.8G     0  4.8G    0% /run/user/0</span><br><span class="line">/dev/sdb                 800G   33M  800G    1% /home/data</span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># blkid /dev/sdb</span></span><br><span class="line">/dev/sdb: UUID=<span class="string">"37cba98b-2d19-4543-bd71-ba9b132916c"</span> TYPE=<span class="string">"xfs"</span> </span><br><span class="line">[root@This-Address-Is-Forged-70 ~]<span class="comment"># cp /etc/fstab /etc/fstab-20230418</span></span><br><span class="line"></span><br><span class="line">[root@localhost ~]<span class="comment"># </span></span><br><span class="line">cat &gt;&gt; /etc/fstab &lt;&lt; EOF</span><br><span class="line"></span><br><span class="line">UUID=37cba98b-2d19-4543-bd71-ba9b132916c    /home/data    xfs defaults     0 0</span><br><span class="line">EOF</span><br><span class="line"></span><br><span class="line">[root@localhost ~]<span class="comment"># more /etc/fstab</span></span><br><span class="line">……</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/d9233db9.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Linux查看服务器配置</title>
      <link>https://www.yansheng.fun/article/d7720e0.html</link>
      <guid>https://www.yansheng.fun/article/d7720e0.html</guid>
      <pubDate>Sun, 30 Apr 2023 12:51:39 GMT</pubDate>
      <description>
      
        &lt;p&gt;Linux查看服务器配置&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>Linux查看服务器配置</p><a id="more"></a><h2 id="查看linux内核">查看Linux内核</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ lsb_release -a</span><br><span class="line">-bash: lsb_release: 未找到命令</span><br><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ cat /proc/version</span><br><span class="line">Linux version 3.10.0-1160.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Mon Oct 19 16:18:59 UTC 2020</span><br><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ uname -a</span><br><span class="line">Linux This-Address-Is-Forged-44.Lyndale.Mpls.MN.US 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux</span><br><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ cat /etc/redhat-release</span><br><span class="line">CentOS Linux release 7.9.2009 (Core)</span><br><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ cat /etc/issue</span><br><span class="line">\S</span><br><span class="line">Kernel \r on an \m</span><br></pre></td></tr></table></figure><h2 id="查看cpu核心数">查看CPU核心数</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ lscpu</span><br><span class="line">Architecture:          x86_64</span><br><span class="line">CPU op-mode(s):        32-bit, 64-bit</span><br><span class="line">Byte Order:            Little Endian</span><br><span class="line">CPU(s):                8</span><br><span class="line">On-line CPU(s) list:   0-7</span><br><span class="line">Thread(s) per core:    1</span><br><span class="line">Core(s) per socket:    1</span><br><span class="line">座：                 8</span><br><span class="line">NUMA 节点：         1</span><br><span class="line">厂商 ID：           GenuineIntel</span><br><span class="line">CPU 系列：          6</span><br><span class="line">型号：              106</span><br><span class="line">型号名称：        Intel(R) Xeon(R) Gold 5318N CPU @ 2.10GHz</span><br><span class="line">步进：              6</span><br><span class="line">CPU MHz：             205.077</span><br><span class="line">BogoMIPS：            419.15</span><br><span class="line">超管理器厂商：  VMware</span><br><span class="line">虚拟化类型：     完全</span><br><span class="line">L1d 缓存：          48K</span><br><span class="line">L1i 缓存：          32K</span><br><span class="line">L2 缓存：           1280K</span><br><span class="line">L3 缓存：           36864K</span><br><span class="line">NUMA 节点0 CPU：    0-7</span><br><span class="line">Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon rep_good nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 arat avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq md_clear spec_ctrl intel_stibp flush_l1d arch_capabilities</span><br><span class="line">[administrator@This-Address-Is-Forged-44 ~]$</span><br></pre></td></tr></table></figure><h2 id="查看内存">查看内存</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ free -h</span><br><span class="line">              total        used        free      shared  buff/cache   available</span><br><span class="line">Mem:            31G        1.4G         29G         11M        848M         29G</span><br><span class="line">Swap:          5.0G          0B        5.0G</span><br></pre></td></tr></table></figure><h2 id="查看是否开放外网">查看是否开放外网</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[administrator@This-Address-Is-Forged-44 ~]$ curl -l https://www.baidu.com/</span><br><span class="line">…………</span><br></pre></td></tr></table></figure>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/d7720e0.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>C语言正确使用extern关键字</title>
      <link>https://www.yansheng.fun/article/c649d86f.html</link>
      <guid>https://www.yansheng.fun/article/c649d86f.html</guid>
      <pubDate>Sat, 15 Apr 2023 17:58:41 GMT</pubDate>
      <description>
      
        &lt;p&gt;利用关键字extern，可以在一个文件中引用另一个文件中定义的变量或者函数，下面就结合具体的实例，分类说明一下。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>利用关键字extern，可以在一个文件中引用另一个文件中定义的变量或者函数，下面就结合具体的实例，分类说明一下。</p><a id="more"></a><h2 id="一-引用同一个文件中的变量">一、引用同一个文件中的变量</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    func(); <span class="comment">//1</span></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num); <span class="comment">//2</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> num = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,num);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果按照这个顺序，变量 num在main函数的后边进行声明和初始化的话，那么在main函数中是不能直接引用num这个变量的，因为当编译器编译到这一句话的时候，找不到num这个变量的声明，但是在func函数中是可以正常使用，因为func对num的调用是发生在num的声明和初始化之后。</p><p>如果我不想改变num的声明的位置，但是想在main函数中直接使用num这个变量，怎么办呢？可以使用extern这个关键字。像下面这一段代码，利用extern关键字先声明一下num变量，告诉编译器num这个变量是存在的，但是不是在这之前声明的，你到别的地方找找吧，果然，这样就可以顺利通过编译啦。但是你要是想欺骗编译器也是不行的，比如你声明了extern int num；但是在后面却没有真正的给出num变量的声明，那么编译器去别的地方找了，但是没找到还是不行的。</p><p>下面的程序就是利用extern关键字，使用在后边定义的变量。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func</span><span class="params">()</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    func(); <span class="comment">//1</span></span><br><span class="line">    <span class="keyword">extern</span> <span class="keyword">int</span> num;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num); <span class="comment">//2</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> num = <span class="number">3</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,num);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="二-引用另一个文件中的变量">二、引用另一个文件中的变量</h2><p>如果extern这个关键字就这点功能，那么这个关键字就显得多余了，因为上边的程序可以通过将num变量在main函数的上边声明，使得在main函数中也可以使用。<br>extern这个关键字的真正的作用是引用不在同一个文件中的变量或者函数。</p><p>main.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">extern</span> <span class="keyword">int</span> num;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> num = <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"fun in a.c"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>例如，这里b.c中定义了一个变量num，如果main.c中想要引用这个变量，那么可以使用extern这个关键字，注意这里能成功引用的原因是，num这个关键字在b.c中是一个全局变量，也就是说只有当一个变量是一个全局变量时，extern变量才会起作用，向下面这样是不行的。</p><p>mian.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">extern</span> <span class="keyword">int</span> num;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> num = <span class="number">5</span>;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"fun in a.c"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>另外，extern关键字只需要指明类型和变量名就行了，不能再重新赋值，初始化需要在原文件所在处进行，如果不进行初始化的话，全局变量会被编译器自动初始化为0。像这种写法是不行的。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">extern</span> <span class="keyword">int</span> num=<span class="number">4</span>;</span><br></pre></td></tr></table></figure><p>但是在声明之后就可以使用变量名进行修改了，像这样：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">extern</span> <span class="keyword">int</span> num;</span><br><span class="line">    num=<span class="number">1</span>;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果不想这个变量被修改可以使用const关键字进行修饰，写法如下：<br>mian.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">extern</span> <span class="keyword">const</span> <span class="keyword">int</span> num;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"%d"</span>,num);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> num=<span class="number">5</span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"fun in a.c"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>使用include将另一个文件全部包含进去可以引用另一个文件中的变量，但是这样做的结果就是，被包含的文件中的所有的变量和方法都可以被这个文件使用，这样就变得不安全，如果只是希望一个文件使用另一个文件中的某个变量还是使用extern关键字更好。</p><h2 id="三-引用另一个文件中的函数">三、引用另一个文件中的函数</h2><p>extern除了引用另一个文件中的变量外，还可以引用另一个文件中的函数，引用方法和引用变量相似。</p><p>mian.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">extern</span> <span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span>;</span><br><span class="line">    func();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>b.c</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string">&lt;stdio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> num=<span class="number">5</span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">func</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">"fun in a.c"</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>这里main函数中引用了b.c中的函数func。因为所有的函数都是全局的，所以对函数的extern用法和对全局变量的修饰基本相同，需要注意的就是，需要指明返回值的类型和参数。</p><hr><p>转自：<a href="https://blog.csdn.net/xingjiarong/article/details/47656339" target="_blank" rel="noopener">https://blog.csdn.net/xingjiarong/article/details/47656339</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/c649d86f.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>C语言标准库--官网</title>
      <link>https://www.yansheng.fun/article/57d60461.html</link>
      <guid>https://www.yansheng.fun/article/57d60461.html</guid>
      <pubDate>Sat, 08 Apr 2023 17:56:32 GMT</pubDate>
      <description>
      
        &lt;p&gt;本文包括大部分C标准库函数，但没有列出一些用途有限的函数以及某些可以简单的从其他函数合成的函数，也没有包含多字节和本地化函数。&lt;/p&gt;
&lt;p&gt;标准库中的各个函数、类型以及宏分别在以下标准头文件中说明：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&amp;lt;assert.h&amp;gt;&lt;/th&gt;
&lt;th&gt;&amp;lt;float.h&amp;gt;&lt;/th&gt;
&lt;th&gt;&amp;lt;math.h&amp;gt;&lt;/th&gt;
&lt;th&gt;&amp;lt;stdarg.h&amp;gt;&lt;/th&gt;
&lt;th&gt;&amp;lt;stdlib.h&amp;gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;ctype.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;limits.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;setjmp.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;stddef.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;string.h&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;errno.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;locale.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;signal.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;stdio.h&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;lt;time.h&amp;gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>本文包括大部分C标准库函数，但没有列出一些用途有限的函数以及某些可以简单的从其他函数合成的函数，也没有包含多字节和本地化函数。</p><p>标准库中的各个函数、类型以及宏分别在以下标准头文件中说明：</p><table><thead><tr><th>&lt;assert.h&gt;</th><th>&lt;float.h&gt;</th><th>&lt;math.h&gt;</th><th>&lt;stdarg.h&gt;</th><th>&lt;stdlib.h&gt;</th></tr></thead><tbody><tr><td>&lt;ctype.h&gt;</td><td>&lt;limits.h&gt;</td><td>&lt;setjmp.h&gt;</td><td>&lt;stddef.h&gt;</td><td>&lt;string.h&gt;</td></tr><tr><td>&lt;errno.h&gt;</td><td>&lt;locale.h&gt;</td><td>&lt;signal.h&gt;</td><td>&lt;stdio.h&gt;</td><td>&lt;time.h&gt;</td></tr></tbody></table><a id="more"></a><h2 id="目录列表">目录列表</h2><ol><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-1/" target="_blank" rel="noopener">输入与输出</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-2/" target="_blank" rel="noopener">字符类测试</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-3/" target="_blank" rel="noopener">字符串函数</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-4/" target="_blank" rel="noopener">数学函数</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-5/" target="_blank" rel="noopener">实用函数</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-6/" target="_blank" rel="noopener">诊断</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-7/" target="_blank" rel="noopener">变长变量表</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-8/" target="_blank" rel="noopener">非局部跳转</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-9/" target="_blank" rel="noopener">信号处理</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-10/" target="_blank" rel="noopener">日期与时间函数</a></li><li><a href="http://www.swordair.com/docs/c-language-standard-library/chapter-11/" target="_blank" rel="noopener">由实现定义的限制和</a></li></ol><p>// 参考如下; <a href="http://www.swordair.com/docs/c-language-standard-library/" target="_blank" rel="noopener">http://www.swordair.com/docs/c-language-standard-library/</a></p><p>标准的函数是固定的，但标准的库函数是随意更改的，每个公司都出一套，个人或团体也可以出一套。</p><h2 id="c语言学习网">C语言学习网</h2><p><a href="http://baike.baidu.com/view/422082.htm" target="_blank" rel="noopener">http://baike.baidu.com/view/422082.htm</a></p><p><a href="http://gcc.gnu.org/" target="_blank" rel="noopener">http://gcc.gnu.org/</a></p><p>可以下载gcc的标准库源码</p><h2 id="c语言官网">C语言官网</h2><p><a href="http://fgetc.com/" target="_blank" rel="noopener">http://fgetc.com/</a></p><p>记载类网站：<a href="http://andriki.com/wiki/C_Standard_Library" target="_blank" rel="noopener">http://andriki.com/wiki/C_Standard_Library</a></p><p>glibc就是C标准库。windows下的东西是不开源的。</p><p>源代码这里可以找到:</p><p><a href="http://mirrors.kernel.org/gnu/glibc/" target="_blank" rel="noopener">http://mirrors.kernel.org/gnu/glibc/</a></p><p>两种压缩格式都行。反正找最大的下就是了。</p><p>标准库的源文件可能有很多版本，但GNU的标准库是比较好的，都是世界顶级的大师做的。GCC也是最好最标准的编译器。</p><p>ubuntu上apt-get source libstdc++6 libc6</p><p><a href="http://gcc.gnu.org/libstdc++/" target="_blank" rel="noopener">http://gcc.gnu.org/libstdc++/</a></p><hr><p>转自：<a href="https://blog.csdn.net/zxxSsdsd/article/details/9816933" target="_blank" rel="noopener">https://blog.csdn.net/zxxSsdsd/article/details/9816933</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/57d60461.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>C语言：__restrict关键字提升性能</title>
      <link>https://www.yansheng.fun/article/9b20682b.html</link>
      <guid>https://www.yansheng.fun/article/9b20682b.html</guid>
      <pubDate>Sat, 08 Apr 2023 17:49:12 GMT</pubDate>
      <description>
      
        
        
          &lt;p&gt;__restrict 是 C 语言中的关键字，它的作用是为编译器带来附加信息。当对指针增加 __restrict 修饰之后，表示当前指针在存活期间是独占内存的，不会有其他指针指向这个地址。编译器在知道这个信息之后，就可以做出优化，从而提升性能。&lt;/p&gt;
&lt;p&gt;据说Click
        
      
      </description>
      
      
      <content:encoded><![CDATA[<p>__restrict 是 C 语言中的关键字，它的作用是为编译器带来附加信息。当对指针增加 __restrict 修饰之后，表示当前指针在存活期间是独占内存的，不会有其他指针指向这个地址。编译器在知道这个信息之后，就可以做出优化，从而提升性能。</p><p>据说Clickhouse用这个关键字提升了1.6倍的聚合函数性能。</p><hr><p>作者：疾风2018<br>链接：<a href="https://www.jianshu.com/p/2f1d86dffb26" target="_blank" rel="noopener">https://www.jianshu.com/p/2f1d86dffb26</a><br>来源：简书<br>著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/9b20682b.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>C语言intptr_t、uintptr_t数据类型的解析</title>
      <link>https://www.yansheng.fun/article/884da0d4.html</link>
      <guid>https://www.yansheng.fun/article/884da0d4.html</guid>
      <pubDate>Wed, 05 Apr 2023 16:46:43 GMT</pubDate>
      <description>
      
        &lt;p&gt;最近开始研读Nginx的源代码，首先就遇到如下的代码：&lt;/p&gt;
&lt;figure class=&quot;highlight c&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;typedef&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;intptr_t&lt;/span&gt;      &lt;span class=&quot;keyword&quot;&gt;ngx_int_t&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;typedef&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;uintptr_t&lt;/span&gt;    &lt;span class=&quot;keyword&quot;&gt;ngx_uint_t&lt;/span&gt;;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;intptr_t和uintptr_t是什么类型？以前没见过，于是查了一下。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>最近开始研读Nginx的源代码，首先就遇到如下的代码：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span>  <span class="keyword">intptr_t</span>      <span class="keyword">ngx_int_t</span>;</span><br><span class="line"><span class="keyword">typedef</span>  <span class="keyword">uintptr_t</span>    <span class="keyword">ngx_uint_t</span>;</span><br></pre></td></tr></table></figure><p>intptr_t和uintptr_t是什么类型？以前没见过，于是查了一下。</p><a id="more"></a><p>这两个数据类型是ISO C99定义的，具体代码在linux平台的/usr/include/stdint.h头文件中。</p><p>该头文件中定义intptr_t和uintptr_t这两个数据类型的代码片段如下：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Types for `void *' pointers.  */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">if</span> __WORDSIZE == 64</span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">ifndef</span> __intptr_t_defined</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">int</span><span class="keyword">intptr_t</span>;</span><br><span class="line"><span class="meta">#  <span class="meta-keyword">define</span> __intptr_t_defined</span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">int</span><span class="keyword">uintptr_t</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span></span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">ifndef</span> __intptr_t_defined</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">int</span><span class="keyword">intptr_t</span>;</span><br><span class="line"><span class="meta">#  <span class="meta-keyword">define</span> __intptr_t_defined</span></span><br><span class="line"><span class="meta"># <span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">int</span><span class="keyword">uintptr_t</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><p>在64位的机器上，intptr_t和uintptr_t分别是long int、unsigned long int的别名；<br>在32位的机器上，intptr_t和uintptr_t分别是int、unsigned int的别名。</p><p>那么为什么要用typedef定义新的别名呢？我想主要是为了提高程序的可移植性（在32位和64位的机器上）。很明显，上述代码会根据宿主机器的位数为intptr_t和uintptr_t适配相应的数据类型。</p><p>另外，如注释所言，定义这两个数据类型别名也是为了“void *”指针。</p><p>在C语言中，任何类型的指针都可以转换为void *类型，并且在将它转换回原来的类型时不会丢失信息。</p><hr><p>转自：<a href="https://blog.csdn.net/cs_zhanyb/article/details/16973379" target="_blank" rel="noopener">https://blog.csdn.net/cs_zhanyb/article/details/16973379</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/884da0d4.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>C语言typedef详解</title>
      <link>https://www.yansheng.fun/article/60c42210.html</link>
      <guid>https://www.yansheng.fun/article/60c42210.html</guid>
      <pubDate>Wed, 05 Apr 2023 16:35:21 GMT</pubDate>
      <description>
      
        &lt;p&gt;C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称，来替代系统默认的基本类型名称、数组类型名称、指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。一旦用户在程序中定义了自己的数据类型名称，就可以在该程序中用自己的数据类型名称来定义变量的类型、数组的类型、指针变量的类型与函数的类型等。&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>C语言允许用户使用 typedef 关键字来定义自己习惯的数据类型名称，来替代系统默认的基本类型名称、数组类型名称、指针类型名称与用户自定义的结构型名称、共用型名称、枚举型名称等。一旦用户在程序中定义了自己的数据类型名称，就可以在该程序中用自己的数据类型名称来定义变量的类型、数组的类型、指针变量的类型与函数的类型等。</p><a id="more"></a><p>例如，C 语言在 C99 之前并未提供布尔类型，但我们可以使用 typedef 关键字来定义一个简单的布尔类型，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">int</span> BOOL;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> TRUE 1</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FALSE 0</span></span><br></pre></td></tr></table></figure><p>定义好之后，就可以像使用基本类型数据一样使用它了，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">BOOL bflag=TRUE;</span><br></pre></td></tr></table></figure><blockquote><p>C99标准中新增了布尔类型，且定义布尔变量的方式有两种，一种是使用 _BOOL，另一种是使用 &lt;stdbool.h&gt; 头文件中定义好的 bool 类型，感兴趣的小伙伴请猛击这里了解详情。</p></blockquote><h2 id="typedef的4种用法">typedef的4种用法</h2><p>在实际使用中，typedef 的应用主要有如下4种。</p><h3 id="1-为基本数据类型定义新的类型名">1) 为基本数据类型定义新的类型名</h3><p>也就是说，系统默认的所有基本类型都可以利用 typedef 关键字来重新定义类型名，示例代码如下所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> COUNT;</span><br></pre></td></tr></table></figure><p>而且，我们还可以使用这种方法来定义与平台无关的类型。比如，要定义一个叫 REAL 的浮点类型，在目标平台一上，让它表示最高精度的类型，即：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">double</span> REAL;</span><br></pre></td></tr></table></figure><p>在不支持 long double 的平台二上，改为：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">double</span> REAL;</span><br></pre></td></tr></table></figure><p>甚至还可以在连 double 都不支持的平台三上，改为：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">float</span> REAL;</span><br></pre></td></tr></table></figure><p>这样，当跨平台移植程序时，我们只需要修改一下 typedef 的定义即可，而不用对其他源代码做任何修改。其实，标准库中广泛地使用了这个技巧，比如 size_t 在 VC++的 crtdefs.h 文件中的定义如下所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> _SIZE_T_DEFINED</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifdef</span>  _WIN64</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> __int64    <span class="keyword">size_t</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">else</span></span></span><br><span class="line"><span class="keyword">typedef</span> _W64 <span class="keyword">unsigned</span> <span class="keyword">int</span>   <span class="keyword">size_t</span>;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> _SIZE_T_DEFINED</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span></span></span><br></pre></td></tr></table></figure><h3 id="2-为自定义数据类型-结构体-共用体和枚举类型-定义简洁的类型名称">2) 为自定义数据类型（结构体、共用体和枚举类型）定义简洁的类型名称</h3><p>以结构体为例，下面我们定义一个名为 Point 的结构体：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Point</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">double</span> x;</span><br><span class="line">    <span class="keyword">double</span> y;</span><br><span class="line">    <span class="keyword">double</span> z;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在调用这个结构体时，我们必须像下面的代码这样来调用这个结构体：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Point</span> <span class="title">oPoint1</span>=&#123;</span><span class="number">100</span>，<span class="number">100</span>，<span class="number">0</span>&#125;;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Point</span> <span class="title">oPoint2</span>;</span></span><br></pre></td></tr></table></figure><p>在这里，结构体 struct Point 为新的数据类型，在定义变量的时候均要向上面的调用方法一样有保留字 struct，而不能像 int 和 double 那样直接使用 Point 来定义变量。现在，我们利用 typedef 定义这个结构体，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagPoint</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">double</span> x;</span><br><span class="line">    <span class="keyword">double</span> y;</span><br><span class="line">    <span class="keyword">double</span> z;</span><br><span class="line">&#125; Point;</span><br></pre></td></tr></table></figure><p>在上面的代码中，实际上完成了两个操作：<br>1、定义了一个新的结构类型，代码如下所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">tagPoint</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">double</span> x;</span><br><span class="line">    <span class="keyword">double</span> y;</span><br><span class="line">    <span class="keyword">double</span> z;</span><br><span class="line">&#125; ;</span><br></pre></td></tr></table></figure><p>其中，struct 关键字和 tagPoint 一起构成了这个结构类型，无论是否存在 typedef 关键字，这个结构都存在。</p><p>2、使用 typedef 为这个新的结构起了一个别名，叫 Point，即：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagPoint</span> <span class="title">Point</span></span></span><br></pre></td></tr></table></figure><p>因此，现在你就可以像 int 和 double 那样直接使用 Point 定义变量，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Point oPoint1=&#123;<span class="number">100</span>，<span class="number">100</span>，<span class="number">0</span>&#125;;</span><br><span class="line">Point oPoint2;</span><br></pre></td></tr></table></figure><p>为了加深对 typedef 的理解，我们再来看一个结构体例子，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">char</span> *pItem;</span><br><span class="line">    pNode pNext;</span><br><span class="line">&#125; *pNode;</span><br></pre></td></tr></table></figure><p>从表面上看，上面的示例代码与前面的定义方法相同，所以应该没有什么问题。但是编译器却报了一个错误，为什么呢？莫非 C 语言不允许在结构中包含指向它自己的指针？</p><p>其实问题并非在于 struct 定义的本身，大家应该都知道，C 语言是允许在结构中包含指向它自己的指针的，我们可以在建立链表等<a href="http://c.biancheng.net/data_structure/" target="_blank" rel="noopener">数据结构</a>的实现上看到很多这类例子。那问题在哪里呢？其实，根本问题还是在于 typedef 的应用。</p><p>在上面的代码中，新结构建立的过程中遇到了 pNext 声明，其类型是 pNode。这里要特别注意的是，pNode 表示的是该结构体的新别名。于是问题出现了，在结构体类型本身还没有建立完成的时候，编译器根本就不认识 pNode，因为这个结构体类型的新别名还不存在，所以自然就会报错。因此，我们要做一些适当的调整，比如将结构体中的 pNext 声明修改成如下方式：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">char</span> *pItem;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span> *<span class="title">pNext</span>;</span></span><br><span class="line">&#125; *pNode;</span><br></pre></td></tr></table></figure><p>或者将 struct 与 typedef 分开定义，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span> *<span class="title">pNode</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">char</span> *pItem;</span><br><span class="line">    pNode pNext;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在上面的代码中，我们同样使用 typedef 给一个还未完全声明的类型 tagNode 起了一个新别名。不过，虽然 C 语言编译器完全支持这种做法，但不推荐这样做。建议还是使用如下规范定义方法：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">char</span> *pItem;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span> *<span class="title">pNext</span>;</span></span><br><span class="line">&#125;;</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">tagNode</span> *<span class="title">pNode</span>;</span></span><br></pre></td></tr></table></figure><h3 id="3-为数组定义简洁的类型名称">3) 为数组定义简洁的类型名称</h3><p>它的定义方法很简单，与为基本数据类型定义新的别名方法一样，示例代码如下所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">int</span> INT_ARRAY_100[<span class="number">100</span>];</span><br><span class="line">INT_ARRAY_100 arr;</span><br></pre></td></tr></table></figure><h3 id="4-为指针定义简洁的名称">4) 为指针定义简洁的名称</h3><p>对于指针，我们同样可以使用下面的方式来定义一个新的别名：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span>* PCHAR;</span><br><span class="line">PCHAR pa;</span><br></pre></td></tr></table></figure><p>对于上面这种简单的变量声明，使用 typedef 来定义一个新的别名或许会感觉意义不大，但在比较复杂的变量声明中，typedef 的优势马上就体现出来了，如下面的示例代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">int</span> *(*a[<span class="number">5</span>])(<span class="keyword">int</span>,<span class="keyword">char</span>*);</span><br></pre></td></tr></table></figure><p>对于上面变量的声明，如果我们使用 typdef 来给它定义一个别名，这会非常有意义，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// PFun是我们创建的一个类型别名</span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">int</span> *(*PFun)(<span class="keyword">int</span>,<span class="keyword">char</span>*);</span><br><span class="line"><span class="comment">// 使用定义的新类型来声明对象，等价于int*(*a[5])(int,char*);</span></span><br><span class="line">PFun a[<span class="number">5</span>];</span><br></pre></td></tr></table></figure><h2 id="小心使用-typedef-带来的陷阱">小心使用 typedef 带来的陷阱</h2><p>接下来看一个简单的 typedef 使用示例，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">char</span>* PCHAR;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">strcmp</span><span class="params">(<span class="keyword">const</span> PCHAR,<span class="keyword">const</span> PCHAR)</span></span>;</span><br></pre></td></tr></table></figure><p>在上面的代码中，“const PCHAR” 是否相当于 “const char*” 呢？</p><p>答案是否定的，原因很简单，typedef 是用来定义一种类型的新别名的，它不同于宏，不是简单的字符串替换（有关 typedef 和 #define 的区别，请猛击这里了解详情）。因此，“const PCHAR”中的 const 给予了整个指针本身常量性，也就是形成了常量指针“char<em>const（一个指向char的常量指针）”。即它实际上相当于“char</em>const”，而不是“const char*（指向常量 char 的指针）”。当然，要想让 const PCHAR 相当于 const char* 也很容易，如下面的代码所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">const</span> <span class="keyword">char</span>* PCHAR;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">strcmp</span><span class="params">(PCHAR， PCHAR)</span></span>;</span><br></pre></td></tr></table></figure><p>其实，无论什么时候，只要为指针声明 typedef，那么就应该在最终的 typedef 名称中加一个 const，以使得该指针本身是常量。</p><p>还需要特别注意的是，虽然 typedef 并不真正影响对象的存储特性，但在语法上它还是一个存储类的关键字，就像 auto、extern、static 和 register 等关键字一样。因此，像下面这种声明方式是不可行的：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">static</span> <span class="keyword">int</span> INT_STATIC;</span><br></pre></td></tr></table></figure><p>不可行的原因是不能声明多个存储类关键字，由于 typedef 已经占据了存储类关键字的位置，因此，在 typedef 声明中就不能够再使用 static 或任何其他存储类关键字了。当然，编译器也会报错，如在 VC++2010 中的报错信息为“无法指定多个存储类”。</p><hr><p>转自：<a href="http://c.biancheng.net/view/298.html" target="_blank" rel="noopener">http://c.biancheng.net/view/298.html</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/60c42210.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>VSCode左下角显示大纲（显示所有函数方法）</title>
      <link>https://www.yansheng.fun/article/469cdac7.html</link>
      <guid>https://www.yansheng.fun/article/469cdac7.html</guid>
      <pubDate>Wed, 05 Apr 2023 16:15:57 GMT</pubDate>
      <description>
      
        &lt;p&gt;VSCode左下角显示大纲（显示所有函数方法）&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>VSCode左下角显示大纲（显示所有函数方法）</p><a id="more"></a><h3 id="方法一：shift-ctl-o-显示在顶部-不方便查看">方法一：Shift+Ctl+O(显示在顶部，不方便查看)</h3><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/56c5837b69654cca8f48e20a3a15df83.png" alt="在这里插入图片描述"></p><h3 id="方法二：显示大纲-在编辑器左下角显示-方便查看">方法二：显示大纲(在编辑器左下角显示，方便查看)</h3><p>Shift+Ctl+P -&gt; View: Quick Open View -&gt; 大纲</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/2b97d2391f5b41d194a628f556c0930e.png" alt="在这里插入图片描述"></p><hr><p>转自：<a href="https://blog.csdn.net/shuipaopaojin/article/details/95939081" target="_blank" rel="noopener">https://blog.csdn.net/shuipaopaojin/article/details/95939081</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/469cdac7.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>PostgreSQL查找配置文件位置、数据所在目录</title>
      <link>https://www.yansheng.fun/article/a8a7137b.html</link>
      <guid>https://www.yansheng.fun/article/a8a7137b.html</guid>
      <pubDate>Wed, 05 Apr 2023 13:39:30 GMT</pubDate>
      <description>
      
        &lt;p&gt;PostgreSQL查找配置文件位置、数据所在目录&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>PostgreSQL查找配置文件位置、数据所在目录</p><a id="more"></a><h2 id="方案一-用数据库的超级用户登录数据库-使用查询语句查询">方案一、用数据库的超级用户登录数据库，使用查询语句查询</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> su - postgres <span class="comment"># 这里是切换到操作系统的postgres用户</span></span></span><br><span class="line"><span class="meta">$</span><span class="bash"> psql <span class="comment"># 缺省用户名的情况下，会把当前系统用户名当作数据库登录用户名，数据库的postgres是超级用户</span></span></span><br><span class="line">psql (13.2 (Ubuntu 13.2-1.pgdg18.04+1))</span><br><span class="line">Type "help" for help.</span><br><span class="line"></span><br><span class="line">postgres=# show config_file; -- 查询配置文件所在位置</span><br><span class="line">               config_file               </span><br><span class="line">-----------------------------------------</span><br><span class="line"> /etc/postgresql/13/main/postgresql.conf</span><br><span class="line">(1 row)</span><br><span class="line"></span><br><span class="line">postgres=# show data_directory; -- 查询数据储存目录</span><br><span class="line">      data_directory      </span><br><span class="line">--------------------------</span><br><span class="line"> /data/postgresql/13/main</span><br><span class="line">(1 row)</span><br></pre></td></tr></table></figure><h2 id="方案二-使用操作系统root用户查找postgresql进程">方案二、使用操作系统root用户查找postgresql进程</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> ps -ef|grep postgresql</span></span><br><span class="line">postgres 23746     1  0 Aug31 ?        00:04:40 /usr/lib/postgresql/13/bin/postgres -D /data/postgresql/13/main -c config_file=/etc/postgresql/13/main/postgresql.conf</span><br></pre></td></tr></table></figure><p>可以看到<code>-D</code>后面的参数即为数据目录，<code>-c</code>后面的参数即为配置文件所在位置。</p><hr><p>转自：<a href="https://blog.csdn.net/DongGeGe214/article/details/121489384" target="_blank" rel="noopener">https://blog.csdn.net/DongGeGe214/article/details/121489384</a></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/a8a7137b.html#disqus_thread</comments>
    </item>
    
    <item>
      <title>Windows的svchost.exe消耗很多流量，禁用Windows更新</title>
      <link>https://www.yansheng.fun/article/6d87f8ef.html</link>
      <guid>https://www.yansheng.fun/article/6d87f8ef.html</guid>
      <pubDate>Sat, 01 Apr 2023 15:10:22 GMT</pubDate>
      <description>
      
        &lt;p&gt;发现在待机状态，svchost.exe这个Windows服务主进程消耗了很多流量，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/aed367fad4f6466b9ce04d8a7ed29cdd.png&quot; alt=&quot;在这里插入图片描述&quot;&gt;&lt;/p&gt;
      
      </description>
      
      
      <content:encoded><![CDATA[<p>发现在待机状态，svchost.exe这个Windows服务主进程消耗了很多流量，如下图：</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/aed367fad4f6466b9ce04d8a7ed29cdd.png" alt="在这里插入图片描述"></p><a id="more"></a><p>搜了下，发现是系统的进程，不能随便禁用的。</p><p>参考：<a href="https://digi.china.com/digi/20201124/20201124658058.html" target="_blank" rel="noopener">https://digi.china.com/digi/20201124/20201124658058.html</a></p><p>系统后台进程肯定是不能随便禁用的，然后发现好像<strong>win更新程序</strong>也会用这个偷偷下载更新包，打开服务看了下，果然更新的服务是开启的……立马禁用掉！！！<br><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/151411cddc864e31bb9f9cb9712cae73.png" alt="在这里插入图片描述"></p><p>禁用，并设置恢复时无操作，不然又会重启。</p><p><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/95e557c1c402442fb0d95677dc8fd38d.png" alt="在这里插入图片描述"><br><img src="https://cdn.jsdelivr.net/gh/yansheng836/github-oss/csdn-img/ca608e5e53f946d6bac56dad5051ce24.png" alt="在这里插入图片描述"></p>]]></content:encoded>
      
      <comments>https://www.yansheng.fun/article/6d87f8ef.html#disqus_thread</comments>
    </item>
    
  </channel>
</rss>
