<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>WANG!</title>
    <link>https://hiwangzi.com/</link>
    <description>Recent content on WANG!</description>
    <generator>Hugo -- gohugo.io</generator>
    <lastBuildDate>Mon, 18 Dec 2023 12:19:09 +0800</lastBuildDate><atom:link href="https://hiwangzi.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>是周报也是未来的期望</title>
      <link>https://hiwangzi.com/posts/2023/12/18/the-last-2-weeks-of-the-year/</link>
      <pubDate>Mon, 18 Dec 2023 12:19:09 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2023/12/18/the-last-2-weeks-of-the-year/</guid>
      <description>Remind me again. Goals for this month.</description>
      <content:encoded><![CDATA[<p>首先回应上篇blog（<a href="https://hiwangzi.com/posts/2023/10/25/the-last-68-days-of-the-year/">The Last 68 Days of the Year</a>），在12月5号办理了入职，上周四正式开始工作，算是完成了先找到新工作的这件事。</p>
<p>上周工作开始后，就是忙忙碌碌。不过昨晚才开始想，这都是自己给自己制造压力，自己没必要焦虑，只要自己尽心做好工作，不要去想其他的东西，徒增烦恼。上个周末大多数时间被自己空耗，刷小红书、X，两者切换着刷，以后要少在社交媒体上浪费时间，或者说要经常自己提醒自己，要做创作者而不是消费者。同时消费内容，也应该去消费那些精品系统性的内容。</p>
<p>2023年最后的两周里，希望自己能认真贯彻前段时间计划的《深入学习》和《健康生活》。想来还是要列一下这两周里要完成的子计划：</p>
<ul>
<li>读完实践完成《Spring in Action》第四版</li>
<li>体重到90KG以下</li>
</ul>
<p>已经降低难度啦，王子好好干！</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>The Last 68 Days of the Year</title>
      <link>https://hiwangzi.com/posts/2023/10/25/the-last-68-days-of-the-year/</link>
      <pubDate>Wed, 25 Oct 2023 12:42:04 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2023/10/25/the-last-68-days-of-the-year/</guid>
      <description>There are only 68 days of 2023. How to make the most of these days?</description>
      <content:encoded><![CDATA[<p>逃避，至少对于我目前的情况，并不能真正的解决问题。很羡慕或者说又会有些害怕那些技术高手，害怕被他们一眼识破自己的这点三脚猫功夫，就一直逃避这件事，可逃避这件事，会引来后续一系列的麻烦。最近几周又想了一下，如果自己总是觉得这些东西是自己的弱点，那么解决这件事的最好方法不应该是自己也去学习掌握么？至少这样会让自己心里从容一些，在见到各位技术高手大牛时，不至于自卑。或许因为知识不足而自卑，看起来不算是一件坏事，但是如果没有解决问题，这份情绪除了让自己内耗，并没有什么用处。</p>
<p>在遇到问题的时候，我喜欢整理，整理文件，整理桌面，那么，今天就整理一下博客吧。删除所有笔记类的文章，统一链接到 GitHub 仓库，散落的内容合并到一起吧。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2023/10/25/the-last-68-days-of-the-year/resources/screenshot-of-my-blog-about-notes.png" alt="Screenshot of my blog about notes"  />
</p>
<p>接下来的计划，就是要在一个月内找到一份新工作。不写太多心愿，完成这一点之后，再写下新的目标。</p>
<p>「道且长，衣衫薄，来日方长」这句话以前是从高晓松的节目上听来的，还用做过好长一段时间的博客副标题，可现在的我觉得，先不论道阻是否长，先做事，行动起来就好，因此「持续学习」会是接下来一段时间自己的人生准则。那么，各位，就新年再见吧。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>How to Read Java Class Version</title>
      <link>https://hiwangzi.com/posts/2022/07/11/how-to-read-java-class-version/</link>
      <pubDate>Mon, 11 Jul 2022 12:19:38 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2022/07/11/how-to-read-java-class-version/</guid>
      <description>Updated on Jan 8 2024.
Actually, we can just use javap -v to get the version information. For example,
$ javap -v Main.class Classfile /Users/luke/Developer/Learn/Spring/learn-spring-in-action-v4/chapter1/build/classes/java/main/com/hiwangzi/chapter1/Main.class Last modified Dec 8, 2023; size 1717 bytes SHA-256 checksum f6202b165f5e178e46a5f0d5b31c5112ffe23eb342f0b47afcc7b1084c63eb8a Compiled from &amp;#34;Main.java&amp;#34; public class com.hiwangzi.chapter1.Main minor version: 0 major version: 65 It is more convenient.
$ javap -v Main.class | grep version minor version: 0 major version: 65 It is easy enough to read the class file signature and get these values without a 3rd party API.</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong>Updated</strong> on Jan 8 2024.</p>
</blockquote>
<p>Actually, we can just use <code>javap -v</code> to get the version information. For example,</p>
<pre tabindex="0"><code>$ javap -v Main.class               
Classfile /Users/luke/Developer/Learn/Spring/learn-spring-in-action-v4/chapter1/build/classes/java/main/com/hiwangzi/chapter1/Main.class
  Last modified Dec 8, 2023; size 1717 bytes
  SHA-256 checksum f6202b165f5e178e46a5f0d5b31c5112ffe23eb342f0b47afcc7b1084c63eb8a
  Compiled from &#34;Main.java&#34;
public class com.hiwangzi.chapter1.Main
  minor version: 0
  major version: 65
</code></pre><p>It is more convenient.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>$ javap -v Main.class | grep version
</span></span><span style="display:flex;"><span>  minor version: <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>  major version: <span style="color:#ae81ff">65</span>
</span></span></code></pre></div><hr>
<p>It is easy enough to read the <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1">class file signature</a> and get these values without a 3rd party API. All you need to do is read the first 8 bytes.</p>
<pre tabindex="0"><code>ClassFile {
    u4 magic;
    u2 minor_version;
    u2 major_version;
</code></pre><p>e.g.: Read a file which is version 61.0 (Java 17)</p>
<pre tabindex="0"><code>hexdump -C Identification.class 
00000000  ca fe ba be 00 00 00 3d  00 20 0a 00 02 00 03 07  |.......=. ......|
00000010  00 04 0c 00 05 00 06 01  00 10 6a 61 76 61 2f 6c  |..........java/l|
00000020  61 6e 67 2f 4f 62 6a 65  63 74 01 00 06 3c 69 6e  |ang/Object...&lt;in|
00000030  69 74 3e 01 00 03 28 29  56 09 00 08 00 09 07 00  |it&gt;...()V.......|
...
</code></pre><p>the opening bytes are:</p>
<pre tabindex="0"><code>ca fe ba be 00 00 00 3d
</code></pre><p>&hellip;where <code>ca fe ba be</code> are the magic bytes, <code>00 00</code> is the minor version and <code>00 3d</code> is the major version.</p>
<h2 id="major-version-number-of-the-class-file-format-being-used">major version number of the class file format being used</h2>
<ul>
<li>Java SE 18 = 62 (0x3E hex)</li>
<li>Java SE 17 = 61 (0x3D hex)</li>
<li>Java SE 16 = 60 (0x3C hex)</li>
<li>Java SE 15 = 59 (0x3B hex)</li>
<li>Java SE 14 = 58 (0x3A hex)</li>
<li>Java SE 13 = 57 (0x39 hex)</li>
<li>Java SE 12 = 56 (0x38 hex)</li>
<li>Java SE 11 = 55 (0x37 hex)</li>
<li>Java SE 10 = 54 (0x36 hex)</li>
<li>Java SE 9 = 53 (0x35 hex)</li>
<li>Java SE 8 = 52 (0x34 hex)</li>
<li>Java SE 7 = 51 (0x33 hex)</li>
<li>Java SE 6.0 = 50 (0x32 hex)</li>
<li>Java SE 5.0 = 49 (0x31 hex)</li>
<li>JDK 1.4 = 48 (0x30 hex)</li>
<li>JDK 1.3 = 47 (0x2F hex)</li>
<li>JDK 1.2 = 46 (0x2E hex)</li>
<li>JDK 1.1 = 45 (0x2D hex)</li>
</ul>
<h2 id="references">References</h2>
<ul>
<li><a href="https://stackoverflow.com/a/27123">https://stackoverflow.com/a/27123</a></li>
<li><a href="https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1">https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.1</a></li>
<li><a href="https://en.wikipedia.org/wiki/Java_class_file#General_layout">https://en.wikipedia.org/wiki/Java_class_file#General_layout</a></li>
<li><a href="https://unix.stackexchange.com/questions/10826/shell-how-to-read-the-bytes-of-a-binary-file-and-print-as-hexadecimal">https://unix.stackexchange.com/questions/10826/shell-how-to-read-the-bytes-of-a-binary-file-and-print-as-hexadecimal</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>新冠隔离12日</title>
      <link>https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/</link>
      <pubDate>Sat, 16 Apr 2022 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/</guid>
      <description>发热 居住的小区在3月18日就开始封闭，在新冠确诊之前，已经经历了十次左右核酸检测。对于如何感染上新冠病毒这件事，如今只能猜测核酸检测时密集接触，或是快递包裹上带有病毒。
酒店 我是4月3日晚上10点多被拉去酒店隔离的，在酒店6天没见到防疫人员，只有一个酒店工作人员在微信上负责对接。酒店只有4层、5层，我是在4层和女朋友一起隔离。
虽然没有明确的后续流程告知，但是酒店里，条件还是比较好的，至少能保证一家人或者单人一间隔离，大家也都比较谨慎，在我们几个自发的志愿者提醒下，基本没有出门走动的，饭的话是由安保大白送到楼上，再由我们几个志愿者分发到房间门口。志愿者里有位大叔非常热心，向酒店申请了喷壶、消毒药片，在酒店4层，算上我总共有4人做志愿者，两人负责做走廊消杀，两人负责发放餐食、物资。在每次活动前，我们都互相先把身上喷一下消毒水，戴好医用手套。个人觉得，在酒店里，应该不少人都已经转阴了。
关于消毒药片有个小悲剧，我们在把消毒药片发到房门口后，在群里发文字跟大家说，这个是放到马桶水箱里面的。但可能又是因为消毒药片和一小袋中药是一起发放的，有位阿姨不识字，误服了消毒药片，在10点多赶紧拨打了120送去急救。内心当时非常难受，觉得愧疚万分。后续在群里发的各种消息，改成了语音发一遍，文字再发一遍的形式。
酒店的几天里，很多人也都询问何时做核酸，但是也没有得到答复。到了9号下午，在我们几个志愿者清运完各个房间的垃圾之后（进入酒店第二天发放的黄袋子，要一段时间，才会统一清运一次）。回到房间后，我看到酒店工作人员在群里发了一个名单，通知转运第一批人，让大家收拾好，但是没有通知去哪里。
到了晚上，又通知先不转运，第二天再转运。然后我就先去睡了，到了10号凌晨2点，被外面一阵敲打声吵醒，也不知道是什么声音，看了一下手机，才发现，10点的时候，酒店工作人员又通知说，大家快做好准备，要出发了，同时发了一个第二批转运的名单。在凌晨2点我醒了的时候，才发现，第二批名单已经先行转运走了（也就是说，第二批名单上的人，被临时通知没几个小时，在不知道目的地的情况下，就出发了）。
没在这两批名单的人就很紧张，觉得在酒店隔离可能已经转阴，害怕去了方舱再次被传染，有人提议一起去12345登记投诉。后续他们就在酒店做抗原、核酸检测了，虽然到了方舱的第二天看到这个消息，也有不满，但发现后面新进入酒店的感染者多是老人、儿童，心里还是比较支持的了。
作为第一批名单的人，最终接到的消息是等待大巴把第二批名单的人送到后，会回来再接。此时我们只能盼着，方舱医院不要太混乱，至少大家在酒店的隔离都是小心谨慎。
方舱 应该是3点左右吧，开始通知第一批名单的人下楼，到了车上，又等了半个多小时，所有人才到齐（一些人跟我一样，早早睡下了，没看到消息）。
快到五点，终于到了方舱医院，在一位早到的病患指导下，去空病房抱了被子回到床位，就躺下尝试休息了。在四人一间的活动板房里，听着此起彼伏的呼噜声，熬到了6点多，天亮了。
早饭的混乱打破了我的幻想，大白把之前馊了的盒饭，误当作早饭发放，随后运来的早饭，大白往那边一放，一群人发生了哄抢。再加上大家不戴口罩的聚集洗漱，让我都觉得在酒店时的小心翼翼是种“荒唐”。
经过早餐的混乱，再次形成了靠病患自己组织成的志愿者分发餐食的秩序。
虽然看着“今日闵行”公众号写着“物资保障良好”，但是我在方舱的几天里，在我后面来的一批病患，一直没拿到过洗漱用品，再加上前三天的高温天气，感觉他们真的难过。还有就是总共1500人左右的方舱，只有三台净水器能够打热水，每次接热水都是排长龙。（PS：我在隔离前，所幸是收拾了一堆东西去的，包括电热水壶）。
前三天，每天1人只有1瓶矿泉水。这三天里，志愿者们多次找大白反馈物资问题，可得到的答复总是已向上面反馈，可天知道，这上面到底是谁。在第三天下午，我在教室避暑的时候，突然听到外面跑过一群人，一阵喧闹，过了一会儿出去看，发现是最初牵头的志愿者，实在是无法忍耐，和大白们起了冲突，到了大门口，打开大门，跑到了门外，大白尝试关门，我们把他拉了进来，让大门开着。现在想来，也实在惊险，如果只是他个人被关在门外，怕是要被扣上一个破坏防疫的罪名了。
在两辆警车依次来到之后，又来了一辆满载身着防护服的特警的车辆。这里不细说了，只说最后结论，依然没有一个方舱医院的负责人露面，只有一名警官负责协调，反馈了三天无法解决的喝水问题，最终方案是当天下午会再送来一批矿泉水，烧水壶会之后解决，并且除三餐外，会增加水果酸奶。
和我想的不同，本以为这样方舱医院步入正常运营的正轨，但是在大白咨询了上级领导矿泉水发放方式后，让大家自己去拿，随后又一波哄抢发生了。后来改为排队领取，再次群体密集聚集。
抗议的第二天（入院的第四天）早上的核酸检测，大白们依然无组织，直接通知全员做核酸，先需要排队找核酸贴纸，再是排队去做检测，真的是失望……明明可以按照之前的形式，分病区做检测，但就是没有人愿意把事情做好，就变成了“有决定权的人不做事（或者说也根本不在乎效率、科学与防疫），做事的人没有决定权（同时也没有主观能动性）”。
入院的第五天，实在看不下去依旧混乱，我提前去护士站找护士要来了我所在病区的核酸检测贴纸和试管（护士站其实也按病区已经提前分好了贴纸，但不知道为什么前一天会无序排队），发到了每个房间，让大家等会儿人少一些，再去排队。
再次混乱无序的排队领取出院小结，虽然明明出院小结是按照病区、床号顺序已经打印好，只要按照病区来叫，会很快的分发完毕，但发放形式依然是通知大家出来排队领取……这个时候我已经无力吐槽了。
然后也不意外，出院登车也是依旧混乱，一边在排队领出院小结，另一边在等待排队登车。虽然出院前大家都已经扫码登记了出院目的地，但依然不采用提前按目的地（镇或街道）分批排队登车的形式。最后各辆大巴上，平均目的地要跑5、6个镇。所有人都很累，病患、大白、司机、镇上分流点等待的工作人员……但所有人却都主动或被动地选择了这种方式。
深夜，大巴车继续在空荡的街道上缓缓前行……
感谢 感谢酒店里名为“莫言”的工作人员，尽可能地帮助协调各种问题！
感谢各位病患志愿者，大家都在尝试，让这个世界尽量少一些糟糕！
感谢各位医护人员，各位大白，虽然我对你们的工作模式多有不满，可前三天里最高31度的高温下，防护服下的你们也的确辛苦！
再补几张照片 ⬆️ 方舱隔离的午餐 ⬆️ 方舱厕所 ⬆️ 在1500人左右的方舱里，厕所环境迅速恶化，几个志愿者讨论后把厕所分区，自己清理了厕所里堆积在角落的厕纸。虽然已经告知大家可以把厕纸直接冲走，但大家的习惯可能一时难改……又或者说，这件事由工作人员广播告知，更有信服力。 ⬆️ 方舱里爬行的虫子 ⬆️ 淋浴隔间，但境遇同厕所，环境很快恶化，照明也在几天后损坏 ⬆️ 一场大雨后的入院登记处 哦，对了还有，方舱里也是没有药的，只有入院时发放的两盒连花清瘟颗粒，我因为没什么症状，也就没有吃。倒是看到两次，有人去找护士索要治疗腹泻的药，护士跟他说让他如果拉肚子，就不要再继续吃连花清瘟了。</description>
      <content:encoded><![CDATA[<h2 id="发热">发热</h2>
<p>居住的小区在3月18日就开始封闭，在新冠确诊之前，已经经历了十次左右核酸检测。对于如何感染上新冠病毒这件事，如今只能猜测核酸检测时密集接触，或是快递包裹上带有病毒。</p>
<h2 id="酒店">酒店</h2>
<p>我是4月3日晚上10点多被拉去酒店隔离的，在酒店6天没见到防疫人员，只有一个酒店工作人员在微信上负责对接。酒店只有4层、5层，我是在4层和女朋友一起隔离。</p>
<p>虽然没有明确的后续流程告知，但是酒店里，条件还是比较好的，至少能保证一家人或者单人一间隔离，大家也都比较谨慎，在我们几个自发的志愿者提醒下，基本没有出门走动的，饭的话是由安保大白送到楼上，再由我们几个志愿者分发到房间门口。志愿者里有位大叔非常热心，向酒店申请了喷壶、消毒药片，在酒店4层，算上我总共有4人做志愿者，两人负责做走廊消杀，两人负责发放餐食、物资。在每次活动前，我们都互相先把身上喷一下消毒水，戴好医用手套。个人觉得，在酒店里，应该不少人都已经转阴了。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/medicine-in-hotel.jpg" alt="连花清瘟、中药"  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/foods-in-hotel.jpg" alt="酒店的餐食"  />
</p>
<p>关于消毒药片有个小悲剧，我们在把消毒药片发到房门口后，在群里发文字跟大家说，这个是放到马桶水箱里面的。但可能又是因为消毒药片和一小袋中药是一起发放的，有位阿姨不识字，误服了消毒药片，在10点多赶紧拨打了120送去急救。内心当时非常难受，觉得愧疚万分。后续在群里发的各种消息，改成了语音发一遍，文字再发一遍的形式。</p>
<p>酒店的几天里，很多人也都询问何时做核酸，但是也没有得到答复。到了9号下午，在我们几个志愿者清运完各个房间的垃圾之后（进入酒店第二天发放的黄袋子，要一段时间，才会统一清运一次）。回到房间后，我看到酒店工作人员在群里发了一个名单，通知转运第一批人，让大家收拾好，但是没有通知去哪里。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/packaged-waste.jpg" alt="清运房间里的垃圾"  />
</p>
<p>到了晚上，又通知先不转运，第二天再转运。然后我就先去睡了，到了10号凌晨2点，被外面一阵敲打声吵醒，也不知道是什么声音，看了一下手机，才发现，10点的时候，酒店工作人员又通知说，大家快做好准备，要出发了，同时发了一个第二批转运的名单。在凌晨2点我醒了的时候，才发现，第二批名单已经先行转运走了（也就是说，第二批名单上的人，被临时通知没几个小时，在不知道目的地的情况下，就出发了）。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/transfer-or-not.jpg" alt="变来变去的转运时间"  />
</p>
<p>没在这两批名单的人就很紧张，觉得在酒店隔离可能已经转阴，害怕去了方舱再次被传染，有人提议一起去12345登记投诉。后续他们就在酒店做抗原、核酸检测了，虽然到了方舱的第二天看到这个消息，也有不满，但发现后面新进入酒店的感染者多是老人、儿童，心里还是比较支持的了。</p>
<p>作为第一批名单的人，最终接到的消息是等待大巴把第二批名单的人送到后，会回来再接。此时我们只能盼着，方舱医院不要太混乱，至少大家在酒店的隔离都是小心谨慎。</p>
<h2 id="方舱">方舱</h2>
<p>应该是3点左右吧，开始通知第一批名单的人下楼，到了车上，又等了半个多小时，所有人才到齐（一些人跟我一样，早早睡下了，没看到消息）。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/camp.jpg" alt="方舱"  />
</p>
<p>快到五点，终于到了方舱医院，在一位早到的病患指导下，去空病房抱了被子回到床位，就躺下尝试休息了。在四人一间的活动板房里，听着此起彼伏的呼噜声，熬到了6点多，天亮了。</p>
<p>早饭的混乱打破了我的幻想，大白把之前馊了的盒饭，误当作早饭发放，随后运来的早饭，大白往那边一放，一群人发生了哄抢。再加上大家不戴口罩的聚集洗漱，让我都觉得在酒店时的小心翼翼是种“荒唐”。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/chaos-in-camp.jpg" alt="“运行平稳”的“医院”"  />
</p>
<p>经过早餐的混乱，再次形成了靠病患自己组织成的志愿者分发餐食的秩序。</p>
<p>虽然看着“今日闵行”公众号写着“物资保障良好”，但是我在方舱的几天里，在我后面来的一批病患，一直没拿到过洗漱用品，再加上前三天的高温天气，感觉他们真的难过。还有就是总共1500人左右的方舱，只有三台净水器能够打热水，每次接热水都是排长龙。（PS：我在隔离前，所幸是收拾了一堆东西去的，包括电热水壶）。</p>
<p>前三天，每天1人只有1瓶矿泉水。这三天里，志愿者们多次找大白反馈物资问题，可得到的答复总是已向上面反馈，可天知道，这上面到底是谁。在第三天下午，我在教室避暑的时候，突然听到外面跑过一群人，一阵喧闹，过了一会儿出去看，发现是最初牵头的志愿者，实在是无法忍耐，和大白们起了冲突，到了大门口，打开大门，跑到了门外，大白尝试关门，我们把他拉了进来，让大门开着。现在想来，也实在惊险，如果只是他个人被关在门外，怕是要被扣上一个破坏防疫的罪名了。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/protest.jpg" alt="抗议"  />
</p>
<p>在两辆警车依次来到之后，又来了一辆满载身着防护服的特警的车辆。这里不细说了，只说最后结论，依然没有一个方舱医院的负责人露面，只有一名警官负责协调，反馈了三天无法解决的喝水问题，最终方案是当天下午会再送来一批矿泉水，烧水壶会之后解决，并且除三餐外，会增加水果酸奶。</p>
<p>和我想的不同，本以为这样方舱医院步入正常运营的正轨，但是在大白咨询了上级领导矿泉水发放方式后，让大家自己去拿，随后又一波哄抢发生了。后来改为排队领取，再次群体密集聚集。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/still-in-chaos-1.jpg" alt="群体密集聚集领水"  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/still-in-chaos-2.jpg" alt="抗议的第二天（入院的第四天）早上的核酸检测，大白们依然无组织，直接通知全员做核酸，先需要排队找核酸贴纸，再是排队去做检测，真的是失望……明明可以按照之前的形式，分病区做检测，但就是没有人愿意把事情做好，就变成了“&lt;strong&gt;有决定权的人不做事（或者说也根本不在乎效率、科学与防疫），做事的人没有决定权（同时也没有主观能动性）&lt;/strong&gt;”"  />
</p>
<p>抗议的第二天（入院的第四天）早上的核酸检测，大白们依然无组织，直接通知全员做核酸，先需要排队找核酸贴纸，再是排队去做检测，真的是失望……明明可以按照之前的形式，分病区做检测，但就是没有人愿意把事情做好，就变成了“<strong>有决定权的人不做事（或者说也根本不在乎效率、科学与防疫），做事的人没有决定权（同时也没有主观能动性）</strong>”。</p>
<p>入院的第五天，实在看不下去依旧混乱，我提前去护士站找护士要来了我所在病区的核酸检测贴纸和试管（护士站其实也按病区已经提前分好了贴纸，但不知道为什么前一天会无序排队），发到了每个房间，让大家等会儿人少一些，再去排队。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/still-in-chaos-3.jpg" alt="出院短信、低效排队领取出院小结"  />
</p>
<p>再次混乱无序的排队领取出院小结，虽然明明出院小结是按照病区、床号顺序已经打印好，只要按照病区来叫，会很快的分发完毕，但发放形式依然是通知大家出来排队领取……这个时候我已经无力吐槽了。</p>
<p>然后也不意外，出院登车也是依旧混乱，一边在排队领出院小结，另一边在等待排队登车。虽然出院前大家都已经扫码登记了出院目的地，但依然不采用提前按目的地（镇或街道）分批排队登车的形式。最后各辆大巴上，平均目的地要跑5、6个镇。所有人都很累，病患、大白、司机、镇上分流点等待的工作人员……但所有人却都主动或被动地选择了这种方式。</p>
<p>深夜，大巴车继续在空荡的街道上缓缓前行……</p>
<h2 id="感谢">感谢</h2>
<p>感谢酒店里名为“莫言”的工作人员，尽可能地帮助协调各种问题！</p>
<p>感谢各位病患志愿者，大家都在尝试，让这个世界尽量少一些糟糕！</p>
<p>感谢各位医护人员，各位大白，虽然我对你们的工作模式多有不满，可前三天里最高31度的高温下，防护服下的你们也的确辛苦！</p>
<h3 id="再补几张照片">再补几张照片</h3>
<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/lunch-in-camp.jpg"/> <figcaption>
            ⬆️ 方舱隔离的午餐
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/toilet-1.jpg"/> <figcaption>
            ⬆️ 方舱厕所
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/toilet-2.jpg"/> <figcaption>
            ⬆️ 在1500人左右的方舱里，厕所环境迅速恶化，几个志愿者讨论后把厕所分区，自己清理了厕所里堆积在角落的厕纸。虽然已经告知大家可以把厕纸直接冲走，但大家的习惯可能一时难改……又或者说，这件事由工作人员广播告知，更有信服力。
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/bug.jpg"/> <figcaption>
            ⬆️ 方舱里爬行的虫子
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/bathroom.jpg"/> <figcaption>
            ⬆️ 淋浴隔间，但境遇同厕所，环境很快恶化，照明也在几天后损坏
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2022/04/16/covid19-camp-12-days/resources/the-entry-after-ranning.jpg"/> <figcaption>
            ⬆️ 一场大雨后的入院登记处
        </figcaption>
</figure>

<p>哦，对了还有，方舱里也是没有药的，只有入院时发放的两盒连花清瘟颗粒，我因为没什么症状，也就没有吃。倒是看到两次，有人去找护士索要治疗腹泻的药，护士跟他说让他如果拉肚子，就不要再继续吃连花清瘟了。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>再见 2021</title>
      <link>https://hiwangzi.com/posts/2021/12/31/goodbye-2021/</link>
      <pubDate>Fri, 31 Dec 2021 23:14:45 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2021/12/31/goodbye-2021/</guid>
      <description>距离2021结束还有2个多小时，此刻的我已经昏昏沉沉，眼皮耷拉。
或许是只有近期才会记忆深刻，或许是上半年确实没什么值得记忆，只有最近几个月的事还留在脑海中。
十月份，去长沙玩耍了一趟 虽然2021里也没有什么特别值得述说的故事，但心态还是有所成长，尤其是在和亲密的人产生争执独处的日子里。或许是开心的日子，就迷迷糊糊一不留神，就从指尖溜走；又或许是那些快乐也只是庸人的傻乐。但总之，2021让我真正再次审视自己是发生在最后的两个月里。
以下是12月月初写下的文字：
2021年，最后30天，即将跟25岁告别，还是挺恍惚的，一个数字就这样到了自己的眼前。
前段时间看的一期圆桌派，窦文涛讲到，重大的心态改变或者说人生转变，都是发生在旅途中，或者是突然出现的意外后。大意是说，只有当自己独处之时，才会真正地思考自己。
那最近这段日子，或许就属于我的这个阶段吧。
历史上自己想做过的事情很多，而真正做成的事情寥寥无几，仿佛生命无限长，总是能有那么一个未来，成为自己想象中的自己。以上这种想法也并不是第一次才想到，之前每次的结论都是相似，在“要从现在开始珍惜每一天，认真做事，过好每一天”这样的话语下，继续在一天天的生活和无痕的时光里，沉湎。
而这次，感觉似乎有那么一些不一样。此刻的我，开始觉得，生活或许就是这样，值得纪念的日子总是少数。之前总是崇尚于宏大话题，忘记了宏大是由一点点小事构成的，反复提及宏大，或许只是因为从未迈开过第三步，第一步壮志凌云，第二步咬牙切齿，然后，就没有然后了。
何苦迷恋于自己心中的完美呢。60分OK，80分很棒，总会有日子，成为值得纪念的某天。
不过，切实可行的目标，还是要有的，希望在这2021年的尾巴里，做成以下几件事：
再减重5KG Target: 82KG 读完《Java编程的逻辑》 学完《赖世雄音标》 读完《Animal Farm》 谨此。以上。
那现在，要对自己做一个汇报。
在汇报开始之前，要纠正上文中的一个高预期错误，希望做成的第一件事中的82KG就是加倍之后的要求，11月30日的体重是89KG，所以实际目标应该为84KG。对于目标，总是盲目乐观，是自己的一个问题，希望在2022年，能慢慢调整这一点。至少，目标估计得要准确一些。
对了，还有自己在这段时间里，想到了「自己为什么不喜欢打游戏」这个问题的答案。是因为自己总想成为一个天赋者，总希望自己能被大家道出 wow。然而现实是，我在知道自己是不是所谓天赋者的反面之前，就因为不能实现这个高高的目标，在笨拙之中离开，似乎使自己保留了一种体面。然而现在意识到之后，很想对当时的自己说，「大可不必，没有那么多聚光灯投射在身上，做自己就好了。而且终有一天，你会说出『I don’t give a shit』」。
2021年12月31日 体重 86.5 KG 虽然目标1没有达成，但11月开始的努力还是力挽狂澜，控制住了发福K线图😂
目标2《Java编程的逻辑》这本书也没读完，在阅读过程之中，发现还是需要再复习一下数据结构与算法，就开始看《数据结构与算法图解》了。
目标3可以说初步完成，但是后半部分的辅音，尤其是这 [ʒ] [n] [ŋ] [l] 四个，对我来说很难，还是需要再多多练习。
目标4在12月14日时，决定放到元旦之后进行。
总结一下，40%的完成率是有的，对于自己还是一个可以接受的结果。虽然过程不总是如意，但有计划指导，还是好过前半年的得过且过。
11月后开始记录的观影记录 2021年的读书记录 2021年的跑步记录 对于2022年，我的愿望/目标：
精进技术，读完之前列的书单 学好英语，能够真正地使用使用这门语言 体魄健壮，生活能够更加健康（80KG以下、每天有效睡眠8小时、吃得健康自律） 那再来2个小目标吧：
读书12本（4本英文书） 跑量达到365✖️2 = 730KM 不管如何，最重要的是认真生活。愿我的朋友们、家人们，愿每个人，都有自己喜欢的生活！</description>
      <content:encoded><![CDATA[<p>距离2021结束还有2个多小时，此刻的我已经昏昏沉沉，眼皮耷拉。</p>
<p>或许是只有近期才会记忆深刻，或许是上半年确实没什么值得记忆，只有最近几个月的事还留在脑海中。</p>
<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/changsha.jpg"/> <figcaption>
            十月份，去长沙玩耍了一趟
        </figcaption>
</figure>

<p>虽然2021里也没有什么特别值得述说的故事，但心态还是有所成长，尤其是在和亲密的人产生争执独处的日子里。或许是开心的日子，就迷迷糊糊一不留神，就从指尖溜走；又或许是那些快乐也只是庸人的傻乐。但总之，2021让我真正再次审视自己是发生在最后的两个月里。</p>
<p>以下是12月月初写下的文字：</p>
<blockquote>
<p>2021年，最后30天，即将跟25岁告别，还是挺恍惚的，一个数字就这样到了自己的眼前。</p>
<p>前段时间看的一期圆桌派，窦文涛讲到，重大的心态改变或者说人生转变，都是发生在旅途中，或者是突然出现的意外后。大意是说，只有当自己独处之时，才会真正地思考自己。</p>
<p>那最近这段日子，或许就属于我的这个阶段吧。</p>
<p>历史上自己想做过的事情很多，而真正做成的事情寥寥无几，仿佛生命无限长，总是能有那么一个未来，成为自己想象中的自己。以上这种想法也并不是第一次才想到，之前每次的结论都是相似，在“要从现在开始珍惜每一天，认真做事，过好每一天”这样的话语下，继续在一天天的生活和无痕的时光里，沉湎。</p>
<p>而这次，感觉似乎有那么一些不一样。此刻的我，开始觉得，生活或许就是这样，值得纪念的日子总是少数。之前总是崇尚于宏大话题，忘记了宏大是由一点点小事构成的，反复提及宏大，或许只是因为从未迈开过第三步，第一步壮志凌云，第二步咬牙切齿，然后，就没有然后了。</p>
<p>何苦迷恋于自己心中的完美呢。60分OK，80分很棒，总会有日子，成为值得纪念的某天。</p>
<p>不过，切实可行的目标，还是要有的，希望在这2021年的尾巴里，做成以下几件事：</p>
<ol>
<li>再减重5KG Target: 82KG</li>
<li>读完《Java编程的逻辑》</li>
<li>学完《赖世雄音标》</li>
<li>读完《Animal Farm》</li>
</ol>
<p>谨此。以上。</p>
</blockquote>
<p>那现在，要对自己做一个汇报。</p>
<p>在汇报开始之前，要纠正上文中的一个高预期错误，希望做成的第一件事中的82KG就是加倍之后的要求，11月30日的体重是89KG，所以实际目标应该为84KG。对于目标，总是盲目乐观，是自己的一个问题，希望在2022年，能慢慢调整这一点。至少，目标估计得要准确一些。</p>
<p>对了，还有自己在这段时间里，想到了「自己为什么不喜欢打游戏」这个问题的答案。是因为自己总想成为一个天赋者，总希望自己能被大家道出 wow。然而现实是，我在知道自己是不是所谓天赋者的反面之前，就因为不能实现这个高高的目标，在笨拙之中离开，似乎使自己保留了一种体面。然而现在意识到之后，很想对当时的自己说，「大可不必，没有那么多聚光灯投射在身上，做自己就好了。而且终有一天，你会说出『I don’t give a shit』」。</p>
<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/weight.jpg"/> <figcaption>
            2021年12月31日 体重 86.5 KG
        </figcaption>
</figure>

<p>虽然目标1没有达成，但11月开始的努力还是力挽狂澜，控制住了发福K线图😂</p>
<p>目标2《Java编程的逻辑》这本书也没读完，在阅读过程之中，发现还是需要再复习一下数据结构与算法，就开始看《数据结构与算法图解》了。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/book.png" alt="《数据结构与算法图解》"  />
</p>
<p>目标3可以说初步完成，但是后半部分的辅音，尤其是这 [ʒ] [n] [ŋ] [l] 四个，对我来说很难，还是需要再多多练习。</p>
<p>目标4在12月14日时，决定放到元旦之后进行。</p>
<p>总结一下，40%的完成率是有的，对于自己还是一个可以接受的结果。虽然过程不总是如意，但有计划指导，还是好过前半年的得过且过。</p>
<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/movie.png"/> <figcaption>
            11月后开始记录的观影记录
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/read.png"/> <figcaption>
            2021年的读书记录
        </figcaption>
</figure>

<figure>
    <img loading="lazy" src="https://hiwangzi.com/posts/2021/12/31/goodbye-2021/resources/running.jpg"/> <figcaption>
            2021年的跑步记录
        </figcaption>
</figure>

<p>对于2022年，我的愿望/目标：</p>
<ul>
<li><input disabled="" type="checkbox"> 精进技术，读完之前列的书单</li>
<li><input disabled="" type="checkbox"> 学好英语，能够真正地使用使用这门语言</li>
<li><input disabled="" type="checkbox"> 体魄健壮，生活能够更加健康（80KG以下、每天有效睡眠8小时、吃得健康自律）</li>
</ul>
<p>那再来2个小目标吧：</p>
<ul>
<li><input disabled="" type="checkbox"> 读书12本（4本英文书）</li>
<li><input disabled="" type="checkbox"> 跑量达到365✖️2 = 730KM</li>
</ul>
<p>不管如何，最重要的是认真生活。愿我的朋友们、家人们，愿每个人，都有自己喜欢的生活！</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>碳水化合物</title>
      <link>https://hiwangzi.com/posts/2021/05/24/carbohydrate/</link>
      <pubDate>Mon, 24 May 2021 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2021/05/24/carbohydrate/</guid>
      <description>最早发现糖中的碳、氢、氧比例都如下，所以把糖也称为碳水化合物（后来发现一些糖也并非这个比例）
$$ \ce{ Cn(H2O)m } $$
单糖 $$ \ce { C6(H2O)6 } $$
可以被人体直接吸收 常见：葡萄糖、果糖、半乳糖 葡萄糖 + 氧气 → 水 + 二氧化碳 + 能量 葡萄糖 → 乳酸 + 能量 （酸奶） 葡萄糖 → 酒精 + 能量 （酿酒） 二糖 $$ \ce { C12(H2O)11 } $$
常见：麦芽糖、蔗糖（最常见）、乳糖 （脱去1分子水）葡萄糖 + 葡萄糖 = 麦芽糖 + 水 （脱去1分子水）葡萄糖 + 果糖 = 蔗糖 + 水 （脱去1分子水）葡萄糖 + 半乳糖 = 乳糖 + 水 二糖可以水解，然后被人体吸收 代糖 不一定是糖，只要一点点就很甜 多糖 碳原子超过100个 常见： 水解：淀粉（大米、白面）→ 半糖 糖原 ←(合成/分解)→ 单糖 -(合成)→ 脂肪 纤维素：木头、棉花、蔬菜、粗粮 几丁质：甲壳动物的壳 参考 “元气森林”真的没有糖吗？人类为什么喜欢吃糖？ - YouTube </description>
      <content:encoded><![CDATA[<p>最早发现糖中的碳、氢、氧比例都如下，所以把糖也称为碳水化合物（后来发现一些糖也并非这个比例）</p>
<p>$$
\ce{ Cn(H2O)m }
$$</p>
<h2 id="单糖">单糖</h2>
<p>$$
\ce { C6(H2O)6 }
$$</p>
<ul>
<li>可以被人体直接吸收</li>
<li>常见：葡萄糖、果糖、半乳糖</li>
<li>葡萄糖 + 氧气 → 水 + 二氧化碳 + 能量</li>
<li>葡萄糖 → 乳酸 + 能量 （酸奶）</li>
<li>葡萄糖 → 酒精 + 能量 （酿酒）</li>
</ul>
<h2 id="二糖">二糖</h2>
<p>$$
\ce { C12(H2O)11 }
$$</p>
<ul>
<li>常见：麦芽糖、蔗糖（最常见）、乳糖
<ul>
<li>（脱去1分子水）葡萄糖 + 葡萄糖 = 麦芽糖 + 水</li>
<li>（脱去1分子水）葡萄糖 + 果糖 = 蔗糖 + 水</li>
<li>（脱去1分子水）葡萄糖 + 半乳糖 = 乳糖 + 水</li>
</ul>
</li>
<li>二糖可以水解，然后被人体吸收</li>
</ul>
<h2 id="代糖">代糖</h2>
<ul>
<li>不一定是糖，只要一点点就很甜</li>
</ul>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2021/05/24/carbohydrate/resources/sugar-substitute.jpg" alt="代糖"  />
</p>
<h2 id="多糖">多糖</h2>
<ul>
<li>碳原子超过100个</li>
<li>常见：
<ul>
<li>水解：淀粉（大米、白面）→ 半糖</li>
<li>糖原     ←(合成/分解)→    单糖     -(合成)→    脂肪</li>
<li>纤维素：木头、棉花、蔬菜、粗粮</li>
<li>几丁质：甲壳动物的壳</li>
</ul>
</li>
</ul>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2021/05/24/carbohydrate/resources/polysaccharide.jpg" alt="多糖"  />
</p>
<h2 id="参考">参考</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=sNQ8uAAIHnc">“元气森林”真的没有糖吗？人类为什么喜欢吃糖？ - YouTube</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>截图 | 识别二维码</title>
      <link>https://hiwangzi.com/posts/2020/05/21/mac-scan-qr-code-from-pasteboard-after-screen-capture/</link>
      <pubDate>Thu, 21 May 2020 12:05:27 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2020/05/21/mac-scan-qr-code-from-pasteboard-after-screen-capture/</guid>
      <description>macOS中截图后识别二维码</description>
      <content:encoded><![CDATA[<h3 id="目的">目的</h3>
<ul>
<li>不想掏出手机扫描二维码</li>
<li>不想保存成文件，再使用解析工具（太麻烦</li>
</ul>
<h3 id="目标">目标</h3>
<ul>
<li>截图后可以自动识别二维码内容</li>
</ul>
<h3 id="使用说明">使用说明</h3>
<ul>
<li>需要安装：<code>pngpaste</code>, <code>zbar</code> (使用 homebrew 安装: <code>brew install pngpaste zbar</code>）</li>
<li>使用截图软件，保存至剪贴板后，执行以下命令</li>
</ul>
<pre tabindex="0"><code>pngpaste - | zbarimg -q PNG:- | awk -F &#39;QR-Code:&#39; &#39;{print $2}&#39;
</code></pre><h3 id="演示">演示</h3>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2020/05/21/mac-scan-qr-code-from-pasteboard-after-screen-capture/resources/demo.gif" alt="操作演示"  />
</p>
<ul>
<li>我使用的截图软件 <a href="https://apps.apple.com/us/app/xnip-screenshot-annotation/id1221250572">Xnip</a></li>
<li>此处我为上述命令定义了别名 <code>dqr</code></li>
<li>演示中的二维码（你也可以试一试
<img loading="lazy" src="https://hiwangzi.com/posts/2020/05/21/mac-scan-qr-code-from-pasteboard-after-screen-capture/resources/qrcode-hiwangzi.com.png" alt="本站二维码"  />
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Hugo Now</title>
      <link>https://hiwangzi.com/posts/2019/04/17/hugo-now/</link>
      <pubDate>Wed, 17 Apr 2019 18:15:45 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2019/04/17/hugo-now/</guid>
      <description>从 Hexo 切换到 Hugo！</description>
      <content:encoded><![CDATA[<p>因为切换了博客生成器，<strong>订阅地址发生了变化</strong>，请订阅 <a href="https://hiwangzi.com/index.xml">新地址</a>。</p>
<p>昨天晚上开始折腾将 Hexo 替换为 Hugo 来生成博客，以下是关于我对于 Hugo 的一些配置。</p>
<ul>
<li>修改 <code>archetypes/default.md</code>，默认模版增加了 <code>summary</code>、<code>tags</code> 字段。</li>
<li>建立 <a href="https://github.com/hiwangzi/blogs/tree/15cf97bf639312217d719493915c0f05d46d0797/config"><code>config</code> 目录</a>代替原有的 <code>config.toml</code>，根据<a href="https://gohugo.io/getting-started/configuration/#configuration-directory">官方文档说明</a>，创建了默认（均先加载该配置，然后加载其他配置）以及两个环境下的配置目录（<code>development</code>、<code>production</code>）。这样就可以实现默认情况下 <code>hugo server</code> 调用 <code>development</code> 配置，<code>hugo</code> 调用 <code>production</code> 配置。</li>
<li>通过 Git 子模块的形式，引入主题 <a href="https://themes.gohugo.io/tale-hugo/">tale</a>，根据主题的文档说明，做了如下操作：
<ul>
<li><a href="https://github.com/hiwangzi/blogs/tree/15cf97bf639312217d719493915c0f05d46d0797/layouts">覆盖了部分页面配置</a>，目的是自定义菜单栏、加载 Disqus 评论插件。</li>
<li><a href="https://github.com/hiwangzi/blogs/tree/15cf97bf639312217d719493915c0f05d46d0797/static">覆盖了 favicon 静态资源</a>，实现自定义站点 icon 图标。</li>
</ul>
</li>
<li>通过修改配置文件，将生成结果放置到 <code>docs</code> 目录下。这样可以通过配置 GitHub 项目的 Pages 获取方式，来实现页面的渲染。
<img loading="lazy" src="https://hiwangzi.com/posts/2019/04/17/hugo-now/resources/github-pages-config.png" alt="GitHub Pages配置方式"  />
</li>
<li>通过 Hugo 的 <a href="https://gohugo.io/content-management/taxonomies/">taxonomies 机制</a>，实现标签。</li>
</ul>
<h3 id="感受">感受</h3>
<ul>
<li>比起 Hexo，Hugo 的速度真的快很多。</li>
<li>项目中可以摆脱复杂的 npm 依赖，也可以减少一个系统级的 npm 包。</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>java.util.List 的 remove(int) 与 remove(Object)</title>
      <link>https://hiwangzi.com/posts/2018/07/08/java-util-list-remove-int-remove-object/</link>
      <pubDate>Sun, 08 Jul 2018 11:29:16 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2018/07/08/java-util-list-remove-int-remove-object/</guid>
      <description>最近看到 V2EX 上一个帖子《关于 Java foreach 循环删除多个元素的有趣问题（不是抛异常哦）》，我根据代码预测的执行结果与实际楼主贴出的并不相同。看了评论，才发现自己忽略了一点，觉得有点意思，因此记录一下。</description>
      <content:encoded><![CDATA[<p>最近看到 V2EX 上一个帖子<a href="https://www.v2ex.com/t/465153">《关于 Java foreach 循环删除多个元素的有趣问题（不是抛异常哦）》</a>，我根据代码预测的执行结果与实际楼主贴出的并不相同。看了评论，才发现自己忽略了一点，觉得有点意思，因此记录一下。</p>
<p>帖子正文中贴出的代码为：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.ArrayList<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> java.util.List<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">ForeachTest</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">main</span><span style="color:#f92672">(</span>String<span style="color:#f92672">[]</span> args<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>        List<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">&gt;</span> test <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ArrayList<span style="color:#f92672">&lt;&gt;();</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">;</span> i <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">100</span><span style="color:#f92672">;</span> i<span style="color:#f92672">++)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>            test<span style="color:#f92672">.</span><span style="color:#a6e22e">add</span><span style="color:#f92672">(</span>i<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>        System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>test<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">;</span> i <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">50</span><span style="color:#f92672">;</span> i<span style="color:#f92672">++)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> t <span style="color:#f92672">:</span> test<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>                System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>t<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>                test<span style="color:#f92672">.</span><span style="color:#a6e22e">remove</span><span style="color:#f92672">(</span>t<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">break</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>test<span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>我预测的执行结果：</p>
<pre tabindex="0"><code>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
0
1
2
3
……此处省略
47
48
49
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
</code></pre><p>实际执行结果：</p>
<pre tabindex="0"><code>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
0
1
1
1
……此处省略
1
1
1
[1, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
</code></pre><p>我预测的理由是，每次最内层的循环只执行一次，并且移除第一个元素。但我忽略了一点，楼主贴出的代码之中，实际调用的是 <code>remove(int)</code> 方法，而不是 <code>remove(Object)</code> 方法。前者是根据下标移除对应元素，后者是移除对应的元素。第一次循环之中，移除了第0个元素（<code>test.get(0)</code>值为<code>0</code>），随后的循环，均移除第1个元素（<code>test.get(0)</code>值为<code>1</code>）。</p>
<p>因此，将 <code>for (int t : test)</code> 更改为 <code>for (Integer t : test)</code>，即可实现预测中的输出。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>译｜在 URLs 中使用 JSON</title>
      <link>https://hiwangzi.com/posts/2018/05/14/json-in-urls/</link>
      <pubDate>Mon, 14 May 2018 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2018/05/14/json-in-urls/</guid>
      <description>除了在 URL 中使用路径作为参数或使用查询参数之外，是否还有更好的选择呢？</description>
      <content:encoded><![CDATA[<blockquote>
<p>原文地址：<a href="https://blogs.dropbox.com/developers/2015/03/json-in-urls/">JSON in URLs | Dropbox Developer Blog</a></p>
</blockquote>
<p>基于 HTTP 的 API 经常将参数编码为 URL 路径或查询参数。例如，调用丢丢盒（Dropbox）API 搜索文件名时的路径可能如下所示：</p>
<pre tabindex="0"><code>/1/search/auto/My+Documents?query=draft+2013
</code></pre><p>虽然对于简单的例子而言，使用 URL 编码似乎已经足够完美，但使用 JSON 可能也有一些优点。</p>
<h2 id="混乱的-url-路径">混乱的 URL 路径</h2>
<p>在上面的例子中，因为第一个 <code>+</code> 就在 URL 之中，所以其就是字面意义上的加号。而第二个 <code>+</code> 表示一个空格，因为它位于 URL 查询部分。这两者很容易混淆，因为他们的编码规则在大多数情况下是相同的，而且就像 <code>urlencode</code> 一样，有时一些库提供的函数的名字又非常模棱两可。我们 SDK 的一个早期版本就因此有过一个 bug。</p>
<p>另一个常见的错误就是误认为在路径部分 <code>/</code> 同其他普通字符一样。</p>
<ul>
<li><code>/hello-world</code> 等价于 <code>/hello%2Dworld</code></li>
<li><code>/hello/world</code> <strong>不</strong>等价于 <code>/hello%2Fworld</code></li>
</ul>
<p>符号 <code>/</code> 是保留的分界符。将其改为使用 <code>%</code> 编码的形式会改变 URL 的含义。大多数 URL 编码库并没有非常清晰地对两者作出区分。虽然大多数情况下这不重要，<a href="https://sakurity.com/blog/2015/03/15/authy_bypass.html">但某些情况却非常关键</a>。</p>
<h2 id="url-查询参数表现力不足">URL 查询参数表现力不足</h2>
<p>假设 API 参数需要一组值时，该怎么处理呢？一些 API 可能使用逗号或重复的名字来处理。</p>
<pre tabindex="0"><code>/docs/salary.csv?columns=1,2
/docs/salary.csv?column=1&amp;column=2
</code></pre><p>对于嵌套的字段，一些 API 可能如下处理：</p>
<pre tabindex="0"><code>/emails?from[name]=Don&amp;from[date]=1998-03-24&amp;to[name]=Norm
</code></pre><p>这些变通都是合理的，但他们仍然只是变通之举。并没有普遍的标准。但 JSON 可以一致、简单的处理嵌套。</p>
<h2 id="使用-url-编码是否很糟糕呢">使用 URL 编码是否很糟糕呢？</h2>
<p>不，它只是为不同的情况设计的：人类交互使用。</p>
<p>JSON 将一切字符串用引号包裹。这让许多事情变得更简单以及更健壮，但对于人们来说，读与写可能略显乏味单调。</p>
<p>相较于 JSON，URL 参数可以更快的开始使用。在通常情况下，这非常不错。但缺点就是更容易造成混乱，因此任何处理 URL 参数的代码都会变得很复杂。</p>
<p>这里要做一些合理的权衡。 我不会在我的浏览器地址栏使用 JSON，但对于基于 HTTP 的 API 来说，使用 JSON 来处理可能是一个更好的选择。</p>
<h2 id="所以问题在哪儿呢">所以问题在哪儿呢？</h2>
<p>当思考到这的时候，我们可以说对比于 URL 编码，使用 JSON 在某些方面更佳。对于结构化的数据，HTTP API 响应已经基本上都在使用 JSON 了。最近一次我处理 URL 编码的响应体是在 2007 年时使用 OAuth 1。目前 OAuth 2 已经使用 JSON 了。</p>
<p>API 请求体分裂成了 JSON 和 URL 编码两种形式。URL 编码的一个好处是<a href="https://stripe.com/docs/api/curl#create_charge">你可以很好的使用 <code>curl</code> 命令行工具做示例</a>。但很多 API，包括丢丢盒新一些的 API，已经开始在请求体中使用 JSON。</p>
<p>所以为什么不在 URL 中同样使用 JSON 呢？就像下面这样：</p>
<ul>
<li>URL encoded: <code>/log?a=b&amp;c=4</code></li>
<li>JSON in URL: <code>/log?%7B%22a%22:%22b%22,%22c%22:4%7D</code></li>
</ul>
<p>第一点，JSON 形式更长了。这可能会导致你的 URL 超出<a href="https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184#417184">长度限制</a>。</p>
<p>同时，它看起来很丑，但这可以通过抽象来解决。例如，除非在 packet 层面上出现了错误，否则你也无需去处理原始网络 packet。同样的道理，除非你的 URL 出现错误，否则你无需去接触丑陋版本的 URL。一旦它通过了检测，你在错误消息或日志输出中看到的就只是解码过的字符串了。</p>
<p>创建一个整理抽象层需要花费额外的工作，尤其过去从未使用过类似方式。虽然在 URL 中使用 JSON 前期会有一些烦恼，但它带来的好处值得让人一试。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>译｜if(a - b &lt; 0) 与 if(a &lt; b) 的区别</title>
      <link>https://hiwangzi.com/posts/2018/05/08/difference-between-if-a-b-0-and-if-a-b/</link>
      <pubDate>Tue, 08 May 2018 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2018/05/08/difference-between-if-a-b-0-and-if-a-b/</guid>
      <description>一个针对此问题 Stack Overflow 上的回答。</description>
      <content:encoded><![CDATA[<h2 id="目录">目录</h2>
<ul>
<li><a href="#%E9%97%AE%E9%A2%98">问题</a></li>
<li><a href="#%E8%B5%9E%E5%90%8C%E6%9C%80%E5%A4%9A%E7%9A%84%E5%9B%9E%E7%AD%94">赞同最多的回答</a></li>
</ul>
<blockquote>
<p>原文地址：<a href="https://stackoverflow.com/questions/33147339/difference-between-if-a-b-0-and-if-a-b">java - Difference between if (a - b &lt; 0) and if (a &lt; b) - Stack Overflow</a></p>
</blockquote>
<h2 id="问题">问题</h2>
<p>在阅读 Java 的 <code>ArrayList</code> 源代码时，我注意到在 <code>if</code> 语句中的一些比较语句。</p>
<p>在 Java 7 之中，<a href="https://github.com/openjdk/jdk7/blob/7772c7a0446e7036773890e72e771a3e222cb4c7/jdk/src/share/classes/java/util/ArrayList.java#L204"><code>grow(int)</code></a> 方法使用了如下代码：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>newCapacity <span style="color:#f92672">-</span> minCapacity <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    newCapacity <span style="color:#f92672">=</span> minCapacity<span style="color:#f92672">;</span>
</span></span></code></pre></div><p>在 Java 6 中，没有 <code>grow</code> 方法。但方法 <a href="https://github.com/openjdk/jdk6/blob/3e49aa876353eaa215cde71eb21acc9b7f9872a0/jdk/src/share/classes/java/util/ArrayList.java#L180"><code>ensureCapacity(int)</code></a> 却使用如下方式比较数值：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>newCapacity <span style="color:#f92672">&lt;</span> minCapacity<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    newCapacity <span style="color:#f92672">=</span> minCapacity<span style="color:#f92672">;</span>
</span></span></code></pre></div><p>变更比较语句写法的原因是什么呢？为了性能还是说只是代码风格的变化？</p>
<p>我可以理解，与 0 作比较速度更快，但同时却需多执行一个减法，这不是额外的开销吗？同时对于编译后的字节码来说，做差比较需要涉及两个指令（<code>ISUB</code> 和 <code>IF_ICMPGE</code>），而直接比较只需要涉及 <code>IFGE</code> 一条指令。</p>
<h2 id="赞同最多的回答">赞同最多的回答</h2>
<p><code>a &lt; b</code> 与 <code>a - b &lt; 0</code> 可以表示不同的含义。</p>
<p>考虑如下场景：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> a <span style="color:#f92672">=</span> Integer<span style="color:#f92672">.</span><span style="color:#a6e22e">MAX_VALUE</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> b <span style="color:#f92672">=</span> Integer<span style="color:#f92672">.</span><span style="color:#a6e22e">MIN_VALUE</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>a <span style="color:#f92672">&lt;</span> b<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;a &lt; b&#34;</span><span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>a <span style="color:#f92672">-</span> b <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;a - b &lt; 0&#34;</span><span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><p>执行结果是：只会打印 <code>a - b &lt; 0</code>。因为 <code>a &lt; b</code> 显然是 false，但 <code>a - b</code> 产生了溢出，结果是 <code>-1</code>，因此结果为 true。</p>
<ul>
<li>译者注：
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">int</span> max <span style="color:#f92672">=</span> Integer<span style="color:#f92672">.</span><span style="color:#a6e22e">MAX_VALUE</span><span style="color:#f92672">;</span> <span style="color:#75715e">//  2147483647
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> min <span style="color:#f92672">=</span> Integer<span style="color:#f92672">.</span><span style="color:#a6e22e">MIN_VALUE</span><span style="color:#f92672">;</span> <span style="color:#75715e">// -2147483648
</span></span></span></code></pre></div></li>
</ul>
<p>说回问题本身，我们假设数组长度本身已经非常接近于 <code>Integer.MAX_VALUE</code> 来看一看。<code>ArrayList</code> 之中的代码如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#75715e">// 译者注：可以查看问题中的第一个链接 grow(int) 方法
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">int</span> oldCapacity <span style="color:#f92672">=</span> elementData<span style="color:#f92672">.</span><span style="color:#a6e22e">length</span><span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">int</span> newCapacity <span style="color:#f92672">=</span> oldCapacity <span style="color:#f92672">+</span> <span style="color:#f92672">(</span>oldCapacity <span style="color:#f92672">&gt;&gt;</span> <span style="color:#ae81ff">1</span><span style="color:#f92672">);</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>newCapacity <span style="color:#f92672">-</span> minCapacity <span style="color:#f92672">&lt;</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    newCapacity <span style="color:#f92672">=</span> minCapacity<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>newCapacity <span style="color:#f92672">-</span> MAX_ARRAY_SIZE <span style="color:#f92672">&gt;</span> <span style="color:#ae81ff">0</span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    newCapacity <span style="color:#f92672">=</span> hugeCapacity<span style="color:#f92672">(</span>minCapacity<span style="color:#f92672">);</span>
</span></span></code></pre></div><p><code>oldCapacity</code> 非常接近 <code>Integer.MAX_VALUE</code>，因此 <code>newCapacity</code>（即<code>oldCapacity + 0.5 * oldCapacity</code>）有可能产生溢出，假设溢出后值为 <code>Integer.MIN_VALUE</code> (负值)。然后，减去 <code>minCapacity</code> 又<strong>下溢</strong>变为正值（译者注：假设参数<code>minCapacity</code>为正值）。</p>
<p>因此第一个 <code>if</code> 块中的代码将不会被执行。但假设代码条件写作 <code>if (newCapacity &lt; minCapacity)</code>，结果将会是 <code>true</code>（因为 <code>newCapacity</code> 是负值），这将导致 <code>newCapacity</code> 被强行指定为 <code>minCapacity</code> 而没有考虑 <code>oldCapacity</code>。</p>
<p>这个溢出问题将会被下一个 <code>if</code> 语句所处理。当 <code>newCapacity</code> 溢出后，此 <code>if</code> 的结果为 <code>true</code>：<code>MAX_ARRAY_SIZE</code> 为 <code>Integer.MAX_VALUE - 8</code>，所以 <code>Integer.MIN_VALUE - (Integer.MAX_VALUE - 8) &gt; 0</code> 为 <code>true</code>。因此 <code>newCapacity</code> 可以被正确的处理：<code>hugeCapacity</code> 方法将返回 <code>MAX_ARRAY_SIZE</code> 或 <code>Integer.MAX_VALUE</code>。</p>
<p>注意：这就是对应 Java 代码中注释 <code>// overflow-conscious</code> 的含义。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>安装 Arch 中遇到的 Broadcom b43(BCM43228) 网卡问题</title>
      <link>https://hiwangzi.com/posts/2018/03/25/arch-install-with-bcm/</link>
      <pubDate>Sun, 25 Mar 2018 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2018/03/25/arch-install-with-bcm/</guid>
      <description>之前按照《以官方 Wiki 的方式安装 ArchLinux》，并结合官方文档，成功的在 VirtualBox 环境下安装好了 Arch。虚拟机限于内存、显卡等因素，体验不够好，因此今天准备在旧笔记本实机安装。在第一步联网过程中，就遇到了阻碍，特此记录。</description>
      <content:encoded><![CDATA[<p>之前按照以 <a href="https://www.viseator.com/2017/05/17/arch_install/">官方 Wiki 的方式安装 ArchLinux</a>，并结合 <a href="https://wiki.archlinux.org/index.php/installation_guide">官方文档</a>，成功的在 VirtualBox 环境下安装好了 Arch。虚拟机限于内存、显卡等因素，体验不够好，因此今天准备在旧笔记本实机安装。在第一步联网过程中，就遇到了阻碍，特此记录。</p>
<h2 id="查看网卡类型">查看网卡类型</h2>
<p>在之前的虚拟机环境下，采用 NAT 模式联网，网卡自动识别并加载，只需要执行 <code>dhcpcd</code> 获取 IP 后即可成功连接互联网。但这次，系统并不能自动驱动硬件工作，所以我们需要先检查一下网卡类型。</p>
<ul>
<li>执行 <code>lspci -k</code> 查看 Network controller 这一项。</li>
</ul>
<pre tabindex="0"><code>02:00.0 Network controller: Broadcom Limited BCM43228 802.11a/b/g/n
Subsystem: Foxconn International, Inc. BCM43228 802.11a/b/g/n
Kernel driver in use: bcma-pci-bridge
Kernel moudles: bcma
</code></pre><ul>
<li>
<p>检查 <code>ip link</code> 输出结果中有没有 <code>wlan0</code> 或 <code>wlps21</code> 一类的设备。如果有的话，只需要执行 <code>ip link set &lt;设备名&gt; up</code> 即可，无需再额外安装驱动程序。</p>
</li>
<li>
<p>如果没有，即需要检查内核的固件信息 <code>dmesg | grep firmware</code>，得到更多提示</p>
</li>
</ul>
<pre tabindex="0"><code>b43-phy0 ERROR: You must go to http://wireless.kernel.or/en/users/Drivers/b43#devicefirmware and download the correct firmware for this driver version.
</code></pre><ul>
<li>如果没有这样的信息，可以先尝试执行 <code>iwlwifi</code> 一类命令，然后查找对应的错误信息 <code>dmesg | grep iwlwifi</code></li>
<li>获得提示信息后，例如上面的网站，可以访问得到进一步的信息。此处根据上述 <code>ERROR</code> 中的网站给出的指导，执行 <code>lspci -nn -d 14e4:</code> 获得详细的硬件型号，并下载<a href="https://aur.archlinux.org/packages/b43-firmware/">对应的驱动</a>。关于博通无线网卡，可以查阅 <a href="https://wiki.archlinux.org/index.php/Broadcom_wireless">Wiki</a> 页面 获得更多信息</li>
</ul>
<h2 id="下载并安装驱动">下载并安装驱动</h2>
<ul>
<li>
<p>没网络怎么下载 ❓ 可以下载至安装U盘的根目录，安装时切换至 <code>/run/archiso/bootmnt</code>，即可看到下载的内容，将其拷贝至 <code>/root</code> 解压。</p>
</li>
<li>
<p>如何来安装驱动 ❓ <a href="https://www.cnblogs.com/clouds008/p/7460928.html">更多参考</a> 在上一步解压完成后，会得到一个 <code>.o</code> 结尾的问题，执行 <code>b43-fwcutter -w /lib/firmware xxx.o</code> 即可完成安装。</p>
</li>
<li>
<p>安装后怎么启动 ❓ <a href="http://linuxwireless.sipsolutions.net/en/users/Drivers/b43/">更多参考</a> 卸载之前的驱动，然后再加载新安装的驱动。</p>
<ul>
<li>卸载旧驱动（如果你知道你正在使用的驱动名称的话，只需执行对应的命令即可）
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>modprobe -r b43 bcma
</span></span><span style="display:flex;"><span>modprobe -r brcmsmac bcma
</span></span><span style="display:flex;"><span>modprobe -r wl
</span></span></code></pre></div></li>
<li>加载新驱动（只需执行对应的驱动命令即可）
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>modprobe b43
</span></span><span style="display:flex;"><span>modprobe brcmsmac
</span></span><span style="display:flex;"><span>modprobe wl
</span></span></code></pre></div></li>
</ul>
</li>
<li>
<p>安装完成后可以通过 <code>ip link</code> 查看是否有新增加的网络接口信息。</p>
</li>
</ul>
<h2 id="安装完成后的联网过程">安装完成后的联网过程</h2>
<blockquote>
<p>此部分内容主要参考了 <a href="https://linux.cn/article-4015-1.html">在命令行中管理 Wifi 连接</a></p>
</blockquote>
<ul>
<li>
<p>通过 <code>ip link set &lt;设备名&gt; up</code> 启动接口服务。</p>
</li>
<li>
<p>可以通过 <code>iw dev &lt;设备名&gt; scan | less</code> 扫描附近网络。</p>
</li>
<li>
<p>联网（方式 1）无加密网络</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>iw dev &lt;设备名&gt; connect &lt;网络 SSID&gt;
</span></span></code></pre></div></li>
<li>
<p>联网（方式 2）WEP 加密</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>iw dev &lt;设备名&gt; connect &lt;网络 SSID&gt; key 0:&lt;WEP密钥&gt;
</span></span></code></pre></div></li>
<li>
<p>联网（方式 3）WPA/WPA2 加密（现在最常见）</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-txt" data-lang="txt"><span style="display:flex;"><span>network={
</span></span><span style="display:flex;"><span>    ssid=&#34;&lt;网络 SSID&gt;&#34;
</span></span><span style="display:flex;"><span>    psk=&#34;&lt;密码&gt;&#34;
</span></span><span style="display:flex;"><span>    priority=1
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li><code>vim /etc/wpasupplicant/wpa_supplicant.conf</code> 编辑文件（其实放在别的位置也行），增加以上内容（注意包含引号）</li>
<li><code>wpa_supplicant -i &lt;设备名&gt; -c /etc/wpa_supplicant/wpa_supplicant.conf &amp;</code> 后台启动网络连接</li>
</ul>
</li>
<li>
<p>获取 IP：<code>dhcpcd &lt;设备名&gt;</code> 自动获取 IP 地址</p>
</li>
<li>
<p>测试网络：<code>ping hiwangzi.com</code> 测试网络连接是否正常~</p>
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>什么是 Unix</title>
      <link>https://hiwangzi.com/posts/2018/02/03/what-is-unix/</link>
      <pubDate>Sat, 03 Feb 2018 00:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2018/02/03/what-is-unix/</guid>
      <description>关于内核 当计算机启动时，计算机要经历一系列动作，这些动作构成了引导过程。引导过程的最后一个动作是启动一个非常复杂的程序，该程序就被称为内核（Kernel）。 内核的作用是控制计算机，提供基础服务，是操作系统的核心。 内核有许多种类型，但基本可以分为两大类： 单内核：一个庞大的程序自身可以完成所有的事 微内核：一个非常小的程序只执行最基本的任务，其余通过调用其他程序（称为服务器(server)）实现 内核的使用： 大多数 Unix 系统使用的是某种类型的单内核，一些 Unix （例如 OS X，Minix）使用微内核。 Linux 是单内核。 补：Linus 阅读了 Andrew Tanenbaum 的《Operating System: Design and Implementation》，该书解释了 Minix 的设计原则。Linus 选择使用单内核设计 Linux，而 Andrew Tanenbaum 设计的 Minix 使用的是微内核。在 Linux 开始引起注意后不久，Tanenbaum 公开批判这种设计决策。直到今天，Tanenbaum 仍然在批评这种单内核设计。 关于 Unix Unix = Unix 内核 + Unix 实用工具 Unix 过去是属于 AT&amp;amp;T 的商标（必须为大写 UNIX，以下的全大写均指 AT&amp;amp;T 公司的 Unix） 现在可以理解为指代任何 “类Unix” 系统 关于 “类Unix” 的两种理解： 如果操作系统既包含一个 Unix 内核以及一些 Unix 实用工具，又可以运行能够在其他 Unix 操作系统上运行的程序，那么它就是 Unix 系统 如果理解 Unix 的人说这个系统是 Unix，那么它就是 Unix Unix 的历史 20世纪70年代的 Unix：由贝尔实验室转向 Berkeley</description>
      <content:encoded><![CDATA[<h3 id="关于内核">关于内核</h3>
<ul>
<li>当计算机启动时，计算机要经历一系列动作，这些动作构成了引导过程。引导过程的最后一个动作是启动一个非常复杂的程序，该程序就被称为<strong>内核（Kernel）</strong>。</li>
<li>内核的作用是控制计算机，提供基础服务，是<a href="/posts/2017/10/02/vbird-linux-01/#os">操作系统</a>的核心。</li>
<li>内核有许多种类型，但基本可以分为两大类：
<ul>
<li>单内核：一个庞大的程序自身可以完成所有的事</li>
<li>微内核：一个非常小的程序只执行最基本的任务，其余通过调用其他程序（称为服务器(server)）实现</li>
</ul>
</li>
<li>内核的使用：
<ul>
<li>大多数 Unix 系统使用的是某种类型的单内核，一些 Unix （例如 OS X，Minix）使用微内核。</li>
<li>Linux 是单内核。</li>
<li>补：Linus 阅读了 Andrew Tanenbaum 的《Operating System: Design and Implementation》，该书解释了 Minix 的设计原则。Linus 选择使用单内核设计 Linux，而 Andrew Tanenbaum 设计的 Minix 使用的是微内核。在 Linux 开始引起注意后不久，Tanenbaum 公开批判这种设计决策。直到今天，Tanenbaum 仍然在批评这种单内核设计。</li>
</ul>
</li>
</ul>
<h3 id="关于-unix">关于 Unix</h3>
<ul>
<li>Unix = Unix 内核 + Unix 实用工具</li>
<li>Unix 过去是属于 AT&amp;T 的商标（必须为大写 UNIX，以下的全大写均指 AT&amp;T 公司的 Unix）</li>
<li>现在可以理解为指代任何 “类Unix” 系统</li>
<li>关于 “类Unix” 的两种理解：
<ul>
<li>如果操作系统既包含一个 Unix 内核以及一些 Unix 实用工具，又可以运行能够在其他 Unix 操作系统上运行的程序，那么它就是 Unix 系统</li>
<li>如果理解 Unix 的人说这个系统是 Unix，那么它就是 Unix</li>
</ul>
</li>
</ul>
<h3 id="unix-的历史">Unix 的历史</h3>
<ul>
<li>
<p>20世纪70年代的 Unix：由贝尔实验室转向 Berkeley</p>
<ul>
<li>1974年，Berkeley 的 Bob Fabry 教授获得了一份 UNIX 副本，该校的学生们开始增强该系统。</li>
<li>1977年，Bill Joy 装配了第一版的 Berkeley Unix，被称为 BSD(Berkeley Software Distribution)</li>
<li>1979年，AT&amp;T 公司宣布将 UNIX 作为一个商品销售（UNIX System III(&ldquo;Three&rdquo;), UNIX System V(&ldquo;Five&rdquo;)）</li>
<li>1979年，所有的 BSD 用户都被要求购买一个 AT&amp;T 公司的许可证，并且之后每年都在提高许可证的价格。因此，BSD 程序员越来越难以忍受 AT&amp;T 公司的束缚。</li>
</ul>
</li>
<li>
<p>20世纪80年代的 Unix：BSD 与 System V</p>
<ul>
<li>截止至1980年，美国东海岸 Unix（AT&amp;T 的 UNIX）和西海岸的 Unix（BSD）平分秋色，都发展很快。</li>
<li>此时的 UNIX：AT&amp;T 目标是使 UNIX 成为一个成功的商业产品，只面向能够为许可证付大量金钱的公司。1982年，发行了 UNIX System III。1983年，发行了 System V，到年末，System V 安装了 45,000 份。1984年，System V Release 2(SVR2) 发行时，大约安装了 100,000 份。</li>
<li>此时的 BSD：1980年，Berkeley 的 Bob Fabry 教授接到美国国防部高级研究计划局（DARPA，补：1972年前，该机构名为 ARPA，Internet的祖先 Arpanet 也由该机构创造）的一个大合同。Fabry 随后建立了 CSRG(Computer System Research Group) ，该小组一直延续到 1994 年，且在这段时间，对 BSD 和 Unix 在全球的发展产生了重要影响。随后该小组发布的 Unix 版本都受到了学术界与研究社区的高度关注。1982年，4.1BSD支持TCP/IP，成为 Internet 的基础。1983年，4.2BSD发布，全球已有1000份安装。</li>
<li>到 1985 年，Unix 流派就是以上两类。其他形式的 Unix 也都派生自以上两类。</li>
<li>在20世纪80年代末，Unix世界的两大特征：Unix 总体的快速增长和不同类型 Unix 的增殖扩散。</li>
</ul>
</li>
<li>
<p>AT&amp;T 公司的限制</p>
<ul>
<li>1979年，AT&amp;T不允许其公司之外的人查看 UNIX 的源代码</li>
<li>1984年之一：x86 架构的 Minix 操作系统开始编写并于两年后诞生</li>
<li>1984年之二：GNU 计划与 FSF(Free Software Foundation) 基金会的成立</li>
<li>1991年：芬兰大学生 Linux Torvalds 发布了一则简讯，Linux 世界自此开始，随后发展出了数百个发行版</li>
<li>1992年：Bill Jolitz 替换了最后的 6 个 AT&amp;T 公司的内核文件，发行了一个完全与 AT&amp;T 无关的 Unix：386/BSD。后来更名为 FreeBSD。后来衍生出了 NetBSD(可移植到许多种类的计算机)，OpenBSD(关注安全与密码学)。</li>
</ul>
</li>
</ul>
<h3 id="为何-linux-成为了更加流行的-unix">为何 Linux 成为了更加流行的 Unix？</h3>
<ul>
<li>Linux 是基于 GNU GPL 许可发行的，而 GPL 禁止任何人使用 Linux 创建及发行专有系统。而 BSD 许可证远没有 GPL 严格，在 BSD 许可证之下，允许使用部分 BSD 创建新产品而不共享新产品，因此这种情况下，其他人无法从新产品获得好处，也无法使用与修改新产品（但也因为 BSD 许可证的灵活，所以应用也非常广泛）。</li>
<li>Linux 比 FreeBSD 更成功的关键在于发行时机，Linux Torvalds 在 1991 年发行了 Linux 内核，而完全开放源代码的 386/BSD 直到 1992 年才发行。</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>PostgreSQL 满足条件时插入数据</title>
      <link>https://hiwangzi.com/posts/2017/11/23/conditional-insert-into-statement-in-postgres/</link>
      <pubDate>Thu, 23 Nov 2017 22:26:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/11/23/conditional-insert-into-statement-in-postgres/</guid>
      <description>例如：当表中不存在某记录时，才插入这条记录。
INSERT INTO 表名(列名1, 列名2) SELECT &amp;#39;值1&amp;#39;, &amp;#39;值2&amp;#39; WHERE NOT EXISTS ( SELECT * FROM 表名 WHERE 列名1 = &amp;#39;值1&amp;#39;, 列名2 = &amp;#39;值2&amp;#39; ); 参考 PostgreSQL: Documentation: 10: INSERT
This example inserts some rows into table films from a table tmp_films with the same column layout as films:
INSERT INTO films SELECT * FROM tmp_films WHERE date_prod &amp;lt; &#39;2004-05-07&#39;; database - Conditional INSERT INTO statement in postgres - Stack Overflow</description>
      <content:encoded><![CDATA[<p>例如：当表中不存在某记录时，才插入这条记录。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sql" data-lang="sql"><span style="display:flex;"><span><span style="color:#66d9ef">INSERT</span> <span style="color:#66d9ef">INTO</span> <span style="color:#960050;background-color:#1e0010">表名</span>(<span style="color:#960050;background-color:#1e0010">列名</span><span style="color:#ae81ff">1</span>, <span style="color:#960050;background-color:#1e0010">列名</span><span style="color:#ae81ff">2</span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">SELECT</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#39;值1&#39;</span>, <span style="color:#e6db74">&#39;值2&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">WHERE</span> <span style="color:#66d9ef">NOT</span> <span style="color:#66d9ef">EXISTS</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">SELECT</span> <span style="color:#f92672">*</span> <span style="color:#66d9ef">FROM</span> <span style="color:#960050;background-color:#1e0010">表名</span> <span style="color:#66d9ef">WHERE</span> <span style="color:#960050;background-color:#1e0010">列名</span><span style="color:#ae81ff">1</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;值1&#39;</span>, <span style="color:#960050;background-color:#1e0010">列名</span><span style="color:#ae81ff">2</span> <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;值2&#39;</span>
</span></span><span style="display:flex;"><span>);
</span></span></code></pre></div><h2 id="参考">参考</h2>
<ol>
<li>
<p><a href="https://www.postgresql.org/docs/current/static/sql-insert.html">PostgreSQL: Documentation: 10: INSERT</a></p>
<blockquote>
<p>This example inserts some rows into table films from a table tmp_films with the same column layout as films:</p>
<pre><code>INSERT INTO films SELECT * FROM tmp_films WHERE date_prod &lt; '2004-05-07';
</code></pre>
</blockquote>
</li>
<li>
<p><a href="https://stackoverflow.com/questions/15710162/conditional-insert-into-statement-in-postgres">database - Conditional INSERT INTO statement in postgres - Stack Overflow</a></p>
</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>命令行计算 RSA, Base64, Hash</title>
      <link>https://hiwangzi.com/posts/2017/11/20/calculate-rsa-base64-hash-in-terminal/</link>
      <pubDate>Mon, 20 Nov 2017 15:05:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/11/20/calculate-rsa-base64-hash-in-terminal/</guid>
      <description>OpenSSL 是个好工具 👍</description>
      <content:encoded><![CDATA[<h2 id="基础">基础</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># -n 可以去掉换行符</span>
</span></span><span style="display:flex;"><span>echo -n <span style="color:#e6db74">&#39;777777&#39;</span>
</span></span></code></pre></div><h2 id="rsa算法">RSA算法</h2>
<ul>
<li>
<p>加密</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 利用管道命令传递字符串加密</span>
</span></span><span style="display:flex;"><span>echo -n <span style="color:#e6db74">&#39;777777&#39;</span> | openssl rsautl -encrypt -pubin -inkey public_key.pem &gt; message.encrypted
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># （或）利用文件传递字符串加密</span>
</span></span><span style="display:flex;"><span>echo -n <span style="color:#e6db74">&#39;777777&#39;</span> &gt; message.txt
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>openssl rsautl -encrypt -pubin -inkey public_key.pem -in message.txt &gt; message.encrypted
</span></span></code></pre></div></li>
<li>
<p>解密</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl rsautl -decrypt -inkey private_key.pem -in message.encrypted -out message.decrypted
</span></span></code></pre></div></li>
</ul>
<h2 id="base64">Base64</h2>
<ul>
<li>
<p>编码</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl enc -base64 -e -in message.txt &gt; message.base64e
</span></span></code></pre></div></li>
<li>
<p>解码</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>openssl enc -base64 -d -in message.base64 &gt; message.base64d
</span></span></code></pre></div></li>
</ul>
<h2 id="hash">Hash</h2>
<ul>
<li>
<p>MD5</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo -n <span style="color:#e6db74">&#39;777777&#39;</span> | md5sum
</span></span></code></pre></div></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>如此</title>
      <link>https://hiwangzi.com/posts/2017/10/31/so/</link>
      <pubDate>Tue, 31 Oct 2017 21:55:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/10/31/so/</guid>
      <description>抑制偏见，拥抱世界。
&amp;mdash; Zi WANG (@hiwangzi) October 29, 2017 有了记录之后，仍然会觉得，时间眨眼飞逝。
去年的今天，写下了 我的十月 这篇博文，再读来，真的觉得当时的自己的生活还算称得上有趣啦。也许就如花花所说，我一直在粉饰自己过去的时光，所以才总是会觉得现在的自己真是大不如从前。
人虽然总是在变化，可变化有时却没那么快。或许未来的自己会觉得今天的我也并非充足的努力，可此刻的我还是愿意鼓励自我的现状。或许没有去年的十月那么多值得记录的事情，但我知道，自己在踏实的前进。
没有什么更多的事说了，如此&amp;hellip;</description>
      <content:encoded><![CDATA[

<blockquote class="twitter-tweet"><p lang="zh" dir="ltr">抑制偏见，拥抱世界。</p>&mdash; Zi WANG (@hiwangzi) <a href="https://twitter.com/hiwangzi/status/924451304507768834?ref_src=twsrc%5Etfw">October 29, 2017</a></blockquote> <script async src="https://hiwangzi.com/posts/2017/10/31/so/https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>有了记录之后，仍然会觉得，时间眨眼飞逝。</p>
<p>去年的今天，写下了 <a href="/posts/2016/10/31/october-2016/">我的十月</a> 这篇博文，再读来，真的觉得当时的自己的生活还算称得上有趣啦。也许就如花花所说，我一直在粉饰自己过去的时光，所以才总是会觉得现在的自己真是大不如从前。</p>
<p>人虽然总是在变化，可变化有时却没那么快。或许未来的自己会觉得今天的我也并非充足的努力，可此刻的我还是愿意鼓励自我的现状。或许没有去年的十月那么多值得记录的事情，但我知道，自己在踏实的前进。</p>
<p>没有什么更多的事说了，如此&hellip;</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>全栈框架——MEAN</title>
      <link>https://hiwangzi.com/posts/2017/10/25/mean/</link>
      <pubDate>Wed, 25 Oct 2017 17:22:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/10/25/mean/</guid>
      <description>MEAN: MongoDB - Express - AngularJs - Node.js
MongoDB 是一个面向文档的、 NoSQL 类型的数据库。MongoDB 颠覆了传统的基于表的数据存储方式，而采取了类似 JSON 的文档结构来存储数据，因而它在存储数据时可以更加灵活。 Express 是一个 Node.js 框架，可以创建灵活的 Web 服务，比如单页面应用程序、多页面应用程序和混合型 App。 AngularJS 是一个开源的 JavaScript 框架，由 Google 和开源社区共同维护，它用来创建单页面应用程序。它的目标是使用 model-view-controller 模式来规范 Web 应用程序，让开发和测试富交互的单页面应用程序变得更加轻松。 Node.js 是一个运行在服务器端的 JavaScript 运行环境，它的底层是基于 Chrome 的 JavaScript 运行环境——V8 引擎。Node.js 可以作为服务器端语言，用来创建快速、可扩展的应用程序。Node.js 也可以在本机运行，做一些本地操作，比如加速本地开发流程，或者实现一键发布。 MEAN 可以说是传统的 LAMP 方案的有力竞争者。因为从服务器端到页面端都采用同样的语言（JavaScript）和同样的架构模式（MVC），所以一个擅长 JavaScript 的工程师可以兼顾前后端的开发，并且前端代码和后台代码是可以复用的。</description>
      <content:encoded><![CDATA[<p>MEAN: MongoDB - Express - AngularJs - Node.js</p>
<ul>
<li>MongoDB 是一个面向文档的、 NoSQL 类型的数据库。MongoDB 颠覆了传统的基于表的数据存储方式，而采取了类似 JSON 的文档结构来存储数据，因而它在存储数据时可以更加灵活。</li>
<li>Express 是一个 Node.js 框架，可以创建灵活的 Web 服务，比如单页面应用程序、多页面应用程序和混合型 App。</li>
<li>AngularJS 是一个开源的 JavaScript 框架，由 Google 和开源社区共同维护，它用来创建单页面应用程序。它的目标是使用 model-view-controller 模式来规范 Web 应用程序，让开发和测试富交互的单页面应用程序变得更加轻松。</li>
<li>Node.js 是一个运行在服务器端的 JavaScript 运行环境，它的底层是基于 Chrome 的 JavaScript 运行环境——V8 引擎。Node.js 可以作为服务器端语言，用来创建快速、可扩展的应用程序。Node.js 也可以在本机运行，做一些本地操作，比如加速本地开发流程，或者实现一键发布。</li>
</ul>
<p>MEAN 可以说是传统的 LAMP 方案的有力竞争者。因为从服务器端到页面端都采用同样的语言（JavaScript）和同样的架构模式（MVC），所以一个擅长 JavaScript 的工程师可以兼顾前后端的开发，并且前端代码和后台代码是可以复用的。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>(转载) IaaS, PaaS, Saas</title>
      <link>https://hiwangzi.com/posts/2017/10/25/iaas-paas-saas/</link>
      <pubDate>Wed, 25 Oct 2017 17:20:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/10/25/iaas-paas-saas/</guid>
      <description>如果你是一个网站站长，想要建立一个网站。不采用云服务，你所需要的投入大概是：买服务器，安装服务器软件，编写网站程序。
现在你追随潮流，采用流行的云计算，如果你采用 IaaS 服务，那么意味着你就不用自己买服务器了，随便在哪家购买虚拟机，但是还是需要自己装服务器软件
而如果你采用 PaaS 的服务，那么意味着你既不需要买服务器，也不需要自己装服务器软件，只需要自己开发网站程序
如果你再进一步，购买某些在线论坛或者在线网店的服务,这意味着你也不用自己开发网站程序，只需要使用它们开发好的程序，而且他们会负责程序的升级、维护、增加服务器等，而你只需要专心运营即可，此即为 SaaS 。
作者：John Wang 链接：https://www.zhihu.com/question/20387284/answer/28514161 来源：知乎 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</description>
      <content:encoded><![CDATA[<p>如果你是一个网站站长，想要建立一个网站。不采用云服务，你所需要的投入大概是：买服务器，安装服务器软件，编写网站程序。</p>
<p>现在你追随潮流，采用流行的云计算，如果你采用 <strong>IaaS</strong> 服务，那么意味着你就不用自己买服务器了，随便在哪家购买虚拟机，但是还是需要自己装服务器软件</p>
<p>而如果你采用 <strong>PaaS</strong> 的服务，那么意味着你既不需要买服务器，也不需要自己装服务器软件，只需要自己开发网站程序</p>
<p>如果你再进一步，购买某些在线论坛或者在线网店的服务,这意味着你也不用自己开发网站程序，只需要使用它们开发好的程序，而且他们会负责程序的升级、维护、增加服务器等，而你只需要专心运营即可，此即为 <strong>SaaS</strong> 。</p>
<p>作者：John Wang
链接：https://www.zhihu.com/question/20387284/answer/28514161
来源：知乎
著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>scp 命令简明介绍</title>
      <link>https://hiwangzi.com/posts/2017/10/11/scp-newbie-note/</link>
      <pubDate>Wed, 11 Oct 2017 10:53:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/10/11/scp-newbie-note/</guid>
      <description> 安全复制（英语：Secure copy，缩写SCP）是指在本地主机与远程主机或者两台远程主机之间基于Secure Shell（SSH）协议安全地传输电脑文件。“SCP”通常指安全复制协议或者程序本身。安全复制 - 维基百科，自由的百科全书
其使用方法类似于 cp 命令。
复制文件或目录命令：
复制文件：
将本地文件拷贝到远程 scp 文件名 --用户名@计算机IP或者计算机名称:远程路径 从远程将文件拷回本地 scp --用户名@计算机IP或者计算机名称:文件名 本地路径 复制目录：
将本地目录拷贝到远程 scp -r 目录名 用户名@计算机IP或者计算机名称:远程路径 从远程将目录拷回本地 scp -r 用户名@计算机IP或者计算机名称:目录名 本地路径 注意，如果远程主机使用非默认端口22，可以在命令中指定。例如，从远程主机复制一个文件到本地。
scp -P 2222 user@host:directory/SourceFile TargetFile </description>
      <content:encoded><![CDATA[<blockquote>
<p>安全复制（英语：Secure copy，缩写SCP）是指在本地主机与远程主机或者两台远程主机之间基于Secure Shell（SSH）协议安全地传输电脑文件。“SCP”通常指安全复制协议或者程序本身。<a href="https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E5%A4%8D%E5%88%B6">安全复制 - 维基百科，自由的百科全书</a></p>
</blockquote>
<ul>
<li>
<p>其使用方法类似于 <code>cp</code> 命令。</p>
</li>
<li>
<p>复制文件或目录命令：</p>
<ul>
<li>
<p>复制文件：</p>
<ol>
<li>将本地文件拷贝到远程 <code>scp 文件名 --用户名@计算机IP或者计算机名称:远程路径</code></li>
<li>从远程将文件拷回本地 <code>scp --用户名@计算机IP或者计算机名称:文件名 本地路径</code></li>
</ol>
</li>
<li>
<p>复制目录：</p>
<ol>
<li>将本地目录拷贝到远程 <code>scp -r 目录名 用户名@计算机IP或者计算机名称:远程路径</code></li>
<li>从远程将目录拷回本地 <code>scp -r 用户名@计算机IP或者计算机名称:目录名 本地路径</code></li>
</ol>
</li>
</ul>
</li>
<li>
<p>注意，如果远程主机使用非默认端口22，可以在命令中指定。例如，从远程主机复制一个文件到本地。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>scp -P <span style="color:#ae81ff">2222</span> user@host:directory/SourceFile TargetFile
</span></span></code></pre></div></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>「cmd」与「网卡」—— netsh 命令</title>
      <link>https://hiwangzi.com/posts/2017/09/04/netsh-newbie-note/</link>
      <pubDate>Mon, 04 Sep 2017 19:13:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/09/04/netsh-newbie-note/</guid>
      <description>1. 通过命令提示符（cmd）命令连接 Wi-Fi 1.1 连接曾经连接过的 Wi-Fi :: 查看配置的列表（::表示注释） netsh wlan show profile :: 连接 netsh wlan connect ssid=你的SSID名字(简单可以理解为Wi-Fi名) name=你的配置名字 1.2 连接从未连接过的 Wi-Fi :: 先增加一项 Wi-Fi 配置，注意要在配置文件所在目录执行 netsh wlan add profile filename=&amp;#34;你的配置.xml&amp;#34; :: 查看配置的列表，检查是否添加成功 netsh wlan show profile :: 连接 netsh wlan connect ssid=你的SSID名字 name=你的配置名字 示例配置文件 &amp;lt;?xml version=&amp;#34;1.0&amp;#34;?&amp;gt; &amp;lt;WLANProfile xmlns=&amp;#34;http://www.microsoft.com/networking/WLAN/profile/v1&amp;#34;&amp;gt; &amp;lt;name&amp;gt;你的配置名字（与SSID名字相同即可）&amp;lt;/name&amp;gt; &amp;lt;SSIDConfig&amp;gt; &amp;lt;SSID&amp;gt; &amp;lt;name&amp;gt;你的SSID名字&amp;lt;/name&amp;gt; &amp;lt;/SSID&amp;gt; &amp;lt;/SSIDConfig&amp;gt; &amp;lt;connectionType&amp;gt;ESS&amp;lt;/connectionType&amp;gt; &amp;lt;connectionMode&amp;gt;auto&amp;lt;/connectionMode&amp;gt; &amp;lt;MSM&amp;gt; &amp;lt;security&amp;gt; &amp;lt;authEncryption&amp;gt; &amp;lt;authentication&amp;gt;WPA2PSK&amp;lt;/authentication&amp;gt; &amp;lt;encryption&amp;gt;AES&amp;lt;/encryption&amp;gt; &amp;lt;useOneX&amp;gt;false&amp;lt;/useOneX&amp;gt; &amp;lt;/authEncryption&amp;gt; &amp;lt;sharedKey&amp;gt; &amp;lt;keyType&amp;gt;passPhrase&amp;lt;/keyType&amp;gt; &amp;lt;protected&amp;gt;false&amp;lt;/protected&amp;gt; &amp;lt;keyMaterial&amp;gt;你的WiFi密码&amp;lt;/keyMaterial&amp;gt; &amp;lt;/sharedKey&amp;gt; &amp;lt;/security&amp;gt; &amp;lt;/MSM&amp;gt; &amp;lt;MacRandomization xmlns=&amp;#34;http://www.</description>
      <content:encoded><![CDATA[<h2 id="1-通过命令提示符cmd命令连接-wi-fi">1. 通过命令提示符（cmd）命令连接 Wi-Fi</h2>
<h3 id="11-连接曾经连接过的-wi-fi">1.1 连接曾经连接过的 Wi-Fi</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bat" data-lang="bat"><span style="display:flex;"><span>:<span style="color:#75715e">: 查看配置的列表（::表示注释）</span>
</span></span><span style="display:flex;"><span>netsh wlan show profile
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 连接</span>
</span></span><span style="display:flex;"><span>netsh wlan connect ssid=你的SSID名字(简单可以理解为Wi-Fi名) name=你的配置名字
</span></span></code></pre></div><h3 id="12-连接从未连接过的-wi-fi">1.2 连接从未连接过的 Wi-Fi</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bat" data-lang="bat"><span style="display:flex;"><span>:<span style="color:#75715e">: 先增加一项 Wi-Fi 配置，注意要在配置文件所在目录执行</span>
</span></span><span style="display:flex;"><span>netsh wlan add profile filename=<span style="color:#e6db74">&#34;你的配置.xml&#34;</span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 查看配置的列表，检查是否添加成功</span>
</span></span><span style="display:flex;"><span>netsh wlan show profile
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 连接</span>
</span></span><span style="display:flex;"><span>netsh wlan connect ssid=你的SSID名字 name=你的配置名字
</span></span></code></pre></div><h4 id="示例配置文件">示例配置文件</h4>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#75715e">&lt;?xml version=&#34;1.0&#34;?&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;WLANProfile</span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">&#34;http://www.microsoft.com/networking/WLAN/profile/v1&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;name&gt;</span>你的配置名字（与SSID名字相同即可）<span style="color:#f92672">&lt;/name&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;SSIDConfig&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;SSID&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;name&gt;</span>你的SSID名字<span style="color:#f92672">&lt;/name&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/SSID&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/SSIDConfig&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;connectionType&gt;</span>ESS<span style="color:#f92672">&lt;/connectionType&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;connectionMode&gt;</span>auto<span style="color:#f92672">&lt;/connectionMode&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;MSM&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;security&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;authEncryption&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;authentication&gt;</span>WPA2PSK<span style="color:#f92672">&lt;/authentication&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;encryption&gt;</span>AES<span style="color:#f92672">&lt;/encryption&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;useOneX&gt;</span>false<span style="color:#f92672">&lt;/useOneX&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;/authEncryption&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;sharedKey&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;keyType&gt;</span>passPhrase<span style="color:#f92672">&lt;/keyType&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;protected&gt;</span>false<span style="color:#f92672">&lt;/protected&gt;</span>
</span></span><span style="display:flex;"><span>                <span style="color:#f92672">&lt;keyMaterial&gt;</span>你的WiFi密码<span style="color:#f92672">&lt;/keyMaterial&gt;</span>
</span></span><span style="display:flex;"><span>            <span style="color:#f92672">&lt;/sharedKey&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;/security&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/MSM&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;MacRandomization</span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">&#34;http://www.microsoft.com/networking/WLAN/profile/v3&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;enableRandomization&gt;</span>false<span style="color:#f92672">&lt;/enableRandomization&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/MacRandomization&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/WLANProfile&gt;</span>
</span></span></code></pre></div><h2 id="2-查看连接过的-wi-fi-密码">2. 查看连接过的 Wi-Fi 密码</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bat" data-lang="bat"><span style="display:flex;"><span>:<span style="color:#75715e">: 查看特定</span>
</span></span><span style="display:flex;"><span>netsh wlan show profile 配置名称 key=clear
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 查看所有</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#66d9ef">/f</span> <span style="color:#e6db74">&#34;skip=9 tokens=1,2 delims=:&#34;</span> %i in (&#39;netsh wlan show profiles&#39;) do  @echo %j | findstr -i -v echo | netsh wlan show profiles %j key=clear
</span></span></code></pre></div><h2 id="3-查看禁用启用网络接口网卡">3. 查看、禁用、启用网络接口（网卡）</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bat" data-lang="bat"><span style="display:flex;"><span>:<span style="color:#75715e">: 查看网络接口的列表</span>
</span></span><span style="display:flex;"><span>netsh interface show interface
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 禁用网络接口</span>
</span></span><span style="display:flex;"><span>netsh interface set interface 接口名称 disabled
</span></span><span style="display:flex;"><span>:<span style="color:#75715e">: 启用网络接口</span>
</span></span><span style="display:flex;"><span>netsh interface set interface 接口名称 enabled
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    <item>
      <title>代码与数据</title>
      <link>https://hiwangzi.com/posts/2017/09/03/code-and-data/</link>
      <pubDate>Sun, 03 Sep 2017 13:20:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/09/03/code-and-data/</guid>
      <description>半年之前，第一次接触到这种将函数作为参数传递的做法，当时实在觉得难以理解。
PHP 的变量真的是啥都能装，不管函数还是类，这个真的是灵活到飘逸🙈。另外，“魔术方法”哈哈哈哈哈哈哈🌞好酷哦... pic.twitter.com/nxGwbBKAEl
&amp;mdash; @hiwangzi March 28, 2017 直到最近再次接触到 Python，查询了一些资料，才开始对其有了一些初步的认识。
我们暂停一下，看看计算机中比较诡异的地方，也就是代码(code)和数据(data)的统一。这是一个槛，如果不跨过这槛，很多概念就不清楚。我们常常说计算机程序分成 code 和 data 两部分。很多人会理解成，code 是会运行的，是动态的，data 是给 code 使用，是静态的，这是两种完全不同的东西。
回调函数（callback）是什么？ - 回答作者: 黄兢成 https://zhihu.com/question/19801131/answer/17156023
最开始我的认知也就如上面这个问题的答主描述的一般，但如果转变一下思维，将 code 与 data 统一视为视为信息，对于 PHP 中可以将函数作为参数传递的做法，也就可以理解了。
其实 code 只是对行为的一种描述，比如有个机器人可以开灯，关灯，扫地。如果跟机器人约定好，0 表示开灯，1 表示关灯，2 表示扫地。
我发出指令串，0 1 2，就可以控制机器人开灯，关灯，扫地。再约定用二进制表示，两位一个指令，就有一个数字串，000111，这个时候 000111 这串数字就描述了机器人的一系列动作，这个就是从一方面理解是 code，它可以控制机器人的行为。
但另一方面，它可以传递，可以记录，可以修改，也就是数据。只要大家都协商好，code 就可以编码成 data, 将 data 解释运行的时候，也变成了 code。
关于 code 与 data，上面的答主如是说：
有些语言不区分，它的 function(表示code)跟 int, double 的地位是一样的。这种语言称函数是第一类值。 有些语言是不能存储函数，不能动态创建函数，不能动态销毁函数。只能存储一个指向函数的指针，这种语言称函数是第二类值。 在 Python 中，将一切都视为对象，传递的即是函数的指针。这种做法即属于上述描述中的第二类。
最后，发自内心的说，这个回答的内容真得值得一读。
我要走的路还有很长，路漫漫其修远兮……</description>
      <content:encoded><![CDATA[<p>半年之前，第一次接触到这种将函数作为参数传递的做法，当时实在觉得难以理解。</p>


<blockquote class="twitter-tweet"><p lang="zh" dir="ltr">PHP 的变量真的是啥都能装，不管函数还是类，这个真的是灵活到飘逸🙈。另外，“魔术方法”哈哈哈哈哈哈哈🌞好酷哦... <a href="https://t.co/nxGwbBKAEl">pic.twitter.com/nxGwbBKAEl</a></p>&mdash; @hiwangzi <a href="https://twitter.com/hiwangzi/status/846697844496986112?ref_src=twsrc%5Etfw">March 28, 2017</a></blockquote> <script async src="https://hiwangzi.com/posts/2017/09/03/code-and-data/https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<p>直到最近再次接触到 Python，查询了一些资料，才开始对其有了一些初步的认识。</p>
<blockquote>
<p>我们暂停一下，看看计算机中比较诡异的地方，也就是代码(code)和数据(data)的统一。这是一个槛，如果不跨过这槛，很多概念就不清楚。我们常常说计算机程序分成 code 和 data 两部分。很多人会理解成，code 是会运行的，是动态的，data 是给 code 使用，是静态的，这是两种完全不同的东西。</p>
<p>回调函数（callback）是什么？ - 回答作者: 黄兢成 <a href="https://zhihu.com/question/19801131/answer/17156023">https://zhihu.com/question/19801131/answer/17156023</a></p>
</blockquote>
<p>最开始我的认知也就如上面这个问题的答主描述的一般，但如果转变一下思维，将 code 与 data 统一视为视为信息，对于 PHP 中可以将函数作为参数传递的做法，也就可以理解了。</p>
<blockquote>
<p>其实 code 只是对行为的一种描述，比如有个机器人可以开灯，关灯，扫地。如果跟机器人约定好，0 表示开灯，1 表示关灯，2 表示扫地。</p>
<p>我发出指令串，0 1 2，就可以控制机器人开灯，关灯，扫地。再约定用二进制表示，两位一个指令，就有一个数字串，000111，这个时候 000111 这串数字就描述了机器人的一系列动作，这个就是从一方面理解是 code，它可以控制机器人的行为。</p>
<p>但另一方面，它可以传递，可以记录，可以修改，也就是数据。只要大家都协商好，code 就可以编码成 data, 将 data 解释运行的时候，也变成了 code。</p>
</blockquote>
<p>关于 code 与 data，上面的答主如是说：</p>
<blockquote>
<ul>
<li>有些语言不区分，它的 function(表示code)跟 int, double 的地位是一样的。这种语言称函数是第一类值。</li>
<li>有些语言是不能存储函数，不能动态创建函数，不能动态销毁函数。只能存储一个指向函数的指针，这种语言称函数是第二类值。</li>
</ul>
</blockquote>
<p>在 Python 中，将一切都视为对象，传递的即是函数的指针。这种做法即属于上述描述中的第二类。</p>
<p>最后，发自内心的说，这个<a href="https://zhihu.com/question/19801131/answer/17156023">回答的内容</a>真得值得一读。</p>
<p>我要走的路还有很长，路漫漫其修远兮……</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Debian/Linux 下无线网卡驱动的安装</title>
      <link>https://hiwangzi.com/posts/2017/08/29/install-wifi-driver-for-bcm43228-in-linux/</link>
      <pubDate>Tue, 29 Aug 2017 16:43:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/08/29/install-wifi-driver-for-bcm43228-in-linux/</guid>
      <description>在 Debian 下为 BCM43228 无线网卡安装驱动</description>
      <content:encoded><![CDATA[<p>我的 PC 型号是 Acer V3-572G，安装了 Debian 后，发现只能通过有线网络上网，无法识别无线网卡，以下是解决的过程(不局限于此型号 PC):</p>
<ul>
<li>
<p>在命令行键入 <code>lspci</code> ，得到网卡型号「BCM43228」</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>xox@debian-x64:~$ lspci
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>00:00.0 Host bridge: Intel Corporation Haswell-ULT DRAM Controller <span style="color:#f92672">(</span>rev 0b<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:02.0 VGA compatible controller: Intel Corporation Haswell-ULT Integrated Graphics Controller <span style="color:#f92672">(</span>rev 0b<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:03.0 Audio device: Intel Corporation Haswell-ULT HD Audio Controller <span style="color:#f92672">(</span>rev 0b<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:14.0 USB controller: Intel Corporation <span style="color:#ae81ff">8</span> Series USB xHCI HC <span style="color:#f92672">(</span>rev 04<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:16.0 Communication controller: Intel Corporation <span style="color:#ae81ff">8</span> Series HECI <span style="color:#75715e">#0 (rev 04)</span>
</span></span><span style="display:flex;"><span>00:1b.0 Audio device: Intel Corporation <span style="color:#ae81ff">8</span> Series HD Audio Controller <span style="color:#f92672">(</span>rev 04<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1c.0 PCI bridge: Intel Corporation <span style="color:#ae81ff">8</span> Series PCI Express Root Port <span style="color:#ae81ff">3</span> <span style="color:#f92672">(</span>rev e4<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1c.3 PCI bridge: Intel Corporation <span style="color:#ae81ff">8</span> Series PCI Express Root Port <span style="color:#ae81ff">4</span> <span style="color:#f92672">(</span>rev e4<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1c.4 PCI bridge: Intel Corporation <span style="color:#ae81ff">8</span> Series PCI Express Root Port <span style="color:#ae81ff">5</span> <span style="color:#f92672">(</span>rev e4<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1d.0 USB controller: Intel Corporation <span style="color:#ae81ff">8</span> Series USB EHCI <span style="color:#75715e">#1 (rev 04)</span>
</span></span><span style="display:flex;"><span>00:1f.0 ISA bridge: Intel Corporation <span style="color:#ae81ff">8</span> Series LPC Controller <span style="color:#f92672">(</span>rev 04<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1f.2 SATA controller: Intel Corporation <span style="color:#ae81ff">8</span> Series SATA Controller <span style="color:#ae81ff">1</span> <span style="color:#f92672">[</span>AHCI mode<span style="color:#f92672">]</span> <span style="color:#f92672">(</span>rev 04<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>00:1f.3 SMBus: Intel Corporation <span style="color:#ae81ff">8</span> Series SMBus Controller <span style="color:#f92672">(</span>rev 04<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>01:00.0 Unassigned class <span style="color:#f92672">[</span>ff00<span style="color:#f92672">]</span>: Realtek Semiconductor Co., Ltd. RTL8411B PCI Express Card Reader <span style="color:#f92672">(</span>rev 01<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>01:00.1 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller <span style="color:#f92672">(</span>rev 12<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>02:00.0 Network controller: Broadcom Limited BCM43228 802.11a/b/g/n
</span></span><span style="display:flex;"><span>03:00.0 3D controller: NVIDIA Corporation GM108M <span style="color:#f92672">[</span>GeForce 840M<span style="color:#f92672">]</span> <span style="color:#f92672">(</span>rev a2<span style="color:#f92672">)</span>
</span></span></code></pre></div></li>
<li>
<p>使用搜索引擎得到特定型号的固件包</p>
</li>
</ul>
<p>如下图，第一个搜索结果中即有相关信息 <a href="https://wiki.debian.org/wl">wl - Debian Wiki</a></p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/08/29/install-wifi-driver-for-bcm43228-in-linux/resources/1104579-20170829164015671-927631999.jpg" alt=""  />
</p>
<ul>
<li>
<p><code>apt-get install</code> 安装驱动</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span><span style="color:#75715e"># apt-get update</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># apt-get install linux-image-$(uname -r|sed &#39;s,[^-]*-[^-]*-,,&#39;) linux-headers-$(uname -r|sed &#39;s,[^-]*-[^-]*-,,&#39;) broadcom-sta-dkms</span>
</span></span></code></pre></div></li>
<li>
<p>重启即可使用无线网络</p>
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Linux 安装软件的几种方式</title>
      <link>https://hiwangzi.com/posts/2017/08/22/how-to-install-software-for-linux/</link>
      <pubDate>Tue, 22 Aug 2017 16:38:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/08/22/how-to-install-software-for-linux/</guid>
      <description>源代码编译安装 源代码包的安装一般为下载软件源代码，然后编译安装。常见的 C 程序软件的安装步骤是 configure, make, make install 三部曲（./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install）。
一句话来解释整个过程：
根据源码包中 Makefile.in 文件的指示，configure 脚本检查当前的系统环境和配置选项，在当前目录中生成 Makefile 文件(还有其它本文无需关心的文件)，然后 make 程序就按照当前目录中的 Makefile 文件的指示将源代码编译为二进制文件，最后将这些二进制文件移动(即安装)到指定的地方(仍然按照 Makefile 文件的指示)。
借助软件包管理器安装 例如借助 yum、apt-get 等管理软件进行安装。
在 Ubuntu 系统上，软件包的格式是 deb，相比于「源代码编译安装」，deb 包这类的二进制包是依赖硬件和软件平台的。
顺便提一点，apt-get只是dpkg的一个前端而已，dpkg 是Debian软件包管理器的基础。而上层的工具，像是 APT，用于从远程获取软件包以及处理复杂的软件包关系。
二进制格式安装 编译好的文件，类似于 Windows 下的 exe，后缀一般为 bin，如 jdk 就有 bin 后缀（虽然 Linux 下没有后缀的概念，但为了好区分，一般文件名都加后缀）。安装就是先给它可执行权限，然后执行，例如：
chmod 777 xxx.bin ./xxx.bin 总结 源代码编译安装最为灵活自由 借助包管理器最为方便 二进制格式安装方式一般被一些闭源的驱动和预编译的安装包所采用 参考 源代码包 - deepin Wiki 深入理解软件包的配置、编译与安装 在 Linux 下安装软件的方法有哪些？各有什么优劣？ </description>
      <content:encoded><![CDATA[<h2 id="源代码编译安装">源代码编译安装</h2>
<p>源代码包的安装一般为下载软件源代码，然后编译安装。常见的 C 程序软件的安装步骤是 <code>configure</code>, <code>make</code>, <code>make install</code> 三部曲（<code>./configure &amp;&amp; make &amp;&amp; make install</code>）。</p>
<p>一句话来解释整个过程：</p>
<blockquote>
<p>根据源码包中 Makefile.in 文件的指示，configure 脚本检查当前的系统环境和配置选项，在当前目录中生成 Makefile 文件(还有其它本文无需关心的文件)，然后 make 程序就按照当前目录中的 Makefile 文件的指示将源代码编译为二进制文件，最后将这些二进制文件移动(即安装)到指定的地方(仍然按照 Makefile 文件的指示)。</p>
</blockquote>
<h2 id="借助软件包管理器安装">借助软件包管理器安装</h2>
<p>例如借助 <code>yum</code>、<code>apt-get</code> 等管理软件进行安装。</p>
<p>在 Ubuntu 系统上，软件包的格式是 deb，相比于「源代码编译安装」，deb 包这类的二进制包是依赖硬件和软件平台的。</p>
<p>顺便提一点，<code>apt-get</code>只是<code>dpkg</code>的一个前端而已，<code>dpkg</code> 是Debian软件包管理器的基础。而上层的工具，像是 <a href="https://zh.wikipedia.org/wiki/%E9%AB%98%E7%BA%A7%E5%8C%85%E8%A3%85%E5%B7%A5%E5%85%B7">APT</a>，用于从远程获取软件包以及处理复杂的<a href="https://zh.wikipedia.org/wiki/%E9%AB%98%E7%BA%A7%E5%8C%85%E8%A3%85%E5%B7%A5%E5%85%B7#.E4.BE.9D.E8.B3.B4.E9.97.9C.E4.BF.82.E8.99.95.E7.90.86">软件包关系</a>。</p>
<h2 id="二进制格式安装">二进制格式安装</h2>
<p>编译好的文件，类似于 Windows 下的 exe，后缀一般为 bin，如 jdk 就有 bin 后缀（虽然 Linux 下没有后缀的概念，但为了好区分，一般文件名都加后缀）。安装就是先给它可执行权限，然后执行，例如：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>chmod <span style="color:#ae81ff">777</span> xxx.bin
</span></span><span style="display:flex;"><span>./xxx.bin
</span></span></code></pre></div><h1 id="总结">总结</h1>
<ul>
<li>源代码编译安装最为灵活自由</li>
<li>借助包管理器最为方便</li>
<li>二进制格式安装方式一般被一些闭源的驱动和预编译的安装包所采用</li>
</ul>
<h1 id="参考">参考</h1>
<ul>
<li><a href="https://wiki.deepin.org/index.php?title=%E6%BA%90%E4%BB%A3%E7%A0%81%E5%8C%85">源代码包 - deepin Wiki</a></li>
<li><a href="http://www.jinbuguo.com/linux/understand_package_install.html">深入理解软件包的配置、编译与安装</a></li>
<li><a href="https://zhihu.com/question/20126212/">在 Linux 下安装软件的方法有哪些？各有什么优劣？</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>数据库表间多对多关系（附带额外字段）的实体类（POJO 或 POCO）表示</title>
      <link>https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/</link>
      <pubDate>Fri, 26 May 2017 22:25:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/</guid>
      <description>介绍 在之前的 Entity Framework 快速上手介绍 之中，两个实体之间只是简单的一对一关系，而在实际的应用场景中，还会出现多对多关系，同时还有可能会出现多对多关系还附带有其他字段的情况。
下面以几个例子，对表间多对多关系的类表示加以更加详细地描述。虽然两个场景举例是使用的 C# 及 Entity Framework(Model First) 框架自动生成数据库、实体类。但这种设计方法，并不只是在使用 ORM 框架时需要，事实上，它是 POCO 及简单 Java 类（POJO）的设计原则之一。
场景实例 场景一 在考虑多对多关系还附带有字段的情况之前，让我们先看一下，多对多关系但不附带额外字段的情况下，实体类代码的表示。
此处使用 Entity Framework(Model First)，快速将 model diagram 转为数据库中的表及实体类。
假设的场景是学生选课，一名学生可以选多门课，一门课也可以被多个学生选择。E-R 图如下所示： 对应自动生成的数据库如下：
StudentSet CourseSet CourseRegistrationSet 其中 Course_Id 与 Students_Id（注：此处词尾(s)负数的原因参见上面 E-R 图中右边的 Properties 中 End1 Navigation Property 的设置）分别以另外两张数据表的 Id 主键作为外键。 同时 Course_Id 与 Students_Id 两者联合做 CourseRegistrationSet 表的主键。 对应自动生成实体类的代码如下：
Student.cs namespace Model { using System; using System.Collections.Generic; public partial class Student { [System.</description>
      <content:encoded><![CDATA[<h2 id="介绍">介绍</h2>
<p>在之前的 <a href="http://www.cnblogs.com/hiwangzi/p/EntityFrameworkSample.html">Entity Framework 快速上手介绍</a> 之中，两个实体之间只是简单的一对一关系，而在实际的应用场景中，还会出现多对多关系，同时还有可能会出现多对多关系还附带有其他字段的情况。</p>
<p>下面以几个例子，对<strong>表间多对多关系的类表示</strong>加以更加详细地描述。虽然两个场景举例是使用的 C# 及 Entity Framework(Model First) 框架自动生成数据库、实体类。但这种设计方法，并不只是在使用 ORM 框架时需要，事实上，它是 POCO 及简单 Java 类（POJO）的设计原则之一。</p>
<h2 id="场景实例">场景实例</h2>
<h3 id="场景一">场景一</h3>
<p>在考虑多对多关系还附带有字段的情况之前，让我们先看一下，多对多关系但不附带额外字段的情况下，实体类代码的表示。</p>
<p>此处使用 Entity Framework(Model First)，快速将 model diagram 转为数据库中的表及实体类。</p>
<p>假设的场景是学生选课，一名学生可以选多门课，一门课也可以被多个学生选择。E-R 图如下所示：
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526203822872-1383747342.png" alt=""  />
</p>
<p>对应自动生成的数据库如下：</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526204422044-36349200.png" alt=""  />
</p>
<ul>
<li>StudentSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201734497-273871464.png" alt=""  />
</li>
<li>CourseSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201740747-806786252.png" alt=""  />
</li>
<li>CourseRegistrationSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526204412497-32662665.png" alt=""  />

<ul>
<li>其中 <code>Course_Id</code> 与 <code>Students_Id</code>（注：此处词尾(s)负数的原因参见上面 E-R 图中右边的 <code>Properties</code> 中 <code>End1 Navigation Property</code> 的设置）分别以另外两张数据表的 <code>Id</code> 主键作为外键。</li>
<li>同时 <code>Course_Id</code> 与 <code>Students_Id</code> 两者联合做 <code>CourseRegistrationSet</code> 表的主键。</li>
</ul>
</li>
</ul>
<p>对应自动生成实体类的代码如下：</p>
<ul>
<li>Student.cs
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> Model
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">partial</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Student</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2214:DoNotCallOverridableMethodsInConstructors&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> Student()
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.Course = <span style="color:#66d9ef">new</span> HashSet&lt;Course&gt;();
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> Id { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">学号</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">姓名</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2227:CollectionPropertiesShouldBeReadOnly&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> ICollection&lt;Course&gt; Course { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
<li>Course.cs
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> Model
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">partial</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Course</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2214:DoNotCallOverridableMethodsInConstructors&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> Course()
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.Students = <span style="color:#66d9ef">new</span> HashSet&lt;Student&gt;();
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> Id { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">课程名称</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">学分</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2227:CollectionPropertiesShouldBeReadOnly&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> ICollection&lt;Student&gt; Students { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
</ul>
<h4 id="分析">分析</h4>
<ul>
<li>数据库表之间一对一、一对多的关系在代码中是通过 <strong>对象引用</strong> 或 <strong>对象数组/List等形式的引用</strong> 实现的。</li>
<li>从实例中可以看出，CourseRegistrationSet 表中的多对多关系在代码中的表现形式同样是实体类中的 <strong>对象List等形式的引用</strong>，只不过多对多关系是<strong>多个实体类中都存在其他实体类对象List的引用</strong>。</li>
</ul>
<h3 id="场景二">场景二</h3>
<p>现在让我们增加一个需求，实际应用之中，数据库不可能仅仅存储某学生选了某门课程这些信息，同时还需要保存选课时间、操作人、成绩等等信息。</p>
<p>现在让我们为 <code>CourseRegistrationSet</code> 表增加一个字段——成绩。</p>
<ul>
<li>CourseRegistrationSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201746638-724623826.png" alt=""  />
</li>
</ul>
<p>同时我们需要更新一下程序中的代码，这时候问题出现了🙄：两个实体类中互相存储着对方<strong>对象List</strong>的引用，成绩字段该放到哪里呢？</p>
<p>此时我们换一种思路，如果将 <code>CourseRegistrationSet</code> 同样想象为一种特殊的实体，那么就可以实现将 <code>Student</code> 与 <code>Course</code> 关联的同时，还可以保存<strong>成绩</strong>信息。即如下图所示：</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526195449482-1615050529.png" alt=""  />
</p>
<p>如果你刚刚仔细阅读了 Entity Framework(Model First) 自动生成的 <strong>数据库表结构</strong> 以及 <strong>类的代码</strong>，再结合上面新的 E-R图，大概也就可以明白，应该如何在代码中表示多对多关系（附带额外字段/属性）。</p>
<p>上面的场景生成的数据表结构如下：</p>
<ul>
<li>StudentSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201734497-273871464.png" alt=""  />
</li>
<li>CourseSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201740747-806786252.png" alt=""  />
</li>
<li>CourseRegistrationSet
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526201746638-724623826.png" alt=""  />
</li>
</ul>
<p>自动生成的实体类的代码：</p>
<ul>
<li>Student.cs
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> Model
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">partial</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Student</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2214:DoNotCallOverridableMethodsInConstructors&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> Student()
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.CourseRegistration = <span style="color:#66d9ef">new</span> HashSet&lt;CourseRegistration&gt;();
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> Id { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">学号</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">姓名</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2227:CollectionPropertiesShouldBeReadOnly&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> ICollection&lt;CourseRegistration&gt; CourseRegistration { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
<li>Course.cs
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> Model
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">partial</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Course</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2214:DoNotCallOverridableMethodsInConstructors&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> Course()
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">this</span>.CourseRegistration = <span style="color:#66d9ef">new</span> HashSet&lt;CourseRegistration&gt;();
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> Id { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">课程名称</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">学分</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">
</span></span></span><span style="display:flex;"><span><span style="color:#a6e22e">        [System.Diagnostics.CodeAnalysis.SuppressMessage(&#34;Microsoft.Usage&#34;, &#34;CA2227:CollectionPropertiesShouldBeReadOnly&#34;)]</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> ICollection&lt;CourseRegistration&gt; CourseRegistration { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
<li>CourseRegistration.cs
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#66d9ef">namespace</span> Model
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System;
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">using</span> System.Collections.Generic;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">partial</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">CourseRegistration</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> Id { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">string</span> <span style="color:#960050;background-color:#1e0010">成绩</span> { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> Student Student { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">virtual</span> Course Course { <span style="color:#66d9ef">get</span>; <span style="color:#66d9ef">set</span>; }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
</ul>
<h4 id="分析-1">分析</h4>
<ul>
<li>数据库表之间多对多的关系在代码中表示需要将“多对多关系”同样抽象为“实体”来实现。但仍然是通过 <strong>对象引用</strong> 或 <strong>对象数组/List等形式的引用</strong> 实现的。</li>
<li>从实例中可以看出，<code>Student</code> 与 <code>Course</code> 之间原本<strong>直接</strong>的多对多关系被转换成了：
<ul>
<li><code>Student</code> 与 <code>CourseRegistration</code> 的一对多关系</li>
<li><code>Course</code> 与 <code>CourseRegistration</code> 的一对多关系</li>
<li><code>CourseRegistration</code> 与 <code>Student</code>, <code>Course</code> 的一对一关系</li>
</ul>
</li>
</ul>
<h2 id="one-more-thing事实上是主题相关的更多内容">One more thing&hellip;（事实上是主题相关的更多内容）</h2>
<p>在前段时间的实习期间设计数据库时，两次遇到这个问题；同时前段时间在一次上机考试中，又遇到了这个问题。</p>
<ul>
<li>
<p>第一次时，没有找到合适的相关资料，同时秉持着一个现在看来并不恰当的信念：“实体类对应实体表”。因此，解决方法比较粗暴，当时直接将额外字段加到了某一张表之中。下面是当时的情景：（括号中为对应于上面的案例）</p>
<ul>
<li>工人（学生）拥有（选课）技能（课程），额外需要一个字段表示工人对技能的熟练程度（成绩）。</li>
<li>看起来和上面的场景二就是一模一样呀🙃然而当时我并没有想到场景二中的解决方法，而是把“工人对技能的熟练程度”这个字段加到了技能表中。还算幸运的是，技能熟练程度只分为三个级别。</li>
</ul>
</li>
<li>
<p>那段时间，又恰巧碰到了一门考试，遇到了同样的问题，然后正在上机考试的我，突发奇想地想到了这个办法来解决这个问题。但当时设计的类同样<strong>存在缺陷</strong>。</p>
<ul>
<li>题目描述：
<ul>
<li>设计一个机票销售网站提供机票在线销售功能。客户登录系统后，可以查看航班列表，以及剩余机票数量，可以进行机票的购买，可以查看已购机票情况，对已购机票在规定的日期期限内可以退票。</li>
</ul>
</li>
<li>数据库要求：
<ul>
<li>客户表(Id, 身份证号, 姓名, 电话, 密码)</li>
<li>机票表(Id, 航班号, 起飞时间, 价格, 剩余数量)</li>
<li>机票购买表(Id, 客户Id, 机票Id, 购票日期, 退票标志, 退票日期)</li>
</ul>
</li>
<li>我的实体类设计（Java, 此处省略 getter, setter）：
<ul>
<li>Client.java</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Client</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> id<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> String govNumber<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> String fullName<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> String phoneNumber<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> String password<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> List<span style="color:#f92672">&lt;</span>Ticketing<span style="color:#f92672">&gt;</span> ticketingList<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><ul>
<li>Ticket.java</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Ticket</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> id<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> String flightNumber<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> Date takeOffTime<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">double</span> price<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> avaliable<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> List<span style="color:#f92672">&lt;</span>Client<span style="color:#f92672">&gt;</span> clientList<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div><ul>
<li>Ticketing.java</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Ticketing</span> <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> id<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> Client client<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> Ticket ticket<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> Date ticketingDate<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">int</span> cancelRemark<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">private</span> Date cancelDate<span style="color:#f92672">;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span></code></pre></div></li>
</ul>
<p>发现我当时的问题出在哪里了么？如果找到了，欢迎在评论区留言哦~😀（我就先不明说咯，逃</p>
</li>
<li>
<p>第三次遇到此问题</p>
<ul>
<li>自认为此次解决方法算是符合业界规范 😂 如果文章中有什么错误之处，烦请指出，感谢。</li>
<li>如下图所示，通过 Arrangement 实体连接其他三个实体。
<img loading="lazy" src="https://hiwangzi.com/posts/2017/05/26/po-in-many-to-many-relationship/resources/1104579-20170526221155294-1567452524.png" alt=""  />
</li>
</ul>
</li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>什么是.NET</title>
      <link>https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/</link>
      <pubDate>Sat, 25 Mar 2017 13:53:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/</guid>
      <description>开始学习这门课程，是源自一次无意间的发现。上一周时看到金老师的博客，觉得内容非常不错，这才开始了这门课程的学习。
面向对象软件开发实践之基本技能训练 - 网易云课堂
这门课能告诉他们：一个有用的软件到底是如何诞生的，我们在学校里学的操作系统、数据结构等专业课程到底在开发中是怎样应用的……
以下是本课程第一单元的笔记：
工具 .NET Reference Source 在此之前，有一次也想查看微软类库的源代码，可在 Visual Studio 中使用 F12 可以查看到的，仅仅只是定义，并没有对应的实现。那时还在想，难道是微软仅仅只是开放定义给开发人员。后来在网络上也没有搜索到相关内容（那时不知道如何描述，也没有找到合适的人请教），直到在这门课程中看到金老师的演示，才了解到微软的 .NET Framework 框架源码是完全开放的。
查看方式有两种：
直接在 .NET Reference Source 网站中在线浏览。
通过配置，在 Visual Studio 中调试 .NET Framework 源码。 具体配置方法参考：
微软开放了.NET 4.5.1的源代码 .NET Framework 4.5.1 已正式开源 配置Visual Studio 以调试.net framework的源代码 ildasm IL 反汇编程序是 IL 汇编程序 (Ilasm.exe) 的配套工具。Ildasm.exe 可利用包含中间语言 (IL) 代码的可移植可执行 (PE) 文件，并创建适合输入到 Ilasm.exe 的文本文件。此工具自动随 Visual Studio 一起安装。
命令行方式使用文档说明：Ildasm.exe（IL 反汇编程序）
如果已经安装了 Visual Studio 的话，可以在这个目录（C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools）下找到这个程序。实际情况取决于 Visual Studio 的版本，所以路径中的版本数字也可能会有所不同。</description>
      <content:encoded><![CDATA[<p>开始学习这门课程，是源自一次无意间的发现。上一周时看到<a href="http://jinxuliang.com/MainWebSite">金老师的博客</a>，觉得内容非常不错，这才开始了这门课程的学习。</p>
<p><a href="http://mooc.study.163.com/course/BIT-1000003016">面向对象软件开发实践之基本技能训练 - 网易云课堂</a></p>
<blockquote>
<p>这门课能告诉他们：一个有用的软件到底是如何诞生的，我们在学校里学的操作系统、数据结构等专业课程到底在开发中是怎样应用的……</p>
</blockquote>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/resources/1104579-20170325135010252-41469939.png" alt=""  />
</p>
<p>以下是本课程第一单元的笔记：</p>
<h1 id="工具">工具</h1>
<h2 id="net-reference-source">.NET Reference Source</h2>
<p>在此之前，有一次也想查看微软类库的源代码，可在 Visual Studio 中使用 F12 可以查看到的，仅仅只是定义，并没有对应的实现。那时还在想，难道是微软仅仅只是开放定义给开发人员。后来在网络上也没有搜索到相关内容（那时不知道如何描述，也没有找到合适的人请教），直到在这门课程中看到金老师的演示，才了解到微软的 .NET Framework 框架源码是完全开放的。</p>
<p>查看方式有两种：</p>
<ol>
<li>
<p>直接在 <a href="https://referencesource.microsoft.com/">.NET Reference Source</a> 网站中在线浏览。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/resources/1104579-20170325134935721-22581124.png" alt=""  />
</p>
</li>
<li>
<p>通过配置，在 Visual Studio 中调试 .NET Framework 源码。
具体配置方法参考：</p>
<ul>
<li><a href="http://www.infoq.com/cn/news/2014/02/microsoft-net-source-code">微软开放了.NET 4.5.1的源代码</a></li>
<li><a href="http://www.xcode.me/more/open-net-framework-451">.NET Framework 4.5.1 已正式开源</a></li>
<li><a href="http://edu.cnzz.cn/201412/95492de5.shtml">配置Visual Studio 以调试.net framework的源代码</a></li>
</ul>
</li>
</ol>
<h2 id="ildasm">ildasm</h2>
<p>IL 反汇编程序是 IL 汇编程序 (Ilasm.exe) 的配套工具。Ildasm.exe 可利用包含中间语言 (IL) 代码的可移植可执行 (PE) 文件，并创建适合输入到 Ilasm.exe 的文本文件。此工具自动随 Visual Studio 一起安装。</p>
<p>命令行方式使用文档说明：<a href="https://msdn.microsoft.com/zh-cn/library/f7dy01k1(v=vs.110).aspx">Ildasm.exe（IL 反汇编程序）</a></p>
<p>如果已经安装了 Visual Studio 的话，可以在这个目录（<code>C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools</code>）下找到这个程序。实际情况取决于 Visual Studio 的版本，所以路径中的版本数字也可能会有所不同。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/resources/1104579-20170325135053330-1063388121.png" alt=""  />
</p>
<h2 id="ilspy">ilspy</h2>
<p>ILSpy is the open-source .NET assembly browser and decompiler.</p>
<p>这个工具可以帮助我们将 .NET 可执行程序反汇编出 C# 源代码。官网地址：http://ilspy.net/</p>
<h1 id="关于-net">关于 .NET</h1>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/resources/1104579-20170325135111252-670076091.jpg" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/25/what-is-dotnet/resources/1104579-20170325135141455-829966262.jpg" alt=""  />
</p>
<p>未完待续&hellip;</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Entity Framework 新手入门友好实例</title>
      <link>https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/</link>
      <pubDate>Fri, 24 Mar 2017 22:35:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/</guid>
      <description>起因 因为实习的原因，程序之中用到了较多的数据库操作逻辑。如果每一处数据库操作都手写的话，工作量较大且后期不易于维护，所以希望能通过 ORM 框架来解决这两个问题。
在昨天之前，对于 ORM 这个词汇，我也仅仅只是在上个学期的 Java EE 课上看企业老师“神速”地使用 Hibernate 做了建立数据库、插入数据的演示。
这两天花了很多时间了解 Entity Framework，终于在今晚成功地实现了“查插删改”，中间经过了很多的波折。例如：查找的很多资料提供的代码都是不完整的，同时他们的讲解也不够“新人（菜鸟）友好型”。所以我决定把一个简单的实例的具体步骤写出来，帮助像我这样的菜鸟快速将 EF(Entity Framework) 应用起来。
如果博文有不当之处，欢迎指出，谢谢~
简介 首先是两个概念
对象关系映射（英语：Object Relational Mapping，简称 ORM，或 O/RM，或 O/R mapping），是一种程序设计技术，用于实现面向对象编程语言里不同类型系统的数据之间的转换。简单来说，就是可以把一条数据库记录转换为程序中的一个对象，或者反向转换，当然实际上 ORM 可以做更多的事情。）
Entity Framework (又称ADO.NET Entity Framework) 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案。
使用 Entity Framework 在实际数据库相关代码开发中可以采取三种方式：
DB First：先开发数据库，然后借助 Visual Studio 将数据库中的表结构（或视图）转换为程序中实体模型类。 Code First：直接在程序中定义实体模型类，然后借助 Visual Studio 将其转换为数据库中的表。 Model First：借助 Visual Studio 中的可视化设计工具，设计好数据模型（可以理解为E-R图），然后转换为数据库中的表。 本实例采用第三种方式，即 Model First。
实例演示 本实例使用的是 Visual Studio 2017(Community)，通过一个 WinForm 程序访问 SQL Server 2016(Express) 数据库来演示。</description>
      <content:encoded><![CDATA[<h1 id="起因">起因</h1>
<p>因为实习的原因，程序之中用到了较多的数据库操作逻辑。如果每一处数据库操作都手写的话，工作量较大且后期不易于维护，所以希望能通过 ORM 框架来解决这两个问题。</p>
<p>在昨天之前，对于 ORM 这个词汇，我也仅仅只是在上个学期的 Java EE 课上看企业老师“神速”地使用 Hibernate 做了建立数据库、插入数据的演示。</p>
<p>这两天花了很多时间了解 Entity Framework，终于在今晚成功地实现了“查插删改”，中间经过了很多的波折。例如：查找的很多资料提供的代码都是不完整的，同时他们的讲解也不够“新人（菜鸟）友好型”。所以我决定把一个简单的实例的具体步骤写出来，帮助像我这样的菜鸟快速将 EF(Entity Framework) 应用起来。</p>
<p>如果博文有不当之处，欢迎指出，谢谢~</p>
<h1 id="简介">简介</h1>
<p>首先是两个概念</p>
<ul>
<li>
<p><a href="https://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84">对象关系映射</a>（英语：Object Relational Mapping，简称 ORM，或 O/RM，或 O/R mapping），是一种程序设计技术，用于实现面向对象编程语言里不同类型系统的数据之间的转换。简单来说，就是可以把一条数据库记录转换为程序中的一个对象，或者反向转换，当然实际上 ORM 可以做更多的事情。）</p>
</li>
<li>
<p><a href="https://zh.wikipedia.org/wiki/Entity_Framework">Entity Framework</a> (又称ADO.NET Entity Framework) 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案。</p>
</li>
</ul>
<p>使用 Entity Framework 在实际数据库相关代码开发中可以采取三种方式：</p>
<ul>
<li>DB First：先开发数据库，然后借助 Visual Studio 将数据库中的表结构（或视图）转换为程序中实体模型类。</li>
<li>Code First：直接在程序中定义实体模型类，然后借助 Visual Studio 将其转换为数据库中的表。</li>
<li>Model First：借助 Visual Studio 中的可视化设计工具，设计好数据模型（可以理解为E-R图），然后转换为数据库中的表。</li>
</ul>
<p>本实例采用第三种方式，即 Model First。</p>
<h1 id="实例演示">实例演示</h1>
<p>本实例使用的是 Visual Studio 2017(Community)，通过一个 WinForm 程序访问 SQL Server 2016(Express) 数据库来演示。</p>
<p>本程序可以实现学生信息的自我维护，包括对用户名、密码、性别、班级、电话等资料的处理。学生可以填写信息注册账号，然后使用账号登录查看自己的信息，并对自己的信息进行修改。</p>
<p>演示：</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324230234065-200866055.gif" alt="demo"  />
</p>
<h2 id="数据实体">数据实体</h2>
<p>两个实体：</p>
<ul>
<li>
<p>用户（用户名，密码）</p>
</li>
<li>
<p>个人资料（学号，姓名，性别，电话，地址，爱好）</p>
</li>
</ul>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324203238908-2019676022.png" alt="E-R图"  />
</p>
<h2 id="具体步骤">具体步骤</h2>
<h3 id="1-新建一个名为-sstudent-的-winform-程序项目">1. 新建一个名为 Sstudent 的 WinForm 程序项目</h3>
<h3 id="2-新建一个名为-model-的类库项目可选">2. 新建一个名为 Model 的类库项目（可选）</h3>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221145705-2008536491.png" alt=""  />
</p>
<h3 id="3-新增一个名为-sstudent-的-adonet-entity-data-model">3. 新增一个名为 Sstudent 的 ADO.NET Entity Data Model</h3>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221209518-471292487.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221228393-1328355887.png" alt=""  />
</p>
<h4 id="31-在向导中选择空的实体设计器模型">3.1 在向导中选择空的实体设计器模型</h4>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221223299-45703138.png" alt=""  />
</p>
<h4 id="32-然后就可以开始创建自己的实体模型">3.2 然后就可以开始创建自己的实体模型</h4>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221307346-496476446.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221320408-640441422.png" alt=""  />
</p>
<p>这里首先从工具栏拖出两个 Entity 。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221249565-1600712620.png" alt=""  />
</p>
<p>此时我们观察一下属性区，这里有两项比较重要的属性，如下图</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221257736-316838821.png" alt=""  />
</p>
<p>其中 Name 可以理解为对应将来的数据库表中的一条记录的名字，Entity Set Name 对应的则是一张表的名字。这里修改一下，即用户表（或用户集，UserSet）中会有多条用户记录（User）。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221355096-2145566696.png" alt=""  />
</p>
<p>再来观察一下实体中的属性，在我们创建 Entity 的时候，会自动产生一个名为 Id 的非空自增实体键，如下图所示。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221401330-1383697017.png" alt=""  />
</p>
<p>现在我们完善一下两个实体的属性，这里为了简便，所有的属性都设置为了 String 类型，对应到数据库即为 nvarchar(MAX)。这里其中一个属性用中文命名是想说明，C# 对中文是完全支持的。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221413549-389531410.png" alt=""  />
</p>
<p>在完成了实体的创建之后，下一步进行实体之间关系的创建，同样从工具栏中拖出一个关系到两个实体之间，因为用户与个人资料之间的关系是 1对1，所以选中关系后，在属性区修改其对应关系。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221431361-646234423.png" alt=""  />
</p>
<p>然后，在操作区点击右键，选择从模型生成数据库，根据指引，即可完成数据库的建立。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221454127-1051539095.png" alt=""  />
</p>
<p>如果之前没有数据库连接的话，点击“新建连接”选项，按照你的需求选择，这里选择 SQL Server，输入相关信息后，即可完成连接的建立。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221528440-661247942.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221557143-1317974254.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221609049-40650076.png" alt=""  />
</p>
<p>补充：如果此处输入的数据库名不存在，会自动创建对应数据库。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221616158-963792860.png" alt=""  />
</p>
<p>然后按照提示，可以得到自动生成的 SQL 文件，点击绿色按钮执行即可（此处同样要求输入数据库的账号密码）。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221630127-1121502099.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221640752-1514726219.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221647549-2066674917.png" alt=""  />
</p>
<p>在完成创建后，到SQL Server Management Studio 中查看数据库即可发现，表已经被创建。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221659408-465682256.png" alt=""  />
</p>
<p>因为实体之间是 1对1 的关系，所以不会创建新的关系表，而是将其中一张表的主键附加到另一张表中，如下图所示。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221710033-113824704.png" alt=""  />
</p>
<h3 id="4-下面来说一说如何通过创建的模型来访问数据库">4. 下面来说一说如何通过创建的模型来访问数据库。</h3>
<h4 id="41-先来看一下-ef-框架帮我们创建的文件如下图所示">4.1 先来看一下 EF 框架帮我们创建的文件，如下图所示。</h4>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221726643-1991348623.png" alt=""  />
</p>
<h4 id="42-我们新建一个名为-ui-的项目用于展现界面与接受用户操作因为本项目同样直接使用-ef-框架所以在此项目中也需要引用-entity-framework同时引用-model-项目">4.2 我们新建一个名为 UI 的项目，用于展现界面与接受用户操作。因为本项目同样直接使用 EF 框架，所以在此项目中也需要引用 Entity Framework，同时引用 Model 项目。</h4>
<p>(1) 使用 Nuget 引用 Entity Framework。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221817315-2089909743.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221805908-2138574699.png" alt=""  />
</p>
<p>(2) 引用同解决方案的另一个项目 Model。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221741580-223043384.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324221756440-1343484106.png" alt=""  />
</p>
<p>然后就可以方便地如下图所示一般使用“数据库”了，下图所示为两个实体对象集（可理解为数据表）。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324222007221-337398525.png" alt=""  />
</p>
<h4 id="43-通过-ef-框架实现查询功能">4.3 通过 EF 框架实现查询功能。</h4>
<pre tabindex="0"><code class="language-CS" data-lang="CS">// 登录
private void button_Login_Click(object sender, EventArgs e)
{
    // 使用 EF 框架实现查询
    User u=sstudentContainer.UserSet.Where(user =&gt; user.Userame == textBox_Username.Text &amp;&amp; user.Password == textBox_Password.Text).FirstOrDefault();
    // 如果查询不到，会返回 null
    if (u != null)
    {
        new MyProfile(u).Show();
        this.Hide();
    }
    else
    {
        MessageBox.Show(&#34;用户名或密码错误，请重试！&#34;);
    }
}
</code></pre><h4 id="44-通过-ef-框架实现插入功能">4.4 通过 EF 框架实现插入功能。</h4>
<pre tabindex="0"><code class="language-CS" data-lang="CS">// 注册
private void button_Signup_Click(object sender, EventArgs e)
{
    try
    {
        // 使用 EF 框架实现添加新数据功能
        User u = new User();
        Profile p = new Profile();

        u.Password = this.textBox_Password.Text;
        u.Userame = this.textBox_Username.Text;

        p.Address = this.textBox_Address.Text;
        p.Hobby = this.textBox_Hobby.Text;
        p.PhoneNumber = this.textBox_PhoneNumber.Text;
        p.Sex = this.textBox_Sex.Text;
        p.StudentNumber = this.textBox_StudentNumber.Text;
        p.姓名 = this.textBox_FullName.Text;

        u.Profile = p;

        // 添加两个新对象分别进入两张表
        sstudentContainer.UserSet.Add(u);
        // 因为 EF 会自动将关联的对象同时加入数据库，所以无需手动增加
        //sstudentContainer.ProfileSet.Add(p);

        // 保存新增记录进入数据库
        sstudentContainer.SaveChanges();

        MessageBox.Show(&#34;注册成功！&#34;);

        this.Close();
    }
    catch (Exception)
    {
        MessageBox.Show(&#34;抱歉，注册失败！&#34;);
        throw;
    }
}
</code></pre><h4 id="45-通过-ef-框架实现删除功能">4.5 通过 EF 框架实现删除功能。</h4>
<pre tabindex="0"><code class="language-CS" data-lang="CS">// 删除用户所有资料
private void button_Delete_Click(object sender, EventArgs e)
{
    // 使用 EF 框架实现删除数据
    try
    {
        // 需要首先使用 sstudentContainer 查找到该项记录（对象），然后将其删除
        User u = sstudentContainer.UserSet.Where(user =&gt; user.Id == this.user.Id).FirstOrDefault();
        Profile p = u.Profile;

        // 删除用户
        sstudentContainer.ProfileSet.Remove(p);
        sstudentContainer.UserSet.Remove(u);

        // 保存删除操作进入数据库
        sstudentContainer.SaveChanges();

        MessageBox.Show(&#34;再见，删除成功！&#34;);

        this.Close();
    }
    catch (Exception)
    {
        // 发生异常，删除失败
        MessageBox.Show(&#34;抱歉，删除失败！&#34;);
        throw;
    }
}
</code></pre><h4 id="46-通过-ef-框架实现更新功能">4.6 通过 EF 框架实现更新功能。</h4>
<pre tabindex="0"><code class="language-CS" data-lang="CS">// 更新用户资料
private void button_Update_Click(object sender, EventArgs e)
{
    // 使用 EF 框架实现更新数据
    try
    {
        // 需要首先使用 sstudentContainer 查找到该项记录（对象），然后对其进行修改
        User u = sstudentContainer.UserSet.Where(user =&gt; user.Id == this.user.Id).FirstOrDefault();
        Profile p = u.Profile;

        u.Password = this.textBox_Password.Text;
        u.Userame = this.textBox_Username.Text;

        p.Address = this.textBox_Address.Text;
        p.Hobby = this.textBox_Hobby.Text;
        p.PhoneNumber = this.textBox_PhoneNumber.Text;
        p.Sex = this.textBox_Sex.Text;
        p.StudentNumber = this.textBox_StudentNumber.Text;
        p.姓名 = this.textBox_FullName.Text;

        // 保存更改进入数据库
        sstudentContainer.SaveChanges();

        MessageBox.Show(&#34;更新资料成功！&#34;);
    }
    catch (Exception)
    {
        // 发生异常，更新失败
        MessageBox.Show(&#34;更新资料失败！&#34;);
        throw;
    }
}
</code></pre><h4 id="47-当我们尝试运行程序的时候会发现出现异常这是因为在-ui-项目中缺少了数据库连接字符串即下图中的选中部分只要将其复制即可">4.7 当我们尝试运行程序的时候，会发现出现异常，这是因为在 UI 项目中缺少了数据库连接字符串，即下图中的选中部分。只要将其复制，即可。</h4>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324222023596-348197448.png" alt=""  />
</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2017/03/24/entity-framework-newbie-sample/resources/1104579-20170324222029705-941688901.png" alt=""  />
</p>
<h1 id="补充">补充</h1>
<p>EF 能帮我们做的事情还有很多，例如可以方便快捷地通过 ToList() 方法直接将数据库中所有数据转换为对象List。而本文只是一个简单的入门实例，只是仅仅帮助初次接触 EF 摸不到头脑的新手快速实战应用，需要学习的还有很多。如果本文有任何错误或不当之处，敬请指出，共同进步，谢谢~</p>
<p>附上源代码：<a href="./resources/Sstudent.zip">下载地址</a></p>
<p>补充一个不错的视频（但是其中的实例演示并没有成功）：</p>
<p><a href="https://www.youtube.com/watch?v=hbOJjjDyZIA">Entity Framework 實戰技巧 - YouTube</a></p>
<p>Code First 实例可以参考：</p>
<p><a href="https://segmentfault.com/a/1190000004152660">Entity Framework(EF) Code First 多对多关系的实体增，删，改，查操作全程详细示例</a></p>
<p>其他可能对你有帮助的链接：</p>
<ol>
<li>
<p><a href="http://www.jianshu.com/p/ce8026992275">ORM框架之EntityFramework介绍</a></p>
</li>
<li>
<p><a href="http://blog.csdn.net/zezhi821/article/category/1072082">Entity(Ado.net) - zezhi821的专栏</a></p>
</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>JetBrains 套装免费学生授权申请（IntelliJ, WebStorm...）</title>
      <link>https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/</link>
      <pubDate>Fri, 10 Feb 2017 18:20:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/</guid>
      <description>希望各位享受权利的同时不要忘记自己的义务，不要售卖、转手自己的学生优惠资格，不要作践自己作为学生的价值</description>
      <content:encoded><![CDATA[<p>IntelliJ 作为一款强大的 Java 开发 IDE，售价自然也不会低。但是对于学生或教师来说，JetBrains 开发工具免费提供给学生和教师使用。而且取得一次授权后只需要使用相同的 JetBrains 帐号就可以激活其他产品，不需要重复申请。</p>
<h1 id="个人申请步骤如下">个人申请步骤如下：</h1>
<ol>
<li>
<p>打开 <a href="https://www.jetbrains.com/student/">申请页面</a> ，点击 “APPLY NOW” 开始申请。</p>
</li>
<li>
<p>填写姓名，以及学校提供给你的邮箱（邮箱地址要 edu.cn 结尾）
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182225776-2069207674.png" alt="邮箱地址要 edu.cn 结尾"  />
</p>
</li>
<li>
<p>下一步后，进入邮箱查看（如果收件箱没有找到，请查看是否为误判丢进了“垃圾邮件”）
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182401666-127812153.png" alt="我就是在“垃圾邮件”中找到的确认信"  />
</p>
</li>
<li>
<p>点击 “Confirm Request” 进行确认，打开的网站会提示你注册 JetBrains 账号，输入账号与密码后，再次确认。</p>
</li>
<li>
<p>回到邮箱，刷新，此时点击 “Active Educational License”
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182443901-1908718854.png" alt="激活 License"  />
</p>
</li>
<li>
<p>成功的获得授权码。
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182522026-1640609592.png" alt="可以看到，JetBrains 开发工具非常多，而且都可以免费使用了"  />
</p>
</li>
<li>
<p>官网下载开发工具，以 IntelliJ 为例（注意下载<a href="https://www.jetbrains.com/idea"><strong>Ultimate版本</strong></a>），<a href="https://download.jetbrains.8686c.com/idea/ideaIU-2016.3.4.exe">2016.3.4版本直接下载地址</a>在此。</p>
</li>
<li>
<p>可以直接通过之前注册的 JetBrains 帐号激活产品。
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182531260-139502386.png" alt="登录即可激活"  />
</p>
</li>
<li>
<p>激活完成，Help-&gt;Register验证。
<img loading="lazy" src="https://hiwangzi.com/posts/2017/02/10/how-to-apply-jetbrains-education-license/resources/1104579-20170210182537322-1839919749.png" alt="激活成功"  />
</p>
</li>
</ol>
<h1 id="注意">注意：</h1>
<ol>
<li>申请的 Lisence 有效期为一年，在到期后，可以去官网重新认证。</li>
<li>一个 Lisence 可以在多台设备验证，但同时使用的只能为1台，<strong><a href="https://sales.jetbrains.com/hc/zh-cn/articles/206544319-%E6%88%91%E5%8F%AF%E4%BB%A5%E5%9C%A8%E4%B8%A4%E9%83%A8%E4%B8%8D%E5%90%8C%E7%94%B5%E8%84%91%E4%B8%8A%E4%BD%BF%E7%94%A8%E6%88%91%E7%9A%84%E4%B8%AA%E4%BA%BA%E6%8E%88%E6%9D%83%E5%90%97-">参考网站</a></strong>。</li>
<li><a href="https://github.com/ivmm/Student-resources/"><strong>更多的学生优惠资源</strong></a>在此。</li>
<li>最后，引用第3条中作者的一句话，“希望各位享受权利的同时不要忘记自己的义务，不要售卖、转手自己的学生优惠资格，不要作践自己作为学生的价值”，谢谢！</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>我的十月</title>
      <link>https://hiwangzi.com/posts/2016/10/31/october-2016/</link>
      <pubDate>Mon, 31 Oct 2016 21:00:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2016/10/31/october-2016/</guid>
      <description>10月是个忙碌的月份，总感觉每天都是匆匆忙忙，人生何其短……</description>
      <content:encoded><![CDATA[<p>10月是个忙碌的月份，总感觉每天都是匆匆忙忙，人生何其短……</p>
<p>从上个学期末就在计划的教务系统爬虫在10月终于开始真正的实施。这个月以来，大概每个周末都在尝试推进，可大多数时候都是只做一小会儿就不知道干什么去了……一直到上上个周末，抱着一种写不出来就不睡觉的精神，花了大概一天的时间。但是，然而并没有主角光环，在最后一个关键的页面上，出现了目前我无法解决的问题（某一过程陷入死循环）。请教了几个人，还是没有解决，只能等这个学期闲下来或者寒假里，再继续研究了。</p>
<p>这个月，参加的活动比较多。参加了深度的开发者与用户大会（DDUC），又去现场看了老罗的相声；最近又接连熬夜两天，从吃瓜到吃惊的看完了微软与苹果的发布会。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2016/10/31/october-2016/resources/1104579-20170216220039222-1273401378.jpg" alt="Smartisan Conference at Shanghai 2016"  title="Smartisan Conference at Shanghai 2016"  />
</p>
<p>先说深度吧。可以说，深度是我在国内最为佩服的企业（至少目前），在国内一票儿骗拨款的各种国产 Linux 的“辣眼睛”中，作为一家私企，真的是一股清流。我觉得评价“Deepin 做到了小白开箱即用、好用”一点都不过分，我最喜欢的就是它的应用商店了，真的是极大的缓解了我这种“半吊子水平”的用户的 Software Panic。在现场，听了王勇（不过说起来，在去之前我并不知道深度的老板是谁，补充他也是产品经理）的演讲，也才意识到，其实深度也只是小公司，人微言轻，认真做事并活下去也是挺难的。另外，最喜欢王勇讲的一点是“独立思想 创造贡献 最后才是分享”，他觉得这才是开源社区的本质。非常认同这一点，所以，好好做事，然后才是分享。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2016/10/31/october-2016/resources/1104579-20170216220102910-1146504819.jpg" alt="Deepin Developer and User Conference 2016"  title="Deepin Developer &amp; User Conference 2016"  />
</p>
<p>再说说锤子发布会吧。之前对于锤子其实并不了解，知道锤子还是因为当时王自如与罗永浩的现场论战，所以这次去的时候，还和朋友戏谑说“说不定是锤子的最后一场发布会”，似乎现在看来锤子成功的活下去了。虽然锤子M1并没有激发我的购买欲，但Smartisan OS 也还是有一些亮点的。通过不同的手指指纹解锁屏幕，可以快速的打开支付宝或者微信支付的二维码界面、大爆炸分词都挺不错的。</p>
<p>虽然罗永浩总是不停地撕逼，甚至在本次发布会也要黑一下苹果……但他能够介绍很长时间的讯飞等企业，同时承诺以后会把 One Step 开源，这让我对其的好感度提高不少。或许，全靠国内其他友商照应吧。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2016/10/31/october-2016/resources/1104579-20170216220122191-1934671674.jpg" alt="Smartisan Conference at Shanghai 2016"  title="Smartisan Conference at Shanghai 2016"  />
</p>
<p>10月尾声，微软与苹果接连分别召开了自己的新品发布会。总体来讲，感觉都不够让人眼前一亮，或许是因为之前看过太多爆料新闻了吧。不过，Surface Dial让我感觉还不错，以一种简单的方式补足了单纯依靠触摸屏时某些操作不便的不足。就如同之前提到的锤子通过验证不同指纹来打开支付宝或微信二维码。</p>
<p>而说到苹果，在库克对场内观众说可以去后场体验一下新产品的时候，熬夜到3点看完接近两个小时的发布会，让接下来还有两场考试的我，不由得想讲“裤脱看”。发布会一半的时间在演示“神奇的”Touch Bar，真是尴尬症都犯了，而到了 DJ 上台用新款 Macbook Pro 来打碟的时候，我只想说“WTF”。如果 DJ 需要触摸操作的话，那么他需要的应该是 iPad 吧。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2016/10/31/october-2016/resources/1104579-20170216220141832-1880497483.jpg" alt="2016 Macbook Pro with Touch Bar"  title="2016 Macbook Pro with Touch Bar"  />
</p>
<p>在我看来，4个 type-c 可以说代表了未来的趋势，可问题在于，既然 Macbook Pro 都采用了 type-c，为什么不能统一一下，让 iPhone 也换上新接口呢？因为混乱的接口导致需要各种转接器，这还是我心中代表着优质产品的苹果么？</p>
<p>如果说已经阉割了 Touch Bar 的新款13吋 mbp，同时又阉割一系列配置是为了区分价位，可是为什么还有再阉割掉两个接口？这次发布会最让我印象深刻的不是什么产品，而是精明商人库克。15吋低配价格直涨￥5000；new macbook参数不变，价格直涨￥600……</p>
<p>在气愤两天之后，我想明白了，还是我太穷了（滑稽 （哭泣</p>
<p>这个周末，“准备”了1个月的腾讯云校园工作坊终于在昨晚办完了……从最开始准备要筛选报名者，再到线上宣传期间，中间态度的转变很有趣。宣传期间，寥寥无几的报名者，让我一度以为，能来十几个人就已经非常不错了。幸运的是，最终还是接近30个到场的参与者。虽然过程与最终结果都与我想象中的不同，但和小伙伴们一起做成一件事还是非常开心的。</p>
<p><img loading="lazy" src="https://hiwangzi.com/posts/2016/10/31/october-2016/resources/1104579-20170216220155238-1641328351.jpg" alt="Tencent Cloud Campus Lecture 2016"  title="Tencent Cloud Campus Lecture 2016"  />
</p>
<p>现在想来，活动策划期间，最值得注意的就是团队沟通。大致有以下几点吧：</p>
<ul>
<li>人数众多的 IM 沟通群会让人抓狂，尤其不限制交流话题的时候；</li>
<li>与他人沟通要注意反馈，不要想象对方拥有和你一样的思维；</li>
<li>注意说话的语气，“说者无意，听者有心”并非只是一句谚语。</li>
<li>无论如何，这大概就是我10月里值得讲述的事了……</li>
</ul>
<p>好好做事才是真！</p>
<p>以上。</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>关于《未成年人网络保护条例（草案征求意见稿）》的意见</title>
      <link>https://hiwangzi.com/posts/2016/10/04/%E5%85%B3%E4%BA%8E%E6%9C%AA%E6%88%90%E5%B9%B4%E4%BA%BA%E7%BD%91%E7%BB%9C%E4%BF%9D%E6%8A%A4%E6%9D%A1%E4%BE%8B%E8%8D%89%E6%A1%88%E5%BE%81%E6%B1%82%E6%84%8F%E8%A7%81%E7%A8%BF%E7%9A%84%E6%84%8F%E8%A7%81/</link>
      <pubDate>Tue, 04 Oct 2016 09:34:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2016/10/04/%E5%85%B3%E4%BA%8E%E6%9C%AA%E6%88%90%E5%B9%B4%E4%BA%BA%E7%BD%91%E7%BB%9C%E4%BF%9D%E6%8A%A4%E6%9D%A1%E4%BE%8B%E8%8D%89%E6%A1%88%E5%BE%81%E6%B1%82%E6%84%8F%E8%A7%81%E7%A8%BF%E7%9A%84%E6%84%8F%E8%A7%81/</guid>
      <description>2016年9月30日，网信办正式发布《未成年人网络保护条例（草案征求意见稿）》。最早看到这条信息是在知乎（ 网瘾即将合法化，绿坝将强奸全部智能设备 ）。因为对其中的某些条例存在意见，故写了电邮反馈。
同时希望大家也可以将自己的意见通过电邮的形式表达，条例内容及反馈方式在此：
国家互联网信息办公室关于《未成年人网络保护条例（草案征求意见稿）》公开征求意见的通知-中共中央网络安全和信息化领导小组办公室
截止日期是2016年10月31日。
我的邮件内容如下：
您好，
关于这份草案，作为一名已经上网近10年的网民，我有如下意见：
网瘾并不是疾病，不需要治疗。草案中第二十条如此表述：
第二十条 教育、卫生计生等部门依据各自职责，组织开展预防未成年人沉迷网络的教育，对未成年人网络成瘾实施干预和矫治。
县级以上人民政府及其教育行政部门应当为中小学校配备专门教师或提高教师专业水平，增强对未成年人沉迷网络的早期识别和干预能力，并可以通过购买服务等方式提供预防和干预未成年人沉迷网络的教育或服务。
国务院卫生计生部门会同有关部门推动出台网络成瘾的本土化预测和诊断测评系统，制定诊断、治疗规范。
可是截至目前为止，国际社会上并无任何临床标准证明网瘾属于疾病。难道只有我国的青少年独有此病？所以治疗矫正，自然无稽之谈。此种举动，将会使社会上出现越来越多的杨永信之流，带给青少年的反而是更多的伤害。
我认为对于智能终端设备，不应当强制要求出厂时、销售前安装未成年人上网保护软件。草案中第十二条表述如下：
第十二条 智能终端产品制造商在产品出厂时、智能终端产品进口商在产品销售前应当在产品上安装未成年人上网保护软件，或者为安装未成年人上网保护软件提供便利并采用显著方式告知用户安装渠道和方法。
我认为仅保留最后一句表述即可，即
智能终端产品制造商应当为安装未成年人上网保护软件提供便利并采用显著方式告知用户安装渠道和方法。
因为使用智能终端的用户群体中，不止未成年人，还有成年人。对于成年人而言，是拥有能力辨别有害信息的，不需要国家统一划定范围。
我认为保护青少年不受到网络伤害、不沉迷网络的最重要解决途径应当是为青少年增加更多的公益场所、公益娱乐项目。
现在青少年更多地喜欢上网的原因一方面是因为网络世界很精彩，可很重要的另一方面也是他们闲暇时要么无处可去，要么就要花费大量金钱才可以参加绘画、音乐等娱乐活动。
相较于发达国家，我们国家城市中公益性质的活动场所太少。例如，国外的青少年暑假可以在公共游泳馆愉快玩耍，而我们的青少年却要花费百元乃至千元才可以得到同样的娱乐机会。
自然，免费或说低成本的互联网更吸引青少年的注意力。同时，这也是寒门子弟得到知识、提升综合素质成本最低的方式。如果政府再进一步限制青少年上网，那么我国的阶层固化将进一步严重。
以上是我的一点看法，感谢您的阅读，同时希望您能认真考虑一下以上三点意见。
谢谢！
2016年10月4日</description>
      <content:encoded><![CDATA[<p>2016年9月30日，网信办正式发布《未成年人网络保护条例（草案征求意见稿）》。最早看到这条信息是在知乎（ <a href="https://zhuanlan.zhihu.com/p/22743759">网瘾即将合法化，绿坝将强奸全部智能设备</a> ）。因为对其中的某些条例存在意见，故写了电邮反馈。</p>
<p>同时希望大家也可以将自己的意见通过电邮的形式表达，条例内容及反馈方式在此：</p>
<p><a href="http://www.cac.gov.cn/2016-09/30/c_1119656665.htm">国家互联网信息办公室关于《未成年人网络保护条例（草案征求意见稿）》公开征求意见的通知-中共中央网络安全和信息化领导小组办公室</a></p>
<p>截止日期是2016年10月31日。</p>
<p>我的邮件内容如下：</p>
<hr>
<p>您好，</p>
<p>关于这份草案，作为一名已经上网近10年的网民，我有如下意见：</p>
<ol>
<li>
<p>网瘾并不是疾病，不需要治疗。草案中第二十条如此表述：</p>
<blockquote>
<p>第二十条 教育、卫生计生等部门依据各自职责，组织开展预防未成年人沉迷网络的教育，对未成年人网络成瘾<strong>实施干预和矫治</strong>。</p>
<p>县级以上人民政府及其教育行政部门应当为中小学校配备专门教师或提高教师专业水平，增强对未成年人沉迷网络的早期识别和干预能力，并可以通过购买服务等方式提供预防和干预未成年人沉迷网络的教育或服务。</p>
<p>国务院卫生计生部门会同有关部门推动出台网络成瘾的本土化预测和诊断测评系统，制定诊断、治疗规范。</p>
</blockquote>
<p>可是截至目前为止，国际社会上并无任何临床标准证明网瘾属于疾病。难道只有我国的青少年独有此病？所以治疗矫正，自然无稽之谈。此种举动，将会使社会上出现越来越多的<a href="https://zh.wikipedia.org/wiki/%E6%9D%A8%E6%B0%B8%E4%BF%A1">杨永信</a>之流，带给青少年的反而是更多的伤害。</p>
</li>
<li>
<p>我认为对于智能终端设备，不应当强制要求出厂时、销售前安装未成年人上网保护软件。草案中第十二条表述如下：</p>
<blockquote>
<p>第十二条 智能终端产品制造商在产品出厂时、智能终端产品进口商在产品销售前应当在产品上安装未成年人上网保护软件，或者为安装未成年人上网保护软件提供便利并采用显著方式告知用户安装渠道和方法。</p>
</blockquote>
<p>我认为仅保留最后一句表述即可，即</p>
<blockquote>
<p>智能终端产品制造商应当为安装未成年人上网保护软件提供便利并采用显著方式告知用户安装渠道和方法。</p>
</blockquote>
<p>因为使用智能终端的用户群体中，不止未成年人，还有成年人。对于成年人而言，是拥有能力辨别有害信息的，不需要国家统一划定范围。</p>
</li>
<li>
<p>我认为保护青少年不受到网络伤害、不沉迷网络的<strong>最重要解决途径应当是为青少年增加更多的公益场所、公益娱乐项目</strong>。</p>
<p>现在青少年更多地喜欢上网的原因一方面是因为网络世界很精彩，可很重要的另一方面也是他们闲暇时要么无处可去，要么就要花费大量金钱才可以参加绘画、音乐等娱乐活动。</p>
<p>相较于发达国家，我们国家城市中公益性质的活动场所太少。例如，国外的青少年暑假可以在公共游泳馆愉快玩耍，而我们的青少年却要花费百元乃至千元才可以得到同样的娱乐机会。</p>
<p>自然，免费或说低成本的互联网更吸引青少年的注意力。同时，这也是寒门子弟得到知识、提升综合素质成本最低的方式。如果政府再进一步限制青少年上网，那么我国的阶层固化将进一步严重。</p>
</li>
</ol>
<p>以上是我的一点看法，感谢您的阅读，同时希望您能认真考虑一下以上三点意见。</p>
<p>谢谢！</p>
<p>2016年10月4日</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>C#指定并保留分隔符，字符串转数组</title>
      <link>https://hiwangzi.com/posts/2016/09/04/split-string-into-array-by-specific-separator-in-csharp/</link>
      <pubDate>Sun, 04 Sep 2016 14:41:00 +0800</pubDate>
      
      <guid>https://hiwangzi.com/posts/2016/09/04/split-string-into-array-by-specific-separator-in-csharp/</guid>
      <description>mmmmmmynameismickeym -&amp;gt; [&amp;ldquo;m&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;yna&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;eis&amp;rdquo;, &amp;ldquo;m&amp;rdquo;, &amp;ldquo;ickey&amp;rdquo;, &amp;ldquo;m&amp;rdquo;]</description>
      <content:encoded><![CDATA[<h1 id="要求如下">要求如下：</h1>
<pre tabindex="0"><code>source string: mmmmmmynameismickeym

separator: m

result string []: {&#34;m&#34;, &#34;m&#34;, &#34;m&#34;, &#34;m&#34;, &#34;m&#34;, &#34;m&#34;, &#34;yna&#34;, &#34;m&#34;, &#34;eis&#34;, &#34;m&#34;, &#34;ickey&#34;, &#34;m&#34;}
</code></pre><h1 id="思路分析">思路分析：</h1>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>1 判断 source string 是否包含 separator
</span></span><span style="display:flex;"><span>    1.1 若不包含，则将其包装为 string 数组返回
</span></span><span style="display:flex;"><span>    1.2 若包含，则进行下列操作
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>2 将 source string 转换为 char 数组
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>3 对数组每个字符依次进行检测（循环）
</span></span><span style="display:flex;"><span>    3.1 若不为分隔符，则先将内容存入临时 string 变量 temp
</span></span><span style="display:flex;"><span>    3.2 若为分隔符，则检测 temp 是否为空
</span></span><span style="display:flex;"><span>        - 若 temp 不为空，则先将 temp 变量的值写入 result 数组
</span></span><span style="display:flex;"><span>        - 将分隔符写入 result 数组
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>4 循环体外，检查 temp 变量是否为 null
</span></span><span style="display:flex;"><span>    - 若不为空，则将其写入 result 数组
</span></span><span style="display:flex;"><span>    - 返回 string 数组 result
</span></span></code></pre></div><h1 id="代码">代码：</h1>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-cs" data-lang="cs"><span style="display:flex;"><span><span style="color:#75715e">// 需要引入命名空间</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// using System;</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// using System.Linq;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">static</span> <span style="color:#66d9ef">string</span>[] splitString(<span style="color:#66d9ef">string</span> source_str, <span style="color:#66d9ef">char</span> separator)
</span></span><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//1. 判断 source string 是否包含 separator</span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//1.1 string 中不包括分隔符</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> (source_str.IndexOf(separator) == -<span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//为了返回原字符串，将其包成一个只有一项的string数组返回</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">string</span>[] source_str_pack = <span style="color:#66d9ef">new</span> <span style="color:#66d9ef">string</span>[<span style="color:#ae81ff">1</span>]; <span style="color:#75715e">//试一试string[source_str]</span>
</span></span><span style="display:flex;"><span>        source_str_pack[<span style="color:#ae81ff">0</span>] = source_str;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> source_str_pack;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">//1.2 string 中包括分隔符</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>    {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//2. 将 source_str 转换为 char 数组</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">char</span>[] source = source_str.ToCharArray();
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">string</span> temp = <span style="color:#66d9ef">null</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">int</span> resultID = <span style="color:#ae81ff">0</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">string</span>[] result = <span style="color:#66d9ef">new</span> <span style="color:#66d9ef">string</span>[source.Length];<span style="color:#75715e">//这样的结果会有大量的 null 元素，后面在返回结果前，进行处理去除无用的 null 元素</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">//3. 对数组每个字符依次进行检测</span>
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">int</span> i = <span style="color:#ae81ff">0</span>; i &lt; source.Length; i++)
</span></span><span style="display:flex;"><span>        {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//3.1 若不为分隔符，则先将内容存入临时 string 变量 temp</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (source[i].Equals(separator) == <span style="color:#66d9ef">false</span>)
</span></span><span style="display:flex;"><span>            {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">if</span> (temp == <span style="color:#66d9ef">null</span>)
</span></span><span style="display:flex;"><span>                {
</span></span><span style="display:flex;"><span>                    temp = <span style="color:#e6db74">&#34;&#34;</span>;
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                temp = temp.Insert(temp.Length, source[i].ToString());
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//3.2 若为分隔符，则检测 temp 是否为空</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>            {
</span></span><span style="display:flex;"><span>                <span style="color:#75715e">//temp不为空，先将 temp 变量的值写入 result 数组</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">if</span> (temp != <span style="color:#66d9ef">null</span>)
</span></span><span style="display:flex;"><span>                {
</span></span><span style="display:flex;"><span>                    result[resultID] = temp;
</span></span><span style="display:flex;"><span>                    resultID++;
</span></span><span style="display:flex;"><span>                    temp = <span style="color:#66d9ef">null</span>;
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                <span style="color:#75715e">//将分隔符写入 result 数组</span>
</span></span><span style="display:flex;"><span>                result[resultID] = source[i].ToString();
</span></span><span style="display:flex;"><span>                resultID++;
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//4. 检查 temp 变量是否为 null</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//若不为空，先将其写入 result 数组</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> (temp != <span style="color:#66d9ef">null</span>)
</span></span><span style="display:flex;"><span>            {
</span></span><span style="display:flex;"><span>                result[resultID] = temp;
</span></span><span style="display:flex;"><span>                resultID++;
</span></span><span style="display:flex;"><span>                temp = <span style="color:#66d9ef">null</span>;
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//返回 string 数组 result</span>
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">//后面在返回结果前，进行处理去除无用的 null 元素</span>
</span></span><span style="display:flex;"><span>            result = result.Where(s =&gt; !String.IsNullOrEmpty(s)).ToArray();
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> result;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
    
    
    <item>
      <title>值得探访的星球</title>
      <link>https://hiwangzi.com/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://hiwangzi.com/about/</guid>
      <description>about</description>
      <content:encoded><![CDATA[<ul>
<li><a href="https://imzhizi.com/">难以想象的晴朗</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
